@bsv/sdk 1.2.6 → 1.2.8

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 (81) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/primitives/PublicKey.js +6 -0
  3. package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
  4. package/dist/cjs/src/script/templates/PushDrop.js +2 -2
  5. package/dist/cjs/src/script/templates/PushDrop.js.map +1 -1
  6. package/dist/cjs/src/transaction/Transaction.js +1 -5
  7. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  8. package/dist/cjs/src/wallet/CachedKeyDeriver.js +4 -4
  9. package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -1
  10. package/dist/cjs/src/wallet/KeyDeriver.js +5 -5
  11. package/dist/cjs/src/wallet/KeyDeriver.js.map +1 -1
  12. package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
  13. package/dist/cjs/src/wallet/Wallet.interfaces.js +14 -0
  14. package/dist/cjs/src/wallet/Wallet.interfaces.js.map +1 -1
  15. package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
  16. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  17. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  18. package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
  19. package/dist/cjs/src/wallet/substrates/window.CWI.js.map +1 -1
  20. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  21. package/dist/esm/src/primitives/PublicKey.js +6 -0
  22. package/dist/esm/src/primitives/PublicKey.js.map +1 -1
  23. package/dist/esm/src/script/templates/PushDrop.js +2 -2
  24. package/dist/esm/src/script/templates/PushDrop.js.map +1 -1
  25. package/dist/esm/src/transaction/Transaction.js +1 -5
  26. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  27. package/dist/esm/src/wallet/CachedKeyDeriver.js +4 -4
  28. package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -1
  29. package/dist/esm/src/wallet/KeyDeriver.js +5 -5
  30. package/dist/esm/src/wallet/KeyDeriver.js.map +1 -1
  31. package/dist/esm/src/wallet/ProtoWallet.js.map +1 -1
  32. package/dist/esm/src/wallet/Wallet.interfaces.js +13 -1
  33. package/dist/esm/src/wallet/Wallet.interfaces.js.map +1 -1
  34. package/dist/esm/src/wallet/WalletClient.js.map +1 -1
  35. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  36. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  37. package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
  38. package/dist/esm/src/wallet/substrates/window.CWI.js.map +1 -1
  39. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  40. package/dist/types/src/primitives/PublicKey.d.ts.map +1 -1
  41. package/dist/types/src/script/templates/PushDrop.d.ts +5 -4
  42. package/dist/types/src/script/templates/PushDrop.d.ts.map +1 -1
  43. package/dist/types/src/transaction/Transaction.d.ts +0 -1
  44. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  45. package/dist/types/src/wallet/CachedKeyDeriver.d.ts +9 -8
  46. package/dist/types/src/wallet/CachedKeyDeriver.d.ts.map +1 -1
  47. package/dist/types/src/wallet/KeyDeriver.d.ts +10 -9
  48. package/dist/types/src/wallet/KeyDeriver.d.ts.map +1 -1
  49. package/dist/types/src/wallet/ProtoWallet.d.ts +10 -10
  50. package/dist/types/src/wallet/ProtoWallet.d.ts.map +1 -1
  51. package/dist/types/src/wallet/Wallet.interfaces.d.ts +30 -2
  52. package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -1
  53. package/dist/types/src/wallet/WalletClient.d.ts +10 -10
  54. package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
  55. package/dist/types/src/wallet/substrates/WalletWireProcessor.d.ts.map +1 -1
  56. package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts +10 -10
  57. package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts.map +1 -1
  58. package/dist/types/src/wallet/substrates/XDM.d.ts +10 -10
  59. package/dist/types/src/wallet/substrates/XDM.d.ts.map +1 -1
  60. package/dist/types/src/wallet/substrates/window.CWI.d.ts +10 -10
  61. package/dist/types/src/wallet/substrates/window.CWI.d.ts.map +1 -1
  62. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  63. package/dist/umd/bundle.js +1 -1
  64. package/docs/overlay-tools.md +21 -19
  65. package/docs/script.md +21 -19
  66. package/docs/transaction.md +4 -6
  67. package/docs/wallet.md +229 -196
  68. package/package.json +1 -1
  69. package/src/primitives/PublicKey.ts +17 -11
  70. package/src/primitives/__tests/PublicKey.test.ts +6 -0
  71. package/src/script/templates/PushDrop.ts +5 -4
  72. package/src/transaction/Transaction.ts +1 -5
  73. package/src/wallet/CachedKeyDeriver.ts +9 -8
  74. package/src/wallet/KeyDeriver.ts +11 -10
  75. package/src/wallet/ProtoWallet.ts +10 -9
  76. package/src/wallet/Wallet.interfaces.ts +32 -2
  77. package/src/wallet/WalletClient.ts +9 -9
  78. package/src/wallet/substrates/WalletWireProcessor.ts +3 -2
  79. package/src/wallet/substrates/WalletWireTransceiver.ts +11 -11
  80. package/src/wallet/substrates/XDM.ts +9 -9
  81. package/src/wallet/substrates/window.CWI.ts +9 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.2.6",
