@bsv/sdk 2.1.1 → 2.1.3
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/dist/cjs/package.json +1 -1
- package/dist/cjs/src/auth/Peer.js +21 -18
- package/dist/cjs/src/auth/Peer.js.map +1 -1
- package/dist/cjs/src/auth/SessionManager.js.map +1 -1
- package/dist/cjs/src/auth/clients/AuthFetch.js +4 -1
- package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/cjs/src/identity/ContactsManager.js +44 -6
- package/dist/cjs/src/identity/ContactsManager.js.map +1 -1
- package/dist/cjs/src/identity/IdentityClient.js +106 -37
- package/dist/cjs/src/identity/IdentityClient.js.map +1 -1
- package/dist/cjs/src/overlay-tools/LookupResolver.js +180 -82
- package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/cjs/src/primitives/Hash.js +173 -50
- package/dist/cjs/src/primitives/Hash.js.map +1 -1
- package/dist/cjs/src/primitives/SymmetricKey.js +123 -1
- package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/cjs/src/transaction/MerklePath.js +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/auth/Peer.js +28 -18
- package/dist/esm/src/auth/Peer.js.map +1 -1
- package/dist/esm/src/auth/SessionManager.js.map +1 -1
- package/dist/esm/src/auth/clients/AuthFetch.js +4 -1
- package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/esm/src/identity/ContactsManager.js +44 -6
- package/dist/esm/src/identity/ContactsManager.js.map +1 -1
- package/dist/esm/src/identity/IdentityClient.js +106 -37
- package/dist/esm/src/identity/IdentityClient.js.map +1 -1
- package/dist/esm/src/overlay-tools/LookupResolver.js +180 -82
- package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/esm/src/primitives/Hash.js +177 -50
- package/dist/esm/src/primitives/Hash.js.map +1 -1
- package/dist/esm/src/primitives/SymmetricKey.js +123 -1
- package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/esm/src/transaction/MerklePath.js +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/auth/Peer.d.ts +3 -3
- package/dist/types/src/auth/Peer.d.ts.map +1 -1
- package/dist/types/src/auth/SessionManager.d.ts +21 -0
- package/dist/types/src/auth/SessionManager.d.ts.map +1 -1
- package/dist/types/src/auth/clients/AuthFetch.d.ts +2 -2
- package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
- package/dist/types/src/identity/ContactsManager.d.ts +13 -2
- package/dist/types/src/identity/ContactsManager.d.ts.map +1 -1
- package/dist/types/src/identity/IdentityClient.d.ts +50 -24
- package/dist/types/src/identity/IdentityClient.d.ts.map +1 -1
- package/dist/types/src/overlay-tools/LookupResolver.d.ts +15 -1
- package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
- package/dist/types/src/primitives/Hash.d.ts +21 -16
- package/dist/types/src/primitives/Hash.d.ts.map +1 -1
- package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
- package/dist/types/src/wallet/Wallet.interfaces.d.ts +16 -1
- package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -1
- package/dist/types/src/wallet/WalletClient.d.ts +1 -1
- package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/window.CWI.d.ts +1 -1
- package/dist/types/src/wallet/substrates/window.CWI.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +4 -4
- package/package.json +1 -1
- package/src/auth/Peer.ts +30 -20
- package/src/auth/SessionManager.ts +22 -0
- package/src/auth/__tests/Peer.test.ts +47 -1
- package/src/auth/clients/AuthFetch.ts +6 -3
- package/src/identity/ContactsManager.ts +47 -6
- package/src/identity/IdentityClient.ts +137 -53
- package/src/identity/__tests/IdentityClient.additional.test.ts +150 -1
- package/src/identity/__tests/IdentityClient.test.ts +4 -4
- package/src/overlay-tools/LookupResolver.ts +191 -77
- package/src/overlay-tools/__tests/LookupResolver.additional.test.ts +90 -0
- package/src/primitives/Hash.ts +232 -96
- package/src/primitives/SymmetricKey.ts +145 -1
- package/src/primitives/__tests/Hash.additional.test.ts +65 -0
- package/src/primitives/__tests/Hash.test.ts +6 -1
- package/src/script/__tests/Spend.test.ts +45 -4
- package/src/transaction/MerklePath.ts +1 -1
- package/src/transaction/__tests/Transaction.test.ts +17 -0
- package/src/wallet/Wallet.interfaces.ts +16 -1
- package/src/wallet/WalletClient.ts +1 -1
- package/src/wallet/substrates/window.CWI.ts +1 -1
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
import { createHash, createHmac } from 'node:crypto'
|
|
1
2
|
import { SHA1HMAC, SHA512HMAC, pbkdf2 } from '../../primitives/Hash'
|
|
2
3
|
|
|
4
|
+
function toHex (arr: number[]): string {
|
|
5
|
+
return Buffer.from(arr).toString('hex')
|
|
6
|
+
}
|
|
7
|
+
|
|
3
8
|
describe('Hash – additional coverage', () => {
|
|
4
9
|
describe('SHA1HMAC', () => {
|
|
5
10
|
it('produces a correct HMAC-SHA1 digest', () => {
|
|
@@ -56,4 +61,64 @@ describe('Hash – additional coverage', () => {
|
|
|
56
61
|
)
|
|
57
62
|
})
|
|
58
63
|
})
|
|
64
|
+
|
|
65
|
+
describe('pure-TS fallback parity', () => {
|
|
66
|
+
const msg = new Uint8Array([
|
|
67
|
+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
68
|
+
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
69
|
+
0xff, 0xfe, 0xfd, 0xfc
|
|
70
|
+
])
|
|
71
|
+
const key = new Uint8Array([0xde, 0xad, 0xbe, 0xef])
|
|
72
|
+
|
|
73
|
+
const expectedSha256 = createHash('sha256').update(msg).digest('hex')
|
|
74
|
+
const expectedSha512 = createHash('sha512').update(msg).digest('hex')
|
|
75
|
+
const expectedRipemd160 = createHash('ripemd160').update(msg).digest('hex')
|
|
76
|
+
const expectedHash256 = createHash('sha256')
|
|
77
|
+
.update(createHash('sha256').update(msg).digest())
|
|
78
|
+
.digest('hex')
|
|
79
|
+
const expectedHash160 = createHash('ripemd160')
|
|
80
|
+
.update(createHash('sha256').update(msg).digest())
|
|
81
|
+
.digest('hex')
|
|
82
|
+
const expectedSha256Hmac = createHmac('sha256', key)
|
|
83
|
+
.update(msg)
|
|
84
|
+
.digest('hex')
|
|
85
|
+
const expectedSha512Hmac = createHmac('sha512', key)
|
|
86
|
+
.update(msg)
|
|
87
|
+
.digest('hex')
|
|
88
|
+
|
|
89
|
+
it('matches native digests when node:crypto is unavailable', () => {
|
|
90
|
+
const originalGetBuiltin = (process as any).getBuiltinModule
|
|
91
|
+
;(process as any).getBuiltinModule = (): never => {
|
|
92
|
+
throw new Error('blocked for test')
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
jest.isolateModules(() => {
|
|
96
|
+
jest.doMock('node:crypto', () => {
|
|
97
|
+
throw new Error('blocked for test')
|
|
98
|
+
})
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
100
|
+
const fallback = require('../../primitives/Hash')
|
|
101
|
+
expect(toHex(fallback.sha256(Array.from(msg)))).toBe(expectedSha256)
|
|
102
|
+
expect(toHex(fallback.sha512(Array.from(msg)))).toBe(expectedSha512)
|
|
103
|
+
expect(toHex(fallback.ripemd160(Array.from(msg)))).toBe(
|
|
104
|
+
expectedRipemd160
|
|
105
|
+
)
|
|
106
|
+
expect(toHex(fallback.hash256(Array.from(msg)))).toBe(
|
|
107
|
+
expectedHash256
|
|
108
|
+
)
|
|
109
|
+
expect(toHex(fallback.hash160(Array.from(msg)))).toBe(
|
|
110
|
+
expectedHash160
|
|
111
|
+
)
|
|
112
|
+
expect(
|
|
113
|
+
toHex(fallback.sha256hmac(Array.from(key), Array.from(msg)))
|
|
114
|
+
).toBe(expectedSha256Hmac)
|
|
115
|
+
expect(
|
|
116
|
+
toHex(fallback.sha512hmac(Array.from(key), Array.from(msg)))
|
|
117
|
+
).toBe(expectedSha512Hmac)
|
|
118
|
+
})
|
|
119
|
+
} finally {
|
|
120
|
+
;(process as any).getBuiltinModule = originalGetBuiltin
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
})
|
|
59
124
|
})
|
|
@@ -42,6 +42,11 @@ describe('Hash', function () {
|
|
|
42
42
|
])
|
|
43
43
|
})
|
|
44
44
|
|
|
45
|
+
it('preserves SDK hex normalization before hashing', function () {
|
|
46
|
+
expect(hash.sha256('abc', 'hex')).toEqual(hash.sha256([0x0a, 0xbc]))
|
|
47
|
+
expect(() => hash.sha256('zz', 'hex')).toThrow('Invalid hex string')
|
|
48
|
+
})
|
|
49
|
+
|
|
45
50
|
it('should support ripemd160', function () {
|
|
46
51
|
test(hash.RIPEMD160, [
|
|
47
52
|
['', '9c1185a5c5e9fc54612808977ee8f548b2258d31'],
|
|
@@ -230,7 +235,7 @@ describe('Hash', function () {
|
|
|
230
235
|
it('realHtonl preserves value when system is big-endian (forced simulation)', () => {
|
|
231
236
|
// We simulate the big-endian branch of realHtonl by calling
|
|
232
237
|
// the fallback path directly.
|
|
233
|
-
const forceBigEndianRealHtonl = (w: number) => (w >>> 0)
|
|
238
|
+
const forceBigEndianRealHtonl = (w: number): number => (w >>> 0)
|
|
234
239
|
|
|
235
240
|
expect(forceBigEndianRealHtonl(0x11223344)).toBe(0x11223344)
|
|
236
241
|
expect(forceBigEndianRealHtonl(0xaabbccdd)).toBe(0xaabbccdd)
|
|
@@ -512,7 +512,7 @@ describe('Spend', () => {
|
|
|
512
512
|
})
|
|
513
513
|
})
|
|
514
514
|
|
|
515
|
-
it('
|
|
515
|
+
it('Rejects spending an immature coinbase transaction', async () => {
|
|
516
516
|
const sourceTransaction = new Transaction(
|
|
517
517
|
1,
|
|
518
518
|
[{
|
|
@@ -531,8 +531,49 @@ describe('Spend', () => {
|
|
|
531
531
|
)
|
|
532
532
|
const txid = sourceTransaction.id('hex')
|
|
533
533
|
sourceTransaction.merklePath = MerklePath.fromCoinbaseTxidAndHeight(txid, 0)
|
|
534
|
-
const chain = new MockChain({ blockheaders: [] })
|
|
535
|
-
|
|
534
|
+
const chain = new MockChain({ blockheaders: [txid] })
|
|
535
|
+
|
|
536
|
+
const spendTx = new Transaction(
|
|
537
|
+
1,
|
|
538
|
+
[
|
|
539
|
+
{
|
|
540
|
+
unlockingScript: Script.fromASM('OP_TRUE'),
|
|
541
|
+
sourceTransaction,
|
|
542
|
+
sourceOutputIndex: 0
|
|
543
|
+
}
|
|
544
|
+
],
|
|
545
|
+
[{
|
|
546
|
+
lockingScript: Script.fromASM('OP_NOP'),
|
|
547
|
+
satoshis: 1
|
|
548
|
+
}],
|
|
549
|
+
0
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
await expect(spendTx.verify(chain)).rejects.toThrow(
|
|
553
|
+
`Invalid merkle path for transaction ${txid}`
|
|
554
|
+
)
|
|
555
|
+
})
|
|
556
|
+
|
|
557
|
+
it('Successfully validates a mature coinbase spend where sequence is set to undefined', async () => {
|
|
558
|
+
const sourceTransaction = new Transaction(
|
|
559
|
+
1,
|
|
560
|
+
[{
|
|
561
|
+
sourceTXID: '0000000000000000000000000000000000000000000000000000000000000000',
|
|
562
|
+
sourceOutputIndex: 0,
|
|
563
|
+
unlockingScript: Script.fromASM('OP_TRUE'),
|
|
564
|
+
sequence: 0xffffffff
|
|
565
|
+
}],
|
|
566
|
+
[
|
|
567
|
+
{
|
|
568
|
+
lockingScript: Script.fromASM('OP_NOP'),
|
|
569
|
+
satoshis: 2
|
|
570
|
+
}
|
|
571
|
+
],
|
|
572
|
+
0
|
|
573
|
+
)
|
|
574
|
+
const txid = sourceTransaction.id('hex')
|
|
575
|
+
sourceTransaction.merklePath = MerklePath.fromCoinbaseTxidAndHeight(txid, 0)
|
|
576
|
+
const chain = new MockChain({ blockheaders: [txid, ...new Array(100).fill('')] })
|
|
536
577
|
|
|
537
578
|
const spendTx = new Transaction(
|
|
538
579
|
1,
|
|
@@ -551,7 +592,7 @@ describe('Spend', () => {
|
|
|
551
592
|
)
|
|
552
593
|
|
|
553
594
|
const valid = await spendTx.verify(chain)
|
|
554
|
-
|
|
595
|
+
|
|
555
596
|
expect(valid).toBe(true)
|
|
556
597
|
|
|
557
598
|
const b = spendTx.toBinary()
|
|
@@ -375,7 +375,7 @@ export default class MerklePath {
|
|
|
375
375
|
if (this.indexOf(txid) === 0) {
|
|
376
376
|
// Coinbase transaction outputs can only be spent once they're 100 blocks deep.
|
|
377
377
|
const height = await chainTracker.currentHeight()
|
|
378
|
-
if (this.blockHeight + 100
|
|
378
|
+
if (this.blockHeight + 100 > height) {
|
|
379
379
|
return false
|
|
380
380
|
}
|
|
381
381
|
}
|
|
@@ -15,6 +15,23 @@ import MerklePath from '../../transaction/MerklePath'
|
|
|
15
15
|
import { BEEF_V1 } from '../../transaction/Beef'
|
|
16
16
|
import SatoshisPerKilobyte from '../../transaction/fee-models/SatoshisPerKilobyte'
|
|
17
17
|
|
|
18
|
+
// Default Transaction.fee() resolves to LivePolicy.getInstance(), which fetches the live ARC
|
|
19
|
+
// policy endpoint. Replace it with a deterministic 100 sat/kb model so tests never hit the
|
|
20
|
+
// network — the live endpoint is unreliable and not part of what these tests exercise.
|
|
21
|
+
jest.mock('../../transaction/fee-models/LivePolicy', () => {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
23
|
+
const SPKB = require('../../transaction/fee-models/SatoshisPerKilobyte').default
|
|
24
|
+
class MockLivePolicy extends SPKB {
|
|
25
|
+
static instance: MockLivePolicy | null = null
|
|
26
|
+
constructor () { super(100) }
|
|
27
|
+
static getInstance (): MockLivePolicy {
|
|
28
|
+
if (!MockLivePolicy.instance) MockLivePolicy.instance = new MockLivePolicy()
|
|
29
|
+
return MockLivePolicy.instance
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { __esModule: true, default: MockLivePolicy }
|
|
33
|
+
})
|
|
34
|
+
|
|
18
35
|
import sighashVectors from '../../primitives/__tests/sighash.vectors'
|
|
19
36
|
import invalidTransactions from './tx.invalid.vectors'
|
|
20
37
|
import validTransactions from './tx.valid.vectors'
|
|
@@ -412,8 +412,23 @@ export interface AbortActionArgs {
|
|
|
412
412
|
reference: Base64String
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
+
/**
|
|
416
|
+
* Result of an `abortAction` call.
|
|
417
|
+
*
|
|
418
|
+
* `aborted` is informative: `true` indicates the wallet successfully invalidated
|
|
419
|
+
* the action (it will not be broadcast and its inputs are released), `false`
|
|
420
|
+
* indicates the wallet refused to abort because the underlying transaction was
|
|
421
|
+
* found to already be on chain (mined or known to mempool). On a refusal the
|
|
422
|
+
* caller should typically invoke `internalizeAction` instead, which will treat
|
|
423
|
+
* the call as explicit authorization to advance the nosend lifecycle.
|
|
424
|
+
*
|
|
425
|
+
* Note that confirming on-chain status requires network reachability. When
|
|
426
|
+
* confirmation is impossible (services unreachable or returning errors), the
|
|
427
|
+
* wallet proceeds with the abort and returns `aborted: true` rather than
|
|
428
|
+
* refusing — refusal is reserved for positive on-chain confirmation.
|
|
429
|
+
*/
|
|
415
430
|
export interface AbortActionResult {
|
|
416
|
-
aborted:
|
|
431
|
+
aborted: boolean
|
|
417
432
|
}
|
|
418
433
|
|
|
419
434
|
export type AcquireCertificateResult = WalletCertificate
|
|
@@ -169,7 +169,7 @@ export default class WalletClient implements WalletInterface {
|
|
|
169
169
|
|
|
170
170
|
async abortAction (args: {
|
|
171
171
|
reference: Base64String
|
|
172
|
-
}): Promise<{ aborted:
|
|
172
|
+
}): Promise<{ aborted: boolean }> {
|
|
173
173
|
validateAbortActionArgs(args)
|
|
174
174
|
await this.connectToSubstrate()
|
|
175
175
|
return await (this.substrate as WalletInterface).abortAction(
|
|
@@ -130,7 +130,7 @@ export default class WindowCWISubstrate implements WalletInterface {
|
|
|
130
130
|
async abortAction(
|
|
131
131
|
args: { reference: Base64String },
|
|
132
132
|
originator?: OriginatorDomainNameStringUnder250Bytes
|
|
133
|
-
): Promise<{ aborted:
|
|
133
|
+
): Promise<{ aborted: boolean }> {
|
|
134
134
|
return await this.CWI.abortAction(args, originator)
|
|
135
135
|
}
|
|
136
136
|
|