@bsv/wallet-toolbox 1.4.3 → 1.4.5

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 (250) hide show
  1. package/docs/client.md +225 -79
  2. package/docs/monitor.md +32 -1
  3. package/docs/wallet.md +225 -79
  4. package/mobile/out/src/WalletPermissionsManager.d.ts +60 -1
  5. package/mobile/out/src/WalletPermissionsManager.d.ts.map +1 -1
  6. package/mobile/out/src/WalletPermissionsManager.js +223 -15
  7. package/mobile/out/src/WalletPermissionsManager.js.map +1 -1
  8. package/mobile/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -1
  9. package/mobile/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -1
  10. package/mobile/package-lock.json +2 -2
  11. package/mobile/package.json +1 -1
  12. package/out/src/CWIStyleWalletManager.js +1 -1
  13. package/out/src/CWIStyleWalletManager.js.map +1 -1
  14. package/out/src/WalletPermissionsManager.d.ts +60 -1
  15. package/out/src/WalletPermissionsManager.d.ts.map +1 -1
  16. package/out/src/WalletPermissionsManager.js +222 -15
  17. package/out/src/WalletPermissionsManager.js.map +1 -1
  18. package/out/src/__tests/WalletPermissionsManager.initialization.test.js.map +1 -1
  19. package/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -1
  20. package/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -1
  21. package/out/src/sdk/CertOps.d.ts +66 -0
  22. package/out/src/sdk/CertOps.d.ts.map +1 -0
  23. package/out/src/sdk/CertOps.js +198 -0
  24. package/out/src/sdk/CertOps.js.map +1 -0
  25. package/out/src/sdk/StorageSyncReader.d.ts +121 -0
  26. package/out/src/sdk/StorageSyncReader.d.ts.map +1 -0
  27. package/out/src/sdk/StorageSyncReader.js +3 -0
  28. package/out/src/sdk/StorageSyncReader.js.map +1 -0
  29. package/out/src/sdk/StorageSyncReaderWriter.d.ts +89 -0
  30. package/out/src/sdk/StorageSyncReaderWriter.d.ts.map +1 -0
  31. package/out/src/sdk/StorageSyncReaderWriter.js +3 -0
  32. package/out/src/sdk/StorageSyncReaderWriter.js.map +1 -0
  33. package/out/src/services/__tests/ARC.test.d.ts +2 -0
  34. package/out/src/services/__tests/ARC.test.d.ts.map +1 -0
  35. package/out/src/services/__tests/ARC.test.js +104 -0
  36. package/out/src/services/__tests/ARC.test.js.map +1 -0
  37. package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts +98 -0
  38. package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts.map +1 -0
  39. package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js +38 -0
  40. package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js.map +1 -0
  41. package/out/src/storage/methods/listActions.d.ts +5 -0
  42. package/out/src/storage/methods/listActions.d.ts.map +1 -0
  43. package/out/src/storage/methods/listActions.js +228 -0
  44. package/out/src/storage/methods/listActions.js.map +1 -0
  45. package/out/src/storage/methods/listOutputs.d.ts +5 -0
  46. package/out/src/storage/methods/listOutputs.d.ts.map +1 -0
  47. package/out/src/storage/methods/listOutputs.js +295 -0
  48. package/out/src/storage/methods/listOutputs.js.map +1 -0
  49. package/out/src/storage/schema/entities/Certificate.d.ts +43 -0
  50. package/out/src/storage/schema/entities/Certificate.d.ts.map +1 -0
  51. package/out/src/storage/schema/entities/Certificate.js +162 -0
  52. package/out/src/storage/schema/entities/Certificate.js.map +1 -0
  53. package/out/src/storage/schema/entities/CertificateField.d.ts +32 -0
  54. package/out/src/storage/schema/entities/CertificateField.d.ts.map +1 -0
  55. package/out/src/storage/schema/entities/CertificateField.js +114 -0
  56. package/out/src/storage/schema/entities/CertificateField.js.map +1 -0
  57. package/out/src/storage/schema/entities/Commission.d.ts +37 -0
  58. package/out/src/storage/schema/entities/Commission.d.ts.map +1 -0
  59. package/out/src/storage/schema/entities/Commission.js +130 -0
  60. package/out/src/storage/schema/entities/Commission.js.map +1 -0
  61. package/out/src/storage/schema/entities/Output.d.ts +67 -0
  62. package/out/src/storage/schema/entities/Output.d.ts.map +1 -0
  63. package/out/src/storage/schema/entities/Output.js +281 -0
  64. package/out/src/storage/schema/entities/Output.js.map +1 -0
  65. package/out/src/storage/schema/entities/OutputBasket.d.ts +35 -0
  66. package/out/src/storage/schema/entities/OutputBasket.d.ts.map +1 -0
  67. package/out/src/storage/schema/entities/OutputBasket.js +133 -0
  68. package/out/src/storage/schema/entities/OutputBasket.js.map +1 -0
  69. package/out/src/storage/schema/entities/OutputTag.d.ts +31 -0
  70. package/out/src/storage/schema/entities/OutputTag.d.ts.map +1 -0
  71. package/out/src/storage/schema/entities/OutputTag.js +104 -0
  72. package/out/src/storage/schema/entities/OutputTag.js.map +1 -0
  73. package/out/src/storage/schema/entities/OutputTagMap.d.ts +28 -0
  74. package/out/src/storage/schema/entities/OutputTagMap.d.ts.map +1 -0
  75. package/out/src/storage/schema/entities/OutputTagMap.js +101 -0
  76. package/out/src/storage/schema/entities/OutputTagMap.js.map +1 -0
  77. package/out/src/storage/schema/entities/ProvenTx.d.ts +84 -0
  78. package/out/src/storage/schema/entities/ProvenTx.d.ts.map +1 -0
  79. package/out/src/storage/schema/entities/ProvenTx.js +286 -0
  80. package/out/src/storage/schema/entities/ProvenTx.js.map +1 -0
  81. package/out/src/storage/schema/entities/ProvenTxReq.d.ts +135 -0
  82. package/out/src/storage/schema/entities/ProvenTxReq.d.ts.map +1 -0
  83. package/out/src/storage/schema/entities/ProvenTxReq.js +532 -0
  84. package/out/src/storage/schema/entities/ProvenTxReq.js.map +1 -0
  85. package/out/src/storage/schema/entities/SyncState.d.ts +66 -0
  86. package/out/src/storage/schema/entities/SyncState.d.ts.map +1 -0
  87. package/out/src/storage/schema/entities/SyncState.js +284 -0
  88. package/out/src/storage/schema/entities/SyncState.js.map +1 -0
  89. package/out/src/storage/schema/entities/Transaction.d.ts +67 -0
  90. package/out/src/storage/schema/entities/Transaction.d.ts.map +1 -0
  91. package/out/src/storage/schema/entities/Transaction.js +264 -0
  92. package/out/src/storage/schema/entities/Transaction.js.map +1 -0
  93. package/out/src/storage/schema/entities/TxLabel.d.ts +31 -0
  94. package/out/src/storage/schema/entities/TxLabel.d.ts.map +1 -0
  95. package/out/src/storage/schema/entities/TxLabel.js +104 -0
  96. package/out/src/storage/schema/entities/TxLabel.js.map +1 -0
  97. package/out/src/storage/schema/entities/TxLabelMap.d.ts +28 -0
  98. package/out/src/storage/schema/entities/TxLabelMap.d.ts.map +1 -0
  99. package/out/src/storage/schema/entities/TxLabelMap.js +103 -0
  100. package/out/src/storage/schema/entities/TxLabelMap.js.map +1 -0
  101. package/out/src/storage/schema/entities/User.d.ts +29 -0
  102. package/out/src/storage/schema/entities/User.d.ts.map +1 -0
  103. package/out/src/storage/schema/entities/User.js +100 -0
  104. package/out/src/storage/schema/entities/User.js.map +1 -0
  105. package/out/src/storage/schema/tables/Certificate.d.ts +20 -0
  106. package/out/src/storage/schema/tables/Certificate.d.ts.map +1 -0
  107. package/out/src/storage/schema/tables/Certificate.js +3 -0
  108. package/out/src/storage/schema/tables/Certificate.js.map +1 -0
  109. package/out/src/storage/schema/tables/CertificateField.d.ts +12 -0
  110. package/out/src/storage/schema/tables/CertificateField.d.ts.map +1 -0
  111. package/out/src/storage/schema/tables/CertificateField.js +3 -0
  112. package/out/src/storage/schema/tables/CertificateField.js.map +1 -0
  113. package/out/src/storage/schema/tables/Commission.d.ts +13 -0
  114. package/out/src/storage/schema/tables/Commission.d.ts.map +1 -0
  115. package/out/src/storage/schema/tables/Commission.js +3 -0
  116. package/out/src/storage/schema/tables/Commission.js.map +1 -0
  117. package/out/src/storage/schema/tables/MonitorEvent.d.ts +9 -0
  118. package/out/src/storage/schema/tables/MonitorEvent.d.ts.map +1 -0
  119. package/out/src/storage/schema/tables/MonitorEvent.js +3 -0
  120. package/out/src/storage/schema/tables/MonitorEvent.js.map +1 -0
  121. package/out/src/storage/schema/tables/Output.d.ts +36 -0
  122. package/out/src/storage/schema/tables/Output.d.ts.map +1 -0
  123. package/out/src/storage/schema/tables/Output.js +31 -0
  124. package/out/src/storage/schema/tables/Output.js.map +1 -0
  125. package/out/src/storage/schema/tables/OutputBasket.d.ts +12 -0
  126. package/out/src/storage/schema/tables/OutputBasket.d.ts.map +1 -0
  127. package/out/src/storage/schema/tables/OutputBasket.js +3 -0
  128. package/out/src/storage/schema/tables/OutputBasket.js.map +1 -0
  129. package/out/src/storage/schema/tables/OutputTag.d.ts +10 -0
  130. package/out/src/storage/schema/tables/OutputTag.d.ts.map +1 -0
  131. package/out/src/storage/schema/tables/OutputTag.js +3 -0
  132. package/out/src/storage/schema/tables/OutputTag.js.map +1 -0
  133. package/out/src/storage/schema/tables/OutputTagMap.d.ts +9 -0
  134. package/out/src/storage/schema/tables/OutputTagMap.d.ts.map +1 -0
  135. package/out/src/storage/schema/tables/OutputTagMap.js +3 -0
  136. package/out/src/storage/schema/tables/OutputTagMap.js.map +1 -0
  137. package/out/src/storage/schema/tables/ProvenTx.d.ts +14 -0
  138. package/out/src/storage/schema/tables/ProvenTx.d.ts.map +1 -0
  139. package/out/src/storage/schema/tables/ProvenTx.js +3 -0
  140. package/out/src/storage/schema/tables/ProvenTx.js.map +1 -0
  141. package/out/src/storage/schema/tables/ProvenTxReq.d.ts +64 -0
  142. package/out/src/storage/schema/tables/ProvenTxReq.d.ts.map +1 -0
  143. package/out/src/storage/schema/tables/ProvenTxReq.js +3 -0
  144. package/out/src/storage/schema/tables/ProvenTxReq.js.map +1 -0
  145. package/out/src/storage/schema/tables/SyncState.d.ts +18 -0
  146. package/out/src/storage/schema/tables/SyncState.d.ts.map +1 -0
  147. package/out/src/storage/schema/tables/SyncState.js +3 -0
  148. package/out/src/storage/schema/tables/SyncState.js.map +1 -0
  149. package/out/src/storage/schema/tables/Transaction.d.ts +37 -0
  150. package/out/src/storage/schema/tables/Transaction.d.ts.map +1 -0
  151. package/out/src/storage/schema/tables/Transaction.js +21 -0
  152. package/out/src/storage/schema/tables/Transaction.js.map +1 -0
  153. package/out/src/storage/schema/tables/TxLabel.d.ts +10 -0
  154. package/out/src/storage/schema/tables/TxLabel.d.ts.map +1 -0
  155. package/out/src/storage/schema/tables/TxLabel.js +3 -0
  156. package/out/src/storage/schema/tables/TxLabel.js.map +1 -0
  157. package/out/src/storage/schema/tables/TxLabelMap.d.ts +9 -0
  158. package/out/src/storage/schema/tables/TxLabelMap.d.ts.map +1 -0
  159. package/out/src/storage/schema/tables/TxLabelMap.js +3 -0
  160. package/out/src/storage/schema/tables/TxLabelMap.js.map +1 -0
  161. package/out/src/storage/schema/tables/User.d.ts +16 -0
  162. package/out/src/storage/schema/tables/User.d.ts.map +1 -0
  163. package/out/src/storage/schema/tables/User.js +3 -0
  164. package/out/src/storage/schema/tables/User.js.map +1 -0
  165. package/out/test/Wallet/action/abortAction.test.d.ts.map +1 -0
  166. package/out/test/{wallet → Wallet}/action/abortAction.test.js.map +1 -1
  167. package/out/test/Wallet/action/createAction.test.d.ts.map +1 -0
  168. package/out/test/{wallet → Wallet}/action/createAction.test.js.map +1 -1
  169. package/out/test/{wallet → Wallet}/action/createAction2.test.d.ts.map +1 -1
  170. package/out/test/{wallet → Wallet}/action/createAction2.test.js.map +1 -1
  171. package/out/test/Wallet/action/createActionToGenerateBeefs.man.test.d.ts.map +1 -0
  172. package/out/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.js.map +1 -1
  173. package/out/test/Wallet/action/internalizeAction.test.d.ts.map +1 -0
  174. package/out/test/{wallet → Wallet}/action/internalizeAction.test.js.map +1 -1
  175. package/out/test/Wallet/action/relinquishOutput.test.d.ts.map +1 -0
  176. package/out/test/{wallet → Wallet}/action/relinquishOutput.test.js.map +1 -1
  177. package/out/test/Wallet/construct/Wallet.constructor.test.d.ts.map +1 -0
  178. package/out/test/{wallet → Wallet}/construct/Wallet.constructor.test.js.map +1 -1
  179. package/out/test/Wallet/list/listActions.test.d.ts.map +1 -0
  180. package/out/test/{wallet → Wallet}/list/listActions.test.js.map +1 -1
  181. package/out/test/Wallet/list/listActions2.test.d.ts.map +1 -0
  182. package/out/test/{wallet → Wallet}/list/listActions2.test.js.map +1 -1
  183. package/out/test/Wallet/list/listCertificates.test.d.ts.map +1 -0
  184. package/out/test/{wallet → Wallet}/list/listCertificates.test.js.map +1 -1
  185. package/out/test/Wallet/list/listOutputs.test.d.ts.map +1 -0
  186. package/out/test/{wallet → Wallet}/list/listOutputs.test.js.map +1 -1
  187. package/out/test/Wallet/local/localWalletMethods.d.ts +28 -0
  188. package/out/test/Wallet/local/localWalletMethods.d.ts.map +1 -0
  189. package/out/test/Wallet/local/localWalletMethods.js +281 -0
  190. package/out/test/Wallet/local/localWalletMethods.js.map +1 -0
  191. package/out/test/Wallet/support/opers1.man.test.d.ts +2 -0
  192. package/out/test/Wallet/support/opers1.man.test.d.ts.map +1 -0
  193. package/out/test/Wallet/support/opers1.man.test.js +202 -0
  194. package/out/test/Wallet/support/opers1.man.test.js.map +1 -0
  195. package/out/test/Wallet/sync/Wallet.sync.test.d.ts.map +1 -0
  196. package/out/test/{wallet → Wallet}/sync/Wallet.sync.test.js.map +1 -1
  197. package/out/tsconfig.all.tsbuildinfo +1 -1
  198. package/package.json +1 -1
  199. package/src/CWIStyleWalletManager.ts +1 -1
  200. package/src/WalletPermissionsManager.ts +317 -26
  201. package/src/__tests/WalletPermissionsManager.initialization.test.ts +1 -1
  202. package/src/monitor/tasks/TaskCheckNoSends.ts +0 -1
  203. package/src/monitor/tasks/TaskNewHeader.ts +1 -1
  204. package/out/test/wallet/action/abortAction.test.d.ts.map +0 -1
  205. package/out/test/wallet/action/createAction.test.d.ts.map +0 -1
  206. package/out/test/wallet/action/createActionToGenerateBeefs.man.test.d.ts.map +0 -1
  207. package/out/test/wallet/action/internalizeAction.test.d.ts.map +0 -1
  208. package/out/test/wallet/action/relinquishOutput.test.d.ts.map +0 -1
  209. package/out/test/wallet/construct/Wallet.constructor.test.d.ts.map +0 -1
  210. package/out/test/wallet/list/listActions.test.d.ts.map +0 -1
  211. package/out/test/wallet/list/listActions2.test.d.ts.map +0 -1
  212. package/out/test/wallet/list/listCertificates.test.d.ts.map +0 -1
  213. package/out/test/wallet/list/listOutputs.test.d.ts.map +0 -1
  214. package/out/test/wallet/sync/Wallet.sync.test.d.ts.map +0 -1
  215. /package/out/test/{wallet → Wallet}/action/abortAction.test.d.ts +0 -0
  216. /package/out/test/{wallet → Wallet}/action/abortAction.test.js +0 -0
  217. /package/out/test/{wallet → Wallet}/action/createAction.test.d.ts +0 -0
  218. /package/out/test/{wallet → Wallet}/action/createAction.test.js +0 -0
  219. /package/out/test/{wallet → Wallet}/action/createAction2.test.d.ts +0 -0
  220. /package/out/test/{wallet → Wallet}/action/createAction2.test.js +0 -0
  221. /package/out/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.d.ts +0 -0
  222. /package/out/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.js +0 -0
  223. /package/out/test/{wallet → Wallet}/action/internalizeAction.test.d.ts +0 -0
  224. /package/out/test/{wallet → Wallet}/action/internalizeAction.test.js +0 -0
  225. /package/out/test/{wallet → Wallet}/action/relinquishOutput.test.d.ts +0 -0
  226. /package/out/test/{wallet → Wallet}/action/relinquishOutput.test.js +0 -0
  227. /package/out/test/{wallet → Wallet}/construct/Wallet.constructor.test.d.ts +0 -0
  228. /package/out/test/{wallet → Wallet}/construct/Wallet.constructor.test.js +0 -0
  229. /package/out/test/{wallet → Wallet}/list/listActions.test.d.ts +0 -0
  230. /package/out/test/{wallet → Wallet}/list/listActions.test.js +0 -0
  231. /package/out/test/{wallet → Wallet}/list/listActions2.test.d.ts +0 -0
  232. /package/out/test/{wallet → Wallet}/list/listActions2.test.js +0 -0
  233. /package/out/test/{wallet → Wallet}/list/listCertificates.test.d.ts +0 -0
  234. /package/out/test/{wallet → Wallet}/list/listCertificates.test.js +0 -0
  235. /package/out/test/{wallet → Wallet}/list/listOutputs.test.d.ts +0 -0
  236. /package/out/test/{wallet → Wallet}/list/listOutputs.test.js +0 -0
  237. /package/out/test/{wallet → Wallet}/sync/Wallet.sync.test.d.ts +0 -0
  238. /package/out/test/{wallet → Wallet}/sync/Wallet.sync.test.js +0 -0
  239. /package/test/{wallet → Wallet}/action/abortAction.test.ts +0 -0
  240. /package/test/{wallet → Wallet}/action/createAction.test.ts +0 -0
  241. /package/test/{wallet → Wallet}/action/createAction2.test.ts +0 -0
  242. /package/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.ts +0 -0
  243. /package/test/{wallet → Wallet}/action/internalizeAction.test.ts +0 -0
  244. /package/test/{wallet → Wallet}/action/relinquishOutput.test.ts +0 -0
  245. /package/test/{wallet → Wallet}/construct/Wallet.constructor.test.ts +0 -0
  246. /package/test/{wallet → Wallet}/list/listActions.test.ts +0 -0
  247. /package/test/{wallet → Wallet}/list/listActions2.test.ts +0 -0
  248. /package/test/{wallet → Wallet}/list/listCertificates.test.ts +0 -0
  249. /package/test/{wallet → Wallet}/list/listOutputs.test.ts +0 -0
  250. /package/test/{wallet → Wallet}/sync/Wallet.sync.test.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/wallet-toolbox",
