@bsv/wallet-toolbox 1.1.56 → 1.1.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/client.md +22 -7
- package/docs/services.md +17 -1
- package/docs/wallet.md +22 -7
- package/out/src/sdk/types.d.ts +1 -1
- package/out/src/sdk/types.js +1 -1
- package/out/src/services/Services.js +4 -4
- package/out/src/services/Services.js.map +1 -1
- package/out/src/services/__tests/bitrails.test.d.ts +2 -0
- package/out/src/services/__tests/bitrails.test.d.ts.map +1 -0
- package/out/src/services/__tests/bitrails.test.js +48 -0
- package/out/src/services/__tests/bitrails.test.js.map +1 -0
- package/out/src/services/providers/Bitails.d.ts +13 -0
- package/out/src/services/providers/Bitails.d.ts.map +1 -1
- package/out/src/services/providers/Bitails.js +84 -0
- package/out/src/services/providers/Bitails.js.map +1 -1
- package/out/test/Wallet/local/localWallet.man.test.d.ts.map +1 -1
- package/out/test/Wallet/local/localWallet.man.test.js +42 -6
- package/out/test/Wallet/local/localWallet.man.test.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/sdk/types.ts +1 -1
- package/src/services/Services.ts +4 -4
- package/src/services/__tests/bitrails.test.ts +62 -0
- package/src/services/providers/Bitails.ts +116 -2
- package/test/Wallet/local/localWallet.man.test.ts +52 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bsv/wallet-toolbox",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.57",
|
|
4
4
|
"description": "BRC100 conforming wallet, wallet storage and wallet signer components",
|
|
5
5
|
"main": "./out/src/index.js",
|
|
6
6
|
"types": "./out/src/index.d.ts",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/bitcoin-sv/wallet-toolbox#readme",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@bsv/auth-express-middleware": "^1.0.
|
|
33
|
+
"@bsv/auth-express-middleware": "^1.0.9",
|
|
34
34
|
"@bsv/payment-express-middleware": "^1.0.3",
|
|
35
|
-
"@bsv/sdk": "^1.3.
|
|
35
|
+
"@bsv/sdk": "^1.3.29",
|
|
36
36
|
"axios": "^0.29.0",
|
|
37
37
|
"express": "^4.21.2",
|
|
38
38
|
"knex": "^3.1.0",
|
package/src/sdk/types.ts
CHANGED
|
@@ -135,7 +135,7 @@ export type ReqHistoryNote = {
|
|
|
135
135
|
/**
|
|
136
136
|
* `listOutputs` special operation basket name value.
|
|
137
137
|
*
|
|
138
|
-
* Returns
|
|
138
|
+
* Returns wallet's current change balance in the `totalOutputs` result property.
|
|
139
139
|
* The `outputs` result property will always be an empty array.
|
|
140
140
|
*/
|
|
141
141
|
export const specOpWalletBalance =
|
package/src/services/Services.ts
CHANGED
|
@@ -70,12 +70,12 @@ export class Services implements sdk.WalletServices {
|
|
|
70
70
|
})
|
|
71
71
|
|
|
72
72
|
this.postBeefServices = new ServiceCollection<sdk.PostBeefService>()
|
|
73
|
-
|
|
73
|
+
//.add({ name: 'TaalArcBeef', service: this.arc.postBeef.bind(this.arc) })
|
|
74
|
+
//.add({ name: 'WhatsOnChain', service: this.whatsonchain.postBeef.bind(this.whatsonchain) })
|
|
74
75
|
.add({
|
|
75
|
-
name: '
|
|
76
|
-
service: this.
|
|
76
|
+
name: 'Bitails',
|
|
77
|
+
service: this.bitails.postBeef.bind(this.bitails)
|
|
77
78
|
})
|
|
78
|
-
//.add({ name: 'Bitails', service: this.bitails.postBeef.bind(this.bitails) })
|
|
79
79
|
|
|
80
80
|
this.getUtxoStatusServices =
|
|
81
81
|
new ServiceCollection<sdk.GetUtxoStatusService>().add({
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
convertProofToMerklePath,
|
|
3
|
+
sdk,
|
|
4
|
+
Services,
|
|
5
|
+
TscMerkleProofApi
|
|
6
|
+
} from '../../index.client'
|
|
7
|
+
import { Bitails, BitailsMerkleProof } from '../providers/Bitails'
|
|
8
|
+
|
|
9
|
+
describe('bitrails tests', () => {
|
|
10
|
+
jest.setTimeout(99999999)
|
|
11
|
+
|
|
12
|
+
test('0 verify merkle proof to merkle path', async () => {
|
|
13
|
+
const mp = convertProofToMerklePath(
|
|
14
|
+
'068f2ce0d01b5f1e7c7a07c209c3c67d583aeae83e11e92801b51c36f81d6b67',
|
|
15
|
+
proof2
|
|
16
|
+
)
|
|
17
|
+
const root = mp.computeRoot(
|
|
18
|
+
'068f2ce0d01b5f1e7c7a07c209c3c67d583aeae83e11e92801b51c36f81d6b67'
|
|
19
|
+
)
|
|
20
|
+
expect(root).toBe(proof2merkleRoot)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('1 ', async () => {
|
|
24
|
+
const chain: sdk.Chain = 'main'
|
|
25
|
+
const bitails = new Bitails(chain)
|
|
26
|
+
const services = new Services(chain)
|
|
27
|
+
|
|
28
|
+
for (const txid of [
|
|
29
|
+
'068f2ce0d01b5f1e7c7a07c209c3c67d583aeae83e11e92801b51c36f81d6b67',
|
|
30
|
+
'a65c2663d817da6474f7805cf103be6259aae16b01468711552b737c41768c30',
|
|
31
|
+
'243fb25b94b5ef2f8554cd10d105005f51ff543d8b7a498c4e46ed304c3da24a'
|
|
32
|
+
]) {
|
|
33
|
+
const mp = await bitails.getMerklePath(txid, services)
|
|
34
|
+
const root = mp.merklePath!.computeRoot(txid)
|
|
35
|
+
expect(root).toBe(proof2merkleRoot)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const proof2merkleRoot =
|
|
41
|
+
'22b294aac4c3f6f4fdae30dc4f46f68f90feb94f03531c32bcf2ce33be5d4cb0'
|
|
42
|
+
|
|
43
|
+
const proof2: TscMerkleProofApi = {
|
|
44
|
+
index: 9443,
|
|
45
|
+
height: 742198,
|
|
46
|
+
nodes: [
|
|
47
|
+
'463c37bf0ccde321b1dc8ee857e03b8eafe76e6b1803cc3a774cfef61c50c37b',
|
|
48
|
+
'debba259db996d6ca7c4fcfd168d3afe6bfdddab93298466d53ed0421634f405',
|
|
49
|
+
'6335d744771789ef69545b0f449bcde92ae7b9920e775a591fecc7fcfa37846e',
|
|
50
|
+
'38366b3723e8f166fbfe5d7528a57885f47aa25a8296c0679832a95c1e6d2f61',
|
|
51
|
+
'5a999d2186d10a787c3397938fd97a4b3e833aab8cff2ce24cfce7589b9b706b',
|
|
52
|
+
'db97fbd581b8769602c6079e7fe10eb34cd99b844598b31441018ac21babd7e7',
|
|
53
|
+
'583e044e2bbc6b19993e73c3363a8ce3b4580a54510524489daadc6c82205f5a',
|
|
54
|
+
'ba5d97e4fbedb84682f65b254c56f5826f1dc65bd376dc1660f23b81c4035b1d',
|
|
55
|
+
'bfa39460ee7a8293698e41134a53cfc5ba0054416ca092d79ecbf93ae2b8b71b',
|
|
56
|
+
'8f3d186687f3f8186c4cbddcf263bbb4b58e3c279e55f9def048076faff0cc83',
|
|
57
|
+
'287790c47a0044e8e51ee60df33d4d23b972b5a51d8e9be7ac8b635b9f1e7ffc',
|
|
58
|
+
'19444e7ad68681d847d4d88989efa5f13afa46d7cbb47e8ce91876555c3e414d',
|
|
59
|
+
'6d71f472dabd52216a3cb24090d580baed96497b449876c199f48ed07f5ea2b0',
|
|
60
|
+
'af4c17b677b0c7b4d85e7331b4e43fc16f9a7024c9417d7854c55a096ac098b3'
|
|
61
|
+
]
|
|
62
|
+
}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Beef,
|
|
3
|
+
defaultHttpClient,
|
|
4
|
+
HexString,
|
|
5
|
+
HttpClient,
|
|
6
|
+
MerklePath,
|
|
7
|
+
Utils
|
|
8
|
+
} from '@bsv/sdk'
|
|
9
|
+
import {
|
|
10
|
+
convertProofToMerklePath,
|
|
11
|
+
doubleSha256BE,
|
|
12
|
+
sdk,
|
|
13
|
+
wait
|
|
14
|
+
} from '../../index.client'
|
|
3
15
|
import { ReqHistoryNote } from '../../sdk'
|
|
4
16
|
|
|
5
17
|
export interface BitailsConfig {
|
|
@@ -188,6 +200,101 @@ export class Bitails {
|
|
|
188
200
|
})
|
|
189
201
|
return r
|
|
190
202
|
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
*
|
|
206
|
+
* @param txid
|
|
207
|
+
* @param services
|
|
208
|
+
* @returns
|
|
209
|
+
*/
|
|
210
|
+
async getMerklePath(
|
|
211
|
+
txid: string,
|
|
212
|
+
services: sdk.WalletServices
|
|
213
|
+
): Promise<sdk.GetMerklePathResult> {
|
|
214
|
+
const r: sdk.GetMerklePathResult = { name: 'BitailsTsc', notes: [] }
|
|
215
|
+
|
|
216
|
+
const url = `${this.URL}/tx/${txid}/proof/tsc`
|
|
217
|
+
|
|
218
|
+
const nn = () => ({
|
|
219
|
+
name: 'BitailsProofTsc',
|
|
220
|
+
when: new Date().toISOString(),
|
|
221
|
+
txid,
|
|
222
|
+
url
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
const headers = this.getHttpHeaders()
|
|
226
|
+
const requestOptions = {
|
|
227
|
+
method: 'GET',
|
|
228
|
+
headers
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
for (let retry = 0; retry < 2; retry++) {
|
|
232
|
+
try {
|
|
233
|
+
const response = await this.httpClient.request<BitailsMerkleProof>(
|
|
234
|
+
url,
|
|
235
|
+
requestOptions
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
const nne = () => ({
|
|
239
|
+
...nn(),
|
|
240
|
+
txid,
|
|
241
|
+
url,
|
|
242
|
+
status: response.status,
|
|
243
|
+
statusText: response.statusText
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
if (response.statusText === 'Too Many Requests' && retry < 2) {
|
|
247
|
+
r.notes!.push({ ...nne(), what: 'getMerklePathRetry' })
|
|
248
|
+
await wait(2000)
|
|
249
|
+
continue
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (response.status === 404 && response.statusText === 'Not Found') {
|
|
253
|
+
r.notes!.push({ ...nne(), what: 'getMerklePathNotFound' })
|
|
254
|
+
} else if (
|
|
255
|
+
!response.ok ||
|
|
256
|
+
response.status !== 200 ||
|
|
257
|
+
response.statusText !== 'OK'
|
|
258
|
+
) {
|
|
259
|
+
r.notes!.push({ ...nne(), what: 'getMerklePathBadStatus' })
|
|
260
|
+
} else if (!response.data) {
|
|
261
|
+
// Unmined, proof not yet available.
|
|
262
|
+
r.notes!.push({ ...nne(), what: 'getMerklePathNoData' })
|
|
263
|
+
} else {
|
|
264
|
+
const p = response.data
|
|
265
|
+
const header = await services.hashToHeader(p.target)
|
|
266
|
+
if (header) {
|
|
267
|
+
const proof = {
|
|
268
|
+
index: p.index,
|
|
269
|
+
nodes: p.nodes,
|
|
270
|
+
height: header.height
|
|
271
|
+
}
|
|
272
|
+
r.merklePath = convertProofToMerklePath(txid, proof)
|
|
273
|
+
r.header = header
|
|
274
|
+
r.notes!.push({ ...nne(), what: 'getMerklePathSuccess' })
|
|
275
|
+
} else {
|
|
276
|
+
r.notes!.push({
|
|
277
|
+
...nne(),
|
|
278
|
+
what: 'getMerklePathNoHeader',
|
|
279
|
+
target: p.target
|
|
280
|
+
})
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
} catch (eu: unknown) {
|
|
284
|
+
const e = sdk.WalletError.fromUnknown(eu)
|
|
285
|
+
r.notes!.push({
|
|
286
|
+
...nn(),
|
|
287
|
+
what: 'getMerklePathError',
|
|
288
|
+
code: e.code,
|
|
289
|
+
description: e.description
|
|
290
|
+
})
|
|
291
|
+
r.error = e
|
|
292
|
+
}
|
|
293
|
+
return r
|
|
294
|
+
}
|
|
295
|
+
r.notes!.push({ ...nn(), what: 'getMerklePathInternal' })
|
|
296
|
+
return r
|
|
297
|
+
}
|
|
191
298
|
}
|
|
192
299
|
|
|
193
300
|
interface BitailsPostRawsResult {
|
|
@@ -197,3 +304,10 @@ interface BitailsPostRawsResult {
|
|
|
197
304
|
message: string
|
|
198
305
|
}
|
|
199
306
|
}
|
|
307
|
+
|
|
308
|
+
export interface BitailsMerkleProof {
|
|
309
|
+
index: number
|
|
310
|
+
txOrId: string
|
|
311
|
+
target: string
|
|
312
|
+
nodes: string[]
|
|
313
|
+
}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
CreateActionArgs,
|
|
4
4
|
CreateActionOptions,
|
|
5
5
|
CreateActionResult,
|
|
6
|
+
OutpointString,
|
|
6
7
|
P2PKH,
|
|
7
8
|
PrivateKey,
|
|
8
9
|
PublicKey,
|
|
@@ -26,6 +27,10 @@ import {
|
|
|
26
27
|
} from '../../../src'
|
|
27
28
|
import { _tu, TestWalletNoSetup } from '../../utils/TestUtilsWalletStorage'
|
|
28
29
|
import { monitorEventLoopDelay } from 'perf_hooks'
|
|
30
|
+
import {
|
|
31
|
+
validateCreateActionArgs,
|
|
32
|
+
ValidCreateActionArgs
|
|
33
|
+
} from '../../../src/sdk'
|
|
29
34
|
|
|
30
35
|
describe('localWallet tests', () => {
|
|
31
36
|
jest.setTimeout(99999999)
|
|
@@ -39,7 +44,7 @@ describe('localWallet tests', () => {
|
|
|
39
44
|
|
|
40
45
|
const car = await createOneSatTestOutput(setup, {}, 1)
|
|
41
46
|
|
|
42
|
-
await trackReqByTxid(setup, car.txid!)
|
|
47
|
+
//await trackReqByTxid(setup, car.txid!)
|
|
43
48
|
|
|
44
49
|
await setup.wallet.destroy()
|
|
45
50
|
})
|
|
@@ -58,6 +63,16 @@ describe('localWallet tests', () => {
|
|
|
58
63
|
await setup.wallet.destroy()
|
|
59
64
|
})
|
|
60
65
|
|
|
66
|
+
test('0b create 2 nosend and sendWith', async () => {
|
|
67
|
+
const setup = await createSetup('test')
|
|
68
|
+
|
|
69
|
+
const car = await createOneSatTestOutput(setup, { noSend: true }, 2)
|
|
70
|
+
|
|
71
|
+
//await trackReqByTxid(setup, car.txid!)
|
|
72
|
+
|
|
73
|
+
await setup.wallet.destroy()
|
|
74
|
+
})
|
|
75
|
+
|
|
61
76
|
test('1 recover 1 sat outputs', async () => {
|
|
62
77
|
const setup = await createSetup('test')
|
|
63
78
|
|
|
@@ -178,8 +193,14 @@ async function createOneSatTestOutput(
|
|
|
178
193
|
options: CreateActionOptions = {},
|
|
179
194
|
howMany: number = 1
|
|
180
195
|
): Promise<CreateActionResult> {
|
|
196
|
+
if (howMany < 1) throw new sdk.WERR_INVALID_PARAMETER('howMany', 'at least 1')
|
|
197
|
+
|
|
181
198
|
let car: CreateActionResult = {}
|
|
182
199
|
|
|
200
|
+
let noSendChange: OutpointString[] | undefined = undefined
|
|
201
|
+
let txids: string[] = []
|
|
202
|
+
let vargs: ValidCreateActionArgs
|
|
203
|
+
|
|
183
204
|
for (let i = 0; i < howMany; i++) {
|
|
184
205
|
const args: CreateActionArgs = {
|
|
185
206
|
outputs: [
|
|
@@ -198,11 +219,15 @@ async function createOneSatTestOutput(
|
|
|
198
219
|
],
|
|
199
220
|
description: 'create test output',
|
|
200
221
|
options: {
|
|
201
|
-
...options
|
|
222
|
+
...options,
|
|
223
|
+
noSendChange
|
|
202
224
|
}
|
|
203
225
|
}
|
|
226
|
+
vargs = validateCreateActionArgs(args)
|
|
204
227
|
car = await setup.wallet.createAction(args)
|
|
205
228
|
expect(car.txid)
|
|
229
|
+
txids.push(car.txid!)
|
|
230
|
+
noSendChange = car.noSendChange
|
|
206
231
|
|
|
207
232
|
const req = await EntityProvenTxReq.fromStorageTxid(
|
|
208
233
|
setup.activeStorage,
|
|
@@ -210,12 +235,33 @@ async function createOneSatTestOutput(
|
|
|
210
235
|
)
|
|
211
236
|
expect(req !== undefined && req.history.notes !== undefined)
|
|
212
237
|
if (req && req.history.notes) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
238
|
+
if (vargs.isNoSend) {
|
|
239
|
+
expect(req.status === 'nosend').toBe(true)
|
|
240
|
+
expect(req.history.notes.length).toBe(1)
|
|
241
|
+
const n = req.history.notes[0]
|
|
242
|
+
expect(n.what === 'status' && n.status_now === 'nosend').toBe(true)
|
|
243
|
+
} else {
|
|
244
|
+
expect(req.status === 'unsent').toBe(true)
|
|
245
|
+
expect(req.history.notes.length).toBe(1)
|
|
246
|
+
const n = req.history.notes[0]
|
|
247
|
+
expect(n.what === 'status' && n.status_now === 'unsent').toBe(true)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (vargs!.isNoSend) {
|
|
253
|
+
// Create final sending transaction
|
|
254
|
+
const args: CreateActionArgs = {
|
|
255
|
+
description: 'send batch',
|
|
256
|
+
options: {
|
|
257
|
+
...options,
|
|
258
|
+
sendWith: txids
|
|
259
|
+
}
|
|
217
260
|
}
|
|
261
|
+
vargs = validateCreateActionArgs(args)
|
|
262
|
+
car = await setup.wallet.createAction(args)
|
|
218
263
|
}
|
|
264
|
+
|
|
219
265
|
return car
|
|
220
266
|
}
|
|
221
267
|
|