@bsv/sdk 1.8.13 → 1.9.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 (89) 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/kvstore/LocalKVStore.js +7 -7
  5. package/dist/cjs/src/kvstore/LocalKVStore.js.map +1 -1
  6. package/dist/cjs/src/primitives/BigNumber.js +43 -31
  7. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  8. package/dist/cjs/src/primitives/Hash.js +11 -5
  9. package/dist/cjs/src/primitives/Hash.js.map +1 -1
  10. package/dist/cjs/src/primitives/SymmetricKey.js +15 -6
  11. package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
  12. package/dist/cjs/src/primitives/TransactionSignature.js +60 -18
  13. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  14. package/dist/cjs/src/primitives/utils.js +74 -28
  15. package/dist/cjs/src/primitives/utils.js.map +1 -1
  16. package/dist/cjs/src/script/Script.js +217 -108
  17. package/dist/cjs/src/script/Script.js.map +1 -1
  18. package/dist/cjs/src/script/Spend.js +5 -2
  19. package/dist/cjs/src/script/Spend.js.map +1 -1
  20. package/dist/cjs/src/transaction/Beef.js +62 -7
  21. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  22. package/dist/cjs/src/transaction/BeefTx.js +1 -1
  23. package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
  24. package/dist/cjs/src/transaction/Transaction.js +67 -35
  25. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  26. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  27. package/dist/esm/src/auth/Peer.js +36 -16
  28. package/dist/esm/src/auth/Peer.js.map +1 -1
  29. package/dist/esm/src/kvstore/LocalKVStore.js +7 -7
  30. package/dist/esm/src/kvstore/LocalKVStore.js.map +1 -1
  31. package/dist/esm/src/primitives/BigNumber.js +43 -31
  32. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  33. package/dist/esm/src/primitives/Hash.js +11 -5
  34. package/dist/esm/src/primitives/Hash.js.map +1 -1
  35. package/dist/esm/src/primitives/SymmetricKey.js +15 -6
  36. package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
  37. package/dist/esm/src/primitives/TransactionSignature.js +60 -18
  38. package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
  39. package/dist/esm/src/primitives/utils.js +74 -28
  40. package/dist/esm/src/primitives/utils.js.map +1 -1
  41. package/dist/esm/src/script/Script.js +222 -110
  42. package/dist/esm/src/script/Script.js.map +1 -1
  43. package/dist/esm/src/script/Spend.js +6 -2
  44. package/dist/esm/src/script/Spend.js.map +1 -1
  45. package/dist/esm/src/transaction/Beef.js +64 -7
  46. package/dist/esm/src/transaction/Beef.js.map +1 -1
  47. package/dist/esm/src/transaction/BeefTx.js +1 -1
  48. package/dist/esm/src/transaction/BeefTx.js.map +1 -1
  49. package/dist/esm/src/transaction/Transaction.js +69 -35
  50. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  51. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  52. package/dist/types/src/auth/Peer.d.ts +4 -0
  53. package/dist/types/src/auth/Peer.d.ts.map +1 -1
  54. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  55. package/dist/types/src/primitives/Hash.d.ts +10 -10
  56. package/dist/types/src/primitives/Hash.d.ts.map +1 -1
  57. package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
  58. package/dist/types/src/primitives/TransactionSignature.d.ts +34 -13
  59. package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
  60. package/dist/types/src/primitives/utils.d.ts +6 -8
  61. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  62. package/dist/types/src/script/Script.d.ts +18 -9
  63. package/dist/types/src/script/Script.d.ts.map +1 -1
  64. package/dist/types/src/script/Spend.d.ts +1 -0
  65. package/dist/types/src/script/Spend.d.ts.map +1 -1
  66. package/dist/types/src/transaction/Beef.d.ts +9 -0
  67. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  68. package/dist/types/src/transaction/Transaction.d.ts +7 -0
  69. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  70. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  71. package/dist/umd/bundle.js +3 -3
  72. package/dist/umd/bundle.js.map +1 -1
  73. package/docs/reference/primitives.md +87 -37
  74. package/docs/reference/script.md +11 -7
  75. package/docs/reference/transaction.md +2 -0
  76. package/package.json +1 -1
  77. package/src/auth/Peer.ts +44 -18
  78. package/src/kvstore/LocalKVStore.ts +7 -7
  79. package/src/kvstore/__tests/LocalKVStore.test.ts +17 -17
  80. package/src/primitives/BigNumber.ts +44 -23
  81. package/src/primitives/Hash.ts +41 -17
  82. package/src/primitives/SymmetricKey.ts +15 -6
  83. package/src/primitives/TransactionSignature.ts +77 -31
  84. package/src/primitives/utils.ts +80 -30
  85. package/src/script/Script.ts +238 -104
  86. package/src/script/Spend.ts +7 -3
  87. package/src/transaction/Beef.ts +74 -7
  88. package/src/transaction/BeefTx.ts +1 -1
  89. package/src/transaction/Transaction.ts +77 -34
