@bsv/sdk 1.1.22 → 1.1.24

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 (78) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/compat/BSM.js +10 -3
  3. package/dist/cjs/src/compat/BSM.js.map +1 -1
  4. package/dist/cjs/src/primitives/Curve.js +7 -7
  5. package/dist/cjs/src/primitives/Curve.js.map +1 -1
  6. package/dist/cjs/src/primitives/ECDSA.js +394 -71
  7. package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
  8. package/dist/cjs/src/primitives/Point.js +103 -23
  9. package/dist/cjs/src/primitives/Point.js.map +1 -1
  10. package/dist/cjs/src/primitives/TransactionSignature.js +4 -3
  11. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  12. package/dist/cjs/src/primitives/utils.js +53 -16
  13. package/dist/cjs/src/primitives/utils.js.map +1 -1
  14. package/dist/cjs/src/script/Spend.js +6 -43
  15. package/dist/cjs/src/script/Spend.js.map +1 -1
  16. package/dist/cjs/src/script/templates/P2PKH.js +2 -2
  17. package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
  18. package/dist/cjs/src/script/templates/RPuzzle.js +2 -2
  19. package/dist/cjs/src/script/templates/RPuzzle.js.map +1 -1
  20. package/dist/cjs/src/transaction/Transaction.js +79 -65
  21. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  22. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  23. package/dist/esm/src/compat/BSM.js +10 -3
  24. package/dist/esm/src/compat/BSM.js.map +1 -1
  25. package/dist/esm/src/primitives/Curve.js +7 -7
  26. package/dist/esm/src/primitives/Curve.js.map +1 -1
  27. package/dist/esm/src/primitives/ECDSA.js +394 -71
  28. package/dist/esm/src/primitives/ECDSA.js.map +1 -1
  29. package/dist/esm/src/primitives/Point.js +103 -23
  30. package/dist/esm/src/primitives/Point.js.map +1 -1
  31. package/dist/esm/src/primitives/TransactionSignature.js +4 -3
  32. package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
  33. package/dist/esm/src/primitives/utils.js +51 -15
  34. package/dist/esm/src/primitives/utils.js.map +1 -1
  35. package/dist/esm/src/script/Spend.js +5 -42
  36. package/dist/esm/src/script/Spend.js.map +1 -1
  37. package/dist/esm/src/script/templates/P2PKH.js +2 -2
  38. package/dist/esm/src/script/templates/P2PKH.js.map +1 -1
  39. package/dist/esm/src/script/templates/RPuzzle.js +2 -2
  40. package/dist/esm/src/script/templates/RPuzzle.js.map +1 -1
  41. package/dist/esm/src/transaction/Transaction.js +79 -65
  42. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  43. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  44. package/dist/types/src/compat/BSM.d.ts +3 -2
  45. package/dist/types/src/compat/BSM.d.ts.map +1 -1
  46. package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
  47. package/dist/types/src/primitives/Point.d.ts +5 -0
  48. package/dist/types/src/primitives/Point.d.ts.map +1 -1
  49. package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
  50. package/dist/types/src/primitives/utils.d.ts +1 -0
  51. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  52. package/dist/types/src/script/Spend.d.ts.map +1 -1
  53. package/dist/types/src/script/templates/P2PKH.d.ts +1 -1
  54. package/dist/types/src/script/templates/P2PKH.d.ts.map +1 -1
  55. package/dist/types/src/script/templates/RPuzzle.d.ts +1 -1
  56. package/dist/types/src/script/templates/RPuzzle.d.ts.map +1 -1
  57. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  58. package/dist/types/src/transaction/TransactionInput.d.ts +1 -1
  59. package/dist/types/src/transaction/TransactionInput.d.ts.map +1 -1
  60. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  61. package/docs/compat.md +10 -4
  62. package/docs/primitives.md +48 -12
  63. package/docs/script.md +4 -4
  64. package/docs/transaction.md +2 -1
  65. package/package.json +1 -1
  66. package/src/compat/BSM.ts +10 -3
  67. package/src/compat/__tests/BSM.test.ts +7 -2
  68. package/src/primitives/Curve.ts +7 -7
  69. package/src/primitives/ECDSA.ts +485 -75
  70. package/src/primitives/Point.ts +110 -25
  71. package/src/primitives/TransactionSignature.ts +4 -3
  72. package/src/primitives/utils.ts +58 -11
  73. package/src/script/Spend.ts +5 -48
  74. package/src/script/templates/P2PKH.ts +7 -7
  75. package/src/script/templates/RPuzzle.ts +8 -8
  76. package/src/transaction/Transaction.ts +93 -68
  77. package/src/transaction/TransactionInput.ts +1 -1
  78. package/src/transaction/__tests/Transaction.benchmarks.test.ts +222 -0
