Skip to content

Commit 0160ffe

Browse files
committed
bring sdk WhatsOnChain in as SdkWhatsOnChain to permit releasing
1 parent 9b51d86 commit 0160ffe

19 files changed

+1718
-4942
lines changed

docs/client.md

Lines changed: 333 additions & 288 deletions
Large diffs are not rendered by default.

docs/services.md

Lines changed: 207 additions & 187 deletions
Large diffs are not rendered by default.

docs/wallet.md

Lines changed: 333 additions & 288 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 492 additions & 3381 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/sdk/WalletServices.interfaces.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
ArcConfig,
23
Beef,
34
Transaction as BsvTransaction,
45
ChainTracker,
@@ -90,15 +91,6 @@ export interface WalletServices {
9091
*/
9192
getMerklePath(txid: string, useNext?: boolean): Promise<GetMerklePathResult>
9293

93-
/**
94-
*
95-
* @param beef
96-
* @param txids
97-
* @param chain
98-
* @returns
99-
*/
100-
postTxs(beef: Beef, txids: string[]): Promise<PostTxsResult[]>
101-
10294
/**
10395
*
10496
* @param beef
@@ -168,6 +160,8 @@ export interface WalletServicesOptions {
168160
exchangeratesapiKey?: string
169161
chaintracksFiatExchangeRatesUrl?: string
170162
chaintracks?: ChaintracksServiceClient
163+
arcUrl: string
164+
arcConfig: ArcConfig
171165
}
172166

173167
/**
@@ -401,8 +395,7 @@ export type PostTxsService = (
401395

402396
export type PostBeefService = (
403397
beef: Beef,
404-
txids: string[],
405-
services: WalletServices
398+
txids: string[]
406399
) => Promise<PostBeefResult>
407400

408401
export type UpdateFiatExchangeRateService = (

src/services/Services.ts

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,14 @@ import {
1313
wait
1414
} from '../index.client'
1515
import { ServiceCollection } from './ServiceCollection'
16-
1716
import { createDefaultWalletServicesOptions } from './createDefaultWalletServicesOptions'
1817
import { ChaintracksChainTracker } from './chaintracker'
19-
import {
20-
getTaalArcServiceConfig,
21-
makePostBeefToTaalARC,
22-
makePostTxsToTaalARC
23-
} from './providers/arcServices'
2418
import { WhatsOnChain } from './providers/WhatsOnChain'
2519
import {
2620
updateChaintracksFiatExchangeRates,
2721
updateExchangeratesapi
2822
} from './providers/echangeRates'
23+
import ARC from './providers/ARC'
2924

3025
export class Services implements sdk.WalletServices {
3126
static createDefaultOptions(chain: sdk.Chain): sdk.WalletServicesOptions {
@@ -34,10 +29,10 @@ export class Services implements sdk.WalletServices {
3429

3530
options: sdk.WalletServicesOptions
3631
whatsonchain: WhatsOnChain
32+
arc: ARC
3733

3834
getMerklePathServices: ServiceCollection<sdk.GetMerklePathService>
3935
getRawTxServices: ServiceCollection<sdk.GetRawTxService>
40-
postTxsServices: ServiceCollection<sdk.PostTxsService>
4136
postBeefServices: ServiceCollection<sdk.PostBeefService>
4237
getUtxoStatusServices: ServiceCollection<sdk.GetUtxoStatusService>
4338
updateFiatExchangeRateServices: ServiceCollection<sdk.UpdateFiatExchangeRateService>
@@ -57,6 +52,8 @@ export class Services implements sdk.WalletServices {
5752
apiKey: this.options.taalApiKey
5853
})
5954

55+
this.arc = new ARC(this.options.arcUrl, this.options.arcConfig)
56+
6057
this.getMerklePathServices =
6158
new ServiceCollection<sdk.GetMerklePathService>().add({
6259
name: 'WhatsOnChain',
@@ -68,18 +65,9 @@ export class Services implements sdk.WalletServices {
6865
service: this.whatsonchain.getRawTxResult.bind(this.whatsonchain)
6966
})
7067

71-
this.postTxsServices = new ServiceCollection<sdk.PostTxsService>().add({
72-
name: 'TaalArcTxs',
73-
service: makePostTxsToTaalARC(
74-
getTaalArcServiceConfig(this.chain, this.options.taalApiKey!)
75-
)
76-
})
77-
7868
this.postBeefServices = new ServiceCollection<sdk.PostBeefService>().add({
7969
name: 'TaalArcBeef',
80-
service: makePostBeefToTaalARC(
81-
getTaalArcServiceConfig(this.chain, this.options.taalApiKey!)
82-
)
70+
service: this.arc.postBeef.bind(this.arc)
8371
})
8472

8573
this.getUtxoStatusServices =
@@ -138,9 +126,6 @@ export class Services implements sdk.WalletServices {
138126
get getRawTxsCount() {
139127
return this.getRawTxServices.count
140128
}
141-
get postTxsServicesCount() {
142-
return this.postTxsServices.count
143-
}
144129
get postBeefServicesCount() {
145130
return this.postBeefServices.count
146131
}
@@ -179,25 +164,6 @@ export class Services implements sdk.WalletServices {
179164
return r0
180165
}
181166

182-
/**
183-
* The beef must contain at least each rawTx for each txid.
184-
* Some services may require input transactions as well.
185-
* These will be fetched if missing, greatly extending the service response time.
186-
* @param beef
187-
* @param txids
188-
* @returns
189-
*/
190-
async postTxs(beef: Beef, txids: string[]): Promise<sdk.PostTxsResult[]> {
191-
const rs = await Promise.all(
192-
this.postTxsServices.allServices.map(async service => {
193-
const r = await service(beef, txids, this)
194-
return r
195-
})
196-
)
197-
198-
return rs
199-
}
200-
201167
/**
202168
*
203169
* @param beef
@@ -207,15 +173,10 @@ export class Services implements sdk.WalletServices {
207173
async postBeef(beef: Beef, txids: string[]): Promise<sdk.PostBeefResult[]> {
208174
let rs = await Promise.all(
209175
this.postBeefServices.allServices.map(async service => {
210-
const r = await service(beef, txids, this)
176+
const r = await service(beef, txids)
211177
return r
212178
})
213179
)
214-
215-
if (rs.every(r => r.status !== 'success')) {
216-
rs = await this.postTxs(beef, txids)
217-
}
218-
219180
return rs
220181
}
221182

src/services/__tests/ARC.test.ts

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,77 @@
1-
import { toBase58 } from "@bsv/sdk/dist/types/src/primitives/utils"
2-
import { _tu } from "../../../test/utils/TestUtilsWalletStorage"
3-
import { sdk, wait } from "../../index.client"
4-
import ARC from "../providers/ARC"
1+
import { _tu } from '../../../test/utils/TestUtilsWalletStorage'
2+
import { sdk, wait } from '../../index.client'
3+
import ARC from '../providers/ARC'
4+
import { BeefTx } from '@bsv/sdk'
5+
import { arcDefaultUrl } from '../createDefaultWalletServicesOptions'
56

67
describe('ARC tests', () => {
78
jest.setTimeout(99999999)
89

910
const envTest = _tu.getEnv('test')
10-
const arcTest = new ARC(arcUrl(envTest.chain), { apiKey: envTest.taalApiKey })
11+
const arcTest = new ARC(arcDefaultUrl(envTest.chain), {
12+
apiKey: envTest.taalApiKey
13+
})
1114

1215
const envMain = _tu.getEnv('main')
13-
const arcMain = new ARC(arcUrl(envMain.chain), { apiKey: envMain.taalApiKey })
16+
const arcMain = new ARC(arcDefaultUrl(envMain.chain), {
17+
apiKey: envMain.taalApiKey
18+
})
1419

15-
test('7 postRawTx testnet', async () => {
20+
test.skip('7 postRawTx testnet', async () => {
1621
await postRawTxTest('test', arcTest)
1722
})
1823

19-
test('8 postRawTx mainnet', async () => {
24+
test.skip('8 postRawTx mainnet', async () => {
2025
await postRawTxTest('main', arcMain)
2126
})
2227

28+
test.skip('9 postBeef testnet', async () => {
29+
const r = await postBeefTest('test', arcTest)
30+
console.log(`9 postBeef testnet done ${r}`)
31+
})
32+
33+
test.skip('10 postBeef mainnet', async () => {
34+
const r = await postBeefTest('main', arcMain)
35+
console.log(`10 postBeef mainnet done ${r}`)
36+
})
2337
})
2438

25-
function arcUrl(chain: sdk.Chain): string {
26-
const url = chain === 'main'
27-
? 'https://api.taal.com/arc'
28-
: 'https://arc-test.taal.com'
29-
return url
39+
async function postBeefTest(chain: sdk.Chain, arc: ARC): Promise<string> {
40+
if (_tu.noEnv(chain)) return 'skipped'
41+
const c = await _tu.createNoSendTxPair(chain)
42+
43+
const txids = [c.txidDo, c.txidUndo]
44+
45+
const r = await arc.postBeef(c.beef, txids)
46+
expect(r.status).toBe('success')
47+
for (const txid of txids) {
48+
const tr = r.txidResults.find(tx => tx.txid === txid)
49+
expect(tr).not.toBeUndefined()
50+
expect(tr!.status).toBe('success')
51+
}
52+
53+
// replace Undo transaction with double spend transaction and send again.
54+
const beef2 = c.beef.clone()
55+
beef2.txs[beef2.txs.length - 1] = BeefTx.fromTx(c.doubleSpendTx)
56+
const txids2 = [c.txidDo, c.doubleSpendTx.id('hex')]
57+
58+
const r2 = await arc.postBeef(beef2, txids2)
59+
expect(r2.status).toBe('error')
60+
for (const txid of txids2) {
61+
const tr = r2.txidResults.find(tx => tx.txid === txid)
62+
expect(tr).not.toBeUndefined()
63+
if (txid === c.txidDo) {
64+
expect(tr!.status).toBe('success')
65+
} else {
66+
expect(tr!.status).toBe('error')
67+
expect(tr!.doubleSpend).toBe(true)
68+
expect(tr!.competingTxs).toEqual([c.txidUndo])
69+
}
70+
}
71+
return 'passed'
3072
}
3173

32-
async function postRawTxTest(chain: sdk.Chain, arc: ARC) {
74+
async function postRawTxTest(chain: sdk.Chain, arc: ARC): Promise<void> {
3375
if (_tu.noEnv(chain)) return
3476
const c = await _tu.createNoSendTxPair(chain)
3577

@@ -64,4 +106,4 @@ async function postRawTxTest(chain: sdk.Chain, arc: ARC) {
64106
expect(rDouble.status).toBe('error')
65107
expect(rDouble.doubleSpend).toBe(true)
66108
expect(rDouble.competingTxs![0]).toBe(c.txidUndo)
67-
}
109+
}

src/services/__tests/arcServices.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@ import { Services } from '../../index.all'
44
describe.skip('arcServices tests', () => {
55
jest.setTimeout(99999999)
66

7-
test('0 ', async () => {
8-
})
7+
test('0 ', async () => {})
98
})
Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,54 @@
1-
import { Beef } from '@bsv/sdk'
2-
import { Services } from '../../index.client'
1+
import { Beef, BeefTx } from '@bsv/sdk'
2+
import { sdk, Services } from '../../index.client'
3+
import { _tu } from '../../../test/utils/TestUtilsWalletStorage'
34

45
describe('postBeef service tests', () => {
56
jest.setTimeout(99999999)
67

7-
test('0', async () => {
8+
test('0 postBeef mainnet', async () => {
89
const options = Services.createDefaultOptions('main')
910
const services = new Services(options)
11+
await postBeefTest(services)
12+
})
1013

11-
const txid =
12-
'9cce99686bc8621db439b7150dd5b3b269e4b0628fd75160222c417d6f2b95e4'
13-
const rawTx = await services.getRawTx(txid)
14-
const beef = new Beef()
15-
beef.mergeRawTx(rawTx.rawTx!)
16-
const r = await services.postTxs(beef, [txid])
17-
expect(r).toBeTruthy()
14+
test('1 postBeef testnet', async () => {
15+
const options = Services.createDefaultOptions('test')
16+
const services = new Services(options)
17+
await postBeefTest(services)
1818
})
1919
})
20+
21+
async function postBeefTest(services: Services) {
22+
const chain = services.chain
23+
if (_tu.noEnv(chain)) return
24+
const c = await _tu.createNoSendTxPair(chain)
25+
26+
const txids = [c.txidDo, c.txidUndo]
27+
28+
const [r] = await services.postBeef(c.beef, txids)
29+
expect(r.status).toBe('success')
30+
for (const txid of txids) {
31+
const tr = r.txidResults.find(tx => tx.txid === txid)
32+
expect(tr).not.toBeUndefined()
33+
expect(tr!.status).toBe('success')
34+
}
35+
36+
// replace Undo transaction with double spend transaction and send again.
37+
const beef2 = c.beef.clone()
38+
beef2.txs[beef2.txs.length - 1] = BeefTx.fromTx(c.doubleSpendTx)
39+
const txids2 = [c.txidDo, c.doubleSpendTx.id('hex')]
40+
41+
const [r2] = await services.postBeef(beef2, txids2)
42+
expect(r2.status).toBe('error')
43+
for (const txid of txids2) {
44+
const tr = r2.txidResults.find(tx => tx.txid === txid)
45+
expect(tr).not.toBeUndefined()
46+
if (txid === c.txidDo) {
47+
expect(tr!.status).toBe('success')
48+
} else {
49+
expect(tr!.status).toBe('error')
50+
expect(tr!.doubleSpend).toBe(true)
51+
expect(tr!.competingTxs).toEqual([c.txidUndo])
52+
}
53+
}
54+
}

src/services/__tests/postTxs.test.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)