@bsv/sdk 1.2.2 → 1.2.4

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 (72) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/auth/Certificate.js +1 -1
  3. package/dist/cjs/src/auth/Certificate.js.map +1 -1
  4. package/dist/cjs/src/overlay-tools/LookupResolver.js +8 -5
  5. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  6. package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
  7. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +2 -1
  8. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  9. package/dist/cjs/src/transaction/Beef.js +19 -10
  10. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  11. package/dist/cjs/src/transaction/Transaction.js +38 -6
  12. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  13. package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -1
  14. package/dist/cjs/src/wallet/KeyDeriver.js.map +1 -1
  15. package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
  16. package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
  17. package/dist/cjs/src/wallet/WalletError.js.map +1 -1
  18. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  19. package/dist/esm/src/auth/Certificate.js +1 -1
  20. package/dist/esm/src/auth/Certificate.js.map +1 -1
  21. package/dist/esm/src/overlay-tools/LookupResolver.js +8 -5
  22. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  23. package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
  24. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js +2 -1
  25. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  26. package/dist/esm/src/transaction/Beef.js +19 -10
  27. package/dist/esm/src/transaction/Beef.js.map +1 -1
  28. package/dist/esm/src/transaction/Transaction.js +38 -6
  29. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  30. package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -1
  31. package/dist/esm/src/wallet/KeyDeriver.js.map +1 -1
  32. package/dist/esm/src/wallet/ProtoWallet.js.map +1 -1
  33. package/dist/esm/src/wallet/WalletClient.js.map +1 -1
  34. package/dist/esm/src/wallet/WalletError.js.map +1 -1
  35. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  36. package/dist/types/src/auth/Certificate.d.ts.map +1 -1
  37. package/dist/types/src/overlay-tools/LookupResolver.d.ts +10 -3
  38. package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
  39. package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts.map +1 -1
  40. package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts.map +1 -1
  41. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  42. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  43. package/dist/types/src/wallet/CachedKeyDeriver.d.ts.map +1 -1
  44. package/dist/types/src/wallet/KeyDeriver.d.ts.map +1 -1
  45. package/dist/types/src/wallet/ProtoWallet.d.ts.map +1 -1
  46. package/dist/types/src/wallet/Wallet.interfaces.d.ts +11 -11
  47. package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -1
  48. package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
  49. package/dist/types/src/wallet/WalletError.d.ts.map +1 -1
  50. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  51. package/dist/umd/bundle.js +1 -1
  52. package/docs/overlay-tools.md +19 -4
  53. package/package.json +1 -1
  54. package/src/auth/Certificate.ts +9 -9
  55. package/src/auth/index.ts +1 -1
  56. package/src/overlay-tools/LookupResolver.ts +25 -9
  57. package/src/overlay-tools/OverlayAdminTokenTemplate.ts +4 -4
  58. package/src/overlay-tools/SHIPBroadcaster.ts +11 -9
  59. package/src/overlay-tools/__tests/LookupResolver.test.ts +83 -42
  60. package/src/overlay-tools/__tests/SHIPBroadcaster.test.ts +5 -5
  61. package/src/overlay-tools/index.ts +1 -1
  62. package/src/transaction/Beef.ts +33 -48
  63. package/src/transaction/BeefParty.ts +4 -4
  64. package/src/transaction/BeefTx.ts +1 -1
  65. package/src/transaction/Transaction.ts +38 -10
  66. package/src/transaction/__tests/Transaction.test.ts +133 -4
  67. package/src/wallet/CachedKeyDeriver.ts +10 -10
  68. package/src/wallet/KeyDeriver.ts +8 -8
  69. package/src/wallet/ProtoWallet.ts +176 -176
  70. package/src/wallet/Wallet.interfaces.ts +19 -19
  71. package/src/wallet/WalletClient.ts +30 -30
  72. package/src/wallet/WalletError.ts +2 -2
