@bsv/wallet-toolbox-client 2.1.24 → 2.1.26
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/out/src/CWIStyleWalletManager.d.ts +33 -7
- package/out/src/CWIStyleWalletManager.d.ts.map +1 -1
- package/out/src/CWIStyleWalletManager.js +281 -313
- package/out/src/CWIStyleWalletManager.js.map +1 -1
- package/out/src/SetupClient.d.ts +6 -6
- package/out/src/SetupClient.d.ts.map +1 -1
- package/out/src/SetupClient.js +5 -5
- package/out/src/SetupClient.js.map +1 -1
- package/out/src/SetupWallet.d.ts.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 +46 -30
- package/out/src/SimpleWalletManager.js.map +1 -1
- package/out/src/Wallet.d.ts +1 -1
- package/out/src/Wallet.d.ts.map +1 -1
- package/out/src/Wallet.js +102 -100
- package/out/src/Wallet.js.map +1 -1
- package/out/src/WalletAuthenticationManager.d.ts +1 -1
- package/out/src/WalletAuthenticationManager.d.ts.map +1 -1
- package/out/src/WalletAuthenticationManager.js +3 -3
- package/out/src/WalletAuthenticationManager.js.map +1 -1
- package/out/src/WalletLogger.d.ts.map +1 -1
- package/out/src/WalletLogger.js +16 -8
- package/out/src/WalletLogger.js.map +1 -1
- package/out/src/WalletPermissionsManager.d.ts +89 -18
- package/out/src/WalletPermissionsManager.d.ts.map +1 -1
- package/out/src/WalletPermissionsManager.js +656 -870
- 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.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 +11 -10
- package/out/src/fundWalletP2PKH.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.map +1 -1
- package/out/src/mockchain/MockChainStorage.d.ts.map +1 -1
- package/out/src/mockchain/MockChainStorage.js +8 -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 +10 -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 +3 -3
- package/out/src/mockchain/MockMiner.js.map +1 -1
- package/out/src/mockchain/MockServices.d.ts +9 -0
- package/out/src/mockchain/MockServices.d.ts.map +1 -1
- package/out/src/mockchain/MockServices.js +201 -243
- 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 +21 -12
- package/out/src/mockchain/merkleTree.js.map +1 -1
- package/out/src/monitor/Monitor.d.ts +17 -0
- package/out/src/monitor/Monitor.d.ts.map +1 -1
- package/out/src/monitor/Monitor.js +63 -80
- package/out/src/monitor/Monitor.js.map +1 -1
- package/out/src/monitor/tasks/TaskArcSSE.d.ts +2 -2
- package/out/src/monitor/tasks/TaskArcSSE.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskArcSSE.js +10 -23
- package/out/src/monitor/tasks/TaskArcSSE.js.map +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.d.ts +2 -2
- package/out/src/monitor/tasks/TaskCheckForProofs.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.js +28 -16
- package/out/src/monitor/tasks/TaskCheckForProofs.js.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.d.ts +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.js +1 -2
- package/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -1
- package/out/src/monitor/tasks/TaskClock.d.ts +1 -1
- package/out/src/monitor/tasks/TaskClock.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskClock.js +0 -1
- 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.map +1 -1
- package/out/src/monitor/tasks/TaskMineBlock.d.ts +1 -1
- package/out/src/monitor/tasks/TaskMineBlock.d.ts.map +1 -1
- 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 +1 -1
- package/out/src/monitor/tasks/TaskMonitorCallHistory.js.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.d.ts +2 -2
- package/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.js +7 -5
- package/out/src/monitor/tasks/TaskNewHeader.js.map +1 -1
- package/out/src/monitor/tasks/TaskPurge.d.ts +1 -1
- package/out/src/monitor/tasks/TaskPurge.d.ts.map +1 -1
- 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 +2 -2
- package/out/src/monitor/tasks/TaskReorg.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.d.ts +1 -1
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.js +10 -10
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewProvenTxs.d.ts +1 -1
- package/out/src/monitor/tasks/TaskReviewProvenTxs.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewProvenTxs.js +2 -2
- package/out/src/monitor/tasks/TaskReviewProvenTxs.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewStatus.d.ts +1 -1
- package/out/src/monitor/tasks/TaskReviewStatus.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewStatus.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.d.ts +1 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.js.map +1 -1
- package/out/src/monitor/tasks/TaskSendWaiting.d.ts +1 -1
- package/out/src/monitor/tasks/TaskSendWaiting.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskSendWaiting.js +4 -5
- package/out/src/monitor/tasks/TaskSendWaiting.js.map +1 -1
- package/out/src/monitor/tasks/TaskUnFail.d.ts +1 -1
- package/out/src/monitor/tasks/TaskUnFail.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskUnFail.js +13 -15
- 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 +3 -1
- package/out/src/monitor/tasks/WalletMonitorTask.js.map +1 -1
- 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 +32 -24
- package/out/src/sdk/PrivilegedKeyManager.js.map +1 -1
- package/out/src/sdk/WERR_errors.d.ts.map +1 -1
- package/out/src/sdk/WERR_errors.js +5 -5
- package/out/src/sdk/WERR_errors.js.map +1 -1
- package/out/src/sdk/WalletError.d.ts +1 -1
- package/out/src/sdk/WalletError.d.ts.map +1 -1
- package/out/src/sdk/WalletError.js +28 -20
- 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 +19 -19
- package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
- package/out/src/sdk/WalletStorage.interfaces.d.ts +59 -59
- package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
- package/out/src/sdk/types.d.ts +4 -4
- package/out/src/sdk/types.d.ts.map +1 -1
- package/out/src/sdk/types.js +3 -3
- 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 +6 -8
- package/out/src/services/ServiceCollection.js.map +1 -1
- package/out/src/services/Services.d.ts +5 -0
- package/out/src/services/Services.d.ts.map +1 -1
- package/out/src/services/Services.js +190 -196
- package/out/src/services/Services.js.map +1 -1
- package/out/src/services/chaintracker/BHServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/BHServiceClient.js +7 -7
- package/out/src/services/chaintracker/BHServiceClient.js.map +1 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.d.ts.map +1 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.js +5 -5
- package/out/src/services/chaintracker/ChaintracksChainTracker.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts +5 -3
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BulkStorageApi.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts +20 -10
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js +228 -221
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js +9 -10
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.js +1 -1
- 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 +3 -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/BulkIngestorWhatsOnChainCdn.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.js +3 -3
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.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 +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.js +2 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.d.ts +2 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.js +6 -39
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.d.ts +3 -3
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.js +8 -6
- 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 +9 -16
- package/out/src/services/chaintracker/chaintracks/Storage/BulkStorageBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.js +34 -22
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js +31 -30
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.d.ts +2 -2
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.js +11 -10
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createIdbChaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createNoDbChaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts +6 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js +247 -227
- 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 +8 -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 +35 -25
- 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 +13 -11
- package/out/src/services/chaintracker/chaintracks/util/BulkHeaderFile.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts +0 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.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 +21 -13
- 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.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts +1 -1
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js +28 -24
- 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.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.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.js +3 -3
- package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/out/src/services/providers/ARC.d.ts.map +1 -1
- package/out/src/services/providers/ARC.js +7 -14
- package/out/src/services/providers/ARC.js.map +1 -1
- package/out/src/services/providers/ArcSSEClient.d.ts.map +1 -1
- package/out/src/services/providers/ArcSSEClient.js +1 -1
- package/out/src/services/providers/ArcSSEClient.js.map +1 -1
- package/out/src/services/providers/Bitails.d.ts.map +1 -1
- package/out/src/services/providers/Bitails.js +17 -17
- package/out/src/services/providers/Bitails.js.map +1 -1
- package/out/src/services/providers/SdkWhatsOnChain.d.ts.map +1 -1
- package/out/src/services/providers/SdkWhatsOnChain.js.map +1 -1
- package/out/src/services/providers/WhatsOnChain.d.ts +2 -0
- package/out/src/services/providers/WhatsOnChain.d.ts.map +1 -1
- package/out/src/services/providers/WhatsOnChain.js +109 -233
- 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 +3 -3
- 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.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.map +1 -1
- package/out/src/signer/methods/acquireDirectCertificate.js +1 -1
- package/out/src/signer/methods/acquireDirectCertificate.js.map +1 -1
- package/out/src/signer/methods/buildSignableTransaction.d.ts.map +1 -1
- package/out/src/signer/methods/buildSignableTransaction.js +21 -13
- package/out/src/signer/methods/buildSignableTransaction.js.map +1 -1
- package/out/src/signer/methods/completeSignedTransaction.d.ts.map +1 -1
- package/out/src/signer/methods/completeSignedTransaction.js +20 -21
- 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 +8 -7
- package/out/src/signer/methods/createAction.js.map +1 -1
- package/out/src/signer/methods/internalizeAction.d.ts.map +1 -1
- package/out/src/signer/methods/internalizeAction.js +8 -6
- package/out/src/signer/methods/internalizeAction.js.map +1 -1
- package/out/src/signer/methods/proveCertificate.js +1 -1
- package/out/src/signer/methods/signAction.d.ts.map +1 -1
- package/out/src/signer/methods/signAction.js +8 -10
- package/out/src/signer/methods/signAction.js.map +1 -1
- package/out/src/storage/StorageIdb.d.ts +16 -1
- package/out/src/storage/StorageIdb.d.ts.map +1 -1
- package/out/src/storage/StorageIdb.js +578 -1258
- package/out/src/storage/StorageIdb.js.map +1 -1
- package/out/src/storage/StorageProvider.d.ts +10 -0
- package/out/src/storage/StorageProvider.d.ts.map +1 -1
- package/out/src/storage/StorageProvider.js +171 -197
- package/out/src/storage/StorageProvider.js.map +1 -1
- package/out/src/storage/StorageReader.d.ts.map +1 -1
- package/out/src/storage/StorageReader.js +14 -13
- 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 +4 -4
- package/out/src/storage/StorageSyncReader.js.map +1 -1
- package/out/src/storage/WalletStorageManager.d.ts +3 -0
- package/out/src/storage/WalletStorageManager.d.ts.map +1 -1
- package/out/src/storage/WalletStorageManager.js +95 -84
- package/out/src/storage/WalletStorageManager.js.map +1 -1
- package/out/src/storage/idbHelpers.d.ts +42 -0
- package/out/src/storage/idbHelpers.d.ts.map +1 -0
- package/out/src/storage/idbHelpers.js +375 -0
- package/out/src/storage/idbHelpers.js.map +1 -0
- package/out/src/storage/index.client.d.ts +3 -0
- package/out/src/storage/index.client.d.ts.map +1 -1
- package/out/src/storage/index.client.js +3 -0
- package/out/src/storage/index.client.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 +28 -2
- package/out/src/storage/methods/ListActionsSpecOp.js.map +1 -1
- package/out/src/storage/methods/ListOutputsSpecOp.d.ts.map +1 -1
- package/out/src/storage/methods/ListOutputsSpecOp.js +8 -11
- package/out/src/storage/methods/ListOutputsSpecOp.js.map +1 -1
- package/out/src/storage/methods/attemptToPostReqsToNetwork.d.ts +83 -0
- package/out/src/storage/methods/attemptToPostReqsToNetwork.d.ts.map +1 -1
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js +224 -61
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js.map +1 -1
- package/out/src/storage/methods/createAction.d.ts.map +1 -1
- package/out/src/storage/methods/createAction.js +230 -270
- package/out/src/storage/methods/createAction.js.map +1 -1
- package/out/src/storage/methods/generateChange.d.ts.map +1 -1
- package/out/src/storage/methods/generateChange.js +99 -80
- package/out/src/storage/methods/generateChange.js.map +1 -1
- package/out/src/storage/methods/getBeefForTransaction.js +15 -13
- 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 +4 -3
- package/out/src/storage/methods/getSyncChunk.js.map +1 -1
- package/out/src/storage/methods/internalizeAction.js +41 -51
- 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 +85 -110
- package/out/src/storage/methods/listActionsIdb.js.map +1 -1
- package/out/src/storage/methods/listCertificates.d.ts +1 -1
- package/out/src/storage/methods/listCertificates.d.ts.map +1 -1
- package/out/src/storage/methods/listCertificates.js +7 -7
- package/out/src/storage/methods/listCertificates.js.map +1 -1
- package/out/src/storage/methods/listOutputsIdb.d.ts.map +1 -1
- package/out/src/storage/methods/listOutputsIdb.js +24 -27
- package/out/src/storage/methods/listOutputsIdb.js.map +1 -1
- 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 -5
- package/out/src/storage/methods/offsetKey.js.map +1 -1
- package/out/src/storage/methods/processAction.d.ts +0 -11
- package/out/src/storage/methods/processAction.d.ts.map +1 -1
- package/out/src/storage/methods/processAction.js +90 -83
- package/out/src/storage/methods/processAction.js.map +1 -1
- package/out/src/storage/methods/purgeDataIdb.d.ts.map +1 -1
- package/out/src/storage/methods/purgeDataIdb.js +1 -1
- package/out/src/storage/methods/purgeDataIdb.js.map +1 -1
- package/out/src/storage/methods/reviewStatusIdb.d.ts +1 -1
- package/out/src/storage/methods/reviewStatusIdb.d.ts.map +1 -1
- package/out/src/storage/methods/reviewStatusIdb.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 +830 -0
- package/out/src/storage/portable/index.js.map +1 -0
- package/out/src/storage/remoting/StorageClient.d.ts +4 -270
- package/out/src/storage/remoting/StorageClient.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageClient.js +16 -423
- package/out/src/storage/remoting/StorageClient.js.map +1 -1
- package/out/src/storage/remoting/StorageClientBase.d.ts +289 -0
- package/out/src/storage/remoting/StorageClientBase.d.ts.map +1 -0
- package/out/src/storage/remoting/StorageClientBase.js +375 -0
- package/out/src/storage/remoting/StorageClientBase.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 +91 -0
- package/out/src/storage/remoting/entityValidationHelpers.js.map +1 -0
- package/out/src/storage/schema/StorageIdbSchema.d.ts +1 -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.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 +6 -6
- 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 +3 -3
- package/out/src/storage/schema/entities/EntityProvenTx.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTx.js +22 -23
- package/out/src/storage/schema/entities/EntityProvenTx.js.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTxReq.d.ts +9 -0
- package/out/src/storage/schema/entities/EntityProvenTxReq.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTxReq.js +116 -68
- 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 +19 -18
- 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 +25 -26
- 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 +6 -6
- package/out/src/storage/schema/entities/MergeEntity.js.map +1 -1
- 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/storageProviderHelpers.d.ts +34 -0
- package/out/src/storage/storageProviderHelpers.d.ts.map +1 -0
- package/out/src/storage/storageProviderHelpers.js +100 -0
- package/out/src/storage/storageProviderHelpers.js.map +1 -0
- package/out/src/utility/ScriptTemplateBRC29.d.ts.map +1 -1
- package/out/src/utility/ScriptTemplateBRC29.js +4 -2
- package/out/src/utility/ScriptTemplateBRC29.js.map +1 -1
- 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/brc114ActionTimeLabels.d.ts +2 -2
- package/out/src/utility/brc114ActionTimeLabels.d.ts.map +1 -1
- package/out/src/utility/brc114ActionTimeLabels.js +17 -10
- package/out/src/utility/brc114ActionTimeLabels.js.map +1 -1
- package/out/src/utility/identityUtils.d.ts.map +1 -1
- package/out/src/utility/identityUtils.js +6 -6
- package/out/src/utility/identityUtils.js.map +1 -1
- package/out/src/utility/index.client.d.ts +1 -0
- package/out/src/utility/index.client.d.ts.map +1 -1
- package/out/src/utility/index.client.js +1 -0
- package/out/src/utility/index.client.js.map +1 -1
- package/out/src/utility/parseTxScriptOffsets.d.ts +4 -4
- package/out/src/utility/parseTxScriptOffsets.d.ts.map +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 +6 -4
- package/out/src/utility/stampLog.js.map +1 -1
- package/out/src/utility/tscProofToMerklePath.d.ts.map +1 -1
- package/out/src/utility/tscProofToMerklePath.js +1 -1
- package/out/src/utility/tscProofToMerklePath.js.map +1 -1
- package/out/src/utility/utilityHelpers.d.ts +1 -2
- package/out/src/utility/utilityHelpers.d.ts.map +1 -1
- package/out/src/utility/utilityHelpers.js +12 -12
- 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 +3 -3
- package/out/src/utility/utilityHelpers.noBuffer.js.map +1 -1
- package/out/src/wab-client/WABClient.d.ts +3 -3
- package/out/src/wab-client/WABClient.d.ts.map +1 -1
- package/out/src/wab-client/WABClient.js +12 -12
- package/out/src/wab-client/WABClient.js.map +1 -1
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts.map +1 -1
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js +3 -3
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js.map +1 -1
- package/out/tsconfig.client.tsbuildinfo +1 -1
- package/package.json +7 -6
|
@@ -3,9 +3,9 @@ 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
|
+
/// /// TODO: ADD SUPPORT FOR ADMIN COUNTERPARTIES BASED ON WALLET STORAGE
|
|
7
|
+
/// /// PROHIBITION OF SPECIAL OPERATIONS IS ALSO CRITICAL.
|
|
8
|
+
/// /// !!!!!!!! SECURITY-CRITICAL ADDITION — DO NOT USE UNTIL IMPLEMENTED.
|
|
9
9
|
function deepEqual(object1, object2) {
|
|
10
10
|
if (object1 === null || object1 === undefined || object2 === null || object2 === undefined) {
|
|
11
11
|
return object1 === object2;
|
|
@@ -149,7 +149,7 @@ class WalletPermissionsManager {
|
|
|
149
149
|
}
|
|
150
150
|
const schemeID = basketOrProtocolName.split(' ')[1];
|
|
151
151
|
const module = (_a = this.config.permissionModules) === null || _a === void 0 ? void 0 : _a[schemeID];
|
|
152
|
-
if (
|
|
152
|
+
if (module == null) {
|
|
153
153
|
throw new Error(`Unsupported P-module scheme: p ${schemeID}`);
|
|
154
154
|
}
|
|
155
155
|
// Transform request with module
|
|
@@ -174,7 +174,7 @@ class WalletPermissionsManager {
|
|
|
174
174
|
if (pModulesByScheme.has(schemeID))
|
|
175
175
|
return;
|
|
176
176
|
const module = (_a = this.config.permissionModules) === null || _a === void 0 ? void 0 : _a[schemeID];
|
|
177
|
-
if (
|
|
177
|
+
if (module == null) {
|
|
178
178
|
throw new Error(`Unsupported P-${kind} scheme: p ${schemeID}`);
|
|
179
179
|
}
|
|
180
180
|
pModulesByScheme.set(schemeID, module);
|
|
@@ -198,7 +198,7 @@ class WalletPermissionsManager {
|
|
|
198
198
|
*/
|
|
199
199
|
splitLabelsByPermissionModule(labels, pModulesByScheme) {
|
|
200
200
|
const nonPLabels = [];
|
|
201
|
-
if (
|
|
201
|
+
if (labels == null)
|
|
202
202
|
return nonPLabels;
|
|
203
203
|
for (const label of labels) {
|
|
204
204
|
if (label.startsWith('p ')) {
|
|
@@ -233,9 +233,9 @@ class WalletPermissionsManager {
|
|
|
233
233
|
*/
|
|
234
234
|
async decryptListOutputsMetadata(results) {
|
|
235
235
|
if (results.outputs) {
|
|
236
|
-
for (
|
|
237
|
-
if (
|
|
238
|
-
|
|
236
|
+
for (const output of results.outputs) {
|
|
237
|
+
if (output.customInstructions) {
|
|
238
|
+
output.customInstructions = await this.maybeDecryptMetadata(output.customInstructions);
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
}
|
|
@@ -246,31 +246,37 @@ class WalletPermissionsManager {
|
|
|
246
246
|
*/
|
|
247
247
|
async decryptListActionsMetadata(results) {
|
|
248
248
|
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
|
-
}
|
|
249
|
+
for (const action of results.actions) {
|
|
250
|
+
await this.decryptSingleActionMetadata(action);
|
|
270
251
|
}
|
|
271
252
|
}
|
|
272
253
|
return results;
|
|
273
254
|
}
|
|
255
|
+
async decryptSingleActionMetadata(action) {
|
|
256
|
+
if (action.description) {
|
|
257
|
+
action.description = await this.maybeDecryptMetadata(action.description);
|
|
258
|
+
}
|
|
259
|
+
if (action.inputs != null) {
|
|
260
|
+
for (const input of action.inputs) {
|
|
261
|
+
if (input.inputDescription) {
|
|
262
|
+
input.inputDescription = await this.maybeDecryptMetadata(input.inputDescription);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (action.outputs != null) {
|
|
267
|
+
for (const output of action.outputs) {
|
|
268
|
+
await this.decryptActionOutputMetadata(output);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async decryptActionOutputMetadata(output) {
|
|
273
|
+
if (output.outputDescription) {
|
|
274
|
+
output.outputDescription = await this.maybeDecryptMetadata(output.outputDescription);
|
|
275
|
+
}
|
|
276
|
+
if (output.customInstructions) {
|
|
277
|
+
output.customInstructions = await this.maybeDecryptMetadata(output.customInstructions);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
274
280
|
/* ---------------------------------------------------------------------
|
|
275
281
|
* 1) PUBLIC API FOR REGISTERING CALLBACKS (UI PROMPTS, LOGGING, ETC.)
|
|
276
282
|
* --------------------------------------------------------------------- */
|
|
@@ -295,7 +301,7 @@ class WalletPermissionsManager {
|
|
|
295
301
|
* @returns True if successfully unbound, false otherwise
|
|
296
302
|
*/
|
|
297
303
|
unbindCallback(eventName, reference) {
|
|
298
|
-
if (
|
|
304
|
+
if (this.callbacks[eventName] == null)
|
|
299
305
|
return false;
|
|
300
306
|
const arr = this.callbacks[eventName];
|
|
301
307
|
if (typeof reference === 'number') {
|
|
@@ -329,8 +335,9 @@ class WalletPermissionsManager {
|
|
|
329
335
|
try {
|
|
330
336
|
await cb(param);
|
|
331
337
|
}
|
|
332
|
-
catch (
|
|
333
|
-
// Intentionally swallow errors from user-provided callbacks
|
|
338
|
+
catch (_callbackError) {
|
|
339
|
+
// Intentionally swallow errors from user-provided callbacks to prevent
|
|
340
|
+
// a misbehaving callback from disrupting the event dispatch loop.
|
|
334
341
|
}
|
|
335
342
|
}
|
|
336
343
|
}
|
|
@@ -350,7 +357,7 @@ class WalletPermissionsManager {
|
|
|
350
357
|
async grantPermission(params) {
|
|
351
358
|
// 1) Identify the matching queued requests in `activeRequests`
|
|
352
359
|
const matching = this.activeRequests.get(params.requestID);
|
|
353
|
-
if (
|
|
360
|
+
if (matching == null) {
|
|
354
361
|
throw new Error('Request ID not found.');
|
|
355
362
|
}
|
|
356
363
|
// 2) Mark all matching requests as resolved, deleting the entry
|
|
@@ -361,14 +368,14 @@ class WalletPermissionsManager {
|
|
|
361
368
|
// 3) If `ephemeral !== true`, we create or renew an on-chain token
|
|
362
369
|
if (!params.ephemeral) {
|
|
363
370
|
const request = matching.request;
|
|
364
|
-
if (
|
|
365
|
-
//
|
|
366
|
-
await this.
|
|
371
|
+
if (request.renewal) {
|
|
372
|
+
// renewal => spend the old token, produce a new one
|
|
373
|
+
await this.renewPermissionOnChain(request.previousToken, request, params.expiry || 0, // default: never expires
|
|
367
374
|
params.amount);
|
|
368
375
|
}
|
|
369
376
|
else {
|
|
370
|
-
//
|
|
371
|
-
await this.
|
|
377
|
+
// brand-new permission token
|
|
378
|
+
await this.createPermissionOnChain(request, params.expiry || 0, // default: never expires
|
|
372
379
|
params.amount);
|
|
373
380
|
}
|
|
374
381
|
}
|
|
@@ -390,7 +397,7 @@ class WalletPermissionsManager {
|
|
|
390
397
|
async denyPermission(requestID) {
|
|
391
398
|
// 1) Identify the matching requests
|
|
392
399
|
const matching = this.activeRequests.get(requestID);
|
|
393
|
-
if (
|
|
400
|
+
if (matching == null) {
|
|
394
401
|
throw new Error('Request ID not found.');
|
|
395
402
|
}
|
|
396
403
|
// 2) Reject all matching requests, deleting the entry
|
|
@@ -406,33 +413,19 @@ class WalletPermissionsManager {
|
|
|
406
413
|
* @param params.expiry An optional expiry time (in seconds) for the new permission tokens.
|
|
407
414
|
*/
|
|
408
415
|
async grantGroupedPermission(params) {
|
|
409
|
-
var _a, _b, _c;
|
|
410
416
|
const matching = this.activeRequests.get(params.requestID);
|
|
411
|
-
if (
|
|
417
|
+
if (matching == null) {
|
|
412
418
|
throw new Error('Request ID not found.');
|
|
413
419
|
}
|
|
414
420
|
try {
|
|
415
421
|
const originalRequest = matching.request;
|
|
416
422
|
const { originator, permissions: requestedPermissions, displayOriginator } = originalRequest;
|
|
417
423
|
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 ---
|
|
424
|
+
this.validateGrantedPermissionsSubset(params.granted, requestedPermissions);
|
|
432
425
|
const expiry = params.expiry || 0; // default: never expires
|
|
433
426
|
const toCreate = [];
|
|
434
427
|
const toRenew = [];
|
|
435
|
-
if (params.granted.spendingAuthorization) {
|
|
428
|
+
if (params.granted.spendingAuthorization != null) {
|
|
436
429
|
toCreate.push({
|
|
437
430
|
request: {
|
|
438
431
|
type: 'spending',
|
|
@@ -460,11 +453,11 @@ class WalletPermissionsManager {
|
|
|
460
453
|
counterparty,
|
|
461
454
|
reason: p.description
|
|
462
455
|
};
|
|
463
|
-
if (token) {
|
|
464
|
-
|
|
456
|
+
if (token == null) {
|
|
457
|
+
toCreate.push({ request, expiry });
|
|
465
458
|
}
|
|
466
459
|
else {
|
|
467
|
-
|
|
460
|
+
toRenew.push({ oldToken: token, request, expiry });
|
|
468
461
|
}
|
|
469
462
|
}
|
|
470
463
|
for (const b of params.granted.basketAccess || []) {
|
|
@@ -515,9 +508,28 @@ class WalletPermissionsManager {
|
|
|
515
508
|
* Denies a previously requested grouped permission.
|
|
516
509
|
* @param requestID The ID of the request being denied.
|
|
517
510
|
*/
|
|
518
|
-
|
|
511
|
+
/**
|
|
512
|
+
* Validates that every entry in `granted` was part of the original `requested` set.
|
|
513
|
+
* Throws an error on the first mismatch.
|
|
514
|
+
*/
|
|
515
|
+
validateGrantedPermissionsSubset(granted, requested) {
|
|
516
|
+
var _a, _b, _c;
|
|
517
|
+
if ((granted.spendingAuthorization != null) && (requested.spendingAuthorization == null)) {
|
|
518
|
+
throw new Error('Granted spending authorization was not part of the original request.');
|
|
519
|
+
}
|
|
520
|
+
if ((_a = granted.protocolPermissions) === null || _a === void 0 ? void 0 : _a.some(g => { var _a; return ((_a = requested.protocolPermissions) === null || _a === void 0 ? void 0 : _a.find(r => deepEqual(r, g))) == null; })) {
|
|
521
|
+
throw new Error('Granted protocol permissions are not a subset of the original request.');
|
|
522
|
+
}
|
|
523
|
+
if ((_b = granted.basketAccess) === null || _b === void 0 ? void 0 : _b.some(g => { var _a; return ((_a = requested.basketAccess) === null || _a === void 0 ? void 0 : _a.find(r => deepEqual(r, g))) == null; })) {
|
|
524
|
+
throw new Error('Granted basket access permissions are not a subset of the original request.');
|
|
525
|
+
}
|
|
526
|
+
if ((_c = granted.certificateAccess) === null || _c === void 0 ? void 0 : _c.some(g => { var _a; return ((_a = requested.certificateAccess) === null || _a === void 0 ? void 0 : _a.find(r => deepEqual(r, g))) == null; })) {
|
|
527
|
+
throw new Error('Granted certificate access permissions are not a subset of the original request.');
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
denyActiveRequest(requestID) {
|
|
519
531
|
const matching = this.activeRequests.get(requestID);
|
|
520
|
-
if (
|
|
532
|
+
if (matching == null) {
|
|
521
533
|
throw new Error('Request ID not found.');
|
|
522
534
|
}
|
|
523
535
|
const err = new Error('The user has denied the request for permission.');
|
|
@@ -527,9 +539,12 @@ class WalletPermissionsManager {
|
|
|
527
539
|
}
|
|
528
540
|
this.activeRequests.delete(requestID);
|
|
529
541
|
}
|
|
542
|
+
async denyGroupedPermission(requestID) {
|
|
543
|
+
this.denyActiveRequest(requestID);
|
|
544
|
+
}
|
|
530
545
|
async dismissGroupedPermission(requestID) {
|
|
531
546
|
const matching = this.activeRequests.get(requestID);
|
|
532
|
-
if (
|
|
547
|
+
if (matching == null) {
|
|
533
548
|
throw new Error('Request ID not found.');
|
|
534
549
|
}
|
|
535
550
|
for (const p of matching.pending) {
|
|
@@ -540,7 +555,7 @@ class WalletPermissionsManager {
|
|
|
540
555
|
async grantCounterpartyPermission(params) {
|
|
541
556
|
var _a;
|
|
542
557
|
const matching = this.activeRequests.get(params.requestID);
|
|
543
|
-
if (
|
|
558
|
+
if (matching == null) {
|
|
544
559
|
throw new Error('Request ID not found.');
|
|
545
560
|
}
|
|
546
561
|
const originalRequest = matching.request;
|
|
@@ -585,11 +600,11 @@ class WalletPermissionsManager {
|
|
|
585
600
|
counterparty,
|
|
586
601
|
reason: p.description
|
|
587
602
|
};
|
|
588
|
-
if (token) {
|
|
589
|
-
|
|
603
|
+
if (token == null) {
|
|
604
|
+
toCreate.push({ request, expiry });
|
|
590
605
|
}
|
|
591
606
|
else {
|
|
592
|
-
|
|
607
|
+
toRenew.push({ oldToken: token, request, expiry });
|
|
593
608
|
}
|
|
594
609
|
}
|
|
595
610
|
const created = await this.createPermissionTokensBestEffort(toCreate);
|
|
@@ -603,16 +618,7 @@ class WalletPermissionsManager {
|
|
|
603
618
|
this.activeRequests.delete(params.requestID);
|
|
604
619
|
}
|
|
605
620
|
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);
|
|
621
|
+
this.denyActiveRequest(requestID);
|
|
616
622
|
}
|
|
617
623
|
/* ---------------------------------------------------------------------
|
|
618
624
|
* 3) THE "ENSURE" METHODS: CHECK IF PERMISSION EXISTS, OTHERWISE PROMPT
|
|
@@ -627,99 +633,49 @@ class WalletPermissionsManager {
|
|
|
627
633
|
// 1) adminOriginator can do anything
|
|
628
634
|
if (this.isAdminOriginator(originator))
|
|
629
635
|
return true;
|
|
630
|
-
// 2) If security level=0, we consider it
|
|
636
|
+
// 2) If security level=0, we consider it “open” usage
|
|
631
637
|
const [level, protoName] = protocolID;
|
|
632
638
|
if (level === 0)
|
|
633
639
|
return true;
|
|
634
|
-
if (level === 1)
|
|
640
|
+
if (level === 1)
|
|
635
641
|
counterparty = '';
|
|
636
|
-
}
|
|
637
642
|
// 3) If protocol is admin-reserved, block
|
|
638
643
|
if (this.isAdminProtocol(protocolID)) {
|
|
639
644
|
throw new Error(`Protocol “${protoName}” is admin-only.`);
|
|
640
645
|
}
|
|
641
646
|
// 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) {
|
|
649
|
-
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) {
|
|
647
|
+
if (this.isProtocolUsageTypeExempted(usageType))
|
|
658
648
|
return true;
|
|
659
|
-
|
|
660
|
-
if (!this.config.differentiatePrivilegedOperations) {
|
|
649
|
+
if (!this.config.differentiatePrivilegedOperations)
|
|
661
650
|
privileged = false;
|
|
662
|
-
|
|
663
|
-
if (!privileged && this.isWhitelistedCounterpartyProtocol(counterparty, protocolID)) {
|
|
651
|
+
if (!privileged && this.isWhitelistedCounterpartyProtocol(counterparty, protocolID))
|
|
664
652
|
return true;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
type: 'protocol',
|
|
668
|
-
originator,
|
|
669
|
-
privileged,
|
|
670
|
-
protocolID,
|
|
671
|
-
counterparty
|
|
672
|
-
});
|
|
673
|
-
if (this.isPermissionCached(cacheKey)) {
|
|
653
|
+
const cacheKey = this.buildRequestKey({ type: 'protocol', originator, privileged, protocolID, counterparty });
|
|
654
|
+
if (this.isPermissionCached(cacheKey) || this.isRecentlyGranted(cacheKey))
|
|
674
655
|
return true;
|
|
675
|
-
}
|
|
676
|
-
if (this.isRecentlyGranted(cacheKey)) {
|
|
677
|
-
return true;
|
|
678
|
-
}
|
|
679
656
|
// 4) Attempt to find a valid token in the internal basket
|
|
680
|
-
const token = await this.findProtocolToken(originator, privileged, protocolID, counterparty,
|
|
681
|
-
|
|
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 {
|
|
657
|
+
const token = await this.findProtocolToken(originator, privileged, protocolID, counterparty, /* includeExpired= */ true, lookupValues);
|
|
658
|
+
if (token == null) {
|
|
707
659
|
// No token found => request a new one if allowed
|
|
660
|
+
if (!seekPermission)
|
|
661
|
+
throw new Error('No protocol permission token found (seekPermission=false).');
|
|
662
|
+
return await this.requestPermissionFlow({
|
|
663
|
+
type: 'protocol', originator, privileged, protocolID, counterparty, usageType, reason, renewal: false
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
if (this.isTokenExpired(token.expiry)) {
|
|
667
|
+
// has a token but expired => request renewal if allowed
|
|
708
668
|
if (!seekPermission) {
|
|
709
|
-
throw new Error(
|
|
669
|
+
throw new Error('Protocol permission expired and no further user consent allowed (seekPermission=false).');
|
|
710
670
|
}
|
|
711
|
-
|
|
712
|
-
type: 'protocol',
|
|
713
|
-
|
|
714
|
-
privileged,
|
|
715
|
-
protocolID,
|
|
716
|
-
counterparty,
|
|
717
|
-
usageType,
|
|
718
|
-
reason,
|
|
719
|
-
renewal: false
|
|
671
|
+
return await this.requestPermissionFlow({
|
|
672
|
+
type: 'protocol', originator, privileged, protocolID, counterparty, usageType, reason,
|
|
673
|
+
renewal: true, previousToken: token
|
|
720
674
|
});
|
|
721
|
-
return granted;
|
|
722
675
|
}
|
|
676
|
+
// valid and unexpired
|
|
677
|
+
this.cachePermission(cacheKey, token.expiry);
|
|
678
|
+
return true;
|
|
723
679
|
}
|
|
724
680
|
/**
|
|
725
681
|
* Ensures the originator has basket usage permission for the specified basket.
|
|
@@ -730,58 +686,38 @@ class WalletPermissionsManager {
|
|
|
730
686
|
originator = normalizedOriginator;
|
|
731
687
|
if (this.isAdminOriginator(originator))
|
|
732
688
|
return true;
|
|
733
|
-
if (this.isAdminBasket(basket))
|
|
689
|
+
if (this.isAdminBasket(basket))
|
|
734
690
|
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)
|
|
691
|
+
if (!this.isBasketUsageRequired(usageType))
|
|
741
692
|
return true;
|
|
742
693
|
const cacheKey = this.buildRequestKey({ type: 'basket', originator, basket });
|
|
743
|
-
if (this.isPermissionCached(cacheKey))
|
|
744
|
-
return true;
|
|
745
|
-
}
|
|
746
|
-
if (this.isRecentlyGranted(cacheKey)) {
|
|
694
|
+
if (this.isPermissionCached(cacheKey) || this.isRecentlyGranted(cacheKey))
|
|
747
695
|
return true;
|
|
748
|
-
}
|
|
749
696
|
const token = await this.findBasketToken(originator, basket, true, lookupValues);
|
|
750
|
-
if (token) {
|
|
751
|
-
if (!
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
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({
|
|
776
|
-
type: 'basket',
|
|
777
|
-
originator,
|
|
778
|
-
basket,
|
|
779
|
-
usageType,
|
|
780
|
-
reason,
|
|
781
|
-
renewal: false
|
|
697
|
+
if (token == null) {
|
|
698
|
+
if (!seekPermission)
|
|
699
|
+
throw new Error('No basket permission found, and no user consent allowed (seekPermission=false).');
|
|
700
|
+
return await this.requestPermissionFlow({ type: 'basket', originator, basket, usageType, reason, renewal: false });
|
|
701
|
+
}
|
|
702
|
+
if (this.isTokenExpired(token.expiry)) {
|
|
703
|
+
if (!seekPermission)
|
|
704
|
+
throw new Error('Basket permission expired (seekPermission=false).');
|
|
705
|
+
return await this.requestPermissionFlow({
|
|
706
|
+
type: 'basket', originator, basket, usageType, reason, renewal: true, previousToken: token
|
|
782
707
|
});
|
|
783
|
-
return granted;
|
|
784
708
|
}
|
|
709
|
+
this.cachePermission(cacheKey, token.expiry);
|
|
710
|
+
return true;
|
|
711
|
+
}
|
|
712
|
+
/** Returns false when the basket usageType does NOT need a permission check (config-gated). */
|
|
713
|
+
isBasketUsageRequired(usageType) {
|
|
714
|
+
if (usageType === 'insertion' && !this.config.seekBasketInsertionPermissions)
|
|
715
|
+
return false;
|
|
716
|
+
if (usageType === 'removal' && !this.config.seekBasketRemovalPermissions)
|
|
717
|
+
return false;
|
|
718
|
+
if (usageType === 'listing' && !this.config.seekBasketListingPermissions)
|
|
719
|
+
return false;
|
|
720
|
+
return true;
|
|
785
721
|
}
|
|
786
722
|
/**
|
|
787
723
|
* Ensures the originator has a valid certificate permission.
|
|
@@ -811,43 +747,38 @@ class WalletPermissionsManager {
|
|
|
811
747
|
return true;
|
|
812
748
|
}
|
|
813
749
|
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
|
-
});
|
|
750
|
+
/* includeExpired= */ true, lookupValues);
|
|
751
|
+
if (token == null) {
|
|
752
|
+
if (!seekPermission) {
|
|
753
|
+
throw new Error('No certificate permission found (seekPermission=false).');
|
|
834
754
|
}
|
|
755
|
+
return await this.requestPermissionFlow({
|
|
756
|
+
type: 'certificate',
|
|
757
|
+
originator,
|
|
758
|
+
privileged,
|
|
759
|
+
certificate: { verifier, certType, fields },
|
|
760
|
+
usageType,
|
|
761
|
+
reason,
|
|
762
|
+
renewal: false
|
|
763
|
+
});
|
|
835
764
|
}
|
|
836
|
-
|
|
765
|
+
if (this.isTokenExpired(token.expiry)) {
|
|
837
766
|
if (!seekPermission) {
|
|
838
|
-
throw new Error(
|
|
767
|
+
throw new Error('Certificate permission expired (seekPermission=false).');
|
|
839
768
|
}
|
|
840
|
-
|
|
769
|
+
return await this.requestPermissionFlow({
|
|
841
770
|
type: 'certificate',
|
|
842
771
|
originator,
|
|
843
772
|
privileged,
|
|
844
773
|
certificate: { verifier, certType, fields },
|
|
845
774
|
usageType,
|
|
846
775
|
reason,
|
|
847
|
-
renewal:
|
|
776
|
+
renewal: true,
|
|
777
|
+
previousToken: token
|
|
848
778
|
});
|
|
849
|
-
return granted;
|
|
850
779
|
}
|
|
780
|
+
this.cachePermission(cacheKey, token.expiry);
|
|
781
|
+
return true;
|
|
851
782
|
}
|
|
852
783
|
/**
|
|
853
784
|
* Ensures the originator has spending authorization (DSAP) for a certain satoshi amount.
|
|
@@ -892,7 +823,7 @@ class WalletPermissionsManager {
|
|
|
892
823
|
else {
|
|
893
824
|
// no token
|
|
894
825
|
if (!seekPermission) {
|
|
895
|
-
throw new Error(
|
|
826
|
+
throw new Error('No spending authorization found, (seekPermission=false).');
|
|
896
827
|
}
|
|
897
828
|
return await this.requestPermissionFlow({
|
|
898
829
|
type: 'spending',
|
|
@@ -944,9 +875,27 @@ class WalletPermissionsManager {
|
|
|
944
875
|
usageType: 'generic'
|
|
945
876
|
});
|
|
946
877
|
}
|
|
878
|
+
/**
|
|
879
|
+
* Returns true when the given usageType is configured to skip permission checks.
|
|
880
|
+
*/
|
|
881
|
+
isProtocolUsageTypeExempted(usageType) {
|
|
882
|
+
if (usageType === 'signing' && !this.config.seekProtocolPermissionsForSigning)
|
|
883
|
+
return true;
|
|
884
|
+
if (usageType === 'encrypting' && !this.config.seekProtocolPermissionsForEncrypting)
|
|
885
|
+
return true;
|
|
886
|
+
if (usageType === 'hmac' && !this.config.seekProtocolPermissionsForHMAC)
|
|
887
|
+
return true;
|
|
888
|
+
if (usageType === 'publicKey' && !this.config.seekPermissionsForPublicKeyRevelation)
|
|
889
|
+
return true;
|
|
890
|
+
if (usageType === 'identityKey' && !this.config.seekPermissionsForIdentityKeyRevelation)
|
|
891
|
+
return true;
|
|
892
|
+
if (usageType === 'linkageRevelation' && !this.config.seekPermissionsForKeyLinkageRevelation)
|
|
893
|
+
return true;
|
|
894
|
+
return false;
|
|
895
|
+
}
|
|
947
896
|
isProtocolInCounterpartyPermissions(protocolID, counterpartyPermissions) {
|
|
948
897
|
const [, name] = protocolID;
|
|
949
|
-
return
|
|
898
|
+
return counterpartyPermissions.protocols.some(p => p.protocolName === name);
|
|
950
899
|
}
|
|
951
900
|
validateCounterpartyPermissions(raw) {
|
|
952
901
|
if (!raw || !Array.isArray(raw.protocols) || raw.protocols.length === 0)
|
|
@@ -998,15 +947,15 @@ class WalletPermissionsManager {
|
|
|
998
947
|
}
|
|
999
948
|
async fetchManifestPermissions(originator) {
|
|
1000
949
|
const cached = this.manifestCache.get(originator);
|
|
1001
|
-
if (cached && Date.now() - cached.fetchedAt < WalletPermissionsManager.MANIFEST_CACHE_TTL_MS) {
|
|
950
|
+
if ((cached != null) && Date.now() - cached.fetchedAt < WalletPermissionsManager.MANIFEST_CACHE_TTL_MS) {
|
|
1002
951
|
return {
|
|
1003
952
|
groupPermissions: cached.groupPermissions,
|
|
1004
953
|
counterpartyPermissions: cached.counterpartyPermissions
|
|
1005
954
|
};
|
|
1006
955
|
}
|
|
1007
956
|
const inProgress = this.manifestFetchInProgress.get(originator);
|
|
1008
|
-
if (inProgress) {
|
|
1009
|
-
return inProgress;
|
|
957
|
+
if (inProgress != null) {
|
|
958
|
+
return await inProgress;
|
|
1010
959
|
}
|
|
1011
960
|
const fetchPromise = (async () => {
|
|
1012
961
|
try {
|
|
@@ -1025,7 +974,9 @@ class WalletPermissionsManager {
|
|
|
1025
974
|
return { groupPermissions, counterpartyPermissions: counterpartyPermissionsDeclared };
|
|
1026
975
|
}
|
|
1027
976
|
}
|
|
1028
|
-
catch (
|
|
977
|
+
catch (_manifestFetchError) {
|
|
978
|
+
// Manifest fetch or parse failed — fall through to return null/null defaults below
|
|
979
|
+
}
|
|
1029
980
|
const result = { groupPermissions: null, counterpartyPermissions: null };
|
|
1030
981
|
this.manifestCache.set(originator, { ...result, fetchedAt: Date.now() });
|
|
1031
982
|
return result;
|
|
@@ -1051,7 +1002,7 @@ class WalletPermissionsManager {
|
|
|
1051
1002
|
};
|
|
1052
1003
|
const [spendingAuthorization, protocolPermissions, basketAccess, certificateAccess] = await Promise.all([
|
|
1053
1004
|
(async () => {
|
|
1054
|
-
if (
|
|
1005
|
+
if (groupPermissions.spendingAuthorization == null)
|
|
1055
1006
|
return undefined;
|
|
1056
1007
|
const hasAuth = await this.hasSpendingAuthorization({
|
|
1057
1008
|
originator,
|
|
@@ -1102,7 +1053,7 @@ class WalletPermissionsManager {
|
|
|
1102
1053
|
return certChecks.filter(Boolean);
|
|
1103
1054
|
})()
|
|
1104
1055
|
]);
|
|
1105
|
-
if (spendingAuthorization) {
|
|
1056
|
+
if (spendingAuthorization != null) {
|
|
1106
1057
|
permissionsToRequest.spendingAuthorization = spendingAuthorization;
|
|
1107
1058
|
}
|
|
1108
1059
|
permissionsToRequest.protocolPermissions = protocolPermissions;
|
|
@@ -1210,27 +1161,22 @@ class WalletPermissionsManager {
|
|
|
1210
1161
|
protocols: protocolsToRequest
|
|
1211
1162
|
};
|
|
1212
1163
|
const key = `pact:${originator}:${counterparty}`;
|
|
1164
|
+
await this.joinOrCreatePactRequest(key, originator, counterparty, permissionsToRequest, currentRequest.displayOriginator);
|
|
1165
|
+
this.markPactEstablished(originator, counterparty);
|
|
1166
|
+
const satisfied = await this.hasProtocolPermission({
|
|
1167
|
+
originator,
|
|
1168
|
+
privileged: false,
|
|
1169
|
+
protocolID: currentRequest.protocolID,
|
|
1170
|
+
counterparty
|
|
1171
|
+
});
|
|
1172
|
+
return satisfied ? true : null;
|
|
1173
|
+
}
|
|
1174
|
+
async joinOrCreatePactRequest(key, originator, counterparty, permissionsToRequest, displayOriginator) {
|
|
1213
1175
|
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 {
|
|
1176
|
+
if (existing == null) {
|
|
1226
1177
|
const counterpartyPromise = new Promise((resolve, reject) => {
|
|
1227
1178
|
this.activeRequests.set(key, {
|
|
1228
|
-
request: {
|
|
1229
|
-
originator,
|
|
1230
|
-
counterparty,
|
|
1231
|
-
permissions: permissionsToRequest,
|
|
1232
|
-
displayOriginator: currentRequest.displayOriginator
|
|
1233
|
-
},
|
|
1179
|
+
request: { originator, counterparty, permissions: permissionsToRequest, displayOriginator },
|
|
1234
1180
|
pending: [{ resolve, reject }]
|
|
1235
1181
|
});
|
|
1236
1182
|
});
|
|
@@ -1242,14 +1188,17 @@ class WalletPermissionsManager {
|
|
|
1242
1188
|
});
|
|
1243
1189
|
await counterpartyPromise;
|
|
1244
1190
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1191
|
+
else {
|
|
1192
|
+
const existingRequest = existing.request;
|
|
1193
|
+
for (const p of permissionsToRequest.protocols) {
|
|
1194
|
+
if (!existingRequest.permissions.protocols.some(x => x.protocolName === p.protocolName)) {
|
|
1195
|
+
existingRequest.permissions.protocols.push(p);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
await new Promise((resolve, reject) => {
|
|
1199
|
+
existing.pending.push({ resolve, reject });
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1253
1202
|
}
|
|
1254
1203
|
async maybeRequestPeerGroupedLevel2ProtocolPermissions(currentRequest) {
|
|
1255
1204
|
var _a, _b;
|
|
@@ -1270,7 +1219,7 @@ class WalletPermissionsManager {
|
|
|
1270
1219
|
const privileged = (_a = currentRequest.privileged) !== null && _a !== void 0 ? _a : false;
|
|
1271
1220
|
const counterparty = (_b = currentRequest.counterparty) !== null && _b !== void 0 ? _b : 'self';
|
|
1272
1221
|
const groupPermissions = await this.fetchManifestGroupPermissions(originator);
|
|
1273
|
-
if (
|
|
1222
|
+
if (groupPermissions == null) {
|
|
1274
1223
|
return null;
|
|
1275
1224
|
}
|
|
1276
1225
|
const normalizeManifestCounterparty = (cp) => {
|
|
@@ -1316,40 +1265,7 @@ class WalletPermissionsManager {
|
|
|
1316
1265
|
return null;
|
|
1317
1266
|
}
|
|
1318
1267
|
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
|
-
}
|
|
1268
|
+
await this.joinOrCreateGroupedRequest(key, originator, permissionsToRequest, currentRequest.displayOriginator);
|
|
1353
1269
|
const satisfied = await this.checkSpecificPermissionAfterGroupFlow(currentRequest);
|
|
1354
1270
|
return satisfied ? true : null;
|
|
1355
1271
|
}
|
|
@@ -1360,7 +1276,7 @@ class WalletPermissionsManager {
|
|
|
1360
1276
|
const gate = new Promise(resolve => {
|
|
1361
1277
|
release = resolve;
|
|
1362
1278
|
});
|
|
1363
|
-
const currentTail = safePriorTail.then(() => gate);
|
|
1279
|
+
const currentTail = safePriorTail.then(async () => await gate);
|
|
1364
1280
|
this.groupedPermissionFlowTail.set(originator, currentTail);
|
|
1365
1281
|
await safePriorTail;
|
|
1366
1282
|
try {
|
|
@@ -1414,7 +1330,7 @@ class WalletPermissionsManager {
|
|
|
1414
1330
|
if (request.privileged)
|
|
1415
1331
|
return false;
|
|
1416
1332
|
const pid = request.protocolID;
|
|
1417
|
-
if (
|
|
1333
|
+
if (pid == null)
|
|
1418
1334
|
return false;
|
|
1419
1335
|
const cp = (_a = request.counterparty) !== null && _a !== void 0 ? _a : 'self';
|
|
1420
1336
|
return !!((_b = groupPermissions.protocolPermissions) === null || _b === void 0 ? void 0 : _b.some(p => {
|
|
@@ -1439,7 +1355,7 @@ class WalletPermissionsManager {
|
|
|
1439
1355
|
if (request.privileged)
|
|
1440
1356
|
return false;
|
|
1441
1357
|
const cert = request.certificate;
|
|
1442
|
-
if (
|
|
1358
|
+
if (cert == null)
|
|
1443
1359
|
return false;
|
|
1444
1360
|
return !!((_d = groupPermissions.certificateAccess) === null || _d === void 0 ? void 0 : _d.some(c => {
|
|
1445
1361
|
const fieldsA = new Set(c.fields || []);
|
|
@@ -1453,7 +1369,7 @@ class WalletPermissionsManager {
|
|
|
1453
1369
|
}));
|
|
1454
1370
|
}
|
|
1455
1371
|
case 'spending':
|
|
1456
|
-
return
|
|
1372
|
+
return groupPermissions.spendingAuthorization != null;
|
|
1457
1373
|
default:
|
|
1458
1374
|
return false;
|
|
1459
1375
|
}
|
|
@@ -1464,7 +1380,7 @@ class WalletPermissionsManager {
|
|
|
1464
1380
|
}
|
|
1465
1381
|
const originator = currentRequest.originator;
|
|
1466
1382
|
const groupPermissions = await this.fetchManifestGroupPermissions(originator);
|
|
1467
|
-
if (
|
|
1383
|
+
if (groupPermissions == null) {
|
|
1468
1384
|
return null;
|
|
1469
1385
|
}
|
|
1470
1386
|
if (!this.isRequestIncludedInGroupPermissions(currentRequest, groupPermissions)) {
|
|
@@ -1475,19 +1391,22 @@ class WalletPermissionsManager {
|
|
|
1475
1391
|
return null;
|
|
1476
1392
|
}
|
|
1477
1393
|
const key = `group:${originator}`;
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1394
|
+
await this.joinOrCreateGroupedRequest(key, originator, permissionsToRequest, currentRequest.displayOriginator);
|
|
1395
|
+
const satisfied = await this.checkSpecificPermissionAfterGroupFlow(currentRequest);
|
|
1396
|
+
return satisfied ? true : null;
|
|
1397
|
+
}
|
|
1398
|
+
/**
|
|
1399
|
+
* Joins an existing grouped permission request (piggybacks on the existing promise), or creates
|
|
1400
|
+
* a new one and fires the onGroupedPermissionRequested event.
|
|
1401
|
+
*/
|
|
1402
|
+
async joinOrCreateGroupedRequest(key, originator, permissionsToRequest, displayOriginator) {
|
|
1403
|
+
var _a;
|
|
1404
|
+
var _b;
|
|
1405
|
+
const existing = this.activeRequests.get(key);
|
|
1406
|
+
if (existing == null) {
|
|
1484
1407
|
const permPromise = new Promise((resolve, reject) => {
|
|
1485
1408
|
this.activeRequests.set(key, {
|
|
1486
|
-
request: {
|
|
1487
|
-
originator,
|
|
1488
|
-
permissions: permissionsToRequest,
|
|
1489
|
-
displayOriginator: currentRequest.displayOriginator
|
|
1490
|
-
},
|
|
1409
|
+
request: { originator, permissions: permissionsToRequest, displayOriginator },
|
|
1491
1410
|
pending: [{ resolve, reject }]
|
|
1492
1411
|
});
|
|
1493
1412
|
});
|
|
@@ -1498,8 +1417,18 @@ class WalletPermissionsManager {
|
|
|
1498
1417
|
});
|
|
1499
1418
|
await permPromise;
|
|
1500
1419
|
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1420
|
+
else {
|
|
1421
|
+
const existingRequest = existing.request;
|
|
1422
|
+
(_a = (_b = existingRequest.permissions).protocolPermissions) !== null && _a !== void 0 ? _a : (_b.protocolPermissions = []);
|
|
1423
|
+
for (const p of permissionsToRequest.protocolPermissions || []) {
|
|
1424
|
+
if (!existingRequest.permissions.protocolPermissions.some(x => deepEqual(x, p))) {
|
|
1425
|
+
existingRequest.permissions.protocolPermissions.push(p);
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
await new Promise((resolve, reject) => {
|
|
1429
|
+
existing.pending.push({ resolve, reject });
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1503
1432
|
}
|
|
1504
1433
|
/**
|
|
1505
1434
|
* A central method that triggers the permission request flow.
|
|
@@ -1521,22 +1450,39 @@ class WalletPermissionsManager {
|
|
|
1521
1450
|
}
|
|
1522
1451
|
const key = this.buildActiveRequestKey(preparedRequest);
|
|
1523
1452
|
// 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
|
-
});
|
|
1453
|
+
if (this.isPiggybacking(key)) {
|
|
1454
|
+
return await this.piggybackOnExistingQueue(key);
|
|
1529
1455
|
}
|
|
1530
1456
|
const pactResult = await this.maybeRequestPact(preparedRequest);
|
|
1531
|
-
if (pactResult !== null)
|
|
1457
|
+
if (pactResult !== null)
|
|
1532
1458
|
return pactResult;
|
|
1533
|
-
}
|
|
1534
1459
|
const peerGroupResult = await this.maybeRequestPeerGroupedLevel2ProtocolPermissions(preparedRequest);
|
|
1535
|
-
if (peerGroupResult !== null)
|
|
1460
|
+
if (peerGroupResult !== null)
|
|
1536
1461
|
return peerGroupResult;
|
|
1537
|
-
|
|
1462
|
+
const groupResult = await this.resolveGroupedFlow(preparedRequest, key);
|
|
1463
|
+
if (groupResult !== null)
|
|
1464
|
+
return groupResult;
|
|
1465
|
+
// Re-check after grouped flow — another waiter may have set up a queue
|
|
1466
|
+
if (this.isPiggybacking(key))
|
|
1467
|
+
return await this.piggybackOnExistingQueue(key);
|
|
1468
|
+
return await this.enqueueAndFireEvent(preparedRequest, key);
|
|
1469
|
+
}
|
|
1470
|
+
/** Returns true when an active-request queue already has pending waiters for this key. */
|
|
1471
|
+
isPiggybacking(key) {
|
|
1472
|
+
const q = this.activeRequests.get(key);
|
|
1473
|
+
return (q != null) && q.pending.length > 0;
|
|
1474
|
+
}
|
|
1475
|
+
/** Appends to an existing request queue and waits for resolution. */
|
|
1476
|
+
async piggybackOnExistingQueue(key) {
|
|
1477
|
+
const q = this.activeRequests.get(key);
|
|
1478
|
+
return await new Promise((resolve, reject) => {
|
|
1479
|
+
q.pending.push({ resolve, reject });
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
/** Runs the grouped-permission flow (with or without a lock) and checks post-group satisfaction. */
|
|
1483
|
+
async resolveGroupedFlow(preparedRequest, key) {
|
|
1538
1484
|
const hadPendingGroupedFlowBefore = this.config.seekGroupedPermission && this.groupedPermissionFlowTail.has(preparedRequest.originator);
|
|
1539
|
-
let groupResult
|
|
1485
|
+
let groupResult;
|
|
1540
1486
|
if (this.config.seekGroupedPermission) {
|
|
1541
1487
|
groupResult = await this.withGroupedPermissionFlowLock(preparedRequest.originator, async () => {
|
|
1542
1488
|
return await this.maybeRequestGroupedPermissions(preparedRequest);
|
|
@@ -1545,67 +1491,54 @@ class WalletPermissionsManager {
|
|
|
1545
1491
|
else {
|
|
1546
1492
|
groupResult = await this.maybeRequestGroupedPermissions(preparedRequest);
|
|
1547
1493
|
}
|
|
1548
|
-
if (groupResult !== null)
|
|
1494
|
+
if (groupResult !== null)
|
|
1549
1495
|
return groupResult;
|
|
1550
|
-
|
|
1551
|
-
if (this.config.seekGroupedPermission && hadPendingGroupedFlowBefore) {
|
|
1496
|
+
if (hadPendingGroupedFlowBefore) {
|
|
1552
1497
|
const satisfiedAfterGroup = await this.checkSpecificPermissionAfterGroupFlow(preparedRequest);
|
|
1553
|
-
if (satisfiedAfterGroup)
|
|
1498
|
+
if (satisfiedAfterGroup)
|
|
1554
1499
|
return true;
|
|
1555
|
-
}
|
|
1556
1500
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1501
|
+
return null;
|
|
1502
|
+
}
|
|
1503
|
+
/** Creates a new active-request queue entry, fires the event, and returns the promise. */
|
|
1504
|
+
async enqueueAndFireEvent(preparedRequest, key) {
|
|
1505
|
+
const requestPromise = new Promise((resolve, reject) => {
|
|
1506
|
+
this.activeRequests.set(key, { request: preparedRequest, pending: [{ resolve, reject }] });
|
|
1507
|
+
});
|
|
1508
|
+
try {
|
|
1509
|
+
await this.firePermissionRequestEvent(preparedRequest, key);
|
|
1562
1510
|
}
|
|
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
|
-
}
|
|
1511
|
+
catch (e) {
|
|
1512
|
+
const matching = this.activeRequests.get(key);
|
|
1513
|
+
if (matching != null) {
|
|
1514
|
+
for (const p of matching.pending)
|
|
1515
|
+
p.reject(e);
|
|
1516
|
+
this.activeRequests.delete(key);
|
|
1607
1517
|
}
|
|
1608
|
-
}
|
|
1518
|
+
}
|
|
1519
|
+
return await requestPromise;
|
|
1520
|
+
}
|
|
1521
|
+
/** Fires the appropriate onXXXRequested event based on the request type. */
|
|
1522
|
+
async firePermissionRequestEvent(request, key) {
|
|
1523
|
+
var _a;
|
|
1524
|
+
switch (request.type) {
|
|
1525
|
+
case 'protocol':
|
|
1526
|
+
await this.callEvent('onProtocolPermissionRequested', {
|
|
1527
|
+
...request,
|
|
1528
|
+
counterparty: ((_a = request.protocolID) === null || _a === void 0 ? void 0 : _a[0]) === 1 ? undefined : request.counterparty,
|
|
1529
|
+
requestID: key
|
|
1530
|
+
});
|
|
1531
|
+
break;
|
|
1532
|
+
case 'basket':
|
|
1533
|
+
await this.callEvent('onBasketAccessRequested', { ...request, requestID: key });
|
|
1534
|
+
break;
|
|
1535
|
+
case 'certificate':
|
|
1536
|
+
await this.callEvent('onCertificateAccessRequested', { ...request, requestID: key });
|
|
1537
|
+
break;
|
|
1538
|
+
case 'spending':
|
|
1539
|
+
await this.callEvent('onSpendingAuthorizationRequested', { ...request, requestID: key });
|
|
1540
|
+
break;
|
|
1541
|
+
}
|
|
1609
1542
|
}
|
|
1610
1543
|
/** We always use `keyID="1"` and `counterparty="self"` for these encryption ops. */
|
|
1611
1544
|
async encryptPermissionTokenField(plaintext) {
|
|
@@ -1626,7 +1559,8 @@ class WalletPermissionsManager {
|
|
|
1626
1559
|
}, this.adminOriginator);
|
|
1627
1560
|
return plaintext;
|
|
1628
1561
|
}
|
|
1629
|
-
catch (
|
|
1562
|
+
catch (_decryptionError) {
|
|
1563
|
+
// Decryption failed (e.g. wrong key, unencrypted legacy value) — return the raw bytes unchanged
|
|
1630
1564
|
return ciphertext;
|
|
1631
1565
|
}
|
|
1632
1566
|
}
|
|
@@ -1660,7 +1594,8 @@ class WalletPermissionsManager {
|
|
|
1660
1594
|
}, this.adminOriginator);
|
|
1661
1595
|
return sdk_1.Utils.toUTF8(plaintext);
|
|
1662
1596
|
}
|
|
1663
|
-
catch (
|
|
1597
|
+
catch (_decryptionError) {
|
|
1598
|
+
// Decryption failed (e.g. wrong key, unencrypted legacy value) — return original string unchanged
|
|
1664
1599
|
return ciphertext;
|
|
1665
1600
|
}
|
|
1666
1601
|
}
|
|
@@ -1669,6 +1604,68 @@ class WalletPermissionsManager {
|
|
|
1669
1604
|
const now = Math.floor(Date.now() / 1000);
|
|
1670
1605
|
return expiry > 0 && expiry < now;
|
|
1671
1606
|
}
|
|
1607
|
+
/** Decrypts the standard 6 fields from a protocol (DPACP) PushDrop script. */
|
|
1608
|
+
async decryptProtocolTokenFields(fields) {
|
|
1609
|
+
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[0]));
|
|
1610
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[1])), 10);
|
|
1611
|
+
const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[2])) === 'true';
|
|
1612
|
+
const secLevelDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[3])), 10);
|
|
1613
|
+
const protoNameDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[4]));
|
|
1614
|
+
const cptyDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fields[5]));
|
|
1615
|
+
return { domainDecoded, expiryDecoded, privDecoded, secLevelDecoded, protoNameDecoded, cptyDecoded };
|
|
1616
|
+
}
|
|
1617
|
+
/** Parses outpoint string "txid.vout" into [txid, outputIndex]. */
|
|
1618
|
+
parseOutpoint(outpoint) {
|
|
1619
|
+
const [txid, indexStr] = outpoint.split('.');
|
|
1620
|
+
return [txid, Number.parseInt(indexStr, 10)];
|
|
1621
|
+
}
|
|
1622
|
+
/** Normalizes a txid string to lowercase. */
|
|
1623
|
+
normalizeTxid(txid) {
|
|
1624
|
+
return (txid !== null && txid !== void 0 ? txid : '').toLowerCase();
|
|
1625
|
+
}
|
|
1626
|
+
/** Reverses a 32-byte hex txid (for endian normalization). */
|
|
1627
|
+
reverseHexTxid(txid) {
|
|
1628
|
+
const hex = this.normalizeTxid(txid);
|
|
1629
|
+
if (!/^[0-9a-f]{64}$/.test(hex))
|
|
1630
|
+
return hex;
|
|
1631
|
+
const bytes = hex.match(/../g);
|
|
1632
|
+
return (bytes != null) ? bytes.reverse().join('') : hex;
|
|
1633
|
+
}
|
|
1634
|
+
/**
|
|
1635
|
+
* Returns true when an outpoint string (e.g. "txid.vout" or "txid:vout") refers to `token`.
|
|
1636
|
+
*/
|
|
1637
|
+
tokenMatchesOutpointString(outpoint, token) {
|
|
1638
|
+
const dot = outpoint.lastIndexOf('.');
|
|
1639
|
+
const colon = outpoint.lastIndexOf(':');
|
|
1640
|
+
const sep = Math.max(dot, colon);
|
|
1641
|
+
if (sep === -1)
|
|
1642
|
+
return false;
|
|
1643
|
+
const txidPart = outpoint.slice(0, sep);
|
|
1644
|
+
const vout = Number(outpoint.slice(sep + 1));
|
|
1645
|
+
if (!Number.isFinite(vout))
|
|
1646
|
+
return false;
|
|
1647
|
+
return this.normalizeTxid(txidPart) === this.normalizeTxid(token.txid) && vout === token.outputIndex;
|
|
1648
|
+
}
|
|
1649
|
+
/**
|
|
1650
|
+
* Finds the index of the tx input that spends the given permission token.
|
|
1651
|
+
* Handles multiple potential field names for TXID and vout.
|
|
1652
|
+
*/
|
|
1653
|
+
findInputIndexForToken(tx, token) {
|
|
1654
|
+
return tx.inputs.findIndex((input) => {
|
|
1655
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
1656
|
+
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;
|
|
1657
|
+
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;
|
|
1658
|
+
if (typeof txidCandidate === 'string' && typeof voutCandidate === 'number') {
|
|
1659
|
+
const cand = this.normalizeTxid(txidCandidate);
|
|
1660
|
+
if (cand === this.normalizeTxid(token.txid) && voutCandidate === token.outputIndex)
|
|
1661
|
+
return true;
|
|
1662
|
+
if (cand === this.reverseHexTxid(token.txid) && voutCandidate === token.outputIndex)
|
|
1663
|
+
return true;
|
|
1664
|
+
}
|
|
1665
|
+
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;
|
|
1666
|
+
return typeof outpointCandidate === 'string' && this.tokenMatchesOutpointString(outpointCandidate, token);
|
|
1667
|
+
});
|
|
1668
|
+
}
|
|
1672
1669
|
/** Looks for a DPACP permission token matching origin/domain, privileged, protocol, cpty. */
|
|
1673
1670
|
async findProtocolToken(originator, privileged, protocolID, counterparty, includeExpired, originatorLookupValues) {
|
|
1674
1671
|
const [secLevel, protoName] = protocolID;
|
|
@@ -1690,49 +1687,35 @@ class WalletPermissionsManager {
|
|
|
1690
1687
|
include: 'entire transactions'
|
|
1691
1688
|
}, this.adminOriginator);
|
|
1692
1689
|
for (const out of result.outputs) {
|
|
1693
|
-
const [txid,
|
|
1690
|
+
const [txid, outputIndex] = this.parseOutpoint(out.outpoint);
|
|
1694
1691
|
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
1695
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[
|
|
1696
|
-
if (
|
|
1692
|
+
const dec = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
1693
|
+
if ((dec === null || dec === void 0 ? void 0 : dec.fields) == null || dec.fields.length < 6)
|
|
1697
1694
|
continue;
|
|
1698
|
-
const
|
|
1699
|
-
|
|
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) {
|
|
1695
|
+
const f = await this.decryptProtocolTokenFields(dec.fields);
|
|
1696
|
+
if (this.normalizeOriginator(f.domainDecoded) !== originator)
|
|
1707
1697
|
continue;
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
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)) {
|
|
1698
|
+
if (f.privDecoded !== !!privileged ||
|
|
1699
|
+
f.secLevelDecoded !== secLevel ||
|
|
1700
|
+
f.protoNameDecoded !== protoName ||
|
|
1701
|
+
(f.secLevelDecoded === 2 && f.cptyDecoded !== counterparty)) {
|
|
1718
1702
|
continue;
|
|
1719
1703
|
}
|
|
1720
|
-
if (!includeExpired && this.isTokenExpired(expiryDecoded))
|
|
1704
|
+
if (!includeExpired && this.isTokenExpired(f.expiryDecoded))
|
|
1721
1705
|
continue;
|
|
1722
|
-
}
|
|
1723
1706
|
return {
|
|
1724
1707
|
tx: tx.toBEEF(),
|
|
1725
|
-
txid
|
|
1726
|
-
outputIndex
|
|
1727
|
-
outputScript: tx.outputs[
|
|
1708
|
+
txid,
|
|
1709
|
+
outputIndex,
|
|
1710
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
1728
1711
|
satoshis: out.satoshis,
|
|
1729
1712
|
originator,
|
|
1730
|
-
rawOriginator: domainDecoded,
|
|
1713
|
+
rawOriginator: f.domainDecoded,
|
|
1731
1714
|
privileged,
|
|
1732
1715
|
protocol: protoName,
|
|
1733
1716
|
securityLevel: secLevel,
|
|
1734
|
-
expiry: expiryDecoded,
|
|
1735
|
-
counterparty: cptyDecoded
|
|
1717
|
+
expiry: f.expiryDecoded,
|
|
1718
|
+
counterparty: f.cptyDecoded
|
|
1736
1719
|
};
|
|
1737
1720
|
}
|
|
1738
1721
|
}
|
|
@@ -1763,32 +1746,18 @@ class WalletPermissionsManager {
|
|
|
1763
1746
|
for (const out of result.outputs) {
|
|
1764
1747
|
if (seen.has(out.outpoint))
|
|
1765
1748
|
continue;
|
|
1766
|
-
const [txid,
|
|
1749
|
+
const [txid, vout] = this.parseOutpoint(out.outpoint);
|
|
1767
1750
|
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
1768
|
-
const vout = Number(outputIndexStr);
|
|
1769
1751
|
const dec = sdk_1.PushDrop.decode(tx.outputs[vout].lockingScript);
|
|
1770
|
-
if (
|
|
1752
|
+
if ((dec === null || dec === void 0 ? void 0 : dec.fields) == null || dec.fields.length < 6)
|
|
1771
1753
|
continue;
|
|
1772
|
-
const
|
|
1773
|
-
|
|
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) {
|
|
1754
|
+
const f = await this.decryptProtocolTokenFields(dec.fields);
|
|
1755
|
+
if (this.normalizeOriginator(f.domainDecoded) !== originator)
|
|
1781
1756
|
continue;
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
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)) {
|
|
1757
|
+
if (f.privDecoded !== !!privileged ||
|
|
1758
|
+
f.secLevelDecoded !== secLevel ||
|
|
1759
|
+
f.protoNameDecoded !== protoName ||
|
|
1760
|
+
(f.secLevelDecoded === 2 && f.cptyDecoded !== counterparty)) {
|
|
1792
1761
|
continue;
|
|
1793
1762
|
}
|
|
1794
1763
|
seen.add(out.outpoint);
|
|
@@ -1799,12 +1768,12 @@ class WalletPermissionsManager {
|
|
|
1799
1768
|
outputScript: tx.outputs[vout].lockingScript.toHex(),
|
|
1800
1769
|
satoshis: out.satoshis,
|
|
1801
1770
|
originator,
|
|
1802
|
-
rawOriginator: domainDecoded,
|
|
1771
|
+
rawOriginator: f.domainDecoded,
|
|
1803
1772
|
privileged,
|
|
1804
1773
|
protocol: protoName,
|
|
1805
1774
|
securityLevel: secLevel,
|
|
1806
|
-
expiry: expiryDecoded,
|
|
1807
|
-
counterparty: cptyDecoded
|
|
1775
|
+
expiry: f.expiryDecoded,
|
|
1776
|
+
counterparty: f.cptyDecoded
|
|
1808
1777
|
});
|
|
1809
1778
|
}
|
|
1810
1779
|
}
|
|
@@ -1821,30 +1790,25 @@ class WalletPermissionsManager {
|
|
|
1821
1790
|
include: 'entire transactions'
|
|
1822
1791
|
}, this.adminOriginator);
|
|
1823
1792
|
for (const out of result.outputs) {
|
|
1824
|
-
const [txid,
|
|
1793
|
+
const [txid, outputIndex] = this.parseOutpoint(out.outpoint);
|
|
1825
1794
|
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
1826
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[
|
|
1795
|
+
const dec = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
1827
1796
|
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 3)
|
|
1828
1797
|
continue;
|
|
1829
|
-
const
|
|
1830
|
-
|
|
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) {
|
|
1798
|
+
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(dec.fields[0]));
|
|
1799
|
+
if (this.normalizeOriginator(domainDecoded) !== originator)
|
|
1835
1800
|
continue;
|
|
1836
|
-
|
|
1837
|
-
const
|
|
1838
|
-
const basketDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(basketRaw));
|
|
1801
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(dec.fields[1])), 10);
|
|
1802
|
+
const basketDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(dec.fields[2]));
|
|
1839
1803
|
if (basketDecoded !== basket)
|
|
1840
1804
|
continue;
|
|
1841
1805
|
if (!includeExpired && this.isTokenExpired(expiryDecoded))
|
|
1842
1806
|
continue;
|
|
1843
1807
|
return {
|
|
1844
|
-
tx: tx.toBEEF(),
|
|
1845
|
-
txid
|
|
1846
|
-
outputIndex
|
|
1847
|
-
outputScript: tx.outputs[
|
|
1808
|
+
tx: tx.toBEEF(),
|
|
1809
|
+
txid,
|
|
1810
|
+
outputIndex,
|
|
1811
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
1848
1812
|
satoshis: out.satoshis,
|
|
1849
1813
|
originator,
|
|
1850
1814
|
rawOriginator: domainDecoded,
|
|
@@ -1866,39 +1830,33 @@ class WalletPermissionsManager {
|
|
|
1866
1830
|
include: 'entire transactions'
|
|
1867
1831
|
}, this.adminOriginator);
|
|
1868
1832
|
for (const out of result.outputs) {
|
|
1869
|
-
const [txid,
|
|
1833
|
+
const [txid, outputIndex] = this.parseOutpoint(out.outpoint);
|
|
1870
1834
|
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
1871
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[
|
|
1835
|
+
const dec = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
1872
1836
|
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 6)
|
|
1873
1837
|
continue;
|
|
1874
1838
|
const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = dec.fields;
|
|
1875
1839
|
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
1876
|
-
|
|
1877
|
-
if (normalizedDomain !== originator) {
|
|
1840
|
+
if (this.normalizeOriginator(domainDecoded) !== originator)
|
|
1878
1841
|
continue;
|
|
1879
|
-
|
|
1880
|
-
const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
1842
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
1881
1843
|
const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
|
|
1882
1844
|
const typeDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw));
|
|
1883
1845
|
const verifierDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw));
|
|
1884
|
-
const
|
|
1885
|
-
|
|
1886
|
-
if (privDecoded !== !!privileged || typeDecoded !== certType || verifierDec !== verifier) {
|
|
1846
|
+
const allFields = JSON.parse(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fieldsRaw)));
|
|
1847
|
+
if (privDecoded !== !!privileged || typeDecoded !== certType || verifierDec !== verifier)
|
|
1887
1848
|
continue;
|
|
1888
|
-
}
|
|
1889
1849
|
// Check if 'fields' is a subset of 'allFields'
|
|
1890
1850
|
const setAll = new Set(allFields);
|
|
1891
|
-
if (fields.some(f => !setAll.has(f)))
|
|
1851
|
+
if (fields.some(f => !setAll.has(f)))
|
|
1892
1852
|
continue;
|
|
1893
|
-
|
|
1894
|
-
if (!includeExpired && this.isTokenExpired(expiryDecoded)) {
|
|
1853
|
+
if (!includeExpired && this.isTokenExpired(expiryDecoded))
|
|
1895
1854
|
continue;
|
|
1896
|
-
}
|
|
1897
1855
|
return {
|
|
1898
1856
|
tx: tx.toBEEF(),
|
|
1899
|
-
txid
|
|
1900
|
-
outputIndex
|
|
1901
|
-
outputScript: tx.outputs[
|
|
1857
|
+
txid,
|
|
1858
|
+
outputIndex,
|
|
1859
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
1902
1860
|
satoshis: out.satoshis,
|
|
1903
1861
|
originator,
|
|
1904
1862
|
rawOriginator: domainDecoded,
|
|
@@ -1935,11 +1893,11 @@ class WalletPermissionsManager {
|
|
|
1935
1893
|
if (normalizedDomain !== originator)
|
|
1936
1894
|
continue;
|
|
1937
1895
|
const amtDecodedStr = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(amtRaw));
|
|
1938
|
-
const authorizedAmount = parseInt(amtDecodedStr, 10);
|
|
1896
|
+
const authorizedAmount = Number.parseInt(amtDecodedStr, 10);
|
|
1939
1897
|
return {
|
|
1940
1898
|
tx: tx.toBEEF(),
|
|
1941
1899
|
txid: out.outpoint.split('.')[0],
|
|
1942
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
1900
|
+
outputIndex: Number.parseInt(out.outpoint.split('.')[1], 10),
|
|
1943
1901
|
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
1944
1902
|
satoshis: out.satoshis,
|
|
1945
1903
|
originator,
|
|
@@ -2021,7 +1979,7 @@ class WalletPermissionsManager {
|
|
|
2021
1979
|
}, this.adminOriginator);
|
|
2022
1980
|
}
|
|
2023
1981
|
async mapWithConcurrency(items, concurrency, fn) {
|
|
2024
|
-
if (
|
|
1982
|
+
if (items.length === 0)
|
|
2025
1983
|
return [];
|
|
2026
1984
|
const results = new Array(items.length);
|
|
2027
1985
|
let i = 0;
|
|
@@ -2033,11 +1991,11 @@ class WalletPermissionsManager {
|
|
|
2033
1991
|
results[idx] = await fn(items[idx]);
|
|
2034
1992
|
}
|
|
2035
1993
|
};
|
|
2036
|
-
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
1994
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, async () => await worker()));
|
|
2037
1995
|
return results;
|
|
2038
1996
|
}
|
|
2039
1997
|
async runBestEffortBatches(items, chunkSize, runChunk) {
|
|
2040
|
-
if (
|
|
1998
|
+
if (items.length === 0)
|
|
2041
1999
|
return [];
|
|
2042
2000
|
const out = [];
|
|
2043
2001
|
for (let i = 0; i < items.length; i += chunkSize) {
|
|
@@ -2084,8 +2042,8 @@ class WalletPermissionsManager {
|
|
|
2084
2042
|
}
|
|
2085
2043
|
async createPermissionTokensBestEffort(items) {
|
|
2086
2044
|
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));
|
|
2045
|
+
return await this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2046
|
+
const built = await this.mapWithConcurrency(chunk, 8, async (c) => await this.buildPermissionOutput(c.request, c.expiry, c.amount));
|
|
2089
2047
|
await this.createAction({
|
|
2090
2048
|
description: `Grant ${built.length} permissions`,
|
|
2091
2049
|
outputs: built.map(b => b.output),
|
|
@@ -2096,8 +2054,8 @@ class WalletPermissionsManager {
|
|
|
2096
2054
|
}
|
|
2097
2055
|
async renewPermissionTokensBestEffort(items) {
|
|
2098
2056
|
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));
|
|
2057
|
+
return await this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2058
|
+
const built = await this.mapWithConcurrency(chunk, 8, async (c) => await this.buildPermissionOutput(c.request, c.expiry, c.amount));
|
|
2101
2059
|
const inputBeef = new sdk_1.Beef();
|
|
2102
2060
|
for (const c of chunk) {
|
|
2103
2061
|
inputBeef.mergeBeef(sdk_1.Beef.fromBinary(c.oldToken.tx));
|
|
@@ -2164,7 +2122,7 @@ class WalletPermissionsManager {
|
|
|
2164
2122
|
satoshis: 1,
|
|
2165
2123
|
outputDescription: 'Renewed permission token',
|
|
2166
2124
|
...((opts === null || opts === void 0 ? void 0 : opts.basket) ? { basket: opts.basket } : {}),
|
|
2167
|
-
...((opts === null || opts === void 0 ? void 0 : opts.tags) ? { tags: opts.tags }
|
|
2125
|
+
...(((opts === null || opts === void 0 ? void 0 : opts.tags) == null) ? {} : { tags: opts.tags })
|
|
2168
2126
|
}
|
|
2169
2127
|
],
|
|
2170
2128
|
options: {
|
|
@@ -2319,9 +2277,7 @@ class WalletPermissionsManager {
|
|
|
2319
2277
|
const tags = [`originator ${r.originator}`];
|
|
2320
2278
|
switch (r.type) {
|
|
2321
2279
|
case 'protocol': {
|
|
2322
|
-
tags.push(`privileged ${!!r.privileged}`);
|
|
2323
|
-
tags.push(`protocolName ${r.protocolID[1]}`);
|
|
2324
|
-
tags.push(`protocolSecurityLevel ${r.protocolID[0]}`);
|
|
2280
|
+
tags.push(`privileged ${!!r.privileged}`, `protocolName ${r.protocolID[1]}`, `protocolSecurityLevel ${r.protocolID[0]}`);
|
|
2325
2281
|
if (r.protocolID[0] === 2) {
|
|
2326
2282
|
tags.push(`counterparty ${(_a = r.counterparty) !== null && _a !== void 0 ? _a : 'self'}`);
|
|
2327
2283
|
}
|
|
@@ -2332,9 +2288,7 @@ class WalletPermissionsManager {
|
|
|
2332
2288
|
break;
|
|
2333
2289
|
}
|
|
2334
2290
|
case 'certificate': {
|
|
2335
|
-
tags.push(`privileged ${!!r.privileged}`);
|
|
2336
|
-
tags.push(`type ${r.certificate.certType}`);
|
|
2337
|
-
tags.push(`verifier ${r.certificate.verifier}`);
|
|
2291
|
+
tags.push(`privileged ${!!r.privileged}`, `type ${r.certificate.certType}`, `verifier ${r.certificate.verifier}`);
|
|
2338
2292
|
break;
|
|
2339
2293
|
}
|
|
2340
2294
|
case 'spending': {
|
|
@@ -2357,74 +2311,55 @@ class WalletPermissionsManager {
|
|
|
2357
2311
|
* @returns Array of permission tokens that match the filter criteria
|
|
2358
2312
|
*/
|
|
2359
2313
|
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
|
-
}
|
|
2314
|
+
const baseTags = this.buildProtocolFilterTags({ privileged, protocolName, protocolSecurityLevel, counterparty });
|
|
2374
2315
|
const originFilter = originator ? this.prepareOriginator(originator) : undefined;
|
|
2375
|
-
const originVariants = originFilter
|
|
2316
|
+
const originVariants = (originFilter == null) ? [undefined] : originFilter.lookupValues;
|
|
2376
2317
|
const seen = new Set();
|
|
2377
2318
|
const tokens = [];
|
|
2378
2319
|
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
|
-
}
|
|
2320
|
+
const tags = originTag != null ? [...baseTags, `originator ${originTag}`] : [...baseTags];
|
|
2321
|
+
const result = await this.underlying.listOutputs({ basket: BASKET_MAP.protocol, tags, tagQueryMode: 'all', include: 'entire transactions', limit: 10000 }, this.adminOriginator);
|
|
2322
|
+
await this.collectProtocolTokens(result, originFilter, seen, tokens);
|
|
2425
2323
|
}
|
|
2426
2324
|
return tokens;
|
|
2427
2325
|
}
|
|
2326
|
+
/** Builds the base tag array for protocol permission listing. */
|
|
2327
|
+
buildProtocolFilterTags({ privileged, protocolName, protocolSecurityLevel, counterparty }) {
|
|
2328
|
+
const tags = [];
|
|
2329
|
+
if (privileged !== undefined)
|
|
2330
|
+
tags.push(`privileged ${!!privileged}`);
|
|
2331
|
+
if (protocolName)
|
|
2332
|
+
tags.push(`protocolName ${protocolName}`);
|
|
2333
|
+
if (protocolSecurityLevel !== undefined)
|
|
2334
|
+
tags.push(`protocolSecurityLevel ${protocolSecurityLevel}`);
|
|
2335
|
+
if (counterparty)
|
|
2336
|
+
tags.push(`counterparty ${counterparty}`);
|
|
2337
|
+
return tags;
|
|
2338
|
+
}
|
|
2339
|
+
/** Decodes and appends protocol permission tokens from a listOutputs result. */
|
|
2340
|
+
async collectProtocolTokens(result, originFilter, seen, tokens) {
|
|
2341
|
+
for (const out of result.outputs) {
|
|
2342
|
+
if (seen.has(out.outpoint))
|
|
2343
|
+
continue;
|
|
2344
|
+
const [txid, outputIndex] = this.parseOutpoint(out.outpoint);
|
|
2345
|
+
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
2346
|
+
const dec = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
2347
|
+
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 6)
|
|
2348
|
+
continue;
|
|
2349
|
+
const f = await this.decryptProtocolTokenFields(dec.fields);
|
|
2350
|
+
const normalizedDomain = this.normalizeOriginator(f.domainDecoded);
|
|
2351
|
+
if ((originFilter != null) && normalizedDomain !== originFilter.normalized)
|
|
2352
|
+
continue;
|
|
2353
|
+
seen.add(out.outpoint);
|
|
2354
|
+
tokens.push({
|
|
2355
|
+
tx: tx.toBEEF(), txid, outputIndex,
|
|
2356
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
2357
|
+
satoshis: out.satoshis, originator: normalizedDomain, rawOriginator: f.domainDecoded,
|
|
2358
|
+
expiry: f.expiryDecoded, privileged: f.privDecoded,
|
|
2359
|
+
securityLevel: f.secLevelDecoded, protocol: f.protoNameDecoded, counterparty: f.cptyDecoded
|
|
2360
|
+
});
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2428
2363
|
/**
|
|
2429
2364
|
* Returns true if the originator already holds a valid unexpired protocol permission.
|
|
2430
2365
|
* This calls `ensureProtocolPermission` with `seekPermission=false`, so it won't prompt.
|
|
@@ -2456,7 +2391,7 @@ class WalletPermissionsManager {
|
|
|
2456
2391
|
baseTags.push(`basket ${params.basket}`);
|
|
2457
2392
|
}
|
|
2458
2393
|
const originFilter = params.originator ? this.prepareOriginator(params.originator) : undefined;
|
|
2459
|
-
const originVariants = originFilter
|
|
2394
|
+
const originVariants = (originFilter == null) ? [undefined] : originFilter.lookupValues;
|
|
2460
2395
|
const seen = new Set();
|
|
2461
2396
|
const tokens = [];
|
|
2462
2397
|
for (const originTag of originVariants) {
|
|
@@ -2474,26 +2409,25 @@ class WalletPermissionsManager {
|
|
|
2474
2409
|
for (const out of result.outputs) {
|
|
2475
2410
|
if (seen.has(out.outpoint))
|
|
2476
2411
|
continue;
|
|
2477
|
-
const [txid,
|
|
2412
|
+
const [txid, outputIndex] = this.parseOutpoint(out.outpoint);
|
|
2478
2413
|
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
2479
|
-
const dec = sdk_1.PushDrop.decode(tx.outputs[
|
|
2414
|
+
const dec = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
2480
2415
|
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 3)
|
|
2481
2416
|
continue;
|
|
2482
2417
|
const [domainRaw, expiryRaw, basketRaw] = dec.fields;
|
|
2483
2418
|
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
2484
2419
|
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
2485
|
-
if (originFilter && normalizedDomain !== originFilter.normalized)
|
|
2420
|
+
if ((originFilter != null) && normalizedDomain !== originFilter.normalized)
|
|
2486
2421
|
continue;
|
|
2487
|
-
|
|
2488
|
-
const expiryDecoded = parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
2422
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
2489
2423
|
const basketDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(basketRaw));
|
|
2490
2424
|
seen.add(out.outpoint);
|
|
2491
2425
|
tokens.push({
|
|
2492
2426
|
tx: tx.toBEEF(),
|
|
2493
|
-
txid
|
|
2494
|
-
outputIndex
|
|
2427
|
+
txid,
|
|
2428
|
+
outputIndex,
|
|
2495
2429
|
satoshis: out.satoshis,
|
|
2496
|
-
outputScript: tx.outputs[
|
|
2430
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
2497
2431
|
originator: normalizedDomain,
|
|
2498
2432
|
rawOriginator: domainDecoded,
|
|
2499
2433
|
basketName: basketDecoded,
|
|
@@ -2512,7 +2446,7 @@ class WalletPermissionsManager {
|
|
|
2512
2446
|
originator: params.originator,
|
|
2513
2447
|
basket: params.basket,
|
|
2514
2448
|
seekPermission: false,
|
|
2515
|
-
usageType: 'insertion'
|
|
2449
|
+
usageType: 'insertion'
|
|
2516
2450
|
});
|
|
2517
2451
|
return true;
|
|
2518
2452
|
}
|
|
@@ -2546,11 +2480,11 @@ class WalletPermissionsManager {
|
|
|
2546
2480
|
const [domainRaw, amtRaw] = dec.fields;
|
|
2547
2481
|
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
2548
2482
|
const amtDecodedStr = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(amtRaw));
|
|
2549
|
-
const authorizedAmount = parseInt(amtDecodedStr, 10);
|
|
2483
|
+
const authorizedAmount = Number.parseInt(amtDecodedStr, 10);
|
|
2550
2484
|
tokens.push({
|
|
2551
2485
|
tx: tx.toBEEF(),
|
|
2552
2486
|
txid: out.outpoint.split('.')[0],
|
|
2553
|
-
outputIndex: parseInt(out.outpoint.split('.')[1], 10),
|
|
2487
|
+
outputIndex: Number.parseInt(out.outpoint.split('.')[1], 10),
|
|
2554
2488
|
satoshis: out.satoshis,
|
|
2555
2489
|
outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),
|
|
2556
2490
|
originator: domainDecoded,
|
|
@@ -2586,72 +2520,54 @@ class WalletPermissionsManager {
|
|
|
2586
2520
|
* @returns Array of permission tokens that match the filter criteria
|
|
2587
2521
|
*/
|
|
2588
2522
|
async listCertificateAccess(params = {}) {
|
|
2589
|
-
const basketName = BASKET_MAP.certificate;
|
|
2590
2523
|
const baseTags = [];
|
|
2591
|
-
if (params.privileged !== undefined)
|
|
2524
|
+
if (params.privileged !== undefined)
|
|
2592
2525
|
baseTags.push(`privileged ${!!params.privileged}`);
|
|
2593
|
-
|
|
2594
|
-
if (params.certType) {
|
|
2526
|
+
if (params.certType)
|
|
2595
2527
|
baseTags.push(`type ${params.certType}`);
|
|
2596
|
-
|
|
2597
|
-
if (params.verifier) {
|
|
2528
|
+
if (params.verifier)
|
|
2598
2529
|
baseTags.push(`verifier ${params.verifier}`);
|
|
2599
|
-
}
|
|
2600
2530
|
const originFilter = params.originator ? this.prepareOriginator(params.originator) : undefined;
|
|
2601
|
-
const originVariants = originFilter
|
|
2531
|
+
const originVariants = (originFilter == null) ? [undefined] : originFilter.lookupValues;
|
|
2602
2532
|
const seen = new Set();
|
|
2603
2533
|
const tokens = [];
|
|
2604
2534
|
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
|
-
}
|
|
2535
|
+
const tags = originTag != null ? [...baseTags, `originator ${originTag}`] : [...baseTags];
|
|
2536
|
+
const result = await this.underlying.listOutputs({ basket: BASKET_MAP.certificate, tags, tagQueryMode: 'all', include: 'entire transactions', limit: 10000 }, this.adminOriginator);
|
|
2537
|
+
await this.collectCertificateTokens(result, originFilter, seen, tokens);
|
|
2652
2538
|
}
|
|
2653
2539
|
return tokens;
|
|
2654
2540
|
}
|
|
2541
|
+
/** Decodes and appends certificate permission tokens from a listOutputs result. */
|
|
2542
|
+
async collectCertificateTokens(result, originFilter, seen, tokens) {
|
|
2543
|
+
for (const out of result.outputs) {
|
|
2544
|
+
if (seen.has(out.outpoint))
|
|
2545
|
+
continue;
|
|
2546
|
+
const [txid, outputIndex] = this.parseOutpoint(out.outpoint);
|
|
2547
|
+
const tx = sdk_1.Transaction.fromBEEF(result.BEEF, txid);
|
|
2548
|
+
const dec = sdk_1.PushDrop.decode(tx.outputs[outputIndex].lockingScript);
|
|
2549
|
+
if (!(dec === null || dec === void 0 ? void 0 : dec.fields) || dec.fields.length < 6)
|
|
2550
|
+
continue;
|
|
2551
|
+
const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = dec.fields;
|
|
2552
|
+
const domainDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw));
|
|
2553
|
+
const normalizedDomain = this.normalizeOriginator(domainDecoded);
|
|
2554
|
+
if ((originFilter != null) && normalizedDomain !== originFilter.normalized)
|
|
2555
|
+
continue;
|
|
2556
|
+
const expiryDecoded = Number.parseInt(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10);
|
|
2557
|
+
const privDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true';
|
|
2558
|
+
const typeDecoded = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw));
|
|
2559
|
+
const verifierDec = sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw));
|
|
2560
|
+
const allFields = JSON.parse(sdk_1.Utils.toUTF8(await this.decryptPermissionTokenField(fieldsRaw)));
|
|
2561
|
+
seen.add(out.outpoint);
|
|
2562
|
+
tokens.push({
|
|
2563
|
+
tx: tx.toBEEF(), txid, outputIndex, satoshis: out.satoshis,
|
|
2564
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toHex(),
|
|
2565
|
+
originator: normalizedDomain, rawOriginator: domainDecoded,
|
|
2566
|
+
privileged: privDecoded, certType: typeDecoded, certFields: allFields,
|
|
2567
|
+
verifier: verifierDec, expiry: expiryDecoded
|
|
2568
|
+
});
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2655
2571
|
/**
|
|
2656
2572
|
* Returns `true` if the originator already holds a valid unexpired certificate access
|
|
2657
2573
|
* for the given certType/fields. Does not prompt the user.
|
|
@@ -2683,7 +2599,7 @@ class WalletPermissionsManager {
|
|
|
2683
2599
|
basket: true,
|
|
2684
2600
|
certificate: true,
|
|
2685
2601
|
spending: true,
|
|
2686
|
-
...
|
|
2602
|
+
...opts
|
|
2687
2603
|
};
|
|
2688
2604
|
const [protocolTokens, basketTokens, certificateTokens, spendingTokens] = await Promise.all([
|
|
2689
2605
|
include.protocol ? this.listProtocolPermissions({ originator }) : Promise.resolve([]),
|
|
@@ -2693,7 +2609,7 @@ class WalletPermissionsManager {
|
|
|
2693
2609
|
? this.listSpendingAuthorizations({ originator: preparedOriginator.normalized })
|
|
2694
2610
|
: Promise.resolve([])
|
|
2695
2611
|
]);
|
|
2696
|
-
const spendingTokenList = spendingTokens.length ? [spendingTokens[0]] : [];
|
|
2612
|
+
const spendingTokenList = (spendingTokens.length > 0) ? [spendingTokens[0]] : [];
|
|
2697
2613
|
const allTokens = [...protocolTokens, ...basketTokens, ...certificateTokens, ...spendingTokenList];
|
|
2698
2614
|
const seen = new Set();
|
|
2699
2615
|
const deduped = allTokens.filter(t => {
|
|
@@ -2707,13 +2623,13 @@ class WalletPermissionsManager {
|
|
|
2707
2623
|
}
|
|
2708
2624
|
async revokePermissionTokensBestEffort(items) {
|
|
2709
2625
|
const CHUNK = 15;
|
|
2710
|
-
return this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2626
|
+
return await this.runBestEffortBatches(items, CHUNK, async (chunk) => {
|
|
2711
2627
|
await this.revokePermissionTokensChunk(chunk);
|
|
2712
2628
|
return chunk;
|
|
2713
2629
|
});
|
|
2714
2630
|
}
|
|
2715
2631
|
async revokePermissionTokensChunk(oldTokens) {
|
|
2716
|
-
if (
|
|
2632
|
+
if (oldTokens.length === 0)
|
|
2717
2633
|
return;
|
|
2718
2634
|
const inputBeef = new sdk_1.Beef();
|
|
2719
2635
|
for (const token of oldTokens) {
|
|
@@ -2737,48 +2653,8 @@ class WalletPermissionsManager {
|
|
|
2737
2653
|
throw new Error('Failed to create signable transaction');
|
|
2738
2654
|
}
|
|
2739
2655
|
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
2656
|
const inputsToSign = oldTokens.map(token => {
|
|
2781
|
-
let permInputIndex = findInputIndexForToken(token);
|
|
2657
|
+
let permInputIndex = this.findInputIndexForToken(tx, token);
|
|
2782
2658
|
if (permInputIndex === -1 && tx.inputs.length === 1) {
|
|
2783
2659
|
permInputIndex = 0;
|
|
2784
2660
|
}
|
|
@@ -2811,13 +2687,13 @@ class WalletPermissionsManager {
|
|
|
2811
2687
|
async revokePermission(oldToken) {
|
|
2812
2688
|
const oldOutpoint = `${oldToken.txid}.${oldToken.outputIndex}`;
|
|
2813
2689
|
const { signableTransaction } = await this.createAction({
|
|
2814
|
-
description:
|
|
2690
|
+
description: 'Revoke permission',
|
|
2815
2691
|
inputBEEF: oldToken.tx,
|
|
2816
2692
|
inputs: [
|
|
2817
2693
|
{
|
|
2818
2694
|
outpoint: oldOutpoint,
|
|
2819
2695
|
unlockingScriptLength: 73, // length of signature
|
|
2820
|
-
inputDescription:
|
|
2696
|
+
inputDescription: 'Consume old permission token'
|
|
2821
2697
|
}
|
|
2822
2698
|
],
|
|
2823
2699
|
options: {
|
|
@@ -2825,44 +2701,7 @@ class WalletPermissionsManager {
|
|
|
2825
2701
|
}
|
|
2826
2702
|
}, this.adminOriginator);
|
|
2827
2703
|
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
|
-
});
|
|
2704
|
+
let permInputIndex = this.findInputIndexForToken(tx, oldToken);
|
|
2866
2705
|
if (permInputIndex === -1 && tx.inputs.length === 1) {
|
|
2867
2706
|
permInputIndex = 0;
|
|
2868
2707
|
}
|
|
@@ -2886,56 +2725,81 @@ class WalletPermissionsManager {
|
|
|
2886
2725
|
async createAction(args, originator) {
|
|
2887
2726
|
// 1) Identify unique P-modules involved (one per schemeID) from both baskets and labels
|
|
2888
2727
|
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
|
|
2728
|
+
const nonPBaskets = this.collectNonPBaskets(args.outputs, pModulesByScheme);
|
|
2906
2729
|
const nonPLabels = this.splitLabelsByPermissionModule(args.labels, pModulesByScheme);
|
|
2907
2730
|
// 2) Check permissions for non-P baskets
|
|
2908
2731
|
for (const basket of nonPBaskets) {
|
|
2909
|
-
await this.ensureBasketAccess({
|
|
2910
|
-
originator: originator,
|
|
2911
|
-
basket,
|
|
2912
|
-
reason: args.description,
|
|
2913
|
-
usageType: 'insertion'
|
|
2914
|
-
});
|
|
2732
|
+
await this.ensureBasketAccess({ originator: originator, basket, reason: args.description, usageType: 'insertion' });
|
|
2915
2733
|
}
|
|
2916
2734
|
// 3) Check permissions for non-P labels
|
|
2917
2735
|
for (const lbl of nonPLabels) {
|
|
2918
|
-
await this.ensureLabelAccess({
|
|
2919
|
-
originator: originator,
|
|
2920
|
-
label: lbl,
|
|
2921
|
-
reason: args.description,
|
|
2922
|
-
usageType: 'apply'
|
|
2923
|
-
});
|
|
2736
|
+
await this.ensureLabelAccess({ originator: originator, label: lbl, reason: args.description, usageType: 'apply' });
|
|
2924
2737
|
}
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2738
|
+
// 4) Force signAndProcess=false unless the originator is admin and explicitly sets it to true.
|
|
2739
|
+
const modifiedOptions = this.enforceSignAndProcess(args.options, originator);
|
|
2740
|
+
// 5) Encrypt transaction metadata, saving originals for spending auth and line items.
|
|
2741
|
+
const originalDescription = args.description;
|
|
2742
|
+
const { originalInputDescriptions, originalOutputDescriptions } = await this.encryptActionMetadata(args);
|
|
2743
|
+
// 6) Call the underlying wallet's createAction with P-module chaining as needed.
|
|
2744
|
+
const finalArgs = {
|
|
2745
|
+
...args,
|
|
2746
|
+
options: modifiedOptions,
|
|
2747
|
+
labels: [...(args.labels || []), `admin originator ${originator}`, `admin month ${this.getCurrentMonthYearUTC()}`]
|
|
2748
|
+
};
|
|
2749
|
+
let createResult = await this.callCreateActionWithPModules(finalArgs, pModulesByScheme, originator);
|
|
2750
|
+
if (createResult.signableTransaction == null)
|
|
2751
|
+
return createResult;
|
|
2752
|
+
// 7) Parse the signable tx to determine net spend, then gate on spending authorization.
|
|
2753
|
+
const tx = sdk_1.Transaction.fromAtomicBEEF(createResult.signableTransaction.tx);
|
|
2754
|
+
const reference = createResult.signableTransaction.reference;
|
|
2755
|
+
const { netSpent, lineItems } = this.computeNetSpend(tx, args, originalInputDescriptions, originalOutputDescriptions);
|
|
2756
|
+
// 8) If netSpent > 0, require spending authorization. Abort if denied.
|
|
2757
|
+
if (netSpent > 0) {
|
|
2758
|
+
try {
|
|
2759
|
+
await this.ensureSpendingAuthorization({ originator: originator, satoshis: netSpent, lineItems, reason: originalDescription });
|
|
2760
|
+
}
|
|
2761
|
+
catch (err) {
|
|
2762
|
+
await this.underlying.abortAction({ reference });
|
|
2763
|
+
throw err;
|
|
2764
|
+
}
|
|
2765
|
+
}
|
|
2766
|
+
// 9) Finalize or return the signable transaction based on whether more signatures are needed.
|
|
2767
|
+
const vargs = sdk_1.Validation.validateCreateActionArgs(args);
|
|
2768
|
+
if (vargs.isSignAction)
|
|
2769
|
+
return createResult;
|
|
2770
|
+
const signResult = await this.underlying.signAction({ reference, spends: {}, options: args.options }, originator);
|
|
2771
|
+
return { ...createResult, ...signResult, signableTransaction: undefined };
|
|
2772
|
+
}
|
|
2773
|
+
/** Scans outputs to split P-scheme baskets from regular baskets; registers P-modules as a side effect. */
|
|
2774
|
+
collectNonPBaskets(outputs, pModulesByScheme) {
|
|
2775
|
+
const nonPBaskets = [];
|
|
2776
|
+
if (outputs == null)
|
|
2777
|
+
return nonPBaskets;
|
|
2778
|
+
for (const out of outputs) {
|
|
2779
|
+
if (!out.basket)
|
|
2780
|
+
continue;
|
|
2781
|
+
if (out.basket.startsWith('p ')) {
|
|
2782
|
+
this.addPModuleByScheme(out.basket.split(' ')[1], 'basket', pModulesByScheme);
|
|
2783
|
+
}
|
|
2784
|
+
else {
|
|
2785
|
+
nonPBaskets.push(out.basket);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
return nonPBaskets;
|
|
2789
|
+
}
|
|
2790
|
+
/** Enforces signAndProcess=false for non-admin originators; throws if admin override is missing. */
|
|
2791
|
+
enforceSignAndProcess(options, originator) {
|
|
2792
|
+
const modifiedOptions = { ...options };
|
|
2931
2793
|
if (modifiedOptions.signAndProcess !== true) {
|
|
2932
2794
|
modifiedOptions.signAndProcess = false;
|
|
2933
2795
|
}
|
|
2934
2796
|
else if (!this.isAdminOriginator(originator)) {
|
|
2935
2797
|
throw new Error('Only the admin originator can set signAndProcess=true explicitly.');
|
|
2936
2798
|
}
|
|
2937
|
-
|
|
2938
|
-
|
|
2799
|
+
return modifiedOptions;
|
|
2800
|
+
}
|
|
2801
|
+
/** Encrypts all description/instruction fields in args in-place; returns original (plaintext) copies. */
|
|
2802
|
+
async encryptActionMetadata(args) {
|
|
2939
2803
|
const originalInputDescriptions = {};
|
|
2940
2804
|
const originalOutputDescriptions = {};
|
|
2941
2805
|
const inputEncryptionTasks = (args.inputs || []).map(async (input, i) => {
|
|
@@ -2954,64 +2818,34 @@ class WalletPermissionsManager {
|
|
|
2954
2818
|
}
|
|
2955
2819
|
});
|
|
2956
2820
|
await Promise.all([
|
|
2957
|
-
(async () => {
|
|
2958
|
-
args.description = await this.maybeEncryptMetadata(args.description);
|
|
2959
|
-
})(),
|
|
2821
|
+
(async () => { args.description = await this.maybeEncryptMetadata(args.description); })(),
|
|
2960
2822
|
...inputEncryptionTasks,
|
|
2961
2823
|
...outputEncryptionTasks
|
|
2962
2824
|
]);
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
const
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
let createResult;
|
|
2975
|
-
if (pModulesByScheme.size > 0) {
|
|
2976
|
-
// P-modules are involved - chain transformations
|
|
2977
|
-
const pModules = Array.from(pModulesByScheme.values());
|
|
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
|
-
}
|
|
2997
|
-
}
|
|
2998
|
-
else {
|
|
2999
|
-
// No P-modules - call underlying wallet directly
|
|
3000
|
-
createResult = await this.underlying.createAction(finalArgs, originator);
|
|
2825
|
+
return { originalInputDescriptions, originalOutputDescriptions };
|
|
2826
|
+
}
|
|
2827
|
+
/** Calls underlying createAction, chaining P-module request/response transforms when needed. */
|
|
2828
|
+
async callCreateActionWithPModules(finalArgs, pModulesByScheme, originator) {
|
|
2829
|
+
if (pModulesByScheme.size === 0)
|
|
2830
|
+
return await this.underlying.createAction(finalArgs, originator);
|
|
2831
|
+
const pModules = Array.from(pModulesByScheme.values());
|
|
2832
|
+
let transformedArgs = finalArgs;
|
|
2833
|
+
for (const module of pModules) {
|
|
2834
|
+
const transformed = await module.onRequest({ method: 'createAction', args: transformedArgs, originator: originator });
|
|
2835
|
+
transformedArgs = transformed.args;
|
|
3001
2836
|
}
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
2837
|
+
let createResult = await this.underlying.createAction(transformedArgs, originator);
|
|
2838
|
+
for (let i = pModules.length - 1; i >= 0; i--) {
|
|
2839
|
+
createResult = await pModules[i].onResponse(createResult, { method: 'createAction', originator: originator });
|
|
3005
2840
|
}
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
let netSpent = 0;
|
|
2841
|
+
return createResult;
|
|
2842
|
+
}
|
|
2843
|
+
/**
|
|
2844
|
+
* Computes the net satoshis the originator is spending in a createAction call,
|
|
2845
|
+
* accounting for foreign (originator-provided) inputs and outputs plus the fee.
|
|
2846
|
+
* Also builds the line items list for the spending authorization request.
|
|
2847
|
+
*/
|
|
2848
|
+
computeNetSpend(tx, args, originalInputDescriptions, originalOutputDescriptions) {
|
|
3015
2849
|
const lineItems = [];
|
|
3016
2850
|
// Sum originator-provided inputs:
|
|
3017
2851
|
let totalInputSatoshis = 0;
|
|
@@ -3024,7 +2858,7 @@ class WalletPermissionsManager {
|
|
|
3024
2858
|
lineItems.push({
|
|
3025
2859
|
type: 'input',
|
|
3026
2860
|
description: originalInputDescriptions[matchingIndex] || 'No input description provided',
|
|
3027
|
-
satoshis
|
|
2861
|
+
satoshis
|
|
3028
2862
|
});
|
|
3029
2863
|
}
|
|
3030
2864
|
}
|
|
@@ -3039,68 +2873,20 @@ class WalletPermissionsManager {
|
|
|
3039
2873
|
});
|
|
3040
2874
|
}
|
|
3041
2875
|
// 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
|
-
}
|
|
2876
|
+
const fee = tx.getFee();
|
|
2877
|
+
lineItems.push({ type: 'fee', satoshis: fee, description: 'Network fee' });
|
|
3082
2878
|
/**
|
|
3083
|
-
*
|
|
3084
|
-
*
|
|
3085
|
-
* - If the transaction still needs more signatures, we must return the signableTransaction.
|
|
2879
|
+
* Net spend = total foreign outflows minus total foreign inflows plus fee.
|
|
2880
|
+
* Domestic wallet inputs/change outputs are not counted — they are internal.
|
|
3086
2881
|
*/
|
|
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
|
-
};
|
|
2882
|
+
const netSpent = totalOutputSatoshis + fee - totalInputSatoshis;
|
|
2883
|
+
return { netSpent, lineItems };
|
|
3098
2884
|
}
|
|
3099
2885
|
async signAction(...args) {
|
|
3100
|
-
return this.underlying.signAction(...args);
|
|
2886
|
+
return await this.underlying.signAction(...args);
|
|
3101
2887
|
}
|
|
3102
2888
|
async abortAction(...args) {
|
|
3103
|
-
return this.underlying.abortAction(...args);
|
|
2889
|
+
return await this.underlying.abortAction(...args);
|
|
3104
2890
|
}
|
|
3105
2891
|
async listActions(...args) {
|
|
3106
2892
|
const [requestArgs, originator] = args;
|
|
@@ -3231,7 +3017,7 @@ class WalletPermissionsManager {
|
|
|
3231
3017
|
return results;
|
|
3232
3018
|
}
|
|
3233
3019
|
// No P-modules - call underlying wallet directly
|
|
3234
|
-
return this.underlying.internalizeAction(...args);
|
|
3020
|
+
return await this.underlying.internalizeAction(...args);
|
|
3235
3021
|
}
|
|
3236
3022
|
async listOutputs(...args) {
|
|
3237
3023
|
const [requestArgs, originator] = args;
|
|
@@ -3270,11 +3056,11 @@ class WalletPermissionsManager {
|
|
|
3270
3056
|
reason: 'relinquishOutput',
|
|
3271
3057
|
usageType: 'removal'
|
|
3272
3058
|
});
|
|
3273
|
-
return this.underlying.relinquishOutput(...args);
|
|
3059
|
+
return await this.underlying.relinquishOutput(...args);
|
|
3274
3060
|
}
|
|
3275
3061
|
async getPublicKey(...args) {
|
|
3276
3062
|
const [requestArgs, originator] = args;
|
|
3277
|
-
if (requestArgs.protocolID) {
|
|
3063
|
+
if (requestArgs.protocolID != null) {
|
|
3278
3064
|
// Delegate to permission module if needed
|
|
3279
3065
|
const pModuleResult = await this.delegateToPModuleIfNeeded(requestArgs.protocolID[1], 'getPublicKey', requestArgs, originator, async (transformedArgs) => {
|
|
3280
3066
|
return await this.underlying.getPublicKey(transformedArgs, originator);
|
|
@@ -3303,7 +3089,7 @@ class WalletPermissionsManager {
|
|
|
3303
3089
|
usageType: 'identityKey'
|
|
3304
3090
|
});
|
|
3305
3091
|
}
|
|
3306
|
-
return this.underlying.getPublicKey(...args);
|
|
3092
|
+
return await this.underlying.getPublicKey(...args);
|
|
3307
3093
|
}
|
|
3308
3094
|
async revealCounterpartyKeyLinkage(...args) {
|
|
3309
3095
|
const [requestArgs, originator] = args;
|
|
@@ -3315,7 +3101,7 @@ class WalletPermissionsManager {
|
|
|
3315
3101
|
reason: requestArgs.privilegedReason,
|
|
3316
3102
|
usageType: 'linkageRevelation'
|
|
3317
3103
|
});
|
|
3318
|
-
return this.underlying.revealCounterpartyKeyLinkage(...args);
|
|
3104
|
+
return await this.underlying.revealCounterpartyKeyLinkage(...args);
|
|
3319
3105
|
}
|
|
3320
3106
|
async revealSpecificKeyLinkage(...args) {
|
|
3321
3107
|
const [requestArgs, originator] = args;
|
|
@@ -3330,7 +3116,7 @@ class WalletPermissionsManager {
|
|
|
3330
3116
|
reason: requestArgs.privilegedReason,
|
|
3331
3117
|
usageType: 'linkageRevelation'
|
|
3332
3118
|
});
|
|
3333
|
-
return this.underlying.revealSpecificKeyLinkage(...args);
|
|
3119
|
+
return await this.underlying.revealSpecificKeyLinkage(...args);
|
|
3334
3120
|
}
|
|
3335
3121
|
async encrypt(...args) {
|
|
3336
3122
|
const [requestArgs, originator] = args;
|
|
@@ -3349,7 +3135,7 @@ class WalletPermissionsManager {
|
|
|
3349
3135
|
reason: requestArgs.privilegedReason,
|
|
3350
3136
|
usageType: 'encrypting'
|
|
3351
3137
|
});
|
|
3352
|
-
return this.underlying.encrypt(...args);
|
|
3138
|
+
return await this.underlying.encrypt(...args);
|
|
3353
3139
|
}
|
|
3354
3140
|
async decrypt(...args) {
|
|
3355
3141
|
const [requestArgs, originator] = args;
|
|
@@ -3368,7 +3154,7 @@ class WalletPermissionsManager {
|
|
|
3368
3154
|
reason: requestArgs.privilegedReason,
|
|
3369
3155
|
usageType: 'encrypting'
|
|
3370
3156
|
});
|
|
3371
|
-
return this.underlying.decrypt(...args);
|
|
3157
|
+
return await this.underlying.decrypt(...args);
|
|
3372
3158
|
}
|
|
3373
3159
|
async createHmac(...args) {
|
|
3374
3160
|
const [requestArgs, originator] = args;
|
|
@@ -3387,7 +3173,7 @@ class WalletPermissionsManager {
|
|
|
3387
3173
|
reason: requestArgs.privilegedReason,
|
|
3388
3174
|
usageType: 'hmac'
|
|
3389
3175
|
});
|
|
3390
|
-
return this.underlying.createHmac(...args);
|
|
3176
|
+
return await this.underlying.createHmac(...args);
|
|
3391
3177
|
}
|
|
3392
3178
|
async verifyHmac(...args) {
|
|
3393
3179
|
const [requestArgs, originator] = args;
|
|
@@ -3406,7 +3192,7 @@ class WalletPermissionsManager {
|
|
|
3406
3192
|
reason: requestArgs.privilegedReason,
|
|
3407
3193
|
usageType: 'hmac'
|
|
3408
3194
|
});
|
|
3409
|
-
return this.underlying.verifyHmac(...args);
|
|
3195
|
+
return await this.underlying.verifyHmac(...args);
|
|
3410
3196
|
}
|
|
3411
3197
|
async createSignature(...args) {
|
|
3412
3198
|
const [requestArgs, originator] = args;
|
|
@@ -3425,7 +3211,7 @@ class WalletPermissionsManager {
|
|
|
3425
3211
|
reason: requestArgs.privilegedReason,
|
|
3426
3212
|
usageType: 'signing'
|
|
3427
3213
|
});
|
|
3428
|
-
return this.underlying.createSignature(...args);
|
|
3214
|
+
return await this.underlying.createSignature(...args);
|
|
3429
3215
|
}
|
|
3430
3216
|
async verifySignature(...args) {
|
|
3431
3217
|
const [requestArgs, originator] = args;
|
|
@@ -3444,7 +3230,7 @@ class WalletPermissionsManager {
|
|
|
3444
3230
|
reason: requestArgs.privilegedReason,
|
|
3445
3231
|
usageType: 'signing'
|
|
3446
3232
|
});
|
|
3447
|
-
return this.underlying.verifySignature(...args);
|
|
3233
|
+
return await this.underlying.verifySignature(...args);
|
|
3448
3234
|
}
|
|
3449
3235
|
async acquireCertificate(...args) {
|
|
3450
3236
|
const [requestArgs, originator] = args;
|
|
@@ -3458,7 +3244,7 @@ class WalletPermissionsManager {
|
|
|
3458
3244
|
usageType: 'generic'
|
|
3459
3245
|
});
|
|
3460
3246
|
}
|
|
3461
|
-
return this.underlying.acquireCertificate(...args);
|
|
3247
|
+
return await this.underlying.acquireCertificate(...args);
|
|
3462
3248
|
}
|
|
3463
3249
|
async listCertificates(...args) {
|
|
3464
3250
|
const [requestArgs, originator] = args;
|
|
@@ -3466,13 +3252,13 @@ class WalletPermissionsManager {
|
|
|
3466
3252
|
await this.ensureProtocolPermission({
|
|
3467
3253
|
originator: originator,
|
|
3468
3254
|
privileged: requestArgs.privileged,
|
|
3469
|
-
protocolID: [1,
|
|
3255
|
+
protocolID: [1, 'certificate list'],
|
|
3470
3256
|
counterparty: 'self',
|
|
3471
3257
|
reason: requestArgs.privilegedReason,
|
|
3472
3258
|
usageType: 'generic'
|
|
3473
3259
|
});
|
|
3474
3260
|
}
|
|
3475
|
-
return this.underlying.listCertificates(...args);
|
|
3261
|
+
return await this.underlying.listCertificates(...args);
|
|
3476
3262
|
}
|
|
3477
3263
|
async proveCertificate(...args) {
|
|
3478
3264
|
const [requestArgs, originator] = args;
|
|
@@ -3485,21 +3271,21 @@ class WalletPermissionsManager {
|
|
|
3485
3271
|
reason: 'proveCertificate',
|
|
3486
3272
|
usageType: 'disclosure'
|
|
3487
3273
|
});
|
|
3488
|
-
return this.underlying.proveCertificate(...args);
|
|
3274
|
+
return await this.underlying.proveCertificate(...args);
|
|
3489
3275
|
}
|
|
3490
3276
|
async relinquishCertificate(...args) {
|
|
3491
3277
|
const [requestArgs, originator] = args;
|
|
3492
3278
|
if (this.config.seekCertificateRelinquishmentPermissions) {
|
|
3493
3279
|
await this.ensureProtocolPermission({
|
|
3494
3280
|
originator: originator,
|
|
3495
|
-
privileged: requestArgs.privileged
|
|
3281
|
+
privileged: !!requestArgs.privileged,
|
|
3496
3282
|
protocolID: [1, `certificate relinquishment ${requestArgs.type}`],
|
|
3497
3283
|
counterparty: 'self',
|
|
3498
3284
|
reason: requestArgs.privilegedReason || 'relinquishCertificate',
|
|
3499
3285
|
usageType: 'generic'
|
|
3500
3286
|
});
|
|
3501
3287
|
}
|
|
3502
|
-
return this.underlying.relinquishCertificate(...args);
|
|
3288
|
+
return await this.underlying.relinquishCertificate(...args);
|
|
3503
3289
|
}
|
|
3504
3290
|
async discoverByIdentityKey(...args) {
|
|
3505
3291
|
const [_, originator] = args;
|
|
@@ -3507,13 +3293,13 @@ class WalletPermissionsManager {
|
|
|
3507
3293
|
await this.ensureProtocolPermission({
|
|
3508
3294
|
originator: originator,
|
|
3509
3295
|
privileged: false,
|
|
3510
|
-
protocolID: [1,
|
|
3296
|
+
protocolID: [1, 'identity resolution'],
|
|
3511
3297
|
counterparty: 'self',
|
|
3512
3298
|
reason: 'discoverByIdentityKey',
|
|
3513
3299
|
usageType: 'generic'
|
|
3514
3300
|
});
|
|
3515
3301
|
}
|
|
3516
|
-
return this.underlying.discoverByIdentityKey(...args);
|
|
3302
|
+
return await this.underlying.discoverByIdentityKey(...args);
|
|
3517
3303
|
}
|
|
3518
3304
|
async discoverByAttributes(...args) {
|
|
3519
3305
|
const [_, originator] = args;
|
|
@@ -3521,26 +3307,26 @@ class WalletPermissionsManager {
|
|
|
3521
3307
|
await this.ensureProtocolPermission({
|
|
3522
3308
|
originator: originator,
|
|
3523
3309
|
privileged: false,
|
|
3524
|
-
protocolID: [1,
|
|
3310
|
+
protocolID: [1, 'identity resolution'],
|
|
3525
3311
|
counterparty: 'self',
|
|
3526
3312
|
reason: 'discoverByAttributes',
|
|
3527
3313
|
usageType: 'generic'
|
|
3528
3314
|
});
|
|
3529
3315
|
}
|
|
3530
|
-
return this.underlying.discoverByAttributes(...args);
|
|
3316
|
+
return await this.underlying.discoverByAttributes(...args);
|
|
3531
3317
|
}
|
|
3532
3318
|
async isAuthenticated(...args) {
|
|
3533
|
-
return this.underlying.isAuthenticated(...args);
|
|
3319
|
+
return await this.underlying.isAuthenticated(...args);
|
|
3534
3320
|
}
|
|
3535
3321
|
async waitForAuthentication(...args) {
|
|
3536
|
-
|
|
3322
|
+
const [_, originator] = args;
|
|
3537
3323
|
if (this.config.seekGroupedPermission && originator) {
|
|
3538
3324
|
const { normalized: normalizedOriginator } = this.prepareOriginator(originator);
|
|
3539
3325
|
const normalized = normalizedOriginator;
|
|
3540
3326
|
await this.withGroupedPermissionFlowLock(normalized, async () => {
|
|
3541
3327
|
// 1. Fetch manifest.json from the originator
|
|
3542
3328
|
const groupPermissions = await this.fetchManifestGroupPermissions(normalized);
|
|
3543
|
-
if (groupPermissions) {
|
|
3329
|
+
if (groupPermissions != null) {
|
|
3544
3330
|
// 2. Filter out already-granted permissions
|
|
3545
3331
|
const permissionsToRequest = await this.filterAlreadyGrantedPermissions(normalized, groupPermissions);
|
|
3546
3332
|
// 3. If any permissions are left to request, start the flow
|
|
@@ -3573,19 +3359,19 @@ class WalletPermissionsManager {
|
|
|
3573
3359
|
});
|
|
3574
3360
|
}
|
|
3575
3361
|
// Finally, after handling grouped permissions, call the underlying method.
|
|
3576
|
-
return this.underlying.waitForAuthentication(...args);
|
|
3362
|
+
return await this.underlying.waitForAuthentication(...args);
|
|
3577
3363
|
}
|
|
3578
3364
|
async getHeight(...args) {
|
|
3579
|
-
return this.underlying.getHeight(...args);
|
|
3365
|
+
return await this.underlying.getHeight(...args);
|
|
3580
3366
|
}
|
|
3581
3367
|
async getHeaderForHeight(...args) {
|
|
3582
|
-
return this.underlying.getHeaderForHeight(...args);
|
|
3368
|
+
return await this.underlying.getHeaderForHeight(...args);
|
|
3583
3369
|
}
|
|
3584
3370
|
async getNetwork(...args) {
|
|
3585
|
-
return this.underlying.getNetwork(...args);
|
|
3371
|
+
return await this.underlying.getNetwork(...args);
|
|
3586
3372
|
}
|
|
3587
3373
|
async getVersion(...args) {
|
|
3588
|
-
return this.underlying.getVersion(...args);
|
|
3374
|
+
return await this.underlying.getVersion(...args);
|
|
3589
3375
|
}
|
|
3590
3376
|
/* ---------------------------------------------------------------------
|
|
3591
3377
|
* 8) INTERNAL HELPER UTILITIES
|
|
@@ -3646,7 +3432,7 @@ class WalletPermissionsManager {
|
|
|
3646
3432
|
*/
|
|
3647
3433
|
isPermissionCached(key) {
|
|
3648
3434
|
const entry = this.permissionCache.get(key);
|
|
3649
|
-
if (
|
|
3435
|
+
if (entry == null)
|
|
3650
3436
|
return false;
|
|
3651
3437
|
if (Date.now() - entry.cachedAt > WalletPermissionsManager.CACHE_TTL_MS) {
|
|
3652
3438
|
this.permissionCache.delete(key);
|
|
@@ -3715,7 +3501,7 @@ class WalletPermissionsManager {
|
|
|
3715
3501
|
isWhitelistedCounterpartyProtocol(counterparty, protocolID) {
|
|
3716
3502
|
var _a;
|
|
3717
3503
|
const whitelist = this.config.whitelistedCounterparties;
|
|
3718
|
-
if (
|
|
3504
|
+
if (whitelist == null)
|
|
3719
3505
|
return false;
|
|
3720
3506
|
if (!counterparty || counterparty === 'self' || counterparty === 'anyone')
|
|
3721
3507
|
return false;
|