@bsv/sdk 1.0.12 → 1.0.14

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 (119) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/compat/BSM.js.map +1 -1
  3. package/dist/cjs/src/compat/ECIES.js +105 -76
  4. package/dist/cjs/src/compat/ECIES.js.map +1 -1
  5. package/dist/cjs/src/compat/HD.js +65 -65
  6. package/dist/cjs/src/compat/HD.js.map +1 -1
  7. package/dist/cjs/src/compat/Mnemonic.js +79 -79
  8. package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
  9. package/dist/cjs/src/compat/bip-39-wordlist-en.js +2 -2
  10. package/dist/cjs/src/compat/bip-39-wordlist-en.js.map +1 -1
  11. package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
  12. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  13. package/dist/cjs/src/primitives/DRBG.js.map +1 -1
  14. package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
  15. package/dist/cjs/src/primitives/Hash.js +26 -13
  16. package/dist/cjs/src/primitives/Hash.js.map +1 -1
  17. package/dist/cjs/src/primitives/PrivateKey.js +3 -2
  18. package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
  19. package/dist/cjs/src/primitives/PublicKey.js +1 -2
  20. package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
  21. package/dist/cjs/src/primitives/Random.js +2 -2
  22. package/dist/cjs/src/primitives/Random.js.map +1 -1
  23. package/dist/cjs/src/primitives/Signature.js +141 -4
  24. package/dist/cjs/src/primitives/Signature.js.map +1 -1
  25. package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
  26. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  27. package/dist/cjs/src/primitives/utils.js +14 -9
  28. package/dist/cjs/src/primitives/utils.js.map +1 -1
  29. package/dist/cjs/src/script/Spend.js.map +1 -1
  30. package/dist/cjs/src/script/templates/P2PKH.js +1 -1
  31. package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
  32. package/dist/cjs/src/transaction/MerklePath.js +3 -3
  33. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  34. package/dist/cjs/src/transaction/Transaction.js +15 -4
  35. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  36. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  37. package/dist/esm/src/compat/BSM.js.map +1 -1
  38. package/dist/esm/src/compat/ECIES.js +105 -76
  39. package/dist/esm/src/compat/ECIES.js.map +1 -1
  40. package/dist/esm/src/compat/HD.js +65 -65
  41. package/dist/esm/src/compat/HD.js.map +1 -1
  42. package/dist/esm/src/compat/Mnemonic.js +79 -79
  43. package/dist/esm/src/compat/Mnemonic.js.map +1 -1
  44. package/dist/esm/src/compat/bip-39-wordlist-en.js +2 -2
  45. package/dist/esm/src/compat/bip-39-wordlist-en.js.map +1 -1
  46. package/dist/esm/src/primitives/AESGCM.js.map +1 -1
  47. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  48. package/dist/esm/src/primitives/DRBG.js.map +1 -1
  49. package/dist/esm/src/primitives/ECDSA.js.map +1 -1
  50. package/dist/esm/src/primitives/Hash.js +26 -13
  51. package/dist/esm/src/primitives/Hash.js.map +1 -1
  52. package/dist/esm/src/primitives/PrivateKey.js +3 -2
  53. package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
  54. package/dist/esm/src/primitives/PublicKey.js +1 -2
  55. package/dist/esm/src/primitives/PublicKey.js.map +1 -1
  56. package/dist/esm/src/primitives/Random.js +2 -2
  57. package/dist/esm/src/primitives/Random.js.map +1 -1
  58. package/dist/esm/src/primitives/Signature.js +141 -4
  59. package/dist/esm/src/primitives/Signature.js.map +1 -1
  60. package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
  61. package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
  62. package/dist/esm/src/primitives/utils.js +14 -9
  63. package/dist/esm/src/primitives/utils.js.map +1 -1
  64. package/dist/esm/src/script/Spend.js.map +1 -1
  65. package/dist/esm/src/script/templates/P2PKH.js +1 -1
  66. package/dist/esm/src/script/templates/P2PKH.js.map +1 -1
  67. package/dist/esm/src/transaction/MerklePath.js +3 -3
  68. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  69. package/dist/esm/src/transaction/Transaction.js +16 -4
  70. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  71. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  72. package/dist/types/src/compat/ECIES.d.ts +36 -36
  73. package/dist/types/src/compat/ECIES.d.ts.map +1 -1
  74. package/dist/types/src/compat/HD.d.ts +65 -65
  75. package/dist/types/src/compat/HD.d.ts.map +1 -1
  76. package/dist/types/src/compat/Mnemonic.d.ts +79 -79
  77. package/dist/types/src/compat/Mnemonic.d.ts.map +1 -1
  78. package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
  79. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  80. package/dist/types/src/primitives/Hash.d.ts.map +1 -1
  81. package/dist/types/src/primitives/PrivateKey.d.ts.map +1 -1
  82. package/dist/types/src/primitives/PublicKey.d.ts.map +1 -1
  83. package/dist/types/src/primitives/Signature.d.ts +62 -0
  84. package/dist/types/src/primitives/Signature.d.ts.map +1 -1
  85. package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
  86. package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
  87. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  88. package/dist/types/src/script/Spend.d.ts.map +1 -1
  89. package/dist/types/src/transaction/Transaction.d.ts +1 -0
  90. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  91. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  92. package/docs/compat.md +4 -4
  93. package/docs/primitives.md +288 -79
  94. package/package.json +1 -1
  95. package/src/compat/BSM.ts +12 -12
  96. package/src/compat/ECIES.ts +417 -418
  97. package/src/compat/HD.ts +228 -228
  98. package/src/compat/Mnemonic.ts +173 -173
  99. package/src/compat/__tests/BSM.test.ts +13 -2
  100. package/src/compat/bip-39-wordlist-en.ts +2052 -2052
  101. package/src/primitives/AESGCM.ts +30 -30
  102. package/src/primitives/BigNumber.ts +0 -1
  103. package/src/primitives/DRBG.ts +5 -5
  104. package/src/primitives/ECDSA.ts +1 -1
  105. package/src/primitives/Hash.ts +278 -293
  106. package/src/primitives/PrivateKey.ts +18 -19
  107. package/src/primitives/PublicKey.ts +9 -10
  108. package/src/primitives/Random.ts +4 -4
  109. package/src/primitives/Signature.ts +158 -14
  110. package/src/primitives/SymmetricKey.ts +3 -3
  111. package/src/primitives/TransactionSignature.ts +9 -9
  112. package/src/primitives/index.ts +1 -1
  113. package/src/primitives/utils.ts +60 -64
  114. package/src/script/Spend.ts +12 -12
  115. package/src/script/index.ts +1 -1
  116. package/src/script/templates/P2PKH.ts +1 -1
  117. package/src/transaction/MerklePath.ts +3 -3
  118. package/src/transaction/Transaction.ts +36 -26
  119. package/src/transaction/__tests/Transaction.test.ts +5 -5
