@bsv/sdk 1.5.3 → 1.6.1

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 (72) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/overlay-tools/LookupResolver.js +0 -4
  3. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  4. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +0 -2
  5. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  6. package/dist/cjs/src/primitives/AESGCM.js +113 -137
  7. package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
  8. package/dist/cjs/src/primitives/BigNumber.js +1019 -3947
  9. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  10. package/dist/cjs/src/primitives/K256.js +53 -37
  11. package/dist/cjs/src/primitives/K256.js.map +1 -1
  12. package/dist/cjs/src/primitives/Mersenne.js +16 -21
  13. package/dist/cjs/src/primitives/Mersenne.js.map +1 -1
  14. package/dist/cjs/src/primitives/MontgomoryMethod.js.map +1 -1
  15. package/dist/cjs/src/primitives/utils.js +27 -17
  16. package/dist/cjs/src/primitives/utils.js.map +1 -1
  17. package/dist/cjs/src/script/Spend.js +618 -858
  18. package/dist/cjs/src/script/Spend.js.map +1 -1
  19. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  20. package/dist/esm/src/overlay-tools/LookupResolver.js +0 -4
  21. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  22. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js +0 -2
  23. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  24. package/dist/esm/src/primitives/AESGCM.js +112 -137
  25. package/dist/esm/src/primitives/AESGCM.js.map +1 -1
  26. package/dist/esm/src/primitives/BigNumber.js +1011 -3969
  27. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  28. package/dist/esm/src/primitives/K256.js +53 -37
  29. package/dist/esm/src/primitives/K256.js.map +1 -1
  30. package/dist/esm/src/primitives/Mersenne.js +16 -21
  31. package/dist/esm/src/primitives/Mersenne.js.map +1 -1
  32. package/dist/esm/src/primitives/MontgomoryMethod.js.map +1 -1
  33. package/dist/esm/src/primitives/utils.js +29 -17
  34. package/dist/esm/src/primitives/utils.js.map +1 -1
  35. package/dist/esm/src/script/Spend.js +618 -857
  36. package/dist/esm/src/script/Spend.js.map +1 -1
  37. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  38. package/dist/types/src/overlay-tools/LookupResolver.d.ts +1 -3
  39. package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
  40. package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts +1 -0
  41. package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts.map +1 -1
  42. package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
  43. package/dist/types/src/primitives/BigNumber.d.ts +238 -1705
  44. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  45. package/dist/types/src/primitives/K256.d.ts.map +1 -1
  46. package/dist/types/src/primitives/Mersenne.d.ts +2 -2
  47. package/dist/types/src/primitives/Mersenne.d.ts.map +1 -1
  48. package/dist/types/src/primitives/utils.d.ts +2 -0
  49. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  50. package/dist/types/src/script/Spend.d.ts +11 -1
  51. package/dist/types/src/script/Spend.d.ts.map +1 -1
  52. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  53. package/dist/umd/bundle.js +1 -1
  54. package/docs/performance.md +70 -0
  55. package/docs/primitives.md +262 -3049
  56. package/package.json +1 -1
  57. package/src/auth/__tests/Peer.test.ts +38 -23
  58. package/src/auth/certificates/__tests/MasterCertificate.test.ts +27 -20
  59. package/src/auth/certificates/__tests/VerifiableCertificate.test.ts +24 -24
  60. package/src/overlay-tools/LookupResolver.ts +1 -9
  61. package/src/overlay-tools/SHIPBroadcaster.ts +1 -2
  62. package/src/overlay-tools/__tests/LookupResolver.test.ts +0 -112
  63. package/src/primitives/AESGCM.ts +118 -164
  64. package/src/primitives/BigNumber.ts +867 -4180
  65. package/src/primitives/K256.ts +57 -37
  66. package/src/primitives/Mersenne.ts +16 -20
  67. package/src/primitives/MontgomoryMethod.ts +2 -2
  68. package/src/primitives/__tests/ReductionContext.test.ts +6 -1
  69. package/src/primitives/utils.ts +28 -17
  70. package/src/script/Spend.ts +634 -1309
  71. package/src/transaction/__tests/Transaction.test.ts +14 -16
  72. package/src/transaction/__tests/Transaction.benchmarks.test.ts +0 -237
@@ -26,6 +26,9 @@ const BRC62Hex =
26
26
  const MerkleRootFromBEEF =
27
27
  'bb6f640cc4ee56bf38eb5a1969ac0c16caa2d3d202b22bf3735d10eec0ca6e00'
28
28
 
