@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
@@ -11,6 +11,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
11
11
  | [LookupResolverConfig](#interface-lookupresolverconfig) |
12
12
  | [OverlayBroadcastFacilitator](#interface-overlaybroadcastfacilitator) |
13
13
  | [OverlayLookupFacilitator](#interface-overlaylookupfacilitator) |
14
+ | [RankedHost](#interface-rankedhost) |
14
15
  | [SHIPBroadcasterConfig](#interface-shipbroadcasterconfig) |
15
16
  | [TaggedBEEF](#interface-taggedbeef) |
16
17
 
@@ -101,6 +102,10 @@ export interface LookupResolverConfig {
101
102
  hostOverrides?: Record<string, string[]>;
102
103
  additionalHosts?: Record<string, string[]>;
103
104
  cache?: CacheOptions;
105
+ reputationStorage?: "localStorage" | {
106
+ get: (key: string) => string | null | undefined;
107
+ set: (key: string, value: string) => void;
108
+ };
104
109
  }
105
110
  ```
106
111
 
@@ -150,6 +155,17 @@ The network preset to use, unless other options override it.
150
155
  networkPreset?: "mainnet" | "testnet" | "local"
151
156
  ```
152
157
 
158
+ #### Property reputationStorage
159
+
160
+ Optional storage for host reputation data.
161
+
162
+ ```ts
163
+ reputationStorage?: "localStorage" | {
164
+ get: (key: string) => string | null | undefined;
165
+ set: (key: string, value: string) => void;
166
+ }
167
+ ```
168
+
153
169
  #### Property slapTrackers
154
170
 
155
171
  The list of SLAP trackers queried to resolve Overlay Services hosts for a given lookup service.
@@ -199,6 +215,17 @@ See also: [LookupAnswer](./overlay-tools.md#type-lookupanswer), [LookupQuestion]
199
215
 
200
216
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
201
217
 
218
+ ---
219
+ ### Interface: RankedHost
220
+
221
+ ```ts
222
+ export interface RankedHost extends HostReputationEntry {
223
+ score: number;
224
+ }
225
+ ```
226
+
227
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
228
+
202
229
  ---
203
230
  ### Interface: SHIPBroadcasterConfig
204
231
 
@@ -294,6 +321,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
294
321
  | --- |
295
322
  | [HTTPSOverlayBroadcastFacilitator](#class-httpsoverlaybroadcastfacilitator) |
296
323
  | [HTTPSOverlayLookupFacilitator](#class-httpsoverlaylookupfacilitator) |
324
+ | [HostReputationTracker](#class-hostreputationtracker) |
297
325
  | [LookupResolver](#class-lookupresolver) |
298
326
  | [OverlayAdminTokenTemplate](#class-overlayadmintokentemplate) |
299
327
  | [TopicBroadcaster](#class-topicbroadcaster) |
@@ -333,6 +361,24 @@ See also: [LookupAnswer](./overlay-tools.md#type-lookupanswer), [LookupQuestion]
333
361
 
334
362
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
335
363
 
364
+ ---
365
+ ### Class: HostReputationTracker
366
+
367
+ ```ts
368
+ export class HostReputationTracker {
369
+ constructor(store?: KeyValueStore)
370
+ reset(): void
371
+ recordSuccess(host: string, latencyMs: number): void
372
+ recordFailure(host: string, reason?: unknown): void
373
+ rankHosts(hosts: string[], now: number = Date.now()): RankedHost[]
374
+ snapshot(host: string): HostReputationEntry | undefined
375
+ }
376
+ ```
377
+
378
+ See also: [RankedHost](./overlay-tools.md#interface-rankedhost)
379
+
380
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
381
+
336
382
  ---
337
383
  ### Class: LookupResolver
338
384
 
@@ -569,6 +615,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
569
615
  | --- |
570
616
  | [DEFAULT_SLAP_TRACKERS](#variable-default_slap_trackers) |
571
617
  | [DEFAULT_TESTNET_SLAP_TRACKERS](#variable-default_testnet_slap_trackers) |
618
+ | [getOverlayHostReputationTracker](#variable-getoverlayhostreputationtracker) |
572
619
 
573
620
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
574
621
 
@@ -599,3 +646,14 @@ DEFAULT_TESTNET_SLAP_TRACKERS: string[] = [
599
646
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
600
647
 
601
648
  ---
649
+ ### Variable: getOverlayHostReputationTracker
650
+
651
+ ```ts
652
+ getOverlayHostReputationTracker = (): HostReputationTracker => globalTracker
653
+ ```
654
+
655
+ See also: [HostReputationTracker](./overlay-tools.md#class-hostreputationtracker)
656
+
657
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
658
+
659
+ ---
@@ -4,6 +4,15 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
4
4
 
5
5
  ## Interfaces
6
6
 
7
+ | |
8
+ | --- |
9
+ | [JacobianPointBI](#interface-jacobianpointbi) |
10
+ | [SignatureHashCache](#interface-signaturehashcache) |
11
+
12
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
13
+
14
+ ---
15
+
7
16
  ### Interface: JacobianPointBI
8
17
 
9
18
  ```ts
@@ -16,6 +25,20 @@ export interface JacobianPointBI {
16
25
 
17
26
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
18
27
 
28
+ ---
29
+ ### Interface: SignatureHashCache
30
+
31
+ ```ts
32
+ export interface SignatureHashCache {
33
+ hashPrevouts?: number[];
34
+ hashSequence?: number[];
35
+ hashOutputsAll?: number[];
36
+ hashOutputsSingle?: Map<number, number[]>;
37
+ }
38
+ ```
39
+
40
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
41
+
19
42
  ---
20
43
  ## Classes
21
44
 
@@ -3898,7 +3921,7 @@ const sha256 = new SHA256();
3898
3921
  ```ts
3899
3922
  export class SHA256 {
3900
3923
  constructor()
3901
- update(msg: number[] | string, enc?: "hex" | "utf8"): this
3924
+ update(msg: Uint8Array | number[] | string, enc?: "hex" | "utf8"): this
3902
3925
  digest(): number[]
3903
3926
  digestHex(): string
3904
3927
  }
@@ -3919,8 +3942,8 @@ This class also uses the SHA-256 cryptographic hash algorithm that produces a 25
3919
3942
  export class SHA256HMAC {
3920
3943
  blockSize = 64;
3921
3944
  outSize = 32;
3922
- constructor(key: number[] | string)
3923
- update(msg: number[] | string, enc?: "hex"): SHA256HMAC
3945
+ constructor(key: Uint8Array | number[] | string)
3946
+ update(msg: Uint8Array | number[] | string, enc?: "hex"): SHA256HMAC
3924
3947
  digest(): number[]
3925
3948
  digestHex(): string
3926
3949
  }
@@ -3935,7 +3958,7 @@ If the key size is larger than the blockSize, it is digested using SHA-256.
3935
3958
  If the key size is less than the blockSize, it is padded with zeroes.
3936
3959
 
3937
3960
  ```ts
3938
- constructor(key: number[] | string)
3961
+ constructor(key: Uint8Array | number[] | string)
3939
3962
  ```
3940
3963
 
3941
3964
  Argument Details
@@ -4006,7 +4029,7 @@ let hashedMessage = myHMAC.digestHex();
4006
4029
  Updates the `SHA256HMAC` object with part of the message to be hashed.
4007
4030
 
4008
4031
  ```ts
4009
- update(msg: number[] | string, enc?: "hex"): SHA256HMAC
4032
+ update(msg: Uint8Array | number[] | string, enc?: "hex"): SHA256HMAC
4010
4033
  ```
4011
4034
  See also: [SHA256HMAC](./primitives.md#class-sha256hmac)
4012
4035
 
@@ -4067,8 +4090,8 @@ This class also uses the SHA-512 cryptographic hash algorithm that produces a 51
4067
4090
  export class SHA512HMAC {
4068
4091
  blockSize = 128;
4069
4092
  outSize = 32;
4070
- constructor(key: number[] | string)
4071
- update(msg: number[] | string, enc?: "hex" | "utf8"): SHA512HMAC
4093
+ constructor(key: Uint8Array | number[] | string)
4094
+ update(msg: Uint8Array | number[] | string, enc?: "hex" | "utf8"): SHA512HMAC
4072
4095
  digest(): number[]
4073
4096
  digestHex(): string
4074
4097
  }
@@ -4083,7 +4106,7 @@ If the key size is larger than the blockSize, it is digested using SHA-512.
4083
4106
  If the key size is less than the blockSize, it is padded with zeroes.
4084
4107
 
4085
4108
  ```ts
4086
- constructor(key: number[] | string)
4109
+ constructor(key: Uint8Array | number[] | string)
4087
4110
  ```
4088
4111
 
4089
4112
  Argument Details
@@ -4154,7 +4177,7 @@ let hashedMessage = myHMAC.digestHex();
4154
4177
  Updates the `SHA512HMAC` object with part of the message to be hashed.
4155
4178
 
4156
4179
  ```ts
4157
- update(msg: number[] | string, enc?: "hex" | "utf8"): SHA512HMAC
4180
+ update(msg: Uint8Array | number[] | string, enc?: "hex" | "utf8"): SHA512HMAC
4158
4181
  ```
4159
4182
  See also: [SHA512HMAC](./primitives.md#class-sha512hmac)
4160
4183
 
@@ -4682,19 +4705,8 @@ export default class TransactionSignature extends Signature {
4682
4705
  public static readonly SIGHASH_FORKID = 64;
4683
4706
  public static readonly SIGHASH_ANYONECANPAY = 128;
4684
4707
  scope: number;
4685
- static format(params: {
4686
- sourceTXID: string;
4687
- sourceOutputIndex: number;
4688
- sourceSatoshis: number;
4689
- transactionVersion: number;
4690
- otherInputs: TransactionInput[];
4691
- outputs: TransactionOutput[];
4692
- inputIndex: number;
4693
- subscript: Script;
4694
- inputSequence: number;
4695
- lockTime: number;
4696
- scope: number;
4697
- }): number[]
4708
+ static format(params: TransactionSignatureFormatParams): number[]
4709
+ static formatBytes(params: TransactionSignatureFormatParams): Uint8Array
4698
4710
  static fromChecksigFormat(buf: number[]): TransactionSignature
4699
4711
  constructor(r: BigNumber, s: BigNumber, scope: number)
4700
4712
  public hasLowS(): boolean
@@ -4702,7 +4714,41 @@ export default class TransactionSignature extends Signature {
4702
4714
  }
4703
4715
  ```
4704
4716
 
4705
- See also: [BigNumber](./primitives.md#class-bignumber), [Script](./script.md#class-script), [Signature](./primitives.md#class-signature), [TransactionInput](./transaction.md#interface-transactioninput), [TransactionOutput](./transaction.md#interface-transactionoutput)
4717
+ See also: [BigNumber](./primitives.md#class-bignumber), [Signature](./primitives.md#class-signature)
4718
+
4719
+ #### Method format
4720
+
4721
+ Formats the SIGHASH preimage for the targeted input, optionally using a cache to skip recomputing shared hash prefixes.
4722
+
4723
+ ```ts
4724
+ static format(params: TransactionSignatureFormatParams): number[]
4725
+ ```
4726
+
4727
+ Argument Details
4728
+
4729
+ + **params**
4730
+ + Context for the signing input plus transaction metadata.
4731
+ + **params.cache**
4732
+ + Optional cache storing previously computed `hashPrevouts`, `hashSequence`, or `hashOutputs*` values; it will be populated if present.
4733
+
4734
+ #### Method formatBytes
4735
+
4736
+ Formats the same SIGHASH preimage bytes as `format`, supporting the optional cache for hash reuse.
4737
+
4738
+ ```ts
4739
+ static formatBytes(params: TransactionSignatureFormatParams): Uint8Array
4740
+ ```
4741
+
4742
+ Returns
4743
+
4744
+ Bytes for signing.
4745
+
4746
+ Argument Details
4747
+
4748
+ + **params**
4749
+ + Context for the signing operation.
4750
+ + **params.cache**
4751
+ + Optional `SignatureHashCache` that may already contain hashed prefixes and is populated during formatting.
4706
4752
 
4707
4753
  #### Method hasLowS
4708
4754
 
@@ -4721,11 +4767,12 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
4721
4767
 
4722
4768
  ```ts
4723
4769
  export class Writer {
4724
- public bufs: number[][];
4725
- constructor(bufs?: number[][])
4770
+ public bufs: WriterChunk[];
4771
+ constructor(bufs?: WriterChunk[])
4726
4772
  getLength(): number
4773
+ toUint8Array(): Uint8Array
4727
4774
  toArray(): number[]
4728
- write(buf: number[]): this
4775
+ write(buf: WriterChunk): this
4729
4776
  writeReverse(buf: number[]): this
4730
4777
  writeUInt8(n: number): this
4731
4778
  writeInt8(n: number): this
@@ -4764,6 +4811,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
4764
4811
  | [red](#function-red) |
4765
4812
  | [toArray](#function-toarray) |
4766
4813
  | [toBase64](#function-tobase64) |
4814
+ | [verifyNotNull](#function-verifynotnull) |
4767
4815
 
4768
4816
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
4769
4817
 
@@ -4889,6 +4937,38 @@ Argument Details
4889
4937
 
4890
4938
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
4891
4939
 
4940
+ ---
4941
+ ### Function: verifyNotNull
4942
+
4943
+ Verifies that a value is not null or undefined, throwing an error if it is.
4944
+
4945
+ Example
4946
+
4947
+ ```ts
4948
+ const myValue = verifyNotNull(someValue, 'someValue must be defined')
4949
+ ```
4950
+
4951
+ ```ts
4952
+ export function verifyNotNull<T>(value: T | undefined | null, errorMessage: string = "Expected a valid value, but got undefined or null."): T
4953
+ ```
4954
+
4955
+ Returns
4956
+
4957
+ - The verified value
4958
+
4959
+ Argument Details
4960
+
4961
+ + **value**
4962
+ + The value to verify
4963
+ + **errorMessage**
4964
+ + The error message to throw if the value is null or undefined
4965
+
4966
+ Throws
4967
+
4968
+ - If the value is null or undefined
4969
+
4970
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
4971
+
4892
4972
  ---
4893
4973
  ## Types
4894
4974
 
@@ -5276,7 +5356,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5276
5356
  ### Variable: hash160
5277
5357
 
5278
5358
  ```ts
5279
- hash160 = (msg: number[] | string, enc?: "hex" | "utf8"): number[] => {
5359
+ hash160 = (msg: Uint8Array | number[] | string, enc?: "hex" | "utf8"): number[] => {
5280
5360
  const first = new SHA256().update(msg, enc).digest();
5281
5361
  return new RIPEMD160().update(first).digest();
5282
5362
  }
@@ -5290,7 +5370,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5290
5370
  ### Variable: hash256
5291
5371
 
5292
5372
  ```ts
5293
- hash256 = (msg: number[] | string, enc?: "hex" | "utf8"): number[] => {
5373
+ hash256 = (msg: Uint8Array | number[] | string, enc?: "hex" | "utf8"): number[] => {
5294
5374
  const first = new SHA256().update(msg, enc).digest();
5295
5375
  return new SHA256().update(first).digest();
5296
5376
  }
@@ -5622,7 +5702,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5622
5702
  ### Variable: sha256
5623
5703
 
5624
5704
  ```ts
5625
- sha256 = (msg: number[] | string, enc?: "hex" | "utf8"): number[] => {
5705
+ sha256 = (msg: Uint8Array | number[] | string, enc?: "hex" | "utf8"): number[] => {
5626
5706
  return new SHA256().update(msg, enc).digest();
5627
5707
  }
5628
5708
  ```
@@ -5635,7 +5715,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5635
5715
  ### Variable: sha256hmac
5636
5716
 
5637
5717
  ```ts
5638
- sha256hmac = (key: number[] | string, msg: number[] | string, enc?: "hex"): number[] => {
5718
+ sha256hmac = (key: Uint8Array | number[] | string, msg: Uint8Array | number[] | string, enc?: "hex"): number[] => {
5639
5719
  return new SHA256HMAC(key).update(msg, enc).digest();
5640
5720
  }
5641
5721
  ```
@@ -5661,7 +5741,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5661
5741
  ### Variable: sha512hmac
5662
5742
 
5663
5743
  ```ts
5664
- sha512hmac = (key: number[] | string, msg: number[] | string, enc?: "hex"): number[] => {
5744
+ sha512hmac = (key: Uint8Array | number[] | string, msg: Uint8Array | number[] | string, enc?: "hex"): number[] => {
5665
5745
  return new SHA512HMAC(key).update(msg, enc).digest();
5666
5746
  }
5667
5747
  ```
@@ -5818,16 +5898,19 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5818
5898
 
5819
5899
  ```ts
5820
5900
  toHex = (msg: number[]): string => {
5821
- let res = "";
5822
- for (const num of msg) {
5823
- res += zero2(num.toString(16));
5901
+ if (CAN_USE_BUFFER) {
5902
+ return BufferCtor.from(msg).toString("hex");
5903
+ }
5904
+ if (msg.length === 0)
5905
+ return "";
5906
+ const out = new Array(msg.length);
5907
+ for (let i = 0; i < msg.length; i++) {
5908
+ out[i] = HEX_BYTE_STRINGS[msg[i] & 255];
5824
5909
  }
5825
- return res;
5910
+ return out.join("");
5826
5911
  }
5827
5912
  ```
5828
5913
 
5829
- See also: [zero2](./primitives.md#variable-zero2)
5830
-
5831
5914
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
5832
5915
 
5833
5916
  ---
@@ -418,20 +418,18 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
418
418
  ---
419
419
  ### Class: Script
420
420
 
421
- The Script class represents a script in a Bitcoin SV transaction,
422
- encapsulating the functionality to construct, parse, and serialize
423
- scripts used in both locking (output) and unlocking (input) scripts.
424
-
425
421
  ```ts
426
422
  export default class Script {
427
- chunks: ScriptChunk[];
428
423
  static fromASM(asm: string): Script
429
424
  static fromHex(hex: string): Script
430
425
  static fromBinary(bin: number[]): Script
431
- constructor(chunks: ScriptChunk[] = [])
426
+ constructor(chunks: ScriptChunk[] = [], rawBytesCache?: Uint8Array, hexCache?: string, parsed: boolean = true)
427
+ get chunks(): ScriptChunk[]
428
+ set chunks(value: ScriptChunk[])
432
429
  toASM(): string
433
430
  toHex(): string
434
431
  toBinary(): number[]
432
+ toUint8Array(): Uint8Array
435
433
  writeScript(script: Script): Script
436
434
  writeOpCode(op: number): Script
437
435
  setChunkOpCode(i: number, op: number): Script
@@ -451,7 +449,7 @@ See also: [BigNumber](./primitives.md#class-bignumber), [ScriptChunk](./script.m
451
449
  #### Constructor
452
450
 
453
451
  ```ts
454
- constructor(chunks: ScriptChunk[] = [])
452
+ constructor(chunks: ScriptChunk[] = [], rawBytesCache?: Uint8Array, hexCache?: string, parsed: boolean = true)
455
453
  ```
456
454
  See also: [ScriptChunk](./script.md#interface-scriptchunk)
457
455
 
@@ -459,6 +457,12 @@ Argument Details
459
457
 
460
458
  + **chunks**
461
459
  + =[] - An array of script chunks to directly initialize the script.
460
+ + **rawBytesCache**
461
+ + Optional serialized bytes that can be reused instead of reserializing `chunks`.
462
+ + **hexCache**
463
+ + Optional lowercase hex string that matches the serialized bytes, used to satisfy `toHex` quickly.
464
+ + **parsed**
465
+ + When false the script defers parsing `rawBytesCache` until `chunks` is accessed; defaults to true.
462
466
 
463
467
  #### Method findAndDelete
464
468
 
@@ -589,6 +589,7 @@ export class Beef {
589
589
  }
590
590
  toWriter(writer: Writer): void
591
591
  toBinary(): number[]
592
+ toUint8Array(): Uint8Array
592
593
  toBinaryAtomic(txid: string): number[]
593
594
  toHex(): string
594
595
  static fromReader(br: Reader): Beef
@@ -1594,6 +1595,7 @@ export default class Transaction {
1594
1595
  async sign(): Promise<void>
1595
1596
  async broadcast(broadcaster: Broadcaster = defaultBroadcaster()): Promise<BroadcastResponse | BroadcastFailure>
1596
1597
  toBinary(): number[]
1598
+ toUint8Array(): Uint8Array
1597
1599
  toEF(): number[]
1598
1600
  toHexEF(): string
1599
1601
  toHex(): string
@@ -17,7 +17,7 @@ This tutorial builds on your knowledge of basic `WalletClient` usage to explore
17
17
  ## Prerequisites
18
18
 
19
19
  - Complete the [Transaction Types and Data](./transaction-types.md) tutorial
20
- - Have a BRC-100 compliant wallet (such as the [MetaNet Desktop Wallet](https://metanet.bsvb.tech/)) installed and configured
20
+ - Have a BRC-100 compliant wallet (such as the [MetaNet Desktop Wallet](https://desktop.bsvb.tech/)) installed and configured
21
21
  - Some BSV in your wallet
22
22
  - Understanding of Bitcoin transaction fundamentals
23
23
 
@@ -569,4 +569,4 @@ These techniques enable you to build production-ready applications that efficien
569
569
 
570
570
  - [Wallet Reference](../reference/wallet.md)
571
571
  - [BSV Blockchain Documentation](https://docs.bsvblockchain.org/)
572
- - [MetaNet Desktop Wallet](https://metanet.bsvb.tech/)
572
+ - [MetaNet Desktop Wallet](https://desktop.bsvb.tech/)
@@ -18,7 +18,7 @@ In this tutorial, you'll learn how to create your first Bitcoin SV transactions
18
18
 
19
19
  ## Precondition
20
20
 
21
- Install a BRC-100 compliant wallet such as the [MetaNet Desktop Wallet](https://metanet.bsvb.tech/). When you install it, you'll receive a small amount of funds to play with.
21
+ Install a BRC-100 compliant wallet such as the [MetaNet Desktop Wallet](https://desktop.bsvb.tech/). When you install it, you'll receive a small amount of funds to play with.
22
22
 
23
23
  ## Step 1: Setting Up Your Environment
24
24
 
@@ -17,7 +17,7 @@ In the previous tutorial, you created a simple transaction that sent BSV to a si
17
17
  ## Prerequisites
18
18
 
19
19
  - Complete the [Your First BSV Transaction](./first-transaction.md) tutorial
20
- - Have a BRC-100 compliant wallet (such as [MetaNet Desktop Wallet](https://metanet.bsvb.tech/)) installed and configured
20
+ - Have a BRC-100 compliant wallet (such as [MetaNet Desktop Wallet](https://desktop.bsvb.tech/)) installed and configured
21
21
  - Some BSV in your wallet
22
22
 
23
23
  ## Transaction with Multiple Outputs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.8.12",
3
+ "version": "1.9.0",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
package/src/auth/Peer.ts CHANGED
@@ -17,6 +17,8 @@ import * as Utils from '../primitives/utils.js'
17
17
  import { OriginatorDomainNameStringUnder250Bytes, WalletInterface } from '../wallet/Wallet.interfaces.js'
18
18
 
19
19
  const AUTH_VERSION = '0.1'
20
+ const BufferCtor =
21
+ typeof globalThis !== 'undefined' ? (globalThis as any).Buffer : undefined
20
22
 
21
23
  /**
22
24
  * Represents a peer capable of performing mutual authentication.
@@ -63,6 +65,7 @@ export class Peer {
63
65
  private lastInteractedWithPeer: string | undefined
64
66
 
65
67
  private readonly originator?: OriginatorDomainNameStringUnder250Bytes
68
+ private identityPublicKey?: string
66
69
 
67
70
  /**
68
71
  * Creates a new Peer instance
@@ -136,8 +139,7 @@ export class Peer {
136
139
  const generalMessage: AuthMessage = {
137
140
  version: AUTH_VERSION,
138
141
  messageType: 'general',
139
- identityKey: (await this.wallet.getPublicKey({ identityKey: true }, this.originator))
140
- .publicKey,
142
+ identityKey: await this.getIdentityPublicKey(),
141
143
  nonce: requestNonce,
142
144
  yourNonce: peerSession.peerNonce,
143
145
  payload: message,
@@ -186,7 +188,7 @@ export class Peer {
186
188
  // Prepare the message
187
189
  const requestNonce = Utils.toBase64(Random(32))
188
190
  const { signature } = await this.wallet.createSignature({
189
- data: Utils.toArray(JSON.stringify(certificatesToRequest), 'utf8'),
191
+ data: Peer.utf8ToBytes(JSON.stringify(certificatesToRequest)),
190
192
  protocolID: [2, 'auth message signature'],
191
193
  keyID: `${requestNonce} ${peerSession.peerNonce ?? ''}`,
192
194
  counterparty: peerSession.peerIdentityKey
@@ -195,8 +197,7 @@ export class Peer {
195
197
  const certRequestMessage: AuthMessage = {
196
198
  version: AUTH_VERSION,
197
199
  messageType: 'certificateRequest',
198
- identityKey: (await this.wallet.getPublicKey({ identityKey: true }, this.originator))
199
- .publicKey,
200
+ identityKey: await this.getIdentityPublicKey(),
200
201
  nonce: requestNonce,
201
202
  initialNonce: peerSession.sessionNonce,
202
203
  yourNonce: peerSession.peerNonce,
@@ -352,8 +353,7 @@ export class Peer {
352
353
  const initialRequest: AuthMessage = {
353
354
  version: AUTH_VERSION,
354
355
  messageType: 'initialRequest',
355
- identityKey: (await this.wallet.getPublicKey({ identityKey: true }, this.originator))
356
- .publicKey,
356
+ identityKey: await this.getIdentityPublicKey(),
357
357
  initialNonce: sessionNonce,
358
358
  requestedCertificates: this.certificatesToRequest
359
359
  }
@@ -525,7 +525,7 @@ export class Peer {
525
525
 
526
526
  // Create signature
527
527
  const { signature } = await this.wallet.createSignature({
528
- data: Utils.toArray(message.initialNonce + sessionNonce, 'base64'),
528
+ data: Peer.base64ToBytes(message.initialNonce + sessionNonce),
529
529
  protocolID: [2, 'auth message signature'],
530
530
  keyID: `${message.initialNonce} ${sessionNonce}`,
531
531
  counterparty: message.identityKey
@@ -534,8 +534,7 @@ export class Peer {
534
534
  const initialResponseMessage: AuthMessage = {
535
535
  version: AUTH_VERSION,
536
536
  messageType: 'initialResponse',
537
- identityKey: (await this.wallet.getPublicKey({ identityKey: true }, this.originator))
538
- .publicKey,
537
+ identityKey: await this.getIdentityPublicKey(),
539
538
  initialNonce: sessionNonce,
540
539
  yourNonce: message.initialNonce,
541
540
  certificates: certificatesToInclude,
@@ -574,9 +573,8 @@ export class Peer {
574
573
  }
575
574
 
576
575
  // Validate message signature
577
- const dataToVerify = Utils.toArray(
578
- (peerSession.sessionNonce ?? '') + (message.initialNonce ?? ''),
579
- 'base64'
576
+ const dataToVerify = Peer.base64ToBytes(
577
+ (peerSession.sessionNonce ?? '') + (message.initialNonce ?? '')
580
578
  )
581
579
  const { valid } = await this.wallet.verifySignature({
582
580
  data: dataToVerify,
@@ -668,7 +666,7 @@ export class Peer {
668
666
  }
669
667
 
670
668
  const { valid } = await this.wallet.verifySignature({
671
- data: Utils.toArray(JSON.stringify(message.requestedCertificates), 'utf8'),
669
+ data: Peer.utf8ToBytes(JSON.stringify(message.requestedCertificates)),
672
670
  signature: message.signature as number[],
673
671
  protocolID: [2, 'auth message signature'],
674
672
  keyID: `${message.nonce ?? ''} ${peerSession.sessionNonce ?? ''}`,
@@ -721,7 +719,7 @@ export class Peer {
721
719
  const peerSession = await this.getAuthenticatedSession(verifierIdentityKey)
722
720
  const requestNonce = Utils.toBase64(Random(32))
723
721
  const { signature } = await this.wallet.createSignature({
724
- data: Utils.toArray(JSON.stringify(certificates), 'utf8'),
722
+ data: Peer.utf8ToBytes(JSON.stringify(certificates)),
725
723
  protocolID: [2, 'auth message signature'],
726
724
  keyID: `${requestNonce} ${peerSession.peerNonce ?? ''}`,
727
725
  counterparty: peerSession.peerIdentityKey
@@ -730,8 +728,7 @@ export class Peer {
730
728
  const certificateResponse: AuthMessage = {
731
729
  version: AUTH_VERSION,
732
730
  messageType: 'certificateResponse',
733
- identityKey: (await this.wallet.getPublicKey({ identityKey: true }, this.originator))
734
- .publicKey,
731
+ identityKey: await this.getIdentityPublicKey(),
735
732
  nonce: requestNonce,
736
733
  initialNonce: peerSession.sessionNonce,
737
734
  yourNonce: peerSession.peerNonce,
@@ -772,7 +769,7 @@ export class Peer {
772
769
 
773
770
  // Validate message signature
774
771
  const { valid } = await this.wallet.verifySignature({
775
- data: Utils.toArray(JSON.stringify(message.certificates), 'utf8'),
772
+ data: Peer.utf8ToBytes(JSON.stringify(message.certificates)),
776
773
  signature: message.signature as number[],
777
774
  protocolID: [2, 'auth message signature'],
778
775
  keyID: `${message.nonce ?? ''} ${peerSession.sessionNonce ?? ''}`,
@@ -846,4 +843,33 @@ export class Peer {
846
843
  cb(message.identityKey, message.payload ?? [])
847
844
  })
848
845
  }
846
+
847
+ private async getIdentityPublicKey (): Promise<string> {
848
+ if (this.identityPublicKey != null) {
849
+ return this.identityPublicKey
850
+ }
851
+ const { publicKey } = await this.wallet.getPublicKey(
852
+ { identityKey: true },
853
+ this.originator
854
+ )
855
+ this.identityPublicKey = publicKey
856
+ return publicKey
857
+ }
858
+
859
+ private static utf8ToBytes (data: string): number[] {
860
+ if (BufferCtor != null) {
861
+ return Array.from(BufferCtor.from(data, 'utf8'))
862
+ }
863
+ if (typeof TextEncoder !== 'undefined') {
864
+ return Array.from(new TextEncoder().encode(data))
865
+ }
866
+ return Utils.toArray(data, 'utf8')
867
+ }
868
+
869
+ private static base64ToBytes (data: string): number[] {
870
+ if (BufferCtor != null) {
871
+ return Array.from(BufferCtor.from(data, 'base64'))
872
+ }
873
+ return Utils.toArray(data, 'base64')
874
+ }
849
875
  }