@@ -140,9 +140,9 @@ export default class Transaction {
140
140
  const validTxids = new Set<string>()
141
141
  // All BUMP level 0 hashes are valid.
142
142
  for (const bump of BUMPs) {
143
- for (const n of bump.path[0])
144
- if (n.hash)
145
- validTxids.add(n.hash)
143
+ for (const n of bump.path[0]) {
144
+ if (n.hash) { validTxids.add(n.hash) }
145
+ }
146
146
  }
147
147
  // To keep track of which transactions were used.
148
148
  const unusedTxTxids = new Set<string>()
@@ -524,17 +524,47 @@ export default class Transaction {
524
524
  }
525
525
 
526
526
  // Distribute change among change outputs
527
+ let distributedChange = 0
527
528
  if (changeDistribution === 'random') {
528
- // TODO
529
- throw new Error('Not yet implemented')
529
+ // Implement Benford's Law distribution for change outputs
530
+ const changeOutputs = this.outputs.filter(out => out.change)
531
+ let changeToUse = change
532
+
533
+ // Helper function to generate a number approximating Benford's Law
534
+ const benfordNumber = (min: number, max: number): number => {
535
+ const d = Math.floor(Math.random() * 9) + 1
536
+ return Math.floor(min + (max - min) * Math.log10(1 + 1 / d) / Math.log10(10))
537
+ }
538
+
539
+ const benfordNumbers = Array(changeOutputs.length).fill(1)
540
+ changeToUse -= changeOutputs.length
541
+ distributedChange += changeOutputs.length
542
+ for (let i = 0; i < changeOutputs.length - 1; i++) {
543
+ const portion = benfordNumber(0, changeToUse)
544
+ benfordNumbers[i] += portion
545
+ distributedChange += portion
546
+ changeToUse -= portion
547
+ }
548
+
549
+ for (let i = 0; i < this.outputs.length; i++) {
550
+ if (this.outputs[i].change) {
551
+ const t = benfordNumbers.shift()
552
+ this.outputs[i].satoshis = t
553
+ }
554
+ }
530
555
  } else if (changeDistribution === 'equal') {
531
556
  const perOutput = Math.floor(change / changeCount)
532
557
  for (const out of this.outputs) {
533
558
  if (out.change) {
559
+ distributedChange += perOutput
534
560
  out.satoshis = perOutput
535
561
  }
536
562
  }
537
563
  }
564
+ // if there's any remaining change, add it to the last output
565
+ if (distributedChange < change) {
566
+ this.outputs[this.outputs.length - 1].satoshis += (change - distributedChange)
567
+ }
538
568
  }
539
569
 
540
570
  /**
@@ -868,13 +898,14 @@ export default class Transaction {
868
898
 
869
899
  /**
870
900
  * Serializes this transaction, together with its inputs and the respective merkle proofs, into the BEEF (BRC-62) format. This enables efficient verification of its compliance with the rules of SPV.
871
- *
901
+ *
872
902
  * @param allowPartial If true, error will not be thrown if there are any missing sourceTransactions.
873
903
  *
874
904
  * @returns The serialized BEEF structure
875
905
  * @throws Error if there are any missing sourceTransactions unless `allowPartial` is true.
876
906
  */
