@bsv/wallet-toolbox 1.3.21 → 1.3.22

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 (502) hide show
  1. package/mobile/out/src/CWIStyleWalletManager.d.ts +437 -0
  2. package/mobile/out/src/CWIStyleWalletManager.d.ts.map +1 -0
  3. package/mobile/out/src/CWIStyleWalletManager.js +1255 -0
  4. package/mobile/out/src/CWIStyleWalletManager.js.map +1 -0
  5. package/mobile/out/src/SetupClient.d.ts +126 -0
  6. package/mobile/out/src/SetupClient.d.ts.map +1 -0
  7. package/mobile/out/src/SetupClient.js +220 -0
  8. package/mobile/out/src/SetupClient.js.map +1 -0
  9. package/mobile/out/src/SetupWallet.d.ts +100 -0
  10. package/mobile/out/src/SetupWallet.d.ts.map +1 -0
  11. package/mobile/out/src/SetupWallet.js +3 -0
  12. package/mobile/out/src/SetupWallet.js.map +1 -0
  13. package/mobile/out/src/SimpleWalletManager.d.ts +169 -0
  14. package/mobile/out/src/SimpleWalletManager.d.ts.map +1 -0
  15. package/mobile/out/src/SimpleWalletManager.js +315 -0
  16. package/mobile/out/src/SimpleWalletManager.js.map +1 -0
  17. package/mobile/out/src/Wallet.d.ts +177 -0
  18. package/mobile/out/src/Wallet.d.ts.map +1 -0
  19. package/mobile/out/src/Wallet.js +742 -0
  20. package/mobile/out/src/Wallet.js.map +1 -0
  21. package/mobile/out/src/WalletAuthenticationManager.d.ts +33 -0
  22. package/mobile/out/src/WalletAuthenticationManager.d.ts.map +1 -0
  23. package/mobile/out/src/WalletAuthenticationManager.js +113 -0
  24. package/mobile/out/src/WalletAuthenticationManager.js.map +1 -0
  25. package/mobile/out/src/WalletPermissionsManager.d.ts +598 -0
  26. package/mobile/out/src/WalletPermissionsManager.d.ts.map +1 -0
  27. package/mobile/out/src/WalletPermissionsManager.js +1868 -0
  28. package/mobile/out/src/WalletPermissionsManager.js.map +1 -0
  29. package/mobile/out/src/WalletSettingsManager.d.ts +52 -0
  30. package/mobile/out/src/WalletSettingsManager.d.ts.map +1 -0
  31. package/mobile/out/src/WalletSettingsManager.js +82 -0
  32. package/mobile/out/src/WalletSettingsManager.js.map +1 -0
  33. package/mobile/out/src/index.client.d.ts +19 -0
  34. package/mobile/out/src/index.client.d.ts.map +1 -0
  35. package/mobile/out/src/index.client.js +58 -0
  36. package/mobile/out/src/index.client.js.map +1 -0
  37. package/mobile/out/src/index.mobile.d.ts +19 -0
  38. package/mobile/out/src/index.mobile.d.ts.map +1 -0
  39. package/mobile/out/src/index.mobile.js +58 -0
  40. package/mobile/out/src/index.mobile.js.map +1 -0
  41. package/mobile/out/src/monitor/Monitor.d.ts +91 -0
  42. package/mobile/out/src/monitor/Monitor.d.ts.map +1 -0
  43. package/mobile/out/src/monitor/Monitor.js +298 -0
  44. package/mobile/out/src/monitor/Monitor.js.map +1 -0
  45. package/mobile/out/src/monitor/tasks/TaskCheckForProofs.d.ts +53 -0
  46. package/mobile/out/src/monitor/tasks/TaskCheckForProofs.d.ts.map +1 -0
  47. package/mobile/out/src/monitor/tasks/TaskCheckForProofs.js +194 -0
  48. package/mobile/out/src/monitor/tasks/TaskCheckForProofs.js.map +1 -0
  49. package/mobile/out/src/monitor/tasks/TaskCheckNoSends.d.ts +33 -0
  50. package/mobile/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -0
  51. package/mobile/out/src/monitor/tasks/TaskCheckNoSends.js +65 -0
  52. package/mobile/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -0
  53. package/mobile/out/src/monitor/tasks/TaskClock.d.ts +14 -0
  54. package/mobile/out/src/monitor/tasks/TaskClock.d.ts.map +1 -0
  55. package/mobile/out/src/monitor/tasks/TaskClock.js +27 -0
  56. package/mobile/out/src/monitor/tasks/TaskClock.js.map +1 -0
  57. package/mobile/out/src/monitor/tasks/TaskFailAbandoned.d.ts +20 -0
  58. package/mobile/out/src/monitor/tasks/TaskFailAbandoned.d.ts.map +1 -0
  59. package/mobile/out/src/monitor/tasks/TaskFailAbandoned.js +52 -0
  60. package/mobile/out/src/monitor/tasks/TaskFailAbandoned.js.map +1 -0
  61. package/mobile/out/src/monitor/tasks/TaskNewHeader.d.ts +15 -0
  62. package/mobile/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -0
  63. package/mobile/out/src/monitor/tasks/TaskNewHeader.js +43 -0
  64. package/mobile/out/src/monitor/tasks/TaskNewHeader.js.map +1 -0
  65. package/mobile/out/src/monitor/tasks/TaskPurge.d.ts +45 -0
  66. package/mobile/out/src/monitor/tasks/TaskPurge.d.ts.map +1 -0
  67. package/mobile/out/src/monitor/tasks/TaskPurge.js +34 -0
  68. package/mobile/out/src/monitor/tasks/TaskPurge.js.map +1 -0
  69. package/mobile/out/src/monitor/tasks/TaskReviewStatus.d.ts +26 -0
  70. package/mobile/out/src/monitor/tasks/TaskReviewStatus.d.ts.map +1 -0
  71. package/mobile/out/src/monitor/tasks/TaskReviewStatus.js +43 -0
  72. package/mobile/out/src/monitor/tasks/TaskReviewStatus.js.map +1 -0
  73. package/mobile/out/src/monitor/tasks/TaskSendWaiting.d.ts +35 -0
  74. package/mobile/out/src/monitor/tasks/TaskSendWaiting.d.ts.map +1 -0
  75. package/mobile/out/src/monitor/tasks/TaskSendWaiting.js +107 -0
  76. package/mobile/out/src/monitor/tasks/TaskSendWaiting.js.map +1 -0
  77. package/mobile/out/src/monitor/tasks/TaskSyncWhenIdle.d.ts +12 -0
  78. package/mobile/out/src/monitor/tasks/TaskSyncWhenIdle.d.ts.map +1 -0
  79. package/mobile/out/src/monitor/tasks/TaskSyncWhenIdle.js +22 -0
  80. package/mobile/out/src/monitor/tasks/TaskSyncWhenIdle.js.map +1 -0
  81. package/mobile/out/src/monitor/tasks/TaskUnFail.d.ts +41 -0
  82. package/mobile/out/src/monitor/tasks/TaskUnFail.d.ts.map +1 -0
  83. package/mobile/out/src/monitor/tasks/TaskUnFail.js +144 -0
  84. package/mobile/out/src/monitor/tasks/TaskUnFail.js.map +1 -0
  85. package/mobile/out/src/monitor/tasks/WalletMonitorTask.d.ts +40 -0
  86. package/mobile/out/src/monitor/tasks/WalletMonitorTask.d.ts.map +1 -0
  87. package/mobile/out/src/monitor/tasks/WalletMonitorTask.js +37 -0
  88. package/mobile/out/src/monitor/tasks/WalletMonitorTask.js.map +1 -0
  89. package/mobile/out/src/sdk/CertOpsWallet.d.ts +7 -0
  90. package/mobile/out/src/sdk/CertOpsWallet.d.ts.map +1 -0
  91. package/mobile/out/src/sdk/CertOpsWallet.js +3 -0
  92. package/mobile/out/src/sdk/CertOpsWallet.js.map +1 -0
  93. package/mobile/out/src/sdk/PrivilegedKeyManager.d.ts +125 -0
  94. package/mobile/out/src/sdk/PrivilegedKeyManager.d.ts.map +1 -0
  95. package/mobile/out/src/sdk/PrivilegedKeyManager.js +293 -0
  96. package/mobile/out/src/sdk/PrivilegedKeyManager.js.map +1 -0
  97. package/mobile/out/src/sdk/WERR_errors.d.ts +115 -0
  98. package/mobile/out/src/sdk/WERR_errors.d.ts.map +1 -0
  99. package/mobile/out/src/sdk/WERR_errors.js +158 -0
  100. package/mobile/out/src/sdk/WERR_errors.js.map +1 -0
  101. package/mobile/out/src/sdk/WalletError.d.ts +44 -0
  102. package/mobile/out/src/sdk/WalletError.d.ts.map +1 -0
  103. package/mobile/out/src/sdk/WalletError.js +118 -0
  104. package/mobile/out/src/sdk/WalletError.js.map +1 -0
  105. package/mobile/out/src/sdk/WalletServices.interfaces.d.ts +430 -0
  106. package/mobile/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -0
  107. package/mobile/out/src/sdk/WalletServices.interfaces.js +3 -0
  108. package/mobile/out/src/sdk/WalletServices.interfaces.js.map +1 -0
  109. package/mobile/out/src/sdk/WalletSigner.interfaces.d.ts +10 -0
  110. package/mobile/out/src/sdk/WalletSigner.interfaces.d.ts.map +1 -0
  111. package/mobile/out/src/sdk/WalletSigner.interfaces.js +3 -0
  112. package/mobile/out/src/sdk/WalletSigner.interfaces.js.map +1 -0
  113. package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts +452 -0
  114. package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -0
  115. package/mobile/out/src/sdk/WalletStorage.interfaces.js +3 -0
  116. package/mobile/out/src/sdk/WalletStorage.interfaces.js.map +1 -0
  117. package/mobile/out/src/sdk/index.d.ts +10 -0
  118. package/mobile/out/src/sdk/index.d.ts.map +1 -0
  119. package/mobile/out/src/sdk/index.js +26 -0
  120. package/mobile/out/src/sdk/index.js.map +1 -0
  121. package/mobile/out/src/sdk/types.d.ts +158 -0
  122. package/mobile/out/src/sdk/types.d.ts.map +1 -0
  123. package/mobile/out/src/sdk/types.js +90 -0
  124. package/mobile/out/src/sdk/types.js.map +1 -0
  125. package/mobile/out/src/sdk/validationHelpers.d.ts +301 -0
  126. package/mobile/out/src/sdk/validationHelpers.d.ts.map +1 -0
  127. package/mobile/out/src/sdk/validationHelpers.js +629 -0
  128. package/mobile/out/src/sdk/validationHelpers.js.map +1 -0
  129. package/mobile/out/src/services/ServiceCollection.d.ts +25 -0
  130. package/mobile/out/src/services/ServiceCollection.d.ts.map +1 -0
  131. package/mobile/out/src/services/ServiceCollection.js +43 -0
  132. package/mobile/out/src/services/ServiceCollection.js.map +1 -0
  133. package/mobile/out/src/services/Services.d.ts +67 -0
  134. package/mobile/out/src/services/Services.d.ts.map +1 -0
  135. package/mobile/out/src/services/Services.js +391 -0
  136. package/mobile/out/src/services/Services.js.map +1 -0
  137. package/mobile/out/src/services/chaintracker/ChaintracksChainTracker.d.ts +15 -0
  138. package/mobile/out/src/services/chaintracker/ChaintracksChainTracker.d.ts.map +1 -0
  139. package/mobile/out/src/services/chaintracker/ChaintracksChainTracker.js +51 -0
  140. package/mobile/out/src/services/chaintracker/ChaintracksChainTracker.js.map +1 -0
  141. package/mobile/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts +98 -0
  142. package/mobile/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts.map +1 -0
  143. package/mobile/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js +38 -0
  144. package/mobile/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js.map +1 -0
  145. package/mobile/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts +36 -0
  146. package/mobile/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts.map +1 -0
  147. package/mobile/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js +128 -0
  148. package/mobile/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js.map +1 -0
  149. package/mobile/out/src/services/chaintracker/chaintracks/index.d.ts +3 -0
  150. package/mobile/out/src/services/chaintracker/chaintracks/index.d.ts.map +1 -0
  151. package/mobile/out/src/services/chaintracker/chaintracks/index.js +19 -0
  152. package/mobile/out/src/services/chaintracker/chaintracks/index.js.map +1 -0
  153. package/mobile/out/src/services/chaintracker/index.d.ts +3 -0
  154. package/mobile/out/src/services/chaintracker/index.d.ts.map +1 -0
  155. package/mobile/out/src/services/chaintracker/index.js +19 -0
  156. package/mobile/out/src/services/chaintracker/index.js.map +1 -0
  157. package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts +4 -0
  158. package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -0
  159. package/mobile/out/src/services/createDefaultWalletServicesOptions.js +46 -0
  160. package/mobile/out/src/services/createDefaultWalletServicesOptions.js.map +1 -0
  161. package/mobile/out/src/services/index.d.ts +2 -0
  162. package/mobile/out/src/services/index.d.ts.map +1 -0
  163. package/mobile/out/src/services/index.js +18 -0
  164. package/mobile/out/src/services/index.js.map +1 -0
  165. package/mobile/out/src/services/providers/ARC.d.ts +91 -0
  166. package/mobile/out/src/services/providers/ARC.d.ts.map +1 -0
  167. package/mobile/out/src/services/providers/ARC.js +267 -0
  168. package/mobile/out/src/services/providers/ARC.js.map +1 -0
  169. package/mobile/out/src/services/providers/Bitails.d.ts +49 -0
  170. package/mobile/out/src/services/providers/Bitails.d.ts.map +1 -0
  171. package/mobile/out/src/services/providers/Bitails.js +222 -0
  172. package/mobile/out/src/services/providers/Bitails.js.map +1 -0
  173. package/mobile/out/src/services/providers/SdkWhatsOnChain.d.ts +21 -0
  174. package/mobile/out/src/services/providers/SdkWhatsOnChain.d.ts.map +1 -0
  175. package/mobile/out/src/services/providers/SdkWhatsOnChain.js +67 -0
  176. package/mobile/out/src/services/providers/SdkWhatsOnChain.js.map +1 -0
  177. package/mobile/out/src/services/providers/WhatsOnChain.d.ts +71 -0
  178. package/mobile/out/src/services/providers/WhatsOnChain.d.ts.map +1 -0
  179. package/mobile/out/src/services/providers/WhatsOnChain.js +582 -0
  180. package/mobile/out/src/services/providers/WhatsOnChain.js.map +1 -0
  181. package/mobile/out/src/services/providers/echangeRates.d.ts +12 -0
  182. package/mobile/out/src/services/providers/echangeRates.d.ts.map +1 -0
  183. package/mobile/out/src/services/providers/echangeRates.js +237 -0
  184. package/mobile/out/src/services/providers/echangeRates.js.map +1 -0
  185. package/mobile/out/src/services/providers/getBeefForTxid.d.ts +4 -0
  186. package/mobile/out/src/services/providers/getBeefForTxid.d.ts.map +1 -0
  187. package/mobile/out/src/services/providers/getBeefForTxid.js +286 -0
  188. package/mobile/out/src/services/providers/getBeefForTxid.js.map +1 -0
  189. package/mobile/out/src/signer/WalletSigner.d.ts +11 -0
  190. package/mobile/out/src/signer/WalletSigner.d.ts.map +1 -0
  191. package/mobile/out/src/signer/WalletSigner.js +13 -0
  192. package/mobile/out/src/signer/WalletSigner.js.map +1 -0
  193. package/mobile/out/src/signer/methods/acquireDirectCertificate.d.ts +4 -0
  194. package/mobile/out/src/signer/methods/acquireDirectCertificate.d.ts.map +1 -0
  195. package/mobile/out/src/signer/methods/acquireDirectCertificate.js +45 -0
  196. package/mobile/out/src/signer/methods/acquireDirectCertificate.js.map +1 -0
  197. package/mobile/out/src/signer/methods/buildSignableTransaction.d.ts +10 -0
  198. package/mobile/out/src/signer/methods/buildSignableTransaction.d.ts.map +1 -0
  199. package/mobile/out/src/signer/methods/buildSignableTransaction.js +126 -0
  200. package/mobile/out/src/signer/methods/buildSignableTransaction.js.map +1 -0
  201. package/mobile/out/src/signer/methods/createAction.d.ts +20 -0
  202. package/mobile/out/src/signer/methods/createAction.d.ts.map +1 -0
  203. package/mobile/out/src/signer/methods/createAction.js +160 -0
  204. package/mobile/out/src/signer/methods/createAction.js.map +1 -0
  205. package/mobile/out/src/signer/methods/internalizeAction.d.ts +31 -0
  206. package/mobile/out/src/signer/methods/internalizeAction.d.ts.map +1 -0
  207. package/mobile/out/src/signer/methods/internalizeAction.js +95 -0
  208. package/mobile/out/src/signer/methods/internalizeAction.js.map +1 -0
  209. package/mobile/out/src/signer/methods/proveCertificate.d.ts +4 -0
  210. package/mobile/out/src/signer/methods/proveCertificate.d.ts.map +1 -0
  211. package/mobile/out/src/signer/methods/proveCertificate.js +29 -0
  212. package/mobile/out/src/signer/methods/proveCertificate.js.map +1 -0
  213. package/mobile/out/src/signer/methods/signAction.d.ts +13 -0
  214. package/mobile/out/src/signer/methods/signAction.d.ts.map +1 -0
  215. package/mobile/out/src/signer/methods/signAction.js +89 -0
  216. package/mobile/out/src/signer/methods/signAction.js.map +1 -0
  217. package/mobile/out/src/storage/StorageIdb.d.ts +208 -0
  218. package/mobile/out/src/storage/StorageIdb.d.ts.map +1 -0
  219. package/mobile/out/src/storage/StorageIdb.js +2296 -0
  220. package/mobile/out/src/storage/StorageIdb.js.map +1 -0
  221. package/mobile/out/src/storage/StorageProvider.d.ts +209 -0
  222. package/mobile/out/src/storage/StorageProvider.d.ts.map +1 -0
  223. package/mobile/out/src/storage/StorageProvider.js +550 -0
  224. package/mobile/out/src/storage/StorageProvider.js.map +1 -0
  225. package/mobile/out/src/storage/StorageReader.d.ts +76 -0
  226. package/mobile/out/src/storage/StorageReader.d.ts.map +1 -0
  227. package/mobile/out/src/storage/StorageReader.js +129 -0
  228. package/mobile/out/src/storage/StorageReader.js.map +1 -0
  229. package/mobile/out/src/storage/StorageReaderWriter.d.ts +87 -0
  230. package/mobile/out/src/storage/StorageReaderWriter.d.ts.map +1 -0
  231. package/mobile/out/src/storage/StorageReaderWriter.js +338 -0
  232. package/mobile/out/src/storage/StorageReaderWriter.js.map +1 -0
  233. package/mobile/out/src/storage/StorageSyncReader.d.ts +17 -0
  234. package/mobile/out/src/storage/StorageSyncReader.d.ts.map +1 -0
  235. package/mobile/out/src/storage/StorageSyncReader.js +38 -0
  236. package/mobile/out/src/storage/StorageSyncReader.js.map +1 -0
  237. package/mobile/out/src/storage/WalletStorageManager.d.ts +184 -0
  238. package/mobile/out/src/storage/WalletStorageManager.d.ts.map +1 -0
  239. package/mobile/out/src/storage/WalletStorageManager.js +665 -0
  240. package/mobile/out/src/storage/WalletStorageManager.js.map +1 -0
  241. package/mobile/out/src/storage/index.client.d.ts +8 -0
  242. package/mobile/out/src/storage/index.client.d.ts.map +1 -0
  243. package/mobile/out/src/storage/index.client.js +24 -0
  244. package/mobile/out/src/storage/index.client.js.map +1 -0
  245. package/mobile/out/src/storage/index.mobile.d.ts +7 -0
  246. package/mobile/out/src/storage/index.mobile.d.ts.map +1 -0
  247. package/mobile/out/src/storage/index.mobile.js +23 -0
  248. package/mobile/out/src/storage/index.mobile.js.map +1 -0
  249. package/mobile/out/src/storage/methods/ListActionsSpecOp.d.ts +16 -0
  250. package/mobile/out/src/storage/methods/ListActionsSpecOp.d.ts.map +1 -0
  251. package/mobile/out/src/storage/methods/ListActionsSpecOp.js +40 -0
  252. package/mobile/out/src/storage/methods/ListActionsSpecOp.js.map +1 -0
  253. package/mobile/out/src/storage/methods/ListOutputsSpecOp.d.ts +26 -0
  254. package/mobile/out/src/storage/methods/ListOutputsSpecOp.d.ts.map +1 -0
  255. package/mobile/out/src/storage/methods/ListOutputsSpecOp.js +71 -0
  256. package/mobile/out/src/storage/methods/ListOutputsSpecOp.js.map +1 -0
  257. package/mobile/out/src/storage/methods/attemptToPostReqsToNetwork.d.ts +41 -0
  258. package/mobile/out/src/storage/methods/attemptToPostReqsToNetwork.d.ts.map +1 -0
  259. package/mobile/out/src/storage/methods/attemptToPostReqsToNetwork.js +320 -0
  260. package/mobile/out/src/storage/methods/attemptToPostReqsToNetwork.js.map +1 -0
  261. package/mobile/out/src/storage/methods/createAction.d.ts +24 -0
  262. package/mobile/out/src/storage/methods/createAction.d.ts.map +1 -0
  263. package/mobile/out/src/storage/methods/createAction.js +705 -0
  264. package/mobile/out/src/storage/methods/createAction.js.map +1 -0
  265. package/mobile/out/src/storage/methods/generateChange.d.ts +119 -0
  266. package/mobile/out/src/storage/methods/generateChange.d.ts.map +1 -0
  267. package/mobile/out/src/storage/methods/generateChange.js +448 -0
  268. package/mobile/out/src/storage/methods/generateChange.js.map +1 -0
  269. package/mobile/out/src/storage/methods/getBeefForTransaction.d.ts +22 -0
  270. package/mobile/out/src/storage/methods/getBeefForTransaction.d.ts.map +1 -0
  271. package/mobile/out/src/storage/methods/getBeefForTransaction.js +92 -0
  272. package/mobile/out/src/storage/methods/getBeefForTransaction.js.map +1 -0
  273. package/mobile/out/src/storage/methods/getSyncChunk.d.ts +10 -0
  274. package/mobile/out/src/storage/methods/getSyncChunk.d.ts.map +1 -0
  275. package/mobile/out/src/storage/methods/getSyncChunk.js +271 -0
  276. package/mobile/out/src/storage/methods/getSyncChunk.js.map +1 -0
  277. package/mobile/out/src/storage/methods/internalizeAction.d.ts +38 -0
  278. package/mobile/out/src/storage/methods/internalizeAction.d.ts.map +1 -0
  279. package/mobile/out/src/storage/methods/internalizeAction.js +371 -0
  280. package/mobile/out/src/storage/methods/internalizeAction.js.map +1 -0
  281. package/mobile/out/src/storage/methods/listActionsIdb.d.ts +5 -0
  282. package/mobile/out/src/storage/methods/listActionsIdb.d.ts.map +1 -0
  283. package/mobile/out/src/storage/methods/listActionsIdb.js +155 -0
  284. package/mobile/out/src/storage/methods/listActionsIdb.js.map +1 -0
  285. package/mobile/out/src/storage/methods/listCertificates.d.ts +5 -0
  286. package/mobile/out/src/storage/methods/listCertificates.d.ts.map +1 -0
  287. package/mobile/out/src/storage/methods/listCertificates.js +68 -0
  288. package/mobile/out/src/storage/methods/listCertificates.js.map +1 -0
  289. package/mobile/out/src/storage/methods/listOutputsIdb.d.ts +5 -0
  290. package/mobile/out/src/storage/methods/listOutputsIdb.d.ts.map +1 -0
  291. package/mobile/out/src/storage/methods/listOutputsIdb.js +181 -0
  292. package/mobile/out/src/storage/methods/listOutputsIdb.js.map +1 -0
  293. package/mobile/out/src/storage/methods/processAction.d.ts +35 -0
  294. package/mobile/out/src/storage/methods/processAction.d.ts.map +1 -0
  295. package/mobile/out/src/storage/methods/processAction.js +311 -0
  296. package/mobile/out/src/storage/methods/processAction.js.map +1 -0
  297. package/mobile/out/src/storage/methods/purgeDataIdb.d.ts +4 -0
  298. package/mobile/out/src/storage/methods/purgeDataIdb.d.ts.map +1 -0
  299. package/mobile/out/src/storage/methods/purgeDataIdb.js +9 -0
  300. package/mobile/out/src/storage/methods/purgeDataIdb.js.map +1 -0
  301. package/mobile/out/src/storage/methods/reviewStatusIdb.d.ts +20 -0
  302. package/mobile/out/src/storage/methods/reviewStatusIdb.d.ts.map +1 -0
  303. package/mobile/out/src/storage/methods/reviewStatusIdb.js +35 -0
  304. package/mobile/out/src/storage/methods/reviewStatusIdb.js.map +1 -0
  305. package/mobile/out/src/storage/remoting/StorageClient.d.ts +283 -0
  306. package/mobile/out/src/storage/remoting/StorageClient.d.ts.map +1 -0
  307. package/mobile/out/src/storage/remoting/StorageClient.js +477 -0
  308. package/mobile/out/src/storage/remoting/StorageClient.js.map +1 -0
  309. package/mobile/out/src/storage/schema/StorageIdbSchema.d.ts +133 -0
  310. package/mobile/out/src/storage/schema/StorageIdbSchema.d.ts.map +1 -0
  311. package/mobile/out/src/storage/schema/StorageIdbSchema.js +3 -0
  312. package/mobile/out/src/storage/schema/StorageIdbSchema.js.map +1 -0
  313. package/mobile/out/src/storage/schema/entities/EntityBase.d.ts +105 -0
  314. package/mobile/out/src/storage/schema/entities/EntityBase.d.ts.map +1 -0
  315. package/mobile/out/src/storage/schema/entities/EntityBase.js +100 -0
  316. package/mobile/out/src/storage/schema/entities/EntityBase.js.map +1 -0
  317. package/mobile/out/src/storage/schema/entities/EntityCertificate.d.ts +43 -0
  318. package/mobile/out/src/storage/schema/entities/EntityCertificate.d.ts.map +1 -0
  319. package/mobile/out/src/storage/schema/entities/EntityCertificate.js +162 -0
  320. package/mobile/out/src/storage/schema/entities/EntityCertificate.js.map +1 -0
  321. package/mobile/out/src/storage/schema/entities/EntityCertificateField.d.ts +32 -0
  322. package/mobile/out/src/storage/schema/entities/EntityCertificateField.d.ts.map +1 -0
  323. package/mobile/out/src/storage/schema/entities/EntityCertificateField.js +111 -0
  324. package/mobile/out/src/storage/schema/entities/EntityCertificateField.js.map +1 -0
  325. package/mobile/out/src/storage/schema/entities/EntityCommission.d.ts +37 -0
  326. package/mobile/out/src/storage/schema/entities/EntityCommission.d.ts.map +1 -0
  327. package/mobile/out/src/storage/schema/entities/EntityCommission.js +127 -0
  328. package/mobile/out/src/storage/schema/entities/EntityCommission.js.map +1 -0
  329. package/mobile/out/src/storage/schema/entities/EntityOutput.d.ts +67 -0
  330. package/mobile/out/src/storage/schema/entities/EntityOutput.d.ts.map +1 -0
  331. package/mobile/out/src/storage/schema/entities/EntityOutput.js +264 -0
  332. package/mobile/out/src/storage/schema/entities/EntityOutput.js.map +1 -0
  333. package/mobile/out/src/storage/schema/entities/EntityOutputBasket.d.ts +35 -0
  334. package/mobile/out/src/storage/schema/entities/EntityOutputBasket.d.ts.map +1 -0
  335. package/mobile/out/src/storage/schema/entities/EntityOutputBasket.js +133 -0
  336. package/mobile/out/src/storage/schema/entities/EntityOutputBasket.js.map +1 -0
  337. package/mobile/out/src/storage/schema/entities/EntityOutputTag.d.ts +31 -0
  338. package/mobile/out/src/storage/schema/entities/EntityOutputTag.d.ts.map +1 -0
  339. package/mobile/out/src/storage/schema/entities/EntityOutputTag.js +104 -0
  340. package/mobile/out/src/storage/schema/entities/EntityOutputTag.js.map +1 -0
  341. package/mobile/out/src/storage/schema/entities/EntityOutputTagMap.d.ts +28 -0
  342. package/mobile/out/src/storage/schema/entities/EntityOutputTagMap.d.ts.map +1 -0
  343. package/mobile/out/src/storage/schema/entities/EntityOutputTagMap.js +97 -0
  344. package/mobile/out/src/storage/schema/entities/EntityOutputTagMap.js.map +1 -0
  345. package/mobile/out/src/storage/schema/entities/EntityProvenTx.d.ts +84 -0
  346. package/mobile/out/src/storage/schema/entities/EntityProvenTx.d.ts.map +1 -0
  347. package/mobile/out/src/storage/schema/entities/EntityProvenTx.js +276 -0
  348. package/mobile/out/src/storage/schema/entities/EntityProvenTx.js.map +1 -0
  349. package/mobile/out/src/storage/schema/entities/EntityProvenTxReq.d.ts +135 -0
  350. package/mobile/out/src/storage/schema/entities/EntityProvenTxReq.d.ts.map +1 -0
  351. package/mobile/out/src/storage/schema/entities/EntityProvenTxReq.js +522 -0
  352. package/mobile/out/src/storage/schema/entities/EntityProvenTxReq.js.map +1 -0
  353. package/mobile/out/src/storage/schema/entities/EntitySyncState.d.ts +67 -0
  354. package/mobile/out/src/storage/schema/entities/EntitySyncState.d.ts.map +1 -0
  355. package/mobile/out/src/storage/schema/entities/EntitySyncState.js +319 -0
  356. package/mobile/out/src/storage/schema/entities/EntitySyncState.js.map +1 -0
  357. package/mobile/out/src/storage/schema/entities/EntityTransaction.d.ts +67 -0
  358. package/mobile/out/src/storage/schema/entities/EntityTransaction.d.ts.map +1 -0
  359. package/mobile/out/src/storage/schema/entities/EntityTransaction.js +255 -0
  360. package/mobile/out/src/storage/schema/entities/EntityTransaction.js.map +1 -0
  361. package/mobile/out/src/storage/schema/entities/EntityTxLabel.d.ts +31 -0
  362. package/mobile/out/src/storage/schema/entities/EntityTxLabel.d.ts.map +1 -0
  363. package/mobile/out/src/storage/schema/entities/EntityTxLabel.js +104 -0
  364. package/mobile/out/src/storage/schema/entities/EntityTxLabel.js.map +1 -0
  365. package/mobile/out/src/storage/schema/entities/EntityTxLabelMap.d.ts +28 -0
  366. package/mobile/out/src/storage/schema/entities/EntityTxLabelMap.d.ts.map +1 -0
  367. package/mobile/out/src/storage/schema/entities/EntityTxLabelMap.js +97 -0
  368. package/mobile/out/src/storage/schema/entities/EntityTxLabelMap.js.map +1 -0
  369. package/mobile/out/src/storage/schema/entities/EntityUser.d.ts +29 -0
  370. package/mobile/out/src/storage/schema/entities/EntityUser.d.ts.map +1 -0
  371. package/mobile/out/src/storage/schema/entities/EntityUser.js +98 -0
  372. package/mobile/out/src/storage/schema/entities/EntityUser.js.map +1 -0
  373. package/mobile/out/src/storage/schema/entities/MergeEntity.d.ts +33 -0
  374. package/mobile/out/src/storage/schema/entities/MergeEntity.d.ts.map +1 -0
  375. package/mobile/out/src/storage/schema/entities/MergeEntity.js +62 -0
  376. package/mobile/out/src/storage/schema/entities/MergeEntity.js.map +1 -0
  377. package/mobile/out/src/storage/schema/entities/index.d.ts +17 -0
  378. package/mobile/out/src/storage/schema/entities/index.d.ts.map +1 -0
  379. package/mobile/out/src/storage/schema/entities/index.js +33 -0
  380. package/mobile/out/src/storage/schema/entities/index.js.map +1 -0
  381. package/mobile/out/src/storage/schema/tables/TableCertificate.d.ts +20 -0
  382. package/mobile/out/src/storage/schema/tables/TableCertificate.d.ts.map +1 -0
  383. package/mobile/out/src/storage/schema/tables/TableCertificate.js +3 -0
  384. package/mobile/out/src/storage/schema/tables/TableCertificate.js.map +1 -0
  385. package/mobile/out/src/storage/schema/tables/TableCertificateField.d.ts +12 -0
  386. package/mobile/out/src/storage/schema/tables/TableCertificateField.d.ts.map +1 -0
  387. package/mobile/out/src/storage/schema/tables/TableCertificateField.js +3 -0
  388. package/mobile/out/src/storage/schema/tables/TableCertificateField.js.map +1 -0
  389. package/mobile/out/src/storage/schema/tables/TableCommission.d.ts +13 -0
  390. package/mobile/out/src/storage/schema/tables/TableCommission.d.ts.map +1 -0
  391. package/mobile/out/src/storage/schema/tables/TableCommission.js +3 -0
  392. package/mobile/out/src/storage/schema/tables/TableCommission.js.map +1 -0
  393. package/mobile/out/src/storage/schema/tables/TableMonitorEvent.d.ts +9 -0
  394. package/mobile/out/src/storage/schema/tables/TableMonitorEvent.d.ts.map +1 -0
  395. package/mobile/out/src/storage/schema/tables/TableMonitorEvent.js +3 -0
  396. package/mobile/out/src/storage/schema/tables/TableMonitorEvent.js.map +1 -0
  397. package/mobile/out/src/storage/schema/tables/TableOutput.d.ts +36 -0
  398. package/mobile/out/src/storage/schema/tables/TableOutput.d.ts.map +1 -0
  399. package/mobile/out/src/storage/schema/tables/TableOutput.js +31 -0
  400. package/mobile/out/src/storage/schema/tables/TableOutput.js.map +1 -0
  401. package/mobile/out/src/storage/schema/tables/TableOutputBasket.d.ts +12 -0
  402. package/mobile/out/src/storage/schema/tables/TableOutputBasket.d.ts.map +1 -0
  403. package/mobile/out/src/storage/schema/tables/TableOutputBasket.js +3 -0
  404. package/mobile/out/src/storage/schema/tables/TableOutputBasket.js.map +1 -0
  405. package/mobile/out/src/storage/schema/tables/TableOutputTag.d.ts +10 -0
  406. package/mobile/out/src/storage/schema/tables/TableOutputTag.d.ts.map +1 -0
  407. package/mobile/out/src/storage/schema/tables/TableOutputTag.js +3 -0
  408. package/mobile/out/src/storage/schema/tables/TableOutputTag.js.map +1 -0
  409. package/mobile/out/src/storage/schema/tables/TableOutputTagMap.d.ts +9 -0
  410. package/mobile/out/src/storage/schema/tables/TableOutputTagMap.d.ts.map +1 -0
  411. package/mobile/out/src/storage/schema/tables/TableOutputTagMap.js +3 -0
  412. package/mobile/out/src/storage/schema/tables/TableOutputTagMap.js.map +1 -0
  413. package/mobile/out/src/storage/schema/tables/TableProvenTx.d.ts +14 -0
  414. package/mobile/out/src/storage/schema/tables/TableProvenTx.d.ts.map +1 -0
  415. package/mobile/out/src/storage/schema/tables/TableProvenTx.js +3 -0
  416. package/mobile/out/src/storage/schema/tables/TableProvenTx.js.map +1 -0
  417. package/mobile/out/src/storage/schema/tables/TableProvenTxReq.d.ts +64 -0
  418. package/mobile/out/src/storage/schema/tables/TableProvenTxReq.d.ts.map +1 -0
  419. package/mobile/out/src/storage/schema/tables/TableProvenTxReq.js +3 -0
  420. package/mobile/out/src/storage/schema/tables/TableProvenTxReq.js.map +1 -0
  421. package/mobile/out/src/storage/schema/tables/TableSettings.d.ts +17 -0
  422. package/mobile/out/src/storage/schema/tables/TableSettings.d.ts.map +1 -0
  423. package/mobile/out/src/storage/schema/tables/TableSettings.js +3 -0
  424. package/mobile/out/src/storage/schema/tables/TableSettings.js.map +1 -0
  425. package/mobile/out/src/storage/schema/tables/TableSyncState.d.ts +18 -0
  426. package/mobile/out/src/storage/schema/tables/TableSyncState.d.ts.map +1 -0
  427. package/mobile/out/src/storage/schema/tables/TableSyncState.js +3 -0
  428. package/mobile/out/src/storage/schema/tables/TableSyncState.js.map +1 -0
  429. package/mobile/out/src/storage/schema/tables/TableTransaction.d.ts +37 -0
  430. package/mobile/out/src/storage/schema/tables/TableTransaction.d.ts.map +1 -0
  431. package/mobile/out/src/storage/schema/tables/TableTransaction.js +21 -0
  432. package/mobile/out/src/storage/schema/tables/TableTransaction.js.map +1 -0
  433. package/mobile/out/src/storage/schema/tables/TableTxLabel.d.ts +10 -0
  434. package/mobile/out/src/storage/schema/tables/TableTxLabel.d.ts.map +1 -0
  435. package/mobile/out/src/storage/schema/tables/TableTxLabel.js +3 -0
  436. package/mobile/out/src/storage/schema/tables/TableTxLabel.js.map +1 -0
  437. package/mobile/out/src/storage/schema/tables/TableTxLabelMap.d.ts +9 -0
  438. package/mobile/out/src/storage/schema/tables/TableTxLabelMap.d.ts.map +1 -0
  439. package/mobile/out/src/storage/schema/tables/TableTxLabelMap.js +3 -0
  440. package/mobile/out/src/storage/schema/tables/TableTxLabelMap.js.map +1 -0
  441. package/mobile/out/src/storage/schema/tables/TableUser.d.ts +16 -0
  442. package/mobile/out/src/storage/schema/tables/TableUser.d.ts.map +1 -0
  443. package/mobile/out/src/storage/schema/tables/TableUser.js +3 -0
  444. package/mobile/out/src/storage/schema/tables/TableUser.js.map +1 -0
  445. package/mobile/out/src/storage/schema/tables/index.d.ts +17 -0
  446. package/mobile/out/src/storage/schema/tables/index.d.ts.map +1 -0
  447. package/mobile/out/src/storage/schema/tables/index.js +33 -0
  448. package/mobile/out/src/storage/schema/tables/index.js.map +1 -0
  449. package/mobile/out/src/utility/ScriptTemplateBRC29.d.ts +25 -0
  450. package/mobile/out/src/utility/ScriptTemplateBRC29.d.ts.map +1 -0
  451. package/mobile/out/src/utility/ScriptTemplateBRC29.js +48 -0
  452. package/mobile/out/src/utility/ScriptTemplateBRC29.js.map +1 -0
  453. package/mobile/out/src/utility/identityUtils.d.ts +31 -0
  454. package/mobile/out/src/utility/identityUtils.d.ts.map +1 -0
  455. package/mobile/out/src/utility/identityUtils.js +116 -0
  456. package/mobile/out/src/utility/identityUtils.js.map +1 -0
  457. package/mobile/out/src/utility/index.client.d.ts +7 -0
  458. package/mobile/out/src/utility/index.client.d.ts.map +1 -0
  459. package/mobile/out/src/utility/index.client.js +23 -0
  460. package/mobile/out/src/utility/index.client.js.map +1 -0
  461. package/mobile/out/src/utility/parseTxScriptOffsets.d.ts +14 -0
  462. package/mobile/out/src/utility/parseTxScriptOffsets.d.ts.map +1 -0
  463. package/mobile/out/src/utility/parseTxScriptOffsets.js +26 -0
  464. package/mobile/out/src/utility/parseTxScriptOffsets.js.map +1 -0
  465. package/mobile/out/src/utility/stampLog.d.ts +18 -0
  466. package/mobile/out/src/utility/stampLog.d.ts.map +1 -0
  467. package/mobile/out/src/utility/stampLog.js +72 -0
  468. package/mobile/out/src/utility/stampLog.js.map +1 -0
  469. package/mobile/out/src/utility/tscProofToMerklePath.d.ts +8 -0
  470. package/mobile/out/src/utility/tscProofToMerklePath.d.ts.map +1 -0
  471. package/mobile/out/src/utility/tscProofToMerklePath.js +41 -0
  472. package/mobile/out/src/utility/tscProofToMerklePath.js.map +1 -0
  473. package/mobile/out/src/utility/utilityHelpers.d.ts +129 -0
  474. package/mobile/out/src/utility/utilityHelpers.d.ts.map +1 -0
  475. package/mobile/out/src/utility/utilityHelpers.js +266 -0
  476. package/mobile/out/src/utility/utilityHelpers.js.map +1 -0
  477. package/mobile/out/src/utility/utilityHelpers.noBuffer.d.ts +9 -0
  478. package/mobile/out/src/utility/utilityHelpers.noBuffer.d.ts.map +1 -0
  479. package/mobile/out/src/utility/utilityHelpers.noBuffer.js +23 -0
  480. package/mobile/out/src/utility/utilityHelpers.noBuffer.js.map +1 -0
  481. package/mobile/out/src/wab-client/WABClient.d.ts +49 -0
  482. package/mobile/out/src/wab-client/WABClient.d.ts.map +1 -0
  483. package/mobile/out/src/wab-client/WABClient.js +80 -0
  484. package/mobile/out/src/wab-client/WABClient.js.map +1 -0
  485. package/mobile/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts +34 -0
  486. package/mobile/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts.map +1 -0
  487. package/mobile/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js +16 -0
  488. package/mobile/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js.map +1 -0
  489. package/mobile/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.d.ts +7 -0
  490. package/mobile/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.d.ts.map +1 -0
  491. package/mobile/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.js +36 -0
  492. package/mobile/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.js.map +1 -0
  493. package/mobile/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts +28 -0
  494. package/mobile/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts.map +1 -0
  495. package/mobile/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js +69 -0
  496. package/mobile/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js.map +1 -0
  497. package/mobile/out/tsconfig.mobile.tsbuildinfo +1 -0
  498. package/mobile/package-lock.json +5 -12
  499. package/mobile/package.json +1 -1
  500. package/package.json +1 -1
  501. package/tsconfig.json +3 -0
  502. package/tsconfig.mobile.json +22 -0
