@bsv/wallet-toolbox 1.1.24 → 1.1.25

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 (194) hide show
  1. package/docs/client.md +2319 -84
  2. package/docs/wallet.md +2319 -84
  3. package/out/src/CWIStyleWalletManager.d.ts +411 -0
  4. package/out/src/CWIStyleWalletManager.d.ts.map +1 -0
  5. package/out/src/CWIStyleWalletManager.js +1131 -0
  6. package/out/src/CWIStyleWalletManager.js.map +1 -0
  7. package/out/src/SetupClient.d.ts +249 -0
  8. package/out/src/SetupClient.d.ts.map +1 -0
  9. package/out/src/SetupClient.js +252 -0
  10. package/out/src/SetupClient.js.map +1 -0
  11. package/out/src/SimpleWalletManager.d.ts +169 -0
  12. package/out/src/SimpleWalletManager.d.ts.map +1 -0
  13. package/out/src/SimpleWalletManager.js +315 -0
  14. package/out/src/SimpleWalletManager.js.map +1 -0
  15. package/out/src/Wallet.d.ts +6 -1
  16. package/out/src/Wallet.d.ts.map +1 -1
  17. package/out/src/Wallet.js +29 -2
  18. package/out/src/Wallet.js.map +1 -1
  19. package/out/src/WalletAuthenticationManager.d.ts +33 -0
  20. package/out/src/WalletAuthenticationManager.d.ts.map +1 -0
  21. package/out/src/WalletAuthenticationManager.js +107 -0
  22. package/out/src/WalletAuthenticationManager.js.map +1 -0
  23. package/out/src/WalletPermissionsManager.d.ts +575 -0
  24. package/out/src/WalletPermissionsManager.d.ts.map +1 -0
  25. package/out/src/WalletPermissionsManager.js +1807 -0
  26. package/out/src/WalletPermissionsManager.js.map +1 -0
  27. package/out/src/WalletSettingsManager.d.ts +59 -0
  28. package/out/src/WalletSettingsManager.d.ts.map +1 -0
  29. package/out/src/WalletSettingsManager.js +168 -0
  30. package/out/src/WalletSettingsManager.js.map +1 -0
  31. package/out/src/__tests/CWIStyleWalletManager.test.d.ts +2 -0
  32. package/out/src/__tests/CWIStyleWalletManager.test.d.ts.map +1 -0
  33. package/out/src/__tests/CWIStyleWalletManager.test.js +472 -0
  34. package/out/src/__tests/CWIStyleWalletManager.test.js.map +1 -0
  35. package/out/src/__tests/WalletPermissionsManager.callbacks.test.d.ts +2 -0
  36. package/out/src/__tests/WalletPermissionsManager.callbacks.test.d.ts.map +1 -0
  37. package/out/src/__tests/WalletPermissionsManager.callbacks.test.js +239 -0
  38. package/out/src/__tests/WalletPermissionsManager.callbacks.test.js.map +1 -0
  39. package/out/src/__tests/WalletPermissionsManager.checks.test.d.ts +2 -0
  40. package/out/src/__tests/WalletPermissionsManager.checks.test.d.ts.map +1 -0
  41. package/out/src/__tests/WalletPermissionsManager.checks.test.js +644 -0
  42. package/out/src/__tests/WalletPermissionsManager.checks.test.js.map +1 -0
  43. package/out/src/__tests/WalletPermissionsManager.encryption.test.d.ts +2 -0
  44. package/out/src/__tests/WalletPermissionsManager.encryption.test.d.ts.map +1 -0
  45. package/out/src/__tests/WalletPermissionsManager.encryption.test.js +295 -0
  46. package/out/src/__tests/WalletPermissionsManager.encryption.test.js.map +1 -0
  47. package/out/src/__tests/WalletPermissionsManager.fixtures.d.ts +82 -0
  48. package/out/src/__tests/WalletPermissionsManager.fixtures.d.ts.map +1 -0
  49. package/out/src/__tests/WalletPermissionsManager.fixtures.js +260 -0
  50. package/out/src/__tests/WalletPermissionsManager.fixtures.js.map +1 -0
  51. package/out/src/__tests/WalletPermissionsManager.flows.test.d.ts +2 -0
  52. package/out/src/__tests/WalletPermissionsManager.flows.test.d.ts.map +1 -0
  53. package/out/src/__tests/WalletPermissionsManager.flows.test.js +389 -0
  54. package/out/src/__tests/WalletPermissionsManager.flows.test.js.map +1 -0
  55. package/out/src/__tests/WalletPermissionsManager.initialization.test.d.ts +2 -0
  56. package/out/src/__tests/WalletPermissionsManager.initialization.test.d.ts.map +1 -0
  57. package/out/src/__tests/WalletPermissionsManager.initialization.test.js +227 -0
  58. package/out/src/__tests/WalletPermissionsManager.initialization.test.js.map +1 -0
  59. package/out/src/__tests/WalletPermissionsManager.proxying.test.d.ts +2 -0
  60. package/out/src/__tests/WalletPermissionsManager.proxying.test.d.ts.map +1 -0
  61. package/out/src/__tests/WalletPermissionsManager.proxying.test.js +566 -0
  62. package/out/src/__tests/WalletPermissionsManager.proxying.test.js.map +1 -0
  63. package/out/src/__tests/WalletPermissionsManager.tokens.test.d.ts +2 -0
  64. package/out/src/__tests/WalletPermissionsManager.tokens.test.d.ts.map +1 -0
  65. package/out/src/__tests/WalletPermissionsManager.tokens.test.js +460 -0
  66. package/out/src/__tests/WalletPermissionsManager.tokens.test.js.map +1 -0
  67. package/out/src/index.all.d.ts +9 -0
  68. package/out/src/index.all.d.ts.map +1 -1
  69. package/out/src/index.all.js +9 -0
  70. package/out/src/index.all.js.map +1 -1
  71. package/out/src/index.client.d.ts +9 -0
  72. package/out/src/index.client.d.ts.map +1 -1
  73. package/out/src/index.client.js +9 -0
  74. package/out/src/index.client.js.map +1 -1
  75. package/out/src/utility/identityUtils.d.ts +31 -0
  76. package/out/src/utility/identityUtils.d.ts.map +1 -0
  77. package/out/src/utility/identityUtils.js +114 -0
  78. package/out/src/utility/identityUtils.js.map +1 -0
  79. package/out/src/wab-client/WABClient.d.ts +38 -0
  80. package/out/src/wab-client/WABClient.d.ts.map +1 -0
  81. package/out/src/wab-client/WABClient.js +95 -0
  82. package/out/src/wab-client/WABClient.js.map +1 -0
  83. package/out/src/wab-client/__tests/WABClient.test.d.ts +2 -0
  84. package/out/src/wab-client/__tests/WABClient.test.d.ts.map +1 -0
  85. package/out/src/wab-client/__tests/WABClient.test.js +47 -0
  86. package/out/src/wab-client/__tests/WABClient.test.js.map +1 -0
  87. package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts +34 -0
  88. package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts.map +1 -0
  89. package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js +16 -0
  90. package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js.map +1 -0
  91. package/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.d.ts +7 -0
  92. package/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.d.ts.map +1 -0
  93. package/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.js +40 -0
  94. package/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.js.map +1 -0
  95. package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts +28 -0
  96. package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts.map +1 -0
  97. package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js +73 -0
  98. package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js.map +1 -0
  99. package/out/test/Wallet/action/abortAction.test.d.ts.map +1 -0
  100. package/out/test/{wallet → Wallet}/action/abortAction.test.js.map +1 -1
  101. package/out/test/Wallet/action/createAction.test.d.ts.map +1 -0
  102. package/out/test/{wallet → Wallet}/action/createAction.test.js.map +1 -1
  103. package/out/test/{wallet → Wallet}/action/createAction2.test.d.ts.map +1 -1
  104. package/out/test/{wallet → Wallet}/action/createAction2.test.js.map +1 -1
  105. package/out/test/Wallet/action/createActionToGenerateBeefs.man.test.d.ts.map +1 -0
  106. package/out/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.js.map +1 -1
  107. package/out/test/Wallet/action/internalizeAction.test.d.ts.map +1 -0
  108. package/out/test/{wallet → Wallet}/action/internalizeAction.test.js.map +1 -1
  109. package/out/test/Wallet/action/relinquishOutput.test.d.ts.map +1 -0
  110. package/out/test/{wallet → Wallet}/action/relinquishOutput.test.js.map +1 -1
  111. package/out/test/Wallet/construct/Wallet.constructor.test.d.ts.map +1 -0
  112. package/out/test/{wallet → Wallet}/construct/Wallet.constructor.test.js.map +1 -1
  113. package/out/test/Wallet/list/listActions.test.d.ts.map +1 -0
  114. package/out/test/{wallet → Wallet}/list/listActions.test.js.map +1 -1
  115. package/out/test/Wallet/list/listActions2.test.d.ts.map +1 -0
  116. package/out/test/{wallet → Wallet}/list/listActions2.test.js.map +1 -1
  117. package/out/test/Wallet/list/listCertificates.test.d.ts.map +1 -0
  118. package/out/test/{wallet → Wallet}/list/listCertificates.test.js.map +1 -1
  119. package/out/test/Wallet/list/listOutputs.test.d.ts.map +1 -0
  120. package/out/test/{wallet → Wallet}/list/listOutputs.test.js.map +1 -1
  121. package/out/test/Wallet/sync/Wallet.sync.test.d.ts.map +1 -0
  122. package/out/test/{wallet → Wallet}/sync/Wallet.sync.test.js.map +1 -1
  123. package/out/tsconfig.all.tsbuildinfo +1 -1
  124. package/package.json +3 -3
  125. package/src/CWIStyleWalletManager.ts +1891 -0
  126. package/src/SimpleWalletManager.ts +553 -0
  127. package/src/Wallet.ts +47 -3
  128. package/src/WalletAuthenticationManager.ts +183 -0
  129. package/src/WalletPermissionsManager.ts +2639 -0
  130. package/src/WalletSettingsManager.ts +241 -0
  131. package/src/__tests/CWIStyleWalletManager.test.ts +709 -0
  132. package/src/__tests/WalletPermissionsManager.callbacks.test.ts +328 -0
  133. package/src/__tests/WalletPermissionsManager.checks.test.ts +857 -0
  134. package/src/__tests/WalletPermissionsManager.encryption.test.ts +407 -0
  135. package/src/__tests/WalletPermissionsManager.fixtures.ts +283 -0
  136. package/src/__tests/WalletPermissionsManager.flows.test.ts +490 -0
  137. package/src/__tests/WalletPermissionsManager.initialization.test.ts +333 -0
  138. package/src/__tests/WalletPermissionsManager.proxying.test.ts +753 -0
  139. package/src/__tests/WalletPermissionsManager.tokens.test.ts +584 -0
  140. package/src/index.all.ts +9 -0
  141. package/src/index.client.ts +9 -0
  142. package/src/utility/identityUtils.ts +170 -0
  143. package/src/wab-client/WABClient.ts +103 -0
  144. package/src/wab-client/__tests/WABClient.test.ts +58 -0
  145. package/src/wab-client/auth-method-interactors/AuthMethodInteractor.ts +47 -0
  146. package/src/wab-client/auth-method-interactors/PersonaIDInteractor.ts +45 -0
  147. package/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.ts +82 -0
  148. package/out/test/wallet/action/abortAction.test.d.ts.map +0 -1
  149. package/out/test/wallet/action/createAction.test.d.ts.map +0 -1
  150. package/out/test/wallet/action/createActionToGenerateBeefs.man.test.d.ts.map +0 -1
  151. package/out/test/wallet/action/internalizeAction.test.d.ts.map +0 -1
  152. package/out/test/wallet/action/relinquishOutput.test.d.ts.map +0 -1
  153. package/out/test/wallet/construct/Wallet.constructor.test.d.ts.map +0 -1
  154. package/out/test/wallet/list/listActions.test.d.ts.map +0 -1
  155. package/out/test/wallet/list/listActions2.test.d.ts.map +0 -1
  156. package/out/test/wallet/list/listCertificates.test.d.ts.map +0 -1
  157. package/out/test/wallet/list/listOutputs.test.d.ts.map +0 -1
  158. package/out/test/wallet/sync/Wallet.sync.test.d.ts.map +0 -1
  159. /package/out/test/{wallet → Wallet}/action/abortAction.test.d.ts +0 -0
  160. /package/out/test/{wallet → Wallet}/action/abortAction.test.js +0 -0
  161. /package/out/test/{wallet → Wallet}/action/createAction.test.d.ts +0 -0
  162. /package/out/test/{wallet → Wallet}/action/createAction.test.js +0 -0
  163. /package/out/test/{wallet → Wallet}/action/createAction2.test.d.ts +0 -0
  164. /package/out/test/{wallet → Wallet}/action/createAction2.test.js +0 -0
  165. /package/out/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.d.ts +0 -0
  166. /package/out/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.js +0 -0
  167. /package/out/test/{wallet → Wallet}/action/internalizeAction.test.d.ts +0 -0
  168. /package/out/test/{wallet → Wallet}/action/internalizeAction.test.js +0 -0
  169. /package/out/test/{wallet → Wallet}/action/relinquishOutput.test.d.ts +0 -0
  170. /package/out/test/{wallet → Wallet}/action/relinquishOutput.test.js +0 -0
  171. /package/out/test/{wallet → Wallet}/construct/Wallet.constructor.test.d.ts +0 -0
  172. /package/out/test/{wallet → Wallet}/construct/Wallet.constructor.test.js +0 -0
  173. /package/out/test/{wallet → Wallet}/list/listActions.test.d.ts +0 -0
  174. /package/out/test/{wallet → Wallet}/list/listActions.test.js +0 -0
  175. /package/out/test/{wallet → Wallet}/list/listActions2.test.d.ts +0 -0
  176. /package/out/test/{wallet → Wallet}/list/listActions2.test.js +0 -0
  177. /package/out/test/{wallet → Wallet}/list/listCertificates.test.d.ts +0 -0
  178. /package/out/test/{wallet → Wallet}/list/listCertificates.test.js +0 -0
  179. /package/out/test/{wallet → Wallet}/list/listOutputs.test.d.ts +0 -0
  180. /package/out/test/{wallet → Wallet}/list/listOutputs.test.js +0 -0
  181. /package/out/test/{wallet → Wallet}/sync/Wallet.sync.test.d.ts +0 -0
  182. /package/out/test/{wallet → Wallet}/sync/Wallet.sync.test.js +0 -0
  183. /package/test/{wallet → Wallet}/action/abortAction.test.ts +0 -0
  184. /package/test/{wallet → Wallet}/action/createAction.test.ts +0 -0
  185. /package/test/{wallet → Wallet}/action/createAction2.test.ts +0 -0
  186. /package/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.ts +0 -0
  187. /package/test/{wallet → Wallet}/action/internalizeAction.test.ts +0 -0
  188. /package/test/{wallet → Wallet}/action/relinquishOutput.test.ts +0 -0
  189. /package/test/{wallet → Wallet}/construct/Wallet.constructor.test.ts +0 -0
  190. /package/test/{wallet → Wallet}/list/listActions.test.ts +0 -0
  191. /package/test/{wallet → Wallet}/list/listActions2.test.ts +0 -0
  192. /package/test/{wallet → Wallet}/list/listCertificates.test.ts +0 -0
  193. /package/test/{wallet → Wallet}/list/listOutputs.test.ts +0 -0
  194. /package/test/{wallet → Wallet}/sync/Wallet.sync.test.ts +0 -0