@@ -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
@@ -5309,7 +5356,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5309
5356
  ### Variable: hash160
5310
5357
 
5311
5358
  ```ts
5312
- hash160 = (msg: number[] | string, enc?: "hex" | "utf8"): number[] => {
5359
+ hash160 = (msg: Uint8Array | number[] | string, enc?: "hex" | "utf8"): number[] => {
5313
5360
  const first = new SHA256().update(msg, enc).digest();
5314
5361
  return new RIPEMD160().update(first).digest();
5315
5362
  }
@@ -5323,7 +5370,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5323
5370
  ### Variable: hash256
5324
5371
 
5325
5372
  ```ts
5326
- hash256 = (msg: number[] | string, enc?: "hex" | "utf8"): number[] => {
5373
+ hash256 = (msg: Uint8Array | number[] | string, enc?: "hex" | "utf8"): number[] => {
5327
5374
  const first = new SHA256().update(msg, enc).digest();
5328
5375
  return new SHA256().update(first).digest();
5329
5376
  }
@@ -5655,7 +5702,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5655
5702
  ### Variable: sha256
5656
5703
 
5657
5704
  ```ts
5658
- sha256 = (msg: number[] | string, enc?: "hex" | "utf8"): number[] => {
5705
+ sha256 = (msg: Uint8Array | number[] | string, enc?: "hex" | "utf8"): number[] => {
5659
5706
  return new SHA256().update(msg, enc).digest();
5660
5707
  }
5661
5708
  ```
@@ -5668,7 +5715,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5668
5715
  ### Variable: sha256hmac
5669
5716
 
5670
5717
  ```ts
5671
- sha256hmac = (key: number[] | string, msg: number[] | string, enc?: "hex"): number[] => {
5718
+ sha256hmac = (key: Uint8Array | number[] | string, msg: Uint8Array | number[] | string, enc?: "hex"): number[] => {
5672
5719
  return new SHA256HMAC(key).update(msg, enc).digest();
5673
5720
  }
5674
5721
  ```
@@ -5694,7 +5741,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5694
5741
  ### Variable: sha512hmac
5695
5742
 
5696
5743
  ```ts
5697
- sha512hmac = (key: number[] | string, msg: number[] | string, enc?: "hex"): number[] => {
5744
+ sha512hmac = (key: Uint8Array | number[] | string, msg: Uint8Array | number[] | string, enc?: "hex"): number[] => {
5698
5745
  return new SHA512HMAC(key).update(msg, enc).digest();
5699
5746
  }
5700
5747
  ```
@@ -5851,16 +5898,19 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
5851
5898
 
5852
5899
  ```ts
5853
5900
  toHex = (msg: number[]): string => {
5854
- let res = "";
5855
- for (const num of msg) {
5856
- res += zero2(num.toString(16));
5901
+ if (CAN_USE_BUFFER) {
5902
+ return BufferCtor.from(msg).toString("hex");
5857
5903
  }
5858
- return res;
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];
5909
+ }
5910
+ return out.join("");
5859
5911
  }
5860
5912
  ```
5861
5913
 
5862
- See also: [zero2](./primitives.md#variable-zero2)
5863
-
5864
5914
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
5865
5915
 
5866
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.8.13",
3
+ "version": "1.9.1",
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
  }
@@ -115,7 +115,7 @@ export default class LocalKVStore {
115
115
  tagQueryMode: 'all',
116
116
  include: 'entire transactions',
117
117
  limit
118
- })
118
+ }, this.originator)
119
119
  return results
120
120
  }
121
121
 
@@ -175,7 +175,7 @@ export default class LocalKVStore {
175
175
  const { plaintext } = await this.wallet.decrypt({
176
176
  ...this.getProtocol(key),
177
177
  ciphertext: field
178
- })
178
+ }, this.originator)
179
179
  r.value = Utils.toUTF8(plaintext)
180
180
  }
181
181
  return r
@@ -241,7 +241,7 @@ export default class LocalKVStore {
241
241
  const { ciphertext } = await this.wallet.encrypt({
242
242
  ...protocol,
243
243
  plaintext: valueAsArray
244
- })
244
+ }, this.originator)
245
245
  valueAsArray = ciphertext
246
246
  }
247
247
 
@@ -272,7 +272,7 @@ export default class LocalKVStore {
272
272
  acceptDelayedBroadcast: this.acceptDelayedBroadcast,
273
273
  randomizeOutputs: false
274
274
  }