29
+ const testPrivateKey = new PrivateKey(11)
30
+ const testP2PKHScript = new P2PKH().lock(testPrivateKey.toPublicKey().toHash())
31
+
29
32
  describe('Transaction', () => {
30
33
  const txhex =
31
34
  '000000000100000000000000000000000000000000000000000000000000000000000000000000000001ae0000000001050000000000000001ae00000000'
@@ -713,19 +716,18 @@ describe('Transaction', () => {
713
716
  value: 10000
714
717
  }
715
718
  ]
716
- const priv = PrivateKey.fromRandom()
717
719
  const tx = new Transaction()
718
720
  utxos.forEach(utxo => {
719
721
  const u = {
720
722
  txid: utxo.tx_hash,
721
723
  vout: utxo.tx_pos,
722
- script: new P2PKH().lock(priv.toPublicKey().toHash()).toHex(),
724
+ script: testP2PKHScript.toHex(),
723
725
  satoshis: utxo.value
724
726
  }
725
- tx.addInput(fromUtxo(u, new P2PKH().unlock(priv)))
727
+ tx.addInput(fromUtxo(u, new P2PKH().unlock(testPrivateKey)))
726
728
  })
727
729
  tx.addOutput({
728
- lockingScript: new P2PKH().lock(priv.toAddress()),
730
+ lockingScript: testP2PKHScript,
729
731
  change: true
730
732
  })
731
733
  await tx.fee({ computeFee: async () => 10 })
@@ -1138,26 +1140,24 @@ describe('Transaction', () => {
1138
1140
 
1139
1141
  describe('addP2PKHOutput', () => {
1140
1142
  it('should create an output on the current transaction using an address hash or string', async () => {
1141
- const privateKey = PrivateKey.fromRandom()
1142
- const pubKeyHash = privateKey.toPublicKey().toHash()
1143
- const lockingScript = new P2PKH().lock(privateKey.toAddress())
1143
+ const pubKeyHash = testPrivateKey.toPublicKey().toHash()
1144
1144
  const tx = new Transaction()
1145
1145
  tx.addInput({
1146
1146
  sourceTXID: '00'.repeat(32),
1147
1147
  sourceOutputIndex: 0,
1148
- unlockingScriptTemplate: new P2PKH().unlock(privateKey)
1148
+ unlockingScriptTemplate: new P2PKH().unlock(testPrivateKey)
1149
1149
  })
1150
- tx.addP2PKHOutput(privateKey.toAddress(), 10000)
1150
+ tx.addP2PKHOutput(testPrivateKey.toAddress(), 10000)
1151
1151
  tx.addP2PKHOutput(pubKeyHash, 10000)
1152
1152
  expect(tx.outputs.length).toEqual(2)
1153
1153
  expect(tx.outputs[0].satoshis).toEqual(10000)
1154
1154
  expect(tx.outputs[1].satoshis).toEqual(10000)
1155
1155
  expect(
1156
- tx.outputs[0].lockingScript.toHex() === lockingScript.toHex()
1156
+ tx.outputs[0].lockingScript.toHex() === testP2PKHScript.toHex()
1157
1157
  ).toBeTruthy()
1158
1158
  expect(
1159
1159
  tx.outputs[0].lockingScript.toHex() === tx.outputs[1].lockingScript.toHex()
1160
- ).toBeTruthy()
1160
+ ).toBeTruthy()
1161
1161
  })
1162
1162
  })
1163
1163
  })
@@ -1290,13 +1290,11 @@ describe('Transaction', () => {
1290
1290
 
1291
1291
  describe('addP2PKHOutput', () => {
1292
1292
  it('should create an output on the current transaction using an address hash or string', async () => {
1293
- const privateKey = PrivateKey.fromRandom()
1294
- const lockingScript = new P2PKH().lock(privateKey.toAddress())
1295
1293
  const tx = new Transaction()
1296
1294
  tx.addInput({
1297
1295
  sourceTXID: '00'.repeat(32),
1298
1296
  sourceOutputIndex: 0,
1299
- unlockingScriptTemplate: new P2PKH().unlock(privateKey),
1297
+ unlockingScriptTemplate: new P2PKH().unlock(testPrivateKey),
1300
1298
  })
1301
1299
  })
1302
1300
  })
@@ -1311,7 +1309,7 @@ describe('Transaction', () => {
1311
1309
  })
1312
1310
  sourceTransaction.addOutput({
1313
1311
  satoshis: 2,
1314
- lockingScript: Script.fromASM('OP_2 OP_MUL ' + 'OP_DUP OP_MUL '.repeat(16) + 'OP_DROP'),
1312
+ lockingScript: Script.fromASM('OP_2 OP_MUL ' + 'OP_DUP OP_MUL '.repeat(22) + 'OP_DROP'),
1315
1313
  })
1316
1314
  await sourceTransaction.sign()
1317
1315
 
@@ -1336,7 +1334,7 @@ describe('Transaction', () => {
1336
1334
  await tx.sign()
1337
1335
 
1338
1336
  // default should be 100KB
1339
- await expect(tx.verify('scripts only', new SatoshisPerKilobyte(1))).rejects.toThrow('Stack memory usage has exceeded 100000 bytes')
1337
+ await expect(tx.verify('scripts only', new SatoshisPerKilobyte(1))).rejects.toThrow('Stack memory usage has exceeded 32000000 bytes')
1340
1338
  })
1341
1339
  })
1342
1340
 
@@ -1,237 +0,0 @@
1
- // __tests__/transaction.benchmark.test.ts
2
-
3
- import Transaction from '../../transaction/Transaction'
4
- import PrivateKey from '../../primitives/PrivateKey'
5
- import P2PKH from '../../script/templates/P2PKH'
6
- import { jest } from '@jest/globals'
7
- import MerklePath from '../MerklePath'
8
-
9
- jest.setTimeout(60000) // Increase timeout for benchmarking tests if necessary
10
-
11
- // Helper function to measure execution time
12
- async function measureTime(fn: () => Promise<void>): Promise<number> {
13
- const start = process.hrtime()
14
- await fn()
15
- const diff = process.hrtime(start)
16
- const timeInMs = diff[0] * 1000 + diff[1] / 1e6
17
- return timeInMs
18
- }
19
-
20
- describe('Transaction Verification Benchmark', () => {
21
- const privateKey = new PrivateKey(1)
22
- const publicKey = privateKey.toPublicKey()
23
- const publicKeyHash = publicKey.toHash()
24
- const p2pkh = new P2PKH()
25
-
26
- it('verifies a transaction with a deep input chain', async () => {
27
- const depth = 100
28
- let tx = new Transaction()
29
- tx.addOutput({
30
- lockingScript: p2pkh.lock(publicKeyHash),
31
- satoshis: 100000
32
- })
33
- const blockHeight = 1631619
34
- const txid = tx.hash('hex') as string
35
-
36
- const path = [
37
- [
38
- { offset: 0, hash: txid, txid: true, duplicate: false },
39
- { offset: 1, hash: 'otherHash1', txid: false, duplicate: false }
40
- ],
41
- [{ offset: 1, hash: 'mergedHash1', txid: false, duplicate: false }]
42
- ]
43
-
44
- const merklePath = new MerklePath(blockHeight, path)
45
-
46
- // Assign the MerklePath to the transaction
47
- tx.merklePath = merklePath
48
-
49
- for (let i = 1; i < depth + 1; i++) {
50
- const newTx = new Transaction()
51
- newTx.addInput({
52
- sourceTransaction: tx,
53
- sourceOutputIndex: 0,
54
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
55
- sequence: 0xffffffff
56
- })
57
- newTx.addOutput({
58
- lockingScript: p2pkh.lock(publicKeyHash),
59
- satoshis: 100000 - i * 10
60
- })
61
- await newTx.sign()
62
- tx = newTx
63
- }
64
- })
65
-
66
- it('verifies a transaction with a wide input set', async () => {
67
- // Create a transaction with many inputs (e.g., 100 inputs)
68
- const inputCount = 100
69
- const sourceTxs: Transaction[] = []
70
-
71
- // Create source transactions
72
- for (let i = 0; i < inputCount; i++) {
73
- const sourceTx = new Transaction()
74
- sourceTx.addOutput({
75
- lockingScript: p2pkh.lock(publicKeyHash),
76
- satoshis: 1000
77
- })
78
- const blockHeight = 1631619
79
- const txid = sourceTx.hash('hex') as string
80
- const path = [
81
- [
82
- { offset: 0, hash: txid, txid: true, duplicate: false },
83
- { offset: 1, hash: 'otherHash1', txid: false, duplicate: false }
84
- ],
85
- [{ offset: 1, hash: 'mergedHash1', txid: false, duplicate: false }]
86
- ]
87
-
88
- const merklePath = new MerklePath(blockHeight, path)
89
-
90
- // Assign the MerklePath to the transaction
91
- sourceTx.merklePath = merklePath
92
- sourceTxs.push(sourceTx)
93
- }
94
-
95
- // Create transaction with many inputs
96
- const tx = new Transaction()
97
- for (let i = 0; i < inputCount; i++) {
98
- tx.addInput({
99
- sourceTransaction: sourceTxs[i],
100
- sourceOutputIndex: 0,
101
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
102
- sequence: 0xffffffff
103
- })
104
- }
105
- tx.addOutput({
106
- lockingScript: p2pkh.lock(publicKeyHash),
107
- satoshis: inputCount * 1000 - 1000
108
- })
109
- await tx.sign()
110
-
111
- // Measure verification time
112
- const timeTaken = await measureTime(async () => {
113
- const verified = await tx.verify('scripts only')
114
- expect(verified).toBe(true)
115
- })
116
- })
117
-
118
- it('verifies a large transaction with many inputs and outputs', async () => {
119
- const inputCount = 50
120
- const outputCount = 50
121
- const sourceTxs: Transaction[] = []
122
-
123
- // Create source transactions
124
- for (let i = 0; i < inputCount; i++) {
125
- const sourceTx = new Transaction()
126
- sourceTx.addOutput({
127
- lockingScript: p2pkh.lock(publicKeyHash),
128
- satoshis: 2000
129
- })
130
- const blockHeight = 1631619
131
- const txid = sourceTx.hash('hex') as string
132
- const path = [
133
- [
134
- { offset: 0, hash: txid, txid: true, duplicate: false },
135
- { offset: 1, hash: 'otherHash1', txid: false, duplicate: false }
136
- ],
137
- [{ offset: 1, hash: 'mergedHash1', txid: false, duplicate: false }]
138
- ]
139
-
140
- const merklePath = new MerklePath(blockHeight, path)
141
-
142
- // Assign the MerklePath to the transaction
143
- sourceTx.merklePath = merklePath
144
- sourceTxs.push(sourceTx)
145
- }
146
-
147
- // Create transaction with many inputs and outputs
148
- const tx = new Transaction()
149
- for (let i = 0; i < inputCount; i++) {
150
- tx.addInput({
151
- sourceTransaction: sourceTxs[i],
152
- sourceOutputIndex: 0,
153
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
154
- sequence: 0xffffffff
155
- })
156
- }
157
- for (let i = 0; i < outputCount; i++) {
158
- tx.addOutput({
159
- lockingScript: p2pkh.lock(publicKeyHash),
160
- satoshis: 1000
161
- })
162
- }
163
- await tx.sign()
164
-
165
- // Measure verification time
166
- const timeTaken = await measureTime(async () => {
167
- const verified = await tx.verify('scripts only')
168
- expect(verified).toBe(true)
169
- })
170
- })
171
-
172
- it('verifies a transaction with nested inputs (complex graph)', async () => {
173
- // Create a transaction graph where inputs come from transactions with multiple inputs
174
- const depth = 5
175
- const fanOut = 3
176
- let txs: Transaction[] = []
177
-
178
- // Create base transactions
179
- for (let i = 0; i < fanOut; i++) {
180
- const baseTx = new Transaction()
181
- baseTx.addOutput({
182
- lockingScript: p2pkh.lock(publicKeyHash),
183
- satoshis: 100000
184
- })
185
- const blockHeight = 1631619
186
- const txid = baseTx.hash('hex') as string
187
- const path = [
188
- [
189
- { offset: 0, hash: txid, txid: true, duplicate: false },
190
- { offset: 1, hash: 'otherHash1', txid: false, duplicate: false }
191
- ],
192
- [{ offset: 1, hash: 'mergedHash1', txid: false, duplicate: false }]
193
- ]
194
-
195
- const merklePath = new MerklePath(blockHeight, path)
196
-
197
- // Assign the MerklePath to the transaction
198
- baseTx.merklePath = merklePath
199
- txs.push(baseTx)
200
- }
201
-
202
- // Build the graph
203
- for (let d = 0; d < depth; d++) {
204
- const newTxs: Transaction[] = [] // Ensure newTxs is properly typed
205
- for (const tx of txs) {
206
- const newTx = new Transaction()
207
- for (let i = 0; i < fanOut; i++) {
208
- newTx.addInput({
209
- sourceTransaction: tx,
210
- sourceOutputIndex: 0,
211
- unlockingScriptTemplate: p2pkh.unlock(privateKey),
212
- sequence: 0xffffffff
213
- })
214
- }
215
-
216
- // Ensure tx.outputs[0] exists before accessing satoshis
217
- newTx.addOutput({
218
- lockingScript: p2pkh.lock(publicKeyHash),
219
- satoshis: (tx.outputs[0]?.satoshis ?? 0) - 1000 * fanOut
220
- })
221
-
222
- await newTx.sign()
223
- newTxs.push(newTx)
224
- }
225
- txs = newTxs // Reassign txs with newly created transactions
226
- }
227
-
228
- // Take the last transaction for verification
229
- const finalTx = txs[0]
230
-
231
- // Measure verification time
232
- const timeTaken = await measureTime(async () => {
233
- const verified = await finalTx.verify('scripts only')
234
- expect(verified).toBe(true)
235
- })
236
- })
237
- })