@bopen-io/wallet-toolbox 2.1.21-parity-fix.2 → 2.6.2-brc153.2
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.
- package/CHANGELOG.md +232 -6
- package/LICENSE.txt +58 -0
- package/README.md +236 -47
- package/docs/README.md +3 -1
- package/docs/action-batch-planning.md +220 -0
- package/docs/authentication-observability.md +106 -0
- package/docs/client.md +55 -14
- package/docs/managed-change-policy.md +79 -0
- package/docs/monitor.md +3 -2
- package/docs/setup.md +24 -4
- package/docs/storage.md +16 -6
- package/docs/wallet.md +55 -14
- package/out/src/CWIStyleWalletManager.d.ts +122 -12
- package/out/src/CWIStyleWalletManager.d.ts.map +1 -1
- package/out/src/CWIStyleWalletManager.js +1006 -461
- package/out/src/CWIStyleWalletManager.js.map +1 -1
- package/out/src/Setup.d.ts +13 -6
- package/out/src/Setup.d.ts.map +1 -1
- package/out/src/Setup.js +15 -16
- package/out/src/Setup.js.map +1 -1
- package/out/src/SetupClient.d.ts +8 -6
- package/out/src/SetupClient.d.ts.map +1 -1
- package/out/src/SetupClient.js +11 -12
- package/out/src/SetupClient.js.map +1 -1
- package/out/src/SetupWallet.d.ts +6 -0
- package/out/src/SetupWallet.d.ts.map +1 -1
- package/out/src/ShamirWalletManager.d.ts +5 -5
- package/out/src/ShamirWalletManager.d.ts.map +1 -1
- package/out/src/ShamirWalletManager.js +16 -9
- package/out/src/ShamirWalletManager.js.map +1 -1
- package/out/src/SimpleWalletManager.d.ts +12 -2
- package/out/src/SimpleWalletManager.d.ts.map +1 -1
- package/out/src/SimpleWalletManager.js +73 -31
- package/out/src/SimpleWalletManager.js.map +1 -1
- package/out/src/Wallet.d.ts +88 -14
- package/out/src/Wallet.d.ts.map +1 -1
- package/out/src/Wallet.js +410 -249
- package/out/src/Wallet.js.map +1 -1
- package/out/src/WalletAuthenticationManager.d.ts +31 -7
- package/out/src/WalletAuthenticationManager.d.ts.map +1 -1
- package/out/src/WalletAuthenticationManager.js +219 -35
- package/out/src/WalletAuthenticationManager.js.map +1 -1
- package/out/src/WalletLogger.d.ts.map +1 -1
- package/out/src/WalletLogger.js +45 -32
- package/out/src/WalletLogger.js.map +1 -1
- package/out/src/WalletPermissionsManager.d.ts +163 -19
- package/out/src/WalletPermissionsManager.d.ts.map +1 -1
- package/out/src/WalletPermissionsManager.js +1232 -1180
- package/out/src/WalletPermissionsManager.js.map +1 -1
- package/out/src/WalletSettingsManager.d.ts +2 -2
- package/out/src/WalletSettingsManager.d.ts.map +1 -1
- package/out/src/WalletSettingsManager.js +3 -0
- package/out/src/WalletSettingsManager.js.map +1 -1
- package/out/src/entropy/EntropyCollector.d.ts +1 -1
- package/out/src/entropy/EntropyCollector.d.ts.map +1 -1
- package/out/src/entropy/EntropyCollector.js +18 -20
- package/out/src/entropy/EntropyCollector.js.map +1 -1
- package/out/src/fundWalletP2PKH.d.ts +2 -2
- package/out/src/fundWalletP2PKH.d.ts.map +1 -1
- package/out/src/fundWalletP2PKH.js +15 -15
- package/out/src/fundWalletP2PKH.js.map +1 -1
- package/out/src/index.all.d.ts +2 -0
- package/out/src/index.all.d.ts.map +1 -1
- package/out/src/index.all.js +2 -0
- package/out/src/index.all.js.map +1 -1
- package/out/src/index.client.d.ts +2 -0
- package/out/src/index.client.d.ts.map +1 -1
- package/out/src/index.client.js +2 -0
- package/out/src/index.client.js.map +1 -1
- package/out/src/index.mobile.d.ts +3 -0
- package/out/src/index.mobile.d.ts.map +1 -1
- package/out/src/index.mobile.js +3 -0
- package/out/src/index.mobile.js.map +1 -1
- package/out/src/mockchain/MockChainMigrations.d.ts +3 -3
- package/out/src/mockchain/MockChainMigrations.d.ts.map +1 -1
- package/out/src/mockchain/MockChainMigrations.js +1 -1
- package/out/src/mockchain/MockChainMigrations.js.map +1 -1
- package/out/src/mockchain/MockChainStorage.d.ts.map +1 -1
- package/out/src/mockchain/MockChainStorage.js +9 -8
- package/out/src/mockchain/MockChainStorage.js.map +1 -1
- package/out/src/mockchain/MockChainTracker.d.ts.map +1 -1
- package/out/src/mockchain/MockChainTracker.js +12 -10
- package/out/src/mockchain/MockChainTracker.js.map +1 -1
- package/out/src/mockchain/MockMiner.d.ts.map +1 -1
- package/out/src/mockchain/MockMiner.js +5 -5
- package/out/src/mockchain/MockMiner.js.map +1 -1
- package/out/src/mockchain/MockServices.d.ts +13 -0
- package/out/src/mockchain/MockServices.d.ts.map +1 -1
- package/out/src/mockchain/MockServices.js +232 -283
- package/out/src/mockchain/MockServices.js.map +1 -1
- package/out/src/mockchain/merkleTree.d.ts.map +1 -1
- package/out/src/mockchain/merkleTree.js +61 -57
- package/out/src/mockchain/merkleTree.js.map +1 -1
- package/out/src/monitor/Monitor.d.ts +24 -4
- package/out/src/monitor/Monitor.d.ts.map +1 -1
- package/out/src/monitor/Monitor.js +158 -148
- package/out/src/monitor/Monitor.js.map +1 -1
- package/out/src/monitor/MonitorDaemon.d.ts +5 -2
- package/out/src/monitor/MonitorDaemon.d.ts.map +1 -1
- package/out/src/monitor/MonitorDaemon.js +79 -69
- package/out/src/monitor/MonitorDaemon.js.map +1 -1
- package/out/src/monitor/index.all.js.map +1 -1
- package/out/src/monitor/tasks/TaskArcSSE.d.ts +12 -5
- package/out/src/monitor/tasks/TaskArcSSE.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskArcSSE.js +143 -135
- package/out/src/monitor/tasks/TaskArcSSE.js.map +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.d.ts +6 -4
- package/out/src/monitor/tasks/TaskCheckForProofs.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.js +141 -129
- package/out/src/monitor/tasks/TaskCheckForProofs.js.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.d.ts +63 -3
- package/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.js +103 -13
- package/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -1
- package/out/src/monitor/tasks/TaskCleanupActionBatches.d.ts +13 -0
- package/out/src/monitor/tasks/TaskCleanupActionBatches.d.ts.map +1 -0
- package/out/src/monitor/tasks/TaskCleanupActionBatches.js +24 -0
- package/out/src/monitor/tasks/TaskCleanupActionBatches.js.map +1 -0
- package/out/src/monitor/tasks/TaskClock.d.ts +2 -2
- package/out/src/monitor/tasks/TaskClock.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskClock.js +4 -3
- package/out/src/monitor/tasks/TaskClock.js.map +1 -1
- package/out/src/monitor/tasks/TaskFailAbandoned.d.ts +1 -1
- package/out/src/monitor/tasks/TaskFailAbandoned.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskFailAbandoned.js +2 -1
- package/out/src/monitor/tasks/TaskFailAbandoned.js.map +1 -1
- package/out/src/monitor/tasks/TaskMineBlock.d.ts +4 -2
- package/out/src/monitor/tasks/TaskMineBlock.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskMineBlock.js +5 -2
- package/out/src/monitor/tasks/TaskMineBlock.js.map +1 -1
- package/out/src/monitor/tasks/TaskMonitorCallHistory.d.ts +1 -1
- package/out/src/monitor/tasks/TaskMonitorCallHistory.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskMonitorCallHistory.js +3 -2
- package/out/src/monitor/tasks/TaskMonitorCallHistory.js.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.d.ts +5 -4
- package/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.js +22 -8
- package/out/src/monitor/tasks/TaskNewHeader.js.map +1 -1
- package/out/src/monitor/tasks/TaskPurge.d.ts +4 -2
- package/out/src/monitor/tasks/TaskPurge.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskPurge.js +9 -5
- package/out/src/monitor/tasks/TaskPurge.js.map +1 -1
- package/out/src/monitor/tasks/TaskReorg.d.ts +1 -1
- package/out/src/monitor/tasks/TaskReorg.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReorg.js +6 -4
- package/out/src/monitor/tasks/TaskReorg.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.d.ts +4 -2
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.js +22 -17
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewProvenTxs.d.ts +4 -2
- package/out/src/monitor/tasks/TaskReviewProvenTxs.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewProvenTxs.js +12 -5
- package/out/src/monitor/tasks/TaskReviewProvenTxs.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewStatus.d.ts +4 -2
- package/out/src/monitor/tasks/TaskReviewStatus.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewStatus.js +16 -7
- package/out/src/monitor/tasks/TaskReviewStatus.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.d.ts +4 -2
- package/out/src/monitor/tasks/TaskReviewUtxos.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.js +8 -2
- package/out/src/monitor/tasks/TaskReviewUtxos.js.map +1 -1
- package/out/src/monitor/tasks/TaskSendWaiting.d.ts +4 -1
- package/out/src/monitor/tasks/TaskSendWaiting.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskSendWaiting.js +63 -50
- package/out/src/monitor/tasks/TaskSendWaiting.js.map +1 -1
- package/out/src/monitor/tasks/TaskSyncWhenIdle.d.ts +2 -2
- package/out/src/monitor/tasks/TaskSyncWhenIdle.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskSyncWhenIdle.js +4 -6
- package/out/src/monitor/tasks/TaskSyncWhenIdle.js.map +1 -1
- package/out/src/monitor/tasks/TaskUnFail.d.ts +4 -2
- package/out/src/monitor/tasks/TaskUnFail.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskUnFail.js +13 -67
- package/out/src/monitor/tasks/TaskUnFail.js.map +1 -1
- package/out/src/monitor/tasks/WalletMonitorTask.d.ts.map +1 -1
- package/out/src/monitor/tasks/WalletMonitorTask.js +10 -5
- package/out/src/monitor/tasks/WalletMonitorTask.js.map +1 -1
- package/out/src/monitor/tasks/index.all.d.ts +1 -0
- package/out/src/monitor/tasks/index.all.d.ts.map +1 -1
- package/out/src/monitor/tasks/index.all.js +1 -0
- package/out/src/monitor/tasks/index.all.js.map +1 -1
- package/out/src/sdk/ActionBatch.interfaces.d.ts +159 -0
- package/out/src/sdk/ActionBatch.interfaces.d.ts.map +1 -0
- package/out/src/sdk/ActionBatch.interfaces.js +3 -0
- package/out/src/sdk/ActionBatch.interfaces.js.map +1 -0
- package/out/src/sdk/CertOpsWallet.d.ts +3 -3
- package/out/src/sdk/CertOpsWallet.d.ts.map +1 -1
- package/out/src/sdk/PrivilegedKeyManager.d.ts +3 -3
- package/out/src/sdk/PrivilegedKeyManager.d.ts.map +1 -1
- package/out/src/sdk/PrivilegedKeyManager.js +75 -50
- package/out/src/sdk/PrivilegedKeyManager.js.map +1 -1
- package/out/src/sdk/WERR_errors.d.ts +3 -3
- package/out/src/sdk/WERR_errors.d.ts.map +1 -1
- package/out/src/sdk/WERR_errors.js +29 -14
- package/out/src/sdk/WERR_errors.js.map +1 -1
- package/out/src/sdk/WalletError.d.ts +4 -1
- package/out/src/sdk/WalletError.d.ts.map +1 -1
- package/out/src/sdk/WalletError.js +63 -58
- package/out/src/sdk/WalletError.js.map +1 -1
- package/out/src/sdk/WalletErrorFromJson.d.ts.map +1 -1
- package/out/src/sdk/WalletErrorFromJson.js +1 -3
- package/out/src/sdk/WalletErrorFromJson.js.map +1 -1
- package/out/src/sdk/WalletServices.interfaces.d.ts +45 -20
- package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
- package/out/src/sdk/WalletStorage.interfaces.d.ts +92 -64
- package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
- package/out/src/sdk/index.d.ts +1 -0
- package/out/src/sdk/index.d.ts.map +1 -1
- package/out/src/sdk/index.js +1 -0
- package/out/src/sdk/index.js.map +1 -1
- package/out/src/sdk/types.d.ts +14 -5
- package/out/src/sdk/types.d.ts.map +1 -1
- package/out/src/sdk/types.js +13 -4
- package/out/src/sdk/types.js.map +1 -1
- package/out/src/services/ServiceCollection.d.ts +6 -6
- package/out/src/services/ServiceCollection.d.ts.map +1 -1
- package/out/src/services/ServiceCollection.js +14 -9
- package/out/src/services/ServiceCollection.js.map +1 -1
- package/out/src/services/Services.d.ts +16 -2
- package/out/src/services/Services.d.ts.map +1 -1
- package/out/src/services/Services.js +320 -241
- package/out/src/services/Services.js.map +1 -1
- package/out/src/services/chaintracker/BHServiceClient.d.ts +7 -7
- package/out/src/services/chaintracker/BHServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/BHServiceClient.js +22 -16
- package/out/src/services/chaintracker/BHServiceClient.js.map +1 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.d.ts +5 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.d.ts.map +1 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.js +61 -19
- package/out/src/services/chaintracker/ChaintracksChainTracker.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts +8 -6
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.js +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BulkIngestorApi.d.ts +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BulkStorageApi.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/ChaintracksClientApi.d.ts +11 -0
- package/out/src/services/chaintracker/chaintracks/Api/ChaintracksClientApi.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts +29 -10
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js +369 -259
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.d.ts +6 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.js +39 -44
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts +3 -3
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js +24 -15
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.d.ts +64 -0
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.js +318 -0
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.js +9 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDN.d.ts +1 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDN.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDN.js +10 -3
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDN.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDNBabbage.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDNBabbage.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorChaintracks.d.ts +27 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorChaintracks.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorChaintracks.js +64 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorChaintracks.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.js +6 -5
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainWs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainWs.js +3 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainWs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.js +4 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.d.ts +24 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.js +68 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.d.ts +2 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.js +3 -10
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.d.ts +13 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.js +50 -10
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainWs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainWs.js +4 -3
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainWs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.d.ts +14 -4
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.js +120 -143
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.d.ts +22 -8
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.js +106 -54
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/BulkStorageBase.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/BulkStorageBase.js +12 -17
- package/out/src/services/chaintracker/chaintracks/Storage/BulkStorageBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksKnexMigrations.d.ts +3 -3
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksKnexMigrations.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksKnexMigrations.js +15 -14
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksKnexMigrations.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.d.ts +3 -0
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.js +85 -66
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.d.ts +4 -0
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js +128 -101
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.d.ts +6 -2
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.js +170 -158
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageMemory.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageMemory.js +0 -21
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageMemory.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.d.ts +9 -2
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.js +142 -92
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/configureChaintracksIngestors.d.ts +58 -0
- package/out/src/services/chaintracker/chaintracks/configureChaintracksIngestors.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/configureChaintracksIngestors.js +143 -28
- package/out/src/services/chaintracker/chaintracks/configureChaintracksIngestors.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/configureKnexChaintracks.d.ts +18 -0
- package/out/src/services/chaintracker/chaintracks/configureKnexChaintracks.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/configureKnexChaintracks.js +24 -0
- package/out/src/services/chaintracker/chaintracks/configureKnexChaintracks.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.d.ts +2 -3
- package/out/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.js +4 -22
- package/out/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.d.ts +2 -4
- package/out/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.js +14 -29
- package/out/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.d.ts +2 -3
- package/out/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.js +4 -22
- package/out/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createIdbChaintracks.d.ts +2 -1
- package/out/src/services/chaintracker/chaintracks/createIdbChaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createIdbChaintracks.js +3 -15
- package/out/src/services/chaintracker/chaintracks/createIdbChaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createKnexChaintracks.d.ts +2 -2
- package/out/src/services/chaintracker/chaintracks/createKnexChaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createKnexChaintracks.js +3 -15
- package/out/src/services/chaintracker/chaintracks/createKnexChaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createNoDbChaintracks.d.ts +2 -1
- package/out/src/services/chaintracker/chaintracks/createNoDbChaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createNoDbChaintracks.js +3 -15
- package/out/src/services/chaintracker/chaintracks/createNoDbChaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/index.mobile.d.ts +6 -1
- package/out/src/services/chaintracker/chaintracks/index.mobile.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/index.mobile.js +5 -0
- package/out/src/services/chaintracker/chaintracks/index.mobile.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts +8 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js +282 -252
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataReader.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataReader.js +12 -7
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataReader.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFilesReader.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFilesReader.js +53 -29
- package/out/src/services/chaintracker/chaintracks/util/BulkFilesReader.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkHeaderFile.d.ts +5 -5
- package/out/src/services/chaintracker/chaintracks/util/BulkHeaderFile.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkHeaderFile.js +34 -11
- package/out/src/services/chaintracker/chaintracks/util/BulkHeaderFile.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts +8 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.js +54 -13
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.d.ts +10 -12
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.js +30 -34
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/HeightRange.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/HeightRange.js +28 -18
- package/out/src/services/chaintracker/chaintracks/util/HeightRange.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/SingleWriterMultiReaderLock.d.ts +2 -2
- package/out/src/services/chaintracker/chaintracks/util/SingleWriterMultiReaderLock.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/SingleWriterMultiReaderLock.js +4 -6
- package/out/src/services/chaintracker/chaintracks/util/SingleWriterMultiReaderLock.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts +2 -12
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js +72 -63
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js +4 -2
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.js +9 -10
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.js.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.d.ts +33 -1
- package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.js +94 -15
- package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/out/src/services/networkConfig.d.ts +18 -0
- package/out/src/services/networkConfig.d.ts.map +1 -0
- package/out/src/services/networkConfig.js +92 -0
- package/out/src/services/networkConfig.js.map +1 -0
- package/out/src/services/providers/ARC.d.ts +8 -0
- package/out/src/services/providers/ARC.d.ts.map +1 -1
- package/out/src/services/providers/ARC.js +167 -92
- package/out/src/services/providers/ARC.js.map +1 -1
- package/out/src/services/providers/ArcSSEClient.d.ts +1 -0
- package/out/src/services/providers/ArcSSEClient.d.ts.map +1 -1
- package/out/src/services/providers/ArcSSEClient.js +21 -17
- package/out/src/services/providers/ArcSSEClient.js.map +1 -1
- package/out/src/services/providers/Arcade.d.ts +77 -0
- package/out/src/services/providers/Arcade.d.ts.map +1 -0
- package/out/src/services/providers/Arcade.js +356 -0
- package/out/src/services/providers/Arcade.js.map +1 -0
- package/out/src/services/providers/Bitails.d.ts.map +1 -1
- package/out/src/services/providers/Bitails.js +128 -103
- package/out/src/services/providers/Bitails.js.map +1 -1
- package/out/src/services/providers/SdkWhatsOnChain.d.ts +1 -1
- package/out/src/services/providers/SdkWhatsOnChain.d.ts.map +1 -1
- package/out/src/services/providers/SdkWhatsOnChain.js +18 -3
- package/out/src/services/providers/SdkWhatsOnChain.js.map +1 -1
- package/out/src/services/providers/WhatsOnChain.d.ts +10 -2
- package/out/src/services/providers/WhatsOnChain.d.ts.map +1 -1
- package/out/src/services/providers/WhatsOnChain.js +145 -236
- package/out/src/services/providers/WhatsOnChain.js.map +1 -1
- package/out/src/services/providers/exchangeRates.d.ts.map +1 -1
- package/out/src/services/providers/exchangeRates.js +4 -4
- package/out/src/services/providers/exchangeRates.js.map +1 -1
- package/out/src/services/providers/getBeefForTxid.d.ts +1 -1
- package/out/src/services/providers/getBeefForTxid.d.ts.map +1 -1
- package/out/src/services/providers/getBeefForTxid.js +2 -1
- package/out/src/services/providers/getBeefForTxid.js.map +1 -1
- package/out/src/services/providers/whatsOnChainHelpers.d.ts +68 -0
- package/out/src/services/providers/whatsOnChainHelpers.d.ts.map +1 -0
- package/out/src/services/providers/whatsOnChainHelpers.js +147 -0
- package/out/src/services/providers/whatsOnChainHelpers.js.map +1 -0
- package/out/src/signer/WalletSigner.d.ts.map +1 -1
- package/out/src/signer/WalletSigner.js +4 -1
- package/out/src/signer/WalletSigner.js.map +1 -1
- package/out/src/signer/actionBatch/ActionBatchPlanner.d.ts +29 -0
- package/out/src/signer/actionBatch/ActionBatchPlanner.d.ts.map +1 -0
- package/out/src/signer/actionBatch/ActionBatchPlanner.js +346 -0
- package/out/src/signer/actionBatch/ActionBatchPlanner.js.map +1 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.d.ts +33 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.d.ts.map +1 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.js +869 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.js.map +1 -0
- package/out/src/signer/actionBatch/actionBatchBootstrap.d.ts +11 -0
- package/out/src/signer/actionBatch/actionBatchBootstrap.d.ts.map +1 -0
- package/out/src/signer/actionBatch/actionBatchBootstrap.js +38 -0
- package/out/src/signer/actionBatch/actionBatchBootstrap.js.map +1 -0
- package/out/src/signer/methods/acquireDirectCertificate.js +2 -3
- package/out/src/signer/methods/acquireDirectCertificate.js.map +1 -1
- package/out/src/signer/methods/buildSignableTransaction.d.ts +54 -0
- package/out/src/signer/methods/buildSignableTransaction.d.ts.map +1 -1
- package/out/src/signer/methods/buildSignableTransaction.js +215 -100
- package/out/src/signer/methods/buildSignableTransaction.js.map +1 -1
- package/out/src/signer/methods/completeSignedTransaction.d.ts +3 -7
- package/out/src/signer/methods/completeSignedTransaction.d.ts.map +1 -1
- package/out/src/signer/methods/completeSignedTransaction.js +78 -80
- package/out/src/signer/methods/completeSignedTransaction.js.map +1 -1
- package/out/src/signer/methods/createAction.d.ts.map +1 -1
- package/out/src/signer/methods/createAction.js +81 -41
- package/out/src/signer/methods/createAction.js.map +1 -1
- package/out/src/signer/methods/internalizeAction.d.ts +16 -5
- package/out/src/signer/methods/internalizeAction.d.ts.map +1 -1
- package/out/src/signer/methods/internalizeAction.js +34 -18
- package/out/src/signer/methods/internalizeAction.js.map +1 -1
- package/out/src/signer/methods/proveCertificate.js +1 -1
- package/out/src/signer/methods/proveCertificate.js.map +1 -1
- package/out/src/signer/methods/resultBeef.d.ts +4 -0
- package/out/src/signer/methods/resultBeef.d.ts.map +1 -0
- package/out/src/signer/methods/resultBeef.js +12 -0
- package/out/src/signer/methods/resultBeef.js.map +1 -0
- package/out/src/signer/methods/signAction.d.ts.map +1 -1
- package/out/src/signer/methods/signAction.js +42 -15
- package/out/src/signer/methods/signAction.js.map +1 -1
- package/out/src/signer/methods/verifyUnlockScripts.d.ts +17 -0
- package/out/src/signer/methods/verifyUnlockScripts.d.ts.map +1 -0
- package/out/src/signer/methods/verifyUnlockScripts.js +373 -0
- package/out/src/signer/methods/verifyUnlockScripts.js.map +1 -0
- package/out/src/storage/StorageIdb.d.ts +51 -6
- package/out/src/storage/StorageIdb.d.ts.map +1 -1
- package/out/src/storage/StorageIdb.js +929 -1324
- package/out/src/storage/StorageIdb.js.map +1 -1
- package/out/src/storage/StorageKnex.d.ts +51 -3
- package/out/src/storage/StorageKnex.d.ts.map +1 -1
- package/out/src/storage/StorageKnex.js +751 -314
- package/out/src/storage/StorageKnex.js.map +1 -1
- package/out/src/storage/StorageProvider.d.ts +117 -2
- package/out/src/storage/StorageProvider.d.ts.map +1 -1
- package/out/src/storage/StorageProvider.js +735 -254
- package/out/src/storage/StorageProvider.js.map +1 -1
- package/out/src/storage/StorageReader.d.ts +13 -5
- package/out/src/storage/StorageReader.d.ts.map +1 -1
- package/out/src/storage/StorageReader.js +21 -15
- package/out/src/storage/StorageReader.js.map +1 -1
- package/out/src/storage/StorageReaderWriter.d.ts +0 -1
- package/out/src/storage/StorageReaderWriter.d.ts.map +1 -1
- package/out/src/storage/StorageReaderWriter.js +32 -35
- package/out/src/storage/StorageReaderWriter.js.map +1 -1
- package/out/src/storage/StorageSyncReader.d.ts.map +1 -1
- package/out/src/storage/StorageSyncReader.js +6 -4
- package/out/src/storage/StorageSyncReader.js.map +1 -1
- package/out/src/storage/WalletStorageManager.d.ts +13 -0
- package/out/src/storage/WalletStorageManager.d.ts.map +1 -1
- package/out/src/storage/WalletStorageManager.js +179 -103
- package/out/src/storage/WalletStorageManager.js.map +1 -1
- package/out/src/storage/adminServer/adminServer.d.ts +80 -1
- package/out/src/storage/adminServer/adminServer.d.ts.map +1 -1
- package/out/src/storage/adminServer/adminServer.js +90 -72
- package/out/src/storage/adminServer/adminServer.js.map +1 -1
- package/out/src/storage/adminServer/adminUi.d.ts.map +1 -1
- package/out/src/storage/adminServer/adminUi.js.map +1 -1
- package/out/src/storage/idbHelpers.d.ts +44 -0
- package/out/src/storage/idbHelpers.d.ts.map +1 -0
- package/out/src/storage/idbHelpers.js +395 -0
- package/out/src/storage/idbHelpers.js.map +1 -0
- package/out/src/storage/index.all.d.ts +6 -0
- package/out/src/storage/index.all.d.ts.map +1 -1
- package/out/src/storage/index.all.js +6 -0
- package/out/src/storage/index.all.js.map +1 -1
- package/out/src/storage/index.client.d.ts +4 -0
- package/out/src/storage/index.client.d.ts.map +1 -1
- package/out/src/storage/index.client.js +4 -0
- package/out/src/storage/index.client.js.map +1 -1
- package/out/src/storage/index.mobile.d.ts +3 -0
- package/out/src/storage/index.mobile.d.ts.map +1 -1
- package/out/src/storage/index.mobile.js +3 -0
- package/out/src/storage/index.mobile.js.map +1 -1
- package/out/src/storage/methods/ListActionsSpecOp.d.ts +6 -1
- package/out/src/storage/methods/ListActionsSpecOp.d.ts.map +1 -1
- package/out/src/storage/methods/ListActionsSpecOp.js +75 -9
- package/out/src/storage/methods/ListActionsSpecOp.js.map +1 -1
- package/out/src/storage/methods/ListOutputsSpecOp.d.ts +2 -0
- package/out/src/storage/methods/ListOutputsSpecOp.d.ts.map +1 -1
- package/out/src/storage/methods/ListOutputsSpecOp.js +43 -29
- package/out/src/storage/methods/ListOutputsSpecOp.js.map +1 -1
- package/out/src/storage/methods/actionBatch.d.ts +15 -0
- package/out/src/storage/methods/actionBatch.d.ts.map +1 -0
- package/out/src/storage/methods/actionBatch.js +725 -0
- package/out/src/storage/methods/actionBatch.js.map +1 -0
- package/out/src/storage/methods/actionBatchBlobs.d.ts +15 -0
- package/out/src/storage/methods/actionBatchBlobs.d.ts.map +1 -0
- package/out/src/storage/methods/actionBatchBlobs.js +184 -0
- package/out/src/storage/methods/actionBatchBlobs.js.map +1 -0
- package/out/src/storage/methods/actionBatchValidation.d.ts +17 -0
- package/out/src/storage/methods/actionBatchValidation.d.ts.map +1 -0
- package/out/src/storage/methods/actionBatchValidation.js +416 -0
- package/out/src/storage/methods/actionBatchValidation.js.map +1 -0
- package/out/src/storage/methods/actionPlanning.d.ts +26 -0
- package/out/src/storage/methods/actionPlanning.d.ts.map +1 -0
- package/out/src/storage/methods/actionPlanning.js +103 -0
- package/out/src/storage/methods/actionPlanning.js.map +1 -0
- package/out/src/storage/methods/attemptToPostReqsToNetwork.d.ts +63 -1
- package/out/src/storage/methods/attemptToPostReqsToNetwork.d.ts.map +1 -1
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js +245 -92
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js.map +1 -1
- package/out/src/storage/methods/availableManagedChange.d.ts +11 -0
- package/out/src/storage/methods/availableManagedChange.d.ts.map +1 -0
- package/out/src/storage/methods/availableManagedChange.js +25 -0
- package/out/src/storage/methods/availableManagedChange.js.map +1 -0
- package/out/src/storage/methods/createAction.d.ts +1 -1
- package/out/src/storage/methods/createAction.d.ts.map +1 -1
- package/out/src/storage/methods/createAction.js +783 -416
- package/out/src/storage/methods/createAction.js.map +1 -1
- package/out/src/storage/methods/generateChange.d.ts +2 -2
- package/out/src/storage/methods/generateChange.d.ts.map +1 -1
- package/out/src/storage/methods/generateChange.js +188 -127
- package/out/src/storage/methods/generateChange.js.map +1 -1
- package/out/src/storage/methods/getBeefForTransaction.d.ts +7 -0
- package/out/src/storage/methods/getBeefForTransaction.d.ts.map +1 -1
- package/out/src/storage/methods/getBeefForTransaction.js +291 -63
- package/out/src/storage/methods/getBeefForTransaction.js.map +1 -1
- package/out/src/storage/methods/getSyncChunk.d.ts.map +1 -1
- package/out/src/storage/methods/getSyncChunk.js +11 -8
- package/out/src/storage/methods/getSyncChunk.js.map +1 -1
- package/out/src/storage/methods/internalizeAction.d.ts +77 -6
- package/out/src/storage/methods/internalizeAction.d.ts.map +1 -1
- package/out/src/storage/methods/internalizeAction.js +372 -139
- package/out/src/storage/methods/internalizeAction.js.map +1 -1
- package/out/src/storage/methods/listActionsIdb.d.ts.map +1 -1
- package/out/src/storage/methods/listActionsIdb.js +87 -110
- package/out/src/storage/methods/listActionsIdb.js.map +1 -1
- package/out/src/storage/methods/listActionsKnex.d.ts +1 -1
- package/out/src/storage/methods/listActionsKnex.d.ts.map +1 -1
- package/out/src/storage/methods/listActionsKnex.js +97 -118
- package/out/src/storage/methods/listActionsKnex.js.map +1 -1
- package/out/src/storage/methods/listCertificates.d.ts +2 -2
- package/out/src/storage/methods/listCertificates.d.ts.map +1 -1
- package/out/src/storage/methods/listCertificates.js +8 -8
- package/out/src/storage/methods/listCertificates.js.map +1 -1
- package/out/src/storage/methods/listOutputsIdb.d.ts +1 -1
- package/out/src/storage/methods/listOutputsIdb.d.ts.map +1 -1
- package/out/src/storage/methods/listOutputsIdb.js +144 -150
- package/out/src/storage/methods/listOutputsIdb.js.map +1 -1
- package/out/src/storage/methods/listOutputsKnex.d.ts +2 -2
- package/out/src/storage/methods/listOutputsKnex.d.ts.map +1 -1
- package/out/src/storage/methods/listOutputsKnex.js +217 -246
- package/out/src/storage/methods/listOutputsKnex.js.map +1 -1
- package/out/src/storage/methods/managedChange.d.ts +26 -0
- package/out/src/storage/methods/managedChange.d.ts.map +1 -0
- package/out/src/storage/methods/managedChange.js +42 -0
- package/out/src/storage/methods/managedChange.js.map +1 -0
- package/out/src/storage/methods/offsetKey.d.ts +1 -1
- package/out/src/storage/methods/offsetKey.d.ts.map +1 -1
- package/out/src/storage/methods/offsetKey.js +3 -6
- package/out/src/storage/methods/offsetKey.js.map +1 -1
- package/out/src/storage/methods/processAction.d.ts +2 -11
- package/out/src/storage/methods/processAction.d.ts.map +1 -1
- package/out/src/storage/methods/processAction.js +173 -106
- package/out/src/storage/methods/processAction.js.map +1 -1
- package/out/src/storage/methods/purgeData.d.ts +1 -1
- package/out/src/storage/methods/purgeData.d.ts.map +1 -1
- package/out/src/storage/methods/purgeData.js +169 -172
- package/out/src/storage/methods/purgeData.js.map +1 -1
- package/out/src/storage/methods/purgeDataIdb.d.ts +1 -1
- package/out/src/storage/methods/purgeDataIdb.d.ts.map +1 -1
- package/out/src/storage/methods/purgeDataIdb.js +2 -2
- package/out/src/storage/methods/purgeDataIdb.js.map +1 -1
- package/out/src/storage/methods/reviewStatus.d.ts +4 -3
- package/out/src/storage/methods/reviewStatus.d.ts.map +1 -1
- package/out/src/storage/methods/reviewStatus.js +54 -14
- package/out/src/storage/methods/reviewStatus.js.map +1 -1
- package/out/src/storage/methods/reviewStatusIdb.d.ts +3 -3
- package/out/src/storage/methods/reviewStatusIdb.d.ts.map +1 -1
- package/out/src/storage/methods/reviewStatusIdb.js +54 -13
- package/out/src/storage/methods/reviewStatusIdb.js.map +1 -1
- package/out/src/storage/methods/utils.Buffer.d.ts.map +1 -1
- package/out/src/storage/methods/utils.Buffer.js.map +1 -1
- package/out/src/storage/methods/utils.d.ts.map +1 -1
- package/out/src/storage/methods/utils.js +7 -1
- package/out/src/storage/methods/utils.js.map +1 -1
- package/out/src/storage/portable/index.d.ts +55 -0
- package/out/src/storage/portable/index.d.ts.map +1 -0
- package/out/src/storage/portable/index.js +872 -0
- package/out/src/storage/portable/index.js.map +1 -0
- package/out/src/storage/remoting/BinaryJson.d.ts +10 -0
- package/out/src/storage/remoting/BinaryJson.d.ts.map +1 -0
- package/out/src/storage/remoting/BinaryJson.js +218 -0
- package/out/src/storage/remoting/BinaryJson.js.map +1 -0
- package/out/src/storage/remoting/KnexPaymentReplayStore.d.ts +12 -0
- package/out/src/storage/remoting/KnexPaymentReplayStore.d.ts.map +1 -0
- package/out/src/storage/remoting/KnexPaymentReplayStore.js +46 -0
- package/out/src/storage/remoting/KnexPaymentReplayStore.js.map +1 -0
- package/out/src/storage/remoting/KnexSessionManager.d.ts +57 -0
- package/out/src/storage/remoting/KnexSessionManager.d.ts.map +1 -0
- package/out/src/storage/remoting/KnexSessionManager.js +256 -0
- package/out/src/storage/remoting/KnexSessionManager.js.map +1 -0
- package/out/src/storage/remoting/RateLimitPolicy.d.ts +10 -0
- package/out/src/storage/remoting/RateLimitPolicy.d.ts.map +1 -0
- package/out/src/storage/remoting/RateLimitPolicy.js +37 -0
- package/out/src/storage/remoting/RateLimitPolicy.js.map +1 -0
- package/out/src/storage/remoting/StorageClient.d.ts +7 -271
- package/out/src/storage/remoting/StorageClient.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageClient.js +87 -458
- package/out/src/storage/remoting/StorageClient.js.map +1 -1
- package/out/src/storage/remoting/StorageClientBase.d.ts +318 -0
- package/out/src/storage/remoting/StorageClientBase.d.ts.map +1 -0
- package/out/src/storage/remoting/StorageClientBase.js +474 -0
- package/out/src/storage/remoting/StorageClientBase.js.map +1 -0
- package/out/src/storage/remoting/StorageMobile.d.ts +8 -276
- package/out/src/storage/remoting/StorageMobile.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageMobile.js +43 -435
- package/out/src/storage/remoting/StorageMobile.js.map +1 -1
- package/out/src/storage/remoting/StorageServer.d.ts +106 -9
- package/out/src/storage/remoting/StorageServer.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageServer.js +628 -225
- package/out/src/storage/remoting/StorageServer.js.map +1 -1
- package/out/src/storage/remoting/edgePolicy.d.ts +84 -0
- package/out/src/storage/remoting/edgePolicy.d.ts.map +1 -0
- package/out/src/storage/remoting/edgePolicy.js +570 -0
- package/out/src/storage/remoting/edgePolicy.js.map +1 -0
- package/out/src/storage/remoting/entityValidationHelpers.d.ts +29 -0
- package/out/src/storage/remoting/entityValidationHelpers.d.ts.map +1 -0
- package/out/src/storage/remoting/entityValidationHelpers.js +108 -0
- package/out/src/storage/remoting/entityValidationHelpers.js.map +1 -0
- package/out/src/storage/schema/KnexMigrations.d.ts +7 -3
- package/out/src/storage/schema/KnexMigrations.d.ts.map +1 -1
- package/out/src/storage/schema/KnexMigrations.js +173 -11
- package/out/src/storage/schema/KnexMigrations.js.map +1 -1
- package/out/src/storage/schema/StorageIdbSchema.d.ts +27 -1
- package/out/src/storage/schema/StorageIdbSchema.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityBase.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityBase.js +1 -0
- package/out/src/storage/schema/entities/EntityBase.js.map +1 -1
- package/out/src/storage/schema/entities/EntityCertificate.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityCertificate.js +5 -4
- package/out/src/storage/schema/entities/EntityCertificate.js.map +1 -1
- package/out/src/storage/schema/entities/EntityCertificateField.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityCertificateField.js +5 -7
- package/out/src/storage/schema/entities/EntityCertificateField.js.map +1 -1
- package/out/src/storage/schema/entities/EntityCommission.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityCommission.js +6 -8
- package/out/src/storage/schema/entities/EntityCommission.js.map +1 -1
- package/out/src/storage/schema/entities/EntityOutput.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityOutput.js +21 -24
- package/out/src/storage/schema/entities/EntityOutput.js.map +1 -1
- package/out/src/storage/schema/entities/EntityOutputBasket.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityOutputBasket.js +7 -7
- package/out/src/storage/schema/entities/EntityOutputBasket.js.map +1 -1
- package/out/src/storage/schema/entities/EntityOutputTag.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityOutputTag.js +2 -2
- package/out/src/storage/schema/entities/EntityOutputTag.js.map +1 -1
- package/out/src/storage/schema/entities/EntityOutputTagMap.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityOutputTagMap.js +4 -6
- package/out/src/storage/schema/entities/EntityOutputTagMap.js.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTx.d.ts +8 -4
- package/out/src/storage/schema/entities/EntityProvenTx.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTx.js +77 -64
- package/out/src/storage/schema/entities/EntityProvenTx.js.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTxReq.d.ts +11 -2
- package/out/src/storage/schema/entities/EntityProvenTxReq.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTxReq.js +122 -74
- package/out/src/storage/schema/entities/EntityProvenTxReq.js.map +1 -1
- package/out/src/storage/schema/entities/EntitySyncState.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntitySyncState.js +40 -45
- package/out/src/storage/schema/entities/EntitySyncState.js.map +1 -1
- package/out/src/storage/schema/entities/EntityTransaction.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityTransaction.js +30 -31
- package/out/src/storage/schema/entities/EntityTransaction.js.map +1 -1
- package/out/src/storage/schema/entities/EntityTxLabel.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityTxLabel.js +2 -2
- package/out/src/storage/schema/entities/EntityTxLabel.js.map +1 -1
- package/out/src/storage/schema/entities/EntityTxLabelMap.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityTxLabelMap.js +4 -6
- package/out/src/storage/schema/entities/EntityTxLabelMap.js.map +1 -1
- package/out/src/storage/schema/entities/EntityUser.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityUser.js +3 -3
- package/out/src/storage/schema/entities/EntityUser.js.map +1 -1
- package/out/src/storage/schema/entities/MergeEntity.d.ts.map +1 -1
- package/out/src/storage/schema/entities/MergeEntity.js +17 -18
- package/out/src/storage/schema/entities/MergeEntity.js.map +1 -1
- package/out/src/storage/schema/tables/TableActionBatch.d.ts +26 -0
- package/out/src/storage/schema/tables/TableActionBatch.d.ts.map +1 -0
- package/out/src/storage/schema/tables/TableActionBatch.js +3 -0
- package/out/src/storage/schema/tables/TableActionBatch.js.map +1 -0
- package/out/src/storage/schema/tables/TableAuthSession.d.ts +20 -0
- package/out/src/storage/schema/tables/TableAuthSession.d.ts.map +1 -0
- package/out/src/storage/schema/tables/TableAuthSession.js +15 -0
- package/out/src/storage/schema/tables/TableAuthSession.js.map +1 -0
- package/out/src/storage/schema/tables/TableCertificate.d.ts +2 -1
- package/out/src/storage/schema/tables/TableCertificate.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableCertificateField.d.ts +1 -1
- package/out/src/storage/schema/tables/TableCertificateField.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableCommission.d.ts +1 -1
- package/out/src/storage/schema/tables/TableCommission.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableMonitorEvent.d.ts +1 -1
- package/out/src/storage/schema/tables/TableMonitorEvent.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableOutput.d.ts +3 -2
- package/out/src/storage/schema/tables/TableOutput.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableOutput.js +1 -1
- package/out/src/storage/schema/tables/TableOutput.js.map +1 -1
- package/out/src/storage/schema/tables/TableOutputBasket.d.ts +1 -1
- package/out/src/storage/schema/tables/TableOutputBasket.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableOutputTag.d.ts +1 -1
- package/out/src/storage/schema/tables/TableOutputTag.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableOutputTagMap.d.ts +1 -1
- package/out/src/storage/schema/tables/TableOutputTagMap.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableProvenTx.d.ts +1 -1
- package/out/src/storage/schema/tables/TableProvenTx.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableProvenTxReq.d.ts +24 -1
- package/out/src/storage/schema/tables/TableProvenTxReq.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableSettings.d.ts +1 -1
- package/out/src/storage/schema/tables/TableSettings.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableSyncState.d.ts +1 -1
- package/out/src/storage/schema/tables/TableSyncState.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableTransaction.d.ts +1 -1
- package/out/src/storage/schema/tables/TableTransaction.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableTxLabel.d.ts +1 -1
- package/out/src/storage/schema/tables/TableTxLabel.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableTxLabelMap.d.ts +1 -1
- package/out/src/storage/schema/tables/TableTxLabelMap.d.ts.map +1 -1
- package/out/src/storage/schema/tables/TableUser.d.ts +1 -1
- package/out/src/storage/schema/tables/TableUser.d.ts.map +1 -1
- package/out/src/storage/schema/tables/index.d.ts +2 -0
- package/out/src/storage/schema/tables/index.d.ts.map +1 -1
- package/out/src/storage/schema/tables/index.js +2 -0
- package/out/src/storage/schema/tables/index.js.map +1 -1
- package/out/src/storage/storageProviderHelpers.d.ts +35 -0
- package/out/src/storage/storageProviderHelpers.d.ts.map +1 -0
- package/out/src/storage/storageProviderHelpers.js +106 -0
- package/out/src/storage/storageProviderHelpers.js.map +1 -0
- package/out/src/storage/sync/StorageMySQLDojoReader.d.ts +4 -2
- package/out/src/storage/sync/StorageMySQLDojoReader.d.ts.map +1 -1
- package/out/src/storage/sync/StorageMySQLDojoReader.js +65 -46
- package/out/src/storage/sync/StorageMySQLDojoReader.js.map +1 -1
- package/out/src/utility/Format.d.ts.map +1 -1
- package/out/src/utility/Format.js +15 -49
- package/out/src/utility/Format.js.map +1 -1
- package/out/src/utility/ScriptTemplateBRC29.d.ts +3 -2
- package/out/src/utility/ScriptTemplateBRC29.d.ts.map +1 -1
- package/out/src/utility/ScriptTemplateBRC29.js +22 -11
- package/out/src/utility/ScriptTemplateBRC29.js.map +1 -1
- package/out/src/utility/actionBatchDigest.d.ts +9 -0
- package/out/src/utility/actionBatchDigest.d.ts.map +1 -0
- package/out/src/utility/actionBatchDigest.js +86 -0
- package/out/src/utility/actionBatchDigest.js.map +1 -0
- package/out/src/utility/actionBatchPack.d.ts +16 -0
- package/out/src/utility/actionBatchPack.d.ts.map +1 -0
- package/out/src/utility/actionBatchPack.js +220 -0
- package/out/src/utility/actionBatchPack.js.map +1 -0
- package/out/src/utility/aggregateResults.d.ts +1 -1
- package/out/src/utility/aggregateResults.d.ts.map +1 -1
- package/out/src/utility/aggregateResults.js +2 -2
- package/out/src/utility/aggregateResults.js.map +1 -1
- package/out/src/utility/beefForTxids.d.ts +9 -0
- package/out/src/utility/beefForTxids.d.ts.map +1 -0
- package/out/src/utility/beefForTxids.js +35 -0
- package/out/src/utility/beefForTxids.js.map +1 -0
- package/out/src/utility/brc114ActionTimeLabels.d.ts +2 -2
- package/out/src/utility/brc114ActionTimeLabels.d.ts.map +1 -1
- package/out/src/utility/brc114ActionTimeLabels.js +31 -28
- package/out/src/utility/brc114ActionTimeLabels.js.map +1 -1
- package/out/src/utility/brc153ReferenceLabels.d.ts +23 -0
- package/out/src/utility/brc153ReferenceLabels.d.ts.map +1 -0
- package/out/src/utility/brc153ReferenceLabels.js +51 -0
- package/out/src/utility/brc153ReferenceLabels.js.map +1 -0
- package/out/src/utility/formatUnknown.d.ts +6 -0
- package/out/src/utility/formatUnknown.d.ts.map +1 -0
- package/out/src/utility/formatUnknown.js +39 -0
- package/out/src/utility/formatUnknown.js.map +1 -0
- package/out/src/utility/hashWasm.d.ts +5 -0
- package/out/src/utility/hashWasm.d.ts.map +1 -0
- package/out/src/utility/hashWasm.js +15 -0
- package/out/src/utility/hashWasm.js.map +1 -0
- package/out/src/utility/identityUtils.d.ts +12 -6
- package/out/src/utility/identityUtils.d.ts.map +1 -1
- package/out/src/utility/identityUtils.js +82 -38
- package/out/src/utility/identityUtils.js.map +1 -1
- package/out/src/utility/index.all.d.ts +2 -0
- package/out/src/utility/index.all.d.ts.map +1 -1
- package/out/src/utility/index.all.js +2 -0
- package/out/src/utility/index.all.js.map +1 -1
- package/out/src/utility/index.client.d.ts +2 -0
- package/out/src/utility/index.client.d.ts.map +1 -1
- package/out/src/utility/index.client.js +2 -0
- package/out/src/utility/index.client.js.map +1 -1
- package/out/src/utility/parseTxScriptOffsets.d.ts +5 -5
- package/out/src/utility/parseTxScriptOffsets.d.ts.map +1 -1
- package/out/src/utility/parseTxScriptOffsets.js +1 -1
- package/out/src/utility/parseTxScriptOffsets.js.map +1 -1
- package/out/src/utility/stampLog.d.ts.map +1 -1
- package/out/src/utility/stampLog.js +53 -44
- package/out/src/utility/stampLog.js.map +1 -1
- package/out/src/utility/traceContext.d.ts +13 -0
- package/out/src/utility/traceContext.d.ts.map +1 -0
- package/out/src/utility/traceContext.js +34 -0
- package/out/src/utility/traceContext.js.map +1 -0
- package/out/src/utility/tscProofToMerklePath.js +1 -1
- package/out/src/utility/tscProofToMerklePath.js.map +1 -1
- package/out/src/utility/utilityHelpers.buffer.d.ts +5 -3
- package/out/src/utility/utilityHelpers.buffer.d.ts.map +1 -1
- package/out/src/utility/utilityHelpers.buffer.js +3 -3
- package/out/src/utility/utilityHelpers.buffer.js.map +1 -1
- package/out/src/utility/utilityHelpers.d.ts +3 -4
- package/out/src/utility/utilityHelpers.d.ts.map +1 -1
- package/out/src/utility/utilityHelpers.js +24 -16
- package/out/src/utility/utilityHelpers.js.map +1 -1
- package/out/src/utility/utilityHelpers.noBuffer.d.ts +7 -3
- package/out/src/utility/utilityHelpers.noBuffer.d.ts.map +1 -1
- package/out/src/utility/utilityHelpers.noBuffer.js +7 -8
- package/out/src/utility/utilityHelpers.noBuffer.js.map +1 -1
- package/out/src/wab-client/WABClient.d.ts +36 -90
- package/out/src/wab-client/WABClient.d.ts.map +1 -1
- package/out/src/wab-client/WABClient.js +103 -150
- package/out/src/wab-client/WABClient.js.map +1 -1
- package/out/src/wab-client/WABTransport.d.ts +81 -0
- package/out/src/wab-client/WABTransport.d.ts.map +1 -0
- package/out/src/wab-client/WABTransport.js +420 -0
- package/out/src/wab-client/WABTransport.js.map +1 -0
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts +10 -10
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts.map +1 -1
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js +16 -21
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js.map +1 -1
- package/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.js +1 -4
- package/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.js.map +1 -1
- package/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.js +1 -4
- package/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.js.map +1 -1
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts +2 -1
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts.map +1 -1
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js +14 -3
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js.map +1 -1
- package/package.json +89 -36
- package/license.md +0 -28
- package/out/src/__tests/CWIStyleWalletManager.test.d.ts +0 -2
- package/out/src/__tests/CWIStyleWalletManager.test.d.ts.map +0 -1
- package/out/src/__tests/CWIStyleWalletManager.test.js +0 -809
- package/out/src/__tests/CWIStyleWalletManager.test.js.map +0 -1
- package/out/src/__tests/ShamirWalletManager.test.d.ts +0 -2
- package/out/src/__tests/ShamirWalletManager.test.d.ts.map +0 -1
- package/out/src/__tests/ShamirWalletManager.test.js +0 -299
- package/out/src/__tests/ShamirWalletManager.test.js.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.callbacks.test.d.ts +0 -2
- package/out/src/__tests/WalletPermissionsManager.callbacks.test.d.ts.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.callbacks.test.js +0 -373
- package/out/src/__tests/WalletPermissionsManager.callbacks.test.js.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.checks.test.d.ts +0 -2
- package/out/src/__tests/WalletPermissionsManager.checks.test.d.ts.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.checks.test.js +0 -642
- package/out/src/__tests/WalletPermissionsManager.checks.test.js.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.encryption.test.d.ts +0 -2
- package/out/src/__tests/WalletPermissionsManager.encryption.test.d.ts.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.encryption.test.js +0 -335
- package/out/src/__tests/WalletPermissionsManager.encryption.test.js.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.fixtures.d.ts +0 -87
- package/out/src/__tests/WalletPermissionsManager.fixtures.d.ts.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.fixtures.js +0 -290
- package/out/src/__tests/WalletPermissionsManager.fixtures.js.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.flows.test.d.ts +0 -2
- package/out/src/__tests/WalletPermissionsManager.flows.test.d.ts.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.flows.test.js +0 -613
- package/out/src/__tests/WalletPermissionsManager.flows.test.js.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.initialization.test.d.ts +0 -2
- package/out/src/__tests/WalletPermissionsManager.initialization.test.d.ts.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.initialization.test.js +0 -227
- package/out/src/__tests/WalletPermissionsManager.initialization.test.js.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.pmodules.test.d.ts +0 -2
- package/out/src/__tests/WalletPermissionsManager.pmodules.test.d.ts.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.pmodules.test.js +0 -735
- package/out/src/__tests/WalletPermissionsManager.pmodules.test.js.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.proxying.test.d.ts +0 -2
- package/out/src/__tests/WalletPermissionsManager.proxying.test.d.ts.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.proxying.test.js +0 -584
- package/out/src/__tests/WalletPermissionsManager.proxying.test.js.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.tokens.test.d.ts +0 -2
- package/out/src/__tests/WalletPermissionsManager.tokens.test.d.ts.map +0 -1
- package/out/src/__tests/WalletPermissionsManager.tokens.test.js +0 -415
- package/out/src/__tests/WalletPermissionsManager.tokens.test.js.map +0 -1
- package/out/src/entropy/__tests/EntropyCollector.test.d.ts +0 -2
- package/out/src/entropy/__tests/EntropyCollector.test.d.ts.map +0 -1
- package/out/src/entropy/__tests/EntropyCollector.test.js +0 -137
- package/out/src/entropy/__tests/EntropyCollector.test.js.map +0 -1
- package/out/src/monitor/__test/MonitorDaemon.man.test.d.ts +0 -2
- package/out/src/monitor/__test/MonitorDaemon.man.test.d.ts.map +0 -1
- package/out/src/monitor/__test/MonitorDaemon.man.test.js +0 -41
- package/out/src/monitor/__test/MonitorDaemon.man.test.js.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskArcSSE.test.d.ts +0 -2
- package/out/src/monitor/tasks/__tests/TaskArcSSE.test.d.ts.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskArcSSE.test.js +0 -257
- package/out/src/monitor/tasks/__tests/TaskArcSSE.test.js.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.d.ts +0 -2
- package/out/src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.d.ts.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.js +0 -161
- package/out/src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.js.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskReviewProvenTxs.test.d.ts +0 -2
- package/out/src/monitor/tasks/__tests/TaskReviewProvenTxs.test.d.ts.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskReviewProvenTxs.test.js +0 -214
- package/out/src/monitor/tasks/__tests/TaskReviewProvenTxs.test.js.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskReviewUtxos.test.d.ts +0 -2
- package/out/src/monitor/tasks/__tests/TaskReviewUtxos.test.d.ts.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskReviewUtxos.test.js +0 -92
- package/out/src/monitor/tasks/__tests/TaskReviewUtxos.test.js.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskSendWaiting.test.d.ts +0 -2
- package/out/src/monitor/tasks/__tests/TaskSendWaiting.test.d.ts.map +0 -1
- package/out/src/monitor/tasks/__tests/TaskSendWaiting.test.js +0 -139
- package/out/src/monitor/tasks/__tests/TaskSendWaiting.test.js.map +0 -1
- package/out/src/sdk/__test/CertificateLifeCycle.test.d.ts +0 -2
- package/out/src/sdk/__test/CertificateLifeCycle.test.d.ts.map +0 -1
- package/out/src/sdk/__test/CertificateLifeCycle.test.js +0 -62
- package/out/src/sdk/__test/CertificateLifeCycle.test.js.map +0 -1
- package/out/src/sdk/__test/PrivilegedKeyManager.test.d.ts +0 -2
- package/out/src/sdk/__test/PrivilegedKeyManager.test.d.ts.map +0 -1
- package/out/src/sdk/__test/PrivilegedKeyManager.test.js +0 -647
- package/out/src/sdk/__test/PrivilegedKeyManager.test.js.map +0 -1
- package/out/src/sdk/__test/WalletError.test.d.ts +0 -2
- package/out/src/sdk/__test/WalletError.test.d.ts.map +0 -1
- package/out/src/sdk/__test/WalletError.test.js +0 -255
- package/out/src/sdk/__test/WalletError.test.js.map +0 -1
- package/out/src/sdk/__test/validationHelpers.test.d.ts +0 -2
- package/out/src/sdk/__test/validationHelpers.test.d.ts.map +0 -1
- package/out/src/sdk/__test/validationHelpers.test.js +0 -20
- package/out/src/sdk/__test/validationHelpers.test.js.map +0 -1
- package/out/src/services/__tests/ARC.man.test.d.ts +0 -2
- package/out/src/services/__tests/ARC.man.test.d.ts.map +0 -1
- package/out/src/services/__tests/ARC.man.test.js +0 -104
- package/out/src/services/__tests/ARC.man.test.js.map +0 -1
- package/out/src/services/__tests/ARC.timeout.man.test.d.ts +0 -2
- package/out/src/services/__tests/ARC.timeout.man.test.d.ts.map +0 -1
- package/out/src/services/__tests/ARC.timeout.man.test.js +0 -74
- package/out/src/services/__tests/ARC.timeout.man.test.js.map +0 -1
- package/out/src/services/__tests/ArcGorillaPool.man.test.d.ts +0 -2
- package/out/src/services/__tests/ArcGorillaPool.man.test.d.ts.map +0 -1
- package/out/src/services/__tests/ArcGorillaPool.man.test.js +0 -93
- package/out/src/services/__tests/ArcGorillaPool.man.test.js.map +0 -1
- package/out/src/services/__tests/arcServices.test.d.ts +0 -2
- package/out/src/services/__tests/arcServices.test.d.ts.map +0 -1
- package/out/src/services/__tests/arcServices.test.js +0 -7
- package/out/src/services/__tests/arcServices.test.js.map +0 -1
- package/out/src/services/__tests/bitrails.test.d.ts +0 -2
- package/out/src/services/__tests/bitrails.test.d.ts.map +0 -1
- package/out/src/services/__tests/bitrails.test.js +0 -59
- package/out/src/services/__tests/bitrails.test.js.map +0 -1
- package/out/src/services/__tests/getFiatExchangeRate.test.d.ts +0 -2
- package/out/src/services/__tests/getFiatExchangeRate.test.d.ts.map +0 -1
- package/out/src/services/__tests/getFiatExchangeRate.test.js +0 -156
- package/out/src/services/__tests/getFiatExchangeRate.test.js.map +0 -1
- package/out/src/services/__tests/getMerklePath.test.d.ts +0 -2
- package/out/src/services/__tests/getMerklePath.test.d.ts.map +0 -1
- package/out/src/services/__tests/getMerklePath.test.js +0 -16
- package/out/src/services/__tests/getMerklePath.test.js.map +0 -1
- package/out/src/services/__tests/getRawTx.test.d.ts +0 -2
- package/out/src/services/__tests/getRawTx.test.d.ts.map +0 -1
- package/out/src/services/__tests/getRawTx.test.js +0 -16
- package/out/src/services/__tests/getRawTx.test.js.map +0 -1
- package/out/src/services/__tests/postBeef.test.d.ts +0 -2
- package/out/src/services/__tests/postBeef.test.d.ts.map +0 -1
- package/out/src/services/__tests/postBeef.test.js +0 -101
- package/out/src/services/__tests/postBeef.test.js.map +0 -1
- package/out/src/services/__tests/verifyBeef.test.d.ts +0 -2
- package/out/src/services/__tests/verifyBeef.test.d.ts.map +0 -1
- package/out/src/services/__tests/verifyBeef.test.js +0 -43
- package/out/src/services/__tests/verifyBeef.test.js.map +0 -1
- package/out/src/services/chaintracker/__tests/ChaintracksChainTracker.test.d.ts +0 -2
- package/out/src/services/chaintracker/__tests/ChaintracksChainTracker.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/__tests/ChaintracksChainTracker.test.js +0 -25
- package/out/src/services/chaintracker/__tests/ChaintracksChainTracker.test.js.map +0 -1
- package/out/src/services/chaintracker/__tests/ChaintracksServiceClient.test.d.ts +0 -2
- package/out/src/services/chaintracker/__tests/ChaintracksServiceClient.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/__tests/ChaintracksServiceClient.test.js +0 -27
- package/out/src/services/chaintracker/__tests/ChaintracksServiceClient.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorCDNBabbage.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorCDNBabbage.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorCDNBabbage.test.js +0 -56
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorCDNBabbage.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/LiveIngestorWhatsOnChainPoll.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/LiveIngestorWhatsOnChainPoll.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/LiveIngestorWhatsOnChainPoll.test.js +0 -40
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/LiveIngestorWhatsOnChainPoll.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/WhatsOnChainServices.man.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/WhatsOnChainServices.man.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/WhatsOnChainServices.man.test.js +0 -108
- package/out/src/services/chaintracker/chaintracks/Ingest/__tests/WhatsOnChainServices.man.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageIdb.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageIdb.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageIdb.test.js +0 -87
- package/out/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageIdb.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageKnex.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageKnex.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageKnex.test.js +0 -39
- package/out/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageKnex.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.js +0 -75
- package/out/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/ChaintracksCDN.man.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/__tests/ChaintracksCDN.man.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/ChaintracksCDN.man.test.js +0 -43
- package/out/src/services/chaintracker/chaintracks/__tests/ChaintracksCDN.man.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/ChaintracksClientApi.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/__tests/ChaintracksClientApi.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/ChaintracksClientApi.test.js +0 -164
- package/out/src/services/chaintracker/chaintracks/__tests/ChaintracksClientApi.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/LocalCdnServer.d.ts +0 -12
- package/out/src/services/chaintracker/chaintracks/__tests/LocalCdnServer.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/LocalCdnServer.js +0 -69
- package/out/src/services/chaintracker/chaintracks/__tests/LocalCdnServer.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/bulkIngestorFailures.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/__tests/bulkIngestorFailures.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/bulkIngestorFailures.test.js +0 -109
- package/out/src/services/chaintracker/chaintracks/__tests/bulkIngestorFailures.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.js +0 -54
- package/out/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.js +0 -255
- package/out/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/util/__tests/ChaintracksFetch.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/util/__tests/ChaintracksFetch.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/util/__tests/ChaintracksFetch.test.js +0 -56
- package/out/src/services/chaintracker/chaintracks/util/__tests/ChaintracksFetch.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/util/__tests/HeightRange.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/util/__tests/HeightRange.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/util/__tests/HeightRange.test.js +0 -69
- package/out/src/services/chaintracker/chaintracks/util/__tests/HeightRange.test.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/util/__tests/SingleWriterMultiReaderLock.test.d.ts +0 -2
- package/out/src/services/chaintracker/chaintracks/util/__tests/SingleWriterMultiReaderLock.test.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/util/__tests/SingleWriterMultiReaderLock.test.js +0 -51
- package/out/src/services/chaintracker/chaintracks/util/__tests/SingleWriterMultiReaderLock.test.js.map +0 -1
- package/out/src/services/providers/__tests/ArcSSEClient.test.d.ts +0 -2
- package/out/src/services/providers/__tests/ArcSSEClient.test.d.ts.map +0 -1
- package/out/src/services/providers/__tests/ArcSSEClient.test.js +0 -256
- package/out/src/services/providers/__tests/ArcSSEClient.test.js.map +0 -1
- package/out/src/services/providers/__tests/WhatsOnChain.test.d.ts +0 -2
- package/out/src/services/providers/__tests/WhatsOnChain.test.d.ts.map +0 -1
- package/out/src/services/providers/__tests/WhatsOnChain.test.js +0 -191
- package/out/src/services/providers/__tests/WhatsOnChain.test.js.map +0 -1
- package/out/src/services/providers/__tests/exchangeRates.test.d.ts +0 -2
- package/out/src/services/providers/__tests/exchangeRates.test.d.ts.map +0 -1
- package/out/src/services/providers/__tests/exchangeRates.test.js +0 -23
- package/out/src/services/providers/__tests/exchangeRates.test.js.map +0 -1
- package/out/src/storage/__test/StorageIdb.test.d.ts +0 -2
- package/out/src/storage/__test/StorageIdb.test.d.ts.map +0 -1
- package/out/src/storage/__test/StorageIdb.test.js +0 -44
- package/out/src/storage/__test/StorageIdb.test.js.map +0 -1
- package/out/src/storage/__test/WalletStorageManager.test.d.ts +0 -2
- package/out/src/storage/__test/WalletStorageManager.test.d.ts.map +0 -1
- package/out/src/storage/__test/WalletStorageManager.test.js +0 -254
- package/out/src/storage/__test/WalletStorageManager.test.js.map +0 -1
- package/out/src/storage/__test/adminStats.man.test.d.ts +0 -2
- package/out/src/storage/__test/adminStats.man.test.d.ts.map +0 -1
- package/out/src/storage/__test/adminStats.man.test.js +0 -78
- package/out/src/storage/__test/adminStats.man.test.js.map +0 -1
- package/out/src/storage/__test/findStaleMerkleRoots.test.d.ts +0 -2
- package/out/src/storage/__test/findStaleMerkleRoots.test.d.ts.map +0 -1
- package/out/src/storage/__test/findStaleMerkleRoots.test.js +0 -41
- package/out/src/storage/__test/findStaleMerkleRoots.test.js.map +0 -1
- package/out/src/storage/__test/findStaleMerkleRootsKnex.test.d.ts +0 -2
- package/out/src/storage/__test/findStaleMerkleRootsKnex.test.d.ts.map +0 -1
- package/out/src/storage/__test/findStaleMerkleRootsKnex.test.js +0 -73
- package/out/src/storage/__test/findStaleMerkleRootsKnex.test.js.map +0 -1
- package/out/src/storage/__test/getBeefForTransaction.test.d.ts +0 -2
- package/out/src/storage/__test/getBeefForTransaction.test.d.ts.map +0 -1
- package/out/src/storage/__test/getBeefForTransaction.test.js +0 -347
- package/out/src/storage/__test/getBeefForTransaction.test.js.map +0 -1
- package/out/src/storage/methods/__test/GenerateChange/generateChangeSdk.test.d.ts +0 -2
- package/out/src/storage/methods/__test/GenerateChange/generateChangeSdk.test.d.ts.map +0 -1
- package/out/src/storage/methods/__test/GenerateChange/generateChangeSdk.test.js +0 -1111
- package/out/src/storage/methods/__test/GenerateChange/generateChangeSdk.test.js.map +0 -1
- package/out/src/storage/methods/__test/offsetKey.test.d.ts +0 -2
- package/out/src/storage/methods/__test/offsetKey.test.d.ts.map +0 -1
- package/out/src/storage/methods/__test/offsetKey.test.js +0 -229
- package/out/src/storage/methods/__test/offsetKey.test.js.map +0 -1
- package/out/src/storage/remoting/__test/StorageClient.man.test.d.ts +0 -2
- package/out/src/storage/remoting/__test/StorageClient.man.test.d.ts.map +0 -1
- package/out/src/storage/remoting/__test/StorageClient.man.test.js +0 -487
- package/out/src/storage/remoting/__test/StorageClient.man.test.js.map +0 -1
- package/out/src/storage/remoting/__test/StorageClient.test.d.ts +0 -2
- package/out/src/storage/remoting/__test/StorageClient.test.d.ts.map +0 -1
- package/out/src/storage/remoting/__test/StorageClient.test.js +0 -119
- package/out/src/storage/remoting/__test/StorageClient.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/CertificateFieldTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/CertificateFieldTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/CertificateFieldTests.test.js +0 -301
- package/out/src/storage/schema/entities/__tests/CertificateFieldTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/CertificateTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/CertificateTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/CertificateTests.test.js +0 -308
- package/out/src/storage/schema/entities/__tests/CertificateTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/CommissionTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/CommissionTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/CommissionTests.test.js +0 -316
- package/out/src/storage/schema/entities/__tests/CommissionTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/OutputBasketTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/OutputBasketTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/OutputBasketTests.test.js +0 -228
- package/out/src/storage/schema/entities/__tests/OutputBasketTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/OutputTagMapTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/OutputTagMapTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/OutputTagMapTests.test.js +0 -191
- package/out/src/storage/schema/entities/__tests/OutputTagMapTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/OutputTagTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/OutputTagTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/OutputTagTests.test.js +0 -226
- package/out/src/storage/schema/entities/__tests/OutputTagTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/OutputTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/OutputTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/OutputTests.test.js +0 -413
- package/out/src/storage/schema/entities/__tests/OutputTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/ProvenTxReqTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/ProvenTxReqTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/ProvenTxReqTests.test.js +0 -299
- package/out/src/storage/schema/entities/__tests/ProvenTxReqTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/ProvenTxTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/ProvenTxTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/ProvenTxTests.test.js +0 -474
- package/out/src/storage/schema/entities/__tests/ProvenTxTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/SyncStateTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/SyncStateTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/SyncStateTests.test.js +0 -234
- package/out/src/storage/schema/entities/__tests/SyncStateTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/TransactionTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/TransactionTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/TransactionTests.test.js +0 -539
- package/out/src/storage/schema/entities/__tests/TransactionTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/TxLabelMapTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/TxLabelMapTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/TxLabelMapTests.test.js +0 -304
- package/out/src/storage/schema/entities/__tests/TxLabelMapTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/TxLabelTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/TxLabelTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/TxLabelTests.test.js +0 -170
- package/out/src/storage/schema/entities/__tests/TxLabelTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/stampLogTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/stampLogTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/stampLogTests.test.js +0 -81
- package/out/src/storage/schema/entities/__tests/stampLogTests.test.js.map +0 -1
- package/out/src/storage/schema/entities/__tests/usersTests.test.d.ts +0 -2
- package/out/src/storage/schema/entities/__tests/usersTests.test.d.ts.map +0 -1
- package/out/src/storage/schema/entities/__tests/usersTests.test.js +0 -277
- package/out/src/storage/schema/entities/__tests/usersTests.test.js.map +0 -1
- package/out/src/utility/__tests/utilityHelpers.noBuffer.test.d.ts +0 -2
- package/out/src/utility/__tests/utilityHelpers.noBuffer.test.d.ts.map +0 -1
- package/out/src/utility/__tests/utilityHelpers.noBuffer.test.js +0 -107
- package/out/src/utility/__tests/utilityHelpers.noBuffer.test.js.map +0 -1
- package/out/src/wab-client/__tests/WABClient.man.test.d.ts +0 -2
- package/out/src/wab-client/__tests/WABClient.man.test.d.ts.map +0 -1
- package/out/src/wab-client/__tests/WABClient.man.test.js +0 -52
- package/out/src/wab-client/__tests/WABClient.man.test.js.map +0 -1
|
@@ -3,9 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.WalletPermissionsManager = void 0;
|
|
4
4
|
const sdk_1 = require("@bsv/sdk");
|
|
5
5
|
const brc114ActionTimeLabels_1 = require("./utility/brc114ActionTimeLabels");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// Security invariant: only the configured admin originator bypasses permission
|
|
7
|
+
// prompts. Admin-reserved protocols, baskets, and labels are rejected for all
|
|
8
|
+
// other originators; counterparty bypasses require an explicit configuration
|
|
9
|
+
// allowlist.
|
|
9
10
|
function deepEqual(object1, object2) {
|
|
10
11
|
if (object1 === null || object1 === undefined || object2 === null || object2 === undefined) {
|
|
11
12
|
return object1 === object2;
|
|
@@ -61,6 +62,72 @@ const BASKET_MAP = {
|
|
|
61
62
|
* the old token UTXO and outputs a new one (or none, if fully revoked).
|
|
62
63
|
*/
|
|
63
64
|
class WalletPermissionsManager {
|
|
65
|
+
/** A reference to the BRC-100 wallet instance. */
|
|
66
|
+
underlying;
|
|
67
|
+
/** The "admin" domain or FQDN that is implicitly allowed to do everything. */
|
|
68
|
+
adminOriginator;
|
|
69
|
+
/**
|
|
70
|
+
* Event callbacks that external code can subscribe to, e.g. to show a UI prompt
|
|
71
|
+
* or log events. Each event can have multiple handlers.
|
|
72
|
+
*/
|
|
73
|
+
callbacks = {
|
|
74
|
+
onProtocolPermissionRequested: [],
|
|
75
|
+
onBasketAccessRequested: [],
|
|
76
|
+
onCertificateAccessRequested: [],
|
|
77
|
+
onSpendingAuthorizationRequested: [],
|
|
78
|
+
onGroupedPermissionRequested: [],
|
|
79
|
+
onCounterpartyPermissionRequested: []
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* We queue parallel requests for the same resource so that only one
|
|
83
|
+
* user prompt is created for a single resource. If multiple calls come
|
|
84
|
+
* in at once for the same "protocol:domain:privileged:counterparty" etc.,
|
|
85
|
+
* they get merged.
|
|
86
|
+
*
|
|
87
|
+
* The key is a string derived from the operation; the value is an object with a reference to the
|
|
88
|
+
* associated request and an array of pending promise resolve/reject pairs, one for each active
|
|
89
|
+
* operation that's waiting on the particular resource described by the key.
|
|
90
|
+
*/
|
|
91
|
+
activeRequests = new Map();
|
|
92
|
+
/** Cache recently confirmed permissions to avoid repeated lookups. */
|
|
93
|
+
permissionCache = new Map();
|
|
94
|
+
recentGrants = new Map();
|
|
95
|
+
/**
|
|
96
|
+
* Token mints currently being written on-chain, keyed by permission cache
|
|
97
|
+
* key. A granted permission is only cached once its token finishes minting
|
|
98
|
+
* (network seconds); ensures arriving in that window await the in-flight
|
|
99
|
+
* mint instead of re-prompting the user for a permission they just granted.
|
|
100
|
+
* Stored promises never reject.
|
|
101
|
+
*/
|
|
102
|
+
mintsInFlight = new Map();
|
|
103
|
+
manifestCache = new Map();
|
|
104
|
+
manifestFetchInProgress = new Map();
|
|
105
|
+
static MANIFEST_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
106
|
+
groupedPermissionFlowTail = new Map();
|
|
107
|
+
pactEstablishedCache = new Map();
|
|
108
|
+
/**
|
|
109
|
+
* Parsed BEEF bundles keyed by the raw BEEF array of a `listOutputs`
|
|
110
|
+
* result, so token scans parse each bundle once instead of once per output.
|
|
111
|
+
* `null` records a bundle that failed to parse. WeakMap-keyed so entries
|
|
112
|
+
* are released with their results.
|
|
113
|
+
*/
|
|
114
|
+
parsedBeefCache = new WeakMap();
|
|
115
|
+
/** Counts token-field decrypts so long scans can periodically yield. */
|
|
116
|
+
tokenFieldDecryptCount = 0;
|
|
117
|
+
/** How long a cached permission remains valid (5 minutes). */
|
|
118
|
+
static CACHE_TTL_MS = 5 * 60 * 1000;
|
|
119
|
+
/** Window during which freshly granted permissions are auto-allowed (except spending). */
|
|
120
|
+
static RECENT_GRANT_COVER_MS = 15 * 1000;
|
|
121
|
+
/** Default ports used when normalizing originator values. */
|
|
122
|
+
static DEFAULT_PORTS = {
|
|
123
|
+
'http:': '80',
|
|
124
|
+
'https:': '443'
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Configuration that determines whether to skip or apply various checks and encryption.
|
|
128
|
+
*/
|
|
129
|
+
config;
|
|
130
|
+
telemetry;
|
|
64
131
|
/**
|
|
65
132
|
* Constructs a new Permissions Manager instance.
|
|
66
133
|
*
|
|
@@ -69,38 +136,9 @@ class WalletPermissionsManager {
|
|
|
69
136
|
* @param config A set of boolean flags controlling how strictly permissions are enforced
|
|
70
137
|
*/
|
|
71
138
|
constructor(underlyingWallet, adminOriginator, config = {}) {
|
|
72
|
-
/**
|
|
73
|
-
* Event callbacks that external code can subscribe to, e.g. to show a UI prompt
|
|
74
|
-
* or log events. Each event can have multiple handlers.
|
|
75
|
-
*/
|
|
76
|
-
this.callbacks = {
|
|
77
|
-
onProtocolPermissionRequested: [],
|
|
78
|
-
onBasketAccessRequested: [],
|
|
79
|
-
onCertificateAccessRequested: [],
|
|
80
|
-
onSpendingAuthorizationRequested: [],
|
|
81
|
-
onGroupedPermissionRequested: [],
|
|
82
|
-
onCounterpartyPermissionRequested: []
|
|
83
|
-
};
|
|
84
|
-
/**
|
|
85
|
-
* We queue parallel requests for the same resource so that only one
|
|
86
|
-
* user prompt is created for a single resource. If multiple calls come
|
|
87
|
-
* in at once for the same "protocol:domain:privileged:counterparty" etc.,
|
|
88
|
-
* they get merged.
|
|
89
|
-
*
|
|
90
|
-
* The key is a string derived from the operation; the value is an object with a reference to the
|
|
91
|
-
* associated request and an array of pending promise resolve/reject pairs, one for each active
|
|
92
|
-
* operation that's waiting on the particular resource described by the key.
|
|
93
|
-
*/
|
|
94
|
-
this.activeRequests = new Map();
|
|
95
|
-
/** Cache recently confirmed permissions to avoid repeated lookups. */
|
|
96
|
-
this.permissionCache = new Map();
|
|
97
|
-
this.recentGrants = new Map();
|
|
98
|
-
this.manifestCache = new Map();
|
|
99
|
-
this.manifestFetchInProgress = new Map();
|
|
100
|
-
this.groupedPermissionFlowTail = new Map();
|
|
101
|
-
this.pactEstablishedCache = new Map();
|
|
102
139
|
this.underlying = underlyingWallet;
|
|
103
140
|
this.adminOriginator = this.normalizeOriginator(adminOriginator) || adminOriginator;
|
|
141
|
+
this.telemetry = new sdk_1.Telemetry(config.telemetry);
|
|
104
142
|
// Default all config options to true unless specified
|
|
105
143
|
this.config = {
|
|
106
144
|
seekProtocolPermissionsForSigning: true,
|
|
@@ -142,14 +180,13 @@ class WalletPermissionsManager {
|
|
|
142
180
|
* @returns The transformed response, or null if not a P-basket/protocol (caller should continue normal flow)
|
|
143
181
|
*/
|
|
144
182
|
async delegateToPModuleIfNeeded(basketOrProtocolName, method, args, originator, underlyingCall) {
|
|
145
|
-
var _a;
|
|
146
183
|
// Check if this is a P-protocol/basket
|
|
147
184
|
if (!basketOrProtocolName.startsWith('p ')) {
|
|
148
185
|
return null; // If not, caller should continue normal flow
|
|
149
186
|
}
|
|
150
187
|
const schemeID = basketOrProtocolName.split(' ')[1];
|
|
151
|
-
const module =
|
|
152
|
-
if (
|
|
188
|
+
const module = this.config.permissionModules?.[schemeID];
|
|
189
|
+
if (module == null) {
|
|
153
190
|
throw new Error(`Unsupported P-module scheme: p ${schemeID}`);
|
|
154
191
|
}
|
|
155
192
|
// Transform request with module
|
|
@@ -170,11 +207,10 @@ class WalletPermissionsManager {
|
|
|
170
207
|
* Adds a permission module for the given schemeID if needed, throwing if unsupported.
|
|
171
208
|
*/
|
|
172
209
|
addPModuleByScheme(schemeID, kind, pModulesByScheme) {
|
|
173
|
-
var _a;
|
|
174
210
|
if (pModulesByScheme.has(schemeID))
|
|
175
211
|
return;
|
|
176
|
-
const module =
|
|
177
|
-
if (
|
|
212
|
+
const module = this.config.permissionModules?.[schemeID];
|
|
213
|
+
if (module == null) {
|
|
178
214
|
throw new Error(`Unsupported P-${kind} scheme: p ${schemeID}`);
|
|
179
215
|
}
|
|
180
216
|
pModulesByScheme.set(schemeID, module);
|
|
@@ -198,7 +234,7 @@ class WalletPermissionsManager {
|
|
|
198
234
|
*/
|
|
199
235
|
splitLabelsByPermissionModule(labels, pModulesByScheme) {
|
|
200
236
|
const nonPLabels = [];
|
|
201
|
-
if (
|
|
237
|
+
if (labels == null)
|
|
202
238
|
return nonPLabels;
|
|
203
239
|
for (const label of labels) {
|
|
204
240
|
if (label.startsWith('p ')) {
|
|
@@ -233,9 +269,9 @@ class WalletPermissionsManager {
|
|
|
233
269
|
*/
|
|
234
270
|
async decryptListOutputsMetadata(results) {
|
|
235
271
|
if (results.outputs) {
|
|
236
|
-
for (
|
|
237
|
-
if (
|
|
238
|
-
|
|
272
|
+
for (const output of results.outputs) {
|
|
273
|
+
if (output.customInstructions) {
|
|
274
|
+
output.customInstructions = await this.maybeDecryptMetadata(output.customInstructions);
|
|
239
275
|
}
|
|
240
276
|
}
|
|
241
277
|
}
|
|
@@ -246,31 +282,37 @@ class WalletPermissionsManager {
|
|
|
246
282
|
*/
|
|
247
283
|
async decryptListActionsMetadata(results) {
|
|
248
284
|
if (results.actions) {
|
|
249
|
-
for (
|
|
250
|
-
|
|
251
|
-
results.actions[i].description = await this.maybeDecryptMetadata(results.actions[i].description);
|
|
252
|
-
}
|
|
253
|
-
if (results.actions[i].inputs) {
|
|
254
|
-
for (let j = 0; j < results.actions[i].inputs.length; j++) {
|
|
255
|
-
if (results.actions[i].inputs[j].inputDescription) {
|
|
256
|
-
results.actions[i].inputs[j].inputDescription = await this.maybeDecryptMetadata(results.actions[i].inputs[j].inputDescription);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
if (results.actions[i].outputs) {
|
|
261
|
-
for (let j = 0; j < results.actions[i].outputs.length; j++) {
|
|
262
|
-
if (results.actions[i].outputs[j].outputDescription) {
|
|
263
|
-
results.actions[i].outputs[j].outputDescription = await this.maybeDecryptMetadata(results.actions[i].outputs[j].outputDescription);
|
|
264
|
-
}
|
|
265
|
-
if (results.actions[i].outputs[j].customInstructions) {
|
|
266
|
-
results.actions[i].outputs[j].customInstructions = await this.maybeDecryptMetadata(results.actions[i].outputs[j].customInstructions);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
285
|
+
for (const action of results.actions) {
|
|
286
|
+
await this.decryptSingleActionMetadata(action);
|
|
270
287
|
}
|
|
271
288
|
}
|
|
272
289
|
return results;
|
|
273
290
|
}
|
|
291
|
+
async decryptSingleActionMetadata(action) {
|
|
292
|
+
if (action.description) {
|
|
293
|
+
action.description = await this.maybeDecryptMetadata(action.description);
|
|
294
|
+
}
|
|
295
|
+
if (action.inputs != null) {
|
|
296
|
+
for (const input of action.inputs) {
|
|
297
|
+
if (input.inputDescription) {
|
|
298
|
+
input.inputDescription = await this.maybeDecryptMetadata(input.inputDescription);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (action.outputs != null) {
|
|
303
|
+
for (const output of action.outputs) {
|
|
304
|
+
await this.decryptActionOutputMetadata(output);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
async decryptActionOutputMetadata(output) {
|
|
309
|
+
if (output.outputDescription) {
|
|
310
|
+
output.outputDescription = await this.maybeDecryptMetadata(output.outputDescription);
|
|
311
|
+
}
|
|
312
|
+
if (output.customInstructions) {
|
|
313
|
+
output.customInstructions = await this.maybeDecryptMetadata(output.customInstructions);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
274
316
|
/* ---------------------------------------------------------------------
|
|
275
317
|
* 1) PUBLIC API FOR REGISTERING CALLBACKS (UI PROMPTS, LOGGING, ETC.)
|
|
276
318
|
* --------------------------------------------------------------------- */
|
|
@@ -295,7 +337,7 @@ class WalletPermissionsManager {
|
|
|
295
337
|
* @returns True if successfully unbound, false otherwise
|
|
296
338
|
*/
|
|
297
339
|
unbindCallback(eventName, reference) {
|
|
298
|
-
if (
|
|
340
|
+
if (this.callbacks[eventName] == null)
|
|
299
341
|
return false;
|
|
300
342
|
const arr = this.callbacks[eventName];
|
|
301
343
|
if (typeof reference === 'number') {
|
|
@@ -324,13 +366,26 @@ class WalletPermissionsManager {
|
|
|
324
366
|
*/
|
|
325
367
|
async callEvent(eventName, param) {
|
|
326
368
|
const arr = this.callbacks[eventName] || [];
|
|
327
|
-
for (const cb of arr) {
|
|
369
|
+
for (const [callbackIndex, cb] of arr.entries()) {
|
|
328
370
|
if (typeof cb === 'function') {
|
|
329
371
|
try {
|
|
330
|
-
|
|
372
|
+
if (this.telemetry.enabled && typeof param === 'object' && param != null) {
|
|
373
|
+
await this.telemetry.withSpan('wallet.permission.callback', {
|
|
374
|
+
component: 'wallet-permissions',
|
|
375
|
+
carrier: param,
|
|
376
|
+
attributes: {
|
|
377
|
+
'permission.callback': eventName,
|
|
378
|
+
'permission.callback_index': callbackIndex
|
|
379
|
+
}
|
|
380
|
+
}, async () => await cb(param));
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
await cb(param);
|
|
384
|
+
}
|
|
331
385
|
}
|
|
332
|
-
catch
|
|
333
|
-
// Intentionally swallow errors from user-provided callbacks
|
|
386
|
+
catch {
|
|
387
|
+
// Intentionally swallow errors from user-provided callbacks to prevent
|
|
388
|
+
// a misbehaving callback from disrupting the event dispatch loop.
|
|
334
389
|
}
|
|
335
390
|
}
|
|
336
391
|
}
|
|
@@ -350,7 +405,7 @@ class WalletPermissionsManager {
|
|
|
350
405
|
async grantPermission(params) {
|
|
351
406
|
// 1) Identify the matching queued requests in `activeRequests`
|
|
352
407
|
const matching = this.activeRequests.get(params.requestID);
|
|
353
|
-
if (
|
|
408
|
+
if (matching == null) {
|
|
354
409
|
throw new Error('Request ID not found.');
|
|
355
410
|
}
|
|
356
411
|
// 2) Mark all matching requests as resolved, deleting the entry
|
|
@@ -359,26 +414,45 @@ class WalletPermissionsManager {
|
|
|
359
414
|
}
|
|
360
415
|
this.activeRequests.delete(params.requestID);
|
|
361
416
|
// 3) If `ephemeral !== true`, we create or renew an on-chain token
|
|
362
|
-
if (!params.ephemeral) {
|
|
363
|
-
const request = matching.request;
|
|
364
|
-
if (!request.renewal) {
|
|
365
|
-
// brand-new permission token
|
|
366
|
-
await this.createPermissionOnChain(request, params.expiry || 0, // default: never expires
|
|
367
|
-
params.amount);
|
|
368
|
-
}
|
|
369
|
-
else {
|
|
370
|
-
// renewal => spend the old token, produce a new one
|
|
371
|
-
await this.renewPermissionOnChain(request.previousToken, request, params.expiry || 0, // default: never expires
|
|
372
|
-
params.amount);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
417
|
// Only cache non-ephemeral permissions
|
|
376
418
|
// Ephemeral permissions should not be cached as they are one-time authorizations
|
|
377
419
|
if (!params.ephemeral) {
|
|
420
|
+
const request = matching.request;
|
|
378
421
|
const expiry = params.expiry || 0; // default: never expires
|
|
379
|
-
const key = this.buildRequestKey(
|
|
422
|
+
const key = this.buildRequestKey(request);
|
|
423
|
+
// Several first-contact prompts for the same permission can stack up
|
|
424
|
+
// before any token exists (e.g. one per usage type). Granting them all
|
|
425
|
+
// should yield ONE token: if an identical non-renewal grant just minted
|
|
426
|
+
// (or is minting), don't mint a duplicate. Spending authorizations are
|
|
427
|
+
// excluded — their tokens carry amounts, so every grant is honored.
|
|
428
|
+
let skipDuplicateMint = !request.renewal &&
|
|
429
|
+
request.type !== 'spending' &&
|
|
430
|
+
(this.isPermissionCached(key) || this.isRecentlyGranted(key) || this.mintsInFlight.has(key));
|
|
431
|
+
if (skipDuplicateMint) {
|
|
432
|
+
const inFlight = this.mintsInFlight.get(key);
|
|
433
|
+
if (inFlight != null) {
|
|
434
|
+
await inFlight;
|
|
435
|
+
// The awaited mint may have failed; only skip if it landed.
|
|
436
|
+
skipDuplicateMint = this.isPermissionCached(key) || this.isRecentlyGranted(key);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
if (!skipDuplicateMint) {
|
|
440
|
+
const mint = request.renewal
|
|
441
|
+
? this.renewPermissionOnChain(request.previousToken, request, expiry, params.amount)
|
|
442
|
+
: this.createPermissionOnChain(request, expiry, params.amount);
|
|
443
|
+
// Publish the in-flight mint so concurrent ensures for the same
|
|
444
|
+
// permission wait for it instead of re-prompting (stored promise
|
|
445
|
+
// never rejects; failures still propagate to this caller below).
|
|
446
|
+
this.mintsInFlight.set(key, mint.then(() => { }, () => { }));
|
|
447
|
+
try {
|
|
448
|
+
await mint;
|
|
449
|
+
}
|
|
450
|
+
finally {
|
|
451
|
+
this.mintsInFlight.delete(key);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
380
454
|
this.cachePermission(key, expiry);
|
|
381
|
-
this.markRecentGrant(
|
|
455
|
+
this.markRecentGrant(request);
|
|
382
456
|
}
|
|
383
457
|
}
|
|
384
458
|
/**
|
|
@@ -390,12 +464,16 @@ class WalletPermissionsManager {
|
|
|
390
464
|
async denyPermission(requestID) {
|
|
391
465
|
// 1) Identify the matching requests
|
|
392
466
|
const matching = this.activeRequests.get(requestID);
|
|
393
|
-
if (
|
|
467
|
+
if (matching == null) {
|
|
394
468
|
throw new Error('Request ID not found.');
|
|
395
469
|
}
|
|
396
470
|
// 2) Reject all matching requests, deleting the entry
|
|
471
|
+
// Denials carry the canonical machine-readable code so applications can
|
|
472
|
+
// distinguish user denial from other failures (matches denyActiveRequest).
|
|
473
|
+
const err = new Error('Permission denied.');
|
|
474
|
+
err.code = 'ERR_PERMISSION_DENIED';
|
|
397
475
|
for (const x of matching.pending) {
|
|
398
|
-
x.reject(
|
|
476
|
+
x.reject(err);
|
|
399
477
|
}
|
|
400
478
|
this.activeRequests.delete(requestID);
|
|
401
479
|
}
|
|
@@ -406,33 +484,19 @@ class WalletPermissionsManager {
|
|
|
406
484
|
* @param params.expiry An optional expiry time (in seconds) for the new permission tokens.
|
|
407
485
|
*/
|
|
408
486
|
async grantGroupedPermission(params) {
|
|
409
|
-
var _a, _b, _c;
|
|
410
487
|
const matching = this.activeRequests.get(params.requestID);
|
|
411
|
-
if (
|
|
488
|
+
if (matching == null) {
|
|
412
489
|
throw new Error('Request ID not found.');
|
|
413
490
|
}
|
|
414
491
|
try {
|
|
415
492
|
const originalRequest = matching.request;
|
|
416
493
|
const { originator, permissions: requestedPermissions, displayOriginator } = originalRequest;
|
|
417
494
|
const originLookupValues = this.buildOriginatorLookupValues(displayOriginator, originator);
|
|
418
|
-
|
|
419
|
-
if (params.granted.spendingAuthorization && !requestedPermissions.spendingAuthorization) {
|
|
420
|
-
throw new Error('Granted spending authorization was not part of the original request.');
|
|
421
|
-
}
|
|
422
|
-
if ((_a = params.granted.protocolPermissions) === null || _a === void 0 ? void 0 : _a.some(g => { var _a; return !((_a = requestedPermissions.protocolPermissions) === null || _a === void 0 ? void 0 : _a.find(r => deepEqual(r, g))); })) {
|
|
423
|
-
throw new Error('Granted protocol permissions are not a subset of the original request.');
|
|
424
|
-
}
|
|
425
|
-
if ((_b = params.granted.basketAccess) === null || _b === void 0 ? void 0 : _b.some(g => { var _a; return !((_a = requestedPermissions.basketAccess) === null || _a === void 0 ? void 0 : _a.find(r => deepEqual(r, g))); })) {
|
|
426
|
-
throw new Error('Granted basket access permissions are not a subset of the original request.');
|
|
427
|
-
}
|
|
428
|
-
if ((_c = params.granted.certificateAccess) === null || _c === void 0 ? void 0 : _c.some(g => { var _a; return !((_a = requestedPermissions.certificateAccess) === null || _a === void 0 ? void 0 : _a.find(r => deepEqual(r, g))); })) {
|
|
429
|
-
throw new Error('Granted certificate access permissions are not a subset of the original request.');
|
|
430
|
-
}
|
|
431
|
-
// --- End Validation ---
|
|
495
|
+
this.validateGrantedPermissionsSubset(params.granted, requestedPermissions);
|
|
432
496
|
const expiry = params.expiry || 0; // default: never expires
|
|
433
497
|
const toCreate = [];
|
|
434
498
|
const toRenew = [];
|
|
435
|
-
if (params.granted.spendingAuthorization) {
|
|
499
|
+
if (params.granted.spendingAuthorization != null) {
|
|
436
500
|
toCreate.push({
|
|
437
501
|
request: {
|
|
438
502
|
type: 'spending',
|
|
@@ -446,8 +510,7 @@ class WalletPermissionsManager {
|
|
|
446
510
|
}
|
|
447
511
|
const grantedProtocols = params.granted.protocolPermissions || [];
|
|
448
512
|
const protocolTokens = await this.mapWithConcurrency(grantedProtocols, 8, async (p) => {
|
|
449
|
-
|
|
450
|
-
const counterparty = ((_b = (_a = p.protocolID) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : 0) === 1 ? '' : p.counterparty || 'self';
|
|
513
|
+
const counterparty = (p.protocolID?.[0] ?? 0) === 1 ? '' : p.counterparty || 'self';
|
|
451
514
|
const token = await this.findProtocolToken(originator, false, p.protocolID, counterparty, true, originLookupValues);
|
|
452
515
|
return { p, token, counterparty };
|
|
453
516
|
});
|
|
@@ -460,11 +523,11 @@ class WalletPermissionsManager {
|
|
|
460
523
|
counterparty,
|
|
461
524
|
reason: p.description
|
|
462
525
|
};
|
|
463
|
-
if (token) {
|
|
464
|
-
|
|
526
|
+
if (token == null) {
|
|
527
|
+
toCreate.push({ request, expiry });
|
|
465
528
|
}
|
|
466
529
|
else {
|
|
467
|
-
|
|
530
|
+
toRenew.push({ oldToken: token, request, expiry });
|
|
468
531
|
}
|
|
469
532
|
}
|
|
470
533
|
for (const b of params.granted.basketAccess || []) {
|
|
@@ -515,9 +578,27 @@ class WalletPermissionsManager {
|
|
|
515
578
|
* Denies a previously requested grouped permission.
|
|
516
579
|
* @param requestID The ID of the request being denied.
|
|
517
580
|
*/
|
|
518
|
-
|
|
581
|
+
/**
|
|
582
|
+
* Validates that every entry in `granted` was part of the original `requested` set.
|
|
583
|
+
* Throws an error on the first mismatch.
|
|
584
|
+
*/
|
|
585
|
+
validateGrantedPermissionsSubset(granted, requested) {
|
|
586
|
+
if (granted.spendingAuthorization != null && requested.spendingAuthorization == null) {
|
|
587
|
+
throw new Error('Granted spending authorization was not part of the original request.');
|
|
588
|
+
}
|
|
589
|
+
if (granted.protocolPermissions?.some(g => requested.protocolPermissions?.find(r => deepEqual(r, g)) == null)) {
|
|
590
|
+
throw new Error('Granted protocol permissions are not a subset of the original request.');
|
|
591
|
+
}
|
|
592
|
+
if (granted.basketAccess?.some(g => requested.basketAccess?.find(r => deepEqual(r, g)) == null)) {
|
|
593
|
+
throw new Error('Granted basket access permissions are not a subset of the original request.');
|
|
594
|
+
}
|
|
595
|
+
if (granted.certificateAccess?.some(g => requested.certificateAccess?.find(r => deepEqual(r, g)) == null)) {
|
|
596
|
+
throw new Error('Granted certificate access permissions are not a subset of the original request.');
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
denyActiveRequest(requestID) {
|
|
519
600
|
const matching = this.activeRequests.get(requestID);
|
|
520
|
-
if (
|
|
601
|
+
if (matching == null) {
|
|
521
602
|
throw new Error('Request ID not found.');
|
|
522
603
|
}
|
|
523
604
|
const err = new Error('The user has denied the request for permission.');
|
|
@@ -527,9 +608,12 @@ class WalletPermissionsManager {
|
|
|
527
608
|
}
|
|
528
609
|
this.activeRequests.delete(requestID);
|
|
529
610
|
}
|
|
611
|
+
async denyGroupedPermission(requestID) {
|
|
612
|
+
this.denyActiveRequest(requestID);
|
|
613
|
+
}
|
|
530
614
|
async dismissGroupedPermission(requestID) {
|
|
531
615
|
const matching = this.activeRequests.get(requestID);
|
|
532
|
-
if (
|
|
616
|
+
if (matching == null) {
|
|
533
617
|
throw new Error('Request ID not found.');
|
|
534
618
|
}
|
|
535
619
|
for (const p of matching.pending) {
|
|
@@ -538,9 +622,8 @@ class WalletPermissionsManager {
|
|
|
538
622
|
this.activeRequests.delete(requestID);
|
|
539
623
|
}
|
|
540
624
|
async grantCounterpartyPermission(params) {
|
|
541
|
-
var _a;
|
|
542
625
|
const matching = this.activeRequests.get(params.requestID);
|
|
543
|
-
if (
|
|
626
|
+
if (matching == null) {
|
|
544
627
|
throw new Error('Request ID not found.');
|
|
545
628
|
}
|
|
546
629
|
const originalRequest = matching.request;
|
|
@@ -555,7 +638,7 @@ class WalletPermissionsManager {
|
|
|
555
638
|
return p.protocolID[1];
|
|
556
639
|
return undefined;
|
|
557
640
|
};
|
|
558
|
-
if (
|
|
641
|
+
if (params.granted.protocols?.some(g => {
|
|
559
642
|
const gName = getProtoName(g);
|
|
560
643
|
if (!gName)
|
|
561
644
|
return true;
|
|
@@ -585,11 +668,11 @@ class WalletPermissionsManager {
|
|
|
585
668
|
counterparty,
|
|
586
669
|
reason: p.description
|
|
587
670
|
};
|
|
588
|
-
if (token) {
|
|
589
|
-
|
|
671
|
+
if (token == null) {
|
|
672
|
+
toCreate.push({ request, expiry });
|
|
590
673
|
}
|
|
591
674
|
else {
|
|
592
|
-
|
|
675
|
+
toRenew.push({ oldToken: token, request, expiry });
|
|
593
676
|
}
|
|
594
677
|
}
|
|
595
678
|
const created = await this.createPermissionTokensBestEffort(toCreate);
|
|
@@ -603,16 +686,7 @@ class WalletPermissionsManager {
|
|
|
603
686
|
this.activeRequests.delete(params.requestID);
|
|
604
687
|
}
|
|
605
688
|
async denyCounterpartyPermission(requestID) {
|
|
606
|
-
|
|
607
|
-
if (!matching) {
|
|
608
|
-
throw new Error('Request ID not found.');
|
|
609
|
-
}
|
|
610
|
-
const err = new Error('The user has denied the request for permission.');
|
|
611
|
-
err.code = 'ERR_PERMISSION_DENIED';
|
|
612
|
-
for (const p of matching.pending) {
|
|
613
|
-
p.reject(err);
|
|
614
|
-
}
|
|
615
|
-
this.activeRequests.delete(requestID);
|
|
689
|
+
this.denyActiveRequest(requestID);
|
|
616
690
|
}
|
|
617
691
|
/* ---------------------------------------------------------------------
|
|
618
692
|
* 3) THE "ENSURE" METHODS: CHECK IF PERMISSION EXISTS, OTHERWISE PROMPT
|
|
@@ -627,88 +701,50 @@ class WalletPermissionsManager {
|
|
|
627
701
|
// 1) adminOriginator can do anything
|
|
628
702
|
if (this.isAdminOriginator(originator))
|
|
629
703
|
return true;
|
|
630
|
-
// 2) If security level=0, we consider it
|
|
704
|
+
// 2) If security level=0, we consider it “open” usage
|
|
631
705
|
const [level, protoName] = protocolID;
|
|
632
706
|
if (level === 0)
|
|
633
707
|
return true;
|
|
634
|
-
if (level === 1)
|
|
708
|
+
if (level === 1)
|
|
635
709
|
counterparty = '';
|
|
636
|
-
}
|
|
637
710
|
// 3) If protocol is admin-reserved, block
|
|
638
711
|
if (this.isAdminProtocol(protocolID)) {
|
|
639
712
|
throw new Error(`Protocol “${protoName}” is admin-only.`);
|
|
640
713
|
}
|
|
641
714
|
// Allow the configured exceptions.
|
|
642
|
-
if (
|
|
643
|
-
return true;
|
|
644
|
-
}
|
|
645
|
-
if (usageType === 'encrypting' && !this.config.seekProtocolPermissionsForEncrypting) {
|
|
646
|
-
return true;
|
|
647
|
-
}
|
|
648
|
-
if (usageType === 'hmac' && !this.config.seekProtocolPermissionsForHMAC) {
|
|
715
|
+
if (this.isProtocolUsageTypeExempted(usageType))
|
|
649
716
|
return true;
|
|
650
|
-
|
|
651
|
-
if (usageType === 'publicKey' && !this.config.seekPermissionsForPublicKeyRevelation) {
|
|
652
|
-
return true;
|
|
653
|
-
}
|
|
654
|
-
if (usageType === 'identityKey' && !this.config.seekPermissionsForIdentityKeyRevelation) {
|
|
655
|
-
return true;
|
|
656
|
-
}
|
|
657
|
-
if (usageType === 'linkageRevelation' && !this.config.seekPermissionsForKeyLinkageRevelation) {
|
|
658
|
-
return true;
|
|
659
|
-
}
|
|
660
|
-
if (!this.config.differentiatePrivilegedOperations) {
|
|
717
|
+
if (!this.config.differentiatePrivilegedOperations)
|
|
661
718
|
privileged = false;
|
|
662
|
-
|
|
663
|
-
if (!privileged && this.isWhitelistedCounterpartyProtocol(counterparty, protocolID)) {
|
|
664
|
-
return true;
|
|
665
|
-
}
|
|
666
|
-
const cacheKey = this.buildRequestKey({
|
|
667
|
-
type: 'protocol',
|
|
668
|
-
originator,
|
|
669
|
-
privileged,
|
|
670
|
-
protocolID,
|
|
671
|
-
counterparty
|
|
672
|
-
});
|
|
673
|
-
if (this.isPermissionCached(cacheKey)) {
|
|
719
|
+
if (!privileged && this.isWhitelistedCounterpartyProtocol(counterparty, protocolID))
|
|
674
720
|
return true;
|
|
675
|
-
}
|
|
676
|
-
if (this.
|
|
721
|
+
const cacheKey = this.buildRequestKey({ type: 'protocol', originator, privileged, protocolID, counterparty });
|
|
722
|
+
if (await this.hasRecentOrPendingGrant(cacheKey))
|
|
677
723
|
return true;
|
|
678
|
-
}
|
|
679
724
|
// 4) Attempt to find a valid token in the internal basket
|
|
680
725
|
const token = await this.findProtocolToken(originator, privileged, protocolID, counterparty,
|
|
681
|
-
/*includeExpired
|
|
682
|
-
if (token) {
|
|
683
|
-
if (!this.isTokenExpired(token.expiry)) {
|
|
684
|
-
// valid and unexpired
|
|
685
|
-
this.cachePermission(cacheKey, token.expiry);
|
|
686
|
-
return true;
|
|
687
|
-
}
|
|
688
|
-
else {
|
|
689
|
-
// has a token but expired => request renewal if allowed
|
|
690
|
-
if (!seekPermission) {
|
|
691
|
-
throw new Error(`Protocol permission expired and no further user consent allowed (seekPermission=false).`);
|
|
692
|
-
}
|
|
693
|
-
return await this.requestPermissionFlow({
|
|
694
|
-
type: 'protocol',
|
|
695
|
-
originator,
|
|
696
|
-
privileged,
|
|
697
|
-
protocolID,
|
|
698
|
-
counterparty,
|
|
699
|
-
usageType,
|
|
700
|
-
reason,
|
|
701
|
-
renewal: true,
|
|
702
|
-
previousToken: token
|
|
703
|
-
});
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
else {
|
|
726
|
+
/* includeExpired= */ true, lookupValues);
|
|
727
|
+
if (token == null) {
|
|
707
728
|
// No token found => request a new one if allowed
|
|
729
|
+
if (!seekPermission)
|
|
730
|
+
throw new Error('No protocol permission token found (seekPermission=false).');
|
|
731
|
+
return await this.requestPermissionFlow({
|
|
732
|
+
type: 'protocol',
|
|
733
|
+
originator,
|
|
734
|
+
privileged,
|
|
735
|
+
protocolID,
|
|
736
|
+
counterparty,
|
|
737
|
+
usageType,
|
|
738
|
+
reason,
|
|
739
|
+
renewal: false
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
if (this.isTokenExpired(token.expiry)) {
|
|
743
|
+
// has a token but expired => request renewal if allowed
|
|
708
744
|
if (!seekPermission) {
|
|
709
|
-
throw new Error(
|
|
745
|
+
throw new Error('Protocol permission expired and no further user consent allowed (seekPermission=false).');
|
|
710
746
|
}
|
|
711
|
-
|
|
747
|
+
return await this.requestPermissionFlow({
|
|
712
748
|
type: 'protocol',
|
|
713
749
|
originator,
|
|
714
750
|
privileged,
|
|
@@ -716,10 +752,13 @@ class WalletPermissionsManager {
|
|
|
716
752
|
counterparty,
|
|
717
753
|
usageType,
|
|
718
754
|
reason,
|
|
719
|
-
renewal:
|
|
755
|
+
renewal: true,
|
|
756
|
+
previousToken: token
|
|
720
757
|
});
|
|
721
|
-
return granted;
|
|
722
758
|
}
|
|
759
|
+
// valid and unexpired
|
|
760
|
+
this.cachePermission(cacheKey, token.expiry);
|
|
761
|
+
return true;
|
|
723
762
|
}
|
|
724
763
|
/**
|
|
725
764
|
* Ensures the originator has basket usage permission for the specified basket.
|
|
@@ -730,58 +769,44 @@ class WalletPermissionsManager {
|
|
|
730
769
|
originator = normalizedOriginator;
|
|
731
770
|
if (this.isAdminOriginator(originator))
|
|
732
771
|
return true;
|
|
733
|
-
if (this.isAdminBasket(basket))
|
|
772
|
+
if (this.isAdminBasket(basket))
|
|
734
773
|
throw new Error(`Basket “${basket}” is admin-only.`);
|
|
735
|
-
|
|
736
|
-
if (usageType === 'insertion' && !this.config.seekBasketInsertionPermissions)
|
|
737
|
-
return true;
|
|
738
|
-
if (usageType === 'removal' && !this.config.seekBasketRemovalPermissions)
|
|
739
|
-
return true;
|
|
740
|
-
if (usageType === 'listing' && !this.config.seekBasketListingPermissions)
|
|
774
|
+
if (!this.isBasketUsageRequired(usageType))
|
|
741
775
|
return true;
|
|
742
776
|
const cacheKey = this.buildRequestKey({ type: 'basket', originator, basket });
|
|
743
|
-
if (this.
|
|
744
|
-
return true;
|
|
745
|
-
}
|
|
746
|
-
if (this.isRecentlyGranted(cacheKey)) {
|
|
777
|
+
if (await this.hasRecentOrPendingGrant(cacheKey))
|
|
747
778
|
return true;
|
|
748
|
-
}
|
|
749
779
|
const token = await this.findBasketToken(originator, basket, true, lookupValues);
|
|
750
|
-
if (token) {
|
|
751
|
-
if (!
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
return await this.requestPermissionFlow({
|
|
760
|
-
type: 'basket',
|
|
761
|
-
originator,
|
|
762
|
-
basket,
|
|
763
|
-
usageType,
|
|
764
|
-
reason,
|
|
765
|
-
renewal: true,
|
|
766
|
-
previousToken: token
|
|
767
|
-
});
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
else {
|
|
771
|
-
// none
|
|
772
|
-
if (!seekPermission) {
|
|
773
|
-
throw new Error(`No basket permission found, and no user consent allowed (seekPermission=false).`);
|
|
774
|
-
}
|
|
775
|
-
const granted = await this.requestPermissionFlow({
|
|
780
|
+
if (token == null) {
|
|
781
|
+
if (!seekPermission)
|
|
782
|
+
throw new Error('No basket permission found, and no user consent allowed (seekPermission=false).');
|
|
783
|
+
return await this.requestPermissionFlow({ type: 'basket', originator, basket, usageType, reason, renewal: false });
|
|
784
|
+
}
|
|
785
|
+
if (this.isTokenExpired(token.expiry)) {
|
|
786
|
+
if (!seekPermission)
|
|
787
|
+
throw new Error('Basket permission expired (seekPermission=false).');
|
|
788
|
+
return await this.requestPermissionFlow({
|
|
776
789
|
type: 'basket',
|
|
777
790
|
originator,
|
|
778
791
|
basket,
|
|
779
792
|
usageType,
|
|
780
793
|
reason,
|
|
781
|
-
renewal:
|
|
794
|
+
renewal: true,
|
|
795
|
+
previousToken: token
|
|
782
796
|
});
|
|
783
|
-
return granted;
|
|
784
797
|
}
|
|
798
|
+
this.cachePermission(cacheKey, token.expiry);
|
|
799
|
+
return true;
|
|
800
|
+
}
|
|
801
|
+
/** Returns false when the basket usageType does NOT need a permission check (config-gated). */
|
|
802
|
+
isBasketUsageRequired(usageType) {
|
|
803
|
+
if (usageType === 'insertion' && !this.config.seekBasketInsertionPermissions)
|
|
804
|
+
return false;
|
|
805
|
+
if (usageType === 'removal' && !this.config.seekBasketRemovalPermissions)
|
|
806
|
+
return false;
|
|
807
|
+
if (usageType === 'listing' && !this.config.seekBasketListingPermissions)
|
|
808
|
+
return false;
|
|
809
|
+
return true;
|
|
785
810
|
}
|
|
786
811
|
/**
|
|
787
812
|
* Ensures the originator has a valid certificate permission.
|
|
@@ -804,50 +829,42 @@ class WalletPermissionsManager {
|
|
|
804
829
|
privileged,
|
|
805
830
|
certificate: { verifier, certType, fields }
|
|
806
831
|
});
|
|
807
|
-
if (this.
|
|
808
|
-
return true;
|
|
809
|
-
}
|
|
810
|
-
if (this.isRecentlyGranted(cacheKey)) {
|
|
832
|
+
if (await this.hasRecentOrPendingGrant(cacheKey)) {
|
|
811
833
|
return true;
|
|
812
834
|
}
|
|
813
835
|
const token = await this.findCertificateToken(originator, privileged, verifier, certType, fields,
|
|
814
|
-
/*includeExpired
|
|
815
|
-
if (token) {
|
|
816
|
-
if (!
|
|
817
|
-
|
|
818
|
-
return true;
|
|
819
|
-
}
|
|
820
|
-
else {
|
|
821
|
-
if (!seekPermission) {
|
|
822
|
-
throw new Error(`Certificate permission expired (seekPermission=false).`);
|
|
823
|
-
}
|
|
824
|
-
return await this.requestPermissionFlow({
|
|
825
|
-
type: 'certificate',
|
|
826
|
-
originator,
|
|
827
|
-
privileged,
|
|
828
|
-
certificate: { verifier, certType, fields },
|
|
829
|
-
usageType,
|
|
830
|
-
reason,
|
|
831
|
-
renewal: true,
|
|
832
|
-
previousToken: token
|
|
833
|
-
});
|
|
836
|
+
/* includeExpired= */ true, lookupValues);
|
|
837
|
+
if (token == null) {
|
|
838
|
+
if (!seekPermission) {
|
|
839
|
+
throw new Error('No certificate permission found (seekPermission=false).');
|
|
834
840
|
}
|
|
841
|
+
return await this.requestPermissionFlow({
|
|
842
|
+
type: 'certificate',
|
|
843
|
+
originator,
|
|
844
|
+
privileged,
|
|
845
|
+
certificate: { verifier, certType, fields },
|
|
846
|
+
usageType,
|
|
847
|
+
reason,
|
|
848
|
+
renewal: false
|
|
849
|
+
});
|
|
835
850
|
}
|
|
836
|
-
|
|
851
|
+
if (this.isTokenExpired(token.expiry)) {
|
|
837
852
|
if (!seekPermission) {
|
|
838
|
-
throw new Error(
|
|
853
|
+
throw new Error('Certificate permission expired (seekPermission=false).');
|
|
839
854
|
}
|
|
840
|
-
|
|
855
|
+
return await this.requestPermissionFlow({
|
|
841
856
|
type: 'certificate',
|
|
842
857
|
originator,
|
|
843
858
|
privileged,
|
|
844
859
|
certificate: { verifier, certType, fields },
|
|
845
860
|
usageType,
|
|
846
861
|
reason,
|
|
847
|
-
renewal:
|
|
862
|
+
renewal: true,
|
|
863
|
+
previousToken: token
|
|
848
864
|
});
|
|
849
|
-
return granted;
|
|
850
865
|
}
|
|
866
|
+
this.cachePermission(cacheKey, token.expiry);
|
|
867
|
+
return true;
|
|
851
868
|
}
|
|
852
869
|
/**
|
|
853
870
|
* Ensures the originator has spending authorization (DSAP) for a certain satoshi amount.
|
|
@@ -863,11 +880,14 @@ class WalletPermissionsManager {
|
|
|
863
880
|
return true;
|
|
864
881
|
}
|
|
865
882
|
const cacheKey = this.buildRequestKey({ type: 'spending', originator, spending: { satoshis } });
|
|
866
|
-
|
|
883
|
+
// Spending keys are amount-scoped. The recent-grant window this adds sits
|
|
884
|
+
// inside the pre-existing permissionCache window grantPermission already
|
|
885
|
+
// wrote for spending, so accounting exposure is unchanged.
|
|
886
|
+
if (await this.hasRecentOrPendingGrant(cacheKey)) {
|
|
867
887
|
return true;
|
|
868
888
|
}
|
|
869
889
|
const token = await this.findSpendingToken(originator, lookupValues);
|
|
870
|
-
if (token
|
|
890
|
+
if (token?.authorizedAmount) {
|
|
871
891
|
// Check how much has been spent so far
|
|
872
892
|
const spentSoFar = await this.querySpentSince(token);
|
|
873
893
|
if (spentSoFar + satoshis <= token.authorizedAmount) {
|
|
@@ -892,7 +912,7 @@ class WalletPermissionsManager {
|
|
|
892
912
|
else {
|
|
893
913
|
// no token
|
|
894
914
|
if (!seekPermission) {
|
|
895
|
-
throw new Error(
|
|
915
|
+
throw new Error('No spending authorization found, (seekPermission=false).');
|
|
896
916
|
}
|
|
897
917
|
return await this.requestPermissionFlow({
|
|
898
918
|
type: 'spending',
|
|
@@ -944,9 +964,27 @@ class WalletPermissionsManager {
|
|
|
944
964
|
usageType: 'generic'
|
|
945
965
|
});
|
|
946
966
|
}
|
|
967
|
+
/**
|
|
968
|
+
* Returns true when the given usageType is configured to skip permission checks.
|
|
969
|
+
*/
|
|
970
|
+
isProtocolUsageTypeExempted(usageType) {
|
|
971
|
+
if (usageType === 'signing' && !this.config.seekProtocolPermissionsForSigning)
|
|
972
|
+
return true;
|
|
973
|
+
if (usageType === 'encrypting' && !this.config.seekProtocolPermissionsForEncrypting)
|
|
974
|
+
return true;
|
|
975
|
+
if (usageType === 'hmac' && !this.config.seekProtocolPermissionsForHMAC)
|
|
976
|
+
return true;
|
|
977
|
+
if (usageType === 'publicKey' && !this.config.seekPermissionsForPublicKeyRevelation)
|
|
978
|
+
return true;
|
|
979
|
+
if (usageType === 'identityKey' && !this.config.seekPermissionsForIdentityKeyRevelation)
|
|
980
|
+
return true;
|
|
981
|
+
if (usageType === 'linkageRevelation' && !this.config.seekPermissionsForKeyLinkageRevelation)
|
|
982
|
+
return true;
|
|
983
|
+
return false;
|
|
984
|
+
}
|
|
947
985
|
isProtocolInCounterpartyPermissions(protocolID, counterpartyPermissions) {
|
|
948
986
|
const [, name] = protocolID;
|
|
949
|
-
return
|
|
987
|
+
return counterpartyPermissions.protocols.some(p => p.protocolName === name);
|
|
950
988
|
}
|
|
951
989
|
validateCounterpartyPermissions(raw) {
|
|
952
990
|
if (!raw || !Array.isArray(raw.protocols) || raw.protocols.length === 0)
|
|
@@ -969,23 +1007,22 @@ class WalletPermissionsManager {
|
|
|
969
1007
|
};
|
|
970
1008
|
const validProtocols = raw.protocols
|
|
971
1009
|
.map((p) => {
|
|
972
|
-
var _a, _b;
|
|
973
1010
|
const protocolName = getCI(p, 'protocolName');
|
|
974
1011
|
if (typeof protocolName === 'string') {
|
|
975
1012
|
return {
|
|
976
1013
|
protocolName,
|
|
977
1014
|
protocolID: [2, protocolName],
|
|
978
|
-
description: typeof
|
|
1015
|
+
description: typeof p?.description === 'string' ? p.description : undefined
|
|
979
1016
|
};
|
|
980
1017
|
}
|
|
981
|
-
const protocolIdRaw =
|
|
1018
|
+
const protocolIdRaw = getCI(p, 'protocolID') ?? getCI(p, 'protocolId') ?? getCI(p, 'protocolid');
|
|
982
1019
|
const parsed = parseProtocolId(protocolIdRaw);
|
|
983
1020
|
if (!parsed)
|
|
984
1021
|
return null;
|
|
985
1022
|
return {
|
|
986
1023
|
protocolName: parsed,
|
|
987
1024
|
protocolID: [2, parsed],
|
|
988
|
-
description: typeof
|
|
1025
|
+
description: typeof p?.description === 'string' ? p.description : undefined
|
|
989
1026
|
};
|
|
990
1027
|
})
|
|
991
1028
|
.filter(Boolean);
|
|
@@ -998,15 +1035,15 @@ class WalletPermissionsManager {
|
|
|
998
1035
|
}
|
|
999
1036
|
async fetchManifestPermissions(originator) {
|
|
1000
1037
|
const cached = this.manifestCache.get(originator);
|
|
1001
|
-
if (cached && Date.now() - cached.fetchedAt < WalletPermissionsManager.MANIFEST_CACHE_TTL_MS) {
|
|
1038
|
+
if (cached != null && Date.now() - cached.fetchedAt < WalletPermissionsManager.MANIFEST_CACHE_TTL_MS) {
|
|
1002
1039
|
return {
|
|
1003
1040
|
groupPermissions: cached.groupPermissions,
|
|
1004
1041
|
counterpartyPermissions: cached.counterpartyPermissions
|
|
1005
1042
|
};
|
|
1006
1043
|
}
|
|
1007
1044
|
const inProgress = this.manifestFetchInProgress.get(originator);
|
|
1008
|
-
if (inProgress) {
|
|
1009
|
-
return inProgress;
|
|
1045
|
+
if (inProgress != null) {
|
|
1046
|
+
return await inProgress;
|
|
1010
1047
|
}
|
|
1011
1048
|
const fetchPromise = (async () => {
|
|
1012
1049
|
try {
|
|
@@ -1014,9 +1051,9 @@ class WalletPermissionsManager {
|
|
|
1014
1051
|
const response = await fetch(`${proto}://${originator}/manifest.json`);
|
|
1015
1052
|
if (response.ok) {
|
|
1016
1053
|
const manifest = await response.json();
|
|
1017
|
-
const namespace =
|
|
1018
|
-
const groupPermissions =
|
|
1019
|
-
const counterpartyPermissionsDeclared = this.validateCounterpartyPermissions(namespace
|
|
1054
|
+
const namespace = manifest?.metanet || manifest?.babbage;
|
|
1055
|
+
const groupPermissions = namespace?.groupPermissions || null;
|
|
1056
|
+
const counterpartyPermissionsDeclared = this.validateCounterpartyPermissions(namespace?.counterpartyPermissions);
|
|
1020
1057
|
this.manifestCache.set(originator, {
|
|
1021
1058
|
groupPermissions,
|
|
1022
1059
|
counterpartyPermissions: counterpartyPermissionsDeclared,
|
|
@@ -1025,7 +1062,9 @@ class WalletPermissionsManager {
|
|
|
1025
1062
|
return { groupPermissions, counterpartyPermissions: counterpartyPermissionsDeclared };
|
|
1026
1063
|
}
|
|
1027
1064
|
}
|
|
1028
|
-
catch
|
|
1065
|
+
catch {
|
|
1066
|
+
// Manifest fetch or parse failed — fall through to return null/null defaults below
|
|
1067
|
+
}
|
|
1029
1068
|
const result = { groupPermissions: null, counterpartyPermissions: null };
|
|
1030
1069
|
this.manifestCache.set(originator, { ...result, fetchedAt: Date.now() });
|
|
1031
1070
|
return result;
|
|
@@ -1051,17 +1090,18 @@ class WalletPermissionsManager {
|
|
|
1051
1090
|
};
|
|
1052
1091
|
const [spendingAuthorization, protocolPermissions, basketAccess, certificateAccess] = await Promise.all([
|
|
1053
1092
|
(async () => {
|
|
1054
|
-
if (
|
|
1093
|
+
if (groupPermissions.spendingAuthorization == null)
|
|
1055
1094
|
return undefined;
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1095
|
+
// A standing authorization is a grant regardless of how much of the
|
|
1096
|
+
// monthly allowance has been used — exhaustion is handled by renewal
|
|
1097
|
+
// at spend time. Checking remaining headroom here re-requests (and,
|
|
1098
|
+
// if approved, re-mints) spending after any monthly usage.
|
|
1099
|
+
const { normalized, lookupValues } = this.prepareOriginator(originator);
|
|
1100
|
+
const token = await this.findSpendingToken(normalized, lookupValues);
|
|
1101
|
+
return token != null ? undefined : groupPermissions.spendingAuthorization;
|
|
1061
1102
|
})(),
|
|
1062
1103
|
(async () => {
|
|
1063
1104
|
const protocolChecks = await Promise.all((groupPermissions.protocolPermissions || []).map(async (p) => {
|
|
1064
|
-
var _a;
|
|
1065
1105
|
if (p.counterparty === '')
|
|
1066
1106
|
return null;
|
|
1067
1107
|
const [level] = p.protocolID || [0];
|
|
@@ -1072,7 +1112,7 @@ class WalletPermissionsManager {
|
|
|
1072
1112
|
originator,
|
|
1073
1113
|
privileged: false,
|
|
1074
1114
|
protocolID: p.protocolID,
|
|
1075
|
-
counterparty:
|
|
1115
|
+
counterparty: p.counterparty ?? 'self'
|
|
1076
1116
|
});
|
|
1077
1117
|
return hasPerm ? null : p;
|
|
1078
1118
|
}));
|
|
@@ -1102,7 +1142,7 @@ class WalletPermissionsManager {
|
|
|
1102
1142
|
return certChecks.filter(Boolean);
|
|
1103
1143
|
})()
|
|
1104
1144
|
]);
|
|
1105
|
-
if (spendingAuthorization) {
|
|
1145
|
+
if (spendingAuthorization != null) {
|
|
1106
1146
|
permissionsToRequest.spendingAuthorization = spendingAuthorization;
|
|
1107
1147
|
}
|
|
1108
1148
|
permissionsToRequest.protocolPermissions = protocolPermissions;
|
|
@@ -1111,11 +1151,10 @@ class WalletPermissionsManager {
|
|
|
1111
1151
|
return permissionsToRequest;
|
|
1112
1152
|
}
|
|
1113
1153
|
hasAnyPermissionsToRequest(permissions) {
|
|
1114
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1115
1154
|
return !!(permissions.spendingAuthorization ||
|
|
1116
|
-
(
|
|
1117
|
-
(
|
|
1118
|
-
(
|
|
1155
|
+
(permissions.protocolPermissions?.length ?? 0) > 0 ||
|
|
1156
|
+
(permissions.basketAccess?.length ?? 0) > 0 ||
|
|
1157
|
+
(permissions.certificateAccess?.length ?? 0) > 0);
|
|
1119
1158
|
}
|
|
1120
1159
|
hasGroupedPermissionRequestedHandlers() {
|
|
1121
1160
|
const handlers = this.callbacks.onGroupedPermissionRequested || [];
|
|
@@ -1126,7 +1165,6 @@ class WalletPermissionsManager {
|
|
|
1126
1165
|
return handlers.some(h => typeof h === 'function');
|
|
1127
1166
|
}
|
|
1128
1167
|
async hasPactEstablished(originator, counterparty) {
|
|
1129
|
-
var _a;
|
|
1130
1168
|
if (counterparty === 'self' || counterparty === 'anyone') {
|
|
1131
1169
|
return true;
|
|
1132
1170
|
}
|
|
@@ -1135,7 +1173,7 @@ class WalletPermissionsManager {
|
|
|
1135
1173
|
return true;
|
|
1136
1174
|
}
|
|
1137
1175
|
const { counterpartyPermissions } = await this.fetchManifestPermissions(originator);
|
|
1138
|
-
if (!
|
|
1176
|
+
if (!counterpartyPermissions?.protocols?.length) {
|
|
1139
1177
|
return true;
|
|
1140
1178
|
}
|
|
1141
1179
|
const firstProtocol = counterpartyPermissions.protocols[0];
|
|
@@ -1156,7 +1194,6 @@ class WalletPermissionsManager {
|
|
|
1156
1194
|
this.pactEstablishedCache.set(cacheKey, Date.now());
|
|
1157
1195
|
}
|
|
1158
1196
|
async maybeRequestPact(currentRequest) {
|
|
1159
|
-
var _a;
|
|
1160
1197
|
if (!this.config.seekGroupedPermission) {
|
|
1161
1198
|
return null;
|
|
1162
1199
|
}
|
|
@@ -1182,7 +1219,7 @@ class WalletPermissionsManager {
|
|
|
1182
1219
|
return null;
|
|
1183
1220
|
}
|
|
1184
1221
|
const { counterpartyPermissions } = await this.fetchManifestPermissions(originator);
|
|
1185
|
-
if (!
|
|
1222
|
+
if (!counterpartyPermissions?.protocols?.length) {
|
|
1186
1223
|
return null;
|
|
1187
1224
|
}
|
|
1188
1225
|
if (!this.isProtocolInCounterpartyPermissions(currentRequest.protocolID, counterpartyPermissions)) {
|
|
@@ -1210,27 +1247,22 @@ class WalletPermissionsManager {
|
|
|
1210
1247
|
protocols: protocolsToRequest
|
|
1211
1248
|
};
|
|
1212
1249
|
const key = `pact:${originator}:${counterparty}`;
|
|
1250
|
+
await this.joinOrCreatePactRequest(key, originator, counterparty, permissionsToRequest, currentRequest.displayOriginator);
|
|
1251
|
+
this.markPactEstablished(originator, counterparty);
|
|
1252
|
+
const satisfied = await this.hasProtocolPermission({
|
|
1253
|
+
originator,
|
|
1254
|
+
privileged: false,
|
|
1255
|
+
protocolID: currentRequest.protocolID,
|
|
1256
|
+
counterparty
|
|
1257
|
+
});
|
|
1258
|
+
return satisfied ? true : null;
|
|
1259
|
+
}
|
|
1260
|
+
async joinOrCreatePactRequest(key, originator, counterparty, permissionsToRequest, displayOriginator) {
|
|
1213
1261
|
const existing = this.activeRequests.get(key);
|
|
1214
|
-
if (existing) {
|
|
1215
|
-
const existingRequest = existing.request;
|
|
1216
|
-
for (const p of permissionsToRequest.protocols) {
|
|
1217
|
-
if (!existingRequest.permissions.protocols.find(x => x.protocolName === p.protocolName)) {
|
|
1218
|
-
existingRequest.permissions.protocols.push(p);
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
await new Promise((resolve, reject) => {
|
|
1222
|
-
existing.pending.push({ resolve, reject });
|
|
1223
|
-
});
|
|
1224
|
-
}
|
|
1225
|
-
else {
|
|
1262
|
+
if (existing == null) {
|
|
1226
1263
|
const counterpartyPromise = new Promise((resolve, reject) => {
|
|
1227
1264
|
this.activeRequests.set(key, {
|
|
1228
|
-
request: {
|
|
1229
|
-
originator,
|
|
1230
|
-
counterparty,
|
|
1231
|
-
permissions: permissionsToRequest,
|
|
1232
|
-
displayOriginator: currentRequest.displayOriginator
|
|
1233
|
-
},
|
|
1265
|
+
request: { originator, counterparty, permissions: permissionsToRequest, displayOriginator },
|
|
1234
1266
|
pending: [{ resolve, reject }]
|
|
1235
1267
|
});
|
|
1236
1268
|
});
|
|
@@ -1242,19 +1274,21 @@ class WalletPermissionsManager {
|
|
|
1242
1274
|
});
|
|
1243
1275
|
await counterpartyPromise;
|
|
1244
1276
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1277
|
+
else {
|
|
1278
|
+
const existingRequest = existing.request;
|
|
1279
|
+
for (const p of permissionsToRequest.protocols) {
|
|
1280
|
+
if (!existingRequest.permissions.protocols.some(x => x.protocolName === p.protocolName)) {
|
|
1281
|
+
existingRequest.permissions.protocols.push(p);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
await new Promise((resolve, reject) => {
|
|
1285
|
+
existing.pending.push({ resolve, reject });
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
async maybeRequestPeerGroupedLevel2ProtocolPermissions(currentRequest) {
|
|
1290
|
+
if (!this.config.seekGroupedPermission) {
|
|
1291
|
+
return null;
|
|
1258
1292
|
}
|
|
1259
1293
|
if (!this.hasGroupedPermissionRequestedHandlers()) {
|
|
1260
1294
|
return null;
|
|
@@ -1267,10 +1301,10 @@ class WalletPermissionsManager {
|
|
|
1267
1301
|
return null;
|
|
1268
1302
|
}
|
|
1269
1303
|
const originator = currentRequest.originator;
|
|
1270
|
-
const privileged =
|
|
1271
|
-
const counterparty =
|
|
1304
|
+
const privileged = currentRequest.privileged ?? false;
|
|
1305
|
+
const counterparty = currentRequest.counterparty ?? 'self';
|
|
1272
1306
|
const groupPermissions = await this.fetchManifestGroupPermissions(originator);
|
|
1273
|
-
if (
|
|
1307
|
+
if (groupPermissions == null) {
|
|
1274
1308
|
return null;
|
|
1275
1309
|
}
|
|
1276
1310
|
const normalizeManifestCounterparty = (cp) => {
|
|
@@ -1281,7 +1315,7 @@ class WalletPermissionsManager {
|
|
|
1281
1315
|
return cp;
|
|
1282
1316
|
};
|
|
1283
1317
|
const manifestLevel2ForThisPeer = (groupPermissions.protocolPermissions || [])
|
|
1284
|
-
.filter(p =>
|
|
1318
|
+
.filter(p => (p.protocolID?.[0] ?? 0) === 2)
|
|
1285
1319
|
.map(p => ({
|
|
1286
1320
|
protocolID: p.protocolID,
|
|
1287
1321
|
counterparty: normalizeManifestCounterparty(p.counterparty),
|
|
@@ -1316,40 +1350,7 @@ class WalletPermissionsManager {
|
|
|
1316
1350
|
return null;
|
|
1317
1351
|
}
|
|
1318
1352
|
const key = `group-peer:${originator}:${privileged}:${counterparty}`;
|
|
1319
|
-
|
|
1320
|
-
if (existing) {
|
|
1321
|
-
const existingRequest = existing.request;
|
|
1322
|
-
if (!existingRequest.permissions.protocolPermissions) {
|
|
1323
|
-
existingRequest.permissions.protocolPermissions = [];
|
|
1324
|
-
}
|
|
1325
|
-
for (const p of permissionsToRequest.protocolPermissions || []) {
|
|
1326
|
-
if (!existingRequest.permissions.protocolPermissions.find(x => deepEqual(x, p))) {
|
|
1327
|
-
existingRequest.permissions.protocolPermissions.push(p);
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
await new Promise((resolve, reject) => {
|
|
1331
|
-
existing.pending.push({ resolve, reject });
|
|
1332
|
-
});
|
|
1333
|
-
}
|
|
1334
|
-
else {
|
|
1335
|
-
const permissions = permissionsToRequest;
|
|
1336
|
-
const groupedPromise = new Promise((resolve, reject) => {
|
|
1337
|
-
this.activeRequests.set(key, {
|
|
1338
|
-
request: {
|
|
1339
|
-
originator,
|
|
1340
|
-
permissions,
|
|
1341
|
-
displayOriginator: currentRequest.displayOriginator
|
|
1342
|
-
},
|
|
1343
|
-
pending: [{ resolve, reject }]
|
|
1344
|
-
});
|
|
1345
|
-
});
|
|
1346
|
-
await this.callEvent('onGroupedPermissionRequested', {
|
|
1347
|
-
requestID: key,
|
|
1348
|
-
originator,
|
|
1349
|
-
permissions
|
|
1350
|
-
});
|
|
1351
|
-
await groupedPromise;
|
|
1352
|
-
}
|
|
1353
|
+
await this.joinOrCreateGroupedRequest(key, originator, permissionsToRequest, currentRequest.displayOriginator);
|
|
1353
1354
|
const satisfied = await this.checkSpecificPermissionAfterGroupFlow(currentRequest);
|
|
1354
1355
|
return satisfied ? true : null;
|
|
1355
1356
|
}
|
|
@@ -1360,14 +1361,14 @@ class WalletPermissionsManager {
|
|
|
1360
1361
|
const gate = new Promise(resolve => {
|
|
1361
1362
|
release = resolve;
|
|
1362
1363
|
});
|
|
1363
|
-
const currentTail = safePriorTail.then(() => gate);
|
|
1364
|
+
const currentTail = safePriorTail.then(async () => await gate);
|
|
1364
1365
|
this.groupedPermissionFlowTail.set(originator, currentTail);
|
|
1365
1366
|
await safePriorTail;
|
|
1366
1367
|
try {
|
|
1367
1368
|
return await fn();
|
|
1368
1369
|
}
|
|
1369
1370
|
finally {
|
|
1370
|
-
release
|
|
1371
|
+
release?.();
|
|
1371
1372
|
currentTail.finally(() => {
|
|
1372
1373
|
if (this.groupedPermissionFlowTail.get(originator) === currentTail) {
|
|
1373
1374
|
this.groupedPermissionFlowTail.delete(originator);
|
|
@@ -1376,14 +1377,13 @@ class WalletPermissionsManager {
|
|
|
1376
1377
|
}
|
|
1377
1378
|
}
|
|
1378
1379
|
async checkSpecificPermissionAfterGroupFlow(request) {
|
|
1379
|
-
var _a, _b, _c;
|
|
1380
1380
|
switch (request.type) {
|
|
1381
1381
|
case 'protocol':
|
|
1382
1382
|
return await this.hasProtocolPermission({
|
|
1383
1383
|
originator: request.originator,
|
|
1384
|
-
privileged:
|
|
1384
|
+
privileged: request.privileged ?? false,
|
|
1385
1385
|
protocolID: request.protocolID,
|
|
1386
|
-
counterparty:
|
|
1386
|
+
counterparty: request.counterparty ?? 'self'
|
|
1387
1387
|
});
|
|
1388
1388
|
case 'basket':
|
|
1389
1389
|
return await this.hasBasketAccess({
|
|
@@ -1393,7 +1393,7 @@ class WalletPermissionsManager {
|
|
|
1393
1393
|
case 'certificate':
|
|
1394
1394
|
return await this.hasCertificateAccess({
|
|
1395
1395
|
originator: request.originator,
|
|
1396
|
-
privileged:
|
|
1396
|
+
privileged: request.privileged ?? false,
|
|
1397
1397
|
verifier: request.certificate.verifier,
|
|
1398
1398
|
certType: request.certificate.certType,
|
|
1399
1399
|
fields: request.certificate.fields
|
|
@@ -1408,40 +1408,38 @@ class WalletPermissionsManager {
|
|
|
1408
1408
|
}
|
|
1409
1409
|
}
|
|
1410
1410
|
isRequestIncludedInGroupPermissions(request, groupPermissions) {
|
|
1411
|
-
var _a, _b, _c, _d;
|
|
1412
1411
|
switch (request.type) {
|
|
1413
1412
|
case 'protocol': {
|
|
1414
1413
|
if (request.privileged)
|
|
1415
1414
|
return false;
|
|
1416
1415
|
const pid = request.protocolID;
|
|
1417
|
-
if (
|
|
1416
|
+
if (pid == null)
|
|
1418
1417
|
return false;
|
|
1419
|
-
const cp =
|
|
1420
|
-
return !!
|
|
1421
|
-
var _a;
|
|
1418
|
+
const cp = request.counterparty ?? 'self';
|
|
1419
|
+
return !!groupPermissions.protocolPermissions?.some(p => {
|
|
1422
1420
|
if (p.counterparty === '')
|
|
1423
1421
|
return false;
|
|
1424
1422
|
const [level] = p.protocolID || [0];
|
|
1425
1423
|
if (level === 2 && (p.counterparty === undefined || p.counterparty === null)) {
|
|
1426
1424
|
return false;
|
|
1427
1425
|
}
|
|
1428
|
-
const manifestCp = level === 1 ? '' : (
|
|
1426
|
+
const manifestCp = level === 1 ? '' : (p.counterparty ?? 'self');
|
|
1429
1427
|
return deepEqual(p.protocolID, pid) && manifestCp === cp;
|
|
1430
|
-
})
|
|
1428
|
+
});
|
|
1431
1429
|
}
|
|
1432
1430
|
case 'basket': {
|
|
1433
1431
|
const basket = request.basket;
|
|
1434
1432
|
if (!basket)
|
|
1435
1433
|
return false;
|
|
1436
|
-
return !!
|
|
1434
|
+
return !!groupPermissions.basketAccess?.some(b => b.basket === basket);
|
|
1437
1435
|
}
|
|
1438
1436
|
case 'certificate': {
|
|
1439
1437
|
if (request.privileged)
|
|
1440
1438
|
return false;
|
|
1441
1439
|
const cert = request.certificate;
|
|
1442
|
-
if (
|
|
1440
|
+
if (cert == null)
|
|
1443
1441
|
return false;
|
|
1444
|
-
return !!
|
|
1442
|
+
return !!groupPermissions.certificateAccess?.some(c => {
|
|
1445
1443
|
const fieldsA = new Set(c.fields || []);
|
|
1446
1444
|
const fieldsB = new Set(cert.fields || []);
|
|
1447
1445
|
if (fieldsA.size !== fieldsB.size)
|
|
@@ -1450,10 +1448,10 @@ class WalletPermissionsManager {
|
|
|
1450
1448
|
if (!fieldsB.has(f))
|
|
1451
1449
|
return false;
|
|
1452
1450
|
return c.type === cert.certType && c.verifierPublicKey === cert.verifier;
|
|
1453
|
-
})
|
|
1451
|
+
});
|
|
1454
1452
|
}
|
|
1455
1453
|
case 'spending':
|
|
1456
|
-
return
|
|
1454
|
+
return groupPermissions.spendingAuthorization != null;
|
|
1457
1455
|
default:
|
|
1458
1456
|
return false;
|
|
1459
1457
|
}
|
|
@@ -1464,7 +1462,7 @@ class WalletPermissionsManager {
|
|
|
1464
1462
|
}
|
|
1465
1463
|
const originator = currentRequest.originator;
|
|
1466
1464
|
const groupPermissions = await this.fetchManifestGroupPermissions(originator);
|
|
1467
|
-
if (
|
|
1465
|
+
if (groupPermissions == null) {
|
|
1468
1466
|
return null;
|
|
1469
1467
|
}
|
|
1470
1468
|
if (!this.isRequestIncludedInGroupPermissions(currentRequest, groupPermissions)) {
|
|
@@ -1475,19 +1473,20 @@ class WalletPermissionsManager {
|
|
|
1475
1473
|
return null;
|
|
1476
1474
|
}
|
|
1477
1475
|
const key = `group:${originator}`;
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1476
|
+
await this.joinOrCreateGroupedRequest(key, originator, permissionsToRequest, currentRequest.displayOriginator);
|
|
1477
|
+
const satisfied = await this.checkSpecificPermissionAfterGroupFlow(currentRequest);
|
|
1478
|
+
return satisfied ? true : null;
|
|
1479
|
+
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Joins an existing grouped permission request (piggybacks on the existing promise), or creates
|
|
1482
|
+
* a new one and fires the onGroupedPermissionRequested event.
|
|
1483
|
+
*/
|
|
1484
|
+
async joinOrCreateGroupedRequest(key, originator, permissionsToRequest, displayOriginator) {
|
|
1485
|
+
const existing = this.activeRequests.get(key);
|
|
1486
|
+
if (existing == null) {
|
|
1484
1487
|
const permPromise = new Promise((resolve, reject) => {
|
|
1485
1488
|
this.activeRequests.set(key, {
|
|
1486
|
-
request: {
|
|
1487
|
-
originator,
|
|
1488
|
-
permissions: permissionsToRequest,
|
|
1489
|
-
displayOriginator: currentRequest.displayOriginator
|
|
1490
|
-
},
|
|
1489
|
+
request: { originator, permissions: permissionsToRequest, displayOriginator },
|
|
1491
1490
|
pending: [{ resolve, reject }]
|
|
1492
1491
|
});
|
|
1493
1492
|
});
|
|
@@ -1498,8 +1497,18 @@ class WalletPermissionsManager {
|
|
|
1498
1497
|
});
|
|
1499
1498
|
await permPromise;
|
|
1500
1499
|
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1500
|
+
else {
|
|
1501
|
+
const existingRequest = existing.request;
|
|
1502
|
+
existingRequest.permissions.protocolPermissions ??= [];
|
|
1503
|
+
for (const p of permissionsToRequest.protocolPermissions || []) {
|
|
1504
|
+
if (!existingRequest.permissions.protocolPermissions.some(x => deepEqual(x, p))) {
|
|
1505
|
+
existingRequest.permissions.protocolPermissions.push(p);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
await new Promise((resolve, reject) => {
|
|
1509
|
+
existing.pending.push({ resolve, reject });
|
|
1510
|
+
});
|
|
1511
|
+
}
|
|
1503
1512
|
}
|
|
1504
1513
|
/**
|
|
1505
1514
|
* A central method that triggers the permission request flow.
|
|
@@ -1509,34 +1518,74 @@ class WalletPermissionsManager {
|
|
|
1509
1518
|
* and return a promise that resolves once permission is granted or rejects if denied.
|
|
1510
1519
|
*/
|
|
1511
1520
|
async requestPermissionFlow(r) {
|
|
1512
|
-
|
|
1521
|
+
if (!this.telemetry.enabled)
|
|
1522
|
+
return await this.requestPermissionFlowCore(r);
|
|
1523
|
+
return await this.telemetry.withSpan('wallet.permission.request', {
|
|
1524
|
+
component: 'wallet-permissions',
|
|
1525
|
+
carrier: r,
|
|
1526
|
+
attributes: {
|
|
1527
|
+
'permission.type': r.type,
|
|
1528
|
+
'permission.renewal': r.renewal === true
|
|
1529
|
+
}
|
|
1530
|
+
}, async (span) => {
|
|
1531
|
+
const result = await this.requestPermissionFlowCore(r, span.context);
|
|
1532
|
+
span.end({
|
|
1533
|
+
attributes: {
|
|
1534
|
+
'permission.granted': result
|
|
1535
|
+
}
|
|
1536
|
+
});
|
|
1537
|
+
return result;
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
async requestPermissionFlowCore(r, context) {
|
|
1541
|
+
if (context != null)
|
|
1542
|
+
this.telemetry.bindContext(r, context);
|
|
1513
1543
|
const normalizedOriginator = this.normalizeOriginator(r.originator) || r.originator;
|
|
1514
1544
|
const preparedRequest = {
|
|
1515
1545
|
...r,
|
|
1516
1546
|
originator: normalizedOriginator,
|
|
1517
|
-
displayOriginator:
|
|
1547
|
+
displayOriginator: r.displayOriginator ?? r.previousToken?.rawOriginator ?? r.originator
|
|
1518
1548
|
};
|
|
1519
|
-
if (
|
|
1549
|
+
if (context != null)
|
|
1550
|
+
this.telemetry.bindContext(preparedRequest, context);
|
|
1551
|
+
if (preparedRequest.type === 'protocol' && preparedRequest.protocolID?.[0] === 1) {
|
|
1520
1552
|
preparedRequest.counterparty = '';
|
|
1521
1553
|
}
|
|
1522
1554
|
const key = this.buildActiveRequestKey(preparedRequest);
|
|
1523
1555
|
// If there's already a queue for the same resource, we piggyback on it
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
return new Promise((resolve, reject) => {
|
|
1527
|
-
existingQueue.pending.push({ resolve, reject });
|
|
1528
|
-
});
|
|
1556
|
+
if (this.isPiggybacking(key)) {
|
|
1557
|
+
return await this.piggybackOnExistingQueue(key);
|
|
1529
1558
|
}
|
|
1530
1559
|
const pactResult = await this.maybeRequestPact(preparedRequest);
|
|
1531
|
-
if (pactResult !== null)
|
|
1560
|
+
if (pactResult !== null)
|
|
1532
1561
|
return pactResult;
|
|
1533
|
-
}
|
|
1534
1562
|
const peerGroupResult = await this.maybeRequestPeerGroupedLevel2ProtocolPermissions(preparedRequest);
|
|
1535
|
-
if (peerGroupResult !== null)
|
|
1563
|
+
if (peerGroupResult !== null)
|
|
1536
1564
|
return peerGroupResult;
|
|
1537
|
-
|
|
1565
|
+
const groupResult = await this.resolveGroupedFlow(preparedRequest, key);
|
|
1566
|
+
if (groupResult !== null)
|
|
1567
|
+
return groupResult;
|
|
1568
|
+
// Re-check after grouped flow — another waiter may have set up a queue
|
|
1569
|
+
if (this.isPiggybacking(key))
|
|
1570
|
+
return await this.piggybackOnExistingQueue(key);
|
|
1571
|
+
return await this.enqueueAndFireEvent(preparedRequest, key);
|
|
1572
|
+
}
|
|
1573
|
+
/** Returns true when an active-request queue already has pending waiters for this key. */
|
|
1574
|
+
isPiggybacking(key) {
|
|
1575
|
+
const q = this.activeRequests.get(key);
|
|
1576
|
+
return q != null && q.pending.length > 0;
|
|
1577
|
+
}
|
|
1578
|
+
/** Appends to an existing request queue and waits for resolution. */
|
|
1579
|
+
async piggybackOnExistingQueue(key) {
|
|
1580
|
+
const q = this.activeRequests.get(key);
|
|
1581
|
+
return await new Promise((resolve, reject) => {
|
|
1582
|
+
q.pending.push({ resolve, reject });
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
/** Runs the grouped-permission flow (with or without a lock) and checks post-group satisfaction. */
|
|
1586
|
+
async resolveGroupedFlow(preparedRequest, _key) {
|
|
1538
1587
|
const hadPendingGroupedFlowBefore = this.config.seekGroupedPermission && this.groupedPermissionFlowTail.has(preparedRequest.originator);
|
|
1539
|
-
let groupResult
|
|
1588
|
+
let groupResult;
|
|
1540
1589
|
if (this.config.seekGroupedPermission) {
|
|
1541
1590
|
groupResult = await this.withGroupedPermissionFlowLock(preparedRequest.originator, async () => {
|
|
1542
1591
|
return await this.maybeRequestGroupedPermissions(preparedRequest);
|
|
@@ -1545,68 +1594,79 @@ class WalletPermissionsManager {
|
|
|
1545
1594
|
else {
|
|
1546
1595
|
groupResult = await this.maybeRequestGroupedPermissions(preparedRequest);
|
|
1547
1596
|
}
|
|
1548
|
-
if (groupResult !== null)
|
|
1597
|
+
if (groupResult !== null)
|
|
1549
1598
|
return groupResult;
|
|
1550
|
-
|
|
1551
|
-
if (this.config.seekGroupedPermission && hadPendingGroupedFlowBefore) {
|
|
1599
|
+
if (hadPendingGroupedFlowBefore) {
|
|
1552
1600
|
const satisfiedAfterGroup = await this.checkSpecificPermissionAfterGroupFlow(preparedRequest);
|
|
1553
|
-
if (satisfiedAfterGroup)
|
|
1601
|
+
if (satisfiedAfterGroup)
|
|
1554
1602
|
return true;
|
|
1555
|
-
}
|
|
1556
1603
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1604
|
+
return null;
|
|
1605
|
+
}
|
|
1606
|
+
/** Creates a new active-request queue entry, fires the event, and returns the promise. */
|
|
1607
|
+
async enqueueAndFireEvent(preparedRequest, key) {
|
|
1608
|
+
const requestPromise = new Promise((resolve, reject) => {
|
|
1609
|
+
this.activeRequests.set(key, { request: preparedRequest, pending: [{ resolve, reject }] });
|
|
1610
|
+
});
|
|
1611
|
+
try {
|
|
1612
|
+
await this.firePermissionRequestEvent(preparedRequest, key);
|
|
1562
1613
|
}
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
try {
|
|
1570
|
-
// Fire the relevant onXXXRequested event (which one depends on r.type)
|
|
1571
|
-
switch (preparedRequest.type) {
|
|
1572
|
-
case 'protocol':
|
|
1573
|
-
await this.callEvent('onProtocolPermissionRequested', {
|
|
1574
|
-
...preparedRequest,
|
|
1575
|
-
counterparty: ((_a = preparedRequest.protocolID) === null || _a === void 0 ? void 0 : _a[0]) === 1 ? undefined : preparedRequest.counterparty,
|
|
1576
|
-
requestID: key
|
|
1577
|
-
});
|
|
1578
|
-
break;
|
|
1579
|
-
case 'basket':
|
|
1580
|
-
await this.callEvent('onBasketAccessRequested', {
|
|
1581
|
-
...preparedRequest,
|
|
1582
|
-
requestID: key
|
|
1583
|
-
});
|
|
1584
|
-
break;
|
|
1585
|
-
case 'certificate':
|
|
1586
|
-
await this.callEvent('onCertificateAccessRequested', {
|
|
1587
|
-
...preparedRequest,
|
|
1588
|
-
requestID: key
|
|
1589
|
-
});
|
|
1590
|
-
break;
|
|
1591
|
-
case 'spending':
|
|
1592
|
-
await this.callEvent('onSpendingAuthorizationRequested', {
|
|
1593
|
-
...preparedRequest,
|
|
1594
|
-
requestID: key
|
|
1595
|
-
});
|
|
1596
|
-
break;
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
catch (e) {
|
|
1600
|
-
const matching = this.activeRequests.get(key);
|
|
1601
|
-
if (matching) {
|
|
1602
|
-
for (const p of matching.pending) {
|
|
1603
|
-
p.reject(e);
|
|
1604
|
-
}
|
|
1605
|
-
this.activeRequests.delete(key);
|
|
1606
|
-
}
|
|
1614
|
+
catch (e) {
|
|
1615
|
+
const matching = this.activeRequests.get(key);
|
|
1616
|
+
if (matching != null) {
|
|
1617
|
+
for (const p of matching.pending)
|
|
1618
|
+
p.reject(e);
|
|
1619
|
+
this.activeRequests.delete(key);
|
|
1607
1620
|
}
|
|
1608
|
-
}
|
|
1621
|
+
}
|
|
1622
|
+
return await requestPromise;
|
|
1609
1623
|
}
|
|
1624
|
+
/** Fires the appropriate onXXXRequested event based on the request type. */
|
|
1625
|
+
async firePermissionRequestEvent(request, key) {
|
|
1626
|
+
switch (request.type) {
|
|
1627
|
+
case 'protocol':
|
|
1628
|
+
await this.callPermissionEvent(request, 'onProtocolPermissionRequested', {
|
|
1629
|
+
...request,
|
|
1630
|
+
counterparty: request.protocolID?.[0] === 1 ? undefined : request.counterparty,
|
|
1631
|
+
requestID: key
|
|
1632
|
+
});
|
|
1633
|
+
break;
|
|
1634
|
+
case 'basket':
|
|
1635
|
+
await this.callPermissionEvent(request, 'onBasketAccessRequested', { ...request, requestID: key });
|
|
1636
|
+
break;
|
|
1637
|
+
case 'certificate':
|
|
1638
|
+
await this.callPermissionEvent(request, 'onCertificateAccessRequested', { ...request, requestID: key });
|
|
1639
|
+
break;
|
|
1640
|
+
case 'spending':
|
|
1641
|
+
await this.callPermissionEvent(request, 'onSpendingAuthorizationRequested', { ...request, requestID: key });
|
|
1642
|
+
break;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
async callPermissionEvent(request, eventName, param) {
|
|
1646
|
+
this.telemetry.linkContext(request, param);
|
|
1647
|
+
await this.callEvent(eventName, param);
|
|
1648
|
+
}
|
|
1649
|
+
/* ---------------------------------------------------------------------
|
|
1650
|
+
* 4) SEARCH / DECODE / DECRYPT ON-CHAIN TOKENS (PushDrop Scripts)
|
|
1651
|
+
* --------------------------------------------------------------------- */
|
|
1652
|
+
/**
|
|
1653
|
+
* We will use a administrative "permission token encryption" protocol to store fields
|
|
1654
|
+
* in each permission's PushDrop script. This ensures that only the user's wallet
|
|
1655
|
+
* can decrypt them. In practice, this data is not super sensitive, but we still
|
|
1656
|
+
* follow the principle of least exposure.
|
|
1657
|
+
*/
|
|
1658
|
+
static PERM_TOKEN_ENCRYPTION_PROTOCOL = [
|
|
1659
|
+
2,
|
|
1660
|
+
'admin permission token encryption'
|
|
1661
|
+
];
|
|
1662
|
+
/**
|
|
1663
|
+
* Similarly, we will use a "metadata encryption" protocol to preserve the confidentiality
|
|
1664
|
+
* of transaction descriptions and input/output descriptions from lower storage layers.
|
|
1665
|
+
*/
|
|
1666
|
+
static METADATA_ENCRYPTION_PROTOCOL = [
|
|
1667
|
+
2,
|
|
1668
|
+
'admin metadata encryption'
|
|
1669
|
+
];
|
|
1610
1670
|
/** We always use `keyID="1"` and `counterparty="self"` for these encryption ops. */
|
|
1611
1671
|
async encryptPermissionTokenField(plaintext) {
|
|
1612
1672
|
const data = typeof plaintext === 'string' ? sdk_1.Utils.toArray(plaintext, 'utf8') : plaintext;
|
|
@@ -1617,7 +1677,45 @@ class WalletPermissionsManager {
|
|
|
1617
1677
|
}, this.adminOriginator);
|
|
1618
1678
|
return ciphertext;
|
|
1619
1679
|
}
|
|
1680
|
+
/**
|
|
1681
|
+
* Extracts a transaction from a `listOutputs` result's BEEF bundle, parsing
|
|
1682
|
+
* the bundle only once per result. Calling
|
|
1683
|
+
* `Transaction.fromBEEF(result.BEEF, txid)` per output re-parses the entire
|
|
1684
|
+
* bundle every time — O(n²) in the number of outputs — which can block the
|
|
1685
|
+
* caller's thread (in browser wallets, the UI) for seconds on large
|
|
1686
|
+
* permission baskets.
|
|
1687
|
+
*/
|
|
1688
|
+
transactionFromResultBeef(result, txid) {
|
|
1689
|
+
const beef = result.BEEF;
|
|
1690
|
+
if (beef != null) {
|
|
1691
|
+
let parsed = this.parsedBeefCache.get(beef);
|
|
1692
|
+
if (parsed === undefined) {
|
|
1693
|
+
try {
|
|
1694
|
+
parsed = sdk_1.Beef.fromBinary(beef);
|
|
1695
|
+
}
|
|
1696
|
+
catch {
|
|
1697
|
+
parsed = null;
|
|
1698
|
+
}
|
|
1699
|
+
this.parsedBeefCache.set(beef, parsed);
|
|
1700
|
+
}
|
|
1701
|
+
// findAtomicTransaction (not findTxid().tx) matches fromBEEF exactly:
|
|
1702
|
+
// it attaches merkle paths and sourceTransaction ancestry, which token
|
|
1703
|
+
// consumers rely on when re-serializing via tx.toBEEF().
|
|
1704
|
+
const tx = parsed?.findAtomicTransaction(txid);
|
|
1705
|
+
if (tx != null)
|
|
1706
|
+
return tx;
|
|
1707
|
+
}
|
|
1708
|
+
// Preserve the original behavior (including throwing) for bundles the
|
|
1709
|
+
// fast path can't serve.
|
|
1710
|
+
return sdk_1.Transaction.fromBEEF(beef ?? [], txid);
|
|
1711
|
+
}
|
|
1620
1712
|
async decryptPermissionTokenField(ciphertext) {
|
|
1713
|
+
// Field decrypts run in tight loops over every token in a basket; yield a
|
|
1714
|
+
// macrotask periodically so large scans don't starve the caller's event
|
|
1715
|
+
// loop (in browser wallets, that means blocking rendering and input).
|
|
1716
|
+
if (++this.tokenFieldDecryptCount % 8 === 0) {
|
|
1717
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
1718
|
+
}
|
|
1621
1719
|
try {
|
|
1622
1720
|
const { plaintext } = await this.underlying.decrypt({
|
|
1623
1721
|
ciphertext,
|
|
@@ -1626,7 +1724,8 @@ class WalletPermissionsManager {
|
|
|
1626
1724
|
}, this.adminOriginator);
|
|
1627
1725
|
return plaintext;
|
|
1628
1726
|
}
|
|
1629
|
-
catch
|
|
1727
|
+
catch {
|
|
1728
|
+
// Decryption failed (e.g. wrong key, unencrypted legacy value) — return the raw bytes unchanged
|
|
1630
1729
|
return ciphertext;
|
|
1631
1730
|
}
|
|
1632
1731
|
}
|
|
@@ -1660,7 +1759,8 @@ class WalletPermissionsManager {
|
|
|
1660
1759
|
}, this.adminOriginator);
|
|
1661
1760
|
return sdk_1.Utils.toUTF8(plaintext);
|
|
1662
1761
|
}
|
|
1663
|
-
catch
|
|
1762
|
+
catch {
|
|
1763
|
+
// Decryption failed (e.g. wrong key, unencrypted legacy value) — return original string unchanged
|
|
1664
1764
|
return ciphertext;
|
|
1665
1765
|
}
|
|
1666
1766
|
}
|
|
@@ -1669,71 +1769,200 @@ class WalletPermissionsManager {
|
|
|
1669
1769
|
const now = Math.floor(Date.now() / 1000);
|
|
1670
1770
|
return expiry > 0 && expiry < now;
|
|
1671
1771
|
}
|
|
1772
|
+
/** Decrypts the standard 6 fields from a protocol (DPACP) PushDrop script. */
|
|
1773
|
+
async decryptProtocolTokenFields(fields) {
|
|
1774
|
+
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[0]));
|
|
1775
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[1])), 10);
|
|
1776
|
+
const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[2])) === 'true';
|
|
1777
|
+
const secLevelDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[3])), 10);
|
|
1778
|
+
const protoNameDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[4]));
|
|
1779
|
+
const cptyDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[5]));
|
|
1780
|
+
return { domainDecoded, expiryDecoded, privDecoded, secLevelDecoded, protoNameDecoded, cptyDecoded };
|
|
1781
|
+
}
|
|
1782
|
+
protocolTokenTags(originator, privileged, securityLevel, protocolName, counterparty) {
|
|
1783
|
+
const tags = [
|
|
1784
|
+
`originator ${originator}`,
|
|
1785
|
+
`privileged ${!!privileged}`,
|
|
1786
|
+
`protocolName ${protocolName}`,
|
|
1787
|
+
`protocolSecurityLevel ${securityLevel}`
|
|
1788
|
+
];
|
|
1789
|
+
if (securityLevel === 2)
|
|
1790
|
+
tags.push(`counterparty ${counterparty}`);
|
|
1791
|
+
return tags;
|
|
1792
|
+
}
|
|
1793
|
+
async parseProtocolTokenOutput(result, output, expected) {
|
|
1794
|
+
const [txid, outputIndex] = this.parseOutpoint(output.outpoint);
|
|
1795
|
+
const tx = this.transactionFromResultBeef(result, txid);
|
|
1796
|
+
const decoded = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
1797
|
+
if (decoded?.fields == null || decoded.fields.length < 6)
|
|
1798
|
+
return undefined;
|
|
1799
|
+
const fields = await this.decryptProtocolTokenFields(decoded.fields);
|
|
1800
|
+
if (this.normalizeOriginator(fields.domainDecoded) !== expected.originator)
|
|
1801
|
+
return undefined;
|
|
1802
|
+
const matches = fields.privDecoded === !!expected.privileged &&
|
|
1803
|
+
fields.secLevelDecoded === expected.securityLevel &&
|
|
1804
|
+
fields.protoNameDecoded === expected.protocolName &&
|
|
1805
|
+
(fields.secLevelDecoded !== 2 || fields.cptyDecoded === expected.counterparty);
|
|
1806
|
+
if (!matches)
|
|
1807
|
+
return undefined;
|
|
1808
|
+
return {
|
|
1809
|
+
tx: tx.toBEEF(),
|
|
1810
|
+
txid,
|
|
1811
|
+
outputIndex,
|
|
1812
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
1813
|
+
satoshis: output.satoshis,
|
|
1814
|
+
originator: expected.originator,
|
|
1815
|
+
rawOriginator: fields.domainDecoded,
|
|
1816
|
+
privileged: expected.privileged,
|
|
1817
|
+
protocol: expected.protocolName,
|
|
1818
|
+
securityLevel: expected.securityLevel,
|
|
1819
|
+
expiry: fields.expiryDecoded,
|
|
1820
|
+
counterparty: fields.cptyDecoded
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
async parseBasketTokenOutput(result, output, originator, basket) {
|
|
1824
|
+
const [txid, outputIndex] = this.parseOutpoint(output.outpoint);
|
|
1825
|
+
const tx = this.transactionFromResultBeef(result, txid);
|
|
1826
|
+
const decoded = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
1827
|
+
if (decoded?.fields == null || decoded.fields.length < 3)
|
|
1828
|
+
return undefined;
|
|
1829
|
+
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(decoded.fields[0]));
|
|
1830
|
+
if (this.normalizeOriginator(domainDecoded) !== originator)
|
|
1831
|
+
return undefined;
|
|
1832
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(decoded.fields[1])), 10);
|
|
1833
|
+
const basketDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(decoded.fields[2]));
|
|
1834
|
+
if (basketDecoded !== basket)
|
|
1835
|
+
return undefined;
|
|
1836
|
+
return {
|
|
1837
|
+
tx: tx.toBEEF(),
|
|
1838
|
+
txid,
|
|
1839
|
+
outputIndex,
|
|
1840
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
1841
|
+
satoshis: output.satoshis,
|
|
1842
|
+
originator,
|
|
1843
|
+
rawOriginator: domainDecoded,
|
|
1844
|
+
basketName: basketDecoded,
|
|
1845
|
+
expiry: expiryDecoded
|
|
1846
|
+
};
|
|
1847
|
+
}
|
|
1848
|
+
async parseCertificateTokenOutput(result, output, expected) {
|
|
1849
|
+
const [txid, outputIndex] = this.parseOutpoint(output.outpoint);
|
|
1850
|
+
const tx = this.transactionFromResultBeef(result, txid);
|
|
1851
|
+
const decoded = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
1852
|
+
if (decoded?.fields == null || decoded.fields.length < 6)
|
|
1853
|
+
return undefined;
|
|
1854
|
+
const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = decoded.fields;
|
|
1855
|
+
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
1856
|
+
if (this.normalizeOriginator(domainDecoded) !== expected.originator)
|
|
1857
|
+
return undefined;
|
|
1858
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
1859
|
+
const privileged = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
|
|
1860
|
+
const certType = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw));
|
|
1861
|
+
const verifier = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw));
|
|
1862
|
+
const allFields = JSON.parse(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fieldsRaw)));
|
|
1863
|
+
const metadataMatches = privileged === !!expected.privileged && certType === expected.certType && verifier === expected.verifier;
|
|
1864
|
+
if (!metadataMatches)
|
|
1865
|
+
return undefined;
|
|
1866
|
+
const availableFields = new Set(allFields);
|
|
1867
|
+
if (expected.fields.some(field => !availableFields.has(field)))
|
|
1868
|
+
return undefined;
|
|
1869
|
+
return {
|
|
1870
|
+
tx: tx.toBEEF(),
|
|
1871
|
+
txid,
|
|
1872
|
+
outputIndex,
|
|
1873
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
1874
|
+
satoshis: output.satoshis,
|
|
1875
|
+
originator: expected.originator,
|
|
1876
|
+
rawOriginator: domainDecoded,
|
|
1877
|
+
privileged: expected.privileged,
|
|
1878
|
+
verifier,
|
|
1879
|
+
certType,
|
|
1880
|
+
certFields: allFields,
|
|
1881
|
+
expiry: expiryDecoded
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
/** Parses outpoint string "txid.vout" into [txid, outputIndex]. */
|
|
1885
|
+
parseOutpoint(outpoint) {
|
|
1886
|
+
const [txid, indexStr] = outpoint.split('.');
|
|
1887
|
+
return [txid, Number.parseInt(indexStr, 10)];
|
|
1888
|
+
}
|
|
1889
|
+
/** Normalizes a txid string to lowercase. */
|
|
1890
|
+
normalizeTxid(txid) {
|
|
1891
|
+
return (txid ?? '').toLowerCase();
|
|
1892
|
+
}
|
|
1893
|
+
/** Reverses a 32-byte hex txid (for endian normalization). */
|
|
1894
|
+
reverseHexTxid(txid) {
|
|
1895
|
+
const hex = this.normalizeTxid(txid);
|
|
1896
|
+
if (!/^[0-9a-f]{64}$/.test(hex))
|
|
1897
|
+
return hex;
|
|
1898
|
+
const bytes = hex.match(/../g);
|
|
1899
|
+
return bytes != null ? bytes.reverse().join('') : hex;
|
|
1900
|
+
}
|
|
1901
|
+
/**
|
|
1902
|
+
* Returns true when an outpoint string (e.g. "txid.vout" or "txid:vout") refers to `token`.
|
|
1903
|
+
*/
|
|
1904
|
+
tokenMatchesOutpointString(outpoint, token) {
|
|
1905
|
+
const dot = outpoint.lastIndexOf('.');
|
|
1906
|
+
const colon = outpoint.lastIndexOf(':');
|
|
1907
|
+
const sep = Math.max(dot, colon);
|
|
1908
|
+
if (sep === -1)
|
|
1909
|
+
return false;
|
|
1910
|
+
const txidPart = outpoint.slice(0, sep);
|
|
1911
|
+
const vout = Number(outpoint.slice(sep + 1));
|
|
1912
|
+
if (!Number.isFinite(vout))
|
|
1913
|
+
return false;
|
|
1914
|
+
return this.normalizeTxid(txidPart) === this.normalizeTxid(token.txid) && vout === token.outputIndex;
|
|
1915
|
+
}
|
|
1916
|
+
/**
|
|
1917
|
+
* Finds the index of the tx input that spends the given permission token.
|
|
1918
|
+
* Handles multiple potential field names for TXID and vout.
|
|
1919
|
+
*/
|
|
1920
|
+
findInputIndexForToken(tx, token) {
|
|
1921
|
+
return tx.inputs.findIndex((input) => {
|
|
1922
|
+
const txidCandidate = input?.sourceTXID ??
|
|
1923
|
+
input?.sourceTxid ??
|
|
1924
|
+
input?.sourceTxId ??
|
|
1925
|
+
input?.prevTxId ??
|
|
1926
|
+
input?.prevTxid ??
|
|
1927
|
+
input?.prevTXID ??
|
|
1928
|
+
input?.txid ??
|
|
1929
|
+
input?.txID;
|
|
1930
|
+
const voutCandidate = input?.sourceOutputIndex ?? input?.sourceOutput ?? input?.outputIndex ?? input?.vout ?? input?.prevOutIndex;
|
|
1931
|
+
if (typeof txidCandidate === 'string' && typeof voutCandidate === 'number') {
|
|
1932
|
+
const cand = this.normalizeTxid(txidCandidate);
|
|
1933
|
+
if (cand === this.normalizeTxid(token.txid) && voutCandidate === token.outputIndex)
|
|
1934
|
+
return true;
|
|
1935
|
+
if (cand === this.reverseHexTxid(token.txid) && voutCandidate === token.outputIndex)
|
|
1936
|
+
return true;
|
|
1937
|
+
}
|
|
1938
|
+
const outpointCandidate = input?.outpoint ?? input?.sourceOutpoint ?? input?.prevOutpoint;
|
|
1939
|
+
return typeof outpointCandidate === 'string' && this.tokenMatchesOutpointString(outpointCandidate, token);
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1672
1942
|
/** Looks for a DPACP permission token matching origin/domain, privileged, protocol, cpty. */
|
|
1673
1943
|
async findProtocolToken(originator, privileged, protocolID, counterparty, includeExpired, originatorLookupValues) {
|
|
1674
1944
|
const [secLevel, protoName] = protocolID;
|
|
1675
|
-
const originsToTry =
|
|
1945
|
+
const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator];
|
|
1676
1946
|
for (const originTag of originsToTry) {
|
|
1677
|
-
const tags = [
|
|
1678
|
-
`originator ${originTag}`,
|
|
1679
|
-
`privileged ${!!privileged}`,
|
|
1680
|
-
`protocolName ${protoName}`,
|
|
1681
|
-
`protocolSecurityLevel ${secLevel}`
|
|
1682
|
-
];
|
|
1683
|
-
if (secLevel === 2) {
|
|
1684
|
-
tags.push(`counterparty ${counterparty}`);
|
|
1685
|
-
}
|
|
1686
1947
|
const result = await this.underlying.listOutputs({
|
|
1687
1948
|
basket: BASKET_MAP.protocol,
|
|
1688
|
-
tags,
|
|
1949
|
+
tags: this.protocolTokenTags(originTag, privileged, secLevel, protoName, counterparty),
|
|
1689
1950
|
tagQueryMode: 'all',
|
|
1690
1951
|
include: 'entire transactions'
|
|
1691
1952
|
}, this.adminOriginator);
|
|
1692
1953
|
for (const out of result.outputs) {
|
|
1693
|
-
const
|
|
1694
|
-
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
1695
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
|
|
1696
|
-
if (!dec || !dec.fields || dec.fields.length < 6)
|
|
1697
|
-
continue;
|
|
1698
|
-
const domainRaw = dec.fields[0];
|
|
1699
|
-
const expiryRaw = dec.fields[1];
|
|
1700
|
-
const privRaw = dec.fields[2];
|
|
1701
|
-
const secLevelRaw = dec.fields[3];
|
|
1702
|
-
const protoNameRaw = dec.fields[4];
|
|
1703
|
-
const counterpartyRaw = dec.fields[5];
|
|
1704
|
-
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
1705
|
-
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
1706
|
-
if (normalizedDomain !== originator) {
|
|
1707
|
-
continue;
|
|
1708
|
-
}
|
|
1709
|
-
const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
1710
|
-
const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
|
|
1711
|
-
const secLevelDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(secLevelRaw)), 10);
|
|
1712
|
-
const protoNameDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(protoNameRaw));
|
|
1713
|
-
const cptyDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(counterpartyRaw));
|
|
1714
|
-
if (privDecoded !== !!privileged ||
|
|
1715
|
-
secLevelDecoded !== secLevel ||
|
|
1716
|
-
protoNameDecoded !== protoName ||
|
|
1717
|
-
(secLevelDecoded === 2 && cptyDecoded !== counterparty)) {
|
|
1718
|
-
continue;
|
|
1719
|
-
}
|
|
1720
|
-
if (!includeExpired && this.isTokenExpired(expiryDecoded)) {
|
|
1721
|
-
continue;
|
|
1722
|
-
}
|
|
1723
|
-
return {
|
|
1724
|
-
tx: tx.toBEEF(),
|
|
1725
|
-
txid: out.outpoint.split('.')[0],
|
|
1726
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
1727
|
-
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
1728
|
-
satoshis: out.satoshis,
|
|
1954
|
+
const token = await this.parseProtocolTokenOutput(result, out, {
|
|
1729
1955
|
originator,
|
|
1730
|
-
rawOriginator: domainDecoded,
|
|
1731
1956
|
privileged,
|
|
1732
|
-
protocol: protoName,
|
|
1733
1957
|
securityLevel: secLevel,
|
|
1734
|
-
|
|
1735
|
-
counterparty
|
|
1736
|
-
};
|
|
1958
|
+
protocolName: protoName,
|
|
1959
|
+
counterparty
|
|
1960
|
+
});
|
|
1961
|
+
if (token == null)
|
|
1962
|
+
continue;
|
|
1963
|
+
if (!includeExpired && this.isTokenExpired(token.expiry))
|
|
1964
|
+
continue;
|
|
1965
|
+
return token;
|
|
1737
1966
|
}
|
|
1738
1967
|
}
|
|
1739
1968
|
return undefined;
|
|
@@ -1741,78 +1970,37 @@ class WalletPermissionsManager {
|
|
|
1741
1970
|
/** Finds ALL DPACP permission tokens matching origin/domain, privileged, protocol, cpty. Never filters by expiry. */
|
|
1742
1971
|
async findAllProtocolTokens(originator, privileged, protocolID, counterparty, originatorLookupValues) {
|
|
1743
1972
|
const [secLevel, protoName] = protocolID;
|
|
1744
|
-
const originsToTry =
|
|
1973
|
+
const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator];
|
|
1745
1974
|
const matches = [];
|
|
1746
1975
|
const seen = new Set();
|
|
1747
1976
|
for (const originTag of originsToTry) {
|
|
1748
|
-
const tags = [
|
|
1749
|
-
`originator ${originTag}`,
|
|
1750
|
-
`privileged ${!!privileged}`,
|
|
1751
|
-
`protocolName ${protoName}`,
|
|
1752
|
-
`protocolSecurityLevel ${secLevel}`
|
|
1753
|
-
];
|
|
1754
|
-
if (secLevel === 2) {
|
|
1755
|
-
tags.push(`counterparty ${counterparty}`);
|
|
1756
|
-
}
|
|
1757
1977
|
const result = await this.underlying.listOutputs({
|
|
1758
1978
|
basket: BASKET_MAP.protocol,
|
|
1759
|
-
tags,
|
|
1979
|
+
tags: this.protocolTokenTags(originTag, privileged, secLevel, protoName, counterparty),
|
|
1760
1980
|
tagQueryMode: 'all',
|
|
1761
1981
|
include: 'entire transactions'
|
|
1762
1982
|
}, this.adminOriginator);
|
|
1763
1983
|
for (const out of result.outputs) {
|
|
1764
1984
|
if (seen.has(out.outpoint))
|
|
1765
1985
|
continue;
|
|
1766
|
-
const
|
|
1767
|
-
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
1768
|
-
const vout = Number(outputIndexStr);
|
|
1769
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[vout].lockingScript);
|
|
1770
|
-
if (!dec || !dec.fields || dec.fields.length < 6)
|
|
1771
|
-
continue;
|
|
1772
|
-
const domainRaw = dec.fields[0];
|
|
1773
|
-
const expiryRaw = dec.fields[1];
|
|
1774
|
-
const privRaw = dec.fields[2];
|
|
1775
|
-
const secLevelRaw = dec.fields[3];
|
|
1776
|
-
const protoNameRaw = dec.fields[4];
|
|
1777
|
-
const counterpartyRaw = dec.fields[5];
|
|
1778
|
-
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
1779
|
-
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
1780
|
-
if (normalizedDomain !== originator) {
|
|
1781
|
-
continue;
|
|
1782
|
-
}
|
|
1783
|
-
const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
1784
|
-
const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
|
|
1785
|
-
const secLevelDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(secLevelRaw)), 10);
|
|
1786
|
-
const protoNameDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(protoNameRaw));
|
|
1787
|
-
const cptyDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(counterpartyRaw));
|
|
1788
|
-
if (privDecoded !== !!privileged ||
|
|
1789
|
-
secLevelDecoded !== secLevel ||
|
|
1790
|
-
protoNameDecoded !== protoName ||
|
|
1791
|
-
(secLevelDecoded === 2 && cptyDecoded !== counterparty)) {
|
|
1792
|
-
continue;
|
|
1793
|
-
}
|
|
1794
|
-
seen.add(out.outpoint);
|
|
1795
|
-
matches.push({
|
|
1796
|
-
tx: tx.toBEEF(),
|
|
1797
|
-
txid,
|
|
1798
|
-
outputIndex: vout,
|
|
1799
|
-
outputScript: tx.outputs[vout].lockingScript.toHex(),
|
|
1800
|
-
satoshis: out.satoshis,
|
|
1986
|
+
const token = await this.parseProtocolTokenOutput(result, out, {
|
|
1801
1987
|
originator,
|
|
1802
|
-
rawOriginator: domainDecoded,
|
|
1803
1988
|
privileged,
|
|
1804
|
-
protocol: protoName,
|
|
1805
1989
|
securityLevel: secLevel,
|
|
1806
|
-
|
|
1807
|
-
counterparty
|
|
1990
|
+
protocolName: protoName,
|
|
1991
|
+
counterparty
|
|
1808
1992
|
});
|
|
1993
|
+
if (token == null)
|
|
1994
|
+
continue;
|
|
1995
|
+
seen.add(out.outpoint);
|
|
1996
|
+
matches.push(token);
|
|
1809
1997
|
}
|
|
1810
1998
|
}
|
|
1811
1999
|
return matches;
|
|
1812
2000
|
}
|
|
1813
2001
|
/** Looks for a DBAP token matching (originator, basket). */
|
|
1814
2002
|
async findBasketToken(originator, basket, includeExpired, originatorLookupValues) {
|
|
1815
|
-
const originsToTry =
|
|
2003
|
+
const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator];
|
|
1816
2004
|
for (const originTag of originsToTry) {
|
|
1817
2005
|
const result = await this.underlying.listOutputs({
|
|
1818
2006
|
basket: BASKET_MAP.basket,
|
|
@@ -1821,43 +2009,19 @@ class WalletPermissionsManager {
|
|
|
1821
2009
|
include: 'entire transactions'
|
|
1822
2010
|
}, this.adminOriginator);
|
|
1823
2011
|
for (const out of result.outputs) {
|
|
1824
|
-
const
|
|
1825
|
-
|
|
1826
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
|
|
1827
|
-
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 3)
|
|
1828
|
-
continue;
|
|
1829
|
-
const domainRaw = dec.fields[0];
|
|
1830
|
-
const expiryRaw = dec.fields[1];
|
|
1831
|
-
const basketRaw = dec.fields[2];
|
|
1832
|
-
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
1833
|
-
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
1834
|
-
if (normalizedDomain !== originator) {
|
|
1835
|
-
continue;
|
|
1836
|
-
}
|
|
1837
|
-
const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
1838
|
-
const basketDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(basketRaw));
|
|
1839
|
-
if (basketDecoded !== basket)
|
|
2012
|
+
const token = await this.parseBasketTokenOutput(result, out, originator, basket);
|
|
2013
|
+
if (token == null)
|
|
1840
2014
|
continue;
|
|
1841
|
-
if (!includeExpired && this.isTokenExpired(
|
|
2015
|
+
if (!includeExpired && this.isTokenExpired(token.expiry))
|
|
1842
2016
|
continue;
|
|
1843
|
-
return
|
|
1844
|
-
tx: tx.toBEEF(),
|
|
1845
|
-
txid: out.outpoint.split('.')[0],
|
|
1846
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
1847
|
-
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
1848
|
-
satoshis: out.satoshis,
|
|
1849
|
-
originator,
|
|
1850
|
-
rawOriginator: domainDecoded,
|
|
1851
|
-
basketName: basketDecoded,
|
|
1852
|
-
expiry: expiryDecoded
|
|
1853
|
-
};
|
|
2017
|
+
return token;
|
|
1854
2018
|
}
|
|
1855
2019
|
}
|
|
1856
2020
|
return undefined;
|
|
1857
2021
|
}
|
|
1858
2022
|
/** Looks for a DCAP token matching (origin, privileged, verifier, certType, fields subset). */
|
|
1859
2023
|
async findCertificateToken(originator, privileged, verifier, certType, fields, includeExpired, originatorLookupValues) {
|
|
1860
|
-
const originsToTry =
|
|
2024
|
+
const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator];
|
|
1861
2025
|
for (const originTag of originsToTry) {
|
|
1862
2026
|
const result = await this.underlying.listOutputs({
|
|
1863
2027
|
basket: BASKET_MAP.certificate,
|
|
@@ -1866,55 +2030,25 @@ class WalletPermissionsManager {
|
|
|
1866
2030
|
include: 'entire transactions'
|
|
1867
2031
|
}, this.adminOriginator);
|
|
1868
2032
|
for (const out of result.outputs) {
|
|
1869
|
-
const
|
|
1870
|
-
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
1871
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
|
|
1872
|
-
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 6)
|
|
1873
|
-
continue;
|
|
1874
|
-
const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = dec.fields;
|
|
1875
|
-
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
1876
|
-
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
1877
|
-
if (normalizedDomain !== originator) {
|
|
1878
|
-
continue;
|
|
1879
|
-
}
|
|
1880
|
-
const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
1881
|
-
const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
|
|
1882
|
-
const typeDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw));
|
|
1883
|
-
const verifierDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw));
|
|
1884
|
-
const fieldsJson = await this.decryptPermissionTokenField(fieldsRaw);
|
|
1885
|
-
const allFields = JSON.parse(sdk_1.Utils.toUTF8(fieldsJson));
|
|
1886
|
-
if (privDecoded !== !!privileged || typeDecoded !== certType || verifierDec !== verifier) {
|
|
1887
|
-
continue;
|
|
1888
|
-
}
|
|
1889
|
-
// Check if 'fields' is a subset of 'allFields'
|
|
1890
|
-
const setAll = new Set(allFields);
|
|
1891
|
-
if (fields.some(f => !setAll.has(f))) {
|
|
1892
|
-
continue;
|
|
1893
|
-
}
|
|
1894
|
-
if (!includeExpired && this.isTokenExpired(expiryDecoded)) {
|
|
1895
|
-
continue;
|
|
1896
|
-
}
|
|
1897
|
-
return {
|
|
1898
|
-
tx: tx.toBEEF(),
|
|
1899
|
-
txid: out.outpoint.split('.')[0],
|
|
1900
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
1901
|
-
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
1902
|
-
satoshis: out.satoshis,
|
|
2033
|
+
const token = await this.parseCertificateTokenOutput(result, out, {
|
|
1903
2034
|
originator,
|
|
1904
|
-
rawOriginator: domainDecoded,
|
|
1905
2035
|
privileged,
|
|
1906
|
-
verifier
|
|
1907
|
-
certType
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
2036
|
+
verifier,
|
|
2037
|
+
certType,
|
|
2038
|
+
fields
|
|
2039
|
+
});
|
|
2040
|
+
if (token == null)
|
|
2041
|
+
continue;
|
|
2042
|
+
if (!includeExpired && this.isTokenExpired(token.expiry))
|
|
2043
|
+
continue;
|
|
2044
|
+
return token;
|
|
1911
2045
|
}
|
|
1912
2046
|
}
|
|
1913
2047
|
return undefined;
|
|
1914
2048
|
}
|
|
1915
2049
|
/** Looks for a DSAP token matching origin, returning the first one found. */
|
|
1916
2050
|
async findSpendingToken(originator, originatorLookupValues) {
|
|
1917
|
-
const originsToTry =
|
|
2051
|
+
const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator];
|
|
1918
2052
|
for (const originTag of originsToTry) {
|
|
1919
2053
|
const result = await this.underlying.listOutputs({
|
|
1920
2054
|
basket: BASKET_MAP.spending,
|
|
@@ -1924,9 +2058,9 @@ class WalletPermissionsManager {
|
|
|
1924
2058
|
}, this.adminOriginator);
|
|
1925
2059
|
for (const out of result.outputs) {
|
|
1926
2060
|
const [txid, outputIndexStr] = out.outpoint.split('.');
|
|
1927
|
-
const tx =
|
|
2061
|
+
const tx = this.transactionFromResultBeef(result, txid);
|
|
1928
2062
|
const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
|
|
1929
|
-
if (!
|
|
2063
|
+
if (!dec?.fields || dec.fields.length < 2)
|
|
1930
2064
|
continue;
|
|
1931
2065
|
const domainRaw = dec.fields[0];
|
|
1932
2066
|
const amtRaw = dec.fields[1];
|
|
@@ -1935,11 +2069,11 @@ class WalletPermissionsManager {
|
|
|
1935
2069
|
if (normalizedDomain !== originator)
|
|
1936
2070
|
continue;
|
|
1937
2071
|
const amtDecodedStr = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(amtRaw));
|
|
1938
|
-
const authorizedAmount = parseInt(amtDecodedStr, 10);
|
|
2072
|
+
const authorizedAmount = Number.parseInt(amtDecodedStr, 10);
|
|
1939
2073
|
return {
|
|
1940
2074
|
tx: tx.toBEEF(),
|
|
1941
2075
|
txid: out.outpoint.split('.')[0],
|
|
1942
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
2076
|
+
outputIndex: Number.parseInt(out.outpoint.split('.')[1], 10),
|
|
1943
2077
|
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
1944
2078
|
satoshis: out.satoshis,
|
|
1945
2079
|
originator,
|
|
@@ -2021,9 +2155,9 @@ class WalletPermissionsManager {
|
|
|
2021
2155
|
}, this.adminOriginator);
|
|
2022
2156
|
}
|
|
2023
2157
|
async mapWithConcurrency(items, concurrency, fn) {
|
|
2024
|
-
if (
|
|
2158
|
+
if (items.length === 0)
|
|
2025
2159
|
return [];
|
|
2026
|
-
const results =
|
|
2160
|
+
const results = Array.from({ length: items.length });
|
|
2027
2161
|
let i = 0;
|
|
2028
2162
|
const worker = async () => {
|
|
2029
2163
|
while (true) {
|
|
@@ -2033,11 +2167,11 @@ class WalletPermissionsManager {
|
|
|
2033
2167
|
results[idx] = await fn(items[idx]);
|
|
2034
2168
|
}
|
|
2035
2169
|
};
|
|
2036
|
-
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
2170
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, async () => await worker()));
|
|
2037
2171
|
return results;
|
|
2038
2172
|
}
|
|
2039
2173
|
async runBestEffortBatches(items, chunkSize, runChunk) {
|
|
2040
|
-
if (
|
|
2174
|
+
if (items.length === 0)
|
|
2041
2175
|
return [];
|
|
2042
2176
|
const out = [];
|
|
2043
2177
|
for (let i = 0; i < items.length; i += chunkSize) {
|
|
@@ -2084,8 +2218,8 @@ class WalletPermissionsManager {
|
|
|
2084
2218
|
}
|
|
2085
2219
|
async createPermissionTokensBestEffort(items) {
|
|
2086
2220
|
const CHUNK = 25;
|
|
2087
|
-
return this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2088
|
-
const built = await this.mapWithConcurrency(chunk, 8, c => this.buildPermissionOutput(c.request, c.expiry, c.amount));
|
|
2221
|
+
return await this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2222
|
+
const built = await this.mapWithConcurrency(chunk, 8, async (c) => await this.buildPermissionOutput(c.request, c.expiry, c.amount));
|
|
2089
2223
|
await this.createAction({
|
|
2090
2224
|
description: `Grant ${built.length} permissions`,
|
|
2091
2225
|
outputs: built.map(b => b.output),
|
|
@@ -2096,8 +2230,8 @@ class WalletPermissionsManager {
|
|
|
2096
2230
|
}
|
|
2097
2231
|
async renewPermissionTokensBestEffort(items) {
|
|
2098
2232
|
const CHUNK = 15;
|
|
2099
|
-
return this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2100
|
-
const built = await this.mapWithConcurrency(chunk, 8, c => this.buildPermissionOutput(c.request, c.expiry, c.amount));
|
|
2233
|
+
return await this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2234
|
+
const built = await this.mapWithConcurrency(chunk, 8, async (c) => await this.buildPermissionOutput(c.request, c.expiry, c.amount));
|
|
2101
2235
|
const inputBeef = new sdk_1.Beef();
|
|
2102
2236
|
for (const c of chunk) {
|
|
2103
2237
|
inputBeef.mergeBeef(sdk_1.Beef.fromBinary(c.oldToken.tx));
|
|
@@ -2117,7 +2251,7 @@ class WalletPermissionsManager {
|
|
|
2117
2251
|
signAndProcess: false
|
|
2118
2252
|
}
|
|
2119
2253
|
}, this.adminOriginator);
|
|
2120
|
-
if (!
|
|
2254
|
+
if (!signableTransaction?.reference || !signableTransaction.tx) {
|
|
2121
2255
|
throw new Error('Failed to create signable transaction');
|
|
2122
2256
|
}
|
|
2123
2257
|
const partialTx = sdk_1.Transaction.fromAtomicBEEF(signableTransaction.tx);
|
|
@@ -2139,8 +2273,7 @@ class WalletPermissionsManager {
|
|
|
2139
2273
|
});
|
|
2140
2274
|
}
|
|
2141
2275
|
async coalescePermissionTokens(oldTokens, newScript, opts) {
|
|
2142
|
-
|
|
2143
|
-
if (!(oldTokens === null || oldTokens === void 0 ? void 0 : oldTokens.length))
|
|
2276
|
+
if (!oldTokens?.length)
|
|
2144
2277
|
throw new Error('No permission tokens to coalesce');
|
|
2145
2278
|
if (oldTokens.length < 2)
|
|
2146
2279
|
throw new Error('Need at least 2 tokens to coalesce');
|
|
@@ -2151,7 +2284,7 @@ class WalletPermissionsManager {
|
|
|
2151
2284
|
inputBeef.mergeBeef(sdk_1.Beef.fromBinary(token.tx));
|
|
2152
2285
|
}
|
|
2153
2286
|
const { signableTransaction } = await this.createAction({
|
|
2154
|
-
description:
|
|
2287
|
+
description: opts?.description ?? `Coalesce ${oldTokens.length} permission tokens`,
|
|
2155
2288
|
inputBEEF: inputBeef.toBinary(),
|
|
2156
2289
|
inputs: oldTokens.map((t, i) => ({
|
|
2157
2290
|
outpoint: `${t.txid}.${t.outputIndex}`,
|
|
@@ -2163,8 +2296,8 @@ class WalletPermissionsManager {
|
|
|
2163
2296
|
lockingScript: newScript.toHex(),
|
|
2164
2297
|
satoshis: 1,
|
|
2165
2298
|
outputDescription: 'Renewed permission token',
|
|
2166
|
-
...(
|
|
2167
|
-
...(
|
|
2299
|
+
...(opts?.basket ? { basket: opts.basket } : {}),
|
|
2300
|
+
...(opts?.tags == null ? {} : { tags: opts.tags })
|
|
2168
2301
|
}
|
|
2169
2302
|
],
|
|
2170
2303
|
options: {
|
|
@@ -2173,7 +2306,7 @@ class WalletPermissionsManager {
|
|
|
2173
2306
|
signAndProcess: false
|
|
2174
2307
|
}
|
|
2175
2308
|
}, this.adminOriginator);
|
|
2176
|
-
if (!
|
|
2309
|
+
if (!signableTransaction?.reference || !signableTransaction.tx) {
|
|
2177
2310
|
throw new Error('Failed to create signable transaction');
|
|
2178
2311
|
}
|
|
2179
2312
|
// 2) Sign each input - each token needs its own unlocker with the correct locking script
|
|
@@ -2268,11 +2401,10 @@ class WalletPermissionsManager {
|
|
|
2268
2401
|
* (protocol / basket / certificate / spending).
|
|
2269
2402
|
*/
|
|
2270
2403
|
async buildPushdropFields(r, expiry, amount) {
|
|
2271
|
-
var _a, _b;
|
|
2272
2404
|
switch (r.type) {
|
|
2273
2405
|
case 'protocol': {
|
|
2274
2406
|
const [secLevel, protoName] = r.protocolID;
|
|
2275
|
-
const counterparty = secLevel === 2 ? (
|
|
2407
|
+
const counterparty = secLevel === 2 ? (r.counterparty ?? 'self') : '';
|
|
2276
2408
|
return [
|
|
2277
2409
|
await this.encryptPermissionTokenField(r.originator), // domain
|
|
2278
2410
|
await this.encryptPermissionTokenField(String(expiry)), // expiry
|
|
@@ -2302,7 +2434,7 @@ class WalletPermissionsManager {
|
|
|
2302
2434
|
}
|
|
2303
2435
|
case 'spending': {
|
|
2304
2436
|
// DSAP
|
|
2305
|
-
const authAmt = amount
|
|
2437
|
+
const authAmt = amount ?? (r.spending?.satoshis || 0);
|
|
2306
2438
|
return [
|
|
2307
2439
|
await this.encryptPermissionTokenField(r.originator),
|
|
2308
2440
|
await this.encryptPermissionTokenField(String(authAmt))
|
|
@@ -2315,15 +2447,12 @@ class WalletPermissionsManager {
|
|
|
2315
2447
|
* origin, basket, privileged, protocol name, etc.
|
|
2316
2448
|
*/
|
|
2317
2449
|
buildTagsForRequest(r) {
|
|
2318
|
-
var _a;
|
|
2319
2450
|
const tags = [`originator ${r.originator}`];
|
|
2320
2451
|
switch (r.type) {
|
|
2321
2452
|
case 'protocol': {
|
|
2322
|
-
tags.push(`privileged ${!!r.privileged}`);
|
|
2323
|
-
tags.push(`protocolName ${r.protocolID[1]}`);
|
|
2324
|
-
tags.push(`protocolSecurityLevel ${r.protocolID[0]}`);
|
|
2453
|
+
tags.push(`privileged ${!!r.privileged}`, `protocolName ${r.protocolID[1]}`, `protocolSecurityLevel ${r.protocolID[0]}`);
|
|
2325
2454
|
if (r.protocolID[0] === 2) {
|
|
2326
|
-
tags.push(`counterparty ${
|
|
2455
|
+
tags.push(`counterparty ${r.counterparty ?? 'self'}`);
|
|
2327
2456
|
}
|
|
2328
2457
|
break;
|
|
2329
2458
|
}
|
|
@@ -2332,9 +2461,7 @@ class WalletPermissionsManager {
|
|
|
2332
2461
|
break;
|
|
2333
2462
|
}
|
|
2334
2463
|
case 'certificate': {
|
|
2335
|
-
tags.push(`privileged ${!!r.privileged}`);
|
|
2336
|
-
tags.push(`type ${r.certificate.certType}`);
|
|
2337
|
-
tags.push(`verifier ${r.certificate.verifier}`);
|
|
2464
|
+
tags.push(`privileged ${!!r.privileged}`, `type ${r.certificate.certType}`, `verifier ${r.certificate.verifier}`);
|
|
2338
2465
|
break;
|
|
2339
2466
|
}
|
|
2340
2467
|
case 'spending': {
|
|
@@ -2357,74 +2484,62 @@ class WalletPermissionsManager {
|
|
|
2357
2484
|
* @returns Array of permission tokens that match the filter criteria
|
|
2358
2485
|
*/
|
|
2359
2486
|
async listProtocolPermissions({ originator, privileged, protocolName, protocolSecurityLevel, counterparty } = {}) {
|
|
2360
|
-
const
|
|
2361
|
-
const baseTags = [];
|
|
2362
|
-
if (privileged !== undefined) {
|
|
2363
|
-
baseTags.push(`privileged ${!!privileged}`);
|
|
2364
|
-
}
|
|
2365
|
-
if (protocolName) {
|
|
2366
|
-
baseTags.push(`protocolName ${protocolName}`);
|
|
2367
|
-
}
|
|
2368
|
-
if (protocolSecurityLevel !== undefined) {
|
|
2369
|
-
baseTags.push(`protocolSecurityLevel ${protocolSecurityLevel}`);
|
|
2370
|
-
}
|
|
2371
|
-
if (counterparty) {
|
|
2372
|
-
baseTags.push(`counterparty ${counterparty}`);
|
|
2373
|
-
}
|
|
2487
|
+
const baseTags = this.buildProtocolFilterTags({ privileged, protocolName, protocolSecurityLevel, counterparty });
|
|
2374
2488
|
const originFilter = originator ? this.prepareOriginator(originator) : undefined;
|
|
2375
|
-
const originVariants = originFilter
|
|
2489
|
+
const originVariants = originFilter == null ? [undefined] : originFilter.lookupValues;
|
|
2376
2490
|
const seen = new Set();
|
|
2377
2491
|
const tokens = [];
|
|
2378
2492
|
for (const originTag of originVariants) {
|
|
2379
|
-
const tags = [...baseTags];
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
}
|
|
2383
|
-
const result = await this.underlying.listOutputs({
|
|
2384
|
-
basket: basketName,
|
|
2385
|
-
tags,
|
|
2386
|
-
tagQueryMode: 'all',
|
|
2387
|
-
include: 'entire transactions',
|
|
2388
|
-
limit: 10000
|
|
2389
|
-
}, this.adminOriginator);
|
|
2390
|
-
for (const out of result.outputs) {
|
|
2391
|
-
if (seen.has(out.outpoint))
|
|
2392
|
-
continue;
|
|
2393
|
-
const [txid, outputIndexStr] = out.outpoint.split('.');
|
|
2394
|
-
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
2395
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
|
|
2396
|
-
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 6)
|
|
2397
|
-
continue;
|
|
2398
|
-
const [domainRaw, expiryRaw, privRaw, secRaw, protoRaw, cptyRaw] = dec.fields;
|
|
2399
|
-
const domainDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
2400
|
-
const normalizedDomain = this.normalizeOriginator(domainDec);
|
|
2401
|
-
if (originFilter && normalizedDomain !== originFilter.normalized) {
|
|
2402
|
-
continue;
|
|
2403
|
-
}
|
|
2404
|
-
const expiryDec = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
2405
|
-
const privDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
|
|
2406
|
-
const secDec = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(secRaw)), 10);
|
|
2407
|
-
const protoDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(protoRaw));
|
|
2408
|
-
const cptyDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(cptyRaw));
|
|
2409
|
-
seen.add(out.outpoint);
|
|
2410
|
-
tokens.push({
|
|
2411
|
-
tx: tx.toBEEF(),
|
|
2412
|
-
txid: out.outpoint.split('.')[0],
|
|
2413
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
2414
|
-
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
2415
|
-
satoshis: out.satoshis,
|
|
2416
|
-
originator: normalizedDomain,
|
|
2417
|
-
rawOriginator: domainDec,
|
|
2418
|
-
expiry: expiryDec,
|
|
2419
|
-
privileged: privDec,
|
|
2420
|
-
securityLevel: secDec,
|
|
2421
|
-
protocol: protoDec,
|
|
2422
|
-
counterparty: cptyDec
|
|
2423
|
-
});
|
|
2424
|
-
}
|
|
2493
|
+
const tags = originTag != null ? [...baseTags, `originator ${originTag}`] : [...baseTags];
|
|
2494
|
+
const result = await this.underlying.listOutputs({ basket: BASKET_MAP.protocol, tags, tagQueryMode: 'all', include: 'entire transactions', limit: 10000 }, this.adminOriginator);
|
|
2495
|
+
await this.collectProtocolTokens(result, originFilter, seen, tokens);
|
|
2425
2496
|
}
|
|
2426
2497
|
return tokens;
|
|
2427
2498
|
}
|
|
2499
|
+
/** Builds the base tag array for protocol permission listing. */
|
|
2500
|
+
buildProtocolFilterTags({ privileged, protocolName, protocolSecurityLevel, counterparty }) {
|
|
2501
|
+
const tags = [];
|
|
2502
|
+
if (privileged !== undefined)
|
|
2503
|
+
tags.push(`privileged ${!!privileged}`);
|
|
2504
|
+
if (protocolName)
|
|
2505
|
+
tags.push(`protocolName ${protocolName}`);
|
|
2506
|
+
if (protocolSecurityLevel !== undefined)
|
|
2507
|
+
tags.push(`protocolSecurityLevel ${protocolSecurityLevel}`);
|
|
2508
|
+
if (counterparty)
|
|
2509
|
+
tags.push(`counterparty ${counterparty}`);
|
|
2510
|
+
return tags;
|
|
2511
|
+
}
|
|
2512
|
+
/** Decodes and appends protocol permission tokens from a listOutputs result. */
|
|
2513
|
+
async collectProtocolTokens(result, originFilter, seen, tokens) {
|
|
2514
|
+
for (const out of result.outputs) {
|
|
2515
|
+
if (seen.has(out.outpoint))
|
|
2516
|
+
continue;
|
|
2517
|
+
const [txid, outputIndex] = this.parseOutpoint(out.outpoint);
|
|
2518
|
+
const tx = this.transactionFromResultBeef(result, txid);
|
|
2519
|
+
const dec = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
2520
|
+
if (!dec?.fields || dec.fields.length < 6)
|
|
2521
|
+
continue;
|
|
2522
|
+
const f = await this.decryptProtocolTokenFields(dec.fields);
|
|
2523
|
+
const normalizedDomain = this.normalizeOriginator(f.domainDecoded);
|
|
2524
|
+
if (originFilter != null && normalizedDomain !== originFilter.normalized)
|
|
2525
|
+
continue;
|
|
2526
|
+
seen.add(out.outpoint);
|
|
2527
|
+
tokens.push({
|
|
2528
|
+
tx: tx.toBEEF(),
|
|
2529
|
+
txid,
|
|
2530
|
+
outputIndex,
|
|
2531
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
2532
|
+
satoshis: out.satoshis,
|
|
2533
|
+
originator: normalizedDomain,
|
|
2534
|
+
rawOriginator: f.domainDecoded,
|
|
2535
|
+
expiry: f.expiryDecoded,
|
|
2536
|
+
privileged: f.privDecoded,
|
|
2537
|
+
securityLevel: f.secLevelDecoded,
|
|
2538
|
+
protocol: f.protoNameDecoded,
|
|
2539
|
+
counterparty: f.cptyDecoded
|
|
2540
|
+
});
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2428
2543
|
/**
|
|
2429
2544
|
* Returns true if the originator already holds a valid unexpired protocol permission.
|
|
2430
2545
|
* This calls `ensureProtocolPermission` with `seekPermission=false`, so it won't prompt.
|
|
@@ -2439,7 +2554,7 @@ class WalletPermissionsManager {
|
|
|
2439
2554
|
});
|
|
2440
2555
|
return true;
|
|
2441
2556
|
}
|
|
2442
|
-
catch
|
|
2557
|
+
catch {
|
|
2443
2558
|
return false;
|
|
2444
2559
|
}
|
|
2445
2560
|
}
|
|
@@ -2456,7 +2571,7 @@ class WalletPermissionsManager {
|
|
|
2456
2571
|
baseTags.push(`basket ${params.basket}`);
|
|
2457
2572
|
}
|
|
2458
2573
|
const originFilter = params.originator ? this.prepareOriginator(params.originator) : undefined;
|
|
2459
|
-
const originVariants = originFilter
|
|
2574
|
+
const originVariants = originFilter == null ? [undefined] : originFilter.lookupValues;
|
|
2460
2575
|
const seen = new Set();
|
|
2461
2576
|
const tokens = [];
|
|
2462
2577
|
for (const originTag of originVariants) {
|
|
@@ -2471,38 +2586,41 @@ class WalletPermissionsManager {
|
|
|
2471
2586
|
include: 'entire transactions',
|
|
2472
2587
|
limit: 10000
|
|
2473
2588
|
}, this.adminOriginator);
|
|
2474
|
-
|
|
2475
|
-
if (seen.has(out.outpoint))
|
|
2476
|
-
continue;
|
|
2477
|
-
const [txid, outputIndexStr] = out.outpoint.split('.');
|
|
2478
|
-
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
2479
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
|
|
2480
|
-
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 3)
|
|
2481
|
-
continue;
|
|
2482
|
-
const [domainRaw, expiryRaw, basketRaw] = dec.fields;
|
|
2483
|
-
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
2484
|
-
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
2485
|
-
if (originFilter && normalizedDomain !== originFilter.normalized) {
|
|
2486
|
-
continue;
|
|
2487
|
-
}
|
|
2488
|
-
const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
2489
|
-
const basketDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(basketRaw));
|
|
2490
|
-
seen.add(out.outpoint);
|
|
2491
|
-
tokens.push({
|
|
2492
|
-
tx: tx.toBEEF(),
|
|
2493
|
-
txid: out.outpoint.split('.')[0],
|
|
2494
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
2495
|
-
satoshis: out.satoshis,
|
|
2496
|
-
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
2497
|
-
originator: normalizedDomain,
|
|
2498
|
-
rawOriginator: domainDecoded,
|
|
2499
|
-
basketName: basketDecoded,
|
|
2500
|
-
expiry: expiryDecoded
|
|
2501
|
-
});
|
|
2502
|
-
}
|
|
2589
|
+
await this.collectBasketTokens(result, originFilter, seen, tokens);
|
|
2503
2590
|
}
|
|
2504
2591
|
return tokens;
|
|
2505
2592
|
}
|
|
2593
|
+
/** Decodes and appends basket permission tokens from a listOutputs result. */
|
|
2594
|
+
async collectBasketTokens(result, originFilter, seen, tokens) {
|
|
2595
|
+
for (const out of result.outputs) {
|
|
2596
|
+
if (seen.has(out.outpoint))
|
|
2597
|
+
continue;
|
|
2598
|
+
const [txid, outputIndex] = this.parseOutpoint(out.outpoint);
|
|
2599
|
+
const tx = this.transactionFromResultBeef(result, txid);
|
|
2600
|
+
const dec = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
2601
|
+
if (!dec?.fields || dec.fields.length < 3)
|
|
2602
|
+
continue;
|
|
2603
|
+
const [domainRaw, expiryRaw, basketRaw] = dec.fields;
|
|
2604
|
+
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
2605
|
+
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
2606
|
+
if (originFilter != null && normalizedDomain !== originFilter.normalized)
|
|
2607
|
+
continue;
|
|
2608
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
2609
|
+
const basketDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(basketRaw));
|
|
2610
|
+
seen.add(out.outpoint);
|
|
2611
|
+
tokens.push({
|
|
2612
|
+
tx: tx.toBEEF(),
|
|
2613
|
+
txid,
|
|
2614
|
+
outputIndex,
|
|
2615
|
+
satoshis: out.satoshis,
|
|
2616
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
2617
|
+
originator: normalizedDomain,
|
|
2618
|
+
rawOriginator: domainDecoded,
|
|
2619
|
+
basketName: basketDecoded,
|
|
2620
|
+
expiry: expiryDecoded
|
|
2621
|
+
});
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2506
2624
|
/**
|
|
2507
2625
|
* Returns `true` if the originator already holds a valid unexpired basket permission for `basket`.
|
|
2508
2626
|
*/
|
|
@@ -2512,11 +2630,11 @@ class WalletPermissionsManager {
|
|
|
2512
2630
|
originator: params.originator,
|
|
2513
2631
|
basket: params.basket,
|
|
2514
2632
|
seekPermission: false,
|
|
2515
|
-
usageType: 'insertion'
|
|
2633
|
+
usageType: 'insertion'
|
|
2516
2634
|
});
|
|
2517
2635
|
return true;
|
|
2518
2636
|
}
|
|
2519
|
-
catch
|
|
2637
|
+
catch {
|
|
2520
2638
|
return false;
|
|
2521
2639
|
}
|
|
2522
2640
|
}
|
|
@@ -2539,18 +2657,18 @@ class WalletPermissionsManager {
|
|
|
2539
2657
|
const tokens = [];
|
|
2540
2658
|
for (const out of result.outputs) {
|
|
2541
2659
|
const [txid, outputIndexStr] = out.outpoint.split('.');
|
|
2542
|
-
const tx =
|
|
2660
|
+
const tx = this.transactionFromResultBeef(result, txid);
|
|
2543
2661
|
const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
|
|
2544
|
-
if (!
|
|
2662
|
+
if (!dec?.fields || dec.fields.length < 2)
|
|
2545
2663
|
continue;
|
|
2546
2664
|
const [domainRaw, amtRaw] = dec.fields;
|
|
2547
2665
|
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
2548
2666
|
const amtDecodedStr = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(amtRaw));
|
|
2549
|
-
const authorizedAmount = parseInt(amtDecodedStr, 10);
|
|
2667
|
+
const authorizedAmount = Number.parseInt(amtDecodedStr, 10);
|
|
2550
2668
|
tokens.push({
|
|
2551
2669
|
tx: tx.toBEEF(),
|
|
2552
2670
|
txid: out.outpoint.split('.')[0],
|
|
2553
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
2671
|
+
outputIndex: Number.parseInt(out.outpoint.split('.')[1], 10),
|
|
2554
2672
|
satoshis: out.satoshis,
|
|
2555
2673
|
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
2556
2674
|
originator: domainDecoded,
|
|
@@ -2573,7 +2691,7 @@ class WalletPermissionsManager {
|
|
|
2573
2691
|
});
|
|
2574
2692
|
return true;
|
|
2575
2693
|
}
|
|
2576
|
-
catch
|
|
2694
|
+
catch {
|
|
2577
2695
|
return false;
|
|
2578
2696
|
}
|
|
2579
2697
|
}
|
|
@@ -2586,72 +2704,61 @@ class WalletPermissionsManager {
|
|
|
2586
2704
|
* @returns Array of permission tokens that match the filter criteria
|
|
2587
2705
|
*/
|
|
2588
2706
|
async listCertificateAccess(params = {}) {
|
|
2589
|
-
const basketName = BASKET_MAP.certificate;
|
|
2590
2707
|
const baseTags = [];
|
|
2591
|
-
if (params.privileged !== undefined)
|
|
2708
|
+
if (params.privileged !== undefined)
|
|
2592
2709
|
baseTags.push(`privileged ${!!params.privileged}`);
|
|
2593
|
-
|
|
2594
|
-
if (params.certType) {
|
|
2710
|
+
if (params.certType)
|
|
2595
2711
|
baseTags.push(`type ${params.certType}`);
|
|
2596
|
-
|
|
2597
|
-
if (params.verifier) {
|
|
2712
|
+
if (params.verifier)
|
|
2598
2713
|
baseTags.push(`verifier ${params.verifier}`);
|
|
2599
|
-
}
|
|
2600
2714
|
const originFilter = params.originator ? this.prepareOriginator(params.originator) : undefined;
|
|
2601
|
-
const originVariants = originFilter
|
|
2715
|
+
const originVariants = originFilter == null ? [undefined] : originFilter.lookupValues;
|
|
2602
2716
|
const seen = new Set();
|
|
2603
2717
|
const tokens = [];
|
|
2604
2718
|
for (const originTag of originVariants) {
|
|
2605
|
-
const tags = [...baseTags];
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
}
|
|
2609
|
-
const result = await this.underlying.listOutputs({
|
|
2610
|
-
basket: basketName,
|
|
2611
|
-
tags,
|
|
2612
|
-
tagQueryMode: 'all',
|
|
2613
|
-
include: 'entire transactions',
|
|
2614
|
-
limit: 10000
|
|
2615
|
-
}, this.adminOriginator);
|
|
2616
|
-
for (const out of result.outputs) {
|
|
2617
|
-
if (seen.has(out.outpoint))
|
|
2618
|
-
continue;
|
|
2619
|
-
const [txid, outputIndexStr] = out.outpoint.split('.');
|
|
2620
|
-
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
2621
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript);
|
|
2622
|
-
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 6)
|
|
2623
|
-
continue;
|
|
2624
|
-
const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = dec.fields;
|
|
2625
|
-
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
2626
|
-
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
2627
|
-
if (originFilter && normalizedDomain !== originFilter.normalized) {
|
|
2628
|
-
continue;
|
|
2629
|
-
}
|
|
2630
|
-
const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
2631
|
-
const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
|
|
2632
|
-
const typeDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw));
|
|
2633
|
-
const verifierDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw));
|
|
2634
|
-
const fieldsJson = await this.decryptPermissionTokenField(fieldsRaw);
|
|
2635
|
-
const allFields = JSON.parse(sdk_1.Utils.toUTF8(fieldsJson));
|
|
2636
|
-
seen.add(out.outpoint);
|
|
2637
|
-
tokens.push({
|
|
2638
|
-
tx: tx.toBEEF(),
|
|
2639
|
-
txid: out.outpoint.split('.')[0],
|
|
2640
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
2641
|
-
satoshis: out.satoshis,
|
|
2642
|
-
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
2643
|
-
originator: normalizedDomain,
|
|
2644
|
-
rawOriginator: domainDecoded,
|
|
2645
|
-
privileged: privDecoded,
|
|
2646
|
-
certType: typeDecoded,
|
|
2647
|
-
certFields: allFields,
|
|
2648
|
-
verifier: verifierDec,
|
|
2649
|
-
expiry: expiryDecoded
|
|
2650
|
-
});
|
|
2651
|
-
}
|
|
2719
|
+
const tags = originTag != null ? [...baseTags, `originator ${originTag}`] : [...baseTags];
|
|
2720
|
+
const result = await this.underlying.listOutputs({ basket: BASKET_MAP.certificate, tags, tagQueryMode: 'all', include: 'entire transactions', limit: 10000 }, this.adminOriginator);
|
|
2721
|
+
await this.collectCertificateTokens(result, originFilter, seen, tokens);
|
|
2652
2722
|
}
|
|
2653
2723
|
return tokens;
|
|
2654
2724
|
}
|
|
2725
|
+
/** Decodes and appends certificate permission tokens from a listOutputs result. */
|
|
2726
|
+
async collectCertificateTokens(result, originFilter, seen, tokens) {
|
|
2727
|
+
for (const out of result.outputs) {
|
|
2728
|
+
if (seen.has(out.outpoint))
|
|
2729
|
+
continue;
|
|
2730
|
+
const [txid, outputIndex] = this.parseOutpoint(out.outpoint);
|
|
2731
|
+
const tx = this.transactionFromResultBeef(result, txid);
|
|
2732
|
+
const dec = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
2733
|
+
if (!dec?.fields || dec.fields.length < 6)
|
|
2734
|
+
continue;
|
|
2735
|
+
const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = dec.fields;
|
|
2736
|
+
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
2737
|
+
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
2738
|
+
if (originFilter != null && normalizedDomain !== originFilter.normalized)
|
|
2739
|
+
continue;
|
|
2740
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
2741
|
+
const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
|
|
2742
|
+
const typeDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw));
|
|
2743
|
+
const verifierDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw));
|
|
2744
|
+
const allFields = JSON.parse(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fieldsRaw)));
|
|
2745
|
+
seen.add(out.outpoint);
|
|
2746
|
+
tokens.push({
|
|
2747
|
+
tx: tx.toBEEF(),
|
|
2748
|
+
txid,
|
|
2749
|
+
outputIndex,
|
|
2750
|
+
satoshis: out.satoshis,
|
|
2751
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
2752
|
+
originator: normalizedDomain,
|
|
2753
|
+
rawOriginator: domainDecoded,
|
|
2754
|
+
privileged: privDecoded,
|
|
2755
|
+
certType: typeDecoded,
|
|
2756
|
+
certFields: allFields,
|
|
2757
|
+
verifier: verifierDec,
|
|
2758
|
+
expiry: expiryDecoded
|
|
2759
|
+
});
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2655
2762
|
/**
|
|
2656
2763
|
* Returns `true` if the originator already holds a valid unexpired certificate access
|
|
2657
2764
|
* for the given certType/fields. Does not prompt the user.
|
|
@@ -2669,7 +2776,7 @@ class WalletPermissionsManager {
|
|
|
2669
2776
|
});
|
|
2670
2777
|
return true;
|
|
2671
2778
|
}
|
|
2672
|
-
catch
|
|
2779
|
+
catch {
|
|
2673
2780
|
return false;
|
|
2674
2781
|
}
|
|
2675
2782
|
}
|
|
@@ -2683,7 +2790,7 @@ class WalletPermissionsManager {
|
|
|
2683
2790
|
basket: true,
|
|
2684
2791
|
certificate: true,
|
|
2685
2792
|
spending: true,
|
|
2686
|
-
...
|
|
2793
|
+
...opts
|
|
2687
2794
|
};
|
|
2688
2795
|
const [protocolTokens, basketTokens, certificateTokens, spendingTokens] = await Promise.all([
|
|
2689
2796
|
include.protocol ? this.listProtocolPermissions({ originator }) : Promise.resolve([]),
|
|
@@ -2693,7 +2800,7 @@ class WalletPermissionsManager {
|
|
|
2693
2800
|
? this.listSpendingAuthorizations({ originator: preparedOriginator.normalized })
|
|
2694
2801
|
: Promise.resolve([])
|
|
2695
2802
|
]);
|
|
2696
|
-
const spendingTokenList = spendingTokens.length ? [spendingTokens[0]] : [];
|
|
2803
|
+
const spendingTokenList = spendingTokens.length > 0 ? [spendingTokens[0]] : [];
|
|
2697
2804
|
const allTokens = [...protocolTokens, ...basketTokens, ...certificateTokens, ...spendingTokenList];
|
|
2698
2805
|
const seen = new Set();
|
|
2699
2806
|
const deduped = allTokens.filter(t => {
|
|
@@ -2707,13 +2814,13 @@ class WalletPermissionsManager {
|
|
|
2707
2814
|
}
|
|
2708
2815
|
async revokePermissionTokensBestEffort(items) {
|
|
2709
2816
|
const CHUNK = 15;
|
|
2710
|
-
return this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2817
|
+
return await this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2711
2818
|
await this.revokePermissionTokensChunk(chunk);
|
|
2712
2819
|
return chunk;
|
|
2713
2820
|
});
|
|
2714
2821
|
}
|
|
2715
2822
|
async revokePermissionTokensChunk(oldTokens) {
|
|
2716
|
-
if (
|
|
2823
|
+
if (oldTokens.length === 0)
|
|
2717
2824
|
return;
|
|
2718
2825
|
const inputBeef = new sdk_1.Beef();
|
|
2719
2826
|
for (const token of oldTokens) {
|
|
@@ -2733,52 +2840,12 @@ class WalletPermissionsManager {
|
|
|
2733
2840
|
signAndProcess: false
|
|
2734
2841
|
}
|
|
2735
2842
|
}, this.adminOriginator);
|
|
2736
|
-
if (!
|
|
2843
|
+
if (!signableTransaction?.reference || !signableTransaction.tx) {
|
|
2737
2844
|
throw new Error('Failed to create signable transaction');
|
|
2738
2845
|
}
|
|
2739
2846
|
const tx = sdk_1.Transaction.fromAtomicBEEF(signableTransaction.tx);
|
|
2740
|
-
const normalizeTxid = (txid) => (txid !== null && txid !== void 0 ? txid : '').toLowerCase();
|
|
2741
|
-
const reverseHexTxid = (txid) => {
|
|
2742
|
-
const hex = normalizeTxid(txid);
|
|
2743
|
-
if (!/^[0-9a-f]{64}$/.test(hex))
|
|
2744
|
-
return hex;
|
|
2745
|
-
const bytes = hex.match(/../g);
|
|
2746
|
-
return bytes ? bytes.reverse().join('') : hex;
|
|
2747
|
-
};
|
|
2748
|
-
const matchesOutpointString = (outpoint, token) => {
|
|
2749
|
-
const dot = outpoint.lastIndexOf('.');
|
|
2750
|
-
const colon = outpoint.lastIndexOf(':');
|
|
2751
|
-
const sep = dot > colon ? dot : colon;
|
|
2752
|
-
if (sep === -1)
|
|
2753
|
-
return false;
|
|
2754
|
-
const txidPart = outpoint.slice(0, sep);
|
|
2755
|
-
const indexPart = outpoint.slice(sep + 1);
|
|
2756
|
-
const vout = Number(indexPart);
|
|
2757
|
-
if (!Number.isFinite(vout))
|
|
2758
|
-
return false;
|
|
2759
|
-
return normalizeTxid(txidPart) === normalizeTxid(token.txid) && vout === token.outputIndex;
|
|
2760
|
-
};
|
|
2761
|
-
const findInputIndexForToken = (token) => {
|
|
2762
|
-
return tx.inputs.findIndex((input) => {
|
|
2763
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
2764
|
-
const txidCandidate = (_g = (_f = (_e = (_d = (_c = (_b = (_a = input === null || input === void 0 ? void 0 : input.sourceTXID) !== null && _a !== void 0 ? _a : input === null || input === void 0 ? void 0 : input.sourceTxid) !== null && _b !== void 0 ? _b : input === null || input === void 0 ? void 0 : input.sourceTxId) !== null && _c !== void 0 ? _c : input === null || input === void 0 ? void 0 : input.prevTxId) !== null && _d !== void 0 ? _d : input === null || input === void 0 ? void 0 : input.prevTxid) !== null && _e !== void 0 ? _e : input === null || input === void 0 ? void 0 : input.prevTXID) !== null && _f !== void 0 ? _f : input === null || input === void 0 ? void 0 : input.txid) !== null && _g !== void 0 ? _g : input === null || input === void 0 ? void 0 : input.txID;
|
|
2765
|
-
const voutCandidate = (_l = (_k = (_j = (_h = input === null || input === void 0 ? void 0 : input.sourceOutputIndex) !== null && _h !== void 0 ? _h : input === null || input === void 0 ? void 0 : input.sourceOutput) !== null && _j !== void 0 ? _j : input === null || input === void 0 ? void 0 : input.outputIndex) !== null && _k !== void 0 ? _k : input === null || input === void 0 ? void 0 : input.vout) !== null && _l !== void 0 ? _l : input === null || input === void 0 ? void 0 : input.prevOutIndex;
|
|
2766
|
-
if (typeof txidCandidate === 'string' && typeof voutCandidate === 'number') {
|
|
2767
|
-
const cand = normalizeTxid(txidCandidate);
|
|
2768
|
-
const target = normalizeTxid(token.txid);
|
|
2769
|
-
if (cand === target && voutCandidate === token.outputIndex)
|
|
2770
|
-
return true;
|
|
2771
|
-
if (cand === reverseHexTxid(token.txid) && voutCandidate === token.outputIndex)
|
|
2772
|
-
return true;
|
|
2773
|
-
}
|
|
2774
|
-
const outpointCandidate = (_o = (_m = input === null || input === void 0 ? void 0 : input.outpoint) !== null && _m !== void 0 ? _m : input === null || input === void 0 ? void 0 : input.sourceOutpoint) !== null && _o !== void 0 ? _o : input === null || input === void 0 ? void 0 : input.prevOutpoint;
|
|
2775
|
-
if (typeof outpointCandidate === 'string' && matchesOutpointString(outpointCandidate, token))
|
|
2776
|
-
return true;
|
|
2777
|
-
return false;
|
|
2778
|
-
});
|
|
2779
|
-
};
|
|
2780
2847
|
const inputsToSign = oldTokens.map(token => {
|
|
2781
|
-
let permInputIndex = findInputIndexForToken(token);
|
|
2848
|
+
let permInputIndex = this.findInputIndexForToken(tx, token);
|
|
2782
2849
|
if (permInputIndex === -1 && tx.inputs.length === 1) {
|
|
2783
2850
|
permInputIndex = 0;
|
|
2784
2851
|
}
|
|
@@ -2811,13 +2878,13 @@ class WalletPermissionsManager {
|
|
|
2811
2878
|
async revokePermission(oldToken) {
|
|
2812
2879
|
const oldOutpoint = `${oldToken.txid}.${oldToken.outputIndex}`;
|
|
2813
2880
|
const { signableTransaction } = await this.createAction({
|
|
2814
|
-
description:
|
|
2881
|
+
description: 'Revoke permission',
|
|
2815
2882
|
inputBEEF: oldToken.tx,
|
|
2816
2883
|
inputs: [
|
|
2817
2884
|
{
|
|
2818
2885
|
outpoint: oldOutpoint,
|
|
2819
2886
|
unlockingScriptLength: 73, // length of signature
|
|
2820
|
-
inputDescription:
|
|
2887
|
+
inputDescription: 'Consume old permission token'
|
|
2821
2888
|
}
|
|
2822
2889
|
],
|
|
2823
2890
|
options: {
|
|
@@ -2825,44 +2892,7 @@ class WalletPermissionsManager {
|
|
|
2825
2892
|
}
|
|
2826
2893
|
}, this.adminOriginator);
|
|
2827
2894
|
const tx = sdk_1.Transaction.fromBEEF(signableTransaction.tx);
|
|
2828
|
-
|
|
2829
|
-
const reverseHexTxid = (txid) => {
|
|
2830
|
-
const hex = normalizeTxid(txid);
|
|
2831
|
-
if (!/^[0-9a-f]{64}$/.test(hex))
|
|
2832
|
-
return hex;
|
|
2833
|
-
const bytes = hex.match(/../g);
|
|
2834
|
-
return bytes ? bytes.reverse().join('') : hex;
|
|
2835
|
-
};
|
|
2836
|
-
const matchesOutpointString = (outpoint) => {
|
|
2837
|
-
const dot = outpoint.lastIndexOf('.');
|
|
2838
|
-
const colon = outpoint.lastIndexOf(':');
|
|
2839
|
-
const sep = dot > colon ? dot : colon;
|
|
2840
|
-
if (sep === -1)
|
|
2841
|
-
return false;
|
|
2842
|
-
const txidPart = outpoint.slice(0, sep);
|
|
2843
|
-
const indexPart = outpoint.slice(sep + 1);
|
|
2844
|
-
const vout = Number(indexPart);
|
|
2845
|
-
if (!Number.isFinite(vout))
|
|
2846
|
-
return false;
|
|
2847
|
-
return normalizeTxid(txidPart) === normalizeTxid(oldToken.txid) && vout === oldToken.outputIndex;
|
|
2848
|
-
};
|
|
2849
|
-
let permInputIndex = tx.inputs.findIndex((input) => {
|
|
2850
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
2851
|
-
const txidCandidate = (_g = (_f = (_e = (_d = (_c = (_b = (_a = input === null || input === void 0 ? void 0 : input.sourceTXID) !== null && _a !== void 0 ? _a : input === null || input === void 0 ? void 0 : input.sourceTxid) !== null && _b !== void 0 ? _b : input === null || input === void 0 ? void 0 : input.sourceTxId) !== null && _c !== void 0 ? _c : input === null || input === void 0 ? void 0 : input.prevTxId) !== null && _d !== void 0 ? _d : input === null || input === void 0 ? void 0 : input.prevTxid) !== null && _e !== void 0 ? _e : input === null || input === void 0 ? void 0 : input.prevTXID) !== null && _f !== void 0 ? _f : input === null || input === void 0 ? void 0 : input.txid) !== null && _g !== void 0 ? _g : input === null || input === void 0 ? void 0 : input.txID;
|
|
2852
|
-
const voutCandidate = (_l = (_k = (_j = (_h = input === null || input === void 0 ? void 0 : input.sourceOutputIndex) !== null && _h !== void 0 ? _h : input === null || input === void 0 ? void 0 : input.sourceOutput) !== null && _j !== void 0 ? _j : input === null || input === void 0 ? void 0 : input.outputIndex) !== null && _k !== void 0 ? _k : input === null || input === void 0 ? void 0 : input.vout) !== null && _l !== void 0 ? _l : input === null || input === void 0 ? void 0 : input.prevOutIndex;
|
|
2853
|
-
if (typeof txidCandidate === 'string' && typeof voutCandidate === 'number') {
|
|
2854
|
-
const cand = normalizeTxid(txidCandidate);
|
|
2855
|
-
const target = normalizeTxid(oldToken.txid);
|
|
2856
|
-
if (cand === target && voutCandidate === oldToken.outputIndex)
|
|
2857
|
-
return true;
|
|
2858
|
-
if (cand === reverseHexTxid(oldToken.txid) && voutCandidate === oldToken.outputIndex)
|
|
2859
|
-
return true;
|
|
2860
|
-
}
|
|
2861
|
-
const outpointCandidate = (_o = (_m = input === null || input === void 0 ? void 0 : input.outpoint) !== null && _m !== void 0 ? _m : input === null || input === void 0 ? void 0 : input.sourceOutpoint) !== null && _o !== void 0 ? _o : input === null || input === void 0 ? void 0 : input.prevOutpoint;
|
|
2862
|
-
if (typeof outpointCandidate === 'string' && matchesOutpointString(outpointCandidate))
|
|
2863
|
-
return true;
|
|
2864
|
-
return false;
|
|
2865
|
-
});
|
|
2895
|
+
let permInputIndex = this.findInputIndexForToken(tx, oldToken);
|
|
2866
2896
|
if (permInputIndex === -1 && tx.inputs.length === 1) {
|
|
2867
2897
|
permInputIndex = 0;
|
|
2868
2898
|
}
|
|
@@ -2886,23 +2916,7 @@ class WalletPermissionsManager {
|
|
|
2886
2916
|
async createAction(args, originator) {
|
|
2887
2917
|
// 1) Identify unique P-modules involved (one per schemeID) from both baskets and labels
|
|
2888
2918
|
const pModulesByScheme = new Map();
|
|
2889
|
-
const nonPBaskets =
|
|
2890
|
-
// Check baskets for p modules
|
|
2891
|
-
if (args.outputs) {
|
|
2892
|
-
for (const out of args.outputs) {
|
|
2893
|
-
if (out.basket) {
|
|
2894
|
-
if (out.basket.startsWith('p ')) {
|
|
2895
|
-
const schemeID = out.basket.split(' ')[1];
|
|
2896
|
-
this.addPModuleByScheme(schemeID, 'basket', pModulesByScheme);
|
|
2897
|
-
}
|
|
2898
|
-
else {
|
|
2899
|
-
// Track non-P baskets for normal permission checks
|
|
2900
|
-
nonPBaskets.push(out.basket);
|
|
2901
|
-
}
|
|
2902
|
-
}
|
|
2903
|
-
}
|
|
2904
|
-
}
|
|
2905
|
-
// Check labels for p modules
|
|
2919
|
+
const nonPBaskets = this.collectNonPBaskets(args.outputs, pModulesByScheme);
|
|
2906
2920
|
const nonPLabels = this.splitLabelsByPermissionModule(args.labels, pModulesByScheme);
|
|
2907
2921
|
// 2) Check permissions for non-P baskets
|
|
2908
2922
|
for (const basket of nonPBaskets) {
|
|
@@ -2922,20 +2936,91 @@ class WalletPermissionsManager {
|
|
|
2922
2936
|
usageType: 'apply'
|
|
2923
2937
|
});
|
|
2924
2938
|
}
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2939
|
+
// 4) Force signAndProcess=false unless the originator is admin and explicitly sets it to true.
|
|
2940
|
+
const modifiedOptions = this.enforceSignAndProcess(args.options, originator);
|
|
2941
|
+
// 5) Encrypt transaction metadata, saving originals for spending auth and line items.
|
|
2942
|
+
const originalDescription = args.description;
|
|
2943
|
+
const { originalInputDescriptions, originalOutputDescriptions } = await this.encryptActionMetadata(args);
|
|
2944
|
+
// 6) Call the underlying wallet's createAction with P-module chaining as needed.
|
|
2945
|
+
const finalArgs = {
|
|
2946
|
+
...args,
|
|
2947
|
+
options: modifiedOptions,
|
|
2948
|
+
labels: [...(args.labels || []), `admin originator ${originator}`, `admin month ${this.getCurrentMonthYearUTC()}`]
|
|
2949
|
+
};
|
|
2950
|
+
let createResult = await this.callCreateActionWithPModules(finalArgs, pModulesByScheme, originator);
|
|
2951
|
+
if (createResult.signableTransaction == null)
|
|
2952
|
+
return createResult;
|
|
2953
|
+
// 7) Parse the signable tx to determine net spend, then gate on spending authorization.
|
|
2954
|
+
const tx = sdk_1.Transaction.fromAtomicBEEF(createResult.signableTransaction.tx);
|
|
2955
|
+
const reference = createResult.signableTransaction.reference;
|
|
2956
|
+
// 7a) SECURITY (GHSA-36f9-7rg5-cpf8) defense-in-depth: confirm every
|
|
2957
|
+
// caller-requested output actually appears in the transaction we are about to
|
|
2958
|
+
// authorize and sign. The locking scripts in the signable transaction
|
|
2959
|
+
// originate from storage; a malicious or compromised remote storage provider
|
|
2960
|
+
// could substitute a recipient script, which would then be signed and
|
|
2961
|
+
// broadcast while this manager's caller/UI still shows the requested
|
|
2962
|
+
// recipient. The signer (buildSignableTransaction) rejects this at the
|
|
2963
|
+
// source; this is an independent check at the permissions layer.
|
|
2964
|
+
try {
|
|
2965
|
+
this.verifyRequestedOutputsPresent(tx, args);
|
|
2966
|
+
}
|
|
2967
|
+
catch (err) {
|
|
2968
|
+
await this.underlying.abortAction({ reference });
|
|
2969
|
+
throw err;
|
|
2970
|
+
}
|
|
2971
|
+
const { netSpent, lineItems } = this.computeNetSpend(tx, args, originalInputDescriptions, originalOutputDescriptions);
|
|
2972
|
+
// 8) If netSpent > 0, require spending authorization. Abort if denied.
|
|
2973
|
+
if (netSpent > 0) {
|
|
2974
|
+
try {
|
|
2975
|
+
await this.ensureSpendingAuthorization({
|
|
2976
|
+
originator: originator,
|
|
2977
|
+
satoshis: netSpent,
|
|
2978
|
+
lineItems,
|
|
2979
|
+
reason: originalDescription
|
|
2980
|
+
});
|
|
2981
|
+
}
|
|
2982
|
+
catch (err) {
|
|
2983
|
+
await this.underlying.abortAction({ reference });
|
|
2984
|
+
throw err;
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
// 9) Finalize or return the signable transaction based on whether more signatures are needed.
|
|
2988
|
+
const vargs = sdk_1.Validation.validateCreateActionArgs(args);
|
|
2989
|
+
if (vargs.isSignAction)
|
|
2990
|
+
return createResult;
|
|
2991
|
+
const signResult = await this.underlying.signAction({ reference, spends: {}, options: args.options }, originator);
|
|
2992
|
+
return { ...createResult, ...signResult, signableTransaction: undefined };
|
|
2993
|
+
}
|
|
2994
|
+
/** Scans outputs to split P-scheme baskets from regular baskets; registers P-modules as a side effect. */
|
|
2995
|
+
collectNonPBaskets(outputs, pModulesByScheme) {
|
|
2996
|
+
const nonPBaskets = [];
|
|
2997
|
+
if (outputs == null)
|
|
2998
|
+
return nonPBaskets;
|
|
2999
|
+
for (const out of outputs) {
|
|
3000
|
+
if (!out.basket)
|
|
3001
|
+
continue;
|
|
3002
|
+
if (out.basket.startsWith('p ')) {
|
|
3003
|
+
this.addPModuleByScheme(out.basket.split(' ')[1], 'basket', pModulesByScheme);
|
|
3004
|
+
}
|
|
3005
|
+
else {
|
|
3006
|
+
nonPBaskets.push(out.basket);
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
return nonPBaskets;
|
|
3010
|
+
}
|
|
3011
|
+
/** Enforces signAndProcess=false for non-admin originators; throws if admin override is missing. */
|
|
3012
|
+
enforceSignAndProcess(options, originator) {
|
|
3013
|
+
const modifiedOptions = { ...options };
|
|
2931
3014
|
if (modifiedOptions.signAndProcess !== true) {
|
|
2932
3015
|
modifiedOptions.signAndProcess = false;
|
|
2933
3016
|
}
|
|
2934
3017
|
else if (!this.isAdminOriginator(originator)) {
|
|
2935
3018
|
throw new Error('Only the admin originator can set signAndProcess=true explicitly.');
|
|
2936
3019
|
}
|
|
2937
|
-
|
|
2938
|
-
|
|
3020
|
+
return modifiedOptions;
|
|
3021
|
+
}
|
|
3022
|
+
/** Encrypts all description/instruction fields in args in-place; returns original (plaintext) copies. */
|
|
3023
|
+
async encryptActionMetadata(args) {
|
|
2939
3024
|
const originalInputDescriptions = {};
|
|
2940
3025
|
const originalOutputDescriptions = {};
|
|
2941
3026
|
const inputEncryptionTasks = (args.inputs || []).map(async (input, i) => {
|
|
@@ -2960,58 +3045,74 @@ class WalletPermissionsManager {
|
|
|
2960
3045
|
...inputEncryptionTasks,
|
|
2961
3046
|
...outputEncryptionTasks
|
|
2962
3047
|
]);
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
const
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
// Chain onRequest calls through all modules
|
|
2979
|
-
let transformedArgs = finalArgs;
|
|
2980
|
-
for (const module of pModules) {
|
|
2981
|
-
const transformed = await module.onRequest({
|
|
2982
|
-
method: 'createAction',
|
|
2983
|
-
args: transformedArgs,
|
|
2984
|
-
originator: originator
|
|
2985
|
-
});
|
|
2986
|
-
transformedArgs = transformed.args;
|
|
2987
|
-
}
|
|
2988
|
-
// Call underlying wallet with transformed args
|
|
2989
|
-
createResult = await this.underlying.createAction(transformedArgs, originator);
|
|
2990
|
-
// Chain onResponse calls in reverse order
|
|
2991
|
-
for (let i = pModules.length - 1; i >= 0; i--) {
|
|
2992
|
-
createResult = await pModules[i].onResponse(createResult, {
|
|
2993
|
-
method: 'createAction',
|
|
2994
|
-
originator: originator
|
|
2995
|
-
});
|
|
2996
|
-
}
|
|
3048
|
+
return { originalInputDescriptions, originalOutputDescriptions };
|
|
3049
|
+
}
|
|
3050
|
+
/** Calls underlying createAction, chaining P-module request/response transforms when needed. */
|
|
3051
|
+
async callCreateActionWithPModules(finalArgs, pModulesByScheme, originator) {
|
|
3052
|
+
if (pModulesByScheme.size === 0)
|
|
3053
|
+
return await this.underlying.createAction(finalArgs, originator);
|
|
3054
|
+
const pModules = Array.from(pModulesByScheme.values());
|
|
3055
|
+
let transformedArgs = finalArgs;
|
|
3056
|
+
for (const module of pModules) {
|
|
3057
|
+
const transformed = await module.onRequest({
|
|
3058
|
+
method: 'createAction',
|
|
3059
|
+
args: transformedArgs,
|
|
3060
|
+
originator: originator
|
|
3061
|
+
});
|
|
3062
|
+
transformedArgs = transformed.args;
|
|
2997
3063
|
}
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
createResult = await
|
|
3064
|
+
let createResult = await this.underlying.createAction(transformedArgs, originator);
|
|
3065
|
+
for (let i = pModules.length - 1; i >= 0; i--) {
|
|
3066
|
+
createResult = await pModules[i].onResponse(createResult, { method: 'createAction', originator: originator });
|
|
3001
3067
|
}
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3068
|
+
return createResult;
|
|
3069
|
+
}
|
|
3070
|
+
/**
|
|
3071
|
+
* Computes the net satoshis the originator is spending in a createAction call,
|
|
3072
|
+
* accounting for foreign (originator-provided) inputs and outputs plus the fee.
|
|
3073
|
+
* Also builds the line items list for the spending authorization request.
|
|
3074
|
+
*/
|
|
3075
|
+
/**
|
|
3076
|
+
* Defense-in-depth verification that each caller-requested output (locking
|
|
3077
|
+
* script + amount) is present in the transaction returned for signing.
|
|
3078
|
+
*
|
|
3079
|
+
* The scripts in the signable transaction originate from storage. A malicious
|
|
3080
|
+
* or compromised remote storage provider could substitute a different
|
|
3081
|
+
* recipient script for a caller-specified output. The signer
|
|
3082
|
+
* (buildSignableTransaction) rejects this at the source; this is an
|
|
3083
|
+
* independent check at the permissions layer so the substitution is caught
|
|
3084
|
+
* regardless of how the signable transaction was produced.
|
|
3085
|
+
*
|
|
3086
|
+
* Outputs are matched as a multiset on (lockingScript, satoshis): the
|
|
3087
|
+
* transaction also contains change/commission outputs and the output order is
|
|
3088
|
+
* randomized by default, and a caller may legitimately request the same
|
|
3089
|
+
* script+amount more than once.
|
|
3090
|
+
*
|
|
3091
|
+
* @throws Error if any caller-requested output is absent from the transaction.
|
|
3092
|
+
*/
|
|
3093
|
+
verifyRequestedOutputsPresent(tx, args) {
|
|
3094
|
+
const requested = args.outputs || [];
|
|
3095
|
+
if (requested.length === 0)
|
|
3096
|
+
return;
|
|
3097
|
+
// All transaction outputs as (script hex, satoshis); each may satisfy at
|
|
3098
|
+
// most one requested output.
|
|
3099
|
+
const available = tx.outputs.map(o => ({
|
|
3100
|
+
script: o.lockingScript.toHex().toLowerCase(),
|
|
3101
|
+
satoshis: o.satoshis,
|
|
3102
|
+
used: false
|
|
3103
|
+
}));
|
|
3104
|
+
for (let i = 0; i < requested.length; i++) {
|
|
3105
|
+
const wantScript = (requested[i].lockingScript ?? '').toLowerCase();
|
|
3106
|
+
const wantSats = requested[i].satoshis;
|
|
3107
|
+
const match = available.find(a => !a.used && a.script === wantScript && a.satoshis === wantSats);
|
|
3108
|
+
if (match == null) {
|
|
3109
|
+
throw new Error(`The transaction returned for signing does not contain caller-requested output ${i} ` +
|
|
3110
|
+
`(locking script and amount). The recipient may have been substituted by storage.`);
|
|
3111
|
+
}
|
|
3112
|
+
match.used = true;
|
|
3005
3113
|
}
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
* We only consider inputs the originator explicitly listed in args.inputs.
|
|
3009
|
-
* netSpent = (sum of originator-requested outputs) - (sum of matching originator inputs).
|
|
3010
|
-
* If netSpent > 0, we need spending authorization.
|
|
3011
|
-
*/
|
|
3012
|
-
const tx = sdk_1.Transaction.fromAtomicBEEF(createResult.signableTransaction.tx);
|
|
3013
|
-
const reference = createResult.signableTransaction.reference;
|
|
3014
|
-
let netSpent = 0;
|
|
3114
|
+
}
|
|
3115
|
+
computeNetSpend(tx, args, originalInputDescriptions, originalOutputDescriptions) {
|
|
3015
3116
|
const lineItems = [];
|
|
3016
3117
|
// Sum originator-provided inputs:
|
|
3017
3118
|
let totalInputSatoshis = 0;
|
|
@@ -3024,7 +3125,7 @@ class WalletPermissionsManager {
|
|
|
3024
3125
|
lineItems.push({
|
|
3025
3126
|
type: 'input',
|
|
3026
3127
|
description: originalInputDescriptions[matchingIndex] || 'No input description provided',
|
|
3027
|
-
satoshis
|
|
3128
|
+
satoshis
|
|
3028
3129
|
});
|
|
3029
3130
|
}
|
|
3030
3131
|
}
|
|
@@ -3039,68 +3140,20 @@ class WalletPermissionsManager {
|
|
|
3039
3140
|
});
|
|
3040
3141
|
}
|
|
3041
3142
|
// Add an entry for the transaction fee:
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
satoshis: tx.getFee(),
|
|
3045
|
-
description: 'Network fee'
|
|
3046
|
-
});
|
|
3047
|
-
/**
|
|
3048
|
-
* When it comes to spending authorizations, and the computation of net spend, there are
|
|
3049
|
-
* two types of inputs and two types of outputs:
|
|
3050
|
-
*
|
|
3051
|
-
* There are foreign (originator-requested) ones, and domestic (internally-provided) ones.
|
|
3052
|
-
* The net spend is always calculated from the domestic, internal perspective. Therefore, the
|
|
3053
|
-
* cost of funding the foreign outputs is the base cost to the domestic user, unless this is
|
|
3054
|
-
* somehow offset.
|
|
3055
|
-
*
|
|
3056
|
-
* The only way to offset this cost is when the foreign inputs help carry some of the burden.
|
|
3057
|
-
* This is why we can subtract the sum of the foreign inputs from the sum of foreign outputs,
|
|
3058
|
-
* to gague how much of that cost needs to be born domestically by the user.
|
|
3059
|
-
*
|
|
3060
|
-
* The logic does not need to account for whatever domestic inputs are provided, or whatever
|
|
3061
|
-
* domestic outputs are re-captured by the wallet back as change. The wallet could conceivably
|
|
3062
|
-
* provide 21e8 satoshis as input and re-capture the same amount as change, but the net effect
|
|
3063
|
-
* on actual spending would be zero. Therefore, we base net spend on total foreign outflows
|
|
3064
|
-
* minus total foreign inflows. Fees are also considered.
|
|
3065
|
-
*/
|
|
3066
|
-
netSpent = totalOutputSatoshis + tx.getFee() - totalInputSatoshis;
|
|
3067
|
-
// 8) If netSpent > 0, require spending authorization. Abort if denied.
|
|
3068
|
-
if (netSpent > 0) {
|
|
3069
|
-
try {
|
|
3070
|
-
await this.ensureSpendingAuthorization({
|
|
3071
|
-
originator: originator,
|
|
3072
|
-
satoshis: netSpent,
|
|
3073
|
-
lineItems,
|
|
3074
|
-
reason: originalDescription
|
|
3075
|
-
});
|
|
3076
|
-
}
|
|
3077
|
-
catch (err) {
|
|
3078
|
-
await this.underlying.abortAction({ reference });
|
|
3079
|
-
throw err;
|
|
3080
|
-
}
|
|
3081
|
-
}
|
|
3143
|
+
const fee = tx.getFee();
|
|
3144
|
+
lineItems.push({ type: 'fee', satoshis: fee, description: 'Network fee' });
|
|
3082
3145
|
/**
|
|
3083
|
-
*
|
|
3084
|
-
*
|
|
3085
|
-
* - If the transaction still needs more signatures, we must return the signableTransaction.
|
|
3146
|
+
* Net spend = total foreign outflows minus total foreign inflows plus fee.
|
|
3147
|
+
* Domestic wallet inputs/change outputs are not counted — they are internal.
|
|
3086
3148
|
*/
|
|
3087
|
-
const
|
|
3088
|
-
|
|
3089
|
-
return createResult;
|
|
3090
|
-
}
|
|
3091
|
-
const signResult = await this.underlying.signAction({ reference, spends: {}, options: args.options }, originator);
|
|
3092
|
-
// Merge signResult into createResult and remove signableTransaction:
|
|
3093
|
-
return {
|
|
3094
|
-
...createResult,
|
|
3095
|
-
...signResult,
|
|
3096
|
-
signableTransaction: undefined
|
|
3097
|
-
};
|
|
3149
|
+
const netSpent = totalOutputSatoshis + fee - totalInputSatoshis;
|
|
3150
|
+
return { netSpent, lineItems };
|
|
3098
3151
|
}
|
|
3099
3152
|
async signAction(...args) {
|
|
3100
|
-
return this.underlying.signAction(...args);
|
|
3153
|
+
return await this.underlying.signAction(...args);
|
|
3101
3154
|
}
|
|
3102
3155
|
async abortAction(...args) {
|
|
3103
|
-
return this.underlying.abortAction(...args);
|
|
3156
|
+
return await this.underlying.abortAction(...args);
|
|
3104
3157
|
}
|
|
3105
3158
|
async listActions(...args) {
|
|
3106
3159
|
const [requestArgs, originator] = args;
|
|
@@ -3149,89 +3202,89 @@ class WalletPermissionsManager {
|
|
|
3149
3202
|
// 4) Transparently decrypt transaction metadata, if configured to do so.
|
|
3150
3203
|
return await this.decryptListActionsMetadata(results);
|
|
3151
3204
|
}
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
const [requestArgs, originator] = args;
|
|
3155
|
-
// 1) Identify unique P-modules involved (one per schemeID) from both baskets and labels
|
|
3156
|
-
const pModulesByScheme = new Map();
|
|
3157
|
-
const nonPBaskets = [];
|
|
3158
|
-
// Check baskets for p modules
|
|
3205
|
+
collectInternalizeActionBaskets(requestArgs, pModulesByScheme) {
|
|
3206
|
+
const nonPModuleBaskets = [];
|
|
3159
3207
|
for (const outIndex in requestArgs.outputs) {
|
|
3160
|
-
const
|
|
3161
|
-
if (
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
nonPBaskets.push({
|
|
3170
|
-
outIndex,
|
|
3171
|
-
basket,
|
|
3172
|
-
customInstructions: out.insertionRemittance.customInstructions
|
|
3173
|
-
});
|
|
3174
|
-
}
|
|
3208
|
+
const output = requestArgs.outputs[outIndex];
|
|
3209
|
+
if (output.protocol !== 'basket insertion')
|
|
3210
|
+
continue;
|
|
3211
|
+
const { basket, customInstructions } = output.insertionRemittance;
|
|
3212
|
+
if (basket.startsWith('p ')) {
|
|
3213
|
+
this.addPModuleByScheme(basket.split(' ')[1], 'basket', pModulesByScheme);
|
|
3214
|
+
}
|
|
3215
|
+
else {
|
|
3216
|
+
nonPModuleBaskets.push({ outIndex, basket, customInstructions });
|
|
3175
3217
|
}
|
|
3176
3218
|
}
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
for (const { outIndex, basket, customInstructions } of
|
|
3219
|
+
return nonPModuleBaskets;
|
|
3220
|
+
}
|
|
3221
|
+
async authorizeInternalizeActionBaskets(requestArgs, originator, baskets) {
|
|
3222
|
+
for (const { outIndex, basket, customInstructions } of baskets) {
|
|
3181
3223
|
await this.ensureBasketAccess({
|
|
3182
|
-
originator
|
|
3224
|
+
originator,
|
|
3183
3225
|
basket,
|
|
3184
3226
|
reason: requestArgs.description,
|
|
3185
3227
|
usageType: 'insertion'
|
|
3186
3228
|
});
|
|
3187
|
-
if (customInstructions)
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3229
|
+
if (customInstructions == null || customInstructions === '')
|
|
3230
|
+
continue;
|
|
3231
|
+
requestArgs.outputs[outIndex].insertionRemittance.customInstructions =
|
|
3232
|
+
await this.maybeEncryptMetadata(customInstructions);
|
|
3191
3233
|
}
|
|
3192
|
-
|
|
3193
|
-
|
|
3234
|
+
}
|
|
3235
|
+
async authorizeInternalizeActionLabels(requestArgs, originator, labels) {
|
|
3236
|
+
for (const label of labels) {
|
|
3194
3237
|
await this.ensureLabelAccess({
|
|
3195
|
-
originator
|
|
3196
|
-
label
|
|
3238
|
+
originator,
|
|
3239
|
+
label,
|
|
3197
3240
|
reason: requestArgs.description,
|
|
3198
3241
|
usageType: 'apply'
|
|
3199
3242
|
});
|
|
3200
3243
|
}
|
|
3244
|
+
}
|
|
3245
|
+
async encryptInternalizeActionModuleMetadata(requestArgs) {
|
|
3246
|
+
for (const outIndex in requestArgs.outputs) {
|
|
3247
|
+
const output = requestArgs.outputs[outIndex];
|
|
3248
|
+
const customInstructions = output.insertionRemittance?.customInstructions;
|
|
3249
|
+
if (output.protocol !== 'basket insertion' || !customInstructions)
|
|
3250
|
+
continue;
|
|
3251
|
+
output.insertionRemittance.customInstructions = await this.maybeEncryptMetadata(customInstructions);
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
async runInternalizeActionModules(requestArgs, originator, modules) {
|
|
3255
|
+
let transformedArgs = requestArgs;
|
|
3256
|
+
for (const module of modules) {
|
|
3257
|
+
const transformed = await module.onRequest({
|
|
3258
|
+
method: 'internalizeAction',
|
|
3259
|
+
args: transformedArgs,
|
|
3260
|
+
originator
|
|
3261
|
+
});
|
|
3262
|
+
transformedArgs = transformed.args;
|
|
3263
|
+
}
|
|
3264
|
+
await this.encryptInternalizeActionModuleMetadata(transformedArgs);
|
|
3265
|
+
let result = await this.underlying.internalizeAction(transformedArgs, originator);
|
|
3266
|
+
for (let index = modules.length - 1; index >= 0; index--) {
|
|
3267
|
+
result = await modules[index].onResponse(result, {
|
|
3268
|
+
method: 'internalizeAction',
|
|
3269
|
+
originator
|
|
3270
|
+
});
|
|
3271
|
+
}
|
|
3272
|
+
return result;
|
|
3273
|
+
}
|
|
3274
|
+
async internalizeAction(...args) {
|
|
3275
|
+
const [requestArgs, originator] = args;
|
|
3276
|
+
// 1) Identify unique P-modules involved (one per schemeID) from both baskets and labels
|
|
3277
|
+
const pModulesByScheme = new Map();
|
|
3278
|
+
const nonPBaskets = this.collectInternalizeActionBaskets(requestArgs, pModulesByScheme);
|
|
3279
|
+
const nonPLabels = this.splitLabelsByPermissionModule(requestArgs.labels, pModulesByScheme);
|
|
3280
|
+
await this.authorizeInternalizeActionBaskets(requestArgs, originator, nonPBaskets);
|
|
3281
|
+
await this.authorizeInternalizeActionLabels(requestArgs, originator, nonPLabels);
|
|
3201
3282
|
// 4) Call underlying wallet, with P-module transformations if needed
|
|
3202
3283
|
if (pModulesByScheme.size > 0) {
|
|
3203
|
-
|
|
3204
|
-
const pModules = Array.from(pModulesByScheme.values());
|
|
3205
|
-
// Chain onRequest calls through all modules in order
|
|
3206
|
-
let transformedArgs = requestArgs;
|
|
3207
|
-
for (const module of pModules) {
|
|
3208
|
-
const transformed = await module.onRequest({
|
|
3209
|
-
method: 'internalizeAction',
|
|
3210
|
-
args: transformedArgs,
|
|
3211
|
-
originator: originator
|
|
3212
|
-
});
|
|
3213
|
-
transformedArgs = transformed.args;
|
|
3214
|
-
}
|
|
3215
|
-
// Encrypt custom instructions for p basket outputs
|
|
3216
|
-
for (const outIndex in transformedArgs.outputs) {
|
|
3217
|
-
const out = transformedArgs.outputs[outIndex];
|
|
3218
|
-
if (out.protocol === 'basket insertion' && ((_a = out.insertionRemittance) === null || _a === void 0 ? void 0 : _a.customInstructions)) {
|
|
3219
|
-
out.insertionRemittance.customInstructions = await this.maybeEncryptMetadata(out.insertionRemittance.customInstructions);
|
|
3220
|
-
}
|
|
3221
|
-
}
|
|
3222
|
-
// Call underlying wallet with transformed args
|
|
3223
|
-
let results = await this.underlying.internalizeAction(transformedArgs, originator);
|
|
3224
|
-
// Chain onResponse calls in reverse order
|
|
3225
|
-
for (let i = pModules.length - 1; i >= 0; i--) {
|
|
3226
|
-
results = await pModules[i].onResponse(results, {
|
|
3227
|
-
method: 'internalizeAction',
|
|
3228
|
-
originator: originator
|
|
3229
|
-
});
|
|
3230
|
-
}
|
|
3231
|
-
return results;
|
|
3284
|
+
return await this.runInternalizeActionModules(requestArgs, originator, Array.from(pModulesByScheme.values()));
|
|
3232
3285
|
}
|
|
3233
3286
|
// No P-modules - call underlying wallet directly
|
|
3234
|
-
return this.underlying.internalizeAction(...args);
|
|
3287
|
+
return await this.underlying.internalizeAction(...args);
|
|
3235
3288
|
}
|
|
3236
3289
|
async listOutputs(...args) {
|
|
3237
3290
|
const [requestArgs, originator] = args;
|
|
@@ -3270,11 +3323,11 @@ class WalletPermissionsManager {
|
|
|
3270
3323
|
reason: 'relinquishOutput',
|
|
3271
3324
|
usageType: 'removal'
|
|
3272
3325
|
});
|
|
3273
|
-
return this.underlying.relinquishOutput(...args);
|
|
3326
|
+
return await this.underlying.relinquishOutput(...args);
|
|
3274
3327
|
}
|
|
3275
3328
|
async getPublicKey(...args) {
|
|
3276
3329
|
const [requestArgs, originator] = args;
|
|
3277
|
-
if (requestArgs.protocolID) {
|
|
3330
|
+
if (requestArgs.protocolID != null) {
|
|
3278
3331
|
// Delegate to permission module if needed
|
|
3279
3332
|
const pModuleResult = await this.delegateToPModuleIfNeeded(requestArgs.protocolID[1], 'getPublicKey', requestArgs, originator, async (transformedArgs) => {
|
|
3280
3333
|
return await this.underlying.getPublicKey(transformedArgs, originator);
|
|
@@ -3289,6 +3342,7 @@ class WalletPermissionsManager {
|
|
|
3289
3342
|
protocolID: requestArgs.protocolID,
|
|
3290
3343
|
counterparty: requestArgs.counterparty || 'self',
|
|
3291
3344
|
reason: requestArgs.privilegedReason,
|
|
3345
|
+
seekPermission: requestArgs.seekPermission,
|
|
3292
3346
|
usageType: 'publicKey'
|
|
3293
3347
|
});
|
|
3294
3348
|
}
|
|
@@ -3300,10 +3354,11 @@ class WalletPermissionsManager {
|
|
|
3300
3354
|
protocolID: [1, 'identity key retrieval'],
|
|
3301
3355
|
counterparty: 'self',
|
|
3302
3356
|
reason: requestArgs.privilegedReason,
|
|
3357
|
+
seekPermission: requestArgs.seekPermission,
|
|
3303
3358
|
usageType: 'identityKey'
|
|
3304
3359
|
});
|
|
3305
3360
|
}
|
|
3306
|
-
return this.underlying.getPublicKey(...args);
|
|
3361
|
+
return await this.underlying.getPublicKey(...args);
|
|
3307
3362
|
}
|
|
3308
3363
|
async revealCounterpartyKeyLinkage(...args) {
|
|
3309
3364
|
const [requestArgs, originator] = args;
|
|
@@ -3315,7 +3370,7 @@ class WalletPermissionsManager {
|
|
|
3315
3370
|
reason: requestArgs.privilegedReason,
|
|
3316
3371
|
usageType: 'linkageRevelation'
|
|
3317
3372
|
});
|
|
3318
|
-
return this.underlying.revealCounterpartyKeyLinkage(...args);
|
|
3373
|
+
return await this.underlying.revealCounterpartyKeyLinkage(...args);
|
|
3319
3374
|
}
|
|
3320
3375
|
async revealSpecificKeyLinkage(...args) {
|
|
3321
3376
|
const [requestArgs, originator] = args;
|
|
@@ -3330,7 +3385,7 @@ class WalletPermissionsManager {
|
|
|
3330
3385
|
reason: requestArgs.privilegedReason,
|
|
3331
3386
|
usageType: 'linkageRevelation'
|
|
3332
3387
|
});
|
|
3333
|
-
return this.underlying.revealSpecificKeyLinkage(...args);
|
|
3388
|
+
return await this.underlying.revealSpecificKeyLinkage(...args);
|
|
3334
3389
|
}
|
|
3335
3390
|
async encrypt(...args) {
|
|
3336
3391
|
const [requestArgs, originator] = args;
|
|
@@ -3349,7 +3404,7 @@ class WalletPermissionsManager {
|
|
|
3349
3404
|
reason: requestArgs.privilegedReason,
|
|
3350
3405
|
usageType: 'encrypting'
|
|
3351
3406
|
});
|
|
3352
|
-
return this.underlying.encrypt(...args);
|
|
3407
|
+
return await this.underlying.encrypt(...args);
|
|
3353
3408
|
}
|
|
3354
3409
|
async decrypt(...args) {
|
|
3355
3410
|
const [requestArgs, originator] = args;
|
|
@@ -3368,7 +3423,7 @@ class WalletPermissionsManager {
|
|
|
3368
3423
|
reason: requestArgs.privilegedReason,
|
|
3369
3424
|
usageType: 'encrypting'
|
|
3370
3425
|
});
|
|
3371
|
-
return this.underlying.decrypt(...args);
|
|
3426
|
+
return await this.underlying.decrypt(...args);
|
|
3372
3427
|
}
|
|
3373
3428
|
async createHmac(...args) {
|
|
3374
3429
|
const [requestArgs, originator] = args;
|
|
@@ -3387,7 +3442,7 @@ class WalletPermissionsManager {
|
|
|
3387
3442
|
reason: requestArgs.privilegedReason,
|
|
3388
3443
|
usageType: 'hmac'
|
|
3389
3444
|
});
|
|
3390
|
-
return this.underlying.createHmac(...args);
|
|
3445
|
+
return await this.underlying.createHmac(...args);
|
|
3391
3446
|
}
|
|
3392
3447
|
async verifyHmac(...args) {
|
|
3393
3448
|
const [requestArgs, originator] = args;
|
|
@@ -3406,7 +3461,7 @@ class WalletPermissionsManager {
|
|
|
3406
3461
|
reason: requestArgs.privilegedReason,
|
|
3407
3462
|
usageType: 'hmac'
|
|
3408
3463
|
});
|
|
3409
|
-
return this.underlying.verifyHmac(...args);
|
|
3464
|
+
return await this.underlying.verifyHmac(...args);
|
|
3410
3465
|
}
|
|
3411
3466
|
async createSignature(...args) {
|
|
3412
3467
|
const [requestArgs, originator] = args;
|
|
@@ -3425,7 +3480,7 @@ class WalletPermissionsManager {
|
|
|
3425
3480
|
reason: requestArgs.privilegedReason,
|
|
3426
3481
|
usageType: 'signing'
|
|
3427
3482
|
});
|
|
3428
|
-
return this.underlying.createSignature(...args);
|
|
3483
|
+
return await this.underlying.createSignature(...args);
|
|
3429
3484
|
}
|
|
3430
3485
|
async verifySignature(...args) {
|
|
3431
3486
|
const [requestArgs, originator] = args;
|
|
@@ -3444,7 +3499,7 @@ class WalletPermissionsManager {
|
|
|
3444
3499
|
reason: requestArgs.privilegedReason,
|
|
3445
3500
|
usageType: 'signing'
|
|
3446
3501
|
});
|
|
3447
|
-
return this.underlying.verifySignature(...args);
|
|
3502
|
+
return await this.underlying.verifySignature(...args);
|
|
3448
3503
|
}
|
|
3449
3504
|
async acquireCertificate(...args) {
|
|
3450
3505
|
const [requestArgs, originator] = args;
|
|
@@ -3458,7 +3513,7 @@ class WalletPermissionsManager {
|
|
|
3458
3513
|
usageType: 'generic'
|
|
3459
3514
|
});
|
|
3460
3515
|
}
|
|
3461
|
-
return this.underlying.acquireCertificate(...args);
|
|
3516
|
+
return await this.underlying.acquireCertificate(...args);
|
|
3462
3517
|
}
|
|
3463
3518
|
async listCertificates(...args) {
|
|
3464
3519
|
const [requestArgs, originator] = args;
|
|
@@ -3466,13 +3521,13 @@ class WalletPermissionsManager {
|
|
|
3466
3521
|
await this.ensureProtocolPermission({
|
|
3467
3522
|
originator: originator,
|
|
3468
3523
|
privileged: requestArgs.privileged,
|
|
3469
|
-
protocolID: [1,
|
|
3524
|
+
protocolID: [1, 'certificate list'],
|
|
3470
3525
|
counterparty: 'self',
|
|
3471
3526
|
reason: requestArgs.privilegedReason,
|
|
3472
3527
|
usageType: 'generic'
|
|
3473
3528
|
});
|
|
3474
3529
|
}
|
|
3475
|
-
return this.underlying.listCertificates(...args);
|
|
3530
|
+
return await this.underlying.listCertificates(...args);
|
|
3476
3531
|
}
|
|
3477
3532
|
async proveCertificate(...args) {
|
|
3478
3533
|
const [requestArgs, originator] = args;
|
|
@@ -3485,21 +3540,21 @@ class WalletPermissionsManager {
|
|
|
3485
3540
|
reason: 'proveCertificate',
|
|
3486
3541
|
usageType: 'disclosure'
|
|
3487
3542
|
});
|
|
3488
|
-
return this.underlying.proveCertificate(...args);
|
|
3543
|
+
return await this.underlying.proveCertificate(...args);
|
|
3489
3544
|
}
|
|
3490
3545
|
async relinquishCertificate(...args) {
|
|
3491
3546
|
const [requestArgs, originator] = args;
|
|
3492
3547
|
if (this.config.seekCertificateRelinquishmentPermissions) {
|
|
3493
3548
|
await this.ensureProtocolPermission({
|
|
3494
3549
|
originator: originator,
|
|
3495
|
-
privileged: requestArgs.privileged
|
|
3550
|
+
privileged: !!requestArgs.privileged,
|
|
3496
3551
|
protocolID: [1, `certificate relinquishment ${requestArgs.type}`],
|
|
3497
3552
|
counterparty: 'self',
|
|
3498
3553
|
reason: requestArgs.privilegedReason || 'relinquishCertificate',
|
|
3499
3554
|
usageType: 'generic'
|
|
3500
3555
|
});
|
|
3501
3556
|
}
|
|
3502
|
-
return this.underlying.relinquishCertificate(...args);
|
|
3557
|
+
return await this.underlying.relinquishCertificate(...args);
|
|
3503
3558
|
}
|
|
3504
3559
|
async discoverByIdentityKey(...args) {
|
|
3505
3560
|
const [_, originator] = args;
|
|
@@ -3507,13 +3562,13 @@ class WalletPermissionsManager {
|
|
|
3507
3562
|
await this.ensureProtocolPermission({
|
|
3508
3563
|
originator: originator,
|
|
3509
3564
|
privileged: false,
|
|
3510
|
-
protocolID: [1,
|
|
3565
|
+
protocolID: [1, 'identity resolution'],
|
|
3511
3566
|
counterparty: 'self',
|
|
3512
3567
|
reason: 'discoverByIdentityKey',
|
|
3513
3568
|
usageType: 'generic'
|
|
3514
3569
|
});
|
|
3515
3570
|
}
|
|
3516
|
-
return this.underlying.discoverByIdentityKey(...args);
|
|
3571
|
+
return await this.underlying.discoverByIdentityKey(...args);
|
|
3517
3572
|
}
|
|
3518
3573
|
async discoverByAttributes(...args) {
|
|
3519
3574
|
const [_, originator] = args;
|
|
@@ -3521,26 +3576,26 @@ class WalletPermissionsManager {
|
|
|
3521
3576
|
await this.ensureProtocolPermission({
|
|
3522
3577
|
originator: originator,
|
|
3523
3578
|
privileged: false,
|
|
3524
|
-
protocolID: [1,
|
|
3579
|
+
protocolID: [1, 'identity resolution'],
|
|
3525
3580
|
counterparty: 'self',
|
|
3526
3581
|
reason: 'discoverByAttributes',
|
|
3527
3582
|
usageType: 'generic'
|
|
3528
3583
|
});
|
|
3529
3584
|
}
|
|
3530
|
-
return this.underlying.discoverByAttributes(...args);
|
|
3585
|
+
return await this.underlying.discoverByAttributes(...args);
|
|
3531
3586
|
}
|
|
3532
3587
|
async isAuthenticated(...args) {
|
|
3533
|
-
return this.underlying.isAuthenticated(...args);
|
|
3588
|
+
return await this.underlying.isAuthenticated(...args);
|
|
3534
3589
|
}
|
|
3535
3590
|
async waitForAuthentication(...args) {
|
|
3536
|
-
|
|
3591
|
+
const [_, originator] = args;
|
|
3537
3592
|
if (this.config.seekGroupedPermission && originator) {
|
|
3538
3593
|
const { normalized: normalizedOriginator } = this.prepareOriginator(originator);
|
|
3539
3594
|
const normalized = normalizedOriginator;
|
|
3540
3595
|
await this.withGroupedPermissionFlowLock(normalized, async () => {
|
|
3541
3596
|
// 1. Fetch manifest.json from the originator
|
|
3542
3597
|
const groupPermissions = await this.fetchManifestGroupPermissions(normalized);
|
|
3543
|
-
if (groupPermissions) {
|
|
3598
|
+
if (groupPermissions != null) {
|
|
3544
3599
|
// 2. Filter out already-granted permissions
|
|
3545
3600
|
const permissionsToRequest = await this.filterAlreadyGrantedPermissions(normalized, groupPermissions);
|
|
3546
3601
|
// 3. If any permissions are left to request, start the flow
|
|
@@ -3573,19 +3628,19 @@ class WalletPermissionsManager {
|
|
|
3573
3628
|
});
|
|
3574
3629
|
}
|
|
3575
3630
|
// Finally, after handling grouped permissions, call the underlying method.
|
|
3576
|
-
return this.underlying.waitForAuthentication(...args);
|
|
3631
|
+
return await this.underlying.waitForAuthentication(...args);
|
|
3577
3632
|
}
|
|
3578
3633
|
async getHeight(...args) {
|
|
3579
|
-
return this.underlying.getHeight(...args);
|
|
3634
|
+
return await this.underlying.getHeight(...args);
|
|
3580
3635
|
}
|
|
3581
3636
|
async getHeaderForHeight(...args) {
|
|
3582
|
-
return this.underlying.getHeaderForHeight(...args);
|
|
3637
|
+
return await this.underlying.getHeaderForHeight(...args);
|
|
3583
3638
|
}
|
|
3584
3639
|
async getNetwork(...args) {
|
|
3585
|
-
return this.underlying.getNetwork(...args);
|
|
3640
|
+
return await this.underlying.getNetwork(...args);
|
|
3586
3641
|
}
|
|
3587
3642
|
async getVersion(...args) {
|
|
3588
|
-
return this.underlying.getVersion(...args);
|
|
3643
|
+
return await this.underlying.getVersion(...args);
|
|
3589
3644
|
}
|
|
3590
3645
|
/* ---------------------------------------------------------------------
|
|
3591
3646
|
* 8) INTERNAL HELPER UTILITIES
|
|
@@ -3640,13 +3695,44 @@ class WalletPermissionsManager {
|
|
|
3640
3695
|
return true;
|
|
3641
3696
|
return false;
|
|
3642
3697
|
}
|
|
3698
|
+
/**
|
|
3699
|
+
* Whether the permission is satisfied without consulting on-chain tokens:
|
|
3700
|
+
* cached, recently granted, or — when the user just granted it and its
|
|
3701
|
+
* token is still minting — after the in-flight mint settles. Spares the
|
|
3702
|
+
* user a duplicate prompt for a grant they already made moments ago.
|
|
3703
|
+
*/
|
|
3704
|
+
async hasRecentOrPendingGrant(cacheKey) {
|
|
3705
|
+
if (!this.telemetry.enabled)
|
|
3706
|
+
return await this.hasRecentOrPendingGrantCore(cacheKey);
|
|
3707
|
+
return await this.telemetry.withSpan('wallet.permission.cache_check', {
|
|
3708
|
+
component: 'wallet-permissions'
|
|
3709
|
+
}, async (span) => {
|
|
3710
|
+
const result = await this.hasRecentOrPendingGrantCore(cacheKey);
|
|
3711
|
+
span.end({
|
|
3712
|
+
attributes: {
|
|
3713
|
+
'permission.cache_hit': result,
|
|
3714
|
+
'permission.mint_in_flight': this.mintsInFlight.has(cacheKey)
|
|
3715
|
+
}
|
|
3716
|
+
});
|
|
3717
|
+
return result;
|
|
3718
|
+
});
|
|
3719
|
+
}
|
|
3720
|
+
async hasRecentOrPendingGrantCore(cacheKey) {
|
|
3721
|
+
if (this.isPermissionCached(cacheKey) || this.isRecentlyGranted(cacheKey))
|
|
3722
|
+
return true;
|
|
3723
|
+
const inFlight = this.mintsInFlight.get(cacheKey);
|
|
3724
|
+
if (inFlight == null)
|
|
3725
|
+
return false;
|
|
3726
|
+
await inFlight;
|
|
3727
|
+
return this.isPermissionCached(cacheKey) || this.isRecentlyGranted(cacheKey);
|
|
3728
|
+
}
|
|
3643
3729
|
/**
|
|
3644
3730
|
* Returns true if we have a cached record that the permission identified by
|
|
3645
3731
|
* `key` is valid and unexpired.
|
|
3646
3732
|
*/
|
|
3647
3733
|
isPermissionCached(key) {
|
|
3648
3734
|
const entry = this.permissionCache.get(key);
|
|
3649
|
-
if (
|
|
3735
|
+
if (entry == null)
|
|
3650
3736
|
return false;
|
|
3651
3737
|
if (Date.now() - entry.cachedAt > WalletPermissionsManager.CACHE_TTL_MS) {
|
|
3652
3738
|
this.permissionCache.delete(key);
|
|
@@ -3707,25 +3793,24 @@ class WalletPermissionsManager {
|
|
|
3707
3793
|
}
|
|
3708
3794
|
return port ? `${baseHost}:${port}` : baseHost;
|
|
3709
3795
|
}
|
|
3710
|
-
catch
|
|
3796
|
+
catch {
|
|
3711
3797
|
// Fall back to a conservative lowercase trim if URL parsing fails.
|
|
3712
3798
|
return trimmed.toLowerCase();
|
|
3713
3799
|
}
|
|
3714
3800
|
}
|
|
3715
3801
|
isWhitelistedCounterpartyProtocol(counterparty, protocolID) {
|
|
3716
|
-
var _a;
|
|
3717
3802
|
const whitelist = this.config.whitelistedCounterparties;
|
|
3718
|
-
if (
|
|
3803
|
+
if (whitelist == null)
|
|
3719
3804
|
return false;
|
|
3720
3805
|
if (!counterparty || counterparty === 'self' || counterparty === 'anyone')
|
|
3721
3806
|
return false;
|
|
3722
3807
|
const protocols = whitelist[counterparty] || whitelist[counterparty.toLowerCase()] || whitelist[counterparty.toUpperCase()];
|
|
3723
3808
|
if (!protocols || protocols.length === 0)
|
|
3724
3809
|
return false;
|
|
3725
|
-
const protoName = (
|
|
3810
|
+
const protoName = (protocolID?.[1] ?? '').toString().toLowerCase();
|
|
3726
3811
|
if (!protoName)
|
|
3727
3812
|
return false;
|
|
3728
|
-
return protocols.some(p => (p
|
|
3813
|
+
return protocols.some(p => (p ?? '').toString().toLowerCase() === protoName);
|
|
3729
3814
|
}
|
|
3730
3815
|
/**
|
|
3731
3816
|
* Produces a normalized originator value along with the set of legacy
|
|
@@ -3733,7 +3818,7 @@ class WalletPermissionsManager {
|
|
|
3733
3818
|
* permission tokens (for backwards compatibility).
|
|
3734
3819
|
*/
|
|
3735
3820
|
prepareOriginator(originator) {
|
|
3736
|
-
const trimmed = originator
|
|
3821
|
+
const trimmed = originator?.trim();
|
|
3737
3822
|
if (!trimmed) {
|
|
3738
3823
|
throw new Error('Originator is required for permission checks.');
|
|
3739
3824
|
}
|
|
@@ -3748,7 +3833,7 @@ class WalletPermissionsManager {
|
|
|
3748
3833
|
buildOriginatorLookupValues(...origins) {
|
|
3749
3834
|
const variants = new Set();
|
|
3750
3835
|
for (const origin of origins) {
|
|
3751
|
-
const trimmed = origin
|
|
3836
|
+
const trimmed = origin?.trim();
|
|
3752
3837
|
if (trimmed) {
|
|
3753
3838
|
variants.add(trimmed);
|
|
3754
3839
|
}
|
|
@@ -3760,58 +3845,25 @@ class WalletPermissionsManager {
|
|
|
3760
3845
|
* do not produce multiple user prompts.
|
|
3761
3846
|
*/
|
|
3762
3847
|
buildRequestKey(r) {
|
|
3763
|
-
var _a, _b, _c, _d, _e;
|
|
3764
3848
|
const normalizedOriginator = this.normalizeOriginator(r.originator);
|
|
3765
3849
|
switch (r.type) {
|
|
3766
3850
|
case 'protocol':
|
|
3767
|
-
return `proto:${normalizedOriginator}:${!!r.privileged}:${
|
|
3851
|
+
return `proto:${normalizedOriginator}:${!!r.privileged}:${r.protocolID?.join(',')}:${r.counterparty}`;
|
|
3768
3852
|
case 'basket':
|
|
3769
3853
|
return `basket:${normalizedOriginator}:${r.basket}`;
|
|
3770
3854
|
case 'certificate':
|
|
3771
|
-
return `cert:${normalizedOriginator}:${!!r.privileged}:${
|
|
3855
|
+
return `cert:${normalizedOriginator}:${!!r.privileged}:${r.certificate?.verifier}:${r.certificate?.certType}:${r.certificate?.fields.join('|')}`;
|
|
3772
3856
|
case 'spending':
|
|
3773
|
-
return `spend:${normalizedOriginator}:${
|
|
3857
|
+
return `spend:${normalizedOriginator}:${r.spending?.satoshis}`;
|
|
3774
3858
|
}
|
|
3775
3859
|
}
|
|
3776
3860
|
buildActiveRequestKey(r) {
|
|
3777
|
-
var _a;
|
|
3778
3861
|
const base = this.buildRequestKey(r);
|
|
3779
3862
|
if (r.type === 'protocol' || r.type === 'basket' || r.type === 'certificate') {
|
|
3780
|
-
return `${base}:${
|
|
3863
|
+
return `${base}:${r.usageType ?? ''}`;
|
|
3781
3864
|
}
|
|
3782
3865
|
return base;
|
|
3783
3866
|
}
|
|
3784
3867
|
}
|
|
3785
3868
|
exports.WalletPermissionsManager = WalletPermissionsManager;
|
|
3786
|
-
WalletPermissionsManager.MANIFEST_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
3787
|
-
/** How long a cached permission remains valid (5 minutes). */
|
|
3788
|
-
WalletPermissionsManager.CACHE_TTL_MS = 5 * 60 * 1000;
|
|
3789
|
-
/** Window during which freshly granted permissions are auto-allowed (except spending). */
|
|
3790
|
-
WalletPermissionsManager.RECENT_GRANT_COVER_MS = 15 * 1000;
|
|
3791
|
-
/** Default ports used when normalizing originator values. */
|
|
3792
|
-
WalletPermissionsManager.DEFAULT_PORTS = {
|
|
3793
|
-
'http:': '80',
|
|
3794
|
-
'https:': '443'
|
|
3795
|
-
};
|
|
3796
|
-
/* ---------------------------------------------------------------------
|
|
3797
|
-
* 4) SEARCH / DECODE / DECRYPT ON-CHAIN TOKENS (PushDrop Scripts)
|
|
3798
|
-
* --------------------------------------------------------------------- */
|
|
3799
|
-
/**
|
|
3800
|
-
* We will use a administrative "permission token encryption" protocol to store fields
|
|
3801
|
-
* in each permission's PushDrop script. This ensures that only the user's wallet
|
|
3802
|
-
* can decrypt them. In practice, this data is not super sensitive, but we still
|
|
3803
|
-
* follow the principle of least exposure.
|
|
3804
|
-
*/
|
|
3805
|
-
WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL = [
|
|
3806
|
-
2,
|
|
3807
|
-
'admin permission token encryption'
|
|
3808
|
-
];
|
|
3809
|
-
/**
|
|
3810
|
-
* Similarly, we will use a "metadata encryption" protocol to preserve the confidentiality
|
|
3811
|
-
* of transaction descriptions and input/output descriptions from lower storage layers.
|
|
3812
|
-
*/
|
|
3813
|
-
WalletPermissionsManager.METADATA_ENCRYPTION_PROTOCOL = [
|
|
3814
|
-
2,
|
|
3815
|
-
'admin metadata encryption'
|
|
3816
|
-
];
|
|
3817
3869
|
//# sourceMappingURL=WalletPermissionsManager.js.map
|