275
- })
275
+ }, this.originator)
276
276
 
277
277
  if (outputs.length > 0 && typeof signableTransaction !== 'object') {
278
278
  throw new Error('Wallet did not return a signable transaction when expected.')
@@ -285,7 +285,7 @@ export default class LocalKVStore {
285
285
  const { txid } = await this.wallet.signAction({
286
286
  reference: signableTransaction.reference,
287
287
  spends
288
- })
288
+ }, this.originator)
289
289
  outpoint = `${txid as string}.0`
290
290
  }
291
291
  } catch (error) {
@@ -326,7 +326,7 @@ export default class LocalKVStore {
326
326
  options: {
327
327
  acceptDelayedBroadcast: this.acceptDelayedBroadcast
328
328
  }
329
- })
329
+ }, this.originator)
330
330
  if (typeof signableTransaction !== 'object') {
331
331
  throw new Error('Wallet did not return a signable transaction when expected.')
332
332
  }
@@ -334,7 +334,7 @@ export default class LocalKVStore {
334
334
  const { txid } = await this.wallet.signAction({
335
335
  reference: signableTransaction.reference,
336
336
  spends
337
- })
337
+ }, this.originator)
338
338
  if (txid === undefined) { throw new Error('signAction must return a valid txid') }
339
339
  txids.push(txid)
340
340
  } catch (error) {
@@ -104,7 +104,7 @@ describe('localKVStore', () => {
104
104
  // const testUnlockingScriptHex = 'mockUnlockingScriptHex'; // Defined above
105
105
 
106
106
  beforeEach(() => {
107
- // Reset mocks before each test (clears calls and resets implementations)
107
+ // Reset mocks before each test (clears calls and resets implementations)
108
108
  jest.clearAllMocks()
109
109
 
110
110
  // Create a fresh mock wallet for each test
@@ -122,7 +122,7 @@ describe('localKVStore', () => {
122
122
  // --- Constructor Tests ---
123
123
  describe('constructor', () => {
124
124
  it('should create an instance with default wallet and encrypt=true', () => {
125
- // We need to mock the default WalletClient if the SUT uses it
125
+ // We need to mock the default WalletClient if the SUT uses it
126
126
  const MockedWalletClient = require('../../../mod.js').WalletClient
127
127
  const store = new LocalKVStore(undefined, 'default-context')
128
128
  expect(store).toBeInstanceOf(LocalKVStore)
@@ -200,7 +200,7 @@ describe('localKVStore', () => {
200
200
  let pushDropInstance: PushDrop // To access the instance methods
201
201
 
202
202
  beforeEach(() => {
203
- // Get the mock instance that will be created by `new PushDrop()`
203
+ // Get the mock instance that will be created by `new PushDrop()`
204
204
  pushDropInstance = new (PushDrop as any)()
205
205
  })
206
206
 
@@ -223,7 +223,7 @@ describe('localKVStore', () => {
223
223
  plaintext: valueArray, // Should be Array<number>
224
224
  protocolID: [2, testContext],
225
225
  keyID: testKey
226
- })
226
+ }, undefined)
227
227
  // Check the mock instance's lock method
228
228
  expect(mockPDInstance.lock).toHaveBeenCalledWith(
229
229
  // The lock function expects Array<number[] | Uint8Array>
@@ -250,7 +250,7 @@ describe('localKVStore', () => {
250
250
  acceptDelayedBroadcast: false,
251
251
  randomizeOutputs: false
252
252
  }
253
- })
253
+ }, undefined)
254
254
  expect(mockWallet.signAction).not.toHaveBeenCalled()
255
255
  expect(mockWallet.relinquishOutput).not.toHaveBeenCalled()
256
256
  })
@@ -293,7 +293,7 @@ describe('localKVStore', () => {
293
293
  acceptDelayedBroadcast: false,
294
294
  randomizeOutputs: false
295
295
  }
296
- })
296
+ }, undefined)
297
297
  expect(mockWallet.signAction).not.toHaveBeenCalled()
298
298
  expect(mockWallet.relinquishOutput).not.toHaveBeenCalled()
299
299
  })
@@ -301,7 +301,7 @@ describe('localKVStore', () => {
301
301
  it('should update an existing output (spend and create)', async () => {
302
302
  const existingOutpoint = 'oldTxId.0'
303
303
  const existingOutput = { outpoint: existingOutpoint, txid: 'oldTxId', vout: 0, lockingScript: 'oldScriptHex' } // Added script
304
- const mockBEEF = [1,2,3,4,5,6]
304
+ const mockBEEF = [1, 2, 3, 4, 5, 6]
305
305
  const signableRef = 'signableTxRef123'
306
306
  const signableTx = []
307
307
  const updatedTxId = 'updatedTxId'
@@ -366,7 +366,7 @@ describe('localKVStore', () => {
366
366
  outputs: expect.arrayContaining([ // Check outputs array
367
367
  expect.objectContaining({ lockingScript: testLockingScriptHex }) // Check the new output script
368
368
  ])
369
- }))
369
+ }), undefined)
370
370
 
371
371
  // Verify signing steps
372
372
  expect(MockedTransaction.fromAtomicBEEF).toHaveBeenCalledWith(signableTx)
@@ -383,7 +383,7 @@ describe('localKVStore', () => {
383
383
  spends: {
384
384
  0: { unlockingScript: testUnlockingScriptHex } // Check unlocking script from mock sign result
385
385
  }
386
- })
386
+ }, undefined)
387
387
  expect(mockWallet.relinquishOutput).not.toHaveBeenCalled()
