@bopen-io/wallet-toolbox 1.7.18
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/.claude/settings.local.json +10 -0
- package/.env.template +22 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
- package/.github/ISSUE_TEMPLATE/discussion.md +24 -0
- package/.github/pull_request_template.md +22 -0
- package/.github/workflows/push.yaml +145 -0
- package/.prettierrc +10 -0
- package/CHANGELOG.md +280 -0
- package/CONTRIBUTING.md +89 -0
- package/README.md +43 -0
- package/docs/README.md +85 -0
- package/docs/client.md +19627 -0
- package/docs/monitor.md +953 -0
- package/docs/open-rpc/index.html +46 -0
- package/docs/services.md +6377 -0
- package/docs/setup.md +1268 -0
- package/docs/storage.md +5367 -0
- package/docs/wallet.md +19626 -0
- package/jest.config.ts +25 -0
- package/license.md +28 -0
- package/out/tsconfig.all.tsbuildinfo +1 -0
- package/package.json +63 -0
- package/src/CWIStyleWalletManager.ts +1999 -0
- package/src/Setup.ts +579 -0
- package/src/SetupClient.ts +322 -0
- package/src/SetupWallet.ts +108 -0
- package/src/SimpleWalletManager.ts +526 -0
- package/src/Wallet.ts +1169 -0
- package/src/WalletAuthenticationManager.ts +153 -0
- package/src/WalletLogger.ts +213 -0
- package/src/WalletPermissionsManager.ts +3660 -0
- package/src/WalletSettingsManager.ts +114 -0
- package/src/__tests/CWIStyleWalletManager.test.d.ts.map +1 -0
- package/src/__tests/CWIStyleWalletManager.test.js.map +1 -0
- package/src/__tests/CWIStyleWalletManager.test.ts +675 -0
- package/src/__tests/WalletPermissionsManager.callbacks.test.ts +323 -0
- package/src/__tests/WalletPermissionsManager.checks.test.ts +844 -0
- package/src/__tests/WalletPermissionsManager.encryption.test.ts +412 -0
- package/src/__tests/WalletPermissionsManager.fixtures.ts +307 -0
- package/src/__tests/WalletPermissionsManager.flows.test.ts +462 -0
- package/src/__tests/WalletPermissionsManager.initialization.test.ts +300 -0
- package/src/__tests/WalletPermissionsManager.pmodules.test.ts +798 -0
- package/src/__tests/WalletPermissionsManager.proxying.test.ts +724 -0
- package/src/__tests/WalletPermissionsManager.tokens.test.ts +503 -0
- package/src/index.all.ts +27 -0
- package/src/index.client.ts +25 -0
- package/src/index.mobile.ts +21 -0
- package/src/index.ts +1 -0
- package/src/monitor/Monitor.ts +412 -0
- package/src/monitor/MonitorDaemon.ts +188 -0
- package/src/monitor/README.md +3 -0
- package/src/monitor/__test/MonitorDaemon.man.test.ts +45 -0
- package/src/monitor/tasks/TaskCheckForProofs.ts +243 -0
- package/src/monitor/tasks/TaskCheckNoSends.ts +73 -0
- package/src/monitor/tasks/TaskClock.ts +33 -0
- package/src/monitor/tasks/TaskFailAbandoned.ts +54 -0
- package/src/monitor/tasks/TaskMonitorCallHistory.ts +26 -0
- package/src/monitor/tasks/TaskNewHeader.ts +93 -0
- package/src/monitor/tasks/TaskPurge.ts +68 -0
- package/src/monitor/tasks/TaskReorg.ts +89 -0
- package/src/monitor/tasks/TaskReviewStatus.ts +48 -0
- package/src/monitor/tasks/TaskSendWaiting.ts +122 -0
- package/src/monitor/tasks/TaskSyncWhenIdle.ts +26 -0
- package/src/monitor/tasks/TaskUnFail.ts +151 -0
- package/src/monitor/tasks/WalletMonitorTask.ts +47 -0
- package/src/sdk/CertOpsWallet.ts +18 -0
- package/src/sdk/PrivilegedKeyManager.ts +372 -0
- package/src/sdk/README.md +13 -0
- package/src/sdk/WERR_errors.ts +234 -0
- package/src/sdk/WalletError.ts +170 -0
- package/src/sdk/WalletErrorFromJson.ts +80 -0
- package/src/sdk/WalletServices.interfaces.ts +700 -0
- package/src/sdk/WalletSigner.interfaces.ts +11 -0
- package/src/sdk/WalletStorage.interfaces.ts +606 -0
- package/src/sdk/__test/CertificateLifeCycle.test.ts +131 -0
- package/src/sdk/__test/PrivilegedKeyManager.test.ts +738 -0
- package/src/sdk/__test/WalletError.test.ts +318 -0
- package/src/sdk/__test/validationHelpers.test.ts +21 -0
- package/src/sdk/index.ts +10 -0
- package/src/sdk/types.ts +226 -0
- package/src/services/README.md +11 -0
- package/src/services/ServiceCollection.ts +248 -0
- package/src/services/Services.ts +603 -0
- package/src/services/__tests/ARC.man.test.ts +123 -0
- package/src/services/__tests/ARC.timeout.man.test.ts +79 -0
- package/src/services/__tests/ArcGorillaPool.man.test.ts +108 -0
- package/src/services/__tests/arcServices.test.ts +8 -0
- package/src/services/__tests/bitrails.test.ts +56 -0
- package/src/services/__tests/getMerklePath.test.ts +15 -0
- package/src/services/__tests/getRawTx.test.ts +13 -0
- package/src/services/__tests/postBeef.test.ts +104 -0
- package/src/services/__tests/verifyBeef.test.ts +50 -0
- package/src/services/chaintracker/BHServiceClient.ts +212 -0
- package/src/services/chaintracker/ChaintracksChainTracker.ts +71 -0
- package/src/services/chaintracker/__tests/ChaintracksChainTracker.test.ts +33 -0
- package/src/services/chaintracker/__tests/ChaintracksServiceClient.test.ts +29 -0
- package/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.ts +72 -0
- package/src/services/chaintracker/chaintracks/Api/BulkIngestorApi.ts +83 -0
- package/src/services/chaintracker/chaintracks/Api/BulkStorageApi.ts +92 -0
- package/src/services/chaintracker/chaintracks/Api/ChaintracksApi.ts +64 -0
- package/src/services/chaintracker/chaintracks/Api/ChaintracksClientApi.ts +189 -0
- package/src/services/chaintracker/chaintracks/Api/ChaintracksFetchApi.ts +18 -0
- package/src/services/chaintracker/chaintracks/Api/ChaintracksFsApi.ts +58 -0
- package/src/services/chaintracker/chaintracks/Api/ChaintracksStorageApi.ts +386 -0
- package/src/services/chaintracker/chaintracks/Api/LiveIngestorApi.ts +25 -0
- package/src/services/chaintracker/chaintracks/Chaintracks.ts +609 -0
- package/src/services/chaintracker/chaintracks/ChaintracksService.ts +199 -0
- package/src/services/chaintracker/chaintracks/ChaintracksServiceClient.ts +154 -0
- package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.ts +176 -0
- package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDN.ts +174 -0
- package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDNBabbage.ts +18 -0
- package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.ts +113 -0
- package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainWs.ts +81 -0
- package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.ts +86 -0
- package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.ts +59 -0
- package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.ts +104 -0
- package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainWs.ts +66 -0
- package/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.ts +566 -0
- package/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.ts +219 -0
- package/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorCDNBabbage.test.ts +54 -0
- package/src/services/chaintracker/chaintracks/Ingest/__tests/LiveIngestorWhatsOnChainPoll.test.ts +33 -0
- package/src/services/chaintracker/chaintracks/Ingest/__tests/WhatsOnChainServices.test.ts +124 -0
- package/src/services/chaintracker/chaintracks/Storage/BulkStorageBase.ts +92 -0
- package/src/services/chaintracker/chaintracks/Storage/ChaintracksKnexMigrations.ts +104 -0
- package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.ts +382 -0
- package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.ts +574 -0
- package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.ts +438 -0
- package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageMemory.ts +29 -0
- package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.ts +304 -0
- package/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageIdb.test.ts +102 -0
- package/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageKnex.test.ts +45 -0
- package/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.ts +77 -0
- package/src/services/chaintracker/chaintracks/__tests/ChaintracksClientApi.test.ts +192 -0
- package/src/services/chaintracker/chaintracks/__tests/LocalCdnServer.ts +75 -0
- package/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.ts +62 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNetBlockHeaders.json +1 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_0.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_1.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_2.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_3.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNetBlockHeaders.json +1 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_0.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_1.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_2.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_3.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNetBlockHeaders.json +1 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_0.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_1.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_2.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_3.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNetBlockHeaders.json +1 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_0.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_1.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_2.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_3.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_4.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNetBlockHeaders.json +1 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_0.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_1.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_2.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_3.headers +0 -0
- package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_4.headers +0 -0
- package/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.ts +92 -0
- package/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.ts +111 -0
- package/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.ts +91 -0
- package/src/services/chaintracker/chaintracks/createIdbChaintracks.ts +60 -0
- package/src/services/chaintracker/chaintracks/createKnexChaintracks.ts +65 -0
- package/src/services/chaintracker/chaintracks/createNoDbChaintracks.ts +60 -0
- package/src/services/chaintracker/chaintracks/index.all.ts +12 -0
- package/src/services/chaintracker/chaintracks/index.client.ts +4 -0
- package/src/services/chaintracker/chaintracks/index.mobile.ts +37 -0
- package/src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts +975 -0
- package/src/services/chaintracker/chaintracks/util/BulkFileDataReader.ts +60 -0
- package/src/services/chaintracker/chaintracks/util/BulkFilesReader.ts +336 -0
- package/src/services/chaintracker/chaintracks/util/BulkHeaderFile.ts +247 -0
- package/src/services/chaintracker/chaintracks/util/ChaintracksFetch.ts +69 -0
- package/src/services/chaintracker/chaintracks/util/ChaintracksFs.ts +141 -0
- package/src/services/chaintracker/chaintracks/util/HeightRange.ts +153 -0
- package/src/services/chaintracker/chaintracks/util/SingleWriterMultiReaderLock.ts +76 -0
- package/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.ts +304 -0
- package/src/services/chaintracker/chaintracks/util/__tests/ChaintracksFetch.test.ts +60 -0
- package/src/services/chaintracker/chaintracks/util/__tests/HeightRange.test.ts +67 -0
- package/src/services/chaintracker/chaintracks/util/__tests/SingleWriterMultiReaderLock.test.ts +49 -0
- package/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.ts +573 -0
- package/src/services/chaintracker/chaintracks/util/dirtyHashes.ts +29 -0
- package/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.ts +432 -0
- package/src/services/chaintracker/index.all.ts +4 -0
- package/src/services/chaintracker/index.client.ts +4 -0
- package/src/services/chaintracker/index.mobile.ts +4 -0
- package/src/services/createDefaultWalletServicesOptions.ts +77 -0
- package/src/services/index.ts +1 -0
- package/src/services/processingErrors/arcSuccessError.json +76 -0
- package/src/services/providers/ARC.ts +350 -0
- package/src/services/providers/Bitails.ts +256 -0
- package/src/services/providers/SdkWhatsOnChain.ts +83 -0
- package/src/services/providers/WhatsOnChain.ts +883 -0
- package/src/services/providers/__tests/WhatsOnChain.test.ts +242 -0
- package/src/services/providers/__tests/exchangeRates.test.ts +18 -0
- package/src/services/providers/exchangeRates.ts +265 -0
- package/src/services/providers/getBeefForTxid.ts +369 -0
- package/src/signer/README.md +5 -0
- package/src/signer/WalletSigner.ts +17 -0
- package/src/signer/methods/acquireDirectCertificate.ts +52 -0
- package/src/signer/methods/buildSignableTransaction.ts +183 -0
- package/src/signer/methods/completeSignedTransaction.ts +117 -0
- package/src/signer/methods/createAction.ts +172 -0
- package/src/signer/methods/internalizeAction.ts +106 -0
- package/src/signer/methods/proveCertificate.ts +43 -0
- package/src/signer/methods/signAction.ts +54 -0
- package/src/storage/README.md +14 -0
- package/src/storage/StorageIdb.ts +2304 -0
- package/src/storage/StorageKnex.ts +1425 -0
- package/src/storage/StorageProvider.ts +810 -0
- package/src/storage/StorageReader.ts +194 -0
- package/src/storage/StorageReaderWriter.ts +432 -0
- package/src/storage/StorageSyncReader.ts +34 -0
- package/src/storage/WalletStorageManager.ts +943 -0
- package/src/storage/__test/StorageIdb.test.ts +43 -0
- package/src/storage/__test/WalletStorageManager.test.ts +275 -0
- package/src/storage/__test/adminStats.man.test.ts +89 -0
- package/src/storage/__test/getBeefForTransaction.test.ts +385 -0
- package/src/storage/index.all.ts +11 -0
- package/src/storage/index.client.ts +7 -0
- package/src/storage/index.mobile.ts +6 -0
- package/src/storage/methods/ListActionsSpecOp.ts +70 -0
- package/src/storage/methods/ListOutputsSpecOp.ts +129 -0
- package/src/storage/methods/__test/GenerateChange/generateChangeSdk.test.ts +1057 -0
- package/src/storage/methods/__test/GenerateChange/randomValsUsed1.ts +20 -0
- package/src/storage/methods/__test/offsetKey.test.ts +274 -0
- package/src/storage/methods/attemptToPostReqsToNetwork.ts +389 -0
- package/src/storage/methods/createAction.ts +947 -0
- package/src/storage/methods/generateChange.ts +556 -0
- package/src/storage/methods/getBeefForTransaction.ts +139 -0
- package/src/storage/methods/getSyncChunk.ts +293 -0
- package/src/storage/methods/internalizeAction.ts +562 -0
- package/src/storage/methods/listActionsIdb.ts +183 -0
- package/src/storage/methods/listActionsKnex.ts +226 -0
- package/src/storage/methods/listCertificates.ts +73 -0
- package/src/storage/methods/listOutputsIdb.ts +203 -0
- package/src/storage/methods/listOutputsKnex.ts +263 -0
- package/src/storage/methods/offsetKey.ts +89 -0
- package/src/storage/methods/processAction.ts +420 -0
- package/src/storage/methods/purgeData.ts +251 -0
- package/src/storage/methods/purgeDataIdb.ts +10 -0
- package/src/storage/methods/reviewStatus.ts +101 -0
- package/src/storage/methods/reviewStatusIdb.ts +43 -0
- package/src/storage/methods/utils.Buffer.ts +33 -0
- package/src/storage/methods/utils.ts +56 -0
- package/src/storage/remoting/StorageClient.ts +567 -0
- package/src/storage/remoting/StorageMobile.ts +544 -0
- package/src/storage/remoting/StorageServer.ts +291 -0
- package/src/storage/remoting/__test/StorageClient.test.ts +113 -0
- package/src/storage/schema/KnexMigrations.ts +489 -0
- package/src/storage/schema/StorageIdbSchema.ts +150 -0
- package/src/storage/schema/entities/EntityBase.ts +210 -0
- package/src/storage/schema/entities/EntityCertificate.ts +188 -0
- package/src/storage/schema/entities/EntityCertificateField.ts +136 -0
- package/src/storage/schema/entities/EntityCommission.ts +148 -0
- package/src/storage/schema/entities/EntityOutput.ts +290 -0
- package/src/storage/schema/entities/EntityOutputBasket.ts +153 -0
- package/src/storage/schema/entities/EntityOutputTag.ts +121 -0
- package/src/storage/schema/entities/EntityOutputTagMap.ts +123 -0
- package/src/storage/schema/entities/EntityProvenTx.ts +319 -0
- package/src/storage/schema/entities/EntityProvenTxReq.ts +580 -0
- package/src/storage/schema/entities/EntitySyncState.ts +389 -0
- package/src/storage/schema/entities/EntityTransaction.ts +306 -0
- package/src/storage/schema/entities/EntityTxLabel.ts +121 -0
- package/src/storage/schema/entities/EntityTxLabelMap.ts +123 -0
- package/src/storage/schema/entities/EntityUser.ts +112 -0
- package/src/storage/schema/entities/MergeEntity.ts +73 -0
- package/src/storage/schema/entities/__tests/CertificateFieldTests.test.ts +353 -0
- package/src/storage/schema/entities/__tests/CertificateTests.test.ts +354 -0
- package/src/storage/schema/entities/__tests/CommissionTests.test.ts +371 -0
- package/src/storage/schema/entities/__tests/OutputBasketTests.test.ts +278 -0
- package/src/storage/schema/entities/__tests/OutputTagMapTests.test.ts +242 -0
- package/src/storage/schema/entities/__tests/OutputTagTests.test.ts +288 -0
- package/src/storage/schema/entities/__tests/OutputTests.test.ts +464 -0
- package/src/storage/schema/entities/__tests/ProvenTxReqTests.test.ts +340 -0
- package/src/storage/schema/entities/__tests/ProvenTxTests.test.ts +504 -0
- package/src/storage/schema/entities/__tests/SyncStateTests.test.ts +288 -0
- package/src/storage/schema/entities/__tests/TransactionTests.test.ts +604 -0
- package/src/storage/schema/entities/__tests/TxLabelMapTests.test.ts +361 -0
- package/src/storage/schema/entities/__tests/TxLabelTests.test.ts +198 -0
- package/src/storage/schema/entities/__tests/stampLogTests.test.ts +90 -0
- package/src/storage/schema/entities/__tests/usersTests.test.ts +340 -0
- package/src/storage/schema/entities/index.ts +16 -0
- package/src/storage/schema/tables/TableCertificate.ts +21 -0
- package/src/storage/schema/tables/TableCertificateField.ts +12 -0
- package/src/storage/schema/tables/TableCommission.ts +13 -0
- package/src/storage/schema/tables/TableMonitorEvent.ts +9 -0
- package/src/storage/schema/tables/TableOutput.ts +64 -0
- package/src/storage/schema/tables/TableOutputBasket.ts +12 -0
- package/src/storage/schema/tables/TableOutputTag.ts +10 -0
- package/src/storage/schema/tables/TableOutputTagMap.ts +9 -0
- package/src/storage/schema/tables/TableProvenTx.ts +14 -0
- package/src/storage/schema/tables/TableProvenTxReq.ts +65 -0
- package/src/storage/schema/tables/TableSettings.ts +17 -0
- package/src/storage/schema/tables/TableSyncState.ts +18 -0
- package/src/storage/schema/tables/TableTransaction.ts +54 -0
- package/src/storage/schema/tables/TableTxLabel.ts +10 -0
- package/src/storage/schema/tables/TableTxLabelMap.ts +9 -0
- package/src/storage/schema/tables/TableUser.ts +16 -0
- package/src/storage/schema/tables/index.ts +16 -0
- package/src/storage/sync/StorageMySQLDojoReader.ts +696 -0
- package/src/storage/sync/index.ts +1 -0
- package/src/utility/Format.ts +133 -0
- package/src/utility/README.md +3 -0
- package/src/utility/ReaderUint8Array.ts +187 -0
- package/src/utility/ScriptTemplateBRC29.ts +73 -0
- package/src/utility/__tests/utilityHelpers.noBuffer.test.ts +109 -0
- package/src/utility/aggregateResults.ts +68 -0
- package/src/utility/identityUtils.ts +159 -0
- package/src/utility/index.all.ts +7 -0
- package/src/utility/index.client.ts +7 -0
- package/src/utility/parseTxScriptOffsets.ts +29 -0
- package/src/utility/stampLog.ts +69 -0
- package/src/utility/tscProofToMerklePath.ts +48 -0
- package/src/utility/utilityHelpers.buffer.ts +34 -0
- package/src/utility/utilityHelpers.noBuffer.ts +60 -0
- package/src/utility/utilityHelpers.ts +275 -0
- package/src/wab-client/WABClient.ts +94 -0
- package/src/wab-client/__tests/WABClient.man.test.ts +59 -0
- package/src/wab-client/auth-method-interactors/AuthMethodInteractor.ts +47 -0
- package/src/wab-client/auth-method-interactors/DevConsoleInteractor.ts +73 -0
- package/src/wab-client/auth-method-interactors/PersonaIDInteractor.ts +35 -0
- package/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.ts +72 -0
- package/syncVersions.js +71 -0
- package/test/Wallet/StorageClient/storageClient.man.test.ts +75 -0
- package/test/Wallet/action/abortAction.test.ts +47 -0
- package/test/Wallet/action/createAction.test.ts +299 -0
- package/test/Wallet/action/createAction2.test.ts +1273 -0
- package/test/Wallet/action/createActionToGenerateBeefs.man.test.ts +293 -0
- package/test/Wallet/action/internalizeAction.a.test.ts +286 -0
- package/test/Wallet/action/internalizeAction.test.ts +682 -0
- package/test/Wallet/action/relinquishOutput.test.ts +37 -0
- package/test/Wallet/certificate/acquireCertificate.test.ts +298 -0
- package/test/Wallet/certificate/listCertificates.test.ts +346 -0
- package/test/Wallet/construct/Wallet.constructor.test.ts +57 -0
- package/test/Wallet/get/getHeaderForHeight.test.ts +82 -0
- package/test/Wallet/get/getHeight.test.ts +52 -0
- package/test/Wallet/get/getKnownTxids.test.ts +86 -0
- package/test/Wallet/get/getNetwork.test.ts +27 -0
- package/test/Wallet/get/getVersion.test.ts +27 -0
- package/test/Wallet/list/listActions.test.ts +279 -0
- package/test/Wallet/list/listActions2.test.ts +1381 -0
- package/test/Wallet/list/listCertificates.test.ts +118 -0
- package/test/Wallet/list/listOutputs.test.ts +447 -0
- package/test/Wallet/live/walletLive.man.test.ts +521 -0
- package/test/Wallet/local/localWallet.man.test.ts +93 -0
- package/test/Wallet/local/localWallet2.man.test.ts +277 -0
- package/test/Wallet/signAction/mountaintop.man.test.ts +130 -0
- package/test/Wallet/specOps/specOps.man.test.ts +220 -0
- package/test/Wallet/support/janitor.man.test.ts +40 -0
- package/test/Wallet/support/operations.man.test.ts +407 -0
- package/test/Wallet/support/reqErrorReview.2025.05.06.man.test.ts +347 -0
- package/test/Wallet/sync/Wallet.sync.test.ts +215 -0
- package/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.ts +203 -0
- package/test/Wallet/sync/setActive.test.ts +170 -0
- package/test/WalletClient/LocalKVStore.man.test.ts +114 -0
- package/test/WalletClient/WERR.man.test.ts +35 -0
- package/test/bsv-ts-sdk/LocalKVStore.test.ts +102 -0
- package/test/checkDB.ts +57 -0
- package/test/checkdb +0 -0
- package/test/examples/backup.man.test.ts +59 -0
- package/test/examples/pushdrop.test.ts +282 -0
- package/test/monitor/Monitor.test.ts +620 -0
- package/test/services/Services.test.ts +263 -0
- package/test/storage/KnexMigrations.test.ts +86 -0
- package/test/storage/StorageMySQLDojoReader.man.test.ts +60 -0
- package/test/storage/count.test.ts +177 -0
- package/test/storage/find.test.ts +195 -0
- package/test/storage/findLegacy.test.ts +67 -0
- package/test/storage/idb/allocateChange.test.ts +251 -0
- package/test/storage/idb/count.test.ts +158 -0
- package/test/storage/idb/find.test.ts +177 -0
- package/test/storage/idb/idbSpeed.test.ts +36 -0
- package/test/storage/idb/insert.test.ts +268 -0
- package/test/storage/idb/transactionAbort.test.ts +108 -0
- package/test/storage/idb/update.test.ts +999 -0
- package/test/storage/insert.test.ts +278 -0
- package/test/storage/update.test.ts +1021 -0
- package/test/storage/update2.test.ts +897 -0
- package/test/utils/TestUtilsWalletStorage.ts +2526 -0
- package/test/utils/localWalletMethods.ts +363 -0
- package/test/utils/removeFailedFromDatabase.sql +17 -0
- package/ts2md.json +44 -0
- package/tsconfig.all.json +31 -0
- package/tsconfig.client.json +29 -0
- package/tsconfig.json +17 -0
- package/tsconfig.mobile.json +28 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LookupAnswer,
|
|
3
|
+
Transaction,
|
|
4
|
+
PushDrop,
|
|
5
|
+
VerifiableCertificate,
|
|
6
|
+
Utils,
|
|
7
|
+
ProtoWallet,
|
|
8
|
+
LookupResolver,
|
|
9
|
+
DiscoverCertificatesResult,
|
|
10
|
+
IdentityCertificate,
|
|
11
|
+
IdentityCertifier,
|
|
12
|
+
Base64String
|
|
13
|
+
} from '@bsv/sdk'
|
|
14
|
+
import { Certifier, TrustSettings } from '../WalletSettingsManager'
|
|
15
|
+
|
|
16
|
+
const OUTPUT_INDEX = 0
|
|
17
|
+
|
|
18
|
+
// Our extended certificate includes certifierInfo.
|
|
19
|
+
export interface ExtendedVerifiableCertificate extends IdentityCertificate {
|
|
20
|
+
certifierInfo: IdentityCertifier
|
|
21
|
+
publiclyRevealedKeyring: Record<string, Base64String>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// --- Helper Types for Grouping ---
|
|
25
|
+
|
|
26
|
+
interface IdentityGroup {
|
|
27
|
+
totalTrust: number
|
|
28
|
+
members: ExtendedVerifiableCertificate[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Transforms an array of VerifiableCertificate instances according to the trust settings.
|
|
33
|
+
* Only certificates whose grouped total trust meets the threshold are returned,
|
|
34
|
+
* and each certificate is augmented with a certifierInfo property.
|
|
35
|
+
*
|
|
36
|
+
* @param trustSettings - the user's trust settings including trustLevel and trusted certifiers.
|
|
37
|
+
* @param certificates - an array of VerifiableCertificate objects.
|
|
38
|
+
* @returns a DiscoverCertificatesResult with totalCertificates and ordered certificates.
|
|
39
|
+
*/
|
|
40
|
+
export const transformVerifiableCertificatesWithTrust = (
|
|
41
|
+
trustSettings: TrustSettings,
|
|
42
|
+
certificates: VerifiableCertificate[]
|
|
43
|
+
): DiscoverCertificatesResult => {
|
|
44
|
+
// Group certificates by subject while accumulating trust.
|
|
45
|
+
const identityGroups: Record<string, IdentityGroup> = {}
|
|
46
|
+
// Cache certifier lookups.
|
|
47
|
+
const certifierCache: Record<string, Certifier> = {}
|
|
48
|
+
|
|
49
|
+
certificates.forEach(cert => {
|
|
50
|
+
const { subject, certifier } = cert
|
|
51
|
+
if (!subject || !certifier) return
|
|
52
|
+
|
|
53
|
+
// Lookup and cache certifier details from trustSettings.
|
|
54
|
+
if (!certifierCache[certifier]) {
|
|
55
|
+
const found = trustSettings.trustedCertifiers.find(x => x.identityKey === certifier)
|
|
56
|
+
if (!found) return // Skip this certificate if its certifier is not trusted.
|
|
57
|
+
certifierCache[certifier] = found
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Create the IdentityCertifier object that we want to attach.
|
|
61
|
+
const certifierInfo: IdentityCertifier = {
|
|
62
|
+
name: certifierCache[certifier].name,
|
|
63
|
+
iconUrl: certifierCache[certifier].iconUrl || '',
|
|
64
|
+
description: certifierCache[certifier].description,
|
|
65
|
+
trust: certifierCache[certifier].trust
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Create an extended certificate that includes certifierInfo.
|
|
69
|
+
// Note: We use object spread to copy over all properties from the original certificate.
|
|
70
|
+
const extendedCert: IdentityCertificate = {
|
|
71
|
+
...cert,
|
|
72
|
+
signature: cert.signature!, // We know it exists at this point
|
|
73
|
+
decryptedFields: cert.decryptedFields as Record<string, string>,
|
|
74
|
+
publiclyRevealedKeyring: cert.keyring,
|
|
75
|
+
certifierInfo
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Group certificates by subject.
|
|
79
|
+
if (!identityGroups[subject]) {
|
|
80
|
+
identityGroups[subject] = { totalTrust: 0, members: [] }
|
|
81
|
+
}
|
|
82
|
+
identityGroups[subject].totalTrust += certifierInfo.trust
|
|
83
|
+
identityGroups[subject].members.push(extendedCert)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// Filter out groups that do not meet the trust threshold and flatten the results.
|
|
87
|
+
const finalResults: ExtendedVerifiableCertificate[] = []
|
|
88
|
+
Object.values(identityGroups).forEach(group => {
|
|
89
|
+
if (group.totalTrust >= trustSettings.trustLevel) {
|
|
90
|
+
finalResults.push(...group.members)
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
// Sort the certificates by their certifier trust in descending order.
|
|
95
|
+
finalResults.sort((a, b) => b.certifierInfo.trust - a.certifierInfo.trust)
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
totalCertificates: finalResults.length,
|
|
99
|
+
certificates: finalResults
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Performs an identity overlay service lookup query and returns the parsed results
|
|
105
|
+
*
|
|
106
|
+
* @param query
|
|
107
|
+
* @returns
|
|
108
|
+
*/
|
|
109
|
+
export const queryOverlay = async (query: unknown, resolver: LookupResolver): Promise<VerifiableCertificate[]> => {
|
|
110
|
+
const results = await resolver.query({
|
|
111
|
+
service: 'ls_identity',
|
|
112
|
+
query
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
return await parseResults(results)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Internal func: Parse the returned UTXOs Decrypt and verify the certificates and signatures Return the set of identity keys, certificates and decrypted certificate fields
|
|
120
|
+
*
|
|
121
|
+
* @param {Output[]} outputs
|
|
122
|
+
* @returns {Promise<VerifiableCertificate[]>}
|
|
123
|
+
*/
|
|
124
|
+
export const parseResults = async (lookupResult: LookupAnswer): Promise<VerifiableCertificate[]> => {
|
|
125
|
+
if (lookupResult.type === 'output-list') {
|
|
126
|
+
const parsedResults: VerifiableCertificate[] = []
|
|
127
|
+
|
|
128
|
+
for (const output of lookupResult.outputs) {
|
|
129
|
+
try {
|
|
130
|
+
const tx = Transaction.fromBEEF(output.beef)
|
|
131
|
+
// Decode the Identity token fields from the Bitcoin outputScript
|
|
132
|
+
const decodedOutput = PushDrop.decode(tx.outputs[output.outputIndex].lockingScript)
|
|
133
|
+
|
|
134
|
+
// Parse out the certificate and relevant data
|
|
135
|
+
const certificate: VerifiableCertificate = JSON.parse(Utils.toUTF8(decodedOutput.fields[0])) // TEST
|
|
136
|
+
const verifiableCert = new VerifiableCertificate(
|
|
137
|
+
certificate.type,
|
|
138
|
+
certificate.serialNumber,
|
|
139
|
+
certificate.subject,
|
|
140
|
+
certificate.certifier,
|
|
141
|
+
certificate.revocationOutpoint,
|
|
142
|
+
certificate.fields,
|
|
143
|
+
certificate.keyring,
|
|
144
|
+
certificate.signature
|
|
145
|
+
)
|
|
146
|
+
const decryptedFields = await verifiableCert.decryptFields(new ProtoWallet('anyone'))
|
|
147
|
+
// Verify the certificate signature is correct
|
|
148
|
+
await verifiableCert.verify()
|
|
149
|
+
verifiableCert.decryptedFields = decryptedFields
|
|
150
|
+
parsedResults.push(verifiableCert)
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error(error)
|
|
153
|
+
// do nothing
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return parsedResults
|
|
157
|
+
}
|
|
158
|
+
return []
|
|
159
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Utils as SdkUtils } from '@bsv/sdk'
|
|
2
|
+
|
|
3
|
+
export interface TxScriptOffsets {
|
|
4
|
+
inputs: { vin: number; offset: number; length: number }[]
|
|
5
|
+
outputs: { vout: number; offset: number; length: number }[]
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function parseTxScriptOffsets(rawTx: number[]): TxScriptOffsets {
|
|
9
|
+
const br = new SdkUtils.Reader(rawTx)
|
|
10
|
+
const inputs: { vin: number; offset: number; length: number }[] = []
|
|
11
|
+
const outputs: { vout: number; offset: number; length: number }[] = []
|
|
12
|
+
|
|
13
|
+
br.pos += 4 // version
|
|
14
|
+
const inputsLength = br.readVarIntNum()
|
|
15
|
+
for (let i = 0; i < inputsLength; i++) {
|
|
16
|
+
br.pos += 36 // txid and vout
|
|
17
|
+
const scriptLength = br.readVarIntNum()
|
|
18
|
+
inputs.push({ vin: i, offset: br.pos, length: scriptLength })
|
|
19
|
+
br.pos += scriptLength + 4 // script and sequence
|
|
20
|
+
}
|
|
21
|
+
const outputsLength = br.readVarIntNum()
|
|
22
|
+
for (let i = 0; i < outputsLength; i++) {
|
|
23
|
+
br.pos += 8 // satoshis
|
|
24
|
+
const scriptLength = br.readVarIntNum()
|
|
25
|
+
outputs.push({ vout: i, offset: br.pos, length: scriptLength })
|
|
26
|
+
br.pos += scriptLength
|
|
27
|
+
}
|
|
28
|
+
return { inputs, outputs }
|
|
29
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* If a log is being kept, add a time stamped line.
|
|
3
|
+
* @param log Optional time stamped log to extend, or an object with a log property to update
|
|
4
|
+
* @param lineToAdd Content to add to line.
|
|
5
|
+
* @returns undefined or log extended by time stamped `lineToAdd` and new line.
|
|
6
|
+
*/
|
|
7
|
+
export function stampLog(log: string | undefined | { log?: string }, lineToAdd: string): string | undefined {
|
|
8
|
+
const add = `${new Date().toISOString()} ${lineToAdd}\n`
|
|
9
|
+
if (typeof log === 'object' && typeof log.log === 'string') return (log.log = log.log + add)
|
|
10
|
+
if (typeof log === 'string') return log + add
|
|
11
|
+
return undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Replaces individual timestamps with delta msecs.
|
|
16
|
+
* Looks for two network crossings and adjusts clock for clock skew if found.
|
|
17
|
+
* Assumes log built by repeated calls to `stampLog`
|
|
18
|
+
* @param log Each logged event starts with ISO time stamp, space, rest of line, terminated by `\n`.
|
|
19
|
+
* @returns reformated multi-line event log
|
|
20
|
+
*/
|
|
21
|
+
export function stampLogFormat(log?: string): string {
|
|
22
|
+
if (typeof log !== 'string') return ''
|
|
23
|
+
const logLines = log.split('\n')
|
|
24
|
+
const data: {
|
|
25
|
+
when: number
|
|
26
|
+
rest: string
|
|
27
|
+
delta: number
|
|
28
|
+
newClock: boolean
|
|
29
|
+
}[] = []
|
|
30
|
+
let last = 0
|
|
31
|
+
const newClocks: number[] = []
|
|
32
|
+
for (const line of logLines) {
|
|
33
|
+
const spaceAt = line.indexOf(' ')
|
|
34
|
+
if (spaceAt > -1) {
|
|
35
|
+
const when = new Date(line.substring(0, spaceAt)).getTime()
|
|
36
|
+
const rest = line.substring(spaceAt + 1)
|
|
37
|
+
const delta = when - (last || when)
|
|
38
|
+
const newClock = rest.indexOf('**NETWORK**') > -1
|
|
39
|
+
if (newClock) newClocks.push(data.length)
|
|
40
|
+
data.push({ when, rest, delta, newClock })
|
|
41
|
+
last = when
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const total = data[data.length - 1].when - data[0].when
|
|
45
|
+
if (newClocks.length % 2 === 0) {
|
|
46
|
+
// Adjust for paired network crossing times and clock skew between clocks.
|
|
47
|
+
let network = total
|
|
48
|
+
let lastNewClock = 0
|
|
49
|
+
for (const newClock of newClocks) {
|
|
50
|
+
network -= data[newClock - 1].when - data[lastNewClock].when
|
|
51
|
+
lastNewClock = newClock
|
|
52
|
+
}
|
|
53
|
+
network -= data[data.length - 1].when - data[lastNewClock].when
|
|
54
|
+
let networks = newClocks.length
|
|
55
|
+
for (const newClock of newClocks) {
|
|
56
|
+
const n = networks > 1 ? Math.floor(network / networks) : network
|
|
57
|
+
data[newClock].delta = n
|
|
58
|
+
network -= n
|
|
59
|
+
networks--
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
let log2 = `${new Date(data[0].when).toISOString()} Total = ${total} msecs\n`
|
|
63
|
+
for (const d of data) {
|
|
64
|
+
let df = d.delta.toString()
|
|
65
|
+
df = `${' '.repeat(8 - df.length)}${df}`
|
|
66
|
+
log2 += `${df} ${d.rest}\n`
|
|
67
|
+
}
|
|
68
|
+
return log2
|
|
69
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { MerklePath } from '@bsv/sdk'
|
|
2
|
+
|
|
3
|
+
export interface TscMerkleProofApi {
|
|
4
|
+
height: number
|
|
5
|
+
index: number
|
|
6
|
+
nodes: string[]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function convertProofToMerklePath(txid: string, proof: TscMerkleProofApi): MerklePath {
|
|
10
|
+
const blockHeight = proof.height
|
|
11
|
+
const treeHeight = proof.nodes.length
|
|
12
|
+
type Leaf = {
|
|
13
|
+
offset: number
|
|
14
|
+
hash?: string
|
|
15
|
+
txid?: boolean
|
|
16
|
+
duplicate?: boolean
|
|
17
|
+
}
|
|
18
|
+
const path: Leaf[][] = Array(treeHeight)
|
|
19
|
+
.fill(0)
|
|
20
|
+
.map(() => [])
|
|
21
|
+
let index = proof.index
|
|
22
|
+
for (let level = 0; level < treeHeight; level++) {
|
|
23
|
+
const node = proof.nodes[level]
|
|
24
|
+
const isOdd = index % 2 === 1
|
|
25
|
+
const offset = isOdd ? index - 1 : index + 1
|
|
26
|
+
const leaf: Leaf = { offset }
|
|
27
|
+
if (node === '*' || (level === 0 && node === txid)) {
|
|
28
|
+
leaf.duplicate = true
|
|
29
|
+
} else {
|
|
30
|
+
leaf.hash = node
|
|
31
|
+
}
|
|
32
|
+
path[level].push(leaf)
|
|
33
|
+
if (level === 0) {
|
|
34
|
+
const txidLeaf: Leaf = {
|
|
35
|
+
offset: proof.index,
|
|
36
|
+
hash: txid,
|
|
37
|
+
txid: true
|
|
38
|
+
}
|
|
39
|
+
if (isOdd) {
|
|
40
|
+
path[0].push(txidLeaf)
|
|
41
|
+
} else {
|
|
42
|
+
path[0].unshift(txidLeaf)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
index = index >> 1
|
|
46
|
+
}
|
|
47
|
+
return new MerklePath(blockHeight, path)
|
|
48
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coerce a value to Buffer if currently encoded as a string or
|
|
3
|
+
* @param val Buffer or string or number[]. If string, encoding param applies. If number[], Buffer.from constructor is used.
|
|
4
|
+
* @param encoding defaults to 'hex'. Only applies to val of type string
|
|
5
|
+
* @returns input val if it is a Buffer or new Buffer from string val
|
|
6
|
+
* @publicbody
|
|
7
|
+
*/
|
|
8
|
+
export function asBuffer(val: Buffer | string | number[], encoding?: BufferEncoding): Buffer {
|
|
9
|
+
let b: Buffer
|
|
10
|
+
if (Buffer.isBuffer(val)) b = val
|
|
11
|
+
else if (typeof val === 'string') b = Buffer.from(val, encoding ?? 'hex')
|
|
12
|
+
else b = Buffer.from(val)
|
|
13
|
+
return b
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Coerce a value to an encoded string if currently a Buffer or number[]
|
|
18
|
+
* @param val Buffer or string or number[]. If string, encoding param applies. If number[], Buffer.from constructor is used.
|
|
19
|
+
* @param encoding defaults to 'hex'
|
|
20
|
+
* @returns input val if it is a string; or if number[], first converted to Buffer then as Buffer; if Buffer encoded using `encoding`
|
|
21
|
+
* @publicbody
|
|
22
|
+
*/
|
|
23
|
+
export function asString(val: Buffer | string | number[], encoding?: BufferEncoding): string {
|
|
24
|
+
if (Array.isArray(val)) val = Buffer.from(val)
|
|
25
|
+
return Buffer.isBuffer(val) ? val.toString(encoding ?? 'hex') : val
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function asArray(val: Buffer | string | number[], encoding?: BufferEncoding): number[] {
|
|
29
|
+
let a: number[]
|
|
30
|
+
if (Array.isArray(val)) a = val
|
|
31
|
+
else if (Buffer.isBuffer(val)) a = Array.from(val)
|
|
32
|
+
else a = Array.from(Buffer.from(val, encoding || 'hex'))
|
|
33
|
+
return a
|
|
34
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Utils } from '@bsv/sdk'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convert a value to an encoded string if currently an encoded string or number[] or Uint8Array.
|
|
5
|
+
* @param val string or number[] or Uint8Array. If string, encoding must be hex. If number[], each value must be 0..255.
|
|
6
|
+
* @param enc optional encoding type if val is string, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.
|
|
7
|
+
* @param returnEnc optional encoding type for returned string if different from `enc`, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.
|
|
8
|
+
* @returns hex encoded string representation of val.
|
|
9
|
+
* @publicbody
|
|
10
|
+
*/
|
|
11
|
+
export function asString(
|
|
12
|
+
val: string | number[] | Uint8Array,
|
|
13
|
+
enc?: 'hex' | 'utf8' | 'base64',
|
|
14
|
+
returnEnc?: 'hex' | 'utf8' | 'base64'
|
|
15
|
+
): string {
|
|
16
|
+
enc ||= 'hex'
|
|
17
|
+
returnEnc ||= enc
|
|
18
|
+
if (typeof val === 'string') {
|
|
19
|
+
if (enc === returnEnc) return val
|
|
20
|
+
val = asUint8Array(val, enc)
|
|
21
|
+
}
|
|
22
|
+
let v = Array.isArray(val) ? val : Array.from(val)
|
|
23
|
+
switch (returnEnc) {
|
|
24
|
+
case 'utf8':
|
|
25
|
+
return Utils.toUTF8(v)
|
|
26
|
+
case 'base64':
|
|
27
|
+
return Utils.toBase64(v)
|
|
28
|
+
}
|
|
29
|
+
return Utils.toHex(v)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Convert a value to number[] if currently an encoded string or number[] or Uint8Array.
|
|
34
|
+
* @param val string or number[] or Uint8Array. If string, encoding must be hex. If number[], each value must be 0..255.
|
|
35
|
+
* @param enc optional encoding type if val is string, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.
|
|
36
|
+
* @returns number[] array of byte values representation of val.
|
|
37
|
+
* @publicbody
|
|
38
|
+
*/
|
|
39
|
+
export function asArray(val: string | number[] | Uint8Array, enc?: 'hex' | 'utf8' | 'base64'): number[] {
|
|
40
|
+
if (Array.isArray(val)) return val
|
|
41
|
+
if (typeof val !== 'string') return Array.from(val)
|
|
42
|
+
enc ||= 'hex'
|
|
43
|
+
let a: number[] = Utils.toArray(val, enc)
|
|
44
|
+
return a
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Convert a value to Uint8Array if currently an encoded string or number[] or Uint8Array.
|
|
49
|
+
* @param val string or number[] or Uint8Array. If string, encoding must be hex. If number[], each value must be 0..255.
|
|
50
|
+
* @param enc optional encoding type if val is string, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.
|
|
51
|
+
* @returns Uint8Array representation of val.
|
|
52
|
+
* @publicbody
|
|
53
|
+
*/
|
|
54
|
+
export function asUint8Array(val: string | number[] | Uint8Array, enc?: 'hex' | 'utf8' | 'base64'): Uint8Array {
|
|
55
|
+
if (Array.isArray(val)) return Uint8Array.from(val)
|
|
56
|
+
if (typeof val !== 'string') return val
|
|
57
|
+
enc ||= 'hex'
|
|
58
|
+
let a: number[] = Utils.toArray(val, enc)
|
|
59
|
+
return Uint8Array.from(a)
|
|
60
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { HexString, PubKeyHex, WalletNetwork } from '@bsv/sdk'
|
|
2
|
+
import { Beef, Hash, PrivateKey, PublicKey, Random, Script, Transaction, Utils } from '@bsv/sdk'
|
|
3
|
+
import { Chain } from '../sdk/types'
|
|
4
|
+
import { asArray } from './utilityHelpers.noBuffer'
|
|
5
|
+
import { CertOpsWallet } from '../sdk/CertOpsWallet'
|
|
6
|
+
import { WERR_BAD_REQUEST, WERR_INTERNAL, WERR_INVALID_PARAMETER } from '../sdk/WERR_errors'
|
|
7
|
+
|
|
8
|
+
export async function getIdentityKey(wallet: CertOpsWallet): Promise<PubKeyHex> {
|
|
9
|
+
return (await wallet.getPublicKey({ identityKey: true })).publicKey
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function toWalletNetwork(chain: Chain): WalletNetwork {
|
|
13
|
+
return chain === 'main' ? 'mainnet' : 'testnet'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function makeAtomicBeef(tx: Transaction, beef: number[] | Beef): number[] {
|
|
17
|
+
if (Array.isArray(beef)) beef = Beef.fromBinary(beef)
|
|
18
|
+
beef.mergeTransaction(tx)
|
|
19
|
+
return beef.toBinaryAtomic(tx.id('hex'))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Coerce a bsv transaction encoded as a hex string, serialized array, or Transaction to Transaction
|
|
24
|
+
* If tx is already a Transaction, just return it.
|
|
25
|
+
* @publicbody
|
|
26
|
+
*/
|
|
27
|
+
export function asBsvSdkTx(tx: HexString | number[] | Transaction): Transaction {
|
|
28
|
+
if (Array.isArray(tx)) {
|
|
29
|
+
tx = Transaction.fromBinary(tx)
|
|
30
|
+
} else if (typeof tx === 'string') {
|
|
31
|
+
tx = Transaction.fromHex(tx)
|
|
32
|
+
}
|
|
33
|
+
return tx
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Coerce a bsv script encoded as a hex string, serialized array, or Script to Script
|
|
38
|
+
* If script is already a Script, just return it.
|
|
39
|
+
* @publicbody
|
|
40
|
+
*/
|
|
41
|
+
export function asBsvSdkScript(script: HexString | number[] | Script): Script {
|
|
42
|
+
if (Array.isArray(script)) {
|
|
43
|
+
script = Script.fromBinary(script)
|
|
44
|
+
} else if (typeof script === 'string') {
|
|
45
|
+
script = Script.fromHex(script)
|
|
46
|
+
}
|
|
47
|
+
return script
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param privKey bitcoin private key in 32 byte hex string form
|
|
52
|
+
* @returns @bsv/sdk PrivateKey
|
|
53
|
+
*/
|
|
54
|
+
export function asBsvSdkPrivateKey(privKey: string): PrivateKey {
|
|
55
|
+
return PrivateKey.fromString(privKey, 'hex')
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param pubKey bitcoin public key in standard compressed key hex string form
|
|
60
|
+
* @returns @bsv/sdk PublicKey
|
|
61
|
+
*/
|
|
62
|
+
export function asBsvSdkPublickKey(pubKey: string): PublicKey {
|
|
63
|
+
return PublicKey.fromString(pubKey)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Helper function.
|
|
68
|
+
*
|
|
69
|
+
* Verifies that a possibly optional value has a value.
|
|
70
|
+
*/
|
|
71
|
+
export function verifyTruthy<T>(v: T | null | undefined, description?: string): T {
|
|
72
|
+
if (!v) throw new WERR_INTERNAL(description ?? 'A truthy value is required.')
|
|
73
|
+
return v
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Helper function.
|
|
78
|
+
*
|
|
79
|
+
* Verifies that a hex string is trimmed and lower case.
|
|
80
|
+
*/
|
|
81
|
+
export function verifyHexString(v: string): string {
|
|
82
|
+
if (typeof v !== 'string') throw new WERR_INTERNAL('A string is required.')
|
|
83
|
+
v = v.trim().toLowerCase()
|
|
84
|
+
return v
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Helper function.
|
|
89
|
+
*
|
|
90
|
+
* Verifies that an optional or null hex string is undefined or a trimmed lowercase string.
|
|
91
|
+
*/
|
|
92
|
+
export function verifyOptionalHexString(v?: string | null): string | undefined {
|
|
93
|
+
if (!v) return undefined
|
|
94
|
+
return verifyHexString(v)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Helper function.
|
|
99
|
+
*
|
|
100
|
+
* Verifies that an optional or null number has a numeric value.
|
|
101
|
+
*/
|
|
102
|
+
export function verifyNumber(v: number | null | undefined): number {
|
|
103
|
+
if (typeof v !== 'number') throw new WERR_INTERNAL('A number is required.')
|
|
104
|
+
return v
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Helper function.
|
|
109
|
+
*
|
|
110
|
+
* Verifies that an optional or null number has a numeric value.
|
|
111
|
+
*/
|
|
112
|
+
export function verifyInteger(v: number | null | undefined): number {
|
|
113
|
+
if (typeof v !== 'number' || !Number.isInteger(v)) throw new WERR_INTERNAL('An integer is required.')
|
|
114
|
+
return v
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Helper function.
|
|
119
|
+
*
|
|
120
|
+
* Verifies that a database record identifier is an integer greater than zero.
|
|
121
|
+
*/
|
|
122
|
+
export function verifyId(id: number | undefined | null): number {
|
|
123
|
+
id = verifyInteger(id)
|
|
124
|
+
if (id < 1) throw new WERR_INTERNAL(`id must be valid integer greater than zero.`)
|
|
125
|
+
return id
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Helper function.
|
|
130
|
+
*
|
|
131
|
+
* @throws WERR_BAD_REQUEST if results has length greater than one.
|
|
132
|
+
*
|
|
133
|
+
* @returns results[0] or undefined if length is zero.
|
|
134
|
+
*/
|
|
135
|
+
export function verifyOneOrNone<T>(results: T[]): T | undefined {
|
|
136
|
+
if (results.length > 1) throw new WERR_BAD_REQUEST('Result must be unique.')
|
|
137
|
+
return results[0]
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Helper function.
|
|
142
|
+
*
|
|
143
|
+
* @throws WERR_BAD_REQUEST if results has length other than one.
|
|
144
|
+
*
|
|
145
|
+
* @returns results[0].
|
|
146
|
+
*/
|
|
147
|
+
export function verifyOne<T>(results: T[], errorDescrition?: string): T {
|
|
148
|
+
if (results.length !== 1) throw new WERR_BAD_REQUEST(errorDescrition ?? 'Result must exist and be unique.')
|
|
149
|
+
return results[0]
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Returns an await'able Promise that resolves in the given number of msecs.
|
|
154
|
+
* @param msecs number of milliseconds to wait before resolving the promise.
|
|
155
|
+
* Must be greater than zero and less than 2 minutes (120,000 msecs)
|
|
156
|
+
* @publicbody
|
|
157
|
+
*/
|
|
158
|
+
export function wait(msecs: number): Promise<void> {
|
|
159
|
+
const MIN_WAIT = 0
|
|
160
|
+
const MAX_WAIT = 2 * 60 * 1000 // maximum allowed wait in ms (2 minutes)
|
|
161
|
+
if (typeof msecs !== 'number' || !Number.isFinite(msecs) || isNaN(msecs) || msecs < MIN_WAIT || msecs > MAX_WAIT) {
|
|
162
|
+
throw new WERR_INVALID_PARAMETER('msecs', `a number between ${MIN_WAIT} and ${MAX_WAIT} msecs, not ${msecs}.`)
|
|
163
|
+
}
|
|
164
|
+
return new Promise(resolve => setTimeout(resolve, msecs))
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @returns count cryptographically secure random bytes as array of bytes
|
|
169
|
+
*/
|
|
170
|
+
export function randomBytes(count: number): number[] {
|
|
171
|
+
return Random(count)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @returns count cryptographically secure random bytes as hex encoded string
|
|
176
|
+
*/
|
|
177
|
+
export function randomBytesHex(count: number): string {
|
|
178
|
+
return Utils.toHex(Random(count))
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @returns count cryptographically secure random bytes as base64 encoded string
|
|
183
|
+
*/
|
|
184
|
+
export function randomBytesBase64(count: number): string {
|
|
185
|
+
return Utils.toBase64(Random(count))
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function validateSecondsSinceEpoch(time: number): Date {
|
|
189
|
+
const date = new Date(time * 1000)
|
|
190
|
+
if (date.getTime() / 1000 !== time || time < 1600000000 || time > 100000000000) {
|
|
191
|
+
throw new WERR_INVALID_PARAMETER('time', `valid "since epoch" unix time`)
|
|
192
|
+
}
|
|
193
|
+
return date
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Compares lengths and direct equality of values.
|
|
198
|
+
* @param arr1
|
|
199
|
+
* @param arr2
|
|
200
|
+
* @returns
|
|
201
|
+
*/
|
|
202
|
+
export function arraysEqual(arr1: Number[], arr2: Number[]) {
|
|
203
|
+
if (arr1.length !== arr2.length) return false
|
|
204
|
+
for (let i = 0; i < arr1.length; i++) {
|
|
205
|
+
if (arr1[i] !== arr2[i]) return false
|
|
206
|
+
}
|
|
207
|
+
return true
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function optionalArraysEqual(arr1?: Number[], arr2?: Number[]) {
|
|
211
|
+
if (!arr1 && !arr2) return true
|
|
212
|
+
if (!arr1 || !arr2) return false
|
|
213
|
+
return arraysEqual(arr1, arr2)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function maxDate(d1?: Date, d2?: Date): Date | undefined {
|
|
217
|
+
if (d1 && d2) {
|
|
218
|
+
if (d1 > d2) return d1
|
|
219
|
+
return d2
|
|
220
|
+
}
|
|
221
|
+
if (d1) return d1
|
|
222
|
+
if (d2) return d2
|
|
223
|
+
return undefined
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Calculate the SHA256 hash of an array of bytes
|
|
228
|
+
* @returns sha256 hash of buffer contents.
|
|
229
|
+
* @publicbody
|
|
230
|
+
*/
|
|
231
|
+
export function sha256Hash(data: number[] | Uint8Array): number[] {
|
|
232
|
+
if (!Array.isArray(data)) {
|
|
233
|
+
data = asArray(data)
|
|
234
|
+
}
|
|
235
|
+
const first = new Hash.SHA256().update(data).digest()
|
|
236
|
+
return first
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Calculate the SHA256 hash of the SHA256 hash of an array of bytes.
|
|
241
|
+
* @param data an array of bytes
|
|
242
|
+
* @returns double sha256 hash of data, byte 0 of hash first.
|
|
243
|
+
* @publicbody
|
|
244
|
+
*/
|
|
245
|
+
export function doubleSha256LE(data: number[] | Uint8Array): number[] {
|
|
246
|
+
if (!Array.isArray(data)) {
|
|
247
|
+
data = asArray(data)
|
|
248
|
+
}
|
|
249
|
+
const first = new Hash.SHA256().update(data).digest()
|
|
250
|
+
const second = new Hash.SHA256().update(first).digest()
|
|
251
|
+
return second
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Calculate the SHA256 hash of the SHA256 hash of an array of bytes.
|
|
256
|
+
* @param data is an array of bytes.
|
|
257
|
+
* @returns reversed (big-endian) double sha256 hash of data, byte 31 of hash first.
|
|
258
|
+
* @publicbody
|
|
259
|
+
*/
|
|
260
|
+
export function doubleSha256BE(data: number[] | Uint8Array): number[] {
|
|
261
|
+
return doubleSha256LE(data).reverse()
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Logging function to handle logging based on running in jest "single test" mode,
|
|
266
|
+
*
|
|
267
|
+
* @param {string} message - The main message to log.
|
|
268
|
+
* @param {...any} optionalParams - Additional parameters to log (optional).
|
|
269
|
+
*/
|
|
270
|
+
export const logger = (message: string, ...optionalParams: any[]): void => {
|
|
271
|
+
const isSingleTest = process.argv.some(arg => arg === '--testNamePattern' || arg === '-t')
|
|
272
|
+
if (isSingleTest) {
|
|
273
|
+
console.log(message, ...optionalParams)
|
|
274
|
+
}
|
|
275
|
+
}
|