@@ -0,0 +1,553 @@
1
+ import {
2
+ WalletInterface,
3
+ OriginatorDomainNameStringUnder250Bytes,
4
+ GetPublicKeyArgs,
5
+ GetPublicKeyResult,
6
+ RevealCounterpartyKeyLinkageArgs,
7
+ RevealCounterpartyKeyLinkageResult,
8
+ RevealSpecificKeyLinkageArgs,
9
+ RevealSpecificKeyLinkageResult,
10
+ WalletEncryptArgs,
11
+ WalletEncryptResult,
12
+ WalletDecryptArgs,
13
+ WalletDecryptResult,
14
+ CreateHmacArgs,
15
+ CreateHmacResult,
16
+ VerifyHmacArgs,
17
+ VerifyHmacResult,
18
+ CreateSignatureArgs,
19
+ CreateSignatureResult,
20
+ VerifySignatureArgs,
21
+ VerifySignatureResult,
22
+ CreateActionArgs,
23
+ CreateActionResult,
24
+ SignActionArgs,
25
+ SignActionResult,
26
+ AbortActionArgs,
27
+ AbortActionResult,
28
+ ListActionsArgs,
29
+ ListActionsResult,
30
+ InternalizeActionArgs,
31
+ InternalizeActionResult,
32
+ ListOutputsArgs,
33
+ ListOutputsResult,
34
+ RelinquishOutputArgs,
35
+ RelinquishOutputResult,
36
+ AcquireCertificateArgs,
37
+ AcquireCertificateResult,
38
+ ListCertificatesArgs,
39
+ ListCertificatesResult,
40
+ ProveCertificateArgs,
41
+ ProveCertificateResult,
42
+ RelinquishCertificateArgs,
43
+ RelinquishCertificateResult,
44
+ DiscoverByIdentityKeyArgs,
45
+ DiscoverByAttributesArgs,
46
+ DiscoverCertificatesResult,
47
+ AuthenticatedResult,
48
+ GetHeightResult,
49
+ GetHeaderArgs,
50
+ GetHeaderResult,
51
+ GetNetworkResult,
52
+ GetVersionResult,
53
+ Utils,
54
+ Random,
55
+ SymmetricKey,
56
+ PrivateKey
57
+ } from '@bsv/sdk'
58
+ import { PrivilegedKeyManager } from './sdk/PrivilegedKeyManager'
59
+
60
+ /**
61
+ * SimpleWalletManager is a slimmed-down wallet manager that only requires two things to authenticate:
62
+ * 1. A primary key (32 bytes), which represents the core secret for the wallet.
63
+ * 2. A privileged key manager (an instance of `PrivilegedKeyManager`), responsible for
64
+ * more sensitive operations.
65
+ *
66
+ * Once both pieces are provided (or if a snapshot containing the primary key is loaded,
67
+ * and the privileged key manager is provided separately), the wallet becomes authenticated.
68
+ *
69
+ * After authentication, calls to the standard wallet methods (`createAction`, `signAction`, etc.)
70
+ * are proxied to an underlying `WalletInterface` instance returned by a user-supplied `walletBuilder`.
71
+ *
72
+ * **Important**: This manager does not handle user password flows, recovery, or on-chain
73
+ * token management. It is a straightforward wrapper that ensures the user has provided
74
+ * both their main secret (primary key) and a privileged key manager before allowing usage.
75
+ *
76
+ * It also prevents calls from the special "admin originator" from being used externally.
77
+ * (Any call that tries to use the admin originator as its originator, other than the manager itself,
78
+ * will result in an error, ensuring that only internal operations can use that originator.)
79
+ *
80
+ * The manager can also save and load snapshots of its state. In this simplified version,
81
+ * the snapshot only contains the primary key. If you load a snapshot, you still need to
82
+ * re-provide the privileged key manager to complete authentication.
83
+ */
84
+ export class SimpleWalletManager implements WalletInterface {
85
+ /**
86
+ * Whether the user is currently authenticated (meaning both the primary key
87
+ * and privileged key manager have been provided).
88
+ */
89
+ authenticated: boolean
90
+
91
+ /**
92
+ * The domain name of the administrative originator (wallet operator / vendor, or your own).
93
+ */
94
+ private adminOriginator: OriginatorDomainNameStringUnder250Bytes
95
+
96
+ /**
97
+ * A function that, given the user's primary key and privileged key manager,
98
+ * returns a new `WalletInterface` instance that handles the actual signing,
99
+ * encryption, transaction building, etc.
100
+ */
101
+ private walletBuilder: (
102
+ primaryKey: number[],
103
+ privilegedKeyManager: PrivilegedKeyManager
104
+ ) => Promise<WalletInterface>
105
+
106
+ /**
107
+ * The underlying wallet instance that is built once authenticated.
108
+ */
109
+ private underlying?: WalletInterface
110
+
111
+ /**
112
+ * The privileged key manager, responsible for sensitive tasks.
113
+ */
114
+ private underlyingPrivilegedKeyManager?: PrivilegedKeyManager
115
+
116
+ /**
117
+ * The primary key (32 bytes) that unlocks the wallet functionality.
118
+ */
119
+ private primaryKey?: number[]
120
+
121
+ /**
122
+ * Constructs a new `SimpleWalletManager`.
123
+ *
124
+ * @param adminOriginator The domain name of the administrative originator.
125
+ * @param walletBuilder A function that, given a primary key and privileged key manager,
126
+ * returns a fully functional `WalletInterface`.
127
+ * @param stateSnapshot If provided, a previously saved snapshot of the wallet's state.
128
+ * If the snapshot contains a primary key, it will be loaded immediately
129
+ * (though you will still need to provide a privileged key manager to authenticate).
130
+ */
131
+ constructor(
132
+ adminOriginator: OriginatorDomainNameStringUnder250Bytes,
133
+ walletBuilder: (
134
+ primaryKey: number[],
135
+ privilegedKeyManager: PrivilegedKeyManager
136
+ ) => Promise<WalletInterface>,
137
+ stateSnapshot?: number[]
138
+ ) {
139
+ this.authenticated = false
140
+ this.adminOriginator = adminOriginator
141
+ this.walletBuilder = walletBuilder
142
+
143
+ if (stateSnapshot) {
144
+ this.loadSnapshot(stateSnapshot)
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Provides the primary key (32 bytes) needed for authentication.
150
+ * If a privileged key manager has already been provided, we attempt to build
151
+ * the underlying wallet. Otherwise, we wait until the manager is also provided.
152
+ *
153
+ * @param key A 32-byte primary key.
154
+ */
155
+ async providePrimaryKey(key: number[]): Promise<void> {
156
+ this.primaryKey = key
157
+ await this.tryBuildUnderlying()
158
+ }
159
+
160
+ /**
161
+ * Provides the privileged key manager needed for sensitive tasks.
162
+ * If a primary key has already been provided (or loaded from a snapshot),
163
+ * we attempt to build the underlying wallet. Otherwise, we wait until the key is provided.
164
+ *
165
+ * @param manager An instance of `PrivilegedKeyManager`.
166
+ */
167
+ async providePrivilegedKeyManager(
168
+ manager: PrivilegedKeyManager
169
+ ): Promise<void> {
170
+ this.underlyingPrivilegedKeyManager = manager
171
+ await this.tryBuildUnderlying()
172
+ }
173
+
174
+ /**
175
+ * Internal method that checks if we have both the primary key and privileged manager.
176
+ * If so, we build the underlying wallet instance and become authenticated.
177
+ */
178
+ private async tryBuildUnderlying(): Promise<void> {
179
+ if (this.authenticated) {
180
+ throw new Error('The user is already authenticated.')
181
+ }
182
+ if (!this.primaryKey || !this.underlyingPrivilegedKeyManager) {
183
+ return
184
+ }
185
+ // Build the underlying wallet:
186
+ this.underlying = await this.walletBuilder(
187
+ this.primaryKey,
188
+ this.underlyingPrivilegedKeyManager
189
+ )
190
+ this.authenticated = true
191
+ }
192
+
193
+ /**
194
+ * Destroys the underlying wallet, returning to a default (unauthenticated) state.
195
+ *
196
+ * This clears the primary key, the privileged key manager, and the `authenticated` flag.
197
+ */
198
+ destroy(): void {
199
+ this.underlying = undefined
200
+ this.underlyingPrivilegedKeyManager = undefined
201
+ this.authenticated = false
202
+ this.primaryKey = undefined
203
+ }
204
+
205
+ /**
206
+ * Saves the current wallet state (including just the primary key)
207
+ * into an encrypted snapshot. This snapshot can be stored and later
208
+ * passed to `loadSnapshot` to restore the primary key (and partially authenticate).
209
+ *
210
+ * **Note**: The snapshot does NOT include the privileged key manager.
211
+ * You must still provide that separately after loading the snapshot
212
+ * in order to complete authentication.
213
+ *
214
+ * @remarks
215
+ * Storing the snapshot (which contains the primary key) provides a significant
216
+ * portion of the wallet's secret material. It must be protected carefully.
217
+ *
218
+ * @returns A byte array representing the encrypted snapshot.
219
+ * @throws {Error} if no primary key is currently set.
220
+ */
221
+ saveSnapshot(): number[] {
222
+ if (!this.primaryKey) {
223
+ throw new Error('No primary key is set; cannot save snapshot.')
224
+ }
225
+
226
+ // Generate a random snapshot encryption key:
227
+ const snapshotKey = Random(32)
228
+
229
+ // For this simple wallet manager, we only store the primary key.
230
+ const writer = new Utils.Writer()
231
+ // Write a 1-byte version:
232
+ writer.writeUInt8(1)
233
+ // Write a varint length and then the primary key bytes:
234
+ writer.writeVarIntNum(this.primaryKey.length)
235
+ writer.write(this.primaryKey)
236
+
237
+ const snapshotPreimage = writer.toArray()
238
+
239
+ // Encrypt the data with the snapshotKey:
240
+ const encryptedPayload = new SymmetricKey(snapshotKey).encrypt(
241
+ snapshotPreimage
242
+ ) as number[]
243
+
244
+ // Build the final snapshot: [ snapshotKey (32 bytes) + encryptedPayload ]
245
+ const snapshotWriter = new Utils.Writer()
246
+ snapshotWriter.write(snapshotKey)
247
+ snapshotWriter.write(encryptedPayload)
248
+
249
+ return snapshotWriter.toArray()
250
+ }
251
+
252
+ /**
253
+ * Loads a previously saved state snapshot (produced by `saveSnapshot`).
254
+ * This will restore the primary key but will **not** restore the privileged key manager
255
+ * (that must be provided separately to complete authentication).
256
+ *
257
+ * @param snapshot A byte array that was previously returned by `saveSnapshot`.
258
+ * @throws {Error} If the snapshot format is invalid or decryption fails.
259
+ */
260
+ async loadSnapshot(snapshot: number[]): Promise<void> {
261
+ try {
262
+ const reader = new Utils.Reader(snapshot)
263
+
264
+ // First 32 bytes is the snapshotKey:
265
+ const snapshotKey = reader.read(32)
266
+
267
+ // The rest is the encrypted payload:
268
+ const encryptedPayload = reader.read()
269
+
270
+ // Decrypt the payload with the snapshotKey:
271
+ const decrypted = new SymmetricKey(snapshotKey).decrypt(
272
+ encryptedPayload
273
+ ) as number[]
274
+
275
+ const payloadReader = new Utils.Reader(decrypted)
276
+
277
+ // Check version:
278
+ const version = payloadReader.readUInt8()
279
+ if (version !== 1) {
280
+ throw new Error(`Unsupported snapshot version: ${version}`)
281
+ }
282
+
283
+ // Read the varint length and the primary key:
284
+ const pkLength = payloadReader.readVarIntNum()
285
+ const pk = payloadReader.read(pkLength)
286
+
287
+ this.primaryKey = pk
288
+
289
+ // Attempt to build the underlying wallet if the privileged manager is already provided:
290
+ await this.tryBuildUnderlying()
291
+ } catch (error) {
292
+ throw new Error(`Failed to load snapshot: ${(error as Error).message}`)
293
+ }
294
+ }
295
+
296
+ /**
297
+ * Returns whether the user is currently authenticated (the wallet has a primary key
298
+ * and a privileged key manager). If not authenticated, an error is thrown.
299
+ *
300
+ * @param _ Not used in this manager.
301
+ * @param originator The originator domain, which must not be the admin originator.
302
+ * @throws If not authenticated, or if the originator is the admin.
303
+ */
304
+ async isAuthenticated(
305
+ _: {},
306
+ originator?: OriginatorDomainNameStringUnder250Bytes
307
+ ): Promise<AuthenticatedResult> {
308
+ this.ensureCanCall(originator)
309
+ return { authenticated: true }
310
+ }
311
+
312
+ /**
313
+ * Blocks until the user is authenticated (by providing primaryKey and privileged manager).
314
+ * If not authenticated yet, it waits until that occurs.
315
+ *
316
+ * @param _ Not used in this manager.
317
+ * @param originator The originator domain, which must not be the admin originator.
318
+ * @throws If the originator is the admin.
319
+ */
320
+ async waitForAuthentication(
321
+ _: {},
322
+ originator?: OriginatorDomainNameStringUnder250Bytes
323
+ ): Promise<AuthenticatedResult> {
324
+ if (originator === this.adminOriginator) {
325
+ throw new Error('External applications cannot use the admin originator.')
326
+ }
327
+ while (!this.authenticated) {
328
+ await new Promise(resolve => setTimeout(resolve, 100))
329
+ }
330
+ return { authenticated: true }
331
+ }
332
+
333
+ async getPublicKey(
334
+ args: GetPublicKeyArgs,
335
+ originator?: OriginatorDomainNameStringUnder250Bytes
336
+ ): Promise<GetPublicKeyResult> {
337
+ this.ensureCanCall(originator)
338
+ return this.underlying!.getPublicKey(args, originator)
339
+ }
340
+
341
+ async revealCounterpartyKeyLinkage(
342
+ args: RevealCounterpartyKeyLinkageArgs,
343
+ originator?: OriginatorDomainNameStringUnder250Bytes
344
+ ): Promise<RevealCounterpartyKeyLinkageResult> {
345
+ this.ensureCanCall(originator)
346
+ return this.underlying!.revealCounterpartyKeyLinkage(args, originator)
347
+ }
348
+
349
+ async revealSpecificKeyLinkage(
350
+ args: RevealSpecificKeyLinkageArgs,
351
+ originator?: OriginatorDomainNameStringUnder250Bytes
352
+ ): Promise<RevealSpecificKeyLinkageResult> {
353
+ this.ensureCanCall(originator)
354
+ return this.underlying!.revealSpecificKeyLinkage(args, originator)
355
+ }
356
+
357
+ async encrypt(
358
+ args: WalletEncryptArgs,
359
+ originator?: OriginatorDomainNameStringUnder250Bytes
360
+ ): Promise<WalletEncryptResult> {
361
+ this.ensureCanCall(originator)
362
+ return this.underlying!.encrypt(args, originator)
363
+ }
364
+
365
+ async decrypt(
366
+ args: WalletDecryptArgs,
367
+ originator?: OriginatorDomainNameStringUnder250Bytes
368
+ ): Promise<WalletDecryptResult> {
369
+ this.ensureCanCall(originator)
370
+ return this.underlying!.decrypt(args, originator)
371
+ }
372
+
373
+ async createHmac(
374
+ args: CreateHmacArgs,
375
+ originator?: OriginatorDomainNameStringUnder250Bytes
376
+ ): Promise<CreateHmacResult> {
377
+ this.ensureCanCall(originator)
378
+ return this.underlying!.createHmac(args, originator)
379
+ }
380
+
381
+ async verifyHmac(
382
+ args: VerifyHmacArgs,
383
+ originator?: OriginatorDomainNameStringUnder250Bytes
384
+ ): Promise<VerifyHmacResult> {
385
+ this.ensureCanCall(originator)
386
+ return this.underlying!.verifyHmac(args, originator)
387
+ }
388
+
389
+ async createSignature(
390
+ args: CreateSignatureArgs,
391
+ originator?: OriginatorDomainNameStringUnder250Bytes
392
+ ): Promise<CreateSignatureResult> {
393
+ this.ensureCanCall(originator)
394
+ return this.underlying!.createSignature(args, originator)
395
+ }
396
+
397
+ async verifySignature(
398
+ args: VerifySignatureArgs,
399
+ originator?: OriginatorDomainNameStringUnder250Bytes
400
+ ): Promise<VerifySignatureResult> {
401
+ this.ensureCanCall(originator)
402
+ return this.underlying!.verifySignature(args, originator)
403
+ }
404
+
405
+ async createAction(
406
+ args: CreateActionArgs,
407
+ originator?: OriginatorDomainNameStringUnder250Bytes
408
+ ): Promise<CreateActionResult> {
409
+ this.ensureCanCall(originator)
410
+ return this.underlying!.createAction(args, originator)
411
+ }
412
+
413
+ async signAction(
414
+ args: SignActionArgs,
415
+ originator?: OriginatorDomainNameStringUnder250Bytes
416
+ ): Promise<SignActionResult> {
417
+ this.ensureCanCall(originator)
418
+ return this.underlying!.signAction(args, originator)
419
+ }
420
+
421
+ async abortAction(
422
+ args: AbortActionArgs,
423
+ originator?: OriginatorDomainNameStringUnder250Bytes
424
+ ): Promise<AbortActionResult> {
425
+ this.ensureCanCall(originator)
426
+ return this.underlying!.abortAction(args, originator)
427
+ }
428
+
429
+ async listActions(
430
+ args: ListActionsArgs,
431
+ originator?: OriginatorDomainNameStringUnder250Bytes
432
+ ): Promise<ListActionsResult> {
433
+ this.ensureCanCall(originator)
434
+ return this.underlying!.listActions(args, originator)
435
+ }
436
+
437
+ async internalizeAction(
438
+ args: InternalizeActionArgs,
439
+ originator?: OriginatorDomainNameStringUnder250Bytes
440
+ ): Promise<InternalizeActionResult> {
441
+ this.ensureCanCall(originator)
442
+ return this.underlying!.internalizeAction(args, originator)
443
+ }
444
+
445
+ async listOutputs(
446
+ args: ListOutputsArgs,
447
+ originator?: OriginatorDomainNameStringUnder250Bytes
448
+ ): Promise<ListOutputsResult> {
449
+ this.ensureCanCall(originator)
450
+ return this.underlying!.listOutputs(args, originator)
451
+ }
452
+
453
+ async relinquishOutput(
454
+ args: RelinquishOutputArgs,
455
+ originator?: OriginatorDomainNameStringUnder250Bytes
456
+ ): Promise<RelinquishOutputResult> {
457
+ this.ensureCanCall(originator)
458
+ return this.underlying!.relinquishOutput(args, originator)
459
+ }
460
+
461
+ async acquireCertificate(
462
+ args: AcquireCertificateArgs,
463
+ originator?: OriginatorDomainNameStringUnder250Bytes
464
+ ): Promise<AcquireCertificateResult> {
465
+ this.ensureCanCall(originator)
466
+ return this.underlying!.acquireCertificate(args, originator)
467
+ }
468
+
469
+ async listCertificates(
470
+ args: ListCertificatesArgs,
471
+ originator?: OriginatorDomainNameStringUnder250Bytes
472
+ ): Promise<ListCertificatesResult> {
473
+ this.ensureCanCall(originator)
474
+ return this.underlying!.listCertificates(args, originator)
475
+ }
476
+
477
+ async proveCertificate(
478
+ args: ProveCertificateArgs,
479
+ originator?: OriginatorDomainNameStringUnder250Bytes
480
+ ): Promise<ProveCertificateResult> {
481
+ this.ensureCanCall(originator)
482
+ return this.underlying!.proveCertificate(args, originator)
483
+ }
484
+
485
+ async relinquishCertificate(
486
+ args: RelinquishCertificateArgs,
487
+ originator?: OriginatorDomainNameStringUnder250Bytes
488
+ ): Promise<RelinquishCertificateResult> {
489
+ this.ensureCanCall(originator)
490
+ return this.underlying!.relinquishCertificate(args, originator)
491
+ }
492
+
493
+ async discoverByIdentityKey(
494
+ args: DiscoverByIdentityKeyArgs,
495
+ originator?: OriginatorDomainNameStringUnder250Bytes
496
+ ): Promise<DiscoverCertificatesResult> {
497
+ this.ensureCanCall(originator)
498
+ return this.underlying!.discoverByIdentityKey(args, originator)
499
+ }
500
+
501
+ async discoverByAttributes(
502
+ args: DiscoverByAttributesArgs,
503
+ originator?: OriginatorDomainNameStringUnder250Bytes
504
+ ): Promise<DiscoverCertificatesResult> {
505
+ this.ensureCanCall(originator)
506
+ return this.underlying!.discoverByAttributes(args, originator)
507
+ }
508
+
509
+ async getHeight(
510
+ _: {},
511
+ originator?: OriginatorDomainNameStringUnder250Bytes
512
+ ): Promise<GetHeightResult> {
513
+ this.ensureCanCall(originator)
514
+ return this.underlying!.getHeight({}, originator)
515
+ }
516
+
517
+ async getHeaderForHeight(
518
+ args: GetHeaderArgs,
519
+ originator?: OriginatorDomainNameStringUnder250Bytes
520
+ ): Promise<GetHeaderResult> {
521
+ this.ensureCanCall(originator)
522
+ return this.underlying!.getHeaderForHeight(args, originator)
523
+ }
524
+
525
+ async getNetwork(
526
+ _: {},
527
+ originator?: OriginatorDomainNameStringUnder250Bytes
528
+ ): Promise<GetNetworkResult> {
529
+ this.ensureCanCall(originator)
530
+ return this.underlying!.getNetwork({}, originator)
531
+ }
532
+
533
+ async getVersion(
534
+ _: {},
535
+ originator?: OriginatorDomainNameStringUnder250Bytes
536
+ ): Promise<GetVersionResult> {
537
+ this.ensureCanCall(originator)
538
+ return this.underlying!.getVersion({}, originator)
539
+ }
540
+
541
+ /**
542
+ * A small helper that throws if the user is not authenticated or if the
543
+ * provided originator is the admin (which is not permitted externally).
544
+ */
545
+ private ensureCanCall(originator?: OriginatorDomainNameStringUnder250Bytes) {
546
+ if (originator === this.adminOriginator) {
547
+ throw new Error('External applications cannot use the admin originator.')
548
+ }
549
+ if (!this.authenticated) {
550
+ throw new Error('User is not authenticated.')
551
+ }
552
+ }
553
+ }
package/src/Wallet.ts CHANGED
@@ -62,7 +62,8 @@ import {
62
62
  AuthFetch,
63
63
  verifyNonce,
64
64
  MasterCertificate,
65
- Certificate
65
+ Certificate,
66
+ LookupResolver
66
67
  } from '@bsv/sdk'
67
68
  import {
68
69
  sdk,
@@ -78,6 +79,11 @@ import { proveCertificate } from './signer/methods/proveCertificate'
78
79
  import { createAction } from './signer/methods/createAction'
79
80
  import { signAction } from './signer/methods/signAction'
80
81
  import { internalizeAction } from './signer/methods/internalizeAction'
82
+ import { WalletSettingsManager } from './WalletSettingsManager'
83
+ import {
84
+ queryOverlay,
85
+ transformVerifiableCertificatesWithTrust
86
+ } from './utility/identityUtils'
81
87
  import { maxPossibleSatoshis } from './storage/methods/generateChange'
82
88
 
83
89
  export interface WalletArgs {
@@ -87,6 +93,8 @@ export interface WalletArgs {
87
93
  services?: sdk.WalletServices
88
94
  monitor?: Monitor
89
95
  privilegedKeyManager?: sdk.PrivilegedKeyManager
96
+ settingsManager?: WalletSettingsManager
97
+ lookupResolver?: LookupResolver
90
98
  }
91
99
 
92
100
  function isWalletSigner(args: WalletArgs | WalletSigner): args is WalletSigner {
@@ -97,6 +105,8 @@ export class Wallet implements WalletInterface, ProtoWallet {
97
105
  chain: sdk.Chain
98
106
  keyDeriver: KeyDeriver
99
107
  storage: WalletStorageManager
108
+ settingsManager: WalletSettingsManager
109
+ lookupResolver: LookupResolver
100
110
 
101
111
  services?: sdk.WalletServices
102
112
  monitor?: Monitor
@@ -149,6 +159,10 @@ export class Wallet implements WalletInterface, ProtoWallet {
149
159
  `authenticated as the same identityKey (${args.storage._authId.identityKey}) as the keyDeriver (${args.keyDeriver.identityKey}).`
150
160
  )
151
161
 
162
+ this.settingsManager =
163
+ args.settingsManager || new WalletSettingsManager(this)
164
+ this.lookupResolver = args.lookupResolver || new LookupResolver()
165
+
152
166
  this.chain = args.chain
153
167
  this.keyDeriver = args.keyDeriver
154
168
  this.storage = args.storage
@@ -609,7 +623,22 @@ export class Wallet implements WalletInterface, ProtoWallet {
609
623
  ): Promise<DiscoverCertificatesResult> {
610
624
  sdk.validateOriginator(originator)
611
625
  this.validateAuthAndArgs(args, sdk.validateDiscoverByIdentityKeyArgs)
612
- throw new Error('Method not implemented.')
626
+
627
+ const trustSettings = (await this.settingsManager.get()).trustSettings
628
+ const results = await queryOverlay(
629
+ {
630
+ identityKey: args.identityKey,
631
+ trustedCertifiers: trustSettings.trustedCertifiers
632
+ },
633
+ this.lookupResolver
634
+ )
635
+ if (!results) {
636
+ return {
637
+ totalCertificates: 0,
638
+ certificates: []
639
+ }
640
+ }
641
+ return transformVerifiableCertificatesWithTrust(trustSettings, results)
613
642
  }
614
643
 
615
644
  async discoverByAttributes(
@@ -618,7 +647,22 @@ export class Wallet implements WalletInterface, ProtoWallet {
618
647
  ): Promise<DiscoverCertificatesResult> {
619
648
  sdk.validateOriginator(originator)
620
649
  this.validateAuthAndArgs(args, sdk.validateDiscoverByAttributesArgs)
621
- throw new Error('Method not implemented.')
650
+
651
+ const trustSettings = (await this.settingsManager.get()).trustSettings
652
+ const results = await queryOverlay(
653
+ {
654
+ identityKey: args.attributes,
655
+ trustedCertifiers: trustSettings.trustedCertifiers
656
+ },
657
+ this.lookupResolver
658
+ )
659
+ if (!results) {
660
+ return {
661
+ totalCertificates: 0,
662
+ certificates: []
663
+ }
664
+ }
665
+ return transformVerifiableCertificatesWithTrust(trustSettings, results)
622
666
  }
623
667
 
624
668
  //////////////////