3
- "version": "1.4.3",
3
+ "version": "1.4.5",
4
4
  "description": "BRC100 conforming wallet, wallet storage and wallet signer components",
5
5
  "main": "./out/src/index.js",
6
6
  "types": "./out/src/index.d.ts",
@@ -1870,7 +1870,7 @@ export class CWIStyleWalletManager implements WalletInterface {
1870
1870
  while (!this.authenticated || !this.underlying) {
1871
1871
  await new Promise(resolve => setTimeout(resolve, 100))
1872
1872
  }
1873
- return { authenticated: true }
1873
+ return await this.underlying.waitForAuthentication({}, originator)
1874
1874
  }
1875
1875
 
1876
1876
  async getHeight(_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetHeightResult> {
@@ -11,8 +11,77 @@ import {
11
11
  import { validateCreateActionArgs } from './sdk'
12
12
 
13
13
  ////// TODO: ADD SUPPORT FOR ADMIN COUNTERPARTIES BASED ON WALLET STORAGE
14
+ ////// PROHIBITION OF SPECIAL OPERATIONS IS ALSO CRITICAL.
14
15
  ////// !!!!!!!! SECURITY-CRITICAL ADDITION — DO NOT USE UNTIL IMPLEMENTED.
15
16
 
17
+ function deepEqual(object1: any, object2: any): boolean {
18
+ if (object1 === null || object1 === undefined || object2 === null || object2 === undefined) {
19
+ return object1 === object2
20
+ }
21
+ const keys1 = Object.keys(object1)
22
+ const keys2 = Object.keys(object2)
23
+
24
+ if (keys1.length !== keys2.length) {
25
+ return false
26
+ }
27
+
28
+ for (const key of keys1) {
29
+ const val1 = object1[key]
30
+ const val2 = object2[key]
31
+ const areObjects = isObject(val1) && isObject(val2)
32
+ if ((areObjects && !deepEqual(val1, val2)) || (!areObjects && val1 !== val2)) {
33
+ return false
34
+ }
35
+ }
36
+
37
+ return true
38
+ }
39
+
40
+ function isObject(object: any): boolean {
41
+ return object != null && typeof object === 'object'
42
+ }
43
+
44
+ /**
45
+ * Describes a group of permissions that can be requested together.
46
+ * This structure is based on BRC-73.
47
+ */
48
+ export interface GroupedPermissions {
49
+ description?: string
50
+ spendingAuthorization?: {
51
+ amount: number
52
+ description: string
53
+ }
54
+ protocolPermissions?: Array<{
55
+ protocolID: WalletProtocol
56
+ counterparty?: string
57
+ description: string
58
+ }>
59
+ basketAccess?: Array<{
60
+ basket: string
61
+ description: string
62
+ }>
63
+ certificateAccess?: Array<{
64
+ type: string
65
+ fields: string[]
66
+ verifierPublicKey: string
67
+ description: string
68
+ }>
69
+ }
70
+
71
+ /**
72
+ * The object passed to the UI when a grouped permission is requested.
73
+ */
74
+ export interface GroupedPermissionRequest {
75
+ originator: string
76
+ requestID: string
77
+ permissions: GroupedPermissions
78
+ }
79
+
80
+ /**
81
+ * Signature for functions that handle a grouped permission request event.
82
+ */
83
+ export type GroupedPermissionEventHandler = (request: GroupedPermissionRequest) => void | Promise<void>
84
+
16
85
  /**
17
86
  * Describes a single requested permission that the user must either grant or deny.
18
87
  *
@@ -146,6 +215,7 @@ export interface WalletPermissionsManagerCallbacks {
146
215
  onBasketAccessRequested?: PermissionEventHandler[]
147
216
  onCertificateAccessRequested?: PermissionEventHandler[]
148
217
  onSpendingAuthorizationRequested?: PermissionEventHandler[]
218
+ onGroupedPermissionRequested?: GroupedPermissionEventHandler[]
149
219
  }
150
220
 
151
221
  /**
@@ -255,6 +325,11 @@ export interface PermissionsManagerConfig {
255
325
  */
256
326
  seekSpendingPermissions?: boolean
257
327
 
328
+ /**
329
+ * If true, triggers a grouped permission request flow based on the originator's `manifest.json`.
330
+ */
331
+ seekGroupedPermission?: boolean
332
+
258
333
  /**
259
334
  * If false, permissions are checked without regard for whether we are in
260
335
  * privileged mode. Privileged status is ignored with respect to whether
@@ -300,7 +375,8 @@ export class WalletPermissionsManager implements WalletInterface {
300
375
  onProtocolPermissionRequested: [],
301
376
  onBasketAccessRequested: [],
302
377
  onCertificateAccessRequested: [],
303
- onSpendingAuthorizationRequested: []
378
+ onSpendingAuthorizationRequested: [],
379
+ onGroupedPermissionRequested: []
304
380
  }
305
381
 
306
382
  /**
@@ -316,9 +392,9 @@ export class WalletPermissionsManager implements WalletInterface {
316
392
  private activeRequests: Map<
317
393
  string,
318
394
  {
319
- request: PermissionRequest
395
+ request: PermissionRequest | { originator: string; permissions: GroupedPermissions }
320
396
  pending: Array<{
321
- resolve: (val: boolean) => void
397
+ resolve: (val: any) => void
322
398
  reject: (err: any) => void
323
399
  }>
324
400
  }
@@ -366,6 +442,7 @@ export class WalletPermissionsManager implements WalletInterface {
366
442
  seekCertificateListingPermissions: true,
367
443
  encryptWalletMetadata: true,
368
444
  seekSpendingPermissions: true,
445
+ seekGroupedPermission: true,
369
446
  differentiatePrivilegedOperations: true,
370
447
  ...config // override with user-specified config
371
448
  }
@@ -382,8 +459,11 @@ export class WalletPermissionsManager implements WalletInterface {
382
459
  * @param handler A function that handles the event
383
460
  * @returns A numeric ID you can use to unbind later
384
461
  */
385
- public bindCallback(eventName: keyof WalletPermissionsManagerCallbacks, handler: PermissionEventHandler): number {
386
- const arr = this.callbacks[eventName]!
462
+ public bindCallback(
463
+ eventName: keyof WalletPermissionsManagerCallbacks,
464
+ handler: PermissionEventHandler | GroupedPermissionEventHandler
465
+ ): number {
466
+ const arr = this.callbacks[eventName]! as any[]
387
467
  arr.push(handler)
388
468
  return arr.length - 1
389
469
  }
@@ -469,18 +549,19 @@ export class WalletPermissionsManager implements WalletInterface {
469
549
 
470
550
  // 3) If `ephemeral !== true`, we create or renew an on-chain token
471
551
  if (!params.ephemeral) {
472
- if (!matching.request.renewal) {
552
+ const request = matching.request as PermissionRequest
553
+ if (!request.renewal) {
473
554
  // brand-new permission token
474
555
  await this.createPermissionOnChain(
475
- matching.request,
556
+ request,
476
557
  params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30, // default 30-day expiry
477
558
  params.amount
478
559
  )
479
560
  } else {
480
561
  // renewal => spend the old token, produce a new one
481
562
  await this.renewPermissionOnChain(
482
- matching.request.previousToken!,
483
- matching.request,
563
+ request.previousToken!,
564
+ request,
484
565
  params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30,
485
566
  params.amount
486
567
  )
@@ -489,7 +570,7 @@ export class WalletPermissionsManager implements WalletInterface {
489
570
 
490
571
  // Update the cache regardless of ephemeral status
491
572
  const expiry = params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30
492
- const key = this.buildRequestKey(matching.request)
573
+ const key = this.buildRequestKey(matching.request as PermissionRequest)
493
574
  this.cachePermission(key, expiry)
494
575
  }
495
576
 
@@ -513,6 +594,123 @@ export class WalletPermissionsManager implements WalletInterface {
513
594
  this.activeRequests.delete(requestID)
514
595
  }
515
596
 
597
+ /**
598
+ * Grants a previously requested grouped permission.
599
+ * @param params.requestID The ID of the request being granted.
600
+ * @param params.granted A subset of the originally requested permissions that the user has granted.
601
+ * @param params.expiry An optional expiry time (in seconds) for the new permission tokens.
602
+ */
603
+ public async grantGroupedPermission(params: {
604
+ requestID: string
605
+ granted: Partial<GroupedPermissions>
606
+ expiry?: number
607
+ }): Promise<void> {
608
+ const matching = this.activeRequests.get(params.requestID)
609
+ if (!matching) {
610
+ throw new Error('Request ID not found.')
611
+ }
612
+
613
+ const originalRequest = matching.request as { originator: string; permissions: GroupedPermissions }
614
+ const { originator, permissions: requestedPermissions } = originalRequest
615
+
616
+ // --- Validation: Ensure granted permissions are a subset of what was requested ---
617
+ if (
618
+ params.granted.spendingAuthorization &&
619
+ !deepEqual(params.granted.spendingAuthorization, requestedPermissions.spendingAuthorization)
620
+ ) {
621
+ throw new Error('Granted spending authorization does not match the original request.')
622
+ }
623
+ if (
624
+ params.granted.protocolPermissions?.some(
625
+ g => !requestedPermissions.protocolPermissions?.find(r => deepEqual(r, g))
626
+ )
627
+ ) {
628
+ throw new Error('Granted protocol permissions are not a subset of the original request.')
629
+ }
630
+ if (params.granted.basketAccess?.some(g => !requestedPermissions.basketAccess?.find(r => deepEqual(r, g)))) {
631
+ throw new Error('Granted basket access permissions are not a subset of the original request.')
632
+ }
633
+ if (
634
+ params.granted.certificateAccess?.some(g => !requestedPermissions.certificateAccess?.find(r => deepEqual(r, g)))
635
+ ) {
636
+ throw new Error('Granted certificate access permissions are not a subset of the original request.')
637
+ }
638
+ // --- End Validation ---
639
+
640
+ const expiry = params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30 // 30-day default
641
+
642
+ if (params.granted.spendingAuthorization) {
643
+ await this.createPermissionOnChain(
644
+ {
645
+ type: 'spending',
646
+ originator,
647
+ spending: { satoshis: params.granted.spendingAuthorization.amount },
648
+ reason: params.granted.spendingAuthorization.description
649
+ },
650
+ 0, // No expiry for spending tokens
651
+ params.granted.spendingAuthorization.amount
652
+ )
653
+ }
654
+ for (const p of params.granted.protocolPermissions || []) {
655
+ await this.createPermissionOnChain(
656
+ {
657
+ type: 'protocol',
658
+ originator,
659
+ privileged: false, // No privileged protocols allowed in groups for added security.
660
+ protocolID: p.protocolID,
661
+ counterparty: p.counterparty || 'self',
662
+ reason: p.description
663
+ },
664
+ expiry
665
+ )
666
+ }
667
+ for (const b of params.granted.basketAccess || []) {
668
+ await this.createPermissionOnChain(
669
+ { type: 'basket', originator, basket: b.basket, reason: b.description },
670
+ expiry
671
+ )
672
+ }
673
+ for (const c of params.granted.certificateAccess || []) {
674
+ await this.createPermissionOnChain(
675
+ {
676
+ type: 'certificate',
677
+ originator,
678
+ privileged: false, // No certificates on the privileged identity are allowed as part of groups.
679
+ certificate: {
680
+ verifier: c.verifierPublicKey,
681
+ certType: c.type,
682
+ fields: c.fields
683
+ },
684
+ reason: c.description
685
+ },
686
+ expiry
687
+ )
688
+ }
689
+
690
+ // Resolve all pending promises for this request
691
+ for (const p of matching.pending) {
692
+ p.resolve(true)
693
+ }
694
+ this.activeRequests.delete(params.requestID)
695
+ }
696
+
697
+ /**
698
+ * Denies a previously requested grouped permission.
699
+ * @param requestID The ID of the request being denied.
700
+ */
701
+ public async denyGroupedPermission(requestID: string): Promise<void> {
702
+ const matching = this.activeRequests.get(requestID)
703
+ if (!matching) {
704
+ throw new Error('Request ID not found.')
705
+ }
706
+ const err = new Error('The user has denied the request for permission.')
707
+ ;(err as any).code = 'ERR_PERMISSION_DENIED'
708
+ for (const p of matching.pending) {
709
+ p.reject(err)
710
+ }
711
+ this.activeRequests.delete(requestID)
712
+ }
713
+
516
714
  /* ---------------------------------------------------------------------
517
715
  * 3) THE "ENSURE" METHODS: CHECK IF PERMISSION EXISTS, OTHERWISE PROMPT
518
716
  * --------------------------------------------------------------------- */
@@ -2127,22 +2325,6 @@ export class WalletPermissionsManager implements WalletInterface {
2127
2325
  ...signResult,
2128
2326
  signableTransaction: undefined
2129
2327
  }
2130
-
2131
- // const userWantedImmediate = args.options?.signAndProcess !== false
2132
- // const weOverrode =
2133
- // modifiedOptions.signAndProcess === false &&
2134
- // args.options?.signAndProcess !== false
2135
-
2136
- // // Check if all inputs already have valid unlockingScripts (no partial signatures needed)
2137
- const allInputsHaveScripts = tx.inputs.every(i => i.unlockingScript)
2138
-
2139
- // // If user wanted immediate broadcast and we forcibly suppressed it, we can finalize now by calling signAction with no additional scripts:
2140
- // if (allInputsHaveScripts && userWantedImmediate && weOverrode) {
2141
-
2142
- // }
2143
-
2144
- // // Otherwise, return the partial transaction so the caller can do signAction.
2145
- // return createResult
2146
2328
  }
2147
2329
 
2148
2330
  public async signAction(
@@ -2526,6 +2708,115 @@ export class WalletPermissionsManager implements WalletInterface {
2526
2708
  public async waitForAuthentication(
2527
2709
  ...args: Parameters<WalletInterface['waitForAuthentication']>
2528
2710
  ): ReturnType<WalletInterface['waitForAuthentication']> {
2711
+ const [_, originator] = args
2712
+ if (this.config.seekGroupedPermission && originator) {
2713
+ // 1. Fetch manifest.json from the originator
2714
+ let groupPermissions: GroupedPermissions | undefined
2715
+ try {
2716
+ const proto = originator.startsWith('localhost:') ? 'http' : 'https'
2717
+ const response = await fetch(`${proto}://${originator}/manifest.json`)
2718
+ if (response.ok) {
2719
+ const manifest = await response.json()
2720
+ if (manifest?.babbage?.groupPermissions) {
2721
+ groupPermissions = manifest.babbage.groupPermissions
2722
+ }
2723
+ }
2724
+ } catch (e) {
2725
+ // Ignore fetch/parse errors, just proceed without group permissions.
2726
+ }
2727
+
2728
+ if (groupPermissions) {
2729
+ // 2. Filter out already-granted permissions
2730
+ const permissionsToRequest: GroupedPermissions = {
2731
+ protocolPermissions: [],
2732
+ basketAccess: [],
2733
+ certificateAccess: []
2734
+ }
2735
+
2736
+ if (groupPermissions.spendingAuthorization) {
2737
+ const hasAuth = await this.hasSpendingAuthorization({
2738
+ originator,
2739
+ satoshis: groupPermissions.spendingAuthorization.amount
2740
+ })
2741
+ if (!hasAuth) {
2742
+ permissionsToRequest.spendingAuthorization = groupPermissions.spendingAuthorization
2743
+ }
2744
+ }
2745
+
2746
+ for (const p of groupPermissions.protocolPermissions || []) {
2747
+ const hasPerm = await this.hasProtocolPermission({
2748
+ originator,
2749
+ privileged: false, // Privilege is never allowed here
2750
+ protocolID: p.protocolID,
2751
+ counterparty: p.counterparty || 'self'
2752
+ })
2753
+ if (!hasPerm) {
2754
+ permissionsToRequest.protocolPermissions!.push(p)
2755
+ }
2756
+ }
2757
+
2758
+ for (const b of groupPermissions.basketAccess || []) {
2759
+ const hasAccess = await this.hasBasketAccess({
2760
+ originator,
2761
+ basket: b.basket
2762
+ })
2763
+ if (!hasAccess) {
2764
+ permissionsToRequest.basketAccess!.push(b)
2765
+ }
2766
+ }
2767
+
2768
+ for (const c of groupPermissions.certificateAccess || []) {
2769
+ const hasAccess = await this.hasCertificateAccess({
2770
+ originator,
2771
+ privileged: false, // Privilege is never allowed here for security
2772
+ verifier: c.verifierPublicKey,
2773
+ certType: c.type,
2774
+ fields: c.fields
2775
+ })
2776
+ if (!hasAccess) {
2777
+ permissionsToRequest.certificateAccess!.push(c)
2778
+ }
2779
+ }
2780
+
2781
+ // 3. If any permissions are left to request, start the flow
2782
+ const hasRequests =
2783
+ permissionsToRequest.spendingAuthorization ||
2784
+ (permissionsToRequest.protocolPermissions?.length ?? 0) > 0 ||
2785
+ (permissionsToRequest.basketAccess?.length ?? 0) > 0 ||
2786
+ (permissionsToRequest.certificateAccess?.length ?? 0) > 0
2787
+
2788
+ if (hasRequests) {
2789
+ const key = `group:${originator}`
2790
+ if (this.activeRequests.has(key)) {
2791
+ // Another call is already waiting, piggyback on it
2792
+ await new Promise<boolean>((resolve, reject) => {
2793
+ this.activeRequests.get(key)!.pending.push({ resolve, reject })
2794
+ })
2795
+ } else {
2796
+ // This is the first call, create a new request
2797
+ try {
2798
+ await new Promise<boolean>(async (resolve, reject) => {
2799
+ this.activeRequests.set(key, {
2800
+ request: { originator, permissions: permissionsToRequest },
2801
+ pending: [{ resolve, reject }]
2802
+ })
2803
+
2804
+ await this.callEvent('onGroupedPermissionRequested', {
2805
+ requestID: key,
2806
+ originator,
2807
+ permissions: permissionsToRequest
2808
+ })
2809
+ })
2810
+ } catch (e) {
2811
+ // Permission was denied, re-throw to stop execution
2812
+ throw e
2813
+ }
2814
+ }
2815
+ }
2816
+ }
2817
+ }
2818
+
2819
+ // Finally, after handling grouped permissions, call the underlying method.
2529
2820
  return this.underlying.waitForAuthentication(...args)
2530
2821
  }
2531
2822
 
@@ -188,7 +188,7 @@ describe('WalletPermissionsManager - Initialization & Configuration', () => {
188
188
  'onSpendingAuthorizationRequested',
189
189
  jest.fn(x => {
190
190
  manager.grantPermission({ requestID: x.requestID, ephemeral: true })
191
- })
191
+ }) as any
192
192
  )
193
193
 
194
194
  // Non-admin origin tries to createAction specifying a basket
@@ -52,7 +52,6 @@ export class TaskCheckNoSends extends WalletMonitorTask {
52
52
  return log
53
53
  }
54
54
 
55
-
56
55
  const limit = 100
57
56
  let offset = 0
58
57
  for (;;) {
@@ -6,7 +6,7 @@ import { WalletMonitorTask } from './WalletMonitorTask'
6
6
  * This task polls for new block headers performing two essential functions:
7
7
  * 1. The arrival of a new block is the right time to check for proofs for recently broadcast transactions.
8
8
  * 2. The height of the block is used to limit which proofs are accepted with the aim of avoiding re-orged proofs.
9
- *
9
+ *
10
10
  * The most common new block orphan is one which is almost immediately orphaned.
11
11
  * Waiting a minute before pursuing proof requests avoids almost all the re-org work that could be done.
12
12
  * Thus this task queues new headers for one cycle.
@@ -1 +0,0 @@
1
- {"version":3,"file":"abortAction.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/abortAction.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"createAction.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/createAction.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"createActionToGenerateBeefs.man.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/createActionToGenerateBeefs.man.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"internalizeAction.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/internalizeAction.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"relinquishOutput.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/relinquishOutput.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Wallet.constructor.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/construct/Wallet.constructor.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"listActions.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/list/listActions.test.ts"],"names":[],"mappings":"AAWA,OAAO,qBAAqB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"listActions2.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/list/listActions2.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"listCertificates.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/list/listCertificates.test.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"listOutputs.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/list/listOutputs.test.ts"],"names":[],"mappings":"AAUA,OAAO,qBAAqB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Wallet.sync.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/sync/Wallet.sync.test.ts"],"names":[],"mappings":""}