388
388
  })
389
389
 
@@ -395,7 +395,7 @@ describe('localKVStore', () => {
395
395
  const existingOutpoint2 = 'oldTxId2.1'
396
396
  const existingOutput1 = { outpoint: existingOutpoint1, txid: 'oldTxId1', vout: 0, lockingScript: 's1' }
397
397
  const existingOutput2 = { outpoint: existingOutpoint2, txid: 'oldTxId2', vout: 1, lockingScript: 's2' }
398
- const mockBEEF = [1,2,3,4,5,6]
398
+ const mockBEEF = [1, 2, 3, 4, 5, 6]
399
399
  const signableRef = 'signableTxRefMulti'
400
400
  const signableTx = []
401
401
  const updatedTxId = 'updatedTxIdMulti'
@@ -457,7 +457,7 @@ describe('localKVStore', () => {
457
457
  outputs: expect.arrayContaining([
458
458
  expect.objectContaining({ lockingScript: testLockingScriptHex })
459
459
  ])
460
- }))
460
+ }), undefined)
461
461
 
462
462
  // Verify signing loop
463
463
  expect(MockedTransaction.fromAtomicBEEF).toHaveBeenCalledWith(signableTx)
@@ -478,14 +478,14 @@ describe('localKVStore', () => {
478
478
  0: { unlockingScript: testUnlockingScriptHex }, // Same mock script for both
479
479
  1: { unlockingScript: testUnlockingScriptHex }
480
480
  }
481
- })
481
+ }, undefined)
482
482
  expect(mockWallet.relinquishOutput).not.toHaveBeenCalled()
483
483
  })
484
484
 
485
485
  it('should preserve original error message when createAction fails', async () => {
486
486
  const originalErrorMessage = 'Network connection timeout while creating transaction'
487
487
  const originalError = new Error(originalErrorMessage)
488
-
488
+
489
489
  // Mock the lookupValue to return a value that differs from what we're setting
490
490
  // to ensure set() will attempt to create a transaction
491
491
  const mockedLor: ListOutputsResult = {
@@ -533,7 +533,7 @@ describe('localKVStore', () => {
533
533
  let pushDropInstance: PushDrop // To access the instance methods
534
534
 
535
535
  beforeEach(() => {
536
- // Get the mock instance that will be created by `new PushDrop()`
536
+ // Get the mock instance that will be created by `new PushDrop()`
537
537
  pushDropInstance = new (PushDrop as any)()
538
538
  })
539
539
 
@@ -598,7 +598,7 @@ describe('localKVStore', () => {
598
598
  options: {
599
599
  acceptDelayedBroadcast: false
600
600
  }
601
- })
601
+ }, undefined)
602
602
  // Check that outputs key is absent
603
603
  expect(mockWallet.createAction.mock.calls[0][0]).not.toHaveProperty('outputs')
604
604
 
@@ -619,7 +619,7 @@ describe('localKVStore', () => {
619
619
  0: { unlockingScript: testUnlockingScriptHex },
620
620
  1: { unlockingScript: testUnlockingScriptHex }
621
621
  }
622
- })
622
+ }, undefined)
623
623
  expect(mockWallet.relinquishOutput).not.toHaveBeenCalled()
624
624
  })
625
625
 
@@ -659,7 +659,7 @@ describe('localKVStore', () => {
659
659
  it('should preserve original error message when wallet operations fail during removal', async () => {
660
660
  const originalErrorMessage = 'Insufficient funds to cover transaction fees'
661
661
  const originalError = new Error(originalErrorMessage)
662
-
662
+
663
663
  const existingOutpoint = 'failTxId.0'
664
664
  const existingOutput = { outpoint: existingOutpoint, txid: 'failTxId', vout: 0, lockingScript: 's1' }
665
665
  const mockBEEF = Buffer.from('mockBEEFFail')