@bsv/wallet-toolbox 2.4.3 → 2.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -1
- package/LICENSE.txt +58 -0
- package/README.md +98 -36
- package/docs/README.md +3 -1
- package/docs/action-batch-planning.md +220 -0
- package/docs/authentication-observability.md +94 -0
- package/docs/client.md +1125 -2776
- package/docs/monitor.md +29 -111
- package/docs/services.md +296 -602
- package/docs/setup.md +48 -28
- package/docs/storage.md +329 -1692
- package/docs/wallet.md +9718 -4890
- package/out/src/CWIStyleWalletManager.d.ts +62 -6
- package/out/src/CWIStyleWalletManager.d.ts.map +1 -1
- package/out/src/CWIStyleWalletManager.js +584 -181
- package/out/src/CWIStyleWalletManager.js.map +1 -1
- package/out/src/Setup.d.ts +7 -0
- package/out/src/Setup.d.ts.map +1 -1
- package/out/src/Setup.js +10 -11
- package/out/src/Setup.js.map +1 -1
- package/out/src/SetupClient.d.ts +2 -0
- package/out/src/SetupClient.d.ts.map +1 -1
- package/out/src/SetupClient.js +8 -9
- package/out/src/SetupClient.js.map +1 -1
- package/out/src/SetupWallet.d.ts +6 -0
- package/out/src/SetupWallet.d.ts.map +1 -1
- package/out/src/ShamirWalletManager.d.ts.map +1 -1
- package/out/src/ShamirWalletManager.js.map +1 -1
- package/out/src/SimpleWalletManager.d.ts.map +1 -1
- package/out/src/SimpleWalletManager.js +2 -5
- package/out/src/SimpleWalletManager.js.map +1 -1
- package/out/src/Wallet.d.ts +36 -10
- package/out/src/Wallet.d.ts.map +1 -1
- package/out/src/Wallet.js +167 -132
- package/out/src/Wallet.js.map +1 -1
- package/out/src/WalletAuthenticationManager.d.ts +30 -6
- package/out/src/WalletAuthenticationManager.d.ts.map +1 -1
- package/out/src/WalletAuthenticationManager.js +215 -34
- package/out/src/WalletAuthenticationManager.js.map +1 -1
- package/out/src/WalletLogger.d.ts.map +1 -1
- package/out/src/WalletLogger.js +33 -30
- package/out/src/WalletLogger.js.map +1 -1
- package/out/src/WalletPermissionsManager.d.ts +22 -1
- package/out/src/WalletPermissionsManager.d.ts.map +1 -1
- package/out/src/WalletPermissionsManager.js +392 -267
- package/out/src/WalletPermissionsManager.js.map +1 -1
- package/out/src/WalletSettingsManager.d.ts.map +1 -1
- package/out/src/WalletSettingsManager.js.map +1 -1
- package/out/src/entropy/EntropyCollector.d.ts.map +1 -1
- package/out/src/entropy/EntropyCollector.js +6 -8
- package/out/src/entropy/EntropyCollector.js.map +1 -1
- package/out/src/fundWalletP2PKH.js.map +1 -1
- package/out/src/index.all.d.ts +1 -0
- package/out/src/index.all.d.ts.map +1 -1
- package/out/src/index.all.js +1 -0
- package/out/src/index.all.js.map +1 -1
- package/out/src/index.client.d.ts +2 -0
- package/out/src/index.client.d.ts.map +1 -1
- package/out/src/index.client.js +2 -0
- package/out/src/index.client.js.map +1 -1
- package/out/src/index.mobile.d.ts +2 -0
- package/out/src/index.mobile.d.ts.map +1 -1
- package/out/src/index.mobile.js +2 -0
- package/out/src/index.mobile.js.map +1 -1
- 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.map +1 -1
- package/out/src/mockchain/MockChainTracker.d.ts.map +1 -1
- 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.map +1 -1
- package/out/src/mockchain/MockServices.d.ts +4 -0
- package/out/src/mockchain/MockServices.d.ts.map +1 -1
- package/out/src/mockchain/MockServices.js +69 -74
- 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 +51 -56
- package/out/src/mockchain/merkleTree.js.map +1 -1
- package/out/src/monitor/Monitor.d.ts +4 -0
- package/out/src/monitor/Monitor.d.ts.map +1 -1
- package/out/src/monitor/Monitor.js +60 -57
- package/out/src/monitor/Monitor.js.map +1 -1
- package/out/src/monitor/MonitorDaemon.d.ts +3 -0
- package/out/src/monitor/MonitorDaemon.d.ts.map +1 -1
- package/out/src/monitor/MonitorDaemon.js +65 -56
- package/out/src/monitor/MonitorDaemon.js.map +1 -1
- package/out/src/monitor/index.all.js.map +1 -1
- package/out/src/monitor/tasks/TaskArcSSE.d.ts +5 -0
- package/out/src/monitor/tasks/TaskArcSSE.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskArcSSE.js +86 -77
- package/out/src/monitor/tasks/TaskArcSSE.js.map +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.d.ts +4 -2
- package/out/src/monitor/tasks/TaskCheckForProofs.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.js +132 -131
- package/out/src/monitor/tasks/TaskCheckForProofs.js.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.d.ts +3 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.js +3 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -1
- package/out/src/monitor/tasks/TaskCleanupActionBatches.d.ts +13 -0
- package/out/src/monitor/tasks/TaskCleanupActionBatches.d.ts.map +1 -0
- package/out/src/monitor/tasks/TaskCleanupActionBatches.js +24 -0
- package/out/src/monitor/tasks/TaskCleanupActionBatches.js.map +1 -0
- package/out/src/monitor/tasks/TaskClock.d.ts +1 -1
- package/out/src/monitor/tasks/TaskClock.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskClock.js +1 -1
- package/out/src/monitor/tasks/TaskClock.js.map +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 +3 -1
- package/out/src/monitor/tasks/TaskMineBlock.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskMineBlock.js +3 -1
- package/out/src/monitor/tasks/TaskMineBlock.js.map +1 -1
- package/out/src/monitor/tasks/TaskMonitorCallHistory.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskMonitorCallHistory.js.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.d.ts +4 -3
- package/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.js +4 -3
- package/out/src/monitor/tasks/TaskNewHeader.js.map +1 -1
- package/out/src/monitor/tasks/TaskPurge.d.ts +3 -1
- package/out/src/monitor/tasks/TaskPurge.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskPurge.js +3 -1
- package/out/src/monitor/tasks/TaskPurge.js.map +1 -1
- package/out/src/monitor/tasks/TaskReorg.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReorg.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.d.ts +3 -1
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.js +3 -1
- package/out/src/monitor/tasks/TaskReviewDoubleSpends.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewProvenTxs.d.ts +3 -1
- package/out/src/monitor/tasks/TaskReviewProvenTxs.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewProvenTxs.js +3 -1
- package/out/src/monitor/tasks/TaskReviewProvenTxs.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewStatus.d.ts +3 -1
- package/out/src/monitor/tasks/TaskReviewStatus.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewStatus.js +3 -1
- package/out/src/monitor/tasks/TaskReviewStatus.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.d.ts +3 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.js +3 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.js.map +1 -1
- package/out/src/monitor/tasks/TaskSendWaiting.d.ts +3 -0
- package/out/src/monitor/tasks/TaskSendWaiting.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskSendWaiting.js +53 -46
- package/out/src/monitor/tasks/TaskSendWaiting.js.map +1 -1
- package/out/src/monitor/tasks/TaskSyncWhenIdle.d.ts +1 -1
- package/out/src/monitor/tasks/TaskSyncWhenIdle.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskSyncWhenIdle.js +1 -1
- package/out/src/monitor/tasks/TaskSyncWhenIdle.js.map +1 -1
- package/out/src/monitor/tasks/TaskUnFail.d.ts +3 -1
- package/out/src/monitor/tasks/TaskUnFail.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskUnFail.js +3 -1
- 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.map +1 -1
- package/out/src/monitor/tasks/index.all.d.ts +1 -0
- package/out/src/monitor/tasks/index.all.d.ts.map +1 -1
- package/out/src/monitor/tasks/index.all.js +1 -0
- package/out/src/monitor/tasks/index.all.js.map +1 -1
- package/out/src/sdk/ActionBatch.interfaces.d.ts +159 -0
- package/out/src/sdk/ActionBatch.interfaces.d.ts.map +1 -0
- package/out/src/sdk/ActionBatch.interfaces.js +3 -0
- package/out/src/sdk/ActionBatch.interfaces.js.map +1 -0
- package/out/src/sdk/PrivilegedKeyManager.d.ts.map +1 -1
- package/out/src/sdk/PrivilegedKeyManager.js +3 -3
- package/out/src/sdk/PrivilegedKeyManager.js.map +1 -1
- package/out/src/sdk/WERR_errors.d.ts +1 -1
- package/out/src/sdk/WERR_errors.d.ts.map +1 -1
- package/out/src/sdk/WERR_errors.js +2 -2
- package/out/src/sdk/WERR_errors.js.map +1 -1
- package/out/src/sdk/WalletError.d.ts +3 -0
- package/out/src/sdk/WalletError.d.ts.map +1 -1
- package/out/src/sdk/WalletError.js +53 -56
- package/out/src/sdk/WalletError.js.map +1 -1
- package/out/src/sdk/WalletErrorFromJson.js.map +1 -1
- package/out/src/sdk/WalletServices.interfaces.d.ts +3 -1
- package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
- package/out/src/sdk/WalletStorage.interfaces.d.ts +22 -1
- package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
- package/out/src/sdk/index.d.ts +1 -0
- package/out/src/sdk/index.d.ts.map +1 -1
- package/out/src/sdk/index.js +1 -0
- package/out/src/sdk/index.js.map +1 -1
- package/out/src/sdk/types.js.map +1 -1
- package/out/src/services/ServiceCollection.d.ts.map +1 -1
- package/out/src/services/ServiceCollection.js.map +1 -1
- package/out/src/services/Services.d.ts +8 -2
- package/out/src/services/Services.d.ts.map +1 -1
- package/out/src/services/Services.js +86 -44
- package/out/src/services/Services.js.map +1 -1
- package/out/src/services/chaintracker/BHServiceClient.d.ts +7 -7
- package/out/src/services/chaintracker/BHServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/BHServiceClient.js +9 -9
- package/out/src/services/chaintracker/BHServiceClient.js.map +1 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.d.ts +4 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.d.ts.map +1 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.js +42 -6
- package/out/src/services/chaintracker/ChaintracksChainTracker.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts +4 -4
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.js +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts +3 -0
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js +45 -40
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.d.ts +5 -0
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.js +25 -18
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts +3 -3
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js +6 -7
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.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.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDN.d.ts.map +1 -1
- 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 +0 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainWs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainWs.js.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.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.d.ts +2 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.js +2 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.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.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainWs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainWs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.d.ts +12 -2
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.js +110 -103
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.d.ts +8 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.js +58 -48
- 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.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksKnexMigrations.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksKnexMigrations.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.d.ts +3 -0
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.js +55 -54
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.d.ts +4 -0
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js +97 -72
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.d.ts +5 -0
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.js +145 -136
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.d.ts +4 -0
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.js +92 -68
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/configureChaintracksIngestors.d.ts +43 -0
- package/out/src/services/chaintracker/chaintracks/configureChaintracksIngestors.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/configureChaintracksIngestors.js +76 -0
- package/out/src/services/chaintracker/chaintracks/configureChaintracksIngestors.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/configureKnexChaintracks.d.ts +18 -0
- package/out/src/services/chaintracker/chaintracks/configureKnexChaintracks.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/configureKnexChaintracks.js +24 -0
- package/out/src/services/chaintracker/chaintracks/configureKnexChaintracks.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.d.ts +2 -3
- package/out/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.js +4 -22
- package/out/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.d.ts +2 -4
- package/out/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.js +12 -25
- package/out/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.d.ts +2 -3
- package/out/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.js +4 -22
- package/out/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createIdbChaintracks.d.ts +2 -1
- package/out/src/services/chaintracker/chaintracks/createIdbChaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createIdbChaintracks.js +3 -15
- package/out/src/services/chaintracker/chaintracks/createIdbChaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createKnexChaintracks.d.ts +2 -2
- package/out/src/services/chaintracker/chaintracks/createKnexChaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createKnexChaintracks.js +3 -15
- package/out/src/services/chaintracker/chaintracks/createKnexChaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createNoDbChaintracks.d.ts +2 -1
- package/out/src/services/chaintracker/chaintracks/createNoDbChaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/createNoDbChaintracks.js +3 -15
- package/out/src/services/chaintracker/chaintracks/createNoDbChaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/index.mobile.d.ts +1 -1
- package/out/src/services/chaintracker/chaintracks/index.mobile.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/index.mobile.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts +2 -0
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js +64 -61
- 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.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 +4 -3
- package/out/src/services/chaintracker/chaintracks/util/BulkFilesReader.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkHeaderFile.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkHeaderFile.js.map +1 -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/ChaintracksFs.d.ts +8 -10
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.js +14 -24
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/HeightRange.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/HeightRange.js.map +1 -1
- 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 -11
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js +20 -49
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js +4 -2
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.js.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.d.ts +23 -14
- package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.js +1 -14
- package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/out/src/services/networkConfig.js.map +1 -1
- package/out/src/services/providers/ARC.d.ts +4 -0
- package/out/src/services/providers/ARC.d.ts.map +1 -1
- package/out/src/services/providers/ARC.js +96 -83
- 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.map +1 -1
- package/out/src/services/providers/Arcade.d.ts +4 -0
- package/out/src/services/providers/Arcade.d.ts.map +1 -1
- package/out/src/services/providers/Arcade.js +118 -92
- package/out/src/services/providers/Arcade.js.map +1 -1
- package/out/src/services/providers/Bitails.d.ts.map +1 -1
- package/out/src/services/providers/Bitails.js +107 -86
- 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.map +1 -1
- package/out/src/services/providers/WhatsOnChain.js +19 -6
- package/out/src/services/providers/WhatsOnChain.js.map +1 -1
- package/out/src/services/providers/exchangeRates.js +1 -1
- package/out/src/services/providers/exchangeRates.js.map +1 -1
- package/out/src/services/providers/getBeefForTxid.js.map +1 -1
- package/out/src/services/providers/whatsOnChainHelpers.js.map +1 -1
- package/out/src/signer/WalletSigner.d.ts.map +1 -1
- package/out/src/signer/WalletSigner.js.map +1 -1
- package/out/src/signer/actionBatch/ActionBatchPlanner.d.ts +29 -0
- package/out/src/signer/actionBatch/ActionBatchPlanner.d.ts.map +1 -0
- package/out/src/signer/actionBatch/ActionBatchPlanner.js +346 -0
- package/out/src/signer/actionBatch/ActionBatchPlanner.js.map +1 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.d.ts +33 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.d.ts.map +1 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.js +869 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.js.map +1 -0
- package/out/src/signer/actionBatch/actionBatchBootstrap.d.ts +11 -0
- package/out/src/signer/actionBatch/actionBatchBootstrap.d.ts.map +1 -0
- package/out/src/signer/actionBatch/actionBatchBootstrap.js +38 -0
- package/out/src/signer/actionBatch/actionBatchBootstrap.js.map +1 -0
- package/out/src/signer/methods/acquireDirectCertificate.js.map +1 -1
- package/out/src/signer/methods/buildSignableTransaction.d.ts.map +1 -1
- package/out/src/signer/methods/buildSignableTransaction.js +97 -107
- package/out/src/signer/methods/buildSignableTransaction.js.map +1 -1
- package/out/src/signer/methods/completeSignedTransaction.d.ts +3 -7
- package/out/src/signer/methods/completeSignedTransaction.d.ts.map +1 -1
- package/out/src/signer/methods/completeSignedTransaction.js +14 -57
- 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 +50 -20
- 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 +4 -4
- package/out/src/signer/methods/internalizeAction.js.map +1 -1
- package/out/src/signer/methods/proveCertificate.js.map +1 -1
- package/out/src/signer/methods/resultBeef.js.map +1 -1
- package/out/src/signer/methods/signAction.d.ts.map +1 -1
- package/out/src/signer/methods/signAction.js +29 -4
- package/out/src/signer/methods/signAction.js.map +1 -1
- package/out/src/signer/methods/verifyUnlockScripts.d.ts +17 -0
- package/out/src/signer/methods/verifyUnlockScripts.d.ts.map +1 -0
- package/out/src/signer/methods/verifyUnlockScripts.js +137 -0
- package/out/src/signer/methods/verifyUnlockScripts.js.map +1 -0
- package/out/src/storage/StorageIdb.d.ts +19 -3
- package/out/src/storage/StorageIdb.d.ts.map +1 -1
- package/out/src/storage/StorageIdb.js +232 -53
- package/out/src/storage/StorageIdb.js.map +1 -1
- package/out/src/storage/StorageKnex.d.ts +29 -1
- package/out/src/storage/StorageKnex.d.ts.map +1 -1
- package/out/src/storage/StorageKnex.js +225 -10
- package/out/src/storage/StorageKnex.js.map +1 -1
- package/out/src/storage/StorageProvider.d.ts +57 -1
- package/out/src/storage/StorageProvider.d.ts.map +1 -1
- package/out/src/storage/StorageProvider.js +277 -145
- package/out/src/storage/StorageProvider.js.map +1 -1
- package/out/src/storage/StorageReader.d.ts +13 -5
- package/out/src/storage/StorageReader.d.ts.map +1 -1
- package/out/src/storage/StorageReader.js +3 -0
- package/out/src/storage/StorageReader.js.map +1 -1
- package/out/src/storage/StorageReaderWriter.d.ts.map +1 -1
- 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.map +1 -1
- package/out/src/storage/WalletStorageManager.d.ts +10 -0
- package/out/src/storage/WalletStorageManager.d.ts.map +1 -1
- package/out/src/storage/WalletStorageManager.js +49 -6
- package/out/src/storage/WalletStorageManager.js.map +1 -1
- package/out/src/storage/adminServer/adminServer.d.ts +79 -0
- package/out/src/storage/adminServer/adminServer.d.ts.map +1 -1
- package/out/src/storage/adminServer/adminServer.js +47 -16
- package/out/src/storage/adminServer/adminServer.js.map +1 -1
- package/out/src/storage/adminServer/adminUi.js.map +1 -1
- package/out/src/storage/idbHelpers.d.ts +2 -0
- package/out/src/storage/idbHelpers.d.ts.map +1 -1
- package/out/src/storage/idbHelpers.js +19 -0
- package/out/src/storage/idbHelpers.js.map +1 -1
- package/out/src/storage/index.all.js.map +1 -1
- package/out/src/storage/methods/ListActionsSpecOp.d.ts.map +1 -1
- package/out/src/storage/methods/ListActionsSpecOp.js +48 -71
- 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 +29 -27
- package/out/src/storage/methods/ListOutputsSpecOp.js.map +1 -1
- package/out/src/storage/methods/actionBatch.d.ts +15 -0
- package/out/src/storage/methods/actionBatch.d.ts.map +1 -0
- package/out/src/storage/methods/actionBatch.js +737 -0
- package/out/src/storage/methods/actionBatch.js.map +1 -0
- package/out/src/storage/methods/actionBatchBlobs.d.ts +15 -0
- package/out/src/storage/methods/actionBatchBlobs.d.ts.map +1 -0
- package/out/src/storage/methods/actionBatchBlobs.js +184 -0
- package/out/src/storage/methods/actionBatchBlobs.js.map +1 -0
- package/out/src/storage/methods/actionBatchValidation.d.ts +17 -0
- package/out/src/storage/methods/actionBatchValidation.d.ts.map +1 -0
- package/out/src/storage/methods/actionBatchValidation.js +416 -0
- package/out/src/storage/methods/actionBatchValidation.js.map +1 -0
- package/out/src/storage/methods/actionPlanning.d.ts +12 -0
- package/out/src/storage/methods/actionPlanning.d.ts.map +1 -0
- package/out/src/storage/methods/actionPlanning.js +48 -0
- package/out/src/storage/methods/actionPlanning.js.map +1 -0
- package/out/src/storage/methods/attemptToPostReqsToNetwork.d.ts +0 -21
- package/out/src/storage/methods/attemptToPostReqsToNetwork.d.ts.map +1 -1
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js +43 -51
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js.map +1 -1
- package/out/src/storage/methods/createAction.d.ts +1 -1
- package/out/src/storage/methods/createAction.d.ts.map +1 -1
- package/out/src/storage/methods/createAction.js +66 -63
- package/out/src/storage/methods/createAction.js.map +1 -1
- package/out/src/storage/methods/generateChange.d.ts +2 -2
- package/out/src/storage/methods/generateChange.d.ts.map +1 -1
- package/out/src/storage/methods/generateChange.js +66 -38
- package/out/src/storage/methods/generateChange.js.map +1 -1
- package/out/src/storage/methods/getBeefForTransaction.d.ts.map +1 -1
- package/out/src/storage/methods/getBeefForTransaction.js +48 -42
- 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 +8 -6
- package/out/src/storage/methods/getSyncChunk.js.map +1 -1
- package/out/src/storage/methods/internalizeAction.js +145 -121
- package/out/src/storage/methods/internalizeAction.js.map +1 -1
- package/out/src/storage/methods/listActionsIdb.js.map +1 -1
- package/out/src/storage/methods/listActionsKnex.js +1 -1
- package/out/src/storage/methods/listActionsKnex.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 +1 -1
- package/out/src/storage/methods/listCertificates.js.map +1 -1
- package/out/src/storage/methods/listOutputsIdb.d.ts +1 -1
- package/out/src/storage/methods/listOutputsIdb.d.ts.map +1 -1
- package/out/src/storage/methods/listOutputsIdb.js +133 -152
- package/out/src/storage/methods/listOutputsIdb.js.map +1 -1
- package/out/src/storage/methods/listOutputsKnex.d.ts +1 -1
- package/out/src/storage/methods/listOutputsKnex.d.ts.map +1 -1
- package/out/src/storage/methods/listOutputsKnex.js +213 -254
- package/out/src/storage/methods/listOutputsKnex.js.map +1 -1
- package/out/src/storage/methods/managedChange.d.ts +3 -3
- package/out/src/storage/methods/managedChange.d.ts.map +1 -1
- package/out/src/storage/methods/managedChange.js +1 -2
- package/out/src/storage/methods/managedChange.js.map +1 -1
- package/out/src/storage/methods/offsetKey.d.ts.map +1 -1
- package/out/src/storage/methods/offsetKey.js +0 -1
- package/out/src/storage/methods/offsetKey.js.map +1 -1
- package/out/src/storage/methods/processAction.d.ts +2 -0
- package/out/src/storage/methods/processAction.d.ts.map +1 -1
- package/out/src/storage/methods/processAction.js +8 -8
- package/out/src/storage/methods/processAction.js.map +1 -1
- package/out/src/storage/methods/purgeData.d.ts.map +1 -1
- package/out/src/storage/methods/purgeData.js +157 -179
- package/out/src/storage/methods/purgeData.js.map +1 -1
- package/out/src/storage/methods/purgeDataIdb.d.ts +1 -1
- package/out/src/storage/methods/purgeDataIdb.d.ts.map +1 -1
- package/out/src/storage/methods/purgeDataIdb.js +1 -1
- package/out/src/storage/methods/purgeDataIdb.js.map +1 -1
- package/out/src/storage/methods/reviewStatus.js +6 -6
- package/out/src/storage/methods/reviewStatus.js.map +1 -1
- package/out/src/storage/methods/reviewStatusIdb.js.map +1 -1
- package/out/src/storage/methods/utils.Buffer.js.map +1 -1
- package/out/src/storage/methods/utils.js.map +1 -1
- package/out/src/storage/portable/index.js +2 -2
- package/out/src/storage/portable/index.js.map +1 -1
- package/out/src/storage/remoting/BinaryJson.d.ts.map +1 -1
- package/out/src/storage/remoting/BinaryJson.js +84 -38
- package/out/src/storage/remoting/BinaryJson.js.map +1 -1
- package/out/src/storage/remoting/KnexSessionManager.d.ts.map +1 -1
- package/out/src/storage/remoting/KnexSessionManager.js.map +1 -1
- package/out/src/storage/remoting/RateLimitPolicy.d.ts +10 -0
- package/out/src/storage/remoting/RateLimitPolicy.d.ts.map +1 -0
- package/out/src/storage/remoting/RateLimitPolicy.js +37 -0
- package/out/src/storage/remoting/RateLimitPolicy.js.map +1 -0
- package/out/src/storage/remoting/StorageClient.d.ts +2 -0
- package/out/src/storage/remoting/StorageClient.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageClient.js +82 -50
- package/out/src/storage/remoting/StorageClient.js.map +1 -1
- package/out/src/storage/remoting/StorageClientBase.d.ts +23 -4
- package/out/src/storage/remoting/StorageClientBase.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageClientBase.js +97 -4
- package/out/src/storage/remoting/StorageClientBase.js.map +1 -1
- package/out/src/storage/remoting/StorageMobile.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageMobile.js +34 -22
- package/out/src/storage/remoting/StorageMobile.js.map +1 -1
- package/out/src/storage/remoting/StorageServer.d.ts +62 -1
- package/out/src/storage/remoting/StorageServer.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageServer.js +451 -172
- package/out/src/storage/remoting/StorageServer.js.map +1 -1
- package/out/src/storage/remoting/edgePolicy.d.ts +57 -0
- package/out/src/storage/remoting/edgePolicy.d.ts.map +1 -0
- package/out/src/storage/remoting/edgePolicy.js +387 -0
- package/out/src/storage/remoting/edgePolicy.js.map +1 -0
- package/out/src/storage/remoting/entityValidationHelpers.d.ts.map +1 -1
- package/out/src/storage/remoting/entityValidationHelpers.js +22 -5
- package/out/src/storage/remoting/entityValidationHelpers.js.map +1 -1
- package/out/src/storage/schema/KnexMigrations.d.ts.map +1 -1
- package/out/src/storage/schema/KnexMigrations.js +56 -0
- package/out/src/storage/schema/KnexMigrations.js.map +1 -1
- package/out/src/storage/schema/StorageIdbSchema.d.ts +24 -0
- 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.map +1 -1
- package/out/src/storage/schema/entities/EntityCertificateField.d.ts.map +1 -1
- 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.map +1 -1
- package/out/src/storage/schema/entities/EntityOutput.d.ts.map +1 -1
- 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.map +1 -1
- package/out/src/storage/schema/entities/EntityOutputTag.d.ts.map +1 -1
- 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.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTx.d.ts +3 -0
- package/out/src/storage/schema/entities/EntityProvenTx.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTx.js +46 -36
- package/out/src/storage/schema/entities/EntityProvenTx.js.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTxReq.d.ts +2 -2
- package/out/src/storage/schema/entities/EntityProvenTxReq.d.ts.map +1 -1
- package/out/src/storage/schema/entities/EntityProvenTxReq.js +12 -10
- 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 +25 -34
- 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.map +1 -1
- package/out/src/storage/schema/entities/EntityTxLabel.d.ts.map +1 -1
- 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.map +1 -1
- package/out/src/storage/schema/entities/EntityUser.d.ts.map +1 -1
- 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 +9 -14
- package/out/src/storage/schema/entities/MergeEntity.js.map +1 -1
- package/out/src/storage/schema/tables/TableActionBatch.d.ts +26 -0
- package/out/src/storage/schema/tables/TableActionBatch.d.ts.map +1 -0
- package/out/src/storage/schema/tables/TableActionBatch.js +3 -0
- package/out/src/storage/schema/tables/TableActionBatch.js.map +1 -0
- package/out/src/storage/schema/tables/TableAuthSession.js.map +1 -1
- package/out/src/storage/schema/tables/index.d.ts +1 -0
- package/out/src/storage/schema/tables/index.d.ts.map +1 -1
- package/out/src/storage/schema/tables/index.js +1 -0
- package/out/src/storage/schema/tables/index.js.map +1 -1
- package/out/src/storage/storageProviderHelpers.js.map +1 -1
- package/out/src/storage/sync/StorageMySQLDojoReader.d.ts +3 -0
- package/out/src/storage/sync/StorageMySQLDojoReader.d.ts.map +1 -1
- package/out/src/storage/sync/StorageMySQLDojoReader.js +30 -16
- package/out/src/storage/sync/StorageMySQLDojoReader.js.map +1 -1
- package/out/src/utility/Format.d.ts.map +1 -1
- package/out/src/utility/Format.js +2 -2
- package/out/src/utility/Format.js.map +1 -1
- package/out/src/utility/ScriptTemplateBRC29.d.ts.map +1 -1
- package/out/src/utility/ScriptTemplateBRC29.js.map +1 -1
- package/out/src/utility/actionBatchDigest.d.ts +9 -0
- package/out/src/utility/actionBatchDigest.d.ts.map +1 -0
- package/out/src/utility/actionBatchDigest.js +86 -0
- package/out/src/utility/actionBatchDigest.js.map +1 -0
- package/out/src/utility/actionBatchPack.d.ts +16 -0
- package/out/src/utility/actionBatchPack.d.ts.map +1 -0
- package/out/src/utility/actionBatchPack.js +220 -0
- package/out/src/utility/actionBatchPack.js.map +1 -0
- package/out/src/utility/aggregateResults.d.ts.map +1 -1
- package/out/src/utility/aggregateResults.js.map +1 -1
- package/out/src/utility/beefForTxids.d.ts +9 -0
- package/out/src/utility/beefForTxids.d.ts.map +1 -0
- package/out/src/utility/beefForTxids.js +35 -0
- package/out/src/utility/beefForTxids.js.map +1 -0
- package/out/src/utility/brc114ActionTimeLabels.d.ts.map +1 -1
- package/out/src/utility/brc114ActionTimeLabels.js +26 -30
- package/out/src/utility/brc114ActionTimeLabels.js.map +1 -1
- package/out/src/utility/formatUnknown.d.ts +6 -0
- package/out/src/utility/formatUnknown.d.ts.map +1 -0
- package/out/src/utility/formatUnknown.js +39 -0
- package/out/src/utility/formatUnknown.js.map +1 -0
- package/out/src/utility/hashWasm.d.ts +5 -0
- package/out/src/utility/hashWasm.d.ts.map +1 -0
- package/out/src/utility/hashWasm.js +15 -0
- package/out/src/utility/hashWasm.js.map +1 -0
- package/out/src/utility/identityUtils.d.ts.map +1 -1
- package/out/src/utility/identityUtils.js +2 -4
- package/out/src/utility/identityUtils.js.map +1 -1
- package/out/src/utility/parseTxScriptOffsets.d.ts +1 -1
- package/out/src/utility/parseTxScriptOffsets.d.ts.map +1 -1
- package/out/src/utility/parseTxScriptOffsets.js +1 -1
- package/out/src/utility/parseTxScriptOffsets.js.map +1 -1
- package/out/src/utility/stampLog.d.ts.map +1 -1
- package/out/src/utility/stampLog.js +49 -42
- package/out/src/utility/stampLog.js.map +1 -1
- package/out/src/utility/traceContext.d.ts +13 -0
- package/out/src/utility/traceContext.d.ts.map +1 -0
- package/out/src/utility/traceContext.js +34 -0
- package/out/src/utility/traceContext.js.map +1 -0
- package/out/src/utility/tscProofToMerklePath.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.buffer.js.map +1 -1
- package/out/src/utility/utilityHelpers.d.ts +2 -2
- package/out/src/utility/utilityHelpers.d.ts.map +1 -1
- package/out/src/utility/utilityHelpers.js +8 -4
- package/out/src/utility/utilityHelpers.js.map +1 -1
- package/out/src/utility/utilityHelpers.noBuffer.d.ts.map +1 -1
- package/out/src/utility/utilityHelpers.noBuffer.js +1 -2
- package/out/src/utility/utilityHelpers.noBuffer.js.map +1 -1
- package/out/src/wab-client/WABClient.d.ts +36 -90
- package/out/src/wab-client/WABClient.d.ts.map +1 -1
- package/out/src/wab-client/WABClient.js +103 -151
- package/out/src/wab-client/WABClient.js.map +1 -1
- package/out/src/wab-client/WABTransport.d.ts +81 -0
- package/out/src/wab-client/WABTransport.d.ts.map +1 -0
- package/out/src/wab-client/WABTransport.js +420 -0
- package/out/src/wab-client/WABTransport.js.map +1 -0
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts +10 -10
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts.map +1 -1
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js +16 -21
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js.map +1 -1
- package/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.js.map +1 -1
- package/out/src/wab-client/auth-method-interactors/PersonaIDInteractor.js.map +1 -1
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts +2 -1
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts.map +1 -1
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js +14 -0
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js.map +1 -1
- package/package.json +66 -30
- package/license.md +0 -28
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CWIStyleWalletManager = exports.OverlayUMPTokenInteractor = exports.DEFAULT_PROFILE_ID = exports.ARGON2ID_DEFAULT_HASH_LENGTH = exports.ARGON2ID_DEFAULT_PARALLELISM = exports.ARGON2ID_DEFAULT_MEMORY_KIB = exports.ARGON2ID_DEFAULT_ITERATIONS = exports.PBKDF2_NUM_ROUNDS = void 0;
|
|
3
|
+
exports.CWIStyleWalletManager = exports.OverlayUMPTokenInteractor = exports.UMPTokenLookupError = exports.DEFAULT_PROFILE_ID = exports.MAX_STATE_SNAPSHOT_BYTES = exports.PBKDF2_MAX_ITERATIONS = exports.KDF_MAX_HASH_LENGTH = exports.ARGON2ID_MAX_PARALLELISM = exports.ARGON2ID_MAX_MEMORY_KIB = exports.ARGON2ID_MAX_ITERATIONS = exports.ARGON2ID_DEFAULT_HASH_LENGTH = exports.ARGON2ID_DEFAULT_PARALLELISM = exports.ARGON2ID_DEFAULT_MEMORY_KIB = exports.ARGON2ID_DEFAULT_ITERATIONS = exports.PBKDF2_NUM_ROUNDS = void 0;
|
|
4
4
|
const sdk_1 = require("@bsv/sdk");
|
|
5
|
-
const hash_wasm_1 = require("hash-wasm");
|
|
6
5
|
const PrivilegedKeyManager_1 = require("./sdk/PrivilegedKeyManager");
|
|
6
|
+
const hashWasm_1 = require("./utility/hashWasm");
|
|
7
7
|
/**
|
|
8
8
|
* Number of rounds used in PBKDF2 for deriving password keys.
|
|
9
9
|
*/
|
|
@@ -15,6 +15,72 @@ exports.ARGON2ID_DEFAULT_ITERATIONS = 7;
|
|
|
15
15
|
exports.ARGON2ID_DEFAULT_MEMORY_KIB = 131072;
|
|
16
16
|
exports.ARGON2ID_DEFAULT_PARALLELISM = 1;
|
|
17
17
|
exports.ARGON2ID_DEFAULT_HASH_LENGTH = 32;
|
|
18
|
+
exports.ARGON2ID_MAX_ITERATIONS = 20;
|
|
19
|
+
exports.ARGON2ID_MAX_MEMORY_KIB = 262144;
|
|
20
|
+
exports.ARGON2ID_MAX_PARALLELISM = 16;
|
|
21
|
+
exports.KDF_MAX_HASH_LENGTH = 64;
|
|
22
|
+
exports.PBKDF2_MAX_ITERATIONS = 10_000_000;
|
|
23
|
+
exports.MAX_STATE_SNAPSHOT_BYTES = 16 * 1024 * 1024;
|
|
24
|
+
function isPositiveIntegerInRange(value, maximum) {
|
|
25
|
+
return typeof value === 'number' && Number.isInteger(value) && value > 0 && value <= maximum;
|
|
26
|
+
}
|
|
27
|
+
function isValidKdfConfig(kdf) {
|
|
28
|
+
if (kdf == null)
|
|
29
|
+
return false;
|
|
30
|
+
if (!isPositiveIntegerInRange(kdf.iterations, kdf.algorithm === 'argon2id' ? exports.ARGON2ID_MAX_ITERATIONS : exports.PBKDF2_MAX_ITERATIONS)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
if (kdf.algorithm === 'pbkdf2-sha512') {
|
|
34
|
+
return kdf.hashLength === undefined || isPositiveIntegerInRange(kdf.hashLength, exports.KDF_MAX_HASH_LENGTH);
|
|
35
|
+
}
|
|
36
|
+
if (kdf.algorithm !== 'argon2id')
|
|
37
|
+
return false;
|
|
38
|
+
return (isPositiveIntegerInRange(kdf.memoryKiB, exports.ARGON2ID_MAX_MEMORY_KIB) &&
|
|
39
|
+
isPositiveIntegerInRange(kdf.parallelism, exports.ARGON2ID_MAX_PARALLELISM) &&
|
|
40
|
+
isPositiveIntegerInRange(kdf.hashLength, exports.KDF_MAX_HASH_LENGTH));
|
|
41
|
+
}
|
|
42
|
+
function findKdfVersionFieldIndex(protocolFields) {
|
|
43
|
+
const hasMetadataWithProfiles = protocolFields.length >= 15 &&
|
|
44
|
+
protocolFields[12]?.length === 1 &&
|
|
45
|
+
protocolFields[12][0] === 3;
|
|
46
|
+
if (hasMetadataWithProfiles)
|
|
47
|
+
return 12;
|
|
48
|
+
const hasMetadataWithoutProfiles = protocolFields.length >= 14 &&
|
|
49
|
+
protocolFields[11]?.length === 1 &&
|
|
50
|
+
protocolFields[11][0] === 3;
|
|
51
|
+
return hasMetadataWithoutProfiles ? 11 : -1;
|
|
52
|
+
}
|
|
53
|
+
function addProfilesField(token, protocolFields, kdfVersionFieldIndex) {
|
|
54
|
+
const hasProfilesField = kdfVersionFieldIndex === 12 || (kdfVersionFieldIndex !== 11 && protocolFields[11] != null);
|
|
55
|
+
if (!hasProfilesField || protocolFields[11].length === 0)
|
|
56
|
+
return true;
|
|
57
|
+
if (protocolFields[11].length > exports.MAX_STATE_SNAPSHOT_BYTES)
|
|
58
|
+
return false;
|
|
59
|
+
token.profilesEncrypted = protocolFields[11];
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
function addPasswordKdf(token, protocolFields, kdfVersionFieldIndex) {
|
|
63
|
+
if (kdfVersionFieldIndex === -1)
|
|
64
|
+
return true;
|
|
65
|
+
const kdfAlgorithmField = protocolFields[kdfVersionFieldIndex + 1];
|
|
66
|
+
const kdfParamsField = protocolFields[kdfVersionFieldIndex + 2];
|
|
67
|
+
if (kdfAlgorithmField == null || kdfParamsField == null || kdfParamsField.length > 1024) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const kdfParams = JSON.parse(sdk_1.Utils.toUTF8(kdfParamsField));
|
|
71
|
+
const passwordKdf = {
|
|
72
|
+
algorithm: sdk_1.Utils.toUTF8(kdfAlgorithmField),
|
|
73
|
+
iterations: kdfParams.iterations,
|
|
74
|
+
memoryKiB: kdfParams.memoryKiB,
|
|
75
|
+
parallelism: kdfParams.parallelism,
|
|
76
|
+
hashLength: kdfParams.hashLength
|
|
77
|
+
};
|
|
78
|
+
if (!isValidKdfConfig(passwordKdf))
|
|
79
|
+
return false;
|
|
80
|
+
token.umpVersion = 3;
|
|
81
|
+
token.passwordKdf = passwordKdf;
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
18
84
|
function isLikelyDerSignatureField(field) {
|
|
19
85
|
if (!field || field.length < 8 || field.length > 80) {
|
|
20
86
|
return false;
|
|
@@ -39,7 +105,7 @@ function stripVerifiedPushDropSignature(fields, lockingPublicKey) {
|
|
|
39
105
|
for (let i = 0; i < protocolFieldCount; i++) {
|
|
40
106
|
dataLength += fields[i].length;
|
|
41
107
|
}
|
|
42
|
-
const dataToVerify =
|
|
108
|
+
const dataToVerify = Array.from({ length: dataLength }, () => 0);
|
|
43
109
|
let writeOffset = 0;
|
|
44
110
|
for (let i = 0; i < protocolFieldCount; i++) {
|
|
45
111
|
const field = fields[i];
|
|
@@ -82,14 +148,13 @@ async function pbkdf2NativeOrWasm(passwordBytes, salt, iterations, keyLen, hash
|
|
|
82
148
|
}, baseKey, keyLen * 8);
|
|
83
149
|
return Array.from(new Uint8Array(bits));
|
|
84
150
|
}
|
|
85
|
-
catch
|
|
151
|
+
catch {
|
|
86
152
|
// WebCrypto is unavailable or refused the algorithm (e.g. non-secure context, old
|
|
87
153
|
// Safari). Fall through to the pure-JS hash-wasm implementation below.
|
|
88
|
-
console.debug('[pbkdf2] WebCrypto path failed, falling back to JS implementation', webCryptoErr);
|
|
89
154
|
}
|
|
90
155
|
}
|
|
91
|
-
const hashFunction = hash === 'sha256' ? (0,
|
|
92
|
-
const derived = await (0,
|
|
156
|
+
const hashFunction = hash === 'sha256' ? (0, hashWasm_1.createSHA256)() : (0, hashWasm_1.createSHA512)();
|
|
157
|
+
const derived = await (0, hashWasm_1.pbkdf2)({
|
|
93
158
|
password: new Uint8Array(passwordBytes),
|
|
94
159
|
salt: new Uint8Array(salt),
|
|
95
160
|
iterations,
|
|
@@ -111,8 +176,11 @@ async function pbkdf2NativeOrWasm(passwordBytes, salt, iterations, keyLen, hash
|
|
|
111
176
|
*/
|
|
112
177
|
async function derivePasswordKey(token, passwordBytes, overrideKdf) {
|
|
113
178
|
const kdf = overrideKdf || token.passwordKdf;
|
|
179
|
+
if (kdf != null && !isValidKdfConfig(kdf)) {
|
|
180
|
+
throw new Error('UMP token contains unsupported or unsafe KDF parameters.');
|
|
181
|
+
}
|
|
114
182
|
// Legacy token or explicit PBKDF2 request
|
|
115
|
-
if (
|
|
183
|
+
if (kdf == null || kdf.algorithm === 'pbkdf2-sha512') {
|
|
116
184
|
return await pbkdf2NativeOrWasm(passwordBytes, token.passwordSalt, kdf?.iterations ?? exports.PBKDF2_NUM_ROUNDS, 32, 'sha512');
|
|
117
185
|
}
|
|
118
186
|
// Argon2id path (UMP v3)
|
|
@@ -121,7 +189,7 @@ async function derivePasswordKey(token, passwordBytes, overrideKdf) {
|
|
|
121
189
|
const memorySize = kdf.memoryKiB ?? exports.ARGON2ID_DEFAULT_MEMORY_KIB;
|
|
122
190
|
const parallelism = kdf.parallelism ?? exports.ARGON2ID_DEFAULT_PARALLELISM;
|
|
123
191
|
const hashLength = kdf.hashLength ?? exports.ARGON2ID_DEFAULT_HASH_LENGTH;
|
|
124
|
-
const hash = await (0,
|
|
192
|
+
const hash = await (0, hashWasm_1.argon2id)({
|
|
125
193
|
password: new Uint8Array(passwordBytes),
|
|
126
194
|
salt: new Uint8Array(token.passwordSalt),
|
|
127
195
|
iterations,
|
|
@@ -138,6 +206,43 @@ async function derivePasswordKey(token, passwordBytes, overrideKdf) {
|
|
|
138
206
|
* Unique Identifier for the default profile (16 zero bytes).
|
|
139
207
|
*/
|
|
140
208
|
exports.DEFAULT_PROFILE_ID = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
209
|
+
function isByteArrayOfLength(value, length) {
|
|
210
|
+
return (Array.isArray(value) &&
|
|
211
|
+
value.length === length &&
|
|
212
|
+
value.every(byte => Number.isInteger(byte) && byte >= 0 && byte <= 255));
|
|
213
|
+
}
|
|
214
|
+
function isValidProfile(value) {
|
|
215
|
+
if (value == null || typeof value !== 'object')
|
|
216
|
+
return false;
|
|
217
|
+
const profile = value;
|
|
218
|
+
return (typeof profile.name === 'string' &&
|
|
219
|
+
profile.name.length > 0 &&
|
|
220
|
+
profile.name.length <= 250 &&
|
|
221
|
+
isByteArrayOfLength(profile.id, 16) &&
|
|
222
|
+
isByteArrayOfLength(profile.primaryPad, 32) &&
|
|
223
|
+
isByteArrayOfLength(profile.privilegedPad, 32) &&
|
|
224
|
+
typeof profile.createdAt === 'number' &&
|
|
225
|
+
Number.isFinite(profile.createdAt) &&
|
|
226
|
+
profile.createdAt >= 0);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Raised when UMP absence cannot be established authoritatively.
|
|
230
|
+
*
|
|
231
|
+
* Callers must offer retry/recovery rather than treating this error as a new
|
|
232
|
+
* account. Diagnostics contain counts only and never hashes, keys, or tokens.
|
|
233
|
+
*/
|
|
234
|
+
class UMPTokenLookupError extends Error {
|
|
235
|
+
reason;
|
|
236
|
+
diagnostics;
|
|
237
|
+
code = 'WERR_UMP_LOOKUP_INDETERMINATE';
|
|
238
|
+
constructor(reason, diagnostics, options) {
|
|
239
|
+
super('Unable to determine whether the wallet account already exists. Retry or use account recovery.', options);
|
|
240
|
+
this.reason = reason;
|
|
241
|
+
this.diagnostics = diagnostics;
|
|
242
|
+
this.name = 'UMPTokenLookupError';
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
exports.UMPTokenLookupError = UMPTokenLookupError;
|
|
141
246
|
/**
|
|
142
247
|
* @class OverlayUMPTokenInteractor
|
|
143
248
|
*
|
|
@@ -160,15 +265,17 @@ class OverlayUMPTokenInteractor {
|
|
|
160
265
|
* under the `tm_users` topic to overlay service peers.
|
|
161
266
|
*/
|
|
162
267
|
broadcaster;
|
|
268
|
+
telemetry;
|
|
163
269
|
/**
|
|
164
270
|
* Construct a new OverlayUMPTokenInteractor.
|
|
165
271
|
*
|
|
166
272
|
* @param resolver A LookupResolver instance for performing overlay queries (ls_users).
|
|
167
273
|
* @param broadcaster A SHIPBroadcaster instance for sharing new or updated tokens across the `tm_users` overlay.
|
|
168
274
|
*/
|
|
169
|
-
constructor(resolver = new sdk_1.LookupResolver(), broadcaster = new sdk_1.SHIPBroadcaster(['tm_users'])) {
|
|
275
|
+
constructor(resolver = new sdk_1.LookupResolver(), broadcaster = new sdk_1.SHIPBroadcaster(['tm_users']), telemetry) {
|
|
170
276
|
this.resolver = resolver;
|
|
171
277
|
this.broadcaster = broadcaster;
|
|
278
|
+
this.telemetry = new sdk_1.Telemetry(telemetry);
|
|
172
279
|
}
|
|
173
280
|
/**
|
|
174
281
|
* Finds a UMP token on-chain by the given presentation key hash, if it exists.
|
|
@@ -178,13 +285,10 @@ class OverlayUMPTokenInteractor {
|
|
|
178
285
|
* @returns A UMPToken object (including currentOutpoint) if found, otherwise undefined.
|
|
179
286
|
*/
|
|
180
287
|
async findByPresentationKeyHash(hash) {
|
|
181
|
-
|
|
182
|
-
const question = {
|
|
288
|
+
return await this.findToken({
|
|
183
289
|
service: 'ls_users',
|
|
184
290
|
query: { presentationHash: sdk_1.Utils.toHex(hash) }
|
|
185
|
-
};
|
|
186
|
-
const answer = await this.resolver.query(question);
|
|
187
|
-
return this.parseLookupAnswer(answer);
|
|
291
|
+
}, 'presentation');
|
|
188
292
|
}
|
|
189
293
|
/**
|
|
190
294
|
* Finds a UMP token on-chain by the given recovery key hash, if it exists.
|
|
@@ -194,12 +298,142 @@ class OverlayUMPTokenInteractor {
|
|
|
194
298
|
* @returns A UMPToken object (including currentOutpoint) if found, otherwise undefined.
|
|
195
299
|
*/
|
|
196
300
|
async findByRecoveryKeyHash(hash) {
|
|
197
|
-
|
|
301
|
+
return await this.findToken({
|
|
198
302
|
service: 'ls_users',
|
|
199
303
|
query: { recoveryHash: sdk_1.Utils.toHex(hash) }
|
|
304
|
+
}, 'recovery');
|
|
305
|
+
}
|
|
306
|
+
async findToken(question, lookupKind) {
|
|
307
|
+
const correlationId = this.telemetry.enabled === true ? this.telemetry.createCorrelationId() : undefined;
|
|
308
|
+
const startedAt = Date.now();
|
|
309
|
+
this.telemetry.capture({
|
|
310
|
+
name: 'wallet-toolbox.ump.lookup.started',
|
|
311
|
+
component: 'wallet-toolbox.ump',
|
|
312
|
+
severity: 'debug',
|
|
313
|
+
correlationId,
|
|
314
|
+
attributes: { lookupKind }
|
|
315
|
+
});
|
|
316
|
+
let resolution;
|
|
317
|
+
try {
|
|
318
|
+
resolution = await this.resolver.queryDetailed(question, undefined, {
|
|
319
|
+
waitForAllHosts: true,
|
|
320
|
+
correlationId
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
const diagnostics = this.emptyLookupDiagnostics(correlationId);
|
|
325
|
+
this.captureLookupFailure(lookupKind, 'lookup-unavailable', diagnostics, startedAt, error);
|
|
326
|
+
throw new UMPTokenLookupError('lookup-unavailable', diagnostics, { cause: error });
|
|
327
|
+
}
|
|
328
|
+
const diagnostics = this.toLookupDiagnostics(resolution);
|
|
329
|
+
if (resolution.answer.outputs.length === 0) {
|
|
330
|
+
const authoritative = resolution.progress.isFinal &&
|
|
331
|
+
resolution.progress.hostCount > 0 &&
|
|
332
|
+
resolution.progress.completedHosts === resolution.progress.hostCount &&
|
|
333
|
+
resolution.progress.successfulHosts === resolution.progress.hostCount &&
|
|
334
|
+
resolution.progress.emptyHosts === resolution.progress.hostCount &&
|
|
335
|
+
resolution.progress.failedHosts === 0 &&
|
|
336
|
+
resolution.progress.rejectedHosts === 0 &&
|
|
337
|
+
resolution.progress.freeformHosts === 0;
|
|
338
|
+
if (!authoritative) {
|
|
339
|
+
this.captureLookupFailure(lookupKind, 'lookup-incomplete', diagnostics, startedAt);
|
|
340
|
+
throw new UMPTokenLookupError('lookup-incomplete', diagnostics);
|
|
341
|
+
}
|
|
342
|
+
this.telemetry.capture({
|
|
343
|
+
name: 'wallet-toolbox.ump.lookup.completed',
|
|
344
|
+
component: 'wallet-toolbox.ump',
|
|
345
|
+
severity: 'info',
|
|
346
|
+
correlationId: diagnostics.correlationId,
|
|
347
|
+
attributes: {
|
|
348
|
+
lookupKind,
|
|
349
|
+
result: 'not-found',
|
|
350
|
+
durationMs: Date.now() - startedAt,
|
|
351
|
+
...this.lookupDiagnosticAttributes(diagnostics)
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
return undefined;
|
|
355
|
+
}
|
|
356
|
+
const tokens = this.parseLookupAnswers(resolution.answer);
|
|
357
|
+
const expectedHash = question.query[lookupKind === 'presentation' ? 'presentationHash' : 'recoveryHash'].toLowerCase();
|
|
358
|
+
const everyOutputValidAndMatching = tokens.length === resolution.answer.outputs.length &&
|
|
359
|
+
tokens.every(token => sdk_1.Utils.toHex(lookupKind === 'presentation' ? token.presentationHash : token.recoveryHash).toLowerCase() ===
|
|
360
|
+
expectedHash);
|
|
361
|
+
if (!everyOutputValidAndMatching || tokens.length === 0) {
|
|
362
|
+
this.captureLookupFailure(lookupKind, 'token-malformed', diagnostics, startedAt);
|
|
363
|
+
throw new UMPTokenLookupError('token-malformed', diagnostics);
|
|
364
|
+
}
|
|
365
|
+
if (tokens.length !== 1) {
|
|
366
|
+
const reason = 'token-ambiguous';
|
|
367
|
+
this.captureLookupFailure(lookupKind, reason, diagnostics, startedAt);
|
|
368
|
+
throw new UMPTokenLookupError(reason, diagnostics);
|
|
369
|
+
}
|
|
370
|
+
this.telemetry.capture({
|
|
371
|
+
name: 'wallet-toolbox.ump.lookup.completed',
|
|
372
|
+
component: 'wallet-toolbox.ump',
|
|
373
|
+
severity: 'info',
|
|
374
|
+
correlationId: diagnostics.correlationId,
|
|
375
|
+
attributes: {
|
|
376
|
+
lookupKind,
|
|
377
|
+
result: 'found',
|
|
378
|
+
durationMs: Date.now() - startedAt,
|
|
379
|
+
...this.lookupDiagnosticAttributes(diagnostics)
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
return tokens[0];
|
|
383
|
+
}
|
|
384
|
+
emptyLookupDiagnostics(correlationId) {
|
|
385
|
+
return {
|
|
386
|
+
hostCount: 0,
|
|
387
|
+
completedHosts: 0,
|
|
388
|
+
successfulHosts: 0,
|
|
389
|
+
emptyHosts: 0,
|
|
390
|
+
failedHosts: 0,
|
|
391
|
+
rejectedHosts: 0,
|
|
392
|
+
freeformHosts: 0,
|
|
393
|
+
outputCount: 0,
|
|
394
|
+
...(correlationId !== undefined ? { correlationId } : {})
|
|
200
395
|
};
|
|
201
|
-
|
|
202
|
-
|
|
396
|
+
}
|
|
397
|
+
toLookupDiagnostics(resolution) {
|
|
398
|
+
const progress = resolution.progress;
|
|
399
|
+
return {
|
|
400
|
+
hostCount: progress.hostCount,
|
|
401
|
+
completedHosts: progress.completedHosts,
|
|
402
|
+
successfulHosts: progress.successfulHosts,
|
|
403
|
+
emptyHosts: progress.emptyHosts,
|
|
404
|
+
failedHosts: progress.failedHosts,
|
|
405
|
+
rejectedHosts: progress.rejectedHosts,
|
|
406
|
+
freeformHosts: progress.freeformHosts,
|
|
407
|
+
outputCount: resolution.answer.outputs.length,
|
|
408
|
+
...(progress.correlationId !== undefined ? { correlationId: progress.correlationId } : {})
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
lookupDiagnosticAttributes(diagnostics) {
|
|
412
|
+
return {
|
|
413
|
+
hostCount: diagnostics.hostCount,
|
|
414
|
+
completedHosts: diagnostics.completedHosts,
|
|
415
|
+
successfulHosts: diagnostics.successfulHosts,
|
|
416
|
+
emptyHosts: diagnostics.emptyHosts,
|
|
417
|
+
failedHosts: diagnostics.failedHosts,
|
|
418
|
+
rejectedHosts: diagnostics.rejectedHosts,
|
|
419
|
+
freeformHosts: diagnostics.freeformHosts,
|
|
420
|
+
outputCount: diagnostics.outputCount
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
captureLookupFailure(lookupKind, reason, diagnostics, startedAt, error) {
|
|
424
|
+
this.telemetry.capture({
|
|
425
|
+
name: 'wallet-toolbox.ump.lookup.indeterminate',
|
|
426
|
+
component: 'wallet-toolbox.ump',
|
|
427
|
+
severity: 'warn',
|
|
428
|
+
correlationId: diagnostics.correlationId,
|
|
429
|
+
attributes: {
|
|
430
|
+
lookupKind,
|
|
431
|
+
reason,
|
|
432
|
+
durationMs: Date.now() - startedAt,
|
|
433
|
+
...this.lookupDiagnosticAttributes(diagnostics)
|
|
434
|
+
},
|
|
435
|
+
error
|
|
436
|
+
});
|
|
203
437
|
}
|
|
204
438
|
/**
|
|
205
439
|
* Creates or updates (replaces) a UMP token on-chain. If `oldTokenToConsume` is provided,
|
|
@@ -224,7 +458,13 @@ class OverlayUMPTokenInteractor {
|
|
|
224
458
|
// 2) Resolve the old-token input (if provided) and create the action.
|
|
225
459
|
const { resolvedOldToken, inputToken } = await this.resolveOldTokenInput(oldTokenToConsume);
|
|
226
460
|
const inputs = resolvedOldToken?.currentOutpoint
|
|
227
|
-
? [
|
|
461
|
+
? [
|
|
462
|
+
{
|
|
463
|
+
outpoint: resolvedOldToken.currentOutpoint,
|
|
464
|
+
unlockingScriptLength: 73,
|
|
465
|
+
inputDescription: 'Consume old UMP token'
|
|
466
|
+
}
|
|
467
|
+
]
|
|
228
468
|
: [];
|
|
229
469
|
const createResult = await this.createUMPAction(wallet, adminOriginator, inputs, tokenOutput, inputToken, resolvedOldToken);
|
|
230
470
|
// 3) If the wallet fully processed it (no signable tx), broadcast and return.
|
|
@@ -256,7 +496,7 @@ class OverlayUMPTokenInteractor {
|
|
|
256
496
|
if (token.profilesEncrypted != null)
|
|
257
497
|
fields[11] = token.profilesEncrypted;
|
|
258
498
|
if (token.umpVersion === 3 && token.passwordKdf != null) {
|
|
259
|
-
const vi =
|
|
499
|
+
const vi = token.profilesEncrypted == null ? 11 : 12;
|
|
260
500
|
fields[vi] = [token.umpVersion];
|
|
261
501
|
fields[vi + 1] = sdk_1.Utils.toArray(token.passwordKdf.algorithm, 'utf8');
|
|
262
502
|
const kdfParams = { iterations: token.passwordKdf.iterations };
|
|
@@ -275,28 +515,34 @@ class OverlayUMPTokenInteractor {
|
|
|
275
515
|
if (!oldTokenToConsume?.currentOutpoint)
|
|
276
516
|
return { resolvedOldToken: undefined, inputToken: undefined };
|
|
277
517
|
const inputToken = await this.findByOutpoint(oldTokenToConsume.currentOutpoint);
|
|
278
|
-
if (inputToken == null)
|
|
279
|
-
|
|
518
|
+
if (inputToken == null) {
|
|
519
|
+
throw new Error('The previous UMP token could not be resolved; refusing to publish a duplicate token.');
|
|
520
|
+
}
|
|
280
521
|
return { resolvedOldToken: oldTokenToConsume, inputToken };
|
|
281
522
|
}
|
|
282
|
-
/** Creates the UMP action
|
|
523
|
+
/** Creates the UMP action without dropping a required old-token input on failure. */
|
|
283
524
|
async createUMPAction(wallet, adminOriginator, inputs, outputs, inputToken, resolvedOldToken) {
|
|
284
525
|
try {
|
|
285
526
|
return await wallet.createAction({
|
|
286
|
-
description:
|
|
527
|
+
description: resolvedOldToken == null ? 'Create new UMP token' : 'Renew UMP token (consume old, create new)',
|
|
287
528
|
inputs,
|
|
288
529
|
outputs,
|
|
289
530
|
inputBEEF: inputToken?.beef,
|
|
290
531
|
options: { randomizeOutputs: false, acceptDelayedBroadcast: false }
|
|
291
532
|
}, adminOriginator);
|
|
292
533
|
}
|
|
293
|
-
catch (
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
534
|
+
catch (error) {
|
|
535
|
+
this.telemetry.capture({
|
|
536
|
+
name: 'wallet-toolbox.ump.action.failed',
|
|
537
|
+
component: 'wallet-toolbox.ump',
|
|
538
|
+
severity: 'error',
|
|
539
|
+
attributes: {
|
|
540
|
+
operation: resolvedOldToken == null ? 'create' : 'renew',
|
|
541
|
+
oldTokenInputRequired: resolvedOldToken != null
|
|
542
|
+
},
|
|
543
|
+
error
|
|
544
|
+
});
|
|
545
|
+
throw error;
|
|
300
546
|
}
|
|
301
547
|
}
|
|
302
548
|
/** Handles a fully-finalized (no signable tx) createAction result — broadcasts and returns outpoint. */
|
|
@@ -308,7 +554,7 @@ class OverlayUMPTokenInteractor {
|
|
|
308
554
|
throw new Error('No final TX data to broadcast.');
|
|
309
555
|
const broadcastTx = sdk_1.Transaction.fromAtomicBEEF(createResult.tx);
|
|
310
556
|
const result = await this.broadcaster.broadcast(broadcastTx);
|
|
311
|
-
|
|
557
|
+
this.assertSuccessfulBroadcast(result, 'create-finalized');
|
|
312
558
|
return `${finalTxid}.0`;
|
|
313
559
|
}
|
|
314
560
|
/** Signs the old-token input and broadcasts — used during UMP token renewal. */
|
|
@@ -316,27 +562,43 @@ class OverlayUMPTokenInteractor {
|
|
|
316
562
|
const unlocker = new sdk_1.PushDrop(wallet, adminOriginator).unlock([2, 'admin user management token'], '1', 'self');
|
|
317
563
|
const unlockingScript = await unlocker.sign(partialTx, 0);
|
|
318
564
|
const signResult = await wallet.signAction({ reference, spends: { 0: { unlockingScript: unlockingScript.toHex() } } }, adminOriginator);
|
|
319
|
-
const finalTxid = signResult.txid || (
|
|
565
|
+
const finalTxid = signResult.txid || (signResult.tx == null ? '' : sdk_1.Transaction.fromAtomicBEEF(signResult.tx).id('hex'));
|
|
320
566
|
if (!finalTxid)
|
|
321
567
|
throw new Error('Could not finalize transaction for renewed UMP token.');
|
|
322
568
|
if (signResult.tx == null)
|
|
323
569
|
throw new Error('Final transaction data missing after signing renewed UMP token.');
|
|
324
570
|
const result = await this.broadcaster.broadcast(sdk_1.Transaction.fromAtomicBEEF(signResult.tx));
|
|
325
|
-
|
|
571
|
+
this.assertSuccessfulBroadcast(result, 'renew');
|
|
326
572
|
return `${finalTxid}.0`;
|
|
327
573
|
}
|
|
328
574
|
/** Signs without input spending and broadcasts — used when creating a brand-new UMP token. */
|
|
329
575
|
async signAndBroadcastNewToken(wallet, adminOriginator, reference) {
|
|
330
576
|
const signResult = await wallet.signAction({ reference, spends: {} }, adminOriginator);
|
|
331
|
-
const finalTxid = signResult.txid || (
|
|
577
|
+
const finalTxid = signResult.txid || (signResult.tx == null ? '' : sdk_1.Transaction.fromAtomicBEEF(signResult.tx).id('hex'));
|
|
332
578
|
if (!finalTxid)
|
|
333
579
|
throw new Error('Failed to finalize new UMP token transaction.');
|
|
334
580
|
if (signResult.tx == null)
|
|
335
581
|
throw new Error('Final transaction data missing after signing new UMP token.');
|
|
336
582
|
const result = await this.broadcaster.broadcast(sdk_1.Transaction.fromAtomicBEEF(signResult.tx));
|
|
337
|
-
|
|
583
|
+
this.assertSuccessfulBroadcast(result, 'create');
|
|
338
584
|
return `${finalTxid}.0`;
|
|
339
585
|
}
|
|
586
|
+
assertSuccessfulBroadcast(result, operation) {
|
|
587
|
+
const succeeded = result.status === 'success';
|
|
588
|
+
this.telemetry.capture({
|
|
589
|
+
name: succeeded ? 'wallet-toolbox.ump.broadcast.completed' : 'wallet-toolbox.ump.broadcast.failed',
|
|
590
|
+
component: 'wallet-toolbox.ump',
|
|
591
|
+
severity: succeeded ? 'info' : 'error',
|
|
592
|
+
attributes: {
|
|
593
|
+
operation,
|
|
594
|
+
outcome: result.status,
|
|
595
|
+
...(result.status === 'error' ? { code: result.code } : {})
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
if (!succeeded) {
|
|
599
|
+
throw new Error(`UMP token broadcast failed (${result.code}).`);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
340
602
|
/**
|
|
341
603
|
* Attempts to parse a LookupAnswer from the UMP lookup service. If successful,
|
|
342
604
|
* extracts the token fields from the resulting transaction and constructs
|
|
@@ -346,40 +608,36 @@ class OverlayUMPTokenInteractor {
|
|
|
346
608
|
* @returns The parsed UMPToken or `undefined` if none found/decodable.
|
|
347
609
|
*/
|
|
348
610
|
parseLookupAnswer(answer) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (
|
|
353
|
-
return
|
|
611
|
+
return this.parseLookupAnswers(answer)[0];
|
|
612
|
+
}
|
|
613
|
+
parseLookupAnswers(answer) {
|
|
614
|
+
if (answer.type !== 'output-list' || answer.outputs.length === 0)
|
|
615
|
+
return [];
|
|
616
|
+
const tokens = [];
|
|
617
|
+
for (const output of answer.outputs) {
|
|
618
|
+
const token = this.parseLookupOutput(output);
|
|
619
|
+
if (token != null)
|
|
620
|
+
tokens.push(token);
|
|
354
621
|
}
|
|
355
|
-
|
|
622
|
+
return tokens;
|
|
623
|
+
}
|
|
624
|
+
parseLookupOutput(output) {
|
|
356
625
|
try {
|
|
357
|
-
const tx = sdk_1.Transaction.fromBEEF(beef);
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
626
|
+
const tx = sdk_1.Transaction.fromBEEF(output.beef);
|
|
627
|
+
const txOutput = tx.outputs[output.outputIndex];
|
|
628
|
+
if (txOutput == null)
|
|
629
|
+
return undefined;
|
|
630
|
+
const decoded = sdk_1.PushDrop.decode(txOutput.lockingScript);
|
|
631
|
+
if (decoded.fields == null || decoded.fields.length < 11 || decoded.fields.length > 16) {
|
|
363
632
|
return undefined;
|
|
364
633
|
}
|
|
365
|
-
// Parse protocol fields, excluding the trailing PushDrop signature only when
|
|
366
|
-
// it is cryptographically valid for the preceding field payload.
|
|
367
634
|
const protocolFields = stripVerifiedPushDropSignature(decoded.fields, decoded.lockingPublicKey);
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
if (hasV3MetadataWithProfiles)
|
|
375
|
-
kdfVersionFieldIndex = 12;
|
|
376
|
-
else if (hasV3MetadataWithoutProfiles)
|
|
377
|
-
kdfVersionFieldIndex = 11;
|
|
378
|
-
else
|
|
379
|
-
kdfVersionFieldIndex = -1;
|
|
380
|
-
// Build the UMP token from these fields, preserving outpoint
|
|
381
|
-
const t = {
|
|
382
|
-
// Core fields (unchanged for all versions)
|
|
635
|
+
if (protocolFields.length < 11 ||
|
|
636
|
+
protocolFields.slice(0, 11).some(field => field.length === 0 || field.length > exports.MAX_STATE_SNAPSHOT_BYTES)) {
|
|
637
|
+
return undefined;
|
|
638
|
+
}
|
|
639
|
+
const kdfVersionFieldIndex = findKdfVersionFieldIndex(protocolFields);
|
|
640
|
+
const token = {
|
|
383
641
|
passwordSalt: protocolFields[0],
|
|
384
642
|
passwordPresentationPrimary: protocolFields[1],
|
|
385
643
|
passwordRecoveryPrimary: protocolFields[2],
|
|
@@ -391,41 +649,17 @@ class OverlayUMPTokenInteractor {
|
|
|
391
649
|
presentationKeyEncrypted: protocolFields[8],
|
|
392
650
|
passwordKeyEncrypted: protocolFields[9],
|
|
393
651
|
recoveryKeyEncrypted: protocolFields[10],
|
|
394
|
-
currentOutpoint:
|
|
652
|
+
currentOutpoint: `${tx.id('hex')}.${output.outputIndex}`
|
|
395
653
|
};
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
if (
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
t.umpVersion = protocolFields[kdfVersionFieldIndex][0]; // Single byte value 3
|
|
404
|
-
const kdfAlgorithmField = protocolFields[kdfVersionFieldIndex + 1];
|
|
405
|
-
const kdfParamsField = protocolFields[kdfVersionFieldIndex + 2];
|
|
406
|
-
if (!kdfAlgorithmField || !kdfParamsField) {
|
|
407
|
-
return t;
|
|
408
|
-
}
|
|
409
|
-
const kdfAlgorithm = sdk_1.Utils.toUTF8(kdfAlgorithmField);
|
|
410
|
-
const kdfParamsJson = sdk_1.Utils.toUTF8(kdfParamsField);
|
|
411
|
-
try {
|
|
412
|
-
const kdfParams = JSON.parse(kdfParamsJson);
|
|
413
|
-
t.passwordKdf = {
|
|
414
|
-
algorithm: kdfAlgorithm,
|
|
415
|
-
iterations: kdfParams.iterations,
|
|
416
|
-
memoryKiB: kdfParams.memoryKiB,
|
|
417
|
-
parallelism: kdfParams.parallelism,
|
|
418
|
-
hashLength: kdfParams.hashLength
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
catch (e) {
|
|
422
|
-
console.warn('Failed to parse v3 KDF params:', e);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
return t;
|
|
654
|
+
if (token.presentationHash.length !== 32 || token.recoveryHash.length !== 32)
|
|
655
|
+
return undefined;
|
|
656
|
+
if (!addProfilesField(token, protocolFields, kdfVersionFieldIndex))
|
|
657
|
+
return undefined;
|
|
658
|
+
if (!addPasswordKdf(token, protocolFields, kdfVersionFieldIndex))
|
|
659
|
+
return undefined;
|
|
660
|
+
return token;
|
|
426
661
|
}
|
|
427
|
-
catch
|
|
428
|
-
console.error('Failed to parse or decode UMP token:', e);
|
|
662
|
+
catch {
|
|
429
663
|
return undefined;
|
|
430
664
|
}
|
|
431
665
|
}
|
|
@@ -435,19 +669,43 @@ class OverlayUMPTokenInteractor {
|
|
|
435
669
|
* @returns The result so that we can use it to unlock the transaction
|
|
436
670
|
*/
|
|
437
671
|
async findByOutpoint(outpoint) {
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
672
|
+
const correlationId = this.telemetry.enabled === true ? this.telemetry.createCorrelationId() : undefined;
|
|
673
|
+
const startedAt = Date.now();
|
|
674
|
+
let resolution;
|
|
675
|
+
try {
|
|
676
|
+
resolution = await this.resolver.queryDetailed({
|
|
677
|
+
service: 'ls_users',
|
|
678
|
+
query: {
|
|
679
|
+
outpoint
|
|
680
|
+
}
|
|
681
|
+
}, undefined, {
|
|
682
|
+
waitForAllHosts: true,
|
|
683
|
+
correlationId
|
|
684
|
+
});
|
|
446
685
|
}
|
|
447
|
-
|
|
686
|
+
catch (error) {
|
|
687
|
+
const diagnostics = this.emptyLookupDiagnostics(correlationId);
|
|
688
|
+
this.captureLookupFailure('outpoint', 'lookup-unavailable', diagnostics, startedAt, error);
|
|
689
|
+
throw new UMPTokenLookupError('lookup-unavailable', diagnostics, { cause: error });
|
|
690
|
+
}
|
|
691
|
+
if (resolution.answer.outputs.length === 0) {
|
|
692
|
+
const p = resolution.progress;
|
|
693
|
+
const authoritative = p.isFinal &&
|
|
694
|
+
p.hostCount > 0 &&
|
|
695
|
+
p.completedHosts === p.hostCount &&
|
|
696
|
+
p.successfulHosts === p.hostCount &&
|
|
697
|
+
p.emptyHosts === p.hostCount &&
|
|
698
|
+
p.failedHosts === 0 &&
|
|
699
|
+
p.rejectedHosts === 0 &&
|
|
700
|
+
p.freeformHosts === 0;
|
|
701
|
+
if (!authoritative) {
|
|
702
|
+
const diagnostics = this.toLookupDiagnostics(resolution);
|
|
703
|
+
this.captureLookupFailure('outpoint', 'lookup-incomplete', diagnostics, startedAt);
|
|
704
|
+
throw new UMPTokenLookupError('lookup-incomplete', diagnostics);
|
|
705
|
+
}
|
|
448
706
|
return undefined;
|
|
449
707
|
}
|
|
450
|
-
return
|
|
708
|
+
return resolution.answer.outputs[0];
|
|
451
709
|
}
|
|
452
710
|
}
|
|
453
711
|
exports.OverlayUMPTokenInteractor = OverlayUMPTokenInteractor;
|
|
@@ -468,9 +726,7 @@ class CWIStyleWalletManager {
|
|
|
468
726
|
* Await `ready` before calling wallet methods after constructing with a snapshot.
|
|
469
727
|
*/
|
|
470
728
|
get ready() {
|
|
471
|
-
|
|
472
|
-
this._readyInit = this._init();
|
|
473
|
-
}
|
|
729
|
+
this._readyInit ??= this._init();
|
|
474
730
|
return this._readyInit;
|
|
475
731
|
}
|
|
476
732
|
_readyInit;
|
|
@@ -483,6 +739,10 @@ class CWIStyleWalletManager {
|
|
|
483
739
|
* The system that locates and publishes UMP tokens on-chain.
|
|
484
740
|
*/
|
|
485
741
|
UMPTokenInteractor;
|
|
742
|
+
/**
|
|
743
|
+
* Privacy-bounded diagnostic channel for wallet state transitions.
|
|
744
|
+
*/
|
|
745
|
+
telemetry;
|
|
486
746
|
/**
|
|
487
747
|
* A function called to persist the newly generated recovery key.
|
|
488
748
|
* It should generally trigger a UI prompt where the user is asked to write it down.
|
|
@@ -510,7 +770,7 @@ class CWIStyleWalletManager {
|
|
|
510
770
|
/**
|
|
511
771
|
* Indicates new user or existing user flow.
|
|
512
772
|
*/
|
|
513
|
-
authenticationFlow = '
|
|
773
|
+
authenticationFlow = 'unknown';
|
|
514
774
|
/**
|
|
515
775
|
* The current UMP token in use.
|
|
516
776
|
*/
|
|
@@ -559,32 +819,54 @@ class CWIStyleWalletManager {
|
|
|
559
819
|
* @param stateSnapshot Optional previously saved state snapshot.
|
|
560
820
|
* @param kdfConfig Optional KDF configuration for new UMP tokens.
|
|
561
821
|
*/
|
|
562
|
-
constructor(adminOriginator, walletBuilder, interactor
|
|
822
|
+
constructor(...[adminOriginator, walletBuilder, interactor, recoveryKeySaver, passwordRetriever, newWalletFunder, stateSnapshot, kdfConfig, telemetry]) {
|
|
563
823
|
this.adminOriginator = adminOriginator;
|
|
564
824
|
this.walletBuilder = walletBuilder;
|
|
565
|
-
this.
|
|
825
|
+
this.telemetry = new sdk_1.Telemetry(telemetry);
|
|
826
|
+
this.UMPTokenInteractor = interactor ?? new OverlayUMPTokenInteractor(undefined, undefined, telemetry);
|
|
566
827
|
this.recoveryKeySaver = recoveryKeySaver;
|
|
567
828
|
this.passwordRetriever = passwordRetriever;
|
|
568
829
|
this.authenticated = false;
|
|
569
830
|
this.newWalletFunder = newWalletFunder;
|
|
570
831
|
// Initialize KDF config with Argon2id defaults for v3 tokens
|
|
832
|
+
const kdfAlgorithm = kdfConfig?.algorithm ?? 'argon2id';
|
|
571
833
|
this.kdfConfig = {
|
|
572
|
-
algorithm:
|
|
573
|
-
iterations: kdfConfig?.iterations ?? exports.ARGON2ID_DEFAULT_ITERATIONS,
|
|
834
|
+
algorithm: kdfAlgorithm,
|
|
835
|
+
iterations: kdfConfig?.iterations ?? (kdfAlgorithm === 'argon2id' ? exports.ARGON2ID_DEFAULT_ITERATIONS : exports.PBKDF2_NUM_ROUNDS),
|
|
574
836
|
memoryKiB: kdfConfig?.memoryKiB ?? exports.ARGON2ID_DEFAULT_MEMORY_KIB,
|
|
575
837
|
parallelism: kdfConfig?.parallelism ?? exports.ARGON2ID_DEFAULT_PARALLELISM,
|
|
576
838
|
hashLength: kdfConfig?.hashLength ?? exports.ARGON2ID_DEFAULT_HASH_LENGTH
|
|
577
839
|
};
|
|
840
|
+
if (!isValidKdfConfig(this.kdfConfig)) {
|
|
841
|
+
throw new Error('Unsupported or unsafe KDF configuration.');
|
|
842
|
+
}
|
|
578
843
|
// Store snapshot for lazy init; callers await ready before calling wallet methods.
|
|
579
844
|
this._initSnapshot = stateSnapshot;
|
|
580
845
|
}
|
|
581
846
|
async _init() {
|
|
582
847
|
if (this._initSnapshot !== undefined) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
848
|
+
this.telemetry.capture({
|
|
849
|
+
name: 'wallet-toolbox.snapshot.initialization.started',
|
|
850
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
851
|
+
severity: 'debug'
|
|
587
852
|
});
|
|
853
|
+
try {
|
|
854
|
+
await this.loadSnapshot(this._initSnapshot);
|
|
855
|
+
this.telemetry.capture({
|
|
856
|
+
name: 'wallet-toolbox.snapshot.initialization.completed',
|
|
857
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
858
|
+
severity: 'info'
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
catch (error) {
|
|
862
|
+
this.telemetry.capture({
|
|
863
|
+
name: 'wallet-toolbox.snapshot.initialization.failed',
|
|
864
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
865
|
+
severity: 'error',
|
|
866
|
+
error
|
|
867
|
+
});
|
|
868
|
+
throw error;
|
|
869
|
+
}
|
|
588
870
|
}
|
|
589
871
|
}
|
|
590
872
|
// --- Authentication Methods ---
|
|
@@ -598,8 +880,35 @@ class CWIStyleWalletManager {
|
|
|
598
880
|
if (this.authenticationMode === 'recovery-key-and-password') {
|
|
599
881
|
throw new Error('Presentation key is not needed in this mode');
|
|
600
882
|
}
|
|
883
|
+
if (key.length !== 32 || key.some(byte => !Number.isInteger(byte) || byte < 0 || byte > 255)) {
|
|
884
|
+
throw new TypeError('Presentation key must contain exactly 32 bytes.');
|
|
885
|
+
}
|
|
886
|
+
this.authenticationFlow = 'unknown';
|
|
601
887
|
const hash = sdk_1.Hash.sha256(key);
|
|
602
|
-
const
|
|
888
|
+
const startedAt = Date.now();
|
|
889
|
+
this.telemetry.capture({
|
|
890
|
+
name: 'wallet-toolbox.authentication.account-lookup.started',
|
|
891
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
892
|
+
severity: 'debug',
|
|
893
|
+
attributes: { lookupKind: 'presentation' }
|
|
894
|
+
});
|
|
895
|
+
let token;
|
|
896
|
+
try {
|
|
897
|
+
token = await this.UMPTokenInteractor.findByPresentationKeyHash(hash);
|
|
898
|
+
}
|
|
899
|
+
catch (error) {
|
|
900
|
+
this.telemetry.capture({
|
|
901
|
+
name: 'wallet-toolbox.authentication.account-lookup.failed',
|
|
902
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
903
|
+
severity: 'warn',
|
|
904
|
+
attributes: {
|
|
905
|
+
lookupKind: 'presentation',
|
|
906
|
+
durationMs: Date.now() - startedAt
|
|
907
|
+
},
|
|
908
|
+
error
|
|
909
|
+
});
|
|
910
|
+
throw error;
|
|
911
|
+
}
|
|
603
912
|
if (token == null) {
|
|
604
913
|
// No token found -> New user
|
|
605
914
|
this.authenticationFlow = 'new-user';
|
|
@@ -611,6 +920,16 @@ class CWIStyleWalletManager {
|
|
|
611
920
|
this.presentationKey = key;
|
|
612
921
|
this.currentUMPToken = token;
|
|
613
922
|
}
|
|
923
|
+
this.telemetry.capture({
|
|
924
|
+
name: 'wallet-toolbox.authentication.account-lookup.completed',
|
|
925
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
926
|
+
severity: 'info',
|
|
927
|
+
attributes: {
|
|
928
|
+
lookupKind: 'presentation',
|
|
929
|
+
accountStatus: this.authenticationFlow,
|
|
930
|
+
durationMs: Date.now() - startedAt
|
|
931
|
+
}
|
|
932
|
+
});
|
|
614
933
|
}
|
|
615
934
|
/**
|
|
616
935
|
* Provides the password.
|
|
@@ -621,6 +940,9 @@ class CWIStyleWalletManager {
|
|
|
621
940
|
if (this.authenticationMode === 'presentation-key-and-recovery-key') {
|
|
622
941
|
throw new Error('Password is not needed in this mode');
|
|
623
942
|
}
|
|
943
|
+
if (this.authenticationFlow === 'unknown') {
|
|
944
|
+
throw new Error('Determine account status with a presentation or recovery key before providing a password.');
|
|
945
|
+
}
|
|
624
946
|
if (this.authenticationFlow === 'existing-user') {
|
|
625
947
|
await this.handleExistingUserPassword(password);
|
|
626
948
|
}
|
|
@@ -638,8 +960,7 @@ class CWIStyleWalletManager {
|
|
|
638
960
|
if (this.authenticationMode === 'presentation-key-and-password') {
|
|
639
961
|
if (this.presentationKey == null)
|
|
640
962
|
throw new Error('No presentation key found!');
|
|
641
|
-
rootPrimaryKey = new sdk_1.SymmetricKey(this.XOR(this.presentationKey, derivedPasswordKey))
|
|
642
|
-
.decrypt(this.currentUMPToken.passwordPresentationPrimary);
|
|
963
|
+
rootPrimaryKey = new sdk_1.SymmetricKey(this.XOR(this.presentationKey, derivedPasswordKey)).decrypt(this.currentUMPToken.passwordPresentationPrimary);
|
|
643
964
|
}
|
|
644
965
|
else {
|
|
645
966
|
// 'recovery-key-and-password'
|
|
@@ -647,8 +968,7 @@ class CWIStyleWalletManager {
|
|
|
647
968
|
throw new Error('No recovery key found!');
|
|
648
969
|
const primaryDecryptionKey = this.XOR(this.recoveryKey, derivedPasswordKey);
|
|
649
970
|
rootPrimaryKey = new sdk_1.SymmetricKey(primaryDecryptionKey).decrypt(this.currentUMPToken.passwordRecoveryPrimary);
|
|
650
|
-
rootPrivilegedKey = new sdk_1.SymmetricKey(this.XOR(rootPrimaryKey, derivedPasswordKey))
|
|
651
|
-
.decrypt(this.currentUMPToken.passwordPrimaryPrivileged);
|
|
971
|
+
rootPrivilegedKey = new sdk_1.SymmetricKey(this.XOR(rootPrimaryKey, derivedPasswordKey)).decrypt(this.currentUMPToken.passwordPrimaryPrivileged);
|
|
652
972
|
}
|
|
653
973
|
await this.setupRootInfrastructure(rootPrimaryKey, rootPrivilegedKey);
|
|
654
974
|
await this.switchProfile(this.activeProfileId);
|
|
@@ -673,7 +993,8 @@ class CWIStyleWalletManager {
|
|
|
673
993
|
const recoveryPassword = new sdk_1.SymmetricKey(this.XOR(recoveryKey, passwordKey));
|
|
674
994
|
const primaryPassword = new sdk_1.SymmetricKey(this.XOR(rootPrimaryKey, passwordKey));
|
|
675
995
|
const tempPrivilegedKeyManager = new PrivilegedKeyManager_1.PrivilegedKeyManager(async () => new sdk_1.PrivateKey(rootPrivilegedKey));
|
|
676
|
-
const wrapKey = async (plaintext) => (await tempPrivilegedKeyManager.encrypt({ plaintext, protocolID: [2, 'admin key wrapping'], keyID: '1' }))
|
|
996
|
+
const wrapKey = async (plaintext) => (await tempPrivilegedKeyManager.encrypt({ plaintext, protocolID: [2, 'admin key wrapping'], keyID: '1' }))
|
|
997
|
+
.ciphertext;
|
|
677
998
|
// Build new UMP token (v3 with KDF metadata, no profiles initially)
|
|
678
999
|
const newToken = {
|
|
679
1000
|
passwordSalt,
|
|
@@ -695,14 +1016,19 @@ class CWIStyleWalletManager {
|
|
|
695
1016
|
await this.setupRootInfrastructure(rootPrimaryKey);
|
|
696
1017
|
await this.switchProfile(exports.DEFAULT_PROFILE_ID);
|
|
697
1018
|
// Fund the *default* wallet if funder provided
|
|
698
|
-
if (
|
|
1019
|
+
if (this.newWalletFunder != null && this.underlying != null) {
|
|
699
1020
|
try {
|
|
700
1021
|
await this.newWalletFunder(this.presentationKey, this.underlying, this.adminOriginator);
|
|
701
1022
|
}
|
|
702
|
-
catch (
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
1023
|
+
catch (error) {
|
|
1024
|
+
this.telemetry.capture({
|
|
1025
|
+
name: 'wallet-toolbox.authentication.new-wallet-funding.failed',
|
|
1026
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
1027
|
+
severity: 'error',
|
|
1028
|
+
error: new Error('New wallet funding failed.')
|
|
1029
|
+
});
|
|
1030
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1031
|
+
throw new Error(`Failed to fund new wallet before publishing UMP token: ${message}`, { cause: error });
|
|
706
1032
|
}
|
|
707
1033
|
}
|
|
708
1034
|
if (this.underlying == null)
|
|
@@ -722,6 +1048,9 @@ class CWIStyleWalletManager {
|
|
|
722
1048
|
if (this.authenticationMode === 'presentation-key-and-password') {
|
|
723
1049
|
throw new Error('No recovery key required in this mode');
|
|
724
1050
|
}
|
|
1051
|
+
if (recoveryKey.length !== 32 || recoveryKey.some(byte => !Number.isInteger(byte) || byte < 0 || byte > 255)) {
|
|
1052
|
+
throw new TypeError('Recovery key must contain exactly 32 bytes.');
|
|
1053
|
+
}
|
|
725
1054
|
if (this.authenticationMode === 'recovery-key-and-password') {
|
|
726
1055
|
// Wait for password
|
|
727
1056
|
const hash = sdk_1.Hash.sha256(recoveryKey);
|
|
@@ -755,7 +1084,7 @@ class CWIStyleWalletManager {
|
|
|
755
1084
|
* @returns Encrypted snapshot bytes.
|
|
756
1085
|
*/
|
|
757
1086
|
saveSnapshot() {
|
|
758
|
-
if (
|
|
1087
|
+
if (this.rootPrimaryKey == null || this.currentUMPToken == null) {
|
|
759
1088
|
throw new Error('No root primary key or current UMP token set');
|
|
760
1089
|
}
|
|
761
1090
|
const snapshotKey = (0, sdk_1.Random)(32);
|
|
@@ -778,7 +1107,20 @@ class CWIStyleWalletManager {
|
|
|
778
1107
|
snapshotWriter.write(snapshotKey);
|
|
779
1108
|
snapshotWriter.write(this.activeProfileId); // Active profile ID
|
|
780
1109
|
snapshotWriter.write(snapshotPayload); // Encrypted data
|
|
781
|
-
|
|
1110
|
+
const snapshot = snapshotWriter.toArray();
|
|
1111
|
+
if (snapshot.length > exports.MAX_STATE_SNAPSHOT_BYTES) {
|
|
1112
|
+
throw new Error('Snapshot exceeds the maximum supported size.');
|
|
1113
|
+
}
|
|
1114
|
+
this.telemetry.capture({
|
|
1115
|
+
name: 'wallet-toolbox.snapshot.saved',
|
|
1116
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
1117
|
+
severity: 'info',
|
|
1118
|
+
attributes: {
|
|
1119
|
+
formatVersion: 2,
|
|
1120
|
+
profileCount: this.profiles.length
|
|
1121
|
+
}
|
|
1122
|
+
});
|
|
1123
|
+
return snapshot;
|
|
782
1124
|
}
|
|
783
1125
|
/**
|
|
784
1126
|
* Loads a previously saved state snapshot. Restores root key, UMP token, profiles, and active profile.
|
|
@@ -788,6 +1130,11 @@ class CWIStyleWalletManager {
|
|
|
788
1130
|
*/
|
|
789
1131
|
async loadSnapshot(snapshot) {
|
|
790
1132
|
try {
|
|
1133
|
+
if (snapshot.length === 0 ||
|
|
1134
|
+
snapshot.length > exports.MAX_STATE_SNAPSHOT_BYTES ||
|
|
1135
|
+
snapshot.some(byte => !Number.isInteger(byte) || byte < 0 || byte > 255)) {
|
|
1136
|
+
throw new Error('Snapshot is empty, oversized, or contains invalid bytes.');
|
|
1137
|
+
}
|
|
791
1138
|
const reader = new sdk_1.Utils.Reader(snapshot);
|
|
792
1139
|
const version = reader.readUInt8();
|
|
793
1140
|
let snapshotKey;
|
|
@@ -820,22 +1167,38 @@ class CWIStyleWalletManager {
|
|
|
820
1167
|
await this.setupRootInfrastructure(rootPrimaryKey); // Will automatically load profiles
|
|
821
1168
|
await this.switchProfile(activeProfileId); // Switch to the profile saved in the snapshot
|
|
822
1169
|
this.authenticationFlow = 'existing-user'; // Loading implies existing user
|
|
1170
|
+
this.telemetry.capture({
|
|
1171
|
+
name: 'wallet-toolbox.snapshot.loaded',
|
|
1172
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
1173
|
+
severity: 'info',
|
|
1174
|
+
attributes: {
|
|
1175
|
+
formatVersion: version,
|
|
1176
|
+
profileCount: this.profiles.length
|
|
1177
|
+
}
|
|
1178
|
+
});
|
|
823
1179
|
}
|
|
824
1180
|
catch (error) {
|
|
825
1181
|
this.destroy(); // Clear state on error
|
|
826
|
-
|
|
1182
|
+
this.telemetry.capture({
|
|
1183
|
+
name: 'wallet-toolbox.snapshot.load-failed',
|
|
1184
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
1185
|
+
severity: 'error',
|
|
1186
|
+
error
|
|
1187
|
+
});
|
|
1188
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1189
|
+
throw new Error(`Failed to load snapshot: ${message}`, { cause: error });
|
|
827
1190
|
}
|
|
828
1191
|
}
|
|
829
1192
|
async syncUMPToken() {
|
|
830
|
-
if (!this.authenticated ||
|
|
1193
|
+
if (!this.authenticated || this.currentUMPToken == null || this.rootPrimaryKey == null) {
|
|
831
1194
|
throw new Error('Wallet not authenticated or missing UMP token.');
|
|
832
1195
|
}
|
|
833
1196
|
const currentToken = this.currentUMPToken;
|
|
834
1197
|
let refreshed;
|
|
835
|
-
if (currentToken.presentationHash &&
|
|
1198
|
+
if (currentToken.presentationHash && currentToken.presentationHash.length > 0) {
|
|
836
1199
|
refreshed = await this.UMPTokenInteractor.findByPresentationKeyHash(currentToken.presentationHash);
|
|
837
1200
|
}
|
|
838
|
-
if (
|
|
1201
|
+
if (refreshed == null && currentToken.recoveryHash && currentToken.recoveryHash.length > 0) {
|
|
839
1202
|
refreshed = await this.UMPTokenInteractor.findByRecoveryKeyHash(currentToken.recoveryHash);
|
|
840
1203
|
}
|
|
841
1204
|
if (refreshed == null) {
|
|
@@ -865,7 +1228,7 @@ class CWIStyleWalletManager {
|
|
|
865
1228
|
this.profiles = [];
|
|
866
1229
|
this.activeProfileId = exports.DEFAULT_PROFILE_ID;
|
|
867
1230
|
this.authenticationMode = 'presentation-key-and-password';
|
|
868
|
-
this.authenticationFlow = '
|
|
1231
|
+
this.authenticationFlow = 'unknown';
|
|
869
1232
|
}
|
|
870
1233
|
// --- Profile Management Methods ---
|
|
871
1234
|
/**
|
|
@@ -905,7 +1268,10 @@ class CWIStyleWalletManager {
|
|
|
905
1268
|
* @returns The ID of the newly created profile.
|
|
906
1269
|
*/
|
|
907
1270
|
async addProfile(name) {
|
|
908
|
-
if (!this.authenticated ||
|
|
1271
|
+
if (!this.authenticated ||
|
|
1272
|
+
this.rootPrimaryKey == null ||
|
|
1273
|
+
this.currentUMPToken == null ||
|
|
1274
|
+
this.rootPrivilegedKeyManager == null) {
|
|
909
1275
|
throw new Error('Wallet not fully initialized or authenticated.');
|
|
910
1276
|
}
|
|
911
1277
|
// Ensure name is unique (including 'default')
|
|
@@ -936,7 +1302,10 @@ class CWIStyleWalletManager {
|
|
|
936
1302
|
* @param profileId The 16-byte ID of the profile to delete.
|
|
937
1303
|
*/
|
|
938
1304
|
async deleteProfile(profileId) {
|
|
939
|
-
if (!this.authenticated ||
|
|
1305
|
+
if (!this.authenticated ||
|
|
1306
|
+
this.rootPrimaryKey == null ||
|
|
1307
|
+
this.currentUMPToken == null ||
|
|
1308
|
+
this.rootPrivilegedKeyManager == null) {
|
|
940
1309
|
throw new Error('Wallet not fully initialized or authenticated.');
|
|
941
1310
|
}
|
|
942
1311
|
if (profileId.every(x => x === 0)) {
|
|
@@ -963,7 +1332,7 @@ class CWIStyleWalletManager {
|
|
|
963
1332
|
* @param profileId The 16-byte ID of the profile to switch to (use DEFAULT_PROFILE_ID for default).
|
|
964
1333
|
*/
|
|
965
1334
|
async switchProfile(profileId) {
|
|
966
|
-
if (!this.authenticated ||
|
|
1335
|
+
if (!this.authenticated || this.rootPrimaryKey == null || this.rootPrivilegedKeyManager == null) {
|
|
967
1336
|
throw new Error('Cannot switch profile: Wallet not authenticated or root keys missing.');
|
|
968
1337
|
}
|
|
969
1338
|
let profilePrimaryKey;
|
|
@@ -991,9 +1360,7 @@ class CWIStyleWalletManager {
|
|
|
991
1360
|
const rootPrivileged = await this.rootPrivilegedKeyManager.getPrivilegedKey(reason);
|
|
992
1361
|
const rootPrivilegedBytes = rootPrivileged.toArray();
|
|
993
1362
|
// Apply the profile's pad if applicable
|
|
994
|
-
const profilePrivilegedBytes =
|
|
995
|
-
? rootPrivilegedBytes
|
|
996
|
-
: this.XOR(rootPrivilegedBytes, profilePrivilegedPad);
|
|
1363
|
+
const profilePrivilegedBytes = profilePrivilegedPad == null ? rootPrivilegedBytes : this.XOR(rootPrivilegedBytes, profilePrivilegedPad);
|
|
997
1364
|
return new sdk_1.PrivateKey(profilePrivilegedBytes);
|
|
998
1365
|
});
|
|
999
1366
|
// Build the underlying wallet for the specific profile
|
|
@@ -1006,7 +1373,10 @@ class CWIStyleWalletManager {
|
|
|
1006
1373
|
* Changes the user's password. Re-wraps keys and updates the UMP token.
|
|
1007
1374
|
*/
|
|
1008
1375
|
async changePassword(newPassword) {
|
|
1009
|
-
if (!this.authenticated ||
|
|
1376
|
+
if (!this.authenticated ||
|
|
1377
|
+
this.currentUMPToken == null ||
|
|
1378
|
+
this.rootPrimaryKey == null ||
|
|
1379
|
+
this.rootPrivilegedKeyManager == null) {
|
|
1010
1380
|
throw new Error('Not authenticated or missing required data.');
|
|
1011
1381
|
}
|
|
1012
1382
|
const passwordSalt = (0, sdk_1.Random)(32);
|
|
@@ -1029,7 +1399,7 @@ class CWIStyleWalletManager {
|
|
|
1029
1399
|
* Retrieves the current recovery key. Requires privileged access.
|
|
1030
1400
|
*/
|
|
1031
1401
|
async getRecoveryKey() {
|
|
1032
|
-
if (!this.authenticated ||
|
|
1402
|
+
if (!this.authenticated || this.currentUMPToken == null || this.rootPrivilegedKeyManager == null) {
|
|
1033
1403
|
throw new Error('Not authenticated or missing required data.');
|
|
1034
1404
|
}
|
|
1035
1405
|
return await this.getFactor('recoveryKey');
|
|
@@ -1038,7 +1408,10 @@ class CWIStyleWalletManager {
|
|
|
1038
1408
|
* Changes the user's recovery key. Prompts user to save the new key.
|
|
1039
1409
|
*/
|
|
1040
1410
|
async changeRecoveryKey() {
|
|
1041
|
-
if (!this.authenticated ||
|
|
1411
|
+
if (!this.authenticated ||
|
|
1412
|
+
this.currentUMPToken == null ||
|
|
1413
|
+
this.rootPrimaryKey == null ||
|
|
1414
|
+
this.rootPrivilegedKeyManager == null) {
|
|
1042
1415
|
throw new Error('Not authenticated or missing required data.');
|
|
1043
1416
|
}
|
|
1044
1417
|
// Decrypt existing factors needed
|
|
@@ -1056,7 +1429,10 @@ class CWIStyleWalletManager {
|
|
|
1056
1429
|
* Changes the user's presentation key.
|
|
1057
1430
|
*/
|
|
1058
1431
|
async changePresentationKey(newPresentationKey) {
|
|
1059
|
-
if (!this.authenticated ||
|
|
1432
|
+
if (!this.authenticated ||
|
|
1433
|
+
this.currentUMPToken == null ||
|
|
1434
|
+
this.rootPrimaryKey == null ||
|
|
1435
|
+
this.rootPrivilegedKeyManager == null) {
|
|
1060
1436
|
throw new Error('Not authenticated or missing required data.');
|
|
1061
1437
|
}
|
|
1062
1438
|
if (newPresentationKey.length !== 32) {
|
|
@@ -1083,7 +1459,7 @@ class CWIStyleWalletManager {
|
|
|
1083
1459
|
// Provide more context in error
|
|
1084
1460
|
throw new Error(`XOR length mismatch: ${n1.length} vs ${n2.length}`);
|
|
1085
1461
|
}
|
|
1086
|
-
const r =
|
|
1462
|
+
const r = Array.from({ length: n1.length }, () => 0);
|
|
1087
1463
|
for (let i = 0; i < n1.length; i++) {
|
|
1088
1464
|
r[i] = n1[i] ^ n2[i];
|
|
1089
1465
|
}
|
|
@@ -1097,7 +1473,7 @@ class CWIStyleWalletManager {
|
|
|
1097
1473
|
* @returns The decrypted key bytes.
|
|
1098
1474
|
*/
|
|
1099
1475
|
async getFactor(factorName) {
|
|
1100
|
-
if (!this.authenticated ||
|
|
1476
|
+
if (!this.authenticated || this.currentUMPToken == null || this.rootPrivilegedKeyManager == null) {
|
|
1101
1477
|
throw new Error(`Cannot get factor "${factorName}": Wallet not ready.`);
|
|
1102
1478
|
}
|
|
1103
1479
|
const protocolID = [2, 'admin key wrapping']; // Protocol used for encrypting factors
|
|
@@ -1134,8 +1510,15 @@ class CWIStyleWalletManager {
|
|
|
1134
1510
|
}
|
|
1135
1511
|
}
|
|
1136
1512
|
catch (error) {
|
|
1137
|
-
|
|
1138
|
-
|
|
1513
|
+
this.telemetry.capture({
|
|
1514
|
+
name: 'wallet-toolbox.authentication.factor-decryption.failed',
|
|
1515
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
1516
|
+
severity: 'error',
|
|
1517
|
+
attributes: { factor: factorName },
|
|
1518
|
+
error
|
|
1519
|
+
});
|
|
1520
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1521
|
+
throw new Error(`Failed to decrypt factor "${factorName}": ${message}`, { cause: error });
|
|
1139
1522
|
}
|
|
1140
1523
|
}
|
|
1141
1524
|
/**
|
|
@@ -1145,7 +1528,7 @@ class CWIStyleWalletManager {
|
|
|
1145
1528
|
async updateAuthFactors(passwordSalt, passwordKey, presentationKey, recoveryKey, rootPrimaryKey, rootPrivilegedKey, // Explicitly pass the root key bytes
|
|
1146
1529
|
profiles // Pass current/new profiles list
|
|
1147
1530
|
) {
|
|
1148
|
-
if (!this.authenticated ||
|
|
1531
|
+
if (!this.authenticated || this.rootPrimaryKey == null || this.currentUMPToken == null) {
|
|
1149
1532
|
throw new Error('Wallet is not properly authenticated or missing data for update.');
|
|
1150
1533
|
}
|
|
1151
1534
|
// Ensure we have the OLD token to consume
|
|
@@ -1162,7 +1545,7 @@ class CWIStyleWalletManager {
|
|
|
1162
1545
|
const tempRootPrivilegedKeyManager = new PrivilegedKeyManager_1.PrivilegedKeyManager(async () => new sdk_1.PrivateKey(rootPrivilegedKey));
|
|
1163
1546
|
// Encrypt profiles if provided
|
|
1164
1547
|
let profilesEncrypted;
|
|
1165
|
-
if (
|
|
1548
|
+
if (profiles != null && profiles.length > 0) {
|
|
1166
1549
|
const profilesJson = JSON.stringify(profiles);
|
|
1167
1550
|
const profilesBytes = sdk_1.Utils.toArray(profilesJson, 'utf8');
|
|
1168
1551
|
profilesEncrypted = new sdk_1.SymmetricKey(rootPrimaryKey).encrypt(profilesBytes);
|
|
@@ -1210,7 +1593,12 @@ class CWIStyleWalletManager {
|
|
|
1210
1593
|
const currentActiveId = this.activeProfileId;
|
|
1211
1594
|
let walletToUse = this.underlying;
|
|
1212
1595
|
if (!currentActiveId.every(x => x === 0)) {
|
|
1213
|
-
|
|
1596
|
+
this.telemetry.capture({
|
|
1597
|
+
name: 'wallet-toolbox.ump.profile-switch.started',
|
|
1598
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
1599
|
+
severity: 'debug',
|
|
1600
|
+
attributes: { reason: 'token-update' }
|
|
1601
|
+
});
|
|
1214
1602
|
await this.switchProfile(exports.DEFAULT_PROFILE_ID); // This rebuilds this.underlying
|
|
1215
1603
|
walletToUse = this.underlying;
|
|
1216
1604
|
}
|
|
@@ -1228,8 +1616,13 @@ class CWIStyleWalletManager {
|
|
|
1228
1616
|
finally {
|
|
1229
1617
|
// Switch back if we temporarily switched
|
|
1230
1618
|
if (!currentActiveId.every(x => x === 0)) {
|
|
1231
|
-
console.log('Switching back to original profile...');
|
|
1232
1619
|
await this.switchProfile(currentActiveId);
|
|
1620
|
+
this.telemetry.capture({
|
|
1621
|
+
name: 'wallet-toolbox.ump.profile-switch.completed',
|
|
1622
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
1623
|
+
severity: 'debug',
|
|
1624
|
+
attributes: { reason: 'token-update' }
|
|
1625
|
+
});
|
|
1233
1626
|
}
|
|
1234
1627
|
}
|
|
1235
1628
|
}
|
|
@@ -1261,7 +1654,7 @@ class CWIStyleWalletManager {
|
|
|
1261
1654
|
writeArray(token.passwordKeyEncrypted); // 9
|
|
1262
1655
|
writeArray(token.recoveryKeyEncrypted); // 10
|
|
1263
1656
|
// Write optional profiles field
|
|
1264
|
-
if (
|
|
1657
|
+
if (token.profilesEncrypted != null && token.profilesEncrypted.length > 0) {
|
|
1265
1658
|
writer.writeUInt8(1); // Flag indicating profiles present
|
|
1266
1659
|
writeArray(token.profilesEncrypted);
|
|
1267
1660
|
}
|
|
@@ -1311,6 +1704,9 @@ class CWIStyleWalletManager {
|
|
|
1311
1704
|
}
|
|
1312
1705
|
const readArray = () => {
|
|
1313
1706
|
const length = reader.readVarIntNum();
|
|
1707
|
+
if (length <= 0 || length > exports.MAX_STATE_SNAPSHOT_BYTES) {
|
|
1708
|
+
throw new Error('UMP token field exceeds allowed bounds.');
|
|
1709
|
+
}
|
|
1314
1710
|
return reader.read(length);
|
|
1315
1711
|
};
|
|
1316
1712
|
// Read standard fields (order matches serialization)
|
|
@@ -1344,18 +1740,16 @@ class CWIStyleWalletManager {
|
|
|
1344
1740
|
const algorithm = sdk_1.Utils.toUTF8(algorithmBytes);
|
|
1345
1741
|
const kdfParamsBytes = readArray();
|
|
1346
1742
|
const kdfParamsJson = sdk_1.Utils.toUTF8(kdfParamsBytes);
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
catch (e) {
|
|
1358
|
-
console.warn('Failed to parse KDF params during deserialization:', e);
|
|
1743
|
+
const kdfParams = JSON.parse(kdfParamsJson);
|
|
1744
|
+
passwordKdf = {
|
|
1745
|
+
algorithm,
|
|
1746
|
+
iterations: kdfParams.iterations,
|
|
1747
|
+
memoryKiB: kdfParams.memoryKiB,
|
|
1748
|
+
parallelism: kdfParams.parallelism,
|
|
1749
|
+
hashLength: kdfParams.hashLength
|
|
1750
|
+
};
|
|
1751
|
+
if (!isValidKdfConfig(passwordKdf)) {
|
|
1752
|
+
throw new Error('Serialized UMP token contains unsupported or unsafe KDF parameters.');
|
|
1359
1753
|
}
|
|
1360
1754
|
}
|
|
1361
1755
|
}
|
|
@@ -1363,6 +1757,9 @@ class CWIStyleWalletManager {
|
|
|
1363
1757
|
const outpointLen = reader.readVarIntNum();
|
|
1364
1758
|
const outpointBytes = reader.read(outpointLen);
|
|
1365
1759
|
const currentOutpoint = sdk_1.Utils.toUTF8(outpointBytes);
|
|
1760
|
+
if (currentOutpoint.length > 128 || !/^[^\s.:]+[.:]\d+$/.test(currentOutpoint)) {
|
|
1761
|
+
throw new Error('Serialized UMP token contains an invalid outpoint.');
|
|
1762
|
+
}
|
|
1366
1763
|
const token = {
|
|
1367
1764
|
passwordSalt,
|
|
1368
1765
|
passwordPresentationPrimary,
|
|
@@ -1396,9 +1793,7 @@ class CWIStyleWalletManager {
|
|
|
1396
1793
|
}
|
|
1397
1794
|
this.rootPrimaryKey = rootPrimaryKey;
|
|
1398
1795
|
// Store ephemeral key if provided, for one-time use by the manager
|
|
1399
|
-
let oneTimePrivilegedKey =
|
|
1400
|
-
? undefined
|
|
1401
|
-
: new sdk_1.PrivateKey(ephemeralRootPrivilegedKey);
|
|
1796
|
+
let oneTimePrivilegedKey = ephemeralRootPrivilegedKey == null ? undefined : new sdk_1.PrivateKey(ephemeralRootPrivilegedKey);
|
|
1402
1797
|
// Create the ROOT PrivilegedKeyManager
|
|
1403
1798
|
this.rootPrivilegedKeyManager = new PrivilegedKeyManager_1.PrivilegedKeyManager(async (reason) => {
|
|
1404
1799
|
// 1. Use one-time key if available (for recovery)
|
|
@@ -1415,7 +1810,7 @@ class CWIStyleWalletManager {
|
|
|
1415
1810
|
const decryptedPrivileged = new sdk_1.SymmetricKey(privilegedDecryptor).decrypt(this.currentUMPToken.passwordPrimaryPrivileged);
|
|
1416
1811
|
return !!decryptedPrivileged; // Test passes if decryption works
|
|
1417
1812
|
}
|
|
1418
|
-
catch
|
|
1813
|
+
catch {
|
|
1419
1814
|
// Decryption failure means the password candidate is wrong — this is the
|
|
1420
1815
|
// expected rejection path for an incorrect password. Returning false causes
|
|
1421
1816
|
// the password-retriever loop to prompt the user again rather than crashing.
|
|
@@ -1430,18 +1825,26 @@ class CWIStyleWalletManager {
|
|
|
1430
1825
|
});
|
|
1431
1826
|
// Decrypt and load profiles if present in the token
|
|
1432
1827
|
this.profiles = []; // Clear existing profiles before loading
|
|
1433
|
-
if (
|
|
1828
|
+
if (this.currentUMPToken.profilesEncrypted != null && this.currentUMPToken.profilesEncrypted.length > 0) {
|
|
1434
1829
|
try {
|
|
1435
1830
|
const decryptedProfileBytes = new sdk_1.SymmetricKey(rootPrimaryKey).decrypt(this.currentUMPToken.profilesEncrypted);
|
|
1436
1831
|
const profilesJson = sdk_1.Utils.toUTF8(decryptedProfileBytes);
|
|
1437
|
-
|
|
1832
|
+
const profiles = JSON.parse(profilesJson);
|
|
1833
|
+
if (!Array.isArray(profiles) || profiles.length > 1000 || !profiles.every(isValidProfile)) {
|
|
1834
|
+
throw new Error('Decrypted profile data is invalid or exceeds supported bounds.');
|
|
1835
|
+
}
|
|
1836
|
+
this.profiles = profiles;
|
|
1438
1837
|
}
|
|
1439
1838
|
catch (error) {
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1839
|
+
this.profiles = [];
|
|
1840
|
+
this.telemetry.capture({
|
|
1841
|
+
name: 'wallet-toolbox.profile.load-failed',
|
|
1842
|
+
component: 'wallet-toolbox.cwi-manager',
|
|
1843
|
+
severity: 'error',
|
|
1844
|
+
error
|
|
1845
|
+
});
|
|
1846
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1847
|
+
throw new Error(`Failed to load profiles: ${message}`, { cause: error });
|
|
1445
1848
|
}
|
|
1446
1849
|
}
|
|
1447
1850
|
this.authenticated = true;
|
|
@@ -1568,7 +1971,7 @@ class CWIStyleWalletManager {
|
|
|
1568
1971
|
if (originator === this.adminOriginator) {
|
|
1569
1972
|
throw new Error('External applications are not allowed to use the admin originator.');
|
|
1570
1973
|
}
|
|
1571
|
-
while (!this.authenticated ||
|
|
1974
|
+
while (!this.authenticated || this.underlying == null) {
|
|
1572
1975
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
1573
1976
|
}
|
|
1574
1977
|
return await this.underlying.waitForAuthentication({}, originator);
|