@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,59 @@
1
+ import { SHA1HMAC, SHA512HMAC, pbkdf2 } from '../../primitives/Hash'
2
+
3
+ describe('Hash – additional coverage', () => {
4
+ describe('SHA1HMAC', () => {
5
+ it('produces a correct HMAC-SHA1 digest', () => {
6
+ // SHA1HMAC constructor calls toArray(key, 'hex'), so key must be hex
7
+ const hmac = new SHA1HMAC('deadbeef')
8
+ const result = hmac.update('abcd', 'hex').digest()
9
+ expect(result).toHaveLength(20)
10
+ })
11
+
12
+ it('returns a hex string from digestHex()', () => {
13
+ const hmac = new SHA1HMAC('deadbeef')
14
+ const result = hmac.update('deadbeef', 'hex').digestHex()
15
+ expect(typeof result).toBe('string')
16
+ expect(result).toHaveLength(40) // SHA1 = 20 bytes = 40 hex chars
17
+ })
18
+
19
+ it('handles a key longer than 64 bytes (key hashed internally)', () => {
20
+ // Key longer than SHA1 blockSize (64 bytes) → key is SHA1-hashed.
21
+ // Each hex byte is 2 chars, so 65 bytes = 130 hex chars.
22
+ const longKey = 'ab'.repeat(65) // 65 bytes when decoded from hex
23
+ const hmac = new SHA1HMAC(longKey)
24
+ const result = hmac.update('deadbeef', 'hex').digest()
25
+ expect(result).toHaveLength(20)
26
+ })
27
+ })
28
+
29
+ describe('SHA512HMAC', () => {
30
+ it('produces a correct HMAC-SHA512 digest', () => {
31
+ // SHA512HMAC string key is treated as hex
32
+ const hmac = new SHA512HMAC('deadbeef')
33
+ const result = hmac.update('message').digest()
34
+ expect(result).toHaveLength(64) // SHA512 = 64 bytes
35
+ })
36
+
37
+ it('returns a hex string from digestHex()', () => {
38
+ const hmac = new SHA512HMAC('deadbeef')
39
+ const result = hmac.update(new Uint8Array([1, 2, 3])).digestHex()
40
+ expect(typeof result).toBe('string')
41
+ expect(result).toHaveLength(128) // SHA512 = 64 bytes = 128 hex chars
42
+ })
43
+
44
+ it('accepts a Uint8Array key', () => {
45
+ const key = new Uint8Array([1, 2, 3, 4])
46
+ const hmac = new SHA512HMAC(key)
47
+ const result = hmac.update(new Uint8Array([5, 6, 7])).digest()
48
+ expect(result).toHaveLength(64)
49
+ })
50
+ })
51
+
52
+ describe('pbkdf2', () => {
53
+ it('throws when digest is not sha512', () => {
54
+ expect(() => pbkdf2([1, 2, 3], [4, 5, 6], 1, 32, 'sha256')).toThrow(
55
+ 'Only sha512 is supported in this PBKDF2 implementation'
56
+ )
57
+ })
58
+ })
59
+ })
@@ -0,0 +1,308 @@
1
+ import Curve from '../../primitives/Curve'
2
+ import Point from '../../primitives/Point'
3
+ import JacobianPoint from '../../primitives/JacobianPoint'
4
+ import BigNumber from '../../primitives/BigNumber'
5
+
6
+ const G_COMPRESSED = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'
7
+
8
+ describe('JacobianPoint', () => {
9
+ const curve = new Curve()
10
+ const G = curve.g as Point
11
+
12
+ // --------------------------------------------------------------------------
13
+ // Constructor
14
+ // --------------------------------------------------------------------------
15
+ describe('constructor', () => {
16
+ it('creates point at infinity when all null', () => {
17
+ const jp = new JacobianPoint(null, null, null)
18
+ expect(jp.isInfinity()).toBe(true)
19
+ })
20
+
21
+ it('creates point from string coordinates', () => {
22
+ // Use coordinates of 2G in affine form
23
+ const g2 = G.mul(new BigNumber(2))
24
+ const xHex = g2.getX().toString(16)
25
+ const yHex = g2.getY().toString(16)
26
+ const jp = new JacobianPoint(xHex, yHex, '1')
27
+ expect(jp.isInfinity()).toBe(false)
28
+ })
29
+
30
+ it('creates point from BigNumber coordinates', () => {
31
+ const g2 = G.mul(new BigNumber(2))
32
+ const xBN = g2.getX()
33
+ const yBN = g2.getY()
34
+ const jp = new JacobianPoint(xBN, yBN, curve.one)
35
+ expect(jp.isInfinity()).toBe(false)
36
+ })
37
+ })
38
+
39
+ // --------------------------------------------------------------------------
40
+ // isInfinity
41
+ // --------------------------------------------------------------------------
42
+ describe('isInfinity', () => {
43
+ it('returns true for point at infinity', () => {
44
+ const jp = new JacobianPoint(null, null, null)
45
+ expect(jp.isInfinity()).toBe(true)
46
+ })
47
+
48
+ it('returns false for valid point', () => {
49
+ const g = Point.fromString(G_COMPRESSED)
50
+ const jp = g.toJ()
51
+ expect(jp.isInfinity()).toBe(false)
52
+ })
53
+ })
54
+
55
+ // --------------------------------------------------------------------------
56
+ // toP
57
+ // --------------------------------------------------------------------------
58
+ describe('toP', () => {
59
+ it('toP of infinity gives affine infinity', () => {
60
+ const jp = new JacobianPoint(null, null, null)
61
+ const p = jp.toP()
62
+ expect(p.isInfinity()).toBe(true)
63
+ })
64
+
65
+ it('toP round-trips from affine', () => {
66
+ const g = Point.fromString(G_COMPRESSED)
67
+ const jp = g.toJ()
68
+ const restored = jp.toP()
69
+ expect(restored.eq(g)).toBe(true)
70
+ })
71
+ })
72
+
73
+ // --------------------------------------------------------------------------
74
+ // neg
75
+ // --------------------------------------------------------------------------
76
+ describe('neg', () => {
77
+ it('neg of a JacobianPoint', () => {
78
+ const g = Point.fromString(G_COMPRESSED)
79
+ const jp = g.toJ()
80
+ const negJp = jp.neg()
81
+ // jp + neg(jp) should be infinity
82
+ expect(jp.add(negJp).isInfinity()).toBe(true)
83
+ })
84
+ })
85
+
86
+ // --------------------------------------------------------------------------
87
+ // add
88
+ // --------------------------------------------------------------------------
89
+ describe('add', () => {
90
+ it('O + P = P (this is infinity)', () => {
91
+ const inf = new JacobianPoint(null, null, null)
92
+ const g = Point.fromString(G_COMPRESSED).toJ()
93
+ const result = inf.add(g)
94
+ expect(result.toP().eq(g.toP())).toBe(true)
95
+ })
96
+
97
+ it('P + O = P (argument is infinity)', () => {
98
+ const inf = new JacobianPoint(null, null, null)
99
+ const g = Point.fromString(G_COMPRESSED).toJ()
100
+ const result = g.add(inf)
101
+ expect(result.toP().eq(g.toP())).toBe(true)
102
+ })
103
+
104
+ it('P + (-P) = O', () => {
105
+ const g = Point.fromString(G_COMPRESSED).toJ()
106
+ const negG = g.neg()
107
+ const result = g.add(negG)
108
+ expect(result.isInfinity()).toBe(true)
109
+ })
110
+
111
+ it('P + P = 2P (via dbl)', () => {
112
+ const g = Point.fromString(G_COMPRESSED).toJ()
113
+ const g2 = g.dbl()
114
+ const result = g.add(g)
115
+ expect(result.toP().eq(g2.toP())).toBe(true)
116
+ })
117
+
118
+ it('P + Q = expected result', () => {
119
+ const g1 = G.mul(new BigNumber(3)).toJ()
120
+ const g2 = G.mul(new BigNumber(5)).toJ()
121
+ const expected = G.mul(new BigNumber(8))
122
+ const result = g1.add(g2)
123
+ expect(result.toP().eq(expected)).toBe(true)
124
+ })
125
+ })
126
+
127
+ // --------------------------------------------------------------------------
128
+ // mixedAdd
129
+ // --------------------------------------------------------------------------
130
+ describe('mixedAdd', () => {
131
+ it('O + P = P (this is infinity)', () => {
132
+ const inf = new JacobianPoint(null, null, null)
133
+ const g = Point.fromString(G_COMPRESSED)
134
+ const result = inf.mixedAdd(g)
135
+ expect(result.toP().eq(g)).toBe(true)
136
+ })
137
+
138
+ it('P + O = P (argument is infinity)', () => {
139
+ const g = Point.fromString(G_COMPRESSED).toJ()
140
+ const inf = new Point(null, null)
141
+ const result = g.mixedAdd(inf)
142
+ expect(result.toP().eq(g.toP())).toBe(true)
143
+ })
144
+
145
+ it('P + Q (mixed) = expected', () => {
146
+ const g3 = G.mul(new BigNumber(3)).toJ()
147
+ const g5 = G.mul(new BigNumber(5))
148
+ const expected = G.mul(new BigNumber(8))
149
+ const result = g3.mixedAdd(g5)
150
+ expect(result.toP().eq(expected)).toBe(true)
151
+ })
152
+
153
+ it('P + P (same point) via mixedAdd triggers dbl path', () => {
154
+ const g = Point.fromString(G_COMPRESSED)
155
+ const gJ = g.toJ()
156
+ const result = gJ.mixedAdd(g)
157
+ const expected = g.mul(new BigNumber(2))
158
+ expect(result.toP().eq(expected)).toBe(true)
159
+ })
160
+
161
+ it('mixedAdd P + (-P) = O', () => {
162
+ const g = Point.fromString(G_COMPRESSED)
163
+ const gJ = g.toJ()
164
+ const negG = g.neg()
165
+ const result = gJ.mixedAdd(negG)
166
+ expect(result.isInfinity()).toBe(true)
167
+ })
168
+
169
+ it('throws when point coordinates are null (non-infinity with null x/y)', () => {
170
+ const g = Point.fromString(G_COMPRESSED).toJ()
171
+ // Construct a Point-like object that is not infinity but has null x
172
+ const badPoint = { x: null, y: null, inf: false, isInfinity: () => false, type: 'affine' } as unknown as Point
173
+ expect(() => g.mixedAdd(badPoint)).toThrow('Point coordinates cannot be null')
174
+ })
175
+ })
176
+
177
+ // --------------------------------------------------------------------------
178
+ // dbl
179
+ // --------------------------------------------------------------------------
180
+ describe('dbl', () => {
181
+ it('dbl of infinity is infinity', () => {
182
+ const jp = new JacobianPoint(null, null, null)
183
+ const result = jp.dbl()
184
+ expect(result.isInfinity()).toBe(true)
185
+ })
186
+
187
+ it('dbl with zOne=true path', () => {
188
+ // When a point is created with z=1, the zOne shortcut is used in dbl
189
+ const g = Point.fromString(G_COMPRESSED).toJ()
190
+ // zOne should be true since toJ sets z=curve.one
191
+ const result = g.dbl()
192
+ const expected = G.mul(new BigNumber(2))
193
+ expect(result.toP().eq(expected)).toBe(true)
194
+ })
195
+
196
+ it('dbl with zOne=false path', () => {
197
+ // Get a JacobianPoint where z !== curve.one (e.g. after an add)
198
+ const g3 = G.mul(new BigNumber(3)).toJ()
199
+ const g5 = G.mul(new BigNumber(5)).toJ()
200
+ const sum = g3.add(g5) // z will not be one after arbitrary add
201
+ const doubled = sum.dbl()
202
+ const expected = G.mul(new BigNumber(16))
203
+ expect(doubled.toP().eq(expected)).toBe(true)
204
+ })
205
+ })
206
+
207
+ // --------------------------------------------------------------------------
208
+ // dblp
209
+ // --------------------------------------------------------------------------
210
+ describe('dblp', () => {
211
+ it('dblp with pow=0 returns this', () => {
212
+ const g = Point.fromString(G_COMPRESSED).toJ()
213
+ const result = g.dblp(0)
214
+ expect(result.toP().eq(g.toP())).toBe(true)
215
+ })
216
+
217
+ it('dblp of infinity is infinity', () => {
218
+ const inf = new JacobianPoint(null, null, null)
219
+ const result = inf.dblp(3)
220
+ expect(result.isInfinity()).toBe(true)
221
+ })
222
+
223
+ it('dblp with pow=3 equals three doublings', () => {
224
+ const g = Point.fromString(G_COMPRESSED).toJ()
225
+ const expected = G.mul(new BigNumber(8)) // 2^3 * 1 = 8
226
+ const result = g.dblp(3)
227
+ expect(result.toP().eq(expected)).toBe(true)
228
+ })
229
+ })
230
+
231
+ // --------------------------------------------------------------------------
232
+ // eq
233
+ // --------------------------------------------------------------------------
234
+ describe('eq', () => {
235
+ it('same instance is equal', () => {
236
+ const jp = Point.fromString(G_COMPRESSED).toJ()
237
+ expect(jp.eq(jp)).toBe(true)
238
+ })
239
+
240
+ it('equal points with different z', () => {
241
+ // Two different representations of the same affine point
242
+ const g = Point.fromString(G_COMPRESSED)
243
+ const jp1 = g.toJ()
244
+ const jp2 = g.toJ()
245
+ expect(jp1.eq(jp2)).toBe(true)
246
+ })
247
+
248
+ it('different points are not equal', () => {
249
+ const jp1 = G.mul(new BigNumber(3)).toJ()
250
+ const jp2 = G.mul(new BigNumber(5)).toJ()
251
+ expect(jp1.eq(jp2)).toBe(false)
252
+ })
253
+
254
+ it('infinity equals infinity', () => {
255
+ const inf1 = new JacobianPoint(null, null, null)
256
+ const inf2 = new JacobianPoint(null, null, null)
257
+ expect(inf1.eq(inf2)).toBe(true)
258
+ })
259
+
260
+ it('infinity != non-infinity', () => {
261
+ const inf = new JacobianPoint(null, null, null)
262
+ const g = Point.fromString(G_COMPRESSED).toJ()
263
+ expect(inf.eq(g)).toBe(false)
264
+ })
265
+
266
+ it('eq with an affine Point argument', () => {
267
+ const g = Point.fromString(G_COMPRESSED)
268
+ const jp = g.toJ()
269
+ expect(jp.eq(g)).toBe(true)
270
+ })
271
+ })
272
+
273
+ // --------------------------------------------------------------------------
274
+ // eqXToP
275
+ // --------------------------------------------------------------------------
276
+ describe('eqXToP', () => {
277
+ it('returns true when x matches', () => {
278
+ const g = Point.fromString(G_COMPRESSED)
279
+ const jp = g.toJ()
280
+ expect(jp.eqXToP(g.getX())).toBe(true)
281
+ })
282
+
283
+ it('returns false when x does not match', () => {
284
+ const g = Point.fromString(G_COMPRESSED)
285
+ const jp = g.toJ()
286
+ const wrongX = g.getX().addn(1)
287
+ expect(jp.eqXToP(wrongX)).toBe(false)
288
+ })
289
+ })
290
+
291
+ // --------------------------------------------------------------------------
292
+ // inspect
293
+ // --------------------------------------------------------------------------
294
+ describe('inspect', () => {
295
+ it('returns <EC JPoint Infinity> for infinity', () => {
296
+ const jp = new JacobianPoint(null, null, null)
297
+ expect(jp.inspect()).toBe('<EC JPoint Infinity>')
298
+ })
299
+
300
+ it('returns readable string for a valid point', () => {
301
+ const g = Point.fromString(G_COMPRESSED).toJ()
302
+ const s = g.inspect()
303
+ expect(s).toContain('<EC JPoint x:')
304
+ expect(s).toContain('y:')
305
+ expect(s).toContain('z:')
306
+ })
307
+ })
308
+ })