@bsv/sdk 2.0.12 → 2.0.13

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.
Files changed (77) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/auth/clients/__tests__/AuthFetch.additional.test.js +827 -0
  3. package/dist/cjs/src/auth/clients/__tests__/AuthFetch.additional.test.js.map +1 -0
  4. package/dist/cjs/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.js +654 -0
  5. package/dist/cjs/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.js.map +1 -0
  6. package/dist/cjs/src/transaction/MerklePath.js +132 -0
  7. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  8. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  9. package/dist/esm/src/auth/clients/__tests__/AuthFetch.additional.test.js +825 -0
  10. package/dist/esm/src/auth/clients/__tests__/AuthFetch.additional.test.js.map +1 -0
  11. package/dist/esm/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.js +619 -0
  12. package/dist/esm/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.js.map +1 -0
  13. package/dist/esm/src/transaction/MerklePath.js +132 -0
  14. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  15. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  16. package/dist/types/src/auth/clients/__tests__/AuthFetch.additional.test.d.ts +21 -0
  17. package/dist/types/src/auth/clients/__tests__/AuthFetch.additional.test.d.ts.map +1 -0
  18. package/dist/types/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.d.ts +2 -0
  19. package/dist/types/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.d.ts.map +1 -0
  20. package/dist/types/src/transaction/MerklePath.d.ts +27 -0
  21. package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
  22. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  23. package/dist/umd/bundle.js +1 -1
  24. package/dist/umd/bundle.js.map +1 -1
  25. package/docs/reference/storage.md +1 -1
  26. package/docs/reference/transaction.md +40 -0
  27. package/package.json +1 -1
  28. package/src/auth/clients/__tests__/AuthFetch.additional.test.ts +1131 -0
  29. package/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.ts +770 -0
  30. package/src/compat/__tests/Mnemonic.additional.test.ts +64 -0
  31. package/src/identity/__tests/IdentityClient.additional.test.ts +767 -0
  32. package/src/kvstore/__tests/LocalKVStore.additional.test.ts +611 -0
  33. package/src/kvstore/__tests/kvStoreInterpreter.test.ts +327 -0
  34. package/src/overlay-tools/__tests/HostReputationTracker.additional.test.ts +561 -0
  35. package/src/overlay-tools/__tests/LookupResolver.additional.test.ts +612 -0
  36. package/src/overlay-tools/__tests/withDoubleSpendRetry.test.ts +278 -0
  37. package/src/primitives/__tests/BigNumber.additional.test.ts +79 -0
  38. package/src/primitives/__tests/Curve.additional.test.ts +208 -0
  39. package/src/primitives/__tests/ECDSA.additional.test.ts +122 -0
  40. package/src/primitives/__tests/Hash.additional.test.ts +59 -0
  41. package/src/primitives/__tests/JacobianPoint.test.ts +308 -0
  42. package/src/primitives/__tests/Point.additional.test.ts +503 -0
  43. package/src/primitives/__tests/PublicKey.additional.test.ts +383 -0
  44. package/src/primitives/__tests/Random.additional.test.ts +262 -0
  45. package/src/primitives/__tests/Signature.test.ts +333 -0
  46. package/src/primitives/__tests/TransactionSignature.additional.test.ts +241 -0
  47. package/src/registry/__tests/RegistryClient.additional.test.ts +750 -0
  48. package/src/remittance/__tests/BasicBRC29.additional.test.ts +657 -0
  49. package/src/remittance/__tests/RemittanceManager.additional.test.ts +1272 -0
  50. package/src/script/__tests/LockingUnlockingScript.test.ts +79 -0
  51. package/src/script/__tests/Script.additional.test.ts +100 -0
  52. package/src/script/__tests/ScriptEvaluationError.test.ts +98 -0
  53. package/src/script/__tests/Spend.additional.test.ts +837 -0
  54. package/src/script/templates/__tests/RPuzzle.test.ts +134 -0
  55. package/src/transaction/MerklePath.ts +155 -0
  56. package/src/transaction/__tests/BeefParty.additional.test.ts +22 -0
  57. package/src/transaction/__tests/Broadcaster.test.ts +159 -0
  58. package/src/transaction/__tests/MerklePath.bench.test.ts +105 -0
  59. package/src/transaction/__tests/MerklePath.test.ts +80 -0
  60. package/src/transaction/__tests/Transaction.additional.test.ts +225 -0
  61. package/src/transaction/broadcasters/__tests/ARC.additional.test.ts +585 -0
  62. package/src/transaction/broadcasters/__tests/Teranode.test.ts +349 -0
  63. package/src/transaction/chaintrackers/__tests/BlockHeadersService.test.ts +253 -0
  64. package/src/transaction/chaintrackers/__tests/DefaultChainTracker.test.ts +44 -0
  65. package/src/transaction/chaintrackers/__tests/WhatsOnChain.additional.test.ts +193 -0
  66. package/src/transaction/fee-models/__tests/SatoshisPerKilobyte.test.ts +262 -0
  67. package/src/transaction/http/__tests/BinaryFetchClient.test.ts +212 -0
  68. package/src/transaction/http/__tests/DefaultHttpClient.additional.test.ts +192 -0
  69. package/src/transaction/http/__tests/DefaultHttpClient.test.ts +71 -0
  70. package/src/wallet/__tests/ProtoWallet.additional.test.ts +134 -0
  71. package/src/wallet/__tests/WERR.test.ts +212 -0
  72. package/src/wallet/__tests/WalletClient.additional.test.ts +699 -0
  73. package/src/wallet/__tests/WalletClient.substrate.test.ts +759 -0
  74. package/src/wallet/__tests/WalletError.test.ts +290 -0
  75. package/src/wallet/__tests/validationHelpers.test.ts +1218 -0
  76. package/src/wallet/substrates/__tests/HTTPWalletJSON.test.ts +496 -0
  77. package/src/wallet/substrates/__tests/HTTPWalletWire.test.ts +273 -0
