@bsv/sdk 1.8.12 → 1.9.0

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 (102) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/auth/Peer.js +35 -16
  3. package/dist/cjs/src/auth/Peer.js.map +1 -1
  4. package/dist/cjs/src/overlay-tools/HostReputationTracker.js +216 -0
  5. package/dist/cjs/src/overlay-tools/HostReputationTracker.js.map +1 -0
  6. package/dist/cjs/src/overlay-tools/LookupResolver.js +55 -3
  7. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  8. package/dist/cjs/src/primitives/BigNumber.js +43 -31
  9. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  10. package/dist/cjs/src/primitives/Hash.js +11 -5
  11. package/dist/cjs/src/primitives/Hash.js.map +1 -1
  12. package/dist/cjs/src/primitives/SymmetricKey.js +15 -6
  13. package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
  14. package/dist/cjs/src/primitives/TransactionSignature.js +60 -18
  15. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  16. package/dist/cjs/src/primitives/utils.js +74 -28
  17. package/dist/cjs/src/primitives/utils.js.map +1 -1
  18. package/dist/cjs/src/script/Script.js +217 -108
  19. package/dist/cjs/src/script/Script.js.map +1 -1
  20. package/dist/cjs/src/script/Spend.js +5 -2
  21. package/dist/cjs/src/script/Spend.js.map +1 -1
  22. package/dist/cjs/src/transaction/Beef.js +62 -7
  23. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  24. package/dist/cjs/src/transaction/BeefTx.js +1 -1
  25. package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
  26. package/dist/cjs/src/transaction/Transaction.js +67 -35
  27. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  28. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  29. package/dist/esm/src/auth/Peer.js +36 -16
  30. package/dist/esm/src/auth/Peer.js.map +1 -1
  31. package/dist/esm/src/overlay-tools/HostReputationTracker.js +213 -0
  32. package/dist/esm/src/overlay-tools/HostReputationTracker.js.map +1 -0
  33. package/dist/esm/src/overlay-tools/LookupResolver.js +56 -3
  34. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  35. package/dist/esm/src/primitives/BigNumber.js +43 -31
  36. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  37. package/dist/esm/src/primitives/Hash.js +11 -5
  38. package/dist/esm/src/primitives/Hash.js.map +1 -1
  39. package/dist/esm/src/primitives/SymmetricKey.js +15 -6
  40. package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
  41. package/dist/esm/src/primitives/TransactionSignature.js +60 -18
  42. package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
  43. package/dist/esm/src/primitives/utils.js +74 -28
  44. package/dist/esm/src/primitives/utils.js.map +1 -1
  45. package/dist/esm/src/script/Script.js +222 -110
  46. package/dist/esm/src/script/Script.js.map +1 -1
  47. package/dist/esm/src/script/Spend.js +6 -2
  48. package/dist/esm/src/script/Spend.js.map +1 -1
  49. package/dist/esm/src/transaction/Beef.js +64 -7
  50. package/dist/esm/src/transaction/Beef.js.map +1 -1
  51. package/dist/esm/src/transaction/BeefTx.js +1 -1
  52. package/dist/esm/src/transaction/BeefTx.js.map +1 -1
  53. package/dist/esm/src/transaction/Transaction.js +69 -35
  54. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  55. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  56. package/dist/types/src/auth/Peer.d.ts +4 -0
  57. package/dist/types/src/auth/Peer.d.ts.map +1 -1
  58. package/dist/types/src/overlay-tools/HostReputationTracker.d.ts +37 -0
  59. package/dist/types/src/overlay-tools/HostReputationTracker.d.ts.map +1 -0
  60. package/dist/types/src/overlay-tools/LookupResolver.d.ts +8 -0
  61. package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
  62. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  63. package/dist/types/src/primitives/Hash.d.ts +10 -10
  64. package/dist/types/src/primitives/Hash.d.ts.map +1 -1
  65. package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
  66. package/dist/types/src/primitives/TransactionSignature.d.ts +34 -13
  67. package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
  68. package/dist/types/src/primitives/utils.d.ts +6 -8
  69. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  70. package/dist/types/src/script/Script.d.ts +18 -9
  71. package/dist/types/src/script/Script.d.ts.map +1 -1
  72. package/dist/types/src/script/Spend.d.ts +1 -0
  73. package/dist/types/src/script/Spend.d.ts.map +1 -1
  74. package/dist/types/src/transaction/Beef.d.ts +9 -0
  75. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  76. package/dist/types/src/transaction/Transaction.d.ts +7 -0
  77. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  78. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  79. package/dist/umd/bundle.js +3 -3
  80. package/dist/umd/bundle.js.map +1 -1
  81. package/docs/reference/overlay-tools.md +58 -0
  82. package/docs/reference/primitives.md +120 -37
  83. package/docs/reference/script.md +11 -7
  84. package/docs/reference/transaction.md +2 -0
  85. package/docs/tutorials/advanced-transaction.md +2 -2
  86. package/docs/tutorials/first-transaction.md +1 -1
  87. package/docs/tutorials/transaction-types.md +1 -1
  88. package/package.json +1 -1
  89. package/src/auth/Peer.ts +44 -18
  90. package/src/overlay-tools/HostReputationTracker.ts +232 -0
  91. package/src/overlay-tools/LookupResolver.ts +73 -4
  92. package/src/overlay-tools/__tests/LookupResolver.test.ts +120 -0
  93. package/src/primitives/BigNumber.ts +44 -23
  94. package/src/primitives/Hash.ts +41 -17
  95. package/src/primitives/SymmetricKey.ts +15 -6
  96. package/src/primitives/TransactionSignature.ts +77 -31
  97. package/src/primitives/utils.ts +80 -30
  98. package/src/script/Script.ts +238 -104
  99. package/src/script/Spend.ts +7 -3
  100. package/src/transaction/Beef.ts +74 -7
  101. package/src/transaction/BeefTx.ts +1 -1
  102. package/src/transaction/Transaction.ts +77 -34