3
+ "version": "1.2.8",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -30,7 +30,7 @@ export default class PublicKey extends Point {
30
30
  * const myPrivKey = new PrivateKey(...)
31
31
  * const myPubKey = PublicKey.fromPrivateKey(myPrivKey)
32
32
  */
33
- static fromPrivateKey (key: PrivateKey): PublicKey {
33
+ static fromPrivateKey(key: PrivateKey): PublicKey {
34
34
  const c = new Curve()
35
35
  const p = c.g.mul(key)
36
36
  return new PublicKey(p.x, p.y)
@@ -46,7 +46,7 @@ export default class PublicKey extends Point {
46
46
  * @example
47
47
  * const myPubKey = PublicKey.fromString("03....")
48
48
  */
49
- static fromString (str: string): PublicKey {
49
+ static fromString(str: string): PublicKey {
50
50
  const p = Point.fromString(str)
51
51
  return new PublicKey(p.x, p.y)
52
52
  }
@@ -61,7 +61,7 @@ export default class PublicKey extends Point {
61
61
  * @example
62
62
  * const myPubKey = PublicKey.fromString("03....")
63
63
  */
64
- static fromDER (bytes: number[]): PublicKey {
64
+ static fromDER(bytes: number[]): PublicKey {
65
65
  const p = Point.fromDER(bytes)
66
66
  return new PublicKey(p.x, p.y)
67
67
  }
@@ -76,7 +76,7 @@ export default class PublicKey extends Point {
76
76
  * new PublicKey(point1);
77
77
  * new PublicKey('abc123', 'def456');
78
78
  */
79
- constructor (
79
+ constructor(
80
80
  x: Point | BigNumber | number | number[] | string | null,
81
81
  y: BigNumber | number | number[] | string | null = null,
82
82
  isRed: boolean = true
@@ -84,6 +84,12 @@ export default class PublicKey extends Point {
84
84
  if (x instanceof Point) {
85
85
  super(x.getX(), x.getY())
86
86
  } else {
87
+ // Common gotcha: constructing PublicKey with a DER value when you should use .fromString()
88
+ if (y === null && isRed === true && typeof x === 'string') {
89
+ if (x.length === 66 || x.length === 130) {
90
+ throw new Error('You are using the "new PublicKey()" constructor with a DER hex string. You need to use "PublicKey.fromString()" instead.')
91
+ }
92
+ }
87
93
  super(x, y, isRed)
88
94
  }
89
95
  }
@@ -102,7 +108,7 @@ export default class PublicKey extends Point {
102
108
  * const myPrivKey = new PrivateKey(...)
103
109
  * const sharedSecret = myPubKey.deriveSharedSecret(myPrivKey)
104
110
  */
105
- deriveSharedSecret (priv: PrivateKey): Point {
111
+ deriveSharedSecret(priv: PrivateKey): Point {
106
112
  if (!this.validate()) {
107
113
  throw new Error('Public key not valid for ECDH secret derivation')
108
114
  }
@@ -123,7 +129,7 @@ export default class PublicKey extends Point {
123
129
  * const mySignature = new Signature(...)
124
130
  * const isVerified = myPubKey.verify(myMessage, mySignature)
125
131
  */
126
- verify (msg: number[] | string, sig: Signature, enc?: 'hex' | 'utf8'): boolean {
132
+ verify(msg: number[] | string, sig: Signature, enc?: 'hex' | 'utf8'): boolean {
127
133
  const msgHash = new BigNumber(sha256(msg, enc), 16)
128
134
  return verify(msgHash, sig, this)
129
135
  }
@@ -138,7 +144,7 @@ export default class PublicKey extends Point {
138
144
  * @example
139
145
  * const derPublicKey = myPubKey.toDER()
140
146
  */
141
- toDER (enc?: 'hex' | undefined): number[] | string {
147
+ toDER(enc?: 'hex' | undefined): number[] | string {
142
148
  if (enc === 'hex') return this.encode(true, enc) as string
143
149
  return this.encode(true) as number[]
144
150
  }
@@ -151,7 +157,7 @@ export default class PublicKey extends Point {
151
157
  * @example
152
158
  * const publicKeyHash = pubkey.toHash()
153
159
  */
154
- toHash (enc?: 'hex'): number[] | string {
160
+ toHash(enc?: 'hex'): number[] | string {
155
161
  const pkh = hash160(this.encode(true))
156
162
  if (enc === 'hex') {
157
163
  return toHex(pkh)
@@ -173,7 +179,7 @@ export default class PublicKey extends Point {
173
179
  * const testnetAddress = pubkey.toAddress([0x6f])
174
180
  * const testnetAddress = pubkey.toAddress('testnet')
175
181
  */
176
- toAddress (prefix: number[] | string = [0x00]): string {
182
+ toAddress(prefix: number[] | string = [0x00]): string {
177
183
  if (typeof prefix === 'string') {
178
184
  if (prefix === 'testnet' || prefix === 'test') {
179
185
  prefix = [0x6f]
@@ -192,7 +198,7 @@ export default class PublicKey extends Point {
192
198
  * @param invoiceNumber The invoice number used to derive the child key
193
199
  * @returns The derived child key.
194
200
  */
195
- deriveChild (privateKey: PrivateKey, invoiceNumber: string): PublicKey {
201
+ deriveChild(privateKey: PrivateKey, invoiceNumber: string): PublicKey {
196
202
  const sharedSecret = this.deriveSharedSecret(privateKey)
197
203
  const invoiceNumberBin = toArray(invoiceNumber, 'utf8')
198
204
  const hmac = sha256hmac(sharedSecret.encode(true), invoiceNumberBin)
@@ -219,7 +225,7 @@ export default class PublicKey extends Point {
219
225
  * @example
220
226
  * const publicKey = Signature.fromMsgHashAndCompactSignature(msgHash, 'IMOl2mVKfDgsSsHT4uIYBNN4e...', 'base64');
221
227
  */
222
- static fromMsgHashAndCompactSignature (msgHash: BigNumber, signature: number[] | string, enc?: 'hex' | 'base64'): PublicKey {
228
+ static fromMsgHashAndCompactSignature(msgHash: BigNumber, signature: number[] | string, enc?: 'hex' | 'base64'): PublicKey {
223
229
  const data = toArray(signature, enc)
224
230
  if (data.length !== 65) {
225
231
  throw new Error('Invalid Compact Signature')
@@ -27,6 +27,12 @@ describe('PublicKey', () => {
27
27
  })
28
28
  })
29
29
 
30
+ describe('Constructor', () => {
31
+ it('Should throw when accidentally passing in DER', () => {
32
+ expect(() => new PublicKey('036af279b60aa437d48bb0e2ec0b0c6b5cfaa976663f1f08ad456fd7fff149321d')).toThrow()
33
+ })
34
+ })
35
+
30
36
  describe('Instance methods', () => {
31
37
  test('deriveSharedSecret should derive a shared secret Point', () => {
32
38
  const sharedSecret = publicKey.deriveSharedSecret(privateKey)
@@ -2,6 +2,7 @@ import { ScriptTemplate, LockingScript, UnlockingScript, OP } from '../index.js'
2
2
  import { Utils, Hash, TransactionSignature, Signature, PublicKey } from '../../primitives/index.js'
3
3
  import { Wallet } from '../../wallet/Wallet.interfaces.js'
4
4
  import { Transaction } from '../../transaction/index.js'
5
+ import { SecurityLevel } from '../../wallet/Wallet.interfaces.js'
5
6
 
6
7
  /**
7
8
  * For a given piece of data to push onto the stack in script, creates the correct minimally-encoded script chunk,
@@ -93,14 +94,14 @@ export default class PushDrop implements ScriptTemplate {
93
94
  * Creates a PushDrop locking script with arbitrary data fields and a public key lock.
94
95
  *
95
96
  * @param {number[][]} fields - The token fields to include in the locking script.
96
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID to use.
97
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID to use.
97
98
  * @param {string} keyID - The key ID to use.
98
99
  * @param {string} counterparty - The counterparty involved in the transaction, "self" or "anyone".
99
100
  * @param {boolean} [forSelf=false] - Flag indicating if the lock is for the creator (default no).
100
101
  * @param {boolean} [includeSignature=true] - Flag indicating if a signature should be included in the script (default yes).
101
102
  * @returns {Promise<LockingScript>} The generated PushDrop locking script.
102
103
  */
103
- async lock(fields: number[][], protocolID: [0 | 1 | 2, string], keyID: string, counterparty: string, forSelf = false, includeSignature = true, lockPosition: 'before' | 'after' = 'before'): Promise<LockingScript> {
104
+ async lock(fields: number[][], protocolID: [SecurityLevel, string], keyID: string, counterparty: string, forSelf = false, includeSignature = true, lockPosition: 'before' | 'after' = 'before'): Promise<LockingScript> {
104
105
  const { publicKey } = await this.wallet.getPublicKey({
105
106
  protocolID,
106
107
  keyID,
@@ -148,7 +149,7 @@ export default class PushDrop implements ScriptTemplate {
148
149
  /**
149
150
  * Creates an unlocking script for spending a PushDrop token output.
150
151
  *
151
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID to use.
152
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID to use.
152
153
  * @param {string} keyID - The key ID to use.
153
154
  * @param {string} counterparty - The counterparty involved in the transaction, "self" or "anyone".
154
155
  * @param {string} [sourceTXID] - The TXID of the source transaction.
@@ -159,7 +160,7 @@ export default class PushDrop implements ScriptTemplate {
159
160
  * @returns {Object} An object containing functions to sign the transaction and estimate the script length.
160
161
  */
161
162
  unlock(
162
- protocolID: [0 | 1 | 2, string],
163
+ protocolID: [SecurityLevel, string],
163
164
  keyID: string,
164
165
  counterparty: string,
165
166
  signOutputs: 'all' | 'none' | 'single' = 'all',
@@ -479,13 +479,9 @@ export default class Transaction {
479
479
  * @param changeDistribution - Specifies how the change should be distributed
480
480
  * amongst the change outputs
481
481
  *
482
- * TODO: Benford's law change distribution.
483
482
  */
484
- async fee (modelOrFee?: FeeModel | number, changeDistribution: 'equal' | 'random' = 'equal'): Promise<void> {
483
+ async fee (modelOrFee: FeeModel | number = new SatoshisPerKilobyte(10), changeDistribution: 'equal' | 'random' = 'equal'): Promise<void> {
485
484
  this.cachedHash = undefined
486
- if (typeof modelOrFee === 'undefined') {
487
- modelOrFee = new SatoshisPerKilobyte(10)
488
- }
489
485
  if (typeof modelOrFee === 'number') {
490
486
  const sats = modelOrFee
491
487
  modelOrFee = {
@@ -1,5 +1,6 @@
1
1
  import { PrivateKey, PublicKey, SymmetricKey } from '../primitives/index.js'
2
2
  import KeyDeriver from './KeyDeriver.js'
3
+ import { SecurityLevel } from './Wallet.interfaces.js'
3
4
 
4
5
  /**
5
6
  * A cached version of KeyDeriver that caches the results of key derivation methods.
@@ -26,14 +27,14 @@ export default class CachedKeyDeriver {
26
27
  /**
27
28
  * Derives a public key based on protocol ID, key ID, and counterparty.
28
29
  * Caches the result for future calls with the same parameters.
29
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID including a security level and protocol name.
30
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID including a security level and protocol name.
30
31
  * @param {string} keyID - The key identifier.
31
32
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
32
33
  * @param {boolean} [forSelf=false] - Whether deriving for self.
33
34
  * @returns {PublicKey} - The derived public key.
34
35
  */
35
36
  derivePublicKey (
36
- protocolID: [0 | 1 | 2, string],
37
+ protocolID: [SecurityLevel, string],
37
38
  keyID: string,
38
39
  counterparty: PublicKey | string | 'self' | 'anyone',
39
40
  forSelf: boolean = false
@@ -51,13 +52,13 @@ export default class CachedKeyDeriver {
51
52
  /**
52
53
  * Derives a private key based on protocol ID, key ID, and counterparty.
53
54
  * Caches the result for future calls with the same parameters.
54
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID including a security level and protocol name.
55
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID including a security level and protocol name.
55
56
  * @param {string} keyID - The key identifier.
56
57
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
57
58
  * @returns {PrivateKey} - The derived private key.
58
59
  */
59
60
  derivePrivateKey (
60
- protocolID: [0 | 1 | 2, string],
61
+ protocolID: [SecurityLevel, string],
61
62
  keyID: string,
62
63
  counterparty: PublicKey | string | 'self' | 'anyone'
63
64
  ): PrivateKey {
@@ -74,14 +75,14 @@ export default class CachedKeyDeriver {
74
75
  /**
75
76
  * Derives a symmetric key based on protocol ID, key ID, and counterparty.
76
77
  * Caches the result for future calls with the same parameters.
77
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID including a security level and protocol name.
78
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID including a security level and protocol name.
78
79
  * @param {string} keyID - The key identifier.
79
80
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
80
81
  * @returns {SymmetricKey} - The derived symmetric key.
81
82
  * @throws {Error} - Throws an error if attempting to derive a symmetric key for 'anyone'.
82
83
  */
83
84
  deriveSymmetricKey (
84
- protocolID: [0 | 1 | 2, string],
85
+ protocolID: [SecurityLevel, string],
85
86
  keyID: string,
86
87
  counterparty: PublicKey | string | 'self' | 'anyone'
87
88
  ): SymmetricKey {
@@ -117,13 +118,13 @@ export default class CachedKeyDeriver {
117
118
  * Reveals the specific key association for a given protocol ID, key ID, and counterparty.
118
119
  * Caches the result for future calls with the same parameters.
119
120
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
120
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID including a security level and protocol name.
121
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID including a security level and protocol name.
121
122
  * @param {string} keyID - The key identifier.
122
123
  * @returns {number[]} - The specific key association as a number array.
123
124
  */
124
125
  revealSpecificSecret (
125
126
  counterparty: PublicKey | string | 'self' | 'anyone',
126
- protocolID: [0 | 1 | 2, string],
127
+ protocolID: [SecurityLevel, string],
127
128
  keyID: string
128
129
  ): number[] {
129
130
  const cacheKey = this.generateCacheKey('revealSpecificSecret', counterparty, protocolID, keyID)
@@ -1,4 +1,5 @@
1
1
  import { PrivateKey, PublicKey, SymmetricKey, Hash, Utils } from '../primitives/index.js'
2
+ import { SecurityLevel } from '../wallet/Wallet.interfaces.js'
2
3
 
3
4
  /**
4
5
  * Class responsible for deriving various types of keys using a root private key.
@@ -21,13 +22,13 @@ export default class KeyDeriver {
21
22
 
22
23
  /**
23
24
  * Derives a public key based on protocol ID, key ID, and counterparty.
24
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID including a security level and protocol name.
25
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID including a security level and protocol name.
25
26
  * @param {string} keyID - The key identifier.
26
27
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
27
28
  * @param {boolean} [forSelf=false] - Whether deriving for self.
28
29
  * @returns {PublicKey} - The derived public key.
29
30
  */
30
- derivePublicKey (protocolID: [0 | 1 | 2, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone', forSelf: boolean = false): PublicKey {
31
+ derivePublicKey (protocolID: [SecurityLevel, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone', forSelf: boolean = false): PublicKey {
31
32
  counterparty = this.normalizeCounterparty(counterparty)
32
33
  if (forSelf) {
33
34
  return this.rootKey.deriveChild(counterparty, this.computeInvoiceNumber(protocolID, keyID)).toPublicKey()
@@ -38,12 +39,12 @@ export default class KeyDeriver {
38
39
 
39
40
  /**
40
41
  * Derives a private key based on protocol ID, key ID, and counterparty.
41
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID including a security level and protocol name.
42
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID including a security level and protocol name.
42
43
  * @param {string} keyID - The key identifier.
43
44
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
44
45
  * @returns {PrivateKey} - The derived private key.
45
46
  */
46
- derivePrivateKey (protocolID: [0 | 1 | 2, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone'): PrivateKey {
47
+ derivePrivateKey (protocolID: [SecurityLevel, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone'): PrivateKey {
47
48
  counterparty = this.normalizeCounterparty(counterparty)
48
49
  return this.rootKey.deriveChild(counterparty, this.computeInvoiceNumber(protocolID, keyID))
49
50
  }
@@ -51,13 +52,13 @@ export default class KeyDeriver {
51
52
  /**
52
53
  * Derives a symmetric key based on protocol ID, key ID, and counterparty.
53
54
  * Note: Symmetric keys should not be derivable by everyone due to security risks.
54
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID including a security level and protocol name.
55
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID including a security level and protocol name.
55
56
  * @param {string} keyID - The key identifier.
56
57
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
57
58
  * @returns {SymmetricKey} - The derived symmetric key.
58
59
  * @throws {Error} - Throws an error if attempting to derive a symmetric key for 'anyone'.
59
60
  */
60
- deriveSymmetricKey (protocolID: [0 | 1 | 2, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone'): SymmetricKey {
61
+ deriveSymmetricKey (protocolID: [SecurityLevel, string], keyID: string, counterparty: PublicKey | string | 'self' | 'anyone'): SymmetricKey {
61
62
  if (counterparty === 'anyone') {
62
63
  throw new Error(
63
64
  '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.'
@@ -97,11 +98,11 @@ export default class KeyDeriver {
97
98
  /**
98
99
  * Reveals the specific key association for a given protocol ID, key ID, and counterparty.
99
100
  * @param {PublicKey | string | 'self' | 'anyone'} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
100
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID including a security level and protocol name.
101
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID including a security level and protocol name.
101
102
  * @param {string} keyID - The key identifier.
102
103
  * @returns {number[]} - The specific key association as a number array.
103
104
  */
104
- revealSpecificSecret (counterparty: PublicKey | string | 'self' | 'anyone', protocolID: [0 | 1 | 2, string], keyID: string): number[] {
105
+ revealSpecificSecret (counterparty: PublicKey | string | 'self' | 'anyone', protocolID: [SecurityLevel, string], keyID: string): number[] {
105
106
  counterparty = this.normalizeCounterparty(counterparty)
106
107
  const sharedSecret = this.rootKey.deriveSharedSecret(counterparty)
107
108
  const invoiceNumberBin = Utils.toArray(this.computeInvoiceNumber(protocolID, keyID), 'utf8')
@@ -130,12 +131,12 @@ export default class KeyDeriver {
130
131
 
131
132
  /**
132
133
  * Computes the invoice number based on the protocol ID and key ID.
133
- * @param {[0 | 1 | 2, string]} protocolID - The protocol ID including a security level and protocol name.
134
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID including a security level and protocol name.
134
135
  * @param {string} keyID - The key identifier.
135
136
  * @returns {string} - The computed invoice number.
136
137
  * @throws {Error} - Throws an error if protocol ID or key ID are invalid.
137
138
  */
138
- private computeInvoiceNumber (protocolID: [0 | 1 | 2, string], keyID: string): string {
139
+ private computeInvoiceNumber (protocolID: [SecurityLevel, string], keyID: string): string {
139
140
  const securityLevel = protocolID[0]
140
141
  if (!Number.isInteger(securityLevel) || securityLevel < 0 || securityLevel > 2) {
141
142
  throw new Error('Protocol security level must be 0, 1, or 2')
@@ -23,6 +23,7 @@ import {
23
23
  ProtocolString5To400Bytes,
24
24
  PubKeyHex,
25
25
  SatoshiValue,
26
+ SecurityLevel,
26
27
  TXIDHexString,
27
28
  VersionString7To30Bytes,
28
29
  Wallet
@@ -256,7 +257,7 @@ export default class ProtoWallet implements Wallet {
256
257
  async getPublicKey (
257
258
  args: {
258
259
  identityKey?: true
259
- protocolID?: [0 | 1 | 2, ProtocolString5To400Bytes]
260
+ protocolID?: [SecurityLevel, ProtocolString5To400Bytes]
260
261
  keyID?: KeyIDStringUnder800Bytes
261
262
  privileged?: BooleanDefaultFalse
262
263
  privilegedReason?: DescriptionString5to50Bytes
@@ -338,7 +339,7 @@ export default class ProtoWallet implements Wallet {
338
339
  args: {
339
340
  counterparty: PubKeyHex
340
341
  verifier: PubKeyHex
341
- protocolID: [0 | 1 | 2, ProtocolString5To400Bytes]
342
+ protocolID: [SecurityLevel, ProtocolString5To400Bytes]
342
343
  keyID: KeyIDStringUnder800Bytes
343
344
  privilegedReason?: DescriptionString5to50Bytes
344
345
  privileged?: BooleanDefaultFalse
@@ -348,7 +349,7 @@ export default class ProtoWallet implements Wallet {
348
349
  prover: PubKeyHex
349
350
  verifier: PubKeyHex
350
351
  counterparty: PubKeyHex
351
- protocolID: [0 | 1 | 2, ProtocolString5To400Bytes]
352
+ protocolID: [SecurityLevel, ProtocolString5To400Bytes]
352
353
  keyID: KeyIDStringUnder800Bytes
353
354
  encryptedLinkage: Byte[]
354
355
  encryptedLinkageProof: Byte[]
@@ -390,7 +391,7 @@ export default class ProtoWallet implements Wallet {
390
391
  async encrypt (
391
392
  args: {
392
393
  plaintext: Byte[]
393
- protocolID: [0 | 1 | 2, ProtocolString5To400Bytes]
394
+ protocolID: [SecurityLevel, ProtocolString5To400Bytes]
394
395
  keyID: KeyIDStringUnder800Bytes
395
396
  privilegedReason?: DescriptionString5to50Bytes
396
397
  counterparty?: PubKeyHex | 'self' | 'anyone'
@@ -412,7 +413,7 @@ export default class ProtoWallet implements Wallet {
412
413
  async decrypt (
413
414
  args: {
414
415
  ciphertext: Byte[]
415
- protocolID: [0 | 1 | 2, ProtocolString5To400Bytes]
416
+ protocolID: [SecurityLevel, ProtocolString5To400Bytes]
416
417
  keyID: KeyIDStringUnder800Bytes
417
418
  privilegedReason?: DescriptionString5to50Bytes
418
419
  counterparty?: PubKeyHex | 'self' | 'anyone'
@@ -434,7 +435,7 @@ export default class ProtoWallet implements Wallet {
434
435
  async createHmac (
435
436
  args: {
436
437
  data: Byte[]
437
- protocolID: [0 | 1 | 2, ProtocolString5To400Bytes]
438
+ protocolID: [SecurityLevel, ProtocolString5To400Bytes]
438
439
  keyID: KeyIDStringUnder800Bytes
439
440
  privilegedReason?: DescriptionString5to50Bytes
440
441
  counterparty?: PubKeyHex | 'self' | 'anyone'
@@ -457,7 +458,7 @@ export default class ProtoWallet implements Wallet {
457
458
  args: {
458
459
  data: Byte[]
459
460
  hmac: Byte[]
460
- protocolID: [0 | 1 | 2, ProtocolString5To400Bytes]
461
+ protocolID: [SecurityLevel, ProtocolString5To400Bytes]
461
462
  keyID: KeyIDStringUnder800Bytes
462
463
  privilegedReason?: DescriptionString5to50Bytes
463
464
  counterparty?: PubKeyHex | 'self' | 'anyone'
@@ -484,7 +485,7 @@ export default class ProtoWallet implements Wallet {
484
485
  args: {
485
486
  data?: Byte[]
486
487
  hashToDirectlySign?: Byte[]
487
- protocolID: [0 | 1 | 2, ProtocolString5To400Bytes]
488
+ protocolID: [SecurityLevel, ProtocolString5To400Bytes]
488
489
  keyID: KeyIDStringUnder800Bytes
489
490
  privilegedReason?: DescriptionString5to50Bytes
490
491
  counterparty?: PubKeyHex | 'self' | 'anyone'
@@ -512,7 +513,7 @@ export default class ProtoWallet implements Wallet {
512
513
  data?: Byte[]
513
514
  hashToDirectlyVerify?: Byte[]
514
515
  signature: Byte[]
515
- protocolID: [0 | 1 | 2, ProtocolString5To400Bytes]
516
+ protocolID: [SecurityLevel, ProtocolString5To400Bytes]
516
517
  keyID: KeyIDStringUnder800Bytes
517
518
  privilegedReason?: DescriptionString5to50Bytes
518
519
  counterparty?: PubKeyHex | 'self' | 'anyone'
@@ -191,7 +191,30 @@ export type ErrorDescriptionString20To200Bytes = string
191
191
 
192
192
  export type WalletNetwork = 'mainnet' | 'testnet'
193
193
 
194
- export type WalletProtocol = [0 | 1 | 2, ProtocolString5To400Bytes]
194
+ /**
195
+ * @enum {number} SecurityLevels
196
+ *
197
+ * Silent = 0 Silently grants the request with no user interation.
198
+ * App = 1 Requires user approval for every application.
199
+ * Counterparty = 2 Requires user approval per counterparty per application.
200
+ */
201
+ export enum SecurityLevels {
202
+ Silent = 0,
203
+ App = 1,
204
+ Counterparty = 2
205
+ }
206
+
207
+ /**
208
+ *
209
+ * SecurityLevel for protocols.
210
+ * 0 = Silently grants the request with no user interation.
211
+ * 1 = Requires user approval for every application.
212
+ * 2 = Requires user approval per counterparty per application.
213
+ *
214
+ */
215
+ export type SecurityLevel = 0 | 1 | 2
216
+
217
+ export type WalletProtocol = [SecurityLevel, ProtocolString5To400Bytes]
195
218
 
196
219
  export type WalletCounterparty = PubKeyHex | 'self' | 'anyone'
197
220
 
@@ -528,13 +551,20 @@ export interface ListOutputsResult {
528
551
 
529
552
  /**
530
553
  * @param {WalletProtocol} protocolID - The security level and protocol string under which the data should be encrypted.
554
+ * @param {SecurityLevel} securityLevel - The security level of the protocol.
555
+ * @param {WalletProtocol} protocolID - The security level and protocol string under which the data should be encrypted.
556
+ * @param {SecurityLevel} protocolID[0] - SecurityLevel:
557
+ * 0 = Silently grants the request with no user interation.
558
+ * 1 = Requires user approval for every application.
559
+ * 2 = Requires user approval per counterparty per application.
560
+ * @param {ProtocolString5To400Bytes} protocolID[1] - The name of the protocol.
531
561
  * @param {KeyIDStringUnder800Bytes} keyID - Key ID under which the encryption will be performed.
532
562
  * @param {DescriptionString5to50Bytes} [privilegedReason] - Reason provided for privileged access, required if this is a privileged operation.
533
563
  * @param {WalletCounterparty} [counterparty] - Public key of the counterparty (if two-party encryption is desired).
534
564
  * @param {BooleanDefaultFalse} [privileged] - Whether this is a privileged request.
535
565
  */
536
566
  export interface KeyLinkageArgs {
537
- protocolID: WalletProtocol
567
+ protocolID: [SecurityLevel, ProtocolString5To400Bytes]
538
568
  keyID: KeyIDStringUnder800Bytes
539
569
  counterparty?: WalletCounterparty
540
570
  privileged?: BooleanDefaultFalse
@@ -1,4 +1,4 @@
1
- import { AcquireCertificateArgs, AcquireCertificateResult, Base64String, BasketStringUnder300Bytes, BEEF, BooleanDefaultFalse, BooleanDefaultTrue, Byte, CertificateFieldNameUnder50Bytes, CreateActionArgs, CreateActionResult, DescriptionString5to50Bytes, DiscoverCertificatesResult, EntityIconURLStringMax500Bytes, EntityNameStringMax100Bytes, HexString, InternalizeActionArgs, ISOTimestampString, KeyIDStringUnder800Bytes, LabelStringUnder300Bytes, ListActionsArgs, ListActionsResult, ListCertificatesResult, ListOutputsArgs, ListOutputsResult, OriginatorDomainNameStringUnder250Bytes, OutpointString, OutputTagStringUnder300Bytes, PositiveInteger, PositiveIntegerDefault10Max10000, PositiveIntegerMax10, PositiveIntegerOrZero, ProtocolString5To400Bytes, ProveCertificateArgs, ProveCertificateResult, PubKeyHex, SatoshiValue, SignActionArgs, SignActionResult, TXIDHexString, VersionString7To30Bytes, Wallet } from './Wallet.interfaces.js'
1
+ import { AcquireCertificateArgs, AcquireCertificateResult, Base64String, BasketStringUnder300Bytes, BEEF, BooleanDefaultFalse, BooleanDefaultTrue, Byte, CertificateFieldNameUnder50Bytes, CreateActionArgs, CreateActionResult, DescriptionString5to50Bytes, DiscoverCertificatesResult, EntityIconURLStringMax500Bytes, EntityNameStringMax100Bytes, HexString, InternalizeActionArgs, ISOTimestampString, KeyIDStringUnder800Bytes, LabelStringUnder300Bytes, ListActionsArgs, ListActionsResult, ListCertificatesResult, ListOutputsArgs, ListOutputsResult, OriginatorDomainNameStringUnder250Bytes, OutpointString, OutputTagStringUnder300Bytes, PositiveInteger, PositiveIntegerDefault10Max10000, PositiveIntegerMax10, PositiveIntegerOrZero, ProtocolString5To400Bytes, ProveCertificateArgs, ProveCertificateResult, PubKeyHex, SatoshiValue, SecurityLevel, SignActionArgs, SignActionResult, TXIDHexString, VersionString7To30Bytes, Wallet } from './Wallet.interfaces.js'
2
2
  import WindowCWISubstrate from './substrates/window.CWI.js'
3
3
  import XDMSubstrate from './substrates/XDM.js'
4
4
  import WalletWireTransceiver from './substrates/WalletWireTransceiver.js'
@@ -95,7 +95,7 @@ export default class WalletClient implements Wallet {
95
95
  return await (this.substrate as Wallet).relinquishOutput(args, this.originator)
96
96
  }
97
97
 
98
- async getPublicKey (args: { identityKey?: true, protocolID?: [0 | 1 | 2, ProtocolString5To400Bytes], keyID?: KeyIDStringUnder800Bytes, privileged?: BooleanDefaultFalse, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', forSelf?: BooleanDefaultFalse }): Promise<{ publicKey: PubKeyHex }> {
98
+ async getPublicKey (args: { identityKey?: true, protocolID?: [SecurityLevel, ProtocolString5To400Bytes], keyID?: KeyIDStringUnder800Bytes, privileged?: BooleanDefaultFalse, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', forSelf?: BooleanDefaultFalse }): Promise<{ publicKey: PubKeyHex }> {
99
99
  await this.connectToSubstrate()
100
100
  return await (this.substrate as Wallet).getPublicKey(args, this.originator)
101
101
  }
@@ -105,36 +105,36 @@ export default class WalletClient implements Wallet {
105
105
  return await (this.substrate as Wallet).revealCounterpartyKeyLinkage(args, this.originator)
106
106
  }
107
107
 
108
- async revealSpecificKeyLinkage (args: { counterparty: PubKeyHex, verifier: PubKeyHex, protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, privileged?: BooleanDefaultFalse }): Promise<{ prover: PubKeyHex, verifier: PubKeyHex, counterparty: PubKeyHex, protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, encryptedLinkage: Byte[], encryptedLinkageProof: Byte[], proofType: Byte }> {
108
+ async revealSpecificKeyLinkage (args: { counterparty: PubKeyHex, verifier: PubKeyHex, protocolID: [SecurityLevel, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, privileged?: BooleanDefaultFalse }): Promise<{ prover: PubKeyHex, verifier: PubKeyHex, counterparty: PubKeyHex, protocolID: [SecurityLevel, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, encryptedLinkage: Byte[], encryptedLinkageProof: Byte[], proofType: Byte }> {
109
109
  await this.connectToSubstrate()
110
110
  return await (this.substrate as Wallet).revealSpecificKeyLinkage(args, this.originator)
111
111
  }
112
112
 
113
- async encrypt (args: { plaintext: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ ciphertext: Byte[] }> {
113
+ async encrypt (args: { plaintext: Byte[], protocolID: [SecurityLevel, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ ciphertext: Byte[] }> {
114
114
  await this.connectToSubstrate()
115
115
  return await (this.substrate as Wallet).encrypt(args, this.originator)
116
116
  }
117
117
 
118
- async decrypt (args: { ciphertext: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ plaintext: Byte[] }> {
118
+ async decrypt (args: { ciphertext: Byte[], protocolID: [SecurityLevel, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ plaintext: Byte[] }> {
119
119
  return await (this.substrate as Wallet).decrypt(args, this.originator)
120
120
  }
121
121
 
122
- async createHmac (args: { data: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ hmac: Byte[] }> {
122
+ async createHmac (args: { data: Byte[], protocolID: [SecurityLevel, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ hmac: Byte[] }> {
123
123
  await this.connectToSubstrate()
124
124
  return await (this.substrate as Wallet).createHmac(args, this.originator)
125
125
  }
126
126
 
127
- async verifyHmac (args: { data: Byte[], hmac: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ valid: true }> {
127
+ async verifyHmac (args: { data: Byte[], hmac: Byte[], protocolID: [SecurityLevel, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ valid: true }> {
128
128
  await this.connectToSubstrate()
129
129
  return await (this.substrate as Wallet).verifyHmac(args, this.originator)
130
130
  }
131
131
 
132
- async createSignature (args: { data?: Byte[], hashToDirectlySign?: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ signature: Byte[] }> {
132
+ async createSignature (args: { data?: Byte[], hashToDirectlySign?: Byte[], protocolID: [SecurityLevel, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }): Promise<{ signature: Byte[] }> {
133
133
  await this.connectToSubstrate()
134
134
  return await (this.substrate as Wallet).createSignature(args, this.originator)
135
135
  }
136
136
 
137
- async verifySignature (args: { data?: Byte[], hashToDirectlyVerify?: Byte[], signature: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', forSelf?: BooleanDefaultFalse, privileged?: BooleanDefaultFalse }): Promise<{ valid: true }> {
137
+ async verifySignature (args: { data?: Byte[], hashToDirectlyVerify?: Byte[], signature: Byte[], protocolID: [SecurityLevel, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', forSelf?: BooleanDefaultFalse, privileged?: BooleanDefaultFalse }): Promise<{ valid: true }> {
138
138
  await this.connectToSubstrate()
139
139
  return await (this.substrate as Wallet).verifySignature(args, this.originator)
140
140
  }
@@ -3,6 +3,7 @@ import WalletWire from './WalletWire.js'
3
3
  import { Utils } from '../../primitives/index.js'
4
4
  import calls from './WalletWireCalls.js'
5
5
  import Certificate from '../../auth/Certificate.js'
6
+ import { SecurityLevel } from '../Wallet.interfaces.js'
6
7
 
7
8
  /**
8
9
  * Processes incoming wallet calls received over a wallet wire, with a given wallet.
@@ -1914,8 +1915,8 @@ export default class WalletWireProcessor implements WalletWire {
1914
1915
  }
1915
1916
  }
1916
1917
 
1917
- private decodeProtocolID(reader: Utils.Reader): [0 | 1 | 2, string] {
1918
- const securityLevel = reader.readUInt8() as 0 | 1 | 2
1918
+ private decodeProtocolID(reader: Utils.Reader): [SecurityLevel, string] {
1919
+ const securityLevel = reader.readUInt8() as SecurityLevel
1919
1920
  const protocolLength = reader.readVarIntNum()
1920
1921
  const protocolBytes = reader.read(protocolLength)
1921
1922
  const protocolString = Utils.toUTF8(protocolBytes)