@@ -4,7 +4,6 @@ import UnlockingScript from '../script/UnlockingScript.js'
4
4
  import LockingScript from '../script/LockingScript.js'
5
5
  import { Reader, Writer, toHex, toArray } from '../primitives/utils.js'
6
6
  import { hash256 } from '../primitives/Hash.js'
7
- import BigNumber from '../primitives/BigNumber.js'
8
7
  import FeeModel from './FeeModel.js'
9
8
  import SatoshisPerKilobyte from './fee-models/SatoshisPerKilobyte.js'
10
9
  import { Broadcaster, BroadcastResponse, BroadcastFailure } from './Broadcaster.js'
@@ -54,13 +53,14 @@ export default class Transaction {
54
53
  lockTime: number
55
54
  metadata: Record<string, any>
56
55
  merklePath?: MerklePath
56
+ private cachedHash?: number[]
57
57
 
58
58
  /**
59
59
  * Creates a new transaction, linked to its inputs and their associated merkle paths, from a BEEF (BRC-62) structure.
60
60
  * @param beef A binary representation of a transaction in BEEF format.
61
61
  * @returns An anchored transaction, linked to its associated inputs populated with merkle paths.
62
62
  */
63
- static fromBEEF(beef: number[]): Transaction {
63
+ static fromBEEF (beef: number[]): Transaction {
64
64
  const reader = new Reader(beef)
65
65
  // Read the version
66
66
  const version = reader.readUInt32LE()
@@ -120,7 +120,7 @@ export default class Transaction {
120
120
  return transactions[lastTXID].tx
121
121
  }
122
122
 
123
- private static fromReader(br: Reader): Transaction {
123
+ private static fromReader (br: Reader): Transaction {
124
124
  const version = br.readUInt32LE()
125
125
  const inputsLength = br.readVarIntNum()
126
126
  const inputs: TransactionInput[] = []
@@ -161,7 +161,7 @@ export default class Transaction {
161
161
  * @param {number[]} bin - The binary array representation of the transaction.
162
162
  * @returns {Transaction} - A new Transaction instance.
163
163
  */
164
- static fromBinary(bin: number[]): Transaction {
164
+ static fromBinary (bin: number[]): Transaction {
165
165
  const br = new Reader(bin)
166
166
  return Transaction.fromReader(br)
167
167
  }
@@ -173,7 +173,7 @@ export default class Transaction {
173
173
  * @param {string} hex - The hexadecimal string representation of the transaction.
174
174
  * @returns {Transaction} - A new Transaction instance.
175
175
  */
176
- static fromHex(hex: string): Transaction {
176
+ static fromHex (hex: string): Transaction {
177
177
  return Transaction.fromBinary(toArray(hex, 'hex'))
178
178
  }
179
179
 
@@ -184,11 +184,11 @@ export default class Transaction {
184
184
  * @param {string} hex - The hexadecimal string representation of the transaction BEEF.
185
185
  * @returns {Transaction} - A new Transaction instance.
186
186
  */
187
- static fromHexBEEF(hex: string): Transaction {
187
+ static fromHexBEEF (hex: string): Transaction {
188
188
  return Transaction.fromBEEF(toArray(hex, 'hex'))
189
189
  }
190
190
 
191
- constructor(
191
+ constructor (
192
192
  version: number = 1,
193
193
  inputs: TransactionInput[] = [],
194
194
  outputs: TransactionOutput[] = [],
@@ -210,7 +210,7 @@ export default class Transaction {
210
210
  * @param {TransactionInput} input - The TransactionInput object to add to the transaction.
211
211
  * @throws {Error} - If the input does not have a sourceTXID or sourceTransaction defined.
212
212
  */
213
- addInput(input: TransactionInput): void {
213
+ addInput (input: TransactionInput): void {
214
214
  if (
215
215
  typeof input.sourceTXID === 'undefined' &&
216
216
  typeof input.sourceTransaction === 'undefined'
@@ -221,6 +221,7 @@ export default class Transaction {
221
221
  if (typeof input.sequence === 'undefined') {
222
222
  input.sequence = 0xFFFFFFFF
223
223
  }
224
+ this.cachedHash = undefined
224
225
  this.inputs.push(input)
225
226
  }
226
227
 
@@ -229,7 +230,8 @@ export default class Transaction {
229
230
  *
230
231
  * @param {TransactionOutput} output - The TransactionOutput object to add to the transaction.
231
232
  */
232
- addOutput(output: TransactionOutput): void {
233
+ addOutput (output: TransactionOutput): void {
234
+ this.cachedHash = undefined
233
235
  this.outputs.push(output)
234
236
  }
235
237
 
@@ -238,7 +240,7 @@ export default class Transaction {
238
240
  *
239
241
  * @param {Record<string, any>} metadata - The metadata object to merge into the existing metadata.
240
242
  */
241
- updateMetadata(metadata: Record<string, any>): void {
243
+ updateMetadata (metadata: Record<string, any>): void {
242
244
  this.metadata = {
243
245
  ...this.metadata,
244
246
  ...metadata
@@ -255,7 +257,8 @@ export default class Transaction {
255
257
  *
256
258
  * TODO: Benford's law change distribution.
257
259
  */
258
- async fee(model?: FeeModel, changeDistribution: 'equal' | 'random' = 'equal'): Promise<void> {
260
+ async fee (model?: FeeModel, changeDistribution: 'equal' | 'random' = 'equal'): Promise<void> {
261
+ this.cachedHash = undefined
259
262
  if (typeof model === 'undefined') {
260
263
  model = new SatoshisPerKilobyte(10)
261
264
  }
@@ -307,7 +310,8 @@ export default class Transaction {
307
310
  /**
308
311
  * Signs a transaction, hydrating all its unlocking scripts based on the provided script templates where they are available.
309
312
  */
310
- async sign(): Promise<void> {
313
+ async sign (): Promise<void> {
314
+ this.cachedHash = undefined
311
315
  for (const out of this.outputs) {
312
316
  if (typeof out.satoshis === 'undefined') {
313
317
  if (out.change) {
@@ -319,9 +323,9 @@ export default class Transaction {
319
323
  }
320
324
  const unlockingScripts = await Promise.all(this.inputs.map(async (x, i): Promise<UnlockingScript | undefined> => {
321
325
  if (typeof this.inputs[i].unlockingScriptTemplate === 'object') {
322
- return this.inputs[i].unlockingScriptTemplate.sign(this, i)
326
+ return await this.inputs[i].unlockingScriptTemplate.sign(this, i)
323
327
  } else {
324
- return Promise.resolve(undefined)
328
+ return await Promise.resolve(undefined)
325
329
  }
326
330
  }))
327
331
  for (let i = 0, l = this.inputs.length; i < l; i++) {
@@ -337,7 +341,7 @@ export default class Transaction {
337
341
  * @param broadcaster The Broadcaster instance wwhere the transaction will be sent
338
342
  * @returns A BroadcastResponse or BroadcastFailure from the Broadcaster
339
343
  */
340
- async broadcast(broadcaster: Broadcaster): Promise<BroadcastResponse | BroadcastFailure> {
344
+ async broadcast (broadcaster: Broadcaster): Promise<BroadcastResponse | BroadcastFailure> {
341
345
  return await broadcaster.broadcast(this)
342
346
  }
343
347
 
@@ -346,7 +350,7 @@ export default class Transaction {
346
350
  *
347
351
  * @returns {number[]} - The binary array representation of the transaction.
348
352
  */
349
- toBinary(): number[] {
353
+ toBinary (): number[] {
350
354
  const writer = new Writer()
351
355
  writer.writeUInt32LE(this.version)
352
356
  writer.writeVarIntNum(this.inputs.length)
@@ -378,7 +382,7 @@ export default class Transaction {
378
382
  *
379
383
  * @returns {number[]} - The BRC-30 EF representation of the transaction.
380
384
  */
381
- toEF(): number[] {
385
+ toEF (): number[] {
382
386
  const writer = new Writer()
383
387
  writer.writeUInt32LE(this.version)
384
388
  writer.write([0, 0, 0, 0, 0, 0xef])
@@ -414,7 +418,7 @@ export default class Transaction {
414
418
  *
415
419
  * @returns {string} - The hexadecimal string representation of the transaction EF.
416
420
  */
417
- toHexEF(): string {
421
+ toHexEF (): string {
418
422
  return toHex(this.toEF())
419
423
  }
420
424
 
@@ -423,7 +427,7 @@ export default class Transaction {
423
427
  *
424
428
  * @returns {string} - The hexadecimal string representation of the transaction.
425
429
  */
426
- toHex(): string {
430
+ toHex (): string {
427
431
  return toHex(this.toBinary())
428
432
  }
429
433
 
@@ -432,7 +436,7 @@ export default class Transaction {
432
436
  *
433
437
  * @returns {string} - The hexadecimal string representation of the transaction BEEF.
434
438
  */
435
- toHexBEEF(): string {
439
+ toHexBEEF (): string {
436
440
  return toHex(this.toBEEF())
437
441
  }
438
442
 
@@ -442,8 +446,14 @@ export default class Transaction {
442
446
  * @param {'hex' | undefined} enc - The encoding to use for the hash. If 'hex', returns a hexadecimal string; otherwise returns a binary array.
443
447
  * @returns {string | number[]} - The hash of the transaction in the specified format.
444
448
  */
445
- hash(enc?: 'hex'): number[] | string {
446
- let hash = hash256(this.toBinary())
449
+ hash (enc?: 'hex'): number[] | string {
450
+ let hash
451
+ if (this.cachedHash) {
452
+ hash = this.cachedHash
453
+ } else {
454
+ hash = hash256(this.toBinary())
455
+ this.cachedHash = hash
456
+ }
447
457
  if (enc === 'hex') {
448
458
  return toHex(hash)
449
459
  } else {
@@ -457,8 +467,8 @@ export default class Transaction {
457
467
  * @param {'hex' | undefined} enc - The encoding to use for the ID. If 'hex', returns a hexadecimal string; otherwise returns a binary array.
458
468
  * @returns {string | number[]} - The ID of the transaction in the specified format.
459
469
  */
460
- id(enc?: 'hex'): number[] | string {
461
- const id = hash256(this.toBinary()) as number[]
470
+ id (enc?: 'hex'): number[] | string {
471
+ const id = [...this.hash() as number[]]
462
472
  id.reverse()
463
473
  if (enc === 'hex') {
464
474
  return toHex(id)
@@ -473,7 +483,7 @@ export default class Transaction {
473
483
  *
474
484
  * @returns Whether the transaction is valid according to the rules of SPV.
475
485
  */
476
- async verify(chainTracker: ChainTracker | 'scripts only'): Promise<boolean> {
486
+ async verify (chainTracker: ChainTracker | 'scripts only'): Promise<boolean> {
477
487
  // If the transaction has a valid merkle path, verification is complete.
478
488
  if (typeof this.merklePath === 'object' && chainTracker !== 'scripts only') {
479
489
  const proofValid = await this.merklePath.verify(
@@ -541,7 +551,7 @@ export default class Transaction {
541
551
  *
542
552
  * @returns The serialized BEEF structure
543
553
  */
544
- toBEEF(): number[] {
554
+ toBEEF (): number[] {
545
555
  const writer = new Writer()
546
556
  writer.writeUInt32LE(4022206465)
547
557
  const BUMPs: MerklePath[] = []
@@ -128,7 +128,7 @@ describe('Transaction', () => {
128
128
  it('should add an output', () => {
129
129
  const txOut = {
130
130
  lockingScript: new LockingScript(),
131
- satoshis: new BigNumber(0)
131
+ satoshis: 1
132
132
  }
133
133
  const tx = new Transaction()
134
134
  expect(tx.outputs.length).toEqual(0)
@@ -153,7 +153,7 @@ describe('Transaction', () => {
153
153
  unlockingScriptTemplate: p2pkh.unlock(privateKey),
154
154
  sequence: 0xffffffff
155
155
  }], [{
156
- satoshis: new BigNumber(1000),
156
+ satoshis: 1000,
157
157
  lockingScript: p2pkh.lock(publicKeyHash)
158
158
  }, {
159
159
  lockingScript: p2pkh.lock(publicKeyHash),
@@ -200,7 +200,7 @@ describe('Transaction', () => {
200
200
  }
201
201
  }
202
202
  const spendTx = new Transaction(1, manyInputs, [{
203
- satoshis: new BigNumber(1000),
203
+ satoshis: 1000,
204
204
  lockingScript: p2pkh.lock(publicKeyHash)
205
205
  }, {
206
206
  lockingScript: p2pkh.lock(publicKeyHash),
@@ -228,7 +228,7 @@ describe('Transaction', () => {
228
228
  unlockingScriptTemplate: p2pkh.unlock(privateKey),
229
229
  sequence: 0xffffffff
230
230
  }], [{
231
- satoshis: new BigNumber(1000),
231
+ satoshis: 1000,
232
232
  lockingScript: p2pkh.lock(publicKeyHash)
233
233
  }, {
234
234
  lockingScript: p2pkh.lock(publicKeyHash),
@@ -254,7 +254,7 @@ describe('Transaction', () => {
254
254
  unlockingScriptTemplate: p2pkh.unlock(privateKey),
255
255
  sequence: 0xffffffff
256
256
  }], [{
257
- satoshis: new BigNumber(1000),
257
+ satoshis: 1000,
258
258
  lockingScript: p2pkh.lock(publicKeyHash)
259
259
  }, {
260
260
  lockingScript: p2pkh.lock(publicKeyHash),