@@ -0,0 +1,1868 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WalletPermissionsManager = void 0;
4
+ const sdk_1 = require("@bsv/sdk");
5
+ const sdk_2 = require("./sdk");
6
+ /**
7
+ * A map from each permission type to a special "admin basket" name used for storing
8
+ * the tokens. The tokens themselves are unspent transaction outputs (UTXOs) with a
9
+ * specialized PushDrop script that references the originator, expiry, etc.
10
+ */
11
+ const BASKET_MAP = {
12
+ protocol: 'admin protocol-permission',
13
+ basket: 'admin basket-access',
14
+ certificate: 'admin certificate-access',
15
+ spending: 'admin spending-authorization'
16
+ };
17
+ /**
18
+ * @class WalletPermissionsManager
19
+ *
20
+ * Wraps an underlying BRC-100 `Wallet` implementation with permissions management capabilities.
21
+ * The manager intercepts calls from external applications (identified by originators), checks if the request is allowed,
22
+ * and if not, orchestrates user permission flows. It creates or renews on-chain tokens in special
23
+ * admin baskets to track these authorizations. Finally, it proxies the actual call to the underlying wallet.
24
+ *
25
+ * ### Key Responsibilities:
26
+ * - **Permission Checking**: Before standard wallet operations (e.g. `encrypt`),
27
+ * the manager checks if a valid permission token exists. If not, it attempts to request permission from the user.
28
+ * - **On-Chain Tokens**: When permission is granted, the manager stores it as an unspent "PushDrop" output.
29
+ * This can be spent later to revoke or renew the permission.
30
+ * - **Callbacks**: The manager triggers user-defined callbacks on permission requests (to show a UI prompt),
31
+ * on grants/denials, and on internal processes.
32
+ *
33
+ * ### Implementation Notes:
34
+ * - The manager follows the BRC-100 `createAction` + `signAction` pattern for building or spending these tokens.
35
+ * - Token revocation or renewal uses standard BRC-100 flows: we build a transaction that consumes
36
+ * the old token UTXO and outputs a new one (or none, if fully revoked).
37
+ */
38
+ class WalletPermissionsManager {
39
+ /**
40
+ * Constructs a new Permissions Manager instance.
41
+ *
42
+ * @param underlyingWallet The underlying BRC-100 wallet, where requests are forwarded after permission is granted
43
+ * @param adminOriginator The domain or FQDN that is automatically allowed everything
44
+ * @param config A set of boolean flags controlling how strictly permissions are enforced
45
+ */
46
+ constructor(underlyingWallet, adminOriginator, config = {}) {
47
+ /**
48
+ * Event callbacks that external code can subscribe to, e.g. to show a UI prompt
49
+ * or log events. Each event can have multiple handlers.
50
+ */
51
+ this.callbacks = {
52
+ onProtocolPermissionRequested: [],
53
+ onBasketAccessRequested: [],
54
+ onCertificateAccessRequested: [],
55
+ onSpendingAuthorizationRequested: []
56
+ };
57
+ /**
58
+ * We queue parallel requests for the same resource so that only one
59
+ * user prompt is created for a single resource. If multiple calls come
60
+ * in at once for the same "protocol:domain:privileged:counterparty" etc.,
61
+ * they get merged.
62
+ *
63
+ * The key is a string derived from the operation; the value is an object with a reference to the
64
+ * associated request and an array of pending promise resolve/reject pairs, one for each active
65
+ * operation that's waiting on the particular resource described by the key.
66
+ */
67
+ this.activeRequests = new Map();
68
+ this.underlying = underlyingWallet;
69
+ this.adminOriginator = adminOriginator;
70
+ // Default all config options to true unless specified
71
+ this.config = {
72
+ seekProtocolPermissionsForSigning: true,
73
+ seekProtocolPermissionsForEncrypting: true,
74
+ seekProtocolPermissionsForHMAC: true,
75
+ seekPermissionsForKeyLinkageRevelation: true,
76
+ seekPermissionsForPublicKeyRevelation: true,
77
+ seekPermissionsForIdentityKeyRevelation: true,
78
+ seekPermissionsForIdentityResolution: true,
79
+ seekBasketInsertionPermissions: true,
80
+ seekBasketRemovalPermissions: true,
81
+ seekBasketListingPermissions: true,
82
+ seekPermissionWhenApplyingActionLabels: true,
83
+ seekPermissionWhenListingActionsByLabel: true,
84
+ seekCertificateDisclosurePermissions: true,
85
+ seekCertificateAcquisitionPermissions: true,
86
+ seekCertificateRelinquishmentPermissions: true,
87
+ seekCertificateListingPermissions: true,
88
+ encryptWalletMetadata: true,
89
+ seekSpendingPermissions: true,
90
+ differentiatePrivilegedOperations: true,
91
+ ...config // override with user-specified config
92
+ };
93
+ }
94
+ /* ---------------------------------------------------------------------
95
+ * 1) PUBLIC API FOR REGISTERING CALLBACKS (UI PROMPTS, LOGGING, ETC.)
96
+ * --------------------------------------------------------------------- */
97
+ /**
98
+ * Binds a callback function to a named event, such as `onProtocolPermissionRequested`.
99
+ *
100
+ * @param eventName The name of the event to listen to
101
+ * @param handler A function that handles the event
102
+ * @returns A numeric ID you can use to unbind later
103
+ */
104
+ bindCallback(eventName, handler) {
105
+ const arr = this.callbacks[eventName];
106
+ arr.push(handler);
107
+ return arr.length - 1;
108
+ }
109
+ /**
110
+ * Unbinds a previously registered callback by either its numeric ID (returned by `bindCallback`)
111
+ * or by exact function reference.
112
+ *
113
+ * @param eventName The event name, e.g. "onProtocolPermissionRequested"
114
+ * @param reference Either the numeric ID or the function reference
115
+ * @returns True if successfully unbound, false otherwise
116
+ */
117
+ unbindCallback(eventName, reference) {
118
+ if (!this.callbacks[eventName])
119
+ return false;
120
+ const arr = this.callbacks[eventName];
121
+ if (typeof reference === 'number') {
122
+ if (arr[reference]) {
123
+ arr[reference] = null;
124
+ return true;
125
+ }
126
+ return false;
127
+ }
128
+ else {
129
+ const index = arr.indexOf(reference);
130
+ if (index !== -1) {
131
+ arr[index] = null;
132
+ return true;
133
+ }
134
+ return false;
135
+ }
136
+ }
137
+ /**
138
+ * Internally triggers a named event, calling all subscribed listeners.
139
+ * Each callback is awaited in turn (though errors are swallowed so that
140
+ * one failing callback doesn't prevent the others).
141
+ *
142
+ * @param eventName The event name
143
+ * @param param The parameter object passed to all listeners
144
+ */
145
+ async callEvent(eventName, param) {
146
+ const arr = this.callbacks[eventName] || [];
147
+ for (const cb of arr) {
148
+ if (typeof cb === 'function') {
149
+ try {
150
+ await cb(param);
151
+ }
152
+ catch (e) {
153
+ // Intentionally swallow errors from user-provided callbacks
154
+ }
155
+ }
156
+ }
157
+ }
158
+ /* ---------------------------------------------------------------------
159
+ * 2) PERMISSION (GRANT / DENY) METHODS
160
+ * --------------------------------------------------------------------- */
161
+ /**
162
+ * Grants a previously requested permission.
163
+ * This method:
164
+ * 1) Resolves all pending promise calls waiting on this request
165
+ * 2) Optionally creates or renews an on-chain PushDrop token (unless `ephemeral===true`)
166
+ *
167
+ * @param params requestID to identify which request is granted, plus optional expiry
168
+ * or `ephemeral` usage, etc.
169
+ */
170
+ async grantPermission(params) {
171
+ // 1) Identify the matching queued requests in `activeRequests`
172
+ const matching = this.activeRequests.get(params.requestID);
173
+ if (!matching) {
174
+ throw new Error('Request ID not found.');
175
+ }
176
+ // 2) Mark all matching requests as resolved, deleting the entry
177
+ for (const x of matching.pending) {
178
+ x.resolve(true);
179
+ }
180
+ this.activeRequests.delete(params.requestID);
181
+ // 3) If `ephemeral !== true`, we create or renew an on-chain token
182
+ if (!params.ephemeral) {
183
+ if (!matching.request.renewal) {
184
+ // brand-new permission token
185
+ await this.createPermissionOnChain(matching.request, params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30, // default 30-day expiry
186
+ params.amount);
187
+ }
188
+ else {
189
+ // renewal => spend the old token, produce a new one
190
+ await this.renewPermissionOnChain(matching.request.previousToken, matching.request, params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30, params.amount);
191
+ }
192
+ }
193
+ }
194
+ /**
195
+ * Denies a previously requested permission.
196
+ * This method rejects all pending promise calls waiting on that request
197
+ *
198
+ * @param requestID requestID identifying which request to deny
199
+ */
200
+ async denyPermission(requestID) {
201
+ // 1) Identify the matching requests
202
+ const matching = this.activeRequests.get(requestID);
203
+ if (!matching) {
204
+ throw new Error('Request ID not found.');
205
+ }
206
+ // 2) Reject all matching requests, deleting the entry
207
+ for (const x of matching.pending) {
208
+ x.reject(new Error('Permission denied.'));
209
+ }
210
+ this.activeRequests.delete(requestID);
211
+ }
212
+ /* ---------------------------------------------------------------------
213
+ * 3) THE "ENSURE" METHODS: CHECK IF PERMISSION EXISTS, OTHERWISE PROMPT
214
+ * --------------------------------------------------------------------- */
215
+ /**
216
+ * Ensures the originator has protocol usage permission.
217
+ * If no valid (unexpired) permission token is found, triggers a permission request flow.
218
+ */
219
+ async ensureProtocolPermission({ originator, privileged, protocolID, counterparty, reason, seekPermission = true, usageType }) {
220
+ // 1) adminOriginator can do anything
221
+ if (this.isAdminOriginator(originator))
222
+ return true;
223
+ // 2) If security level=0, we consider it "open" usage
224
+ const [level, protoName] = protocolID;
225
+ if (level === 0)
226
+ return true;
227
+ // 3) If protocol is admin-reserved, block
228
+ if (this.isAdminProtocol(protocolID)) {
229
+ throw new Error(`Protocol “${protoName}” is admin-only.`);
230
+ }
231
+ // Allow the configured exceptions.
232
+ if (usageType === 'signing' && !this.config.seekProtocolPermissionsForSigning) {
233
+ return true;
234
+ }
235
+ if (usageType === 'encrypting' && !this.config.seekProtocolPermissionsForEncrypting) {
236
+ return true;
237
+ }
238
+ if (usageType === 'hmac' && !this.config.seekProtocolPermissionsForHMAC) {
239
+ return true;
240
+ }
241
+ if (usageType === 'publicKey' && !this.config.seekPermissionsForPublicKeyRevelation) {
242
+ return true;
243
+ }
244
+ if (usageType === 'identityKey' && !this.config.seekPermissionsForIdentityKeyRevelation) {
245
+ return true;
246
+ }
247
+ if (usageType === 'linkageRevelation' && !this.config.seekPermissionsForKeyLinkageRevelation) {
248
+ return true;
249
+ }
250
+ if (!this.config.differentiatePrivilegedOperations) {
251
+ privileged = false;
252
+ }
253
+ // 4) Attempt to find a valid token in the internal basket
254
+ const token = await this.findProtocolToken(originator, privileged, protocolID, counterparty,
255
+ /*includeExpired=*/ true);
256
+ if (token) {
257
+ if (!this.isTokenExpired(token.expiry)) {
258
+ // valid and unexpired
259
+ return true;
260
+ }
261
+ else {
262
+ // has a token but expired => request renewal if allowed
263
+ if (!seekPermission) {
264
+ throw new Error(`Protocol permission expired and no further user consent allowed (seekPermission=false).`);
265
+ }
266
+ return await this.requestPermissionFlow({
267
+ type: 'protocol',
268
+ originator,
269
+ privileged,
270
+ protocolID,
271
+ counterparty,
272
+ reason,
273
+ renewal: true,
274
+ previousToken: token
275
+ });
276
+ }
277
+ }
278
+ else {
279
+ // No token found => request a new one if allowed
280
+ if (!seekPermission) {
281
+ throw new Error(`No protocol permission token found (seekPermission=false).`);
282
+ }
283
+ return await this.requestPermissionFlow({
284
+ type: 'protocol',
285
+ originator,
286
+ privileged,
287
+ protocolID,
288
+ counterparty,
289
+ reason,
290
+ renewal: false
291
+ });
292
+ }
293
+ }
294
+ /**
295
+ * Ensures the originator has basket usage permission for the specified basket.
296
+ * If not, triggers a permission request flow.
297
+ */
298
+ async ensureBasketAccess({ originator, basket, reason, seekPermission = true, usageType }) {
299
+ if (this.isAdminOriginator(originator))
300
+ return true;
301
+ if (this.isAdminBasket(basket)) {
302
+ throw new Error(`Basket “${basket}” is admin-only.`);
303
+ }
304
+ if (usageType === 'insertion' && !this.config.seekBasketInsertionPermissions)
305
+ return true;
306
+ if (usageType === 'removal' && !this.config.seekBasketRemovalPermissions)
307
+ return true;
308
+ if (usageType === 'listing' && !this.config.seekBasketListingPermissions)
309
+ return true;
310
+ const token = await this.findBasketToken(originator, basket, true);
311
+ if (token) {
312
+ if (!this.isTokenExpired(token.expiry)) {
313
+ return true;
314
+ }
315
+ else {
316
+ if (!seekPermission) {
317
+ throw new Error(`Basket permission expired (seekPermission=false).`);
318
+ }
319
+ return await this.requestPermissionFlow({
320
+ type: 'basket',
321
+ originator,
322
+ basket,
323
+ reason,
324
+ renewal: true,
325
+ previousToken: token
326
+ });
327
+ }
328
+ }
329
+ else {
330
+ // none
331
+ if (!seekPermission) {
332
+ throw new Error(`No basket permission found, and no user consent allowed (seekPermission=false).`);
333
+ }
334
+ return await this.requestPermissionFlow({
335
+ type: 'basket',
336
+ originator,
337
+ basket,
338
+ reason,
339
+ renewal: false
340
+ });
341
+ }
342
+ }
343
+ /**
344
+ * Ensures the originator has a valid certificate permission.
345
+ * This is relevant when revealing certificate fields in DCAP contexts.
346
+ */
347
+ async ensureCertificateAccess({ originator, privileged, verifier, certType, fields, reason, seekPermission = true, usageType }) {
348
+ if (this.isAdminOriginator(originator))
349
+ return true;
350
+ if (usageType === 'disclosure' && !this.config.seekCertificateDisclosurePermissions) {
351
+ return true;
352
+ }
353
+ if (!this.config.differentiatePrivilegedOperations) {
354
+ privileged = false;
355
+ }
356
+ const token = await this.findCertificateToken(originator, privileged, verifier, certType, fields,
357
+ /*includeExpired=*/ true);
358
+ if (token) {
359
+ if (!this.isTokenExpired(token.expiry)) {
360
+ return true;
361
+ }
362
+ else {
363
+ if (!seekPermission) {
364
+ throw new Error(`Certificate permission expired (seekPermission=false).`);
365
+ }
366
+ return await this.requestPermissionFlow({
367
+ type: 'certificate',
368
+ originator,
369
+ privileged,
370
+ certificate: { verifier, certType, fields },
371
+ reason,
372
+ renewal: true,
373
+ previousToken: token
374
+ });
375
+ }
376
+ }
377
+ else {
378
+ if (!seekPermission) {
379
+ throw new Error(`No certificate permission found (seekPermission=false).`);
380
+ }
381
+ return await this.requestPermissionFlow({
382
+ type: 'certificate',
383
+ originator,
384
+ privileged,
385
+ certificate: { verifier, certType, fields },
386
+ reason,
387
+ renewal: false
388
+ });
389
+ }
390
+ }
391
+ /**
392
+ * Ensures the originator has spending authorization (DSAP) for a certain satoshi amount.
393
+ * If the existing token limit is insufficient, attempts to renew. If no token, attempts to create one.
394
+ */
395
+ async ensureSpendingAuthorization({ originator, satoshis, lineItems, reason, seekPermission = true }) {
396
+ if (this.isAdminOriginator(originator))
397
+ return true;
398
+ if (!this.config.seekSpendingPermissions) {
399
+ // We skip spending permission entirely
400
+ return true;
401
+ }
402
+ const token = await this.findSpendingToken(originator);
403
+ if (token === null || token === void 0 ? void 0 : token.authorizedAmount) {
404
+ // Check how much has been spent so far
405
+ const spentSoFar = await this.querySpentSince(token);
406
+ if (spentSoFar + satoshis <= token.authorizedAmount) {
407
+ return true;
408
+ }
409
+ else {
410
+ // Renew if possible
411
+ if (!seekPermission) {
412
+ throw new Error(`Spending authorization insufficient for ${satoshis}, no user consent (seekPermission=false).`);
413
+ }
414
+ return await this.requestPermissionFlow({
415
+ type: 'spending',
416
+ originator,
417
+ spending: { satoshis, lineItems },
418
+ reason,
419
+ renewal: true,
420
+ previousToken: token
421
+ });
422
+ }
423
+ }
424
+ else {
425
+ // no token
426
+ if (!seekPermission) {
427
+ throw new Error(`No spending authorization found, (seekPermission=false).`);
428
+ }
429
+ return await this.requestPermissionFlow({
430
+ type: 'spending',
431
+ originator,
432
+ spending: { satoshis, lineItems },
433
+ reason,
434
+ renewal: false
435
+ });
436
+ }
437
+ }
438
+ /**
439
+ * Ensures the originator has label usage permission.
440
+ * If no valid (unexpired) permission token is found, triggers a permission request flow.
441
+ */
442
+ async ensureLabelAccess({ originator, label, reason, seekPermission = true, usageType }) {
443
+ // 1) adminOriginator can do anything
444
+ if (this.isAdminOriginator(originator))
445
+ return true;
446
+ // 2) If label is admin-reserved, block
447
+ if (this.isAdminLabel(label)) {
448
+ throw new Error(`Label “${label}” is admin-only.`);
449
+ }
450
+ if (usageType === 'apply' && !this.config.seekPermissionWhenApplyingActionLabels) {
451
+ return true;
452
+ }
453
+ if (usageType === 'list' && !this.config.seekPermissionWhenListingActionsByLabel) {
454
+ return true;
455
+ }
456
+ // 3) Let ensureProtocolPermission handle the rest.
457
+ return await this.ensureProtocolPermission({
458
+ originator,
459
+ privileged: false,
460
+ protocolID: [1, `action label ${label}`],
461
+ counterparty: 'self',
462
+ reason,
463
+ seekPermission,
464
+ usageType: 'generic'
465
+ });
466
+ }
467
+ /**
468
+ * A central method that triggers the permission request flow.
469
+ * - It checks if there's already an active request for the same key
470
+ * - If so, we wait on that existing request rather than creating a duplicative one
471
+ * - Otherwise we create a new request queue, call the relevant "onXXXRequested" event,
472
+ * and return a promise that resolves once permission is granted or rejects if denied.
473
+ */
474
+ async requestPermissionFlow(r) {
475
+ const key = this.buildRequestKey(r);
476
+ // If there's already a queue for the same resource, we piggyback on it
477
+ const existingQueue = this.activeRequests.get(key);
478
+ if (existingQueue && existingQueue.pending.length > 0) {
479
+ return new Promise((resolve, reject) => {
480
+ existingQueue.pending.push({ resolve, reject });
481
+ });
482
+ }
483
+ // Otherwise, create a new queue with a single entry
484
+ // Return a promise that resolves or rejects once the user grants/denies
485
+ return new Promise(async (resolve, reject) => {
486
+ this.activeRequests.set(key, {
487
+ request: r,
488
+ pending: [{ resolve, reject }]
489
+ });
490
+ // Fire the relevant onXXXRequested event (which one depends on r.type)
491
+ switch (r.type) {
492
+ case 'protocol':
493
+ await this.callEvent('onProtocolPermissionRequested', {
494
+ ...r,
495
+ requestID: key
496
+ });
497
+ break;
498
+ case 'basket':
499
+ await this.callEvent('onBasketAccessRequested', {
500
+ ...r,
501
+ requestID: key
502
+ });
503
+ break;
504
+ case 'certificate':
505
+ await this.callEvent('onCertificateAccessRequested', {
506
+ ...r,
507
+ requestID: key
508
+ });
509
+ break;
510
+ case 'spending':
511
+ await this.callEvent('onSpendingAuthorizationRequested', {
512
+ ...r,
513
+ requestID: key
514
+ });
515
+ break;
516
+ }
517
+ });
518
+ }
519
+ /** We always use `keyID="1"` and `counterparty="self"` for these encryption ops. */
520
+ async encryptPermissionTokenField(plaintext) {
521
+ const data = typeof plaintext === 'string' ? sdk_1.Utils.toArray(plaintext, 'utf8') : plaintext;
522
+ const { ciphertext } = await this.underlying.encrypt({
523
+ plaintext: data,
524
+ protocolID: WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,
525
+ keyID: '1'
526
+ }, this.adminOriginator);
527
+ return ciphertext;
528
+ }
529
+ async decryptPermissionTokenField(ciphertext) {
530
+ try {
531
+ const { plaintext } = await this.underlying.decrypt({
532
+ ciphertext,
533
+ protocolID: WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,
534
+ keyID: '1'
535
+ }, this.adminOriginator);
536
+ return plaintext;
537
+ }
538
+ catch (e) {
539
+ return ciphertext;
540
+ }
541
+ }
542
+ /**
543
+ * Encrypts wallet metadata if configured to do so, otherwise returns the original plaintext for storage.
544
+ * @param plaintext The metadata to encrypt if configured to do so
545
+ * @returns The encrypted metadata, or the original value if encryption was disabled.
546
+ */
547
+ async maybeEncryptMetadata(plaintext) {
548
+ if (!this.config.encryptWalletMetadata) {
549
+ return plaintext;
550
+ }
551
+ const { ciphertext } = await this.underlying.encrypt({
552
+ plaintext: sdk_1.Utils.toArray(plaintext, 'utf8'),
553
+ protocolID: WalletPermissionsManager.METADATA_ENCRYPTION_PROTOCOL,
554
+ keyID: '1'
555
+ }, this.adminOriginator);
556
+ return sdk_1.Utils.toBase64(ciphertext);
557
+ }
558
+ /**
559
+ * Attempts to decrypt metadata. if decryption fails, assumes the value is already plaintext and returns it.
560
+ * @param ciphertext The metadata to attempt decryption for.
561
+ * @returns The decrypted metadata. If decryption fails, returns the original value instead.
562
+ */
563
+ async maybeDecryptMetadata(ciphertext) {
564
+ try {
565
+ const { plaintext } = await this.underlying.decrypt({
566
+ ciphertext: sdk_1.Utils.toArray(ciphertext, 'base64'),
567
+ protocolID: WalletPermissionsManager.METADATA_ENCRYPTION_PROTOCOL,
568
+ keyID: '1'
569
+ }, this.adminOriginator);
570
+ return sdk_1.Utils.toUTF8(plaintext);
571
+ }
572
+ catch (e) {
573
+ return ciphertext;
574
+ }
575
+ }
576
+ /** Helper to see if a token's expiry is in the past. */
577
+ isTokenExpired(expiry) {
578
+ const now = Math.floor(Date.now() / 1000);
579
+ return expiry > 0 && expiry < now;
580
+ }
581
+ /** Looks for a DPACP permission token matching origin/domain, privileged, protocol, cpty. */
582
+ async findProtocolToken(originator, privileged, protocolID, counterparty, includeExpired) {
583
+ const [secLevel, protoName] = protocolID;
584
+ const result = await this.underlying.listOutputs({
585
+ basket: BASKET_MAP.protocol,
586
+ tags: [
587
+ `originator ${originator}`,
588
+ `privileged ${!!privileged}`,
589
+ `protocolName ${protoName}`,
590
+ `protocolSecurityLevel ${secLevel}`,
591
+ `counterparty ${counterparty}`
592
+ ],
593
+ tagQueryMode: 'all',
594
+ include: 'entire transactions'
595
+ }, this.adminOriginator);
596
+ for (const out of result.outputs) {
597
+ const [txid, outputIndexStr] = out.outpoint.split('.');
598
+ const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
599
+ const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
600
+ if (!dec || !dec.fields || dec.fields.length < 6)
601
+ continue;
602
+ const domainRaw = dec.fields[0];
603
+ const expiryRaw = dec.fields[1];
604
+ const privRaw = dec.fields[2];
605
+ const secLevelRaw = dec.fields[3];
606
+ const protoNameRaw = dec.fields[4];
607
+ const counterpartyRaw = dec.fields[5];
608
+ const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
609
+ const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
610
+ const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
611
+ const secLevelDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(secLevelRaw)), 10);
612
+ const protoNameDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(protoNameRaw));
613
+ const cptyDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(counterpartyRaw));
614
+ if (domainDecoded !== originator ||
615
+ privDecoded !== !!privileged ||
616
+ secLevelDecoded !== secLevel ||
617
+ protoNameDecoded !== protoName ||
618
+ cptyDecoded !== counterparty) {
619
+ continue;
620
+ }
621
+ if (!includeExpired && this.isTokenExpired(expiryDecoded)) {
622
+ continue;
623
+ }
624
+ return {
625
+ tx: tx.toBEEF(),
626
+ txid: out.outpoint.split('.')[0],
627
+ outputIndex: parseInt(out.outpoint.split('.')[1], 10),
628
+ outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
629
+ satoshis: out.satoshis,
630
+ originator,
631
+ privileged,
632
+ protocol: protoName,
633
+ securityLevel: secLevel,
634
+ expiry: expiryDecoded,
635
+ counterparty: cptyDecoded
636
+ };
637
+ }
638
+ return undefined;
639
+ }
640
+ /** Looks for a DBAP token matching (originator, basket). */
641
+ async findBasketToken(originator, basket, includeExpired) {
642
+ const result = await this.underlying.listOutputs({
643
+ basket: BASKET_MAP.basket,
644
+ tags: [`originator ${originator}`, `basket ${basket}`],
645
+ tagQueryMode: 'all',
646
+ include: 'entire transactions'
647
+ }, this.adminOriginator);
648
+ for (const out of result.outputs) {
649
+ const [txid, outputIndexStr] = out.outpoint.split('.');
650
+ const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
651
+ const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
652
+ if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 3)
653
+ continue;
654
+ const domainRaw = dec.fields[0];
655
+ const expiryRaw = dec.fields[1];
656
+ const basketRaw = dec.fields[2];
657
+ const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
658
+ const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
659
+ const basketDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(basketRaw));
660
+ if (domainDecoded !== originator || basketDecoded !== basket)
661
+ continue;
662
+ if (!includeExpired && this.isTokenExpired(expiryDecoded))
663
+ continue;
664
+ return {
665
+ tx: tx.toBEEF(),
666
+ txid: out.outpoint.split('.')[0],
667
+ outputIndex: parseInt(out.outpoint.split('.')[1], 10),
668
+ outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
669
+ satoshis: out.satoshis,
670
+ originator,
671
+ basketName: basketDecoded,
672
+ expiry: expiryDecoded
673
+ };
674
+ }
675
+ return undefined;
676
+ }
677
+ /** Looks for a DCAP token matching (origin, privileged, verifier, certType, fields subset). */
678
+ async findCertificateToken(originator, privileged, verifier, certType, fields, includeExpired) {
679
+ const result = await this.underlying.listOutputs({
680
+ basket: BASKET_MAP.certificate,
681
+ tags: [`originator ${originator}`, `privileged ${!!privileged}`, `type ${certType}`, `verifier ${verifier}`],
682
+ tagQueryMode: 'all',
683
+ include: 'entire transactions'
684
+ }, this.adminOriginator);
685
+ for (const out of result.outputs) {
686
+ const [txid, outputIndexStr] = out.outpoint.split('.');
687
+ const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
688
+ const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
689
+ if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 6)
690
+ continue;
691
+ const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = dec.fields;
692
+ const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
693
+ const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
694
+ const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
695
+ const typeDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw));
696
+ const verifierDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw));
697
+ const fieldsJson = await this.decryptPermissionTokenField(fieldsRaw);
698
+ const allFields = JSON.parse(sdk_1.Utils.toUTF8(fieldsJson));
699
+ if (domainDecoded !== originator ||
700
+ privDecoded !== !!privileged ||
701
+ typeDecoded !== certType ||
702
+ verifierDec !== verifier) {
703
+ continue;
704
+ }
705
+ // Check if 'fields' is a subset of 'allFields'
706
+ const setAll = new Set(allFields);
707
+ if (fields.some(f => !setAll.has(f))) {
708
+ continue;
709
+ }
710
+ if (!includeExpired && this.isTokenExpired(expiryDecoded)) {
711
+ continue;
712
+ }
713
+ return {
714
+ tx: tx.toBEEF(),
715
+ txid: out.outpoint.split('.')[0],
716
+ outputIndex: parseInt(out.outpoint.split('.')[1], 10),
717
+ outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
718
+ satoshis: out.satoshis,
719
+ originator,
720
+ privileged,
721
+ verifier: verifierDec,
722
+ certType: typeDecoded,
723
+ certFields: allFields,
724
+ expiry: expiryDecoded
725
+ };
726
+ }
727
+ return undefined;
728
+ }
729
+ /** Looks for a DSAP token matching origin, returning the first one found. */
730
+ async findSpendingToken(originator) {
731
+ const result = await this.underlying.listOutputs({
732
+ basket: BASKET_MAP.spending,
733
+ tags: [`originator ${originator}`],
734
+ tagQueryMode: 'all',
735
+ include: 'entire transactions'
736
+ }, this.adminOriginator);
737
+ for (const out of result.outputs) {
738
+ const [txid, outputIndexStr] = out.outpoint.split('.');
739
+ const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
740
+ const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
741
+ if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 2)
742
+ continue;
743
+ const domainRaw = dec.fields[0];
744
+ const amtRaw = dec.fields[1];
745
+ const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
746
+ if (domainDecoded !== originator)
747
+ continue;
748
+ const amtDecodedStr = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(amtRaw));
749
+ const authorizedAmount = parseInt(amtDecodedStr, 10);
750
+ return {
751
+ tx: tx.toBEEF(),
752
+ txid: out.outpoint.split('.')[0],
753
+ outputIndex: parseInt(out.outpoint.split('.')[1], 10),
754
+ outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
755
+ satoshis: out.satoshis,
756
+ originator,
757
+ authorizedAmount,
758
+ expiry: 0 // Not time-limited, monthly authorization
759
+ };
760
+ }
761
+ return undefined;
762
+ }
763
+ /**
764
+ * Returns the current month and year in UTC as a string in the format "YYYY-MM".
765
+ *
766
+ * @returns {string} The current month and year in UTC.
767
+ */
768
+ getCurrentMonthYearUTC() {
769
+ const now = new Date();
770
+ const year = now.getUTCFullYear();
771
+ const month = (now.getUTCMonth() + 1).toString().padStart(2, '0'); // Ensure 2-digit month
772
+ return `${year}-${month}`;
773
+ }
774
+ /**
775
+ * Returns spending for an originator in the current calendar month.
776
+ */
777
+ async querySpentSince(token) {
778
+ const { actions } = await this.underlying.listActions({
779
+ labels: [`admin originator ${token.originator}`, `admin month ${this.getCurrentMonthYearUTC()}`],
780
+ labelQueryMode: 'all'
781
+ }, this.adminOriginator);
782
+ return actions.reduce((a, e) => a + e.satoshis, 0);
783
+ }
784
+ /* ---------------------------------------------------------------------
785
+ * 5) CREATE / RENEW / REVOKE PERMISSION TOKENS ON CHAIN
786
+ * --------------------------------------------------------------------- */
787
+ /**
788
+ * Creates a brand-new permission token as a single-output PushDrop script in the relevant admin basket.
789
+ *
790
+ * The main difference between each type of token is in the "fields" we store in the PushDrop script.
791
+ *
792
+ * @param r The permission request
793
+ * @param expiry The expiry epoch time
794
+ * @param amount For DSAP, the authorized spending limit
795
+ */
796
+ async createPermissionOnChain(r, expiry, amount) {
797
+ const basketName = BASKET_MAP[r.type];
798
+ if (!basketName)
799
+ return;
800
+ // Build the array of encrypted fields for the PushDrop script
801
+ const fields = await this.buildPushdropFields(r, expiry, amount);
802
+ // Construct the script. We do a simple P2PK check. We ask `PushDrop.lock(...)`
803
+ // to create a script with a single OP_CHECKSIG verifying ownership to redeem.
804
+ const script = await new sdk_1.PushDrop(this.underlying).lock(fields, WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL, '1', 'self', true, true);
805
+ // Create tags
806
+ const tags = this.buildTagsForRequest(r);
807
+ // Build a transaction with exactly one output, no explicit inputs since the wallet
808
+ // can internally fund it from its balance.
809
+ await this.createAction({
810
+ description: `Grant ${r.type} permission`,
811
+ outputs: [
812
+ {
813
+ lockingScript: script.toHex(),
814
+ satoshis: 1,
815
+ outputDescription: `${r.type} permission token`,
816
+ basket: basketName,
817
+ tags
818
+ }
819
+ ],
820
+ options: {
821
+ acceptDelayedBroadcast: false
822
+ }
823
+ }, this.adminOriginator);
824
+ }
825
+ /**
826
+ * Renews a permission token by spending the old token as input and creating a new token output.
827
+ * This invalidates the old token and replaces it with a new one.
828
+ *
829
+ * @param oldToken The old token to consume
830
+ * @param r The permission request being renewed
831
+ * @param newExpiry The new expiry epoch time
832
+ * @param newAmount For DSAP, the new authorized amount
833
+ */
834
+ async renewPermissionOnChain(oldToken, r, newExpiry, newAmount) {
835
+ // 1) build new fields
836
+ const newFields = await this.buildPushdropFields(r, newExpiry, newAmount);
837
+ // 2) new script
838
+ const newScript = await new sdk_1.PushDrop(this.underlying).lock(newFields, WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL, '1', 'self', true, true);
839
+ const tags = this.buildTagsForRequest(r);
840
+ // 3) For BRC-100, we do a "createAction" with a partial input referencing oldToken
841
+ // plus a single new output. We'll hydrate the template, then signAction for the wallet to finalize.
842
+ const oldOutpoint = `${oldToken.txid}.${oldToken.outputIndex}`;
843
+ const { signableTransaction } = await this.createAction({
844
+ description: `Renew ${r.type} permission`,
845
+ inputBEEF: oldToken.tx,
846
+ inputs: [
847
+ {
848
+ outpoint: oldOutpoint,
849
+ unlockingScriptLength: 73, // length of signature
850
+ inputDescription: `Consume old ${r.type} token`
851
+ }
852
+ ],
853
+ outputs: [
854
+ {
855
+ lockingScript: newScript.toHex(),
856
+ satoshis: 1,
857
+ outputDescription: `Renewed ${r.type} permission token`,
858
+ basket: BASKET_MAP[r.type],
859
+ tags
860
+ }
861
+ ],
862
+ options: {
863
+ acceptDelayedBroadcast: false
864
+ }
865
+ }, this.adminOriginator);
866
+ const tx = sdk_1.Transaction.fromBEEF(signableTransaction.tx);
867
+ const unlocker = new sdk_1.PushDrop(this.underlying).unlock(WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL, '1', 'self', 'all', false, 1, sdk_1.LockingScript.fromHex(oldToken.outputScript));
868
+ const unlockingScript = await unlocker.sign(tx, 0);
869
+ await this.underlying.signAction({
870
+ reference: signableTransaction.reference,
871
+ spends: {
872
+ 0: {
873
+ unlockingScript: unlockingScript.toHex()
874
+ }
875
+ }
876
+ });
877
+ }
878
+ /**
879
+ * Builds the encrypted array of fields for a PushDrop permission token
880
+ * (protocol / basket / certificate / spending).
881
+ */
882
+ async buildPushdropFields(r, expiry, amount) {
883
+ var _a;
884
+ switch (r.type) {
885
+ case 'protocol': {
886
+ const [secLevel, protoName] = r.protocolID;
887
+ return [
888
+ await this.encryptPermissionTokenField(r.originator), // domain
889
+ await this.encryptPermissionTokenField(String(expiry)), // expiry
890
+ await this.encryptPermissionTokenField(r.privileged === true ? 'true' : 'false'),
891
+ await this.encryptPermissionTokenField(String(secLevel)),
892
+ await this.encryptPermissionTokenField(protoName),
893
+ await this.encryptPermissionTokenField(r.counterparty)
894
+ ];
895
+ }
896
+ case 'basket': {
897
+ return [
898
+ await this.encryptPermissionTokenField(r.originator),
899
+ await this.encryptPermissionTokenField(String(expiry)),
900
+ await this.encryptPermissionTokenField(r.basket)
901
+ ];
902
+ }
903
+ case 'certificate': {
904
+ const { certType, fields, verifier } = r.certificate;
905
+ return [
906
+ await this.encryptPermissionTokenField(r.originator),
907
+ await this.encryptPermissionTokenField(String(expiry)),
908
+ await this.encryptPermissionTokenField(r.privileged ? 'true' : 'false'),
909
+ await this.encryptPermissionTokenField(certType),
910
+ await this.encryptPermissionTokenField(JSON.stringify(fields)),
911
+ await this.encryptPermissionTokenField(verifier)
912
+ ];
913
+ }
914
+ case 'spending': {
915
+ // DSAP
916
+ const authAmt = amount !== null && amount !== void 0 ? amount : (((_a = r.spending) === null || _a === void 0 ? void 0 : _a.satoshis) || 0);
917
+ return [
918
+ await this.encryptPermissionTokenField(r.originator),
919
+ await this.encryptPermissionTokenField(String(authAmt))
920
+ ];
921
+ }
922
+ }
923
+ }
924
+ /**
925
+ * Helper to build an array of tags for the new output, matching the user request's
926
+ * origin, basket, privileged, protocol name, etc.
927
+ */
928
+ buildTagsForRequest(r) {
929
+ const tags = [`originator ${r.originator}`];
930
+ switch (r.type) {
931
+ case 'protocol': {
932
+ tags.push(`privileged ${!!r.privileged}`);
933
+ tags.push(`protocolName ${r.protocolID[1]}`);
934
+ tags.push(`protocolSecurityLevel ${r.protocolID[0]}`);
935
+ tags.push(`counterparty ${r.counterparty}`);
936
+ break;
937
+ }
938
+ case 'basket': {
939
+ tags.push(`basket ${r.basket}`);
940
+ break;
941
+ }
942
+ case 'certificate': {
943
+ tags.push(`privileged ${!!r.privileged}`);
944
+ tags.push(`type ${r.certificate.certType}`);
945
+ tags.push(`verifier ${r.certificate.verifier}`);
946
+ break;
947
+ }
948
+ case 'spending': {
949
+ // Only 'originator' is strictly required as a tag.
950
+ break;
951
+ }
952
+ }
953
+ return tags;
954
+ }
955
+ /* ---------------------------------------------------------------------
956
+ * 6) PUBLIC "LIST/HAS/REVOKE" METHODS
957
+ * --------------------------------------------------------------------- */
958
+ /**
959
+ * Lists all protocol permission tokens (DPACP) with optional filters.
960
+ * @param originator Optional originator domain to filter by
961
+ * @param privileged Optional boolean to filter by privileged status
962
+ * @param protocolName Optional protocol name to filter by
963
+ * @param protocolSecurityLevel Optional protocol security level to filter by
964
+ * @param counterparty Optional counterparty to filter by
965
+ * @returns Array of permission tokens that match the filter criteria
966
+ */
967
+ async listProtocolPermissions({ originator, privileged, protocolName, protocolSecurityLevel, counterparty } = {}) {
968
+ const basketName = BASKET_MAP.protocol;
969
+ const tags = [];
970
+ if (originator) {
971
+ tags.push(`originator ${originator}`);
972
+ }
973
+ if (privileged !== undefined) {
974
+ tags.push(`privileged ${!!privileged}`);
975
+ }
976
+ if (protocolName) {
977
+ tags.push(`protocolName ${protocolName}`);
978
+ }
979
+ if (protocolSecurityLevel !== undefined) {
980
+ tags.push(`protocolSecurityLevel ${protocolSecurityLevel}`);
981
+ }
982
+ if (counterparty) {
983
+ tags.push(`counterparty ${counterparty}`);
984
+ }
985
+ const result = await this.underlying.listOutputs({
986
+ basket: basketName,
987
+ tags,
988
+ tagQueryMode: 'all',
989
+ include: 'entire transactions',
990
+ limit: 100
991
+ }, this.adminOriginator);
992
+ const tokens = [];
993
+ for (const out of result.outputs) {
994
+ const [txid, outputIndexStr] = out.outpoint.split('.');
995
+ const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
996
+ const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
997
+ if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 6)
998
+ continue;
999
+ const [domainRaw, expiryRaw, privRaw, secRaw, protoRaw, cptyRaw] = dec.fields;
1000
+ const domainDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
1001
+ const expiryDec = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
1002
+ const privDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
1003
+ const secDec = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(secRaw)), 10);
1004
+ const protoDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(protoRaw));
1005
+ const cptyDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(cptyRaw));
1006
+ tokens.push({
1007
+ tx: tx.toBEEF(),
1008
+ txid: out.outpoint.split('.')[0],
1009
+ outputIndex: parseInt(out.outpoint.split('.')[1], 10),
1010
+ outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
1011
+ satoshis: out.satoshis,
1012
+ originator: domainDec,
1013
+ expiry: expiryDec,
1014
+ privileged: privDec,
1015
+ securityLevel: secDec,
1016
+ protocol: protoDec,
1017
+ counterparty: cptyDec
1018
+ });
1019
+ }
1020
+ return tokens;
1021
+ }
1022
+ /**
1023
+ * Returns true if the originator already holds a valid unexpired protocol permission.
1024
+ * This calls `ensureProtocolPermission` with `seekPermission=false`, so it won't prompt.
1025
+ */
1026
+ async hasProtocolPermission(params) {
1027
+ try {
1028
+ await this.ensureProtocolPermission({
1029
+ ...params,
1030
+ reason: 'hasProtocolPermission',
1031
+ seekPermission: false,
1032
+ usageType: 'generic'
1033
+ });
1034
+ return true;
1035
+ }
1036
+ catch (_a) {
1037
+ return false;
1038
+ }
1039
+ }
1040
+ /**
1041
+ * Lists basket permission tokens (DBAP) for a given originator or basket (or for all if not specified).
1042
+ * @param params.originator Optional originator to filter by
1043
+ * @param params.basket Optional basket name to filter by
1044
+ * @returns Array of permission tokens that match the filter criteria
1045
+ */
1046
+ async listBasketAccess(params = {}) {
1047
+ const basketName = BASKET_MAP.basket;
1048
+ const tags = [];
1049
+ if (params.originator) {
1050
+ tags.push(`originator ${params.originator}`);
1051
+ }
1052
+ if (params.basket) {
1053
+ tags.push(`basket ${params.basket}`);
1054
+ }
1055
+ const result = await this.underlying.listOutputs({
1056
+ basket: basketName,
1057
+ tags,
1058
+ tagQueryMode: 'all',
1059
+ include: 'entire transactions',
1060
+ limit: 10000
1061
+ }, this.adminOriginator);
1062
+ const tokens = [];
1063
+ for (const out of result.outputs) {
1064
+ const [txid, outputIndexStr] = out.outpoint.split('.');
1065
+ const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
1066
+ const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
1067
+ if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 3)
1068
+ continue;
1069
+ const [domainRaw, expiryRaw, basketRaw] = dec.fields;
1070
+ const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
1071
+ const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
1072
+ const basketDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(basketRaw));
1073
+ tokens.push({
1074
+ tx: tx.toBEEF(),
1075
+ txid: out.outpoint.split('.')[0],
1076
+ outputIndex: parseInt(out.outpoint.split('.')[1], 10),
1077
+ satoshis: out.satoshis,
1078
+ outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
1079
+ originator: domainDecoded,
1080
+ basketName: basketDecoded,
1081
+ expiry: expiryDecoded
1082
+ });
1083
+ }
1084
+ return tokens;
1085
+ }
1086
+ /**
1087
+ * Returns `true` if the originator already holds a valid unexpired basket permission for `basket`.
1088
+ */
1089
+ async hasBasketAccess(params) {
1090
+ try {
1091
+ await this.ensureBasketAccess({
1092
+ originator: params.originator,
1093
+ basket: params.basket,
1094
+ seekPermission: false,
1095
+ usageType: 'insertion' // TODO: Consider a generic case for "has"
1096
+ });
1097
+ return true;
1098
+ }
1099
+ catch (_a) {
1100
+ return false;
1101
+ }
1102
+ }
1103
+ /**
1104
+ * Lists spending authorization tokens (DSAP) for a given originator (or all).
1105
+ */
1106
+ async listSpendingAuthorizations(params) {
1107
+ const basketName = BASKET_MAP.spending;
1108
+ const tags = [];
1109
+ if (params.originator) {
1110
+ tags.push(`originator ${params.originator}`);
1111
+ }
1112
+ const result = await this.underlying.listOutputs({
1113
+ basket: basketName,
1114
+ tags,
1115
+ tagQueryMode: 'all',
1116
+ include: 'entire transactions',
1117
+ limit: 10000
1118
+ }, this.adminOriginator);
1119
+ const tokens = [];
1120
+ for (const out of result.outputs) {
1121
+ const [txid, outputIndexStr] = out.outpoint.split('.');
1122
+ const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
1123
+ const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
1124
+ if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 2)
1125
+ continue;
1126
+ const [domainRaw, amtRaw] = dec.fields;
1127
+ const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
1128
+ const amtDecodedStr = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(amtRaw));
1129
+ const authorizedAmount = parseInt(amtDecodedStr, 10);
1130
+ tokens.push({
1131
+ tx: tx.toBEEF(),
1132
+ txid: out.outpoint.split('.')[0],
1133
+ outputIndex: parseInt(out.outpoint.split('.')[1], 10),
1134
+ satoshis: out.satoshis,
1135
+ outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
1136
+ originator: domainDecoded,
1137
+ authorizedAmount,
1138
+ expiry: 0
1139
+ });
1140
+ }
1141
+ return tokens;
1142
+ }
1143
+ /**
1144
+ * Returns `true` if the originator already holds a valid spending authorization token
1145
+ * with enough available monthly spend. We do not prompt (seekPermission=false).
1146
+ */
1147
+ async hasSpendingAuthorization(params) {
1148
+ try {
1149
+ await this.ensureSpendingAuthorization({
1150
+ originator: params.originator,
1151
+ satoshis: params.satoshis,
1152
+ seekPermission: false
1153
+ });
1154
+ return true;
1155
+ }
1156
+ catch (_a) {
1157
+ return false;
1158
+ }
1159
+ }
1160
+ /**
1161
+ * Lists certificate permission tokens (DCAP) with optional filters.
1162
+ * @param originator Optional originator domain to filter by
1163
+ * @param privileged Optional boolean to filter by privileged status
1164
+ * @param certType Optional certificate type to filter by
1165
+ * @param verifier Optional verifier to filter by
1166
+ * @returns Array of permission tokens that match the filter criteria
1167
+ */
1168
+ async listCertificateAccess(params = {}) {
1169
+ const basketName = BASKET_MAP.certificate;
1170
+ const tags = [];
1171
+ if (params.originator) {
1172
+ tags.push(`originator ${params.originator}`);
1173
+ }
1174
+ if (params.privileged !== undefined) {
1175
+ tags.push(`privileged ${!!params.privileged}`);
1176
+ }
1177
+ if (params.certType) {
1178
+ tags.push(`type ${params.certType}`);
1179
+ }
1180
+ if (params.verifier) {
1181
+ tags.push(`verifier ${params.verifier}`);
1182
+ }
1183
+ const result = await this.underlying.listOutputs({
1184
+ basket: basketName,
1185
+ tags,
1186
+ tagQueryMode: 'all',
1187
+ include: 'entire transactions',
1188
+ limit: 10000
1189
+ }, this.adminOriginator);
1190
+ const tokens = [];
1191
+ for (const out of result.outputs) {
1192
+ const [txid, outputIndexStr] = out.outpoint.split('.');
1193
+ const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
1194
+ const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
1195
+ if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 6)
1196
+ continue;
1197
+ const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = dec.fields;
1198
+ const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
1199
+ const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
1200
+ const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
1201
+ const typeDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw));
1202
+ const verifierDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw));
1203
+ const fieldsJson = await this.decryptPermissionTokenField(fieldsRaw);
1204
+ const allFields = JSON.parse(sdk_1.Utils.toUTF8(fieldsJson));
1205
+ tokens.push({
1206
+ tx: tx.toBEEF(),
1207
+ txid: out.outpoint.split('.')[0],
1208
+ outputIndex: parseInt(out.outpoint.split('.')[1], 10),
1209
+ satoshis: out.satoshis,
1210
+ outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
1211
+ originator: domainDecoded,
1212
+ privileged: privDecoded,
1213
+ certType: typeDecoded,
1214
+ certFields: allFields,
1215
+ verifier: verifierDec,
1216
+ expiry: expiryDecoded
1217
+ });
1218
+ }
1219
+ return tokens;
1220
+ }
1221
+ /**
1222
+ * Returns `true` if the originator already holds a valid unexpired certificate access
1223
+ * for the given certType/fields. Does not prompt the user.
1224
+ */
1225
+ async hasCertificateAccess(params) {
1226
+ try {
1227
+ await this.ensureCertificateAccess({
1228
+ originator: params.originator,
1229
+ privileged: params.privileged,
1230
+ verifier: params.verifier,
1231
+ certType: params.certType,
1232
+ fields: params.fields,
1233
+ seekPermission: false,
1234
+ usageType: 'disclosure'
1235
+ });
1236
+ return true;
1237
+ }
1238
+ catch (_a) {
1239
+ return false;
1240
+ }
1241
+ }
1242
+ /**
1243
+ * Revokes a permission token by spending it with no replacement output.
1244
+ * The manager builds a BRC-100 transaction that consumes the token, effectively invalidating it.
1245
+ */
1246
+ async revokePermission(oldToken) {
1247
+ const oldOutpoint = `${oldToken.txid}.${oldToken.outputIndex}`;
1248
+ const { signableTransaction } = await this.createAction({
1249
+ description: `Revoke permission`,
1250
+ inputBEEF: oldToken.tx,
1251
+ inputs: [
1252
+ {
1253
+ outpoint: oldOutpoint,
1254
+ unlockingScriptLength: 73, // length of signature
1255
+ inputDescription: `Consume old permission token`
1256
+ }
1257
+ ],
1258
+ options: {
1259
+ acceptDelayedBroadcast: false
1260
+ }
1261
+ }, this.adminOriginator);
1262
+ const tx = sdk_1.Transaction.fromBEEF(signableTransaction.tx);
1263
+ const unlocker = new sdk_1.PushDrop(this.underlying).unlock(WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL, '1', 'self', 'all', false, 1, sdk_1.LockingScript.fromHex(oldToken.outputScript));
1264
+ const unlockingScript = await unlocker.sign(tx, 0);
1265
+ await this.underlying.signAction({
1266
+ reference: signableTransaction.reference,
1267
+ spends: {
1268
+ 0: {
1269
+ unlockingScript: unlockingScript.toHex()
1270
+ }
1271
+ }
1272
+ });
1273
+ }
1274
+ /* ---------------------------------------------------------------------
1275
+ * 7) BRC-100 WALLET INTERFACE FORWARDING WITH PERMISSION CHECKS
1276
+ * --------------------------------------------------------------------- */
1277
+ async createAction(args, originator) {
1278
+ // 1) Ensure basket and label permissions
1279
+ if (args.outputs) {
1280
+ for (const out of args.outputs) {
1281
+ if (out.basket) {
1282
+ await this.ensureBasketAccess({
1283
+ originator: originator,
1284
+ basket: out.basket,
1285
+ reason: args.description,
1286
+ usageType: 'insertion'
1287
+ });
1288
+ }
1289
+ }
1290
+ }
1291
+ if (args.labels) {
1292
+ for (const lbl of args.labels) {
1293
+ await this.ensureLabelAccess({
1294
+ originator: originator,
1295
+ label: lbl,
1296
+ reason: args.description,
1297
+ usageType: 'apply'
1298
+ });
1299
+ }
1300
+ }
1301
+ /**
1302
+ * 2) Force signAndProcess=false unless the originator is admin and explicitly sets it to true.
1303
+ * This ensures the underlying wallet returns a signableTransaction, letting us parse the transaction
1304
+ * to determine net spending and request authorization if needed.
1305
+ */
1306
+ const modifiedOptions = { ...(args.options || {}) };
1307
+ if (modifiedOptions.signAndProcess !== true) {
1308
+ modifiedOptions.signAndProcess = false;
1309
+ }
1310
+ else if (!this.isAdminOriginator(originator)) {
1311
+ throw new Error('Only the admin originator can set signAndProcess=true explicitly.');
1312
+ }
1313
+ // 3) Encrypt transaction metadata, saving originals for use in permissions and line items.
1314
+ const originalDescription = args.description;
1315
+ const originalInputDescriptions = {};
1316
+ const originalOutputDescriptions = {};
1317
+ args.description = await this.maybeEncryptMetadata(args.description);
1318
+ for (let i = 0; i < (args.inputs || []).length; i++) {
1319
+ if (args.inputs[i].inputDescription) {
1320
+ originalInputDescriptions[i] = args.inputs[i].inputDescription;
1321
+ args.inputs[i].inputDescription = await this.maybeEncryptMetadata(args.inputs[i].inputDescription);
1322
+ }
1323
+ }
1324
+ for (let i = 0; i < (args.outputs || []).length; i++) {
1325
+ if (args.outputs[i].outputDescription) {
1326
+ originalOutputDescriptions[i] = args.outputs[i].outputDescription;
1327
+ args.outputs[i].outputDescription = await this.maybeEncryptMetadata(args.outputs[i].outputDescription);
1328
+ }
1329
+ if (args.outputs[i].customInstructions) {
1330
+ args.outputs[i].customInstructions = await this.maybeEncryptMetadata(args.outputs[i].customInstructions);
1331
+ }
1332
+ }
1333
+ /**
1334
+ * 4) Call the underlying wallet’s createAction. We add two “admin” labels:
1335
+ * - "admin originator <domain>"
1336
+ * - "admin month YYYY-MM"
1337
+ * These labels help track the originator’s monthly spending.
1338
+ */
1339
+ const createResult = await this.underlying.createAction({
1340
+ ...args,
1341
+ options: modifiedOptions,
1342
+ labels: [
1343
+ ...(args.labels || []),
1344
+ `admin originator ${originator}`,
1345
+ `admin month ${this.getCurrentMonthYearUTC()}`
1346
+ ]
1347
+ }, originator);
1348
+ // If there's no signableTransaction, the underlying wallet must have fully finalized it. Return as is.
1349
+ if (!createResult.signableTransaction) {
1350
+ return createResult;
1351
+ }
1352
+ /**
1353
+ * 5) We have a signable transaction. Parse it to determine how much the originator is actually spending.
1354
+ * We only consider inputs the originator explicitly listed in args.inputs.
1355
+ * netSpent = (sum of originator-requested outputs) - (sum of matching originator inputs).
1356
+ * If netSpent > 0, we need spending authorization.
1357
+ */
1358
+ const tx = sdk_1.Transaction.fromAtomicBEEF(createResult.signableTransaction.tx);
1359
+ const reference = createResult.signableTransaction.reference;
1360
+ let netSpent = 0;
1361
+ const lineItems = [];
1362
+ // Sum originator-provided inputs:
1363
+ let totalInputSatoshis = 0;
1364
+ for (const input of tx.inputs) {
1365
+ const outpoint = `${input.sourceTXID}.${input.sourceOutputIndex}`;
1366
+ const matchingIndex = (args.inputs || []).findIndex(i => i.outpoint === outpoint);
1367
+ if (matchingIndex !== -1) {
1368
+ const satoshis = input.sourceTransaction.outputs[input.sourceOutputIndex].satoshis;
1369
+ totalInputSatoshis += satoshis;
1370
+ lineItems.push({
1371
+ type: 'input',
1372
+ description: originalInputDescriptions[matchingIndex] || 'No input description provided',
1373
+ satoshis: satoshis
1374
+ });
1375
+ }
1376
+ }
1377
+ // Sum originator-requested outputs:
1378
+ const totalOutputSatoshis = (args.outputs || []).reduce((acc, out) => acc + out.satoshis, 0);
1379
+ for (const outIndex in args.outputs || []) {
1380
+ const out = args.outputs[outIndex];
1381
+ lineItems.push({
1382
+ type: 'output',
1383
+ satoshis: out.satoshis,
1384
+ description: originalOutputDescriptions[outIndex] || 'No output description provided'
1385
+ });
1386
+ }
1387
+ // Add an entry for the transaction fee:
1388
+ lineItems.push({
1389
+ type: 'fee',
1390
+ satoshis: tx.getFee(),
1391
+ description: 'Network fee'
1392
+ });
1393
+ /**
1394
+ * When it comes to spending authorizations, and the computation of net spend, there are
1395
+ * two types of inputs and two types of outputs:
1396
+ *
1397
+ * There are foreign (originator-requested) ones, and domestic (internally-provided) ones.
1398
+ * The net spend is always calculated from the domestic, internal perspective. Therefore, the
1399
+ * cost of funding the foreign outputs is the base cost to the domestic user, unless this is
1400
+ * somehow offset.
1401
+ *
1402
+ * The only way to offset this cost is when the foreign inputs help carry some of the burden.
1403
+ * This is why we can subtract the sum of the foreign inputs from the sum of foreign outputs,
1404
+ * to gague how much of that cost needs to be born domestically by the user.
1405
+ *
1406
+ * The logic does not need to account for whatever domestic inputs are provided, or whatever
1407
+ * domestic outputs are re-captured by the wallet back as change. The wallet could conceivably
1408
+ * provide 21e8 satoshis as input and re-capture the same amount as change, but the net effect
1409
+ * on actual spending would be zero. Therefore, we base net spend on total foreign outflows
1410
+ * minus total foreign inflows. Fees are also considered.
1411
+ */
1412
+ netSpent = totalOutputSatoshis + tx.getFee() - totalInputSatoshis;
1413
+ // 6) If netSpent > 0, require spending authorization. Abort if denied.
1414
+ if (netSpent > 0) {
1415
+ try {
1416
+ await this.ensureSpendingAuthorization({
1417
+ originator: originator,
1418
+ satoshis: netSpent,
1419
+ lineItems,
1420
+ reason: originalDescription
1421
+ });
1422
+ }
1423
+ catch (err) {
1424
+ await this.underlying.abortAction({ reference });
1425
+ throw err;
1426
+ }
1427
+ }
1428
+ /**
1429
+ * 7) Decide whether to finalize the transaction automatically or return the signableTransaction:
1430
+ * - If the user originally wanted signAndProcess (the default when undefined), we forcibly set it to false earlier, so check if we should now finalize it.
1431
+ * - If the transaction still needs more signatures, we must return the signableTransaction.
1432
+ */
1433
+ const vargs = (0, sdk_2.validateCreateActionArgs)(args);
1434
+ if (vargs.isSignAction) {
1435
+ return createResult;
1436
+ }
1437
+ const signResult = await this.underlying.signAction({ reference, spends: {}, options: args.options }, originator);
1438
+ // Merge signResult into createResult and remove signableTransaction:
1439
+ return {
1440
+ ...createResult,
1441
+ ...signResult,
1442
+ signableTransaction: undefined
1443
+ };
1444
+ // const userWantedImmediate = args.options?.signAndProcess !== false
1445
+ // const weOverrode =
1446
+ // modifiedOptions.signAndProcess === false &&
1447
+ // args.options?.signAndProcess !== false
1448
+ // // Check if all inputs already have valid unlockingScripts (no partial signatures needed)
1449
+ const allInputsHaveScripts = tx.inputs.every(i => i.unlockingScript);
1450
+ // // If user wanted immediate broadcast and we forcibly suppressed it, we can finalize now by calling signAction with no additional scripts:
1451
+ // if (allInputsHaveScripts && userWantedImmediate && weOverrode) {
1452
+ // }
1453
+ // // Otherwise, return the partial transaction so the caller can do signAction.
1454
+ // return createResult
1455
+ }
1456
+ async signAction(...args) {
1457
+ return this.underlying.signAction(...args);
1458
+ }
1459
+ async abortAction(...args) {
1460
+ return this.underlying.abortAction(...args);
1461
+ }
1462
+ async listActions(...args) {
1463
+ const [requestArgs, originator] = args;
1464
+ // for each label, ensure label access
1465
+ if (requestArgs.labels) {
1466
+ for (const lbl of requestArgs.labels) {
1467
+ await this.ensureLabelAccess({
1468
+ originator: originator,
1469
+ label: lbl,
1470
+ reason: 'listActions',
1471
+ usageType: 'list'
1472
+ });
1473
+ }
1474
+ }
1475
+ const results = await this.underlying.listActions(...args);
1476
+ // Transparently decrypt transaction metadata, if configured to do so.
1477
+ if (results.actions) {
1478
+ for (let i = 0; i < results.actions.length; i++) {
1479
+ if (results.actions[i].description) {
1480
+ results.actions[i].description = await this.maybeDecryptMetadata(results.actions[i].description);
1481
+ }
1482
+ if (results.actions[i].inputs) {
1483
+ for (let j = 0; j < results.actions[i].inputs.length; j++) {
1484
+ if (results.actions[i].inputs[j].inputDescription) {
1485
+ results.actions[i].inputs[j].inputDescription = await this.maybeDecryptMetadata(results.actions[i].inputs[j].inputDescription);
1486
+ }
1487
+ }
1488
+ }
1489
+ if (results.actions[i].outputs) {
1490
+ for (let j = 0; j < results.actions[i].outputs.length; j++) {
1491
+ if (results.actions[i].outputs[j].outputDescription) {
1492
+ results.actions[i].outputs[j].outputDescription = await this.maybeDecryptMetadata(results.actions[i].outputs[j].outputDescription);
1493
+ }
1494
+ if (results.actions[i].outputs[j].customInstructions) {
1495
+ results.actions[i].outputs[j].customInstructions = await this.maybeDecryptMetadata(results.actions[i].outputs[j].customInstructions);
1496
+ }
1497
+ }
1498
+ }
1499
+ }
1500
+ }
1501
+ return results;
1502
+ }
1503
+ async internalizeAction(...args) {
1504
+ const [requestArgs, originator] = args;
1505
+ // If the transaction is inserting outputs into baskets, we also ensure basket permission
1506
+ for (const outIndex in requestArgs.outputs) {
1507
+ const out = requestArgs.outputs[outIndex];
1508
+ if (out.protocol === 'basket insertion') {
1509
+ await this.ensureBasketAccess({
1510
+ originator: originator,
1511
+ basket: out.insertionRemittance.basket,
1512
+ reason: requestArgs.description,
1513
+ usageType: 'insertion'
1514
+ });
1515
+ if (out.insertionRemittance.customInstructions) {
1516
+ requestArgs.outputs[outIndex].insertionRemittance.customInstructions = await this.maybeEncryptMetadata(out.insertionRemittance.customInstructions);
1517
+ }
1518
+ }
1519
+ }
1520
+ return this.underlying.internalizeAction(...args);
1521
+ }
1522
+ async listOutputs(...args) {
1523
+ const [requestArgs, originator] = args;
1524
+ // Ensure the originator has permission for the basket.
1525
+ await this.ensureBasketAccess({
1526
+ originator: originator,
1527
+ basket: requestArgs.basket,
1528
+ reason: 'listOutputs',
1529
+ usageType: 'listing'
1530
+ });
1531
+ const results = await this.underlying.listOutputs(...args);
1532
+ // Transparently decrypt transaction metadata, if configured to do so.
1533
+ if (results.outputs) {
1534
+ for (let i = 0; i < results.outputs.length; i++) {
1535
+ if (results.outputs[i].customInstructions) {
1536
+ results.outputs[i].customInstructions = await this.maybeDecryptMetadata(results.outputs[i].customInstructions);
1537
+ }
1538
+ }
1539
+ }
1540
+ return results;
1541
+ }
1542
+ async relinquishOutput(...args) {
1543
+ const [requestArgs, originator] = args;
1544
+ await this.ensureBasketAccess({
1545
+ originator: originator,
1546
+ basket: requestArgs.basket,
1547
+ reason: 'relinquishOutput',
1548
+ usageType: 'removal'
1549
+ });
1550
+ return this.underlying.relinquishOutput(...args);
1551
+ }
1552
+ async getPublicKey(...args) {
1553
+ const [requestArgs, originator] = args;
1554
+ if (requestArgs.protocolID) {
1555
+ await this.ensureProtocolPermission({
1556
+ originator: originator,
1557
+ privileged: requestArgs.privileged,
1558
+ protocolID: requestArgs.protocolID,
1559
+ counterparty: requestArgs.counterparty || 'self',
1560
+ reason: requestArgs.privilegedReason,
1561
+ usageType: 'publicKey'
1562
+ });
1563
+ }
1564
+ if (requestArgs.identityKey) {
1565
+ // We also require a minimal protocol permission to retrieve the user's identity key
1566
+ await this.ensureProtocolPermission({
1567
+ originator: originator,
1568
+ privileged: requestArgs.privileged,
1569
+ protocolID: [1, 'identity key retrieval'],
1570
+ counterparty: 'self',
1571
+ reason: requestArgs.privilegedReason,
1572
+ usageType: 'identityKey'
1573
+ });
1574
+ }
1575
+ return this.underlying.getPublicKey(...args);
1576
+ }
1577
+ async revealCounterpartyKeyLinkage(...args) {
1578
+ const [requestArgs, originator] = args;
1579
+ await this.ensureProtocolPermission({
1580
+ originator: originator,
1581
+ privileged: requestArgs.privileged,
1582
+ protocolID: [2, `counterparty key linkage revelation ${requestArgs.counterparty}`],
1583
+ counterparty: requestArgs.verifier,
1584
+ reason: requestArgs.privilegedReason,
1585
+ usageType: 'linkageRevelation'
1586
+ });
1587
+ return this.underlying.revealCounterpartyKeyLinkage(...args);
1588
+ }
1589
+ async revealSpecificKeyLinkage(...args) {
1590
+ const [requestArgs, originator] = args;
1591
+ await this.ensureProtocolPermission({
1592
+ originator: originator,
1593
+ privileged: requestArgs.privileged,
1594
+ protocolID: [
1595
+ 2,
1596
+ `specific key linkage revelation ${requestArgs.protocolID[1]} ${requestArgs.protocolID[0] === 2 ? requestArgs.keyID : 'all'}`
1597
+ ],
1598
+ counterparty: requestArgs.verifier,
1599
+ reason: requestArgs.privilegedReason,
1600
+ usageType: 'linkageRevelation'
1601
+ });
1602
+ return this.underlying.revealSpecificKeyLinkage(...args);
1603
+ }
1604
+ async encrypt(...args) {
1605
+ const [requestArgs, originator] = args;
1606
+ await this.ensureProtocolPermission({
1607
+ originator: originator,
1608
+ protocolID: requestArgs.protocolID,
1609
+ privileged: requestArgs.privileged,
1610
+ counterparty: requestArgs.counterparty || 'self',
1611
+ reason: requestArgs.privilegedReason,
1612
+ usageType: 'encrypting'
1613
+ });
1614
+ return this.underlying.encrypt(...args);
1615
+ }
1616
+ async decrypt(...args) {
1617
+ const [requestArgs, originator] = args;
1618
+ await this.ensureProtocolPermission({
1619
+ originator: originator,
1620
+ privileged: requestArgs.privileged,
1621
+ protocolID: requestArgs.protocolID,
1622
+ counterparty: requestArgs.counterparty || 'self',
1623
+ reason: requestArgs.privilegedReason,
1624
+ usageType: 'encrypting'
1625
+ });
1626
+ return this.underlying.decrypt(...args);
1627
+ }
1628
+ async createHmac(...args) {
1629
+ const [requestArgs, originator] = args;
1630
+ await this.ensureProtocolPermission({
1631
+ originator: originator,
1632
+ privileged: requestArgs.privileged,
1633
+ protocolID: requestArgs.protocolID,
1634
+ counterparty: requestArgs.counterparty || 'self',
1635
+ reason: requestArgs.privilegedReason,
1636
+ usageType: 'hmac'
1637
+ });
1638
+ return this.underlying.createHmac(...args);
1639
+ }
1640
+ async verifyHmac(...args) {
1641
+ const [requestArgs, originator] = args;
1642
+ await this.ensureProtocolPermission({
1643
+ originator: originator,
1644
+ privileged: requestArgs.privileged,
1645
+ protocolID: requestArgs.protocolID,
1646
+ counterparty: requestArgs.counterparty || 'self',
1647
+ reason: requestArgs.privilegedReason,
1648
+ usageType: 'hmac'
1649
+ });
1650
+ return this.underlying.verifyHmac(...args);
1651
+ }
1652
+ async createSignature(...args) {
1653
+ const [requestArgs, originator] = args;
1654
+ await this.ensureProtocolPermission({
1655
+ originator: originator,
1656
+ privileged: requestArgs.privileged,
1657
+ protocolID: requestArgs.protocolID,
1658
+ counterparty: requestArgs.counterparty || 'self',
1659
+ reason: requestArgs.privilegedReason,
1660
+ usageType: 'signing'
1661
+ });
1662
+ return this.underlying.createSignature(...args);
1663
+ }
1664
+ async verifySignature(...args) {
1665
+ const [requestArgs, originator] = args;
1666
+ await this.ensureProtocolPermission({
1667
+ originator: originator,
1668
+ privileged: requestArgs.privileged,
1669
+ protocolID: requestArgs.protocolID,
1670
+ counterparty: requestArgs.counterparty || 'self',
1671
+ reason: requestArgs.privilegedReason,
1672
+ usageType: 'signing'
1673
+ });
1674
+ return this.underlying.verifySignature(...args);
1675
+ }
1676
+ async acquireCertificate(...args) {
1677
+ const [requestArgs, originator] = args;
1678
+ if (this.config.seekCertificateAcquisitionPermissions) {
1679
+ await this.ensureProtocolPermission({
1680
+ originator: originator,
1681
+ privileged: requestArgs.privileged,
1682
+ protocolID: [1, `certificate acquisition ${requestArgs.type}`],
1683
+ counterparty: 'self',
1684
+ reason: requestArgs.privilegedReason,
1685
+ usageType: 'generic'
1686
+ });
1687
+ }
1688
+ return this.underlying.acquireCertificate(...args);
1689
+ }
1690
+ async listCertificates(...args) {
1691
+ const [requestArgs, originator] = args;
1692
+ if (this.config.seekCertificateListingPermissions) {
1693
+ await this.ensureProtocolPermission({
1694
+ originator: originator,
1695
+ privileged: requestArgs.privileged,
1696
+ protocolID: [1, `certificate list`],
1697
+ counterparty: 'self',
1698
+ reason: requestArgs.privilegedReason,
1699
+ usageType: 'generic'
1700
+ });
1701
+ }
1702
+ return this.underlying.listCertificates(...args);
1703
+ }
1704
+ async proveCertificate(...args) {
1705
+ const [requestArgs, originator] = args;
1706
+ await this.ensureCertificateAccess({
1707
+ originator: originator,
1708
+ privileged: requestArgs.privileged,
1709
+ verifier: requestArgs.verifier,
1710
+ certType: requestArgs.certificate.type,
1711
+ fields: requestArgs.fieldsToReveal,
1712
+ reason: 'proveCertificate',
1713
+ usageType: 'disclosure'
1714
+ });
1715
+ return this.underlying.proveCertificate(...args);
1716
+ }
1717
+ async relinquishCertificate(...args) {
1718
+ const [requestArgs, originator] = args;
1719
+ if (this.config.seekCertificateRelinquishmentPermissions) {
1720
+ await this.ensureProtocolPermission({
1721
+ originator: originator,
1722
+ privileged: requestArgs.privileged ? true : false,
1723
+ protocolID: [1, `certificate relinquishment ${requestArgs.type}`],
1724
+ counterparty: 'self',
1725
+ reason: requestArgs.privilegedReason || 'relinquishCertificate',
1726
+ usageType: 'generic'
1727
+ });
1728
+ }
1729
+ return this.underlying.relinquishCertificate(...args);
1730
+ }
1731
+ async discoverByIdentityKey(...args) {
1732
+ const [_, originator] = args;
1733
+ if (this.config.seekPermissionsForIdentityResolution) {
1734
+ await this.ensureProtocolPermission({
1735
+ originator: originator,
1736
+ privileged: false,
1737
+ protocolID: [1, `identity resolution`],
1738
+ counterparty: 'self',
1739
+ reason: 'discoverByIdentityKey',
1740
+ usageType: 'generic'
1741
+ });
1742
+ }
1743
+ return this.underlying.discoverByIdentityKey(...args);
1744
+ }
1745
+ async discoverByAttributes(...args) {
1746
+ const [_, originator] = args;
1747
+ if (this.config.seekPermissionsForIdentityResolution) {
1748
+ await this.ensureProtocolPermission({
1749
+ originator: originator,
1750
+ privileged: false,
1751
+ protocolID: [1, `identity resolution`],
1752
+ counterparty: 'self',
1753
+ reason: 'discoverByAttributes',
1754
+ usageType: 'generic'
1755
+ });
1756
+ }
1757
+ return this.underlying.discoverByAttributes(...args);
1758
+ }
1759
+ async isAuthenticated(...args) {
1760
+ return this.underlying.isAuthenticated(...args);
1761
+ }
1762
+ async waitForAuthentication(...args) {
1763
+ return this.underlying.waitForAuthentication(...args);
1764
+ }
1765
+ async getHeight(...args) {
1766
+ return this.underlying.getHeight(...args);
1767
+ }
1768
+ async getHeaderForHeight(...args) {
1769
+ return this.underlying.getHeaderForHeight(...args);
1770
+ }
1771
+ async getNetwork(...args) {
1772
+ return this.underlying.getNetwork(...args);
1773
+ }
1774
+ async getVersion(...args) {
1775
+ return this.underlying.getVersion(...args);
1776
+ }
1777
+ /* ---------------------------------------------------------------------
1778
+ * 8) INTERNAL HELPER UTILITIES
1779
+ * --------------------------------------------------------------------- */
1780
+ /** Returns true if the specified origin is the admin originator. */
1781
+ isAdminOriginator(originator) {
1782
+ return originator === this.adminOriginator;
1783
+ }
1784
+ /**
1785
+ * Checks if the given protocol is admin-reserved per BRC-100 rules:
1786
+ *
1787
+ * - Must not start with `admin` (admin-reserved)
1788
+ * - Must not start with `p ` (allows for future specially permissioned protocols)
1789
+ *
1790
+ * If it violates these rules and the caller is not admin, we consider it "admin-only."
1791
+ */
1792
+ isAdminProtocol(proto) {
1793
+ const protocolName = proto[1];
1794
+ if (protocolName.startsWith('admin') || protocolName.startsWith('p ')) {
1795
+ return true;
1796
+ }
1797
+ return false;
1798
+ }
1799
+ /**
1800
+ * Checks if the given label is admin-reserved per BRC-100 rules:
1801
+ *
1802
+ * - Must not start with `admin` (admin-reserved)
1803
+ *
1804
+ * If it violates these rules and the caller is not admin, we consider it "admin-only."
1805
+ */
1806
+ isAdminLabel(label) {
1807
+ if (label.startsWith('admin')) {
1808
+ return true;
1809
+ }
1810
+ return false;
1811
+ }
1812
+ /**
1813
+ * Checks if the given basket is admin-reserved per BRC-100 rules:
1814
+ *
1815
+ * - Must not start with `admin`
1816
+ * - Must not be `default` (some wallets use this for internal operations)
1817
+ * - Must not start with `p ` (future specially permissioned baskets)
1818
+ */
1819
+ isAdminBasket(basket) {
1820
+ if (basket === 'default')
1821
+ return true;
1822
+ if (basket.startsWith('admin'))
1823
+ return true;
1824
+ if (basket.startsWith('p '))
1825
+ return true;
1826
+ return false;
1827
+ }
1828
+ /**
1829
+ * Builds a "map key" string so that identical requests (e.g. "protocol:domain:true:protoName:counterparty")
1830
+ * do not produce multiple user prompts.
1831
+ */
1832
+ buildRequestKey(r) {
1833
+ var _a, _b, _c, _d;
1834
+ switch (r.type) {
1835
+ case 'protocol':
1836
+ return `proto:${r.originator}:${!!r.privileged}:${(_a = r.protocolID) === null || _a === void 0 ? void 0 : _a.join(',')}:${r.counterparty}`;
1837
+ case 'basket':
1838
+ return `basket:${r.originator}:${r.basket}`;
1839
+ case 'certificate':
1840
+ return `cert:${r.originator}:${!!r.privileged}:${(_b = r.certificate) === null || _b === void 0 ? void 0 : _b.verifier}:${(_c = r.certificate) === null || _c === void 0 ? void 0 : _c.certType}:${(_d = r.certificate) === null || _d === void 0 ? void 0 : _d.fields.join('|')}`;
1841
+ case 'spending':
1842
+ return `spend:${r.originator}`;
1843
+ }
1844
+ }
1845
+ }
1846
+ exports.WalletPermissionsManager = WalletPermissionsManager;
1847
+ /* ---------------------------------------------------------------------
1848
+ * 4) SEARCH / DECODE / DECRYPT ON-CHAIN TOKENS (PushDrop Scripts)
1849
+ * --------------------------------------------------------------------- */
1850
+ /**
1851
+ * We will use a administrative "permission token encryption" protocol to store fields
1852
+ * in each permission's PushDrop script. This ensures that only the user's wallet
1853
+ * can decrypt them. In practice, this data is not super sensitive, but we still
1854
+ * follow the principle of least exposure.
1855
+ */
1856
+ WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL = [
1857
+ 2,
1858
+ 'admin permission token encryption'
1859
+ ];
1860
+ /**
1861
+ * Similarly, we will use a "metadata encryption" protocol to preserve the confidentiality
1862
+ * of transaction descriptions and input/output descriptions from lower storage layers.
1863
+ */
1864
+ WalletPermissionsManager.METADATA_ENCRYPTION_PROTOCOL = [
1865
+ 2,
1866
+ 'admin metadata encryption'
1867
+ ];
1868
+ //# sourceMappingURL=WalletPermissionsManager.js.map