@@ -16,6 +16,9 @@ import { defaultChainTracker } from './chaintrackers/DefaultChainTracker.js'
16
16
  import { Beef, BEEF_V1 } from './Beef.js'
17
17
  import P2PKH from '../script/templates/P2PKH.js'
18
18
 
19
+ const BufferCtor =
20
+ typeof globalThis !== 'undefined' ? (globalThis as any).Buffer : undefined
21
+
19
22
  /**
20
23
  * Represents a complete Bitcoin transaction. This class encapsulates all the details
21
24
  * required for creating, signing, and processing a Bitcoin transaction, including
@@ -59,6 +62,8 @@ export default class Transaction {
59
62
  metadata: Record<string, any>
60
63
  merklePath?: MerklePath
61
64
  private cachedHash?: number[]
65
+ private rawBytesCache?: Uint8Array
66
+ private hexCache?: string
62
67
 
63
68
  // Recursive function for adding merkle proofs or input transactions
64
69
  private static addPathOrInputs (
@@ -280,8 +285,12 @@ export default class Transaction {
280
285
  * @returns {Transaction} - A new Transaction instance.
281
286
  */
282
287
  static fromBinary (bin: number[]): Transaction {
283
- const br = new Reader(bin)
284
- return Transaction.fromReader(br)
288
+ const copy = bin.slice()
289
+ const rawBytes = Uint8Array.from(copy)
290
+ const br = new Reader(copy)
291
+ const tx = Transaction.fromReader(br)
292
+ tx.rawBytesCache = rawBytes
293
+ return tx
285
294
  }
286
295
 
287
296
  /**
@@ -292,7 +301,16 @@ export default class Transaction {
292
301
  * @returns {Transaction} - A new Transaction instance.
293
302
  */
294
303
  static fromHex (hex: string): Transaction {
295
- return Transaction.fromBinary(toArray(hex, 'hex'))
304
+ const bin = toArray(hex, 'hex')
305
+ const rawBytes = Uint8Array.from(bin)
306
+ const br = new Reader(bin)
307
+ const tx = Transaction.fromReader(br)
308
+ tx.rawBytesCache = rawBytes
309
+ tx.hexCache =
310
+ BufferCtor != null
311
+ ? BufferCtor.from(rawBytes).toString('hex')
312
+ : toHex(bin)
313
+ return tx
296
314
  }
297
315
 
298
316
  /**
@@ -337,6 +355,12 @@ export default class Transaction {
337
355
  this.merklePath = merklePath
338
356
  }
339
357
 
358
+ private invalidateSerializationCaches (): void {
359
+ this.cachedHash = undefined
360
+ this.rawBytesCache = undefined
361
+ this.hexCache = undefined
362
+ }
363
+
340
364
  /**
341
365
  * Adds a new input to the transaction.
342
366
  *
@@ -356,7 +380,7 @@ export default class Transaction {
356
380
  if (typeof input.sequence === 'undefined') {
357
381
  input.sequence = 0xffffffff
358
382
  }
359
- this.cachedHash = undefined
383
+ this.invalidateSerializationCaches()
360
384
  this.inputs.push(input)
361
385
  }
362
386
 
@@ -423,7 +447,7 @@ export default class Transaction {
423
447
  modelOrFee: FeeModel | number = LivePolicy.getInstance(),
424
448
  changeDistribution: 'equal' | 'random' = 'equal'
425
449
  ): Promise<void> {
426
- this.cachedHash = undefined
450
+ this.invalidateSerializationCaches()
427
451
  if (typeof modelOrFee === 'number') {
428
452
  const sats = modelOrFee
429
453
  modelOrFee = {
@@ -550,7 +574,7 @@ export default class Transaction {
550
574
  * Signs a transaction, hydrating all its unlocking scripts based on the provided script templates where they are available.
551
575
  */