877
907
  toBEEF (allowPartial?: boolean): number[] {
908
+ this.outputs.length
878
909
  const writer = new Writer()
879
910
  writer.writeUInt32LE(4022206465)
880
911
  const BUMPs: MerklePath[] = []
@@ -919,10 +950,7 @@ export default class Transaction {
919
950
  if (!hasProof) {
920
951
  for (let i = 0; i < tx.inputs.length; i++) {
921
952
  const input = tx.inputs[i]
922
- if (typeof input.sourceTransaction === 'object')
923
- addPathsAndInputs(input.sourceTransaction)
924
- else if (!allowPartial)
925
- throw new Error('A required source transaction is missing!')
953
+ if (typeof input.sourceTransaction === 'object') { addPathsAndInputs(input.sourceTransaction) } else if (!allowPartial) { throw new Error('A required source transaction is missing!') }
926
954
  }
927
955
  }
928
956
  }
@@ -346,7 +346,7 @@ describe('Transaction', () => {
346
346
  // 4000 sats in - 1000 sats out - 1033 sats fee = expected 1967 sats change
347
347
  expect(spendTx.outputs[1].satoshis).toEqual(1967)
348
348
  })
349
- it('Distributes change among multiple change outputs', async () => {
349
+ it('Distributes change equally among multiple change outputs', async () => {
350
350
  const privateKey = new PrivateKey(1)
351
351
  const publicKey = new Curve().g.mul(privateKey)
352
352
  const publicKeyHash = hash160(publicKey.encode(true)) as number[]
@@ -369,17 +369,146 @@ describe('Transaction', () => {
369
369
  }, {
370
370
  lockingScript: p2pkh.lock(publicKeyHash),
371
371
  change: true
372
+ }, {
373
+ lockingScript: p2pkh.lock(publicKeyHash),
374
+ change: true
375
+ }, {
376
+ lockingScript: p2pkh.lock(publicKeyHash),
377
+ change: true
372
378
  }], 0)
373
379
  expect(spendTx.outputs[1].satoshis).not.toBeDefined()
374
380
  expect(spendTx.outputs[2].satoshis).not.toBeDefined()
381
+ expect(spendTx.outputs[3].satoshis).not.toBeDefined()
382
+ expect(spendTx.outputs[4].satoshis).not.toBeDefined()
375
383
  await spendTx.fee({
376
384
  // Our custom fee model will always charge 1033 sats for a tx.
377
- computeFee: async () => 1033
385
+ computeFee: async () => 1032
378
386
  })
379
387
  // 4000 sats in - 1000 sats out - 1033 sats fee = expected 1967 sats change
380
388
  // Divide by 2 (no remainder) = 983 sats per change output
381
- expect(spendTx.outputs[1].satoshis).toEqual(983)
382
- expect(spendTx.outputs[2].satoshis).toEqual(983)
389
+ expect(spendTx.outputs[0].satoshis).toEqual(1000)
390
+ expect(spendTx.outputs[1].satoshis).toEqual(492)
391
+ expect(spendTx.outputs[2].satoshis).toEqual(492)
392
+ expect(spendTx.outputs[3].satoshis).toEqual(492)
393
+ expect(spendTx.outputs[4].satoshis).toEqual(492)
394
+ })
395
+ it('Distributes change randomly among multiple change outputs', async () => {
396
+ const privateKey = new PrivateKey(1)
397
+ const publicKey = new Curve().g.mul(privateKey)
398
+ const publicKeyHash = hash160(publicKey.encode(true)) as number[]
399
+ const p2pkh = new P2PKH()
400
+ const sourceTx = new Transaction(1, [], [{
401
+ lockingScript: p2pkh.lock(publicKeyHash),
402
+ satoshis: 900
403
+ }], 0)
404
+ const spendTx = new Transaction(1, [{
405
+ sourceTransaction: sourceTx,
406
+ sourceOutputIndex: 0,
407
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
408
+ sequence: 0xffffffff
409
+ }], [{
410
+ satoshis: 1,
411
+ lockingScript: p2pkh.lock(publicKeyHash)
412
+ }, {
413
+ lockingScript: p2pkh.lock(publicKeyHash),
414
+ change: true
415
+ }, {
416
+ lockingScript: p2pkh.lock(publicKeyHash),
417
+ change: true
418
+ }, {
419
+ lockingScript: p2pkh.lock(publicKeyHash),
420
+ change: true
421
+ }, {
422
+ lockingScript: p2pkh.lock(publicKeyHash),
423
+ change: true
424
+ }, {
425
+ lockingScript: p2pkh.lock(publicKeyHash),
426
+ change: true
427
+ }, {
428
+ lockingScript: p2pkh.lock(publicKeyHash),
429
+ change: true
430
+ }], 0)
431
+ expect(spendTx.outputs[1].satoshis).not.toBeDefined()
432
+ expect(spendTx.outputs[2].satoshis).not.toBeDefined()
433
+ expect(spendTx.outputs[3].satoshis).not.toBeDefined()
434
+ expect(spendTx.outputs[4].satoshis).not.toBeDefined()
435
+ expect(spendTx.outputs[5].satoshis).not.toBeDefined()
436
+ expect(spendTx.outputs[6].satoshis).not.toBeDefined()
437
+ await spendTx.fee({
438
+ computeFee: async () => 3
439
+ }, 'random')
440
+ expect(spendTx.outputs[0].satoshis).toEqual(1)
441
+ expect(spendTx.outputs.reduce((a, b) => a + b.satoshis, 0)).toEqual(897)
442
+ })
443
+ it('Distributes change randomly among multiple change outputs, with one set output', async () => {
444
+ const privateKey = new PrivateKey(1)
445
+ const publicKey = new Curve().g.mul(privateKey)
446
+ const publicKeyHash = hash160(publicKey.encode(true)) as number[]
447
+ const p2pkh = new P2PKH()
448
+ const sourceTx = new Transaction(1, [], [{
449
+ lockingScript: p2pkh.lock(publicKeyHash),
450
+ satoshis: 9
451
+ }], 0)
452
+ const spendTx = new Transaction(1, [{
453
+ sourceTransaction: sourceTx,
454
+ sourceOutputIndex: 0,
455
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
456
+ sequence: 0xffffffff
457
+ }], [{
458
+ satoshis: 1,
459
+ lockingScript: p2pkh.lock(publicKeyHash)
460
+ }, {
461
+ lockingScript: p2pkh.lock(publicKeyHash),
462
+ change: true
463
+ }, {
464
+ lockingScript: p2pkh.lock(publicKeyHash),
465
+ change: true
466
+ }, {
467
+ lockingScript: p2pkh.lock(publicKeyHash),
468
+ change: true
469
+ }, {
470
+ lockingScript: p2pkh.lock(publicKeyHash),
471
+ change: true
472
+ }, {
473
+ lockingScript: p2pkh.lock(publicKeyHash),
474
+ change: true
475
+ }, {
476
+ lockingScript: p2pkh.lock(publicKeyHash),
477
+ change: true
478
+ }], 0)
479
+ expect(spendTx.outputs[1].satoshis).not.toBeDefined()
480
+ expect(spendTx.outputs[2].satoshis).not.toBeDefined()
481
+ expect(spendTx.outputs[3].satoshis).not.toBeDefined()
482
+ expect(spendTx.outputs[4].satoshis).not.toBeDefined()
483
+ expect(spendTx.outputs[5].satoshis).not.toBeDefined()
484
+ expect(spendTx.outputs[6].satoshis).not.toBeDefined()
485
+ await spendTx.fee({
486
+ computeFee: async () => 1
487
+ }, 'random')
488
+ expect(spendTx.outputs.reduce((a, b) => a + b.satoshis, 0)).toEqual(8)
489
+ })
490
+ it('Distributes change randomly among multiple change outputs, thinnly spread', async () => {
491
+ const privateKey = new PrivateKey(1)
492
+ const publicKey = new Curve().g.mul(privateKey)
493
+ const publicKeyHash = hash160(publicKey.encode(true)) as number[]
494
+ const p2pkh = new P2PKH()
495
+ const sourceTx = new Transaction(1, [], [{
496
+ lockingScript: p2pkh.lock(publicKeyHash),
497
+ satoshis: 46
498
+ }], 0)
499
+ const spendTx = new Transaction(1, [{
500
+ sourceTransaction: sourceTx,
501
+ sourceOutputIndex: 0,
502
+ unlockingScriptTemplate: p2pkh.unlock(privateKey),
503
+ sequence: 0xffffffff
504
+ }], Array(21).fill(null).map(() => ({
505
+ lockingScript: p2pkh.lock(publicKeyHash),
506
+ change: true
507
+ })), 0)
508
+ await spendTx.fee({
509
+ computeFee: async () => 1
510
+ }, 'random')
511
+ expect(spendTx.outputs.reduce((a, b) => a + b.satoshis, 0)).toEqual(45)
383
512
  })
384
513
  it('Calculates fee for utxo based transaction', async () => {
385
514
  const utxos = [ // WoC format utxos
@@ -17,7 +17,7 @@ export default class CachedKeyDeriver {
17
17
  * @param {Object} [options] - Optional settings for the cache.
18
18
  * @param {number} [options.maxCacheSize=1000] - The maximum number of entries to store in the cache.
19
19
  */
20
- constructor(rootKey: PrivateKey | 'anyone', options?: { maxCacheSize?: number }) {
20
+ constructor (rootKey: PrivateKey | 'anyone', options?: { maxCacheSize?: number }) {
21
21
  this.keyDeriver = new KeyDeriver(rootKey)
22
22
  this.cache = new Map<string, any>()
23
23
  this.maxCacheSize = options?.maxCacheSize || 1000
@@ -32,7 +32,7 @@ export default class CachedKeyDeriver {
32
32
  * @param {boolean} [forSelf=false] - Whether deriving for self.
33
33
  * @returns {PublicKey} - The derived public key.
34
34
  */
35
- derivePublicKey(
35
+ derivePublicKey (
36
36
  protocolID: [0 | 1 | 2, string],
37
37
  keyID: string,
38
38
  counterparty: PublicKey | string | 'self' | 'anyone',
@@ -56,7 +56,7 @@ export default class CachedKeyDeriver {
56
56
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
57
57
  * @returns {PrivateKey} - The derived private key.
58
58
  */
59
- derivePrivateKey(
59
+ derivePrivateKey (
60
60
  protocolID: [0 | 1 | 2, string],
61
61
  keyID: string,
62
62
  counterparty: PublicKey | string | 'self' | 'anyone'
@@ -80,7 +80,7 @@ export default class CachedKeyDeriver {
80
80
  * @returns {SymmetricKey} - The derived symmetric key.
81
81
  * @throws {Error} - Throws an error if attempting to derive a symmetric key for 'anyone'.
82
82
  */
83
- deriveSymmetricKey(
83
+ deriveSymmetricKey (
84
84
  protocolID: [0 | 1 | 2, string],
85
85
  keyID: string,
86
86
  counterparty: PublicKey | string | 'self' | 'anyone'
@@ -102,7 +102,7 @@ export default class CachedKeyDeriver {
102
102
  * @returns {number[]} - The shared secret as a number array.
103
103
  * @throws {Error} - Throws an error if attempting to reveal a shared secret for 'self'.
104
104
  */
105
- revealCounterpartySecret(counterparty: PublicKey | string | 'self' | 'anyone'): number[] {
105
+ revealCounterpartySecret (counterparty: PublicKey | string | 'self' | 'anyone'): number[] {
106
106
  const cacheKey = this.generateCacheKey('revealCounterpartySecret', counterparty)
107
107
  if (this.cache.has(cacheKey)) {
108
108
  return this.cacheGet(cacheKey)
@@ -121,7 +121,7 @@ export default class CachedKeyDeriver {
121
121
  * @param {string} keyID - The key identifier.
122
122
  * @returns {number[]} - The specific key association as a number array.
123
123
  */
124
- revealSpecificSecret(
124
+ revealSpecificSecret (
125
125
  counterparty: PublicKey | string | 'self' | 'anyone',
126
126
  protocolID: [0 | 1 | 2, string],
127
127
  keyID: string
@@ -142,7 +142,7 @@ export default class CachedKeyDeriver {
142
142
  * @param {...any} args - The arguments passed to the method.
143
143
  * @returns {string} - The generated cache key.
144
144
  */
145
- private generateCacheKey(methodName: string, ...args: any[]): string {
145
+ private generateCacheKey (methodName: string, ...args: any[]): string {
146
146
  const serializedArgs = args.map((arg) => this.serializeArgument(arg)).join('|')
147
147
  return `${methodName}|${serializedArgs}`
148
148
  }
@@ -152,7 +152,7 @@ export default class CachedKeyDeriver {
152
152
  * @param {any} arg - The argument to serialize.
153
153
  * @returns {string} - The serialized argument.
154
154
  */
155
- private serializeArgument(arg: any): string {
155
+ private serializeArgument (arg: any): string {
156
156
  if (arg instanceof PublicKey || arg instanceof PrivateKey) {
157
157
  return arg.toString()
158
158
  } else if (Array.isArray(arg)) {
@@ -169,7 +169,7 @@ export default class CachedKeyDeriver {
169
169
  * @param {string} cacheKey - The key of the cached item.
170
170
  * @returns {any} - The cached value.
171
171
  */
172
- private cacheGet(cacheKey: string): any {
172
+ private cacheGet (cacheKey: string): any {
173
173
  const value = this.cache.get(cacheKey)
174
174
  // Update the entry to reflect recent use
175
175
  this.cache.delete(cacheKey)
@@ -182,7 +182,7 @@ export default class CachedKeyDeriver {
182
182
  * @param {string} cacheKey - The key of the item to cache.
183
183
  * @param {any} value - The value to cache.
184
184
  */
185
- private cacheSet(cacheKey: string, value: any): void {
185
+ private cacheSet (cacheKey: string, value: any): void {
186
186
  if (this.cache.size >= this.maxCacheSize) {
187
187
  // Evict the least recently used item (first item in Map)
188
188
  const firstKey = this.cache.keys().next().value
@@ -11,7 +11,7 @@ export default class KeyDeriver {
11
11
  * Initializes the KeyDeriver instance with a root private key.
12
12
  * @param {PrivateKey | 'anyone'} rootKey - The root private key or the string 'anyone'.
13
13
  */
14
- constructor(rootKey: PrivateKey | 'anyone') {
14
+ constructor (rootKey: PrivateKey | 'anyone') {
15
15
  if (rootKey === 'anyone') {
16
16
  this.rootKey = new PrivateKey(1)
17
17
  } else {
@@ -27,7 +27,7 @@ export default class KeyDeriver {
27
27
  * @param {boolean} [forSelf=false] - Whether deriving for self.
28
28
  * @returns {PublicKey} - The derived public key.
29
29
  */
30
- derivePublicKey(protocolID: [0 | 1 | 2, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone', forSelf: boolean = false): PublicKey {
30
+ derivePublicKey (protocolID: [0 | 1 | 2, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone', forSelf: boolean = false): PublicKey {
31
31
  counterparty = this.normalizeCounterparty(counterparty)
32
32
  if (forSelf) {
33
33
  return this.rootKey.deriveChild(counterparty, this.computeInvoiceNumber(protocolID, keyID)).toPublicKey()
@@ -43,7 +43,7 @@ export default class KeyDeriver {
43
43
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
44
44
  * @returns {PrivateKey} - The derived private key.
45
45
  */
46
- derivePrivateKey(protocolID: [0 | 1 | 2, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone'): PrivateKey {
46
+ derivePrivateKey (protocolID: [0 | 1 | 2, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone'): PrivateKey {
47
47
  counterparty = this.normalizeCounterparty(counterparty)
48
48
  return this.rootKey.deriveChild(counterparty, this.computeInvoiceNumber(protocolID, keyID))
49
49
  }
@@ -57,7 +57,7 @@ export default class KeyDeriver {
57
57
  * @returns {SymmetricKey} - The derived symmetric key.
58
58
  * @throws {Error} - Throws an error if attempting to derive a symmetric key for 'anyone'.
59
59
  */
60
- deriveSymmetricKey(protocolID: [0 | 1 | 2, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone'): SymmetricKey {
60
+ deriveSymmetricKey (protocolID: [0 | 1 | 2, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone'): SymmetricKey {
61
61
  if (counterparty === 'anyone') {
62
62
  throw new Error(
63
63
  'Symmetric keys (such as encryption keys or HMAC keys) should not be derivable by everyone, because messages would be decryptable by anyone who knows the identity public key of the user, and HMACs would be similarly forgeable.'
@@ -76,7 +76,7 @@ export default class KeyDeriver {
76
76
  * @returns {number[]} - The shared secret as a number array.
77
77
  * @throws {Error} - Throws an error if attempting to reveal a shared secret for 'self'.
78
78
  */
79
- revealCounterpartySecret(counterparty: PublicKey | string | 'self' | 'anyone'): number[] {
79
+ revealCounterpartySecret (counterparty: PublicKey | string | 'self' | 'anyone'): number[] {
80
80
  if (counterparty === 'self') {
81
81
  throw new Error('Counterparty secrets cannot be revealed for counterparty=self.')
82
82
  }
@@ -101,7 +101,7 @@ export default class KeyDeriver {
101
101
  * @param {string} keyID - The key identifier.
102
102
  * @returns {number[]} - The specific key association as a number array.
103
103
  */
104
- revealSpecificSecret(counterparty: PublicKey | string | 'self' | 'anyone', protocolID: [0 | 1 | 2, string], keyID: string): number[] {
104
+ revealSpecificSecret (counterparty: PublicKey | string | 'self' | 'anyone', protocolID: [0 | 1 | 2, string], keyID: string): number[] {
105
105
  counterparty = this.normalizeCounterparty(counterparty)
106
106
  const sharedSecret = this.rootKey.deriveSharedSecret(counterparty)
107
107
  const invoiceNumberBin = Utils.toArray(this.computeInvoiceNumber(protocolID, keyID), 'utf8')
@@ -114,7 +114,7 @@ export default class KeyDeriver {
114
114
  * @returns {PublicKey} - The normalized counterparty public key.
115
115
  * @throws {Error} - Throws an error if the counterparty is invalid.
116
116
  */
117
- private normalizeCounterparty(counterparty: PublicKey | string | 'self' | 'anyone'): PublicKey {
117
+ private normalizeCounterparty (counterparty: PublicKey | string | 'self' | 'anyone'): PublicKey {
118
118
  if (!counterparty) {
119
119
  throw new Error('counterparty must be self, anyone or a public key!')
120
120
  } else if (counterparty === 'self') {
@@ -135,7 +135,7 @@ export default class KeyDeriver {
135
135
  * @returns {string} - The computed invoice number.
136
136
  * @throws {Error} - Throws an error if protocol ID or key ID are invalid.
137
137
  */
138
- private computeInvoiceNumber(protocolID: [0 | 1 | 2, string], keyID: string): string {
138
+ private computeInvoiceNumber (protocolID: [0 | 1 | 2, string], keyID: string): string {
139
139
  const securityLevel = protocolID[0]
140
140
  if (!Number.isInteger(securityLevel) || securityLevel < 0 || securityLevel > 2) {
141
141
  throw new Error('Protocol security level must be 0, 1, or 2')