@@ -0,0 +1,79 @@
1
+ import LockingScript from '../../script/LockingScript'
2
+ import UnlockingScript from '../../script/UnlockingScript'
3
+ import Script from '../../script/Script'
4
+
5
+ describe('LockingScript', () => {
6
+ it('isLockingScript() returns true', () => {
7
+ const script = new LockingScript()
8
+ expect(script.isLockingScript()).toBe(true)
9
+ })
10
+
11
+ it('isUnlockingScript() returns false', () => {
12
+ const script = new LockingScript()
13
+ expect(script.isUnlockingScript()).toBe(false)
14
+ })
15
+
16
+ it('extends Script', () => {
17
+ const script = new LockingScript()
18
+ expect(script).toBeInstanceOf(Script)
19
+ })
20
+
21
+ it('can be constructed from hex via inherited fromHex', () => {
22
+ const hex = '76a914' + '00'.repeat(20) + '88ac'
23
+ const script = Script.fromHex(hex)
24
+ const locking = new LockingScript()
25
+ locking.chunks = script.chunks
26
+ expect(locking.toHex()).toBe(hex)
27
+ expect(locking.isLockingScript()).toBe(true)
28
+ })
29
+
30
+ it('fromHex returns a Script instance that can be used to populate a LockingScript', () => {
31
+ const hex = '51' // OP_1
32
+ const base = Script.fromHex(hex)
33
+ expect(base.toHex()).toBe(hex)
34
+ })
35
+ })
36
+
37
+ describe('UnlockingScript', () => {
38
+ it('isLockingScript() returns false', () => {
39
+ const script = new UnlockingScript()
40
+ expect(script.isLockingScript()).toBe(false)
41
+ })
42
+
43
+ it('isUnlockingScript() returns true', () => {
44
+ const script = new UnlockingScript()
45
+ expect(script.isUnlockingScript()).toBe(true)
46
+ })
47
+
48
+ it('extends Script', () => {
49
+ const script = new UnlockingScript()
50
+ expect(script).toBeInstanceOf(Script)
51
+ })
52
+
53
+ it('can be constructed from hex via inherited fromHex', () => {
54
+ const hex = '4830450221'
55
+ const script = Script.fromHex(hex)
56
+ const unlocking = new UnlockingScript()
57
+ unlocking.chunks = script.chunks
58
+ expect(unlocking.isUnlockingScript()).toBe(true)
59
+ })
60
+ })
61
+
62
+ describe('LockingScript vs UnlockingScript', () => {
63
+ it('LockingScript and UnlockingScript return opposite values for isLockingScript', () => {
64
+ const locking = new LockingScript()
65
+ const unlocking = new UnlockingScript()
66
+ expect(locking.isLockingScript()).not.toBe(unlocking.isLockingScript())
67
+ })
68
+
69
+ it('LockingScript and UnlockingScript return opposite values for isUnlockingScript', () => {
70
+ const locking = new LockingScript()
71
+ const unlocking = new UnlockingScript()
72
+ expect(locking.isUnlockingScript()).not.toBe(unlocking.isUnlockingScript())
73
+ })
74
+
75
+ it('both are instances of Script', () => {
76
+ expect(new LockingScript()).toBeInstanceOf(Script)
77
+ expect(new UnlockingScript()).toBeInstanceOf(Script)
78
+ })
79
+ })
@@ -0,0 +1,100 @@
1
+ import Script from '../Script'
2
+ import OP from '../OP'
3
+ import BigNumber from '../../primitives/BigNumber'
4
+
5
+ describe('Script – additional coverage', () => {
6
+ describe('fromHex', () => {
7
+ it('throws for odd-length hex string', () => {
8
+ expect(() => Script.fromHex('abc')).toThrow()
9
+ })
10
+
11
+ it('throws for non-hex characters', () => {
12
+ expect(() => Script.fromHex('gggg')).toThrow()
13
+ })
14
+ })
15
+
16
+ describe('isLockingScript / isUnlockingScript on base Script', () => {
17
+ it('throws NotImplemented for isLockingScript', () => {
18
+ const script = new Script()
19
+ expect(() => script.isLockingScript()).toThrow('Not implemented')
20
+ })
21
+
22
+ it('throws NotImplemented for isUnlockingScript', () => {
23
+ const script = new Script()
24
+ expect(() => script.isUnlockingScript()).toThrow('Not implemented')
25
+ })
26
+ })
27
+
28
+ describe('writeScript', () => {
29
+ it('appends all chunks from another script', () => {
30
+ const s1 = Script.fromASM('OP_1 OP_2')
31
+ const s2 = Script.fromASM('OP_3')
32
+ s1.writeScript(s2)
33
+ expect(s1.toASM()).toBe('OP_1 OP_2 OP_3')
34
+ })
35
+ })
36
+
37
+ describe('setChunkOpCode', () => {
38
+ it('replaces the opcode at the given index', () => {
39
+ const script = Script.fromASM('OP_1 OP_2 OP_3')
40
+ script.setChunkOpCode(1, OP.OP_NOP)
41
+ expect(script.chunks[1].op).toBe(OP.OP_NOP)
42
+ })
43
+ })
44
+
45
+ describe('writeBn', () => {
46
+ it('pushes OP_0 for zero', () => {
47
+ const script = new Script().writeBn(new BigNumber(0))
48
+ expect(script.chunks[0].op).toBe(OP.OP_0)
49
+ })
50
+
51
+ it('pushes OP_1NEGATE for -1', () => {
52
+ const script = new Script().writeBn(new BigNumber(-1))
53
+ expect(script.chunks[0].op).toBe(OP.OP_1NEGATE)
54
+ })
55
+
56
+ it('pushes OP_1..OP_16 for 1..16', () => {
57
+ for (let n = 1; n <= 16; n++) {
58
+ const script = new Script().writeBn(new BigNumber(n))
59
+ expect(script.chunks[0].op).toBe(OP.OP_1 + (n - 1))
60
+ }
61
+ })
62
+
63
+ it('pushes encoded binary for numbers > 16', () => {
64
+ const script = new Script().writeBn(new BigNumber(1000))
65
+ expect(script.chunks[0].data).toBeDefined()
66
+ })
67
+ })
68
+
69
+ describe('writeNumber', () => {
70
+ it('writes a number to the script', () => {
71
+ const script = new Script().writeNumber(5)
72
+ expect(script.chunks[0].op).toBe(OP.OP_5)
73
+ })
74
+ })
75
+
76
+ describe('writeBin', () => {
77
+ it('uses OP_PUSHDATA1 for data 76..255 bytes', () => {
78
+ const data = new Array(76).fill(0x01)
79
+ const script = new Script().writeBin(data)
80
+ expect(script.chunks[0].op).toBe(OP.OP_PUSHDATA1)
81
+ })
82
+
83
+ it('uses OP_PUSHDATA2 for data 256..65535 bytes', () => {
84
+ const data = new Array(256).fill(0x02)
85
+ const script = new Script().writeBin(data)
86
+ expect(script.chunks[0].op).toBe(OP.OP_PUSHDATA2)
87
+ })
88
+ })
89
+
90
+ describe('findAndDelete – PUSHDATA1 target', () => {
91
+ it('deletes chunks encoded with OP_PUSHDATA1 (76-255 bytes)', () => {
92
+ const data = new Array(76).fill(0xab)
93
+ const target = new Script().writeBin(data)
94
+ const source = new Script().writeBin(data).writeBin(data).writeOpCode(OP.OP_1)
95
+ source.findAndDelete(target)
96
+ expect(source.chunks).toHaveLength(1)
97
+ expect(source.chunks[0].op).toBe(OP.OP_1)
98
+ })
99
+ })
100
+ })
@@ -0,0 +1,98 @@
1
+ import ScriptEvaluationError from '../ScriptEvaluationError'
2
+
3
+ const baseParams = {
4
+ message: 'test error',
5
+ txid: 'a'.repeat(64),
6
+ outputIndex: 0,
7
+ context: 'LockingScript' as const,
8
+ programCounter: 3,
9
+ stackState: [] as number[][],
10
+ altStackState: [] as number[][],
11
+ ifStackState: [] as boolean[],
12
+ stackMem: 0,
13
+ altStackMem: 0
14
+ }
15
+
16
+ describe('ScriptEvaluationError', () => {
17
+ it('constructs with empty stacks', () => {
18
+ const err = new ScriptEvaluationError(baseParams)
19
+ expect(err).toBeInstanceOf(Error)
20
+ expect(err.message).toContain('test error')
21
+ expect(err.txid).toBe('a'.repeat(64))
22
+ expect(err.outputIndex).toBe(0)
23
+ expect(err.context).toBe('LockingScript')
24
+ expect(err.programCounter).toBe(3)
25
+ })
26
+
27
+ it('renders valid stack items as hex in the message (toHex branch)', () => {
28
+ const err = new ScriptEvaluationError({
29
+ ...baseParams,
30
+ stackState: [[0xde, 0xad], [0xbe, 0xef]],
31
+ altStackState: [[0x01]]
32
+ })
33
+ expect(err.message).toContain('dead')
34
+ expect(err.message).toContain('beef')
35
+ expect(err.message).toContain('01')
36
+ })
37
+
38
+ it('renders null stack item as null/undef (null/undef branch)', () => {
39
+ // The message is built before the deep-copy, so null/undef branch is executed
40
+ // even though the constructor later throws when trying to slice null.
41
+ expect(() => {
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ return new ScriptEvaluationError({ ...baseParams, stackState: [null as any] })
44
+ }).toThrow()
45
+ })
46
+
47
+ it('renders undefined stack item as null/undef (undefined branch)', () => {
48
+ expect(() => {
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ return new ScriptEvaluationError({ ...baseParams, stackState: [undefined as any] })
51
+ }).toThrow()
52
+ })
53
+
54
+ it('renders non-array stack item as INVALID_STACK_ITEM', () => {
55
+ expect(() => {
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ return new ScriptEvaluationError({ ...baseParams, stackState: [{ notAnArray: true } as any] })
58
+ }).toThrow()
59
+ })
60
+
61
+ it('renders null alt-stack item as null/undef (covers altStack map branches)', () => {
62
+ expect(() => {
63
+ return new ScriptEvaluationError({
64
+ ...baseParams,
65
+ stackState: [[0x01]],
66
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ altStackState: [null as any]
68
+ })
69
+ }).toThrow()
70
+ })
71
+
72
+ it('includes ifStack entries in the message', () => {
73
+ const err = new ScriptEvaluationError({
74
+ ...baseParams,
75
+ ifStackState: [true, false]
76
+ })
77
+ expect(err.message).toContain('true, false')
78
+ })
79
+
80
+ it('includes UnlockingScript context in the message', () => {
81
+ const err = new ScriptEvaluationError({
82
+ ...baseParams,
83
+ context: 'UnlockingScript'
84
+ })
85
+ expect(err.message).toContain('UnlockingScript')
86
+ })
87
+
88
+ it('deep-copies stackState and altStackState to prevent mutation', () => {
89
+ const originalStack = [[1, 2, 3]]
90
+ const err = new ScriptEvaluationError({
91
+ ...baseParams,
92
+ stackState: originalStack
93
+ })
94
+ // Mutate original — error should keep its own copy
95
+ originalStack[0].push(4)
96
+ expect(err.stackState[0]).toHaveLength(3)
97
+ })
98
+ })