@@ -0,0 +1,222 @@
1
+ // __tests__/transaction.benchmark.test.ts
2
+
3
+ import Transaction from '../../../dist/cjs/src/transaction/Transaction'
4
+ import PrivateKey from '../../../dist/cjs/src/primitives/PrivateKey'
5
+ import { hash160 } from '../../../dist/cjs/src/primitives/Hash'
6
+ import P2PKH from '../../../dist/cjs/src/script/templates/P2PKH'
7
+ import { jest } from '@jest/globals'
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 = hash160(publicKey.toDER())
24
+ const p2pkh = new P2PKH()
25
+
26
+ it('verifies a transaction with a deep input chain', async () => {
27
+ // Create a deep chain of transactions (e.g., depth of 100)
28
+ const depth = 100
29
+ let tx = new Transaction()
30
+ tx.addOutput({
31
+ lockingScript: p2pkh.lock(publicKeyHash),
32
+ satoshis: 100000
33
+ })
34
+ tx.merklePath = {
35
+ // Mock merkle path verification
36
+ blockHeight: 0,
37
+ merkleRoot: '',
38
+ hashes: [],
39
+ verify: async () => true,
40
+ toBinary: () => [],
41
+ computeRoot: () => ''
42
+ }
43
+
44
+ // Build the chain
45
+ for (let i = 0; i < depth; i++) {
46
+ const newTx = new Transaction()
47
+ newTx.addInput({
48
+ sourceTransaction: tx,
49
+ sourceOutputIndex: 0,
50
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
51
+ sequence: 0xffffffff
52
+ })
53
+ newTx.addOutput({
54
+ lockingScript: p2pkh.lock(publicKeyHash),
55
+ satoshis: 100000 - 1000 * (i + 1)
56
+ })
57
+ await newTx.sign()
58
+ tx = newTx
59
+ }
60
+
61
+ // Measure verification time
62
+ const timeTaken = await measureTime(async () => {
63
+ const verified = await tx.verify('scripts only')
64
+ expect(verified).toBe(true)
65
+ })
66
+ console.log(`Verification time for deep chain of depth ${depth}: ${timeTaken.toFixed(2)} ms`)
67
+ })
68
+
69
+ it('verifies a transaction with a wide input set', async () => {
70
+ // Create a transaction with many inputs (e.g., 100 inputs)
71
+ const inputCount = 100
72
+ const sourceTxs = []
73
+
74
+ // Create source transactions
75
+ for (let i = 0; i < inputCount; i++) {
76
+ const sourceTx = new Transaction()
77
+ sourceTx.addOutput({
78
+ lockingScript: p2pkh.lock(publicKeyHash),
79
+ satoshis: 1000
80
+ })
81
+ sourceTx.merklePath = {
82
+ blockHeight: 0,
83
+ merkleRoot: '',
84
+ hashes: [],
85
+ verify: async () => true,
86
+ toBinary: () => [],
87
+ computeRoot: () => ''
88
+ }
89
+ sourceTxs.push(sourceTx)
90
+ }
91
+
92
+ // Create transaction with many inputs
93
+ const tx = new Transaction()
94
+ for (let i = 0; i < inputCount; i++) {
95
+ tx.addInput({
96
+ sourceTransaction: sourceTxs[i],
97
+ sourceOutputIndex: 0,
98
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
99
+ sequence: 0xffffffff
100
+ })
101
+ }
102
+ tx.addOutput({
103
+ lockingScript: p2pkh.lock(publicKeyHash),
104
+ satoshis: inputCount * 1000 - 1000
105
+ })
106
+ await tx.sign()
107
+
108
+ // Measure verification time
109
+ const timeTaken = await measureTime(async () => {
110
+ const verified = await tx.verify('scripts only')
111
+ expect(verified).toBe(true)
112
+ })
113
+ console.log(`Verification time for wide transaction with ${inputCount} inputs: ${timeTaken.toFixed(2)} ms`)
114
+ })
115
+
116
+ it('verifies a large transaction with many inputs and outputs', async () => {
117
+ const inputCount = 50
118
+ const outputCount = 50
119
+ const sourceTxs = []
120
+
121
+ // Create source transactions
122
+ for (let i = 0; i < inputCount; i++) {
123
+ const sourceTx = new Transaction()
124
+ sourceTx.addOutput({
125
+ lockingScript: p2pkh.lock(publicKeyHash),
126
+ satoshis: 2000
127
+ })
128
+ sourceTx.merklePath = {
129
+ blockHeight: 0,
130
+ merkleRoot: '',
131
+ hashes: [],
132
+ verify: async () => true,
133
+ toBinary: () => [],
134
+ computeRoot: () => ''
135
+ }
136
+ sourceTxs.push(sourceTx)
137
+ }
138
+
139
+ // Create transaction with many inputs and outputs
140
+ const tx = new Transaction()
141
+ for (let i = 0; i < inputCount; i++) {
142
+ tx.addInput({
143
+ sourceTransaction: sourceTxs[i],
144
+ sourceOutputIndex: 0,
145
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
146
+ sequence: 0xffffffff
147
+ })
148
+ }
149
+ for (let i = 0; i < outputCount; i++) {
150
+ tx.addOutput({
151
+ lockingScript: p2pkh.lock(publicKeyHash),
152
+ satoshis: 1000
153
+ })
154
+ }
155
+ await tx.sign()
156
+
157
+ // Measure verification time
158
+ const timeTaken = await measureTime(async () => {
159
+ const verified = await tx.verify('scripts only')
160
+ expect(verified).toBe(true)
161
+ })
162
+ console.log(`Verification time for large transaction with ${inputCount} inputs and ${outputCount} outputs: ${timeTaken.toFixed(2)} ms`)
163
+ })
164
+
165
+ it('verifies a transaction with nested inputs (complex graph)', async () => {
166
+ // Create a transaction graph where inputs come from transactions with multiple inputs
167
+ const depth = 5
168
+ const fanOut = 3
169
+ let txs = []
170
+
171
+ // Create base transactions
172
+ for (let i = 0; i < fanOut; i++) {
173
+ const baseTx = new Transaction()
174
+ baseTx.addOutput({
175
+ lockingScript: p2pkh.lock(publicKeyHash),
176
+ satoshis: 100000
177
+ })
178
+ baseTx.merklePath = {
179
+ blockHeight: 0,
180
+ merkleRoot: '',
181
+ hashes: [],
182
+ verify: async () => true,
183
+ toBinary: () => [],
184
+ computeRoot: () => ''
185
+ }
186
+ txs.push(baseTx)
187
+ }
188
+
189
+ // Build the graph
190
+ for (let d = 0; d < depth; d++) {
191
+ const newTxs = []
192
+ for (const tx of txs) {
193
+ const newTx = new Transaction()
194
+ for (let i = 0; i < fanOut; i++) {
195
+ newTx.addInput({
196
+ sourceTransaction: tx,
197
+ sourceOutputIndex: 0,
198
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
199
+ sequence: 0xffffffff
200
+ })
201
+ }
202
+ newTx.addOutput({
203
+ lockingScript: p2pkh.lock(publicKeyHash),
204
+ satoshis: tx.outputs[0].satoshis - 1000 * fanOut
205
+ })
206
+ await newTx.sign()
207
+ newTxs.push(newTx)
208
+ }
209
+ txs = newTxs
210
+ }
211
+
212
+ // Take the last transaction for verification
213
+ const finalTx = txs[0]
214
+
215
+ // Measure verification time
216
+ const timeTaken = await measureTime(async () => {
217
+ const verified = await finalTx.verify('scripts only')
218
+ expect(verified).toBe(true)
219
+ })
220
+ console.log(`Verification time for nested inputs with depth ${depth} and fan-out ${fanOut}: ${timeTaken.toFixed(2)} ms`)
221
+ })
222
+ })