552
576
  async sign (): Promise<void> {
553
- this.cachedHash = undefined
577
+ this.invalidateSerializationCaches()
554
578
  for (const out of this.outputs) {
555
579
  if (typeof out.satoshis === 'undefined') {
556
580
  if (out.change === true) {
@@ -592,13 +616,7 @@ export default class Transaction {
592
616
  return await broadcaster.broadcast(this)
593
617
  }
594
618
 
595
- /**
596
- * Converts the transaction to a binary array format.
597
- *
598
- * @returns {number[]} - The binary array representation of the transaction.
599
- */
600
- toBinary (): number[] {
601
- const writer = new Writer()
619
+ private writeTransactionBody (writer: Writer): void {
602
620
  writer.writeUInt32LE(this.version)
603
621
  writer.writeVarIntNum(this.inputs.length)
604
622
  for (const i of this.inputs) {
@@ -615,20 +633,45 @@ export default class Transaction {
615
633
  if (i.unlockingScript == null) {
616
634
  throw new Error('unlockingScript is undefined')
617
635
  }
618
- const scriptBin = i.unlockingScript.toBinary()
636
+ const scriptBin = i.unlockingScript.toUint8Array()
619
637
  writer.writeVarIntNum(scriptBin.length)
620
638
  writer.write(scriptBin)
621
- writer.writeUInt32LE(i.sequence ?? 0xffffffff) // default to max sequence
639
+ writer.writeUInt32LE(i.sequence ?? 0xffffffff)
622
640
  }
623
641
  writer.writeVarIntNum(this.outputs.length)
624
642
  for (const o of this.outputs) {
625
643
  writer.writeUInt64LE(o.satoshis ?? 0)
626
- const scriptBin = o.lockingScript.toBinary()
644
+ const scriptBin = o.lockingScript.toUint8Array()
627
645
  writer.writeVarIntNum(scriptBin.length)
628
646
  writer.write(scriptBin)
629
647
  }
630
648
  writer.writeUInt32LE(this.lockTime)
631
- return writer.toArray()
649
+ }
650
+
651
+ private buildSerializedBytes (): Uint8Array {
652
+ const writer = new Writer()
653
+ this.writeTransactionBody(writer)
654
+ return writer.toUint8Array()
655
+ }
656
+
657
+ private getSerializedBytes (): Uint8Array {
658
+ if (this.rawBytesCache == null) {
659
+ this.rawBytesCache = this.buildSerializedBytes()
660
+ }
661
+ return this.rawBytesCache
662
+ }
663
+
664
+ /**
665
+ * Converts the transaction to a binary array format.
666
+ *
667
+ * @returns {number[]} - The binary array representation of the transaction.
668
+ */
669
+ toBinary (): number[] {
670
+ return Array.from(this.getSerializedBytes())
671
+ }
672
+
673
+ toUint8Array (): Uint8Array {
674
+ return this.getSerializedBytes()
632
675
  }
633
676
 
634
677
  /**
@@ -696,7 +739,16 @@ export default class Transaction {
696
739
  * @returns {string} - The hexadecimal string representation of the transaction.
697
740
  */
698
741
  toHex (): string {
699
- return toHex(this.toBinary())
742
+ if (this.hexCache != null) {
743
+ return this.hexCache
744
+ }
745
+ const bytes = this.getSerializedBytes()
746
+ const hex =
747
+ BufferCtor != null
748
+ ? BufferCtor.from(bytes).toString('hex')
749
+ : toHex(Array.from(bytes))
750
+ this.hexCache = hex
751
+ return hex
700
752
  }
701
753
 
702
754
  /**
@@ -724,17 +776,13 @@ export default class Transaction {
724
776
  * @returns {string | number[]} - The hash of the transaction in the specified format.
725
777
  */
726
778
  hash (enc?: 'hex'): number[] | string {
727
- let hash
728
- if (this.cachedHash != null) {
729
- hash = this.cachedHash
730
- } else {
731
- hash = hash256(this.toBinary())
732
- this.cachedHash = hash
779
+ if (this.cachedHash == null) {
780
+ this.cachedHash = hash256(this.getSerializedBytes())
733
781
  }
734
782
  if (enc === 'hex') {
735
- return toHex(hash)
783
+ return toHex(this.cachedHash)
736
784
  }
737
- return hash
785
+ return this.cachedHash
738
786
  }
739
787
 
740
788
  /**
@@ -999,14 +1047,9 @@ export default class Transaction {
999
1047
  * @throws Error if there are any missing sourceTransactions unless `allowPartial` is true.
1000
1048
  */
1001
1049
  toAtomicBEEF (allowPartial?: boolean): number[] {
1002
- const writer = new Writer()
1003
- // Write the Atomic BEEF prefix
1004
- writer.writeUInt32LE(0x01010101)
1005
- // Write the subject TXID (big-endian)
1006
- writer.write(this.hash())
1007
- // Append the BEEF data
1050
+ const prefix = [1, 1, 1, 1]
1051
+ const txHash = this.hash() as number[]
1008
1052
  const beefData = this.toBEEF(allowPartial)
1009
- writer.write(beefData)
1010
- return writer.toArray()
1053
+ return prefix.concat(txHash, beefData)
1011
1054
  }
1012
1055
  }