@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,407 @@
|
|
|
1
|
+
import { Beef, MerklePath, Transaction, WalletOutput, Validation, Utils } from '@bsv/sdk'
|
|
2
|
+
import { TableOutput, TableUser, verifyOne, verifyOneOrNone } from '../../../src'
|
|
3
|
+
import { _tu, logger } from '../../utils/TestUtilsWalletStorage'
|
|
4
|
+
import { specOpInvalidChange } from '../../../src/sdk'
|
|
5
|
+
import { Format } from '../../../src/utility/Format'
|
|
6
|
+
import { asString } from '../../../src/utility/utilityHelpers.noBuffer'
|
|
7
|
+
|
|
8
|
+
describe('operations.man tests', () => {
|
|
9
|
+
jest.setTimeout(99999999)
|
|
10
|
+
|
|
11
|
+
test('0 review and release all production invalid change utxos', async () => {
|
|
12
|
+
// const tags = [] // only return invalid change utxos, do not update them to unspendable.
|
|
13
|
+
// const tags = ['release'] // release invalid change utxos to unspendable
|
|
14
|
+
const tags = ['all'] // only return invalid utxos, do not update them to unspendable.
|
|
15
|
+
// const tags = ['release', 'all'] // release invalid utxos to unspendable
|
|
16
|
+
const action = tags.includes('release') ? 'updated to unspendable' : 'found'
|
|
17
|
+
const target = tags.includes('all') ? 'spendable utxos' : 'spendable change utxos'
|
|
18
|
+
const { env, storage } = await _tu.createMainReviewSetup()
|
|
19
|
+
const users = await storage.findUsers({ partial: { userId: 88 } })
|
|
20
|
+
// const users = await storage.findUsers({ partial: {} }) // all users...
|
|
21
|
+
const withInvalid: Record<number, { user: TableUser; outputs: WalletOutput[]; total: number }> = {}
|
|
22
|
+
const vargs: Validation.ValidListOutputsArgs = {
|
|
23
|
+
basket: specOpInvalidChange,
|
|
24
|
+
tags,
|
|
25
|
+
tagQueryMode: 'all',
|
|
26
|
+
includeLockingScripts: false,
|
|
27
|
+
includeTransactions: false,
|
|
28
|
+
includeCustomInstructions: false,
|
|
29
|
+
includeTags: false,
|
|
30
|
+
includeLabels: false,
|
|
31
|
+
limit: 0,
|
|
32
|
+
offset: 0,
|
|
33
|
+
seekPermission: false,
|
|
34
|
+
knownTxids: []
|
|
35
|
+
}
|
|
36
|
+
let log = ''
|
|
37
|
+
for (const user of users) {
|
|
38
|
+
const { userId } = user
|
|
39
|
+
const auth = { userId, identityKey: '' }
|
|
40
|
+
let r = await storage.listOutputs(auth, vargs)
|
|
41
|
+
if (r.totalOutputs > 0) {
|
|
42
|
+
const total: number = r.outputs.reduce((s, o) => (s += o.satoshis), 0)
|
|
43
|
+
let l = `userId ${userId}: ${r.totalOutputs} ${target} ${action}, total ${total}, ${user.identityKey}\n`
|
|
44
|
+
for (const o of r.outputs) {
|
|
45
|
+
l += ` ${o.outpoint} ${o.satoshis} now ${o.spendable ? 'spendable' : 'spent'}\n`
|
|
46
|
+
}
|
|
47
|
+
console.log(l)
|
|
48
|
+
log += l
|
|
49
|
+
withInvalid[userId] = { user, outputs: r.outputs, total }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
console.log(log || `zero invalid ${target} ${action}.`)
|
|
53
|
+
await storage.destroy()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('1 review and unfail false doubleSpends', async () => {
|
|
57
|
+
const { env, storage, services } = await _tu.createMainReviewSetup()
|
|
58
|
+
let offset = 400
|
|
59
|
+
const limit = 100
|
|
60
|
+
let allUnfails: number[] = []
|
|
61
|
+
let reviewed = 0
|
|
62
|
+
for (;;) {
|
|
63
|
+
let log = ''
|
|
64
|
+
const unfails: number[] = []
|
|
65
|
+
const reqs = await storage.findProvenTxReqs({
|
|
66
|
+
partial: { status: 'doubleSpend' },
|
|
67
|
+
paged: { limit, offset },
|
|
68
|
+
orderDescending: true
|
|
69
|
+
})
|
|
70
|
+
for (const req of reqs) {
|
|
71
|
+
const gsr = await services.getStatusForTxids([req.txid])
|
|
72
|
+
if (gsr.results[0].status !== 'unknown') {
|
|
73
|
+
log += `unfail ${req.provenTxReqId} ${req.txid}\n`
|
|
74
|
+
unfails.push(req.provenTxReqId)
|
|
75
|
+
}
|
|
76
|
+
reviewed++
|
|
77
|
+
}
|
|
78
|
+
console.log(`DoubleSpends OFFSET: ${offset} ${reviewed} ${unfails.length} unfails\n${log}`)
|
|
79
|
+
allUnfails = allUnfails.concat(unfails)
|
|
80
|
+
if (reqs.length < limit) break
|
|
81
|
+
offset += reqs.length
|
|
82
|
+
}
|
|
83
|
+
for (const id of allUnfails) {
|
|
84
|
+
await storage.updateProvenTxReq(id, { status: 'unfail' })
|
|
85
|
+
}
|
|
86
|
+
await storage.destroy()
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('2 review and unfail false invalids', async () => {
|
|
90
|
+
const { env, storage, services } = await _tu.createMainReviewSetup()
|
|
91
|
+
let offset = 500
|
|
92
|
+
const limit = 100
|
|
93
|
+
let allUnfails: number[] = []
|
|
94
|
+
let reviewed = 0
|
|
95
|
+
for (;;) {
|
|
96
|
+
let log = ''
|
|
97
|
+
const unfails: number[] = []
|
|
98
|
+
const reqs = await storage.findProvenTxReqs({
|
|
99
|
+
partial: { status: 'invalid' },
|
|
100
|
+
paged: { limit, offset },
|
|
101
|
+
orderDescending: true
|
|
102
|
+
})
|
|
103
|
+
for (const req of reqs) {
|
|
104
|
+
if (!req.txid || !req.rawTx) continue
|
|
105
|
+
const gsr = await services.getStatusForTxids([req.txid])
|
|
106
|
+
if (gsr.results[0].status !== 'unknown') {
|
|
107
|
+
log += `unfail ${req.provenTxReqId} ${req.txid}\n`
|
|
108
|
+
unfails.push(req.provenTxReqId)
|
|
109
|
+
}
|
|
110
|
+
reviewed++
|
|
111
|
+
}
|
|
112
|
+
console.log(`Failed OFFSET: ${offset} ${reviewed} ${unfails.length} unfails\n${log}`)
|
|
113
|
+
allUnfails = allUnfails.concat(unfails)
|
|
114
|
+
if (reqs.length < limit) break
|
|
115
|
+
offset += reqs.length
|
|
116
|
+
}
|
|
117
|
+
for (const id of allUnfails) {
|
|
118
|
+
await storage.updateProvenTxReq(id, { status: 'unfail' })
|
|
119
|
+
}
|
|
120
|
+
await storage.destroy()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test.skip('3 review proven_txs', async () => {
|
|
124
|
+
const { env, storage, services } = await _tu.createMainReviewSetup()
|
|
125
|
+
let offset = 0
|
|
126
|
+
const limit = 100
|
|
127
|
+
let allUnfails: number[] = []
|
|
128
|
+
//for (const provenTxId of [3064, 3065, 11268, 11269, 11270, 11271] ) {
|
|
129
|
+
for (let height = 895000; height < 895026; height++) {
|
|
130
|
+
let log = ''
|
|
131
|
+
const unfails: number[] = []
|
|
132
|
+
const txs = await storage.findProvenTxs({ partial: { height }, paged: { limit, offset } })
|
|
133
|
+
for (const tx of txs) {
|
|
134
|
+
const gmpr = await services.getMerklePath(tx.txid)
|
|
135
|
+
if (gmpr && gmpr.header && gmpr.merklePath) {
|
|
136
|
+
const mp = gmpr.merklePath
|
|
137
|
+
const h = gmpr.header
|
|
138
|
+
const mr = mp.computeRoot(tx.txid)
|
|
139
|
+
const index = mp.path[0].find(leaf => leaf.hash === tx.txid)?.offset!
|
|
140
|
+
|
|
141
|
+
const mp2 = MerklePath.fromBinary(tx.merklePath)
|
|
142
|
+
const mr2 = mp2.computeRoot()
|
|
143
|
+
|
|
144
|
+
if (h.height !== mp.blockHeight || h.merkleRoot !== mr) {
|
|
145
|
+
console.log(`Merkle root mismatch for ${tx.txid} ${h.merkleRoot} != ${mr}`)
|
|
146
|
+
} else {
|
|
147
|
+
if (
|
|
148
|
+
tx.merkleRoot !== mr ||
|
|
149
|
+
tx.height !== mp.blockHeight ||
|
|
150
|
+
tx.blockHash !== h.hash ||
|
|
151
|
+
tx.index !== index ||
|
|
152
|
+
mp2.blockHeight !== tx.height ||
|
|
153
|
+
mr2 !== tx.merkleRoot ||
|
|
154
|
+
asString(tx.merklePath) !== asString(mp.toBinary())
|
|
155
|
+
) {
|
|
156
|
+
debugger
|
|
157
|
+
await storage.updateProvenTx(tx.provenTxId, {
|
|
158
|
+
merklePath: mp.toBinary(),
|
|
159
|
+
merkleRoot: mr,
|
|
160
|
+
height: mp.blockHeight,
|
|
161
|
+
blockHash: h.hash,
|
|
162
|
+
index
|
|
163
|
+
})
|
|
164
|
+
log += `updated ${tx.provenTxId}\n`
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//console.log(`${offset} ${log}`)
|
|
170
|
+
//if (txs.length < limit) break
|
|
171
|
+
//offset += txs.length
|
|
172
|
+
}
|
|
173
|
+
await storage.destroy()
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
test.skip('10 re-internalize failed WUI exports', async () => {
|
|
177
|
+
const { env, storage, services } = await _tu.createMainReviewSetup()
|
|
178
|
+
// From this user
|
|
179
|
+
const user0 = verifyOne(await storage.findUsers({ partial: { userId: 2 } }))
|
|
180
|
+
// To these users
|
|
181
|
+
const users = await storage.findUsers({ partial: { userId: 141 } }) // 111, 141
|
|
182
|
+
for (const user of users) {
|
|
183
|
+
const { userId, identityKey } = user
|
|
184
|
+
const [outputs] = await storage.knex.raw<TableOutput[][]>(`
|
|
185
|
+
SELECT f.* FROM outputs as f where f.userId = 2 and not f.customInstructions is null
|
|
186
|
+
and JSON_EXTRACT(f.customInstructions, '$.payee') = '${identityKey}'
|
|
187
|
+
and not exists(select * from outputs as r where r.userId = ${userId} and r.txid = f.txid)
|
|
188
|
+
`)
|
|
189
|
+
if (outputs.length > 0) console.log(`userId ${userId} ${identityKey} ${outputs.length} outputs`)
|
|
190
|
+
for (const output of outputs) {
|
|
191
|
+
const req = verifyOneOrNone(
|
|
192
|
+
await storage.findProvenTxReqs({ partial: { txid: output.txid, status: 'completed' } })
|
|
193
|
+
)
|
|
194
|
+
const { type, derivationPrefix, derivationSuffix, payee } = JSON.parse(output.customInstructions!)
|
|
195
|
+
if (req && type === 'BRC29' && derivationPrefix && derivationSuffix) {
|
|
196
|
+
const beef = await storage.getBeefForTransaction(req.txid, {})
|
|
197
|
+
// {"type":"BRC29","derivationPrefix":"LDFooHSsXzw=","derivationSuffix":"4f4ixKv+6SY=","payee":"0352caa755d5b6279e15e47e096db908e7c4a73a31775e7e8720bdd4cf2d44873a"}
|
|
198
|
+
await storage.internalizeAction(
|
|
199
|
+
{ userId, identityKey: user.identityKey },
|
|
200
|
+
{
|
|
201
|
+
tx: beef.toBinaryAtomic(req.txid),
|
|
202
|
+
outputs: [
|
|
203
|
+
{
|
|
204
|
+
outputIndex: 0,
|
|
205
|
+
protocol: 'wallet payment',
|
|
206
|
+
paymentRemittance: {
|
|
207
|
+
derivationPrefix: derivationPrefix,
|
|
208
|
+
derivationSuffix: derivationSuffix,
|
|
209
|
+
senderIdentityKey: user0.identityKey
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
],
|
|
213
|
+
description: 'Internalizing export funds tx into foreign wallet'
|
|
214
|
+
}
|
|
215
|
+
)
|
|
216
|
+
console.log('internalize', userId, output.txid)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/*
|
|
221
|
+
*/
|
|
222
|
+
await storage.destroy()
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
test.skip('11 review recent transaction change use for specific userId', async () => {
|
|
226
|
+
const userId = 311
|
|
227
|
+
const { env, storage, services } = await _tu.createMainReviewSetup()
|
|
228
|
+
const countTxs = await storage.countTransactions({
|
|
229
|
+
partial: { userId },
|
|
230
|
+
status: ['completed', 'unproven', 'failed']
|
|
231
|
+
})
|
|
232
|
+
const txs = await storage.findTransactions({
|
|
233
|
+
partial: { userId },
|
|
234
|
+
status: ['unproven', 'completed', 'failed'],
|
|
235
|
+
paged: { limit: 100, offset: Math.max(0, countTxs - 100) }
|
|
236
|
+
})
|
|
237
|
+
for (const tx of txs) {
|
|
238
|
+
const ls = await Format.toLogStringTableTransaction(tx, storage)
|
|
239
|
+
console.log(ls)
|
|
240
|
+
}
|
|
241
|
+
const countReqs = await storage.countProvenTxReqs({ partial: {}, status: ['completed', 'unmined'] })
|
|
242
|
+
const reqs = await storage.findProvenTxReqs({
|
|
243
|
+
partial: {},
|
|
244
|
+
status: ['unmined', 'completed'],
|
|
245
|
+
paged: { limit: 100, offset: countReqs - 100 }
|
|
246
|
+
})
|
|
247
|
+
await storage.destroy()
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
test.skip('12 check storage merged BEEF', async () => {
|
|
251
|
+
const userId = 127
|
|
252
|
+
const txid = 'efba8b92a22c3308f432b292b5ec7efb3869ecd50c62cb3ddfb83871bc7be194'
|
|
253
|
+
const vout = 1
|
|
254
|
+
const { env, storage, services } = await _tu.createMainReviewSetup()
|
|
255
|
+
|
|
256
|
+
const ptx = verifyOne(await storage.findProvenTxs({ partial: { txid } }))
|
|
257
|
+
|
|
258
|
+
const mp = MerklePath.fromBinary(ptx.merklePath)
|
|
259
|
+
expect(mp.blockHeight).toBe(ptx.height)
|
|
260
|
+
|
|
261
|
+
const txids = ['24b19a5179c1f146e825643df4c6dc2ba21674828c20fc2948e105cb1ca91eae']
|
|
262
|
+
|
|
263
|
+
const r = await storage.getReqsAndBeefToShareWithWorld(txids, [])
|
|
264
|
+
|
|
265
|
+
await storage.destroy()
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
test('13 review use of outputs in all following transactions', async () => {
|
|
269
|
+
const { env, storage, services } = await _tu.createMainReviewSetup()
|
|
270
|
+
|
|
271
|
+
const txids = ['2df7b5059112a42fc40adb54ee36244cee0dd216c35ad6c4b6ef4631c14a0e83'] //, '9fb38fc87c6ff39f5c7321a4c689db535c024498ed20031434485c981dd7a182', '3fb6b02e1d001dded1daee3f59dcd684489b96a35a9dfb5082b4119a31689966', '72ea8d84a4c54dbca292f4a79a5ff08cb9917fc3127c1dcff0628aeba8b40823', '0564a515566bc43c1396becf12bbf2d82d821ae7b6e0ef404eedfa090d4877c2', '3b93e4327a50a7f4a421af9fbdec0206b3b7ba5252bc5a0142d0d64aa34c2e73', 'd4b0c3d820696afad43b43e095f3b8c3df52385bb4aeddff0212e0a472dd8e4e']
|
|
272
|
+
const userId = 111
|
|
273
|
+
const txs = await storage.findTransactions({
|
|
274
|
+
partial: { userId },
|
|
275
|
+
status: ['completed', 'unproven', 'failed'],
|
|
276
|
+
orderDescending: true,
|
|
277
|
+
paged: { limit: 50 }
|
|
278
|
+
})
|
|
279
|
+
const allTxids = txs.map(tx => tx.txid!)
|
|
280
|
+
debugger
|
|
281
|
+
const reqs = await storage.findProvenTxReqs({ partial: {}, txids: allTxids })
|
|
282
|
+
const beef = new Beef()
|
|
283
|
+
for (const req of reqs) {
|
|
284
|
+
beef.mergeRawTx(req.rawTx!)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
for (const txid of txids) {
|
|
288
|
+
const o = await storage.findOutputs({ partial: { txid, userId } })
|
|
289
|
+
const tx = await storage.findTransactions({ partial: { txid, userId } })
|
|
290
|
+
if (o && tx) {
|
|
291
|
+
const ltx = await Format.toLogStringTableTransaction(tx[0], storage)
|
|
292
|
+
logger(ltx)
|
|
293
|
+
for (const btx of beef.txs) {
|
|
294
|
+
const tx = btx.tx!
|
|
295
|
+
for (const i of tx.inputs) {
|
|
296
|
+
if (i.sourceTXID === txid && i.sourceOutputIndex === 0) {
|
|
297
|
+
const sltx = Format.toLogStringBeefTxid(beef, btx.txid)
|
|
298
|
+
logger(sltx)
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
await storage.destroy()
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
test('14 review utxo status of inputs of tx', async () => {
|
|
308
|
+
const { env, storage, services } = await _tu.createMainReviewSetup()
|
|
309
|
+
|
|
310
|
+
const tx = Transaction.fromHex(testTxInputUtxoStatus)
|
|
311
|
+
|
|
312
|
+
const inputTxs: Record<string, Transaction> = {}
|
|
313
|
+
|
|
314
|
+
for (const input of tx.inputs) {
|
|
315
|
+
if (input.sourceTXID && !inputTxs[input.sourceTXID]) {
|
|
316
|
+
const source = await services.getRawTx(input.sourceTXID!)
|
|
317
|
+
if (!source.rawTx) {
|
|
318
|
+
throw new Error(`Source transaction ${input.sourceTXID} not found`)
|
|
319
|
+
}
|
|
320
|
+
inputTxs[input.sourceTXID] = Transaction.fromBinary(source.rawTx!)
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
let log = ''
|
|
324
|
+
for (const input of tx.inputs) {
|
|
325
|
+
const stx = inputTxs[input.sourceTXID!]!
|
|
326
|
+
const output = stx.outputs[input.sourceOutputIndex]!
|
|
327
|
+
const hash = services.hashOutputScript(output.lockingScript.toHex())
|
|
328
|
+
const outpoint = `${input.sourceTXID}.${input.sourceOutputIndex}`
|
|
329
|
+
const or = await services.getUtxoStatus(hash, undefined, outpoint)
|
|
330
|
+
log += `${outpoint} ${or.isUtxo} ${or.status}\n`
|
|
331
|
+
}
|
|
332
|
+
logger(log)
|
|
333
|
+
await storage.destroy()
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
test('14a review utxo status of custom spentBy null spendable false outputs', async () => {
|
|
337
|
+
const { env, storage, services } = await _tu.createMainReviewSetup()
|
|
338
|
+
|
|
339
|
+
let offset = 0
|
|
340
|
+
const limit = 100
|
|
341
|
+
|
|
342
|
+
for (;;) {
|
|
343
|
+
let validOutputIds: number[] = []
|
|
344
|
+
|
|
345
|
+
let log = `offset ${offset}\n`
|
|
346
|
+
// select count(*)
|
|
347
|
+
// and o.lockingScript is null
|
|
348
|
+
// and o.txid = '533e50fba3fca9b08845fc46ae3df81713129876faddf84f9d26d4185dea8324'
|
|
349
|
+
const outputs: {
|
|
350
|
+
outputId: number
|
|
351
|
+
txid: string
|
|
352
|
+
vout: number
|
|
353
|
+
lockingScript: number[]
|
|
354
|
+
scriptOffset: number
|
|
355
|
+
scriptLength: number
|
|
356
|
+
}[] = (
|
|
357
|
+
await storage.knex.raw(`
|
|
358
|
+
select o.outputId, o.txid, o.vout, o.lockingScript, o.scriptOffset, o.scriptLength
|
|
359
|
+
from outputs o, transactions t
|
|
360
|
+
where o.transactionId = t.transactionId
|
|
361
|
+
and o.type = 'custom' and o.spentBy is null and o.spendable = 0
|
|
362
|
+
and t.status = 'completed'
|
|
363
|
+
limit ${limit}
|
|
364
|
+
offset ${offset}
|
|
365
|
+
`)
|
|
366
|
+
)[0]
|
|
367
|
+
|
|
368
|
+
for (const { outputId, txid, vout, lockingScript, scriptOffset, scriptLength } of outputs) {
|
|
369
|
+
let script: number[] | null | undefined = lockingScript
|
|
370
|
+
if (!lockingScript) {
|
|
371
|
+
script = await storage.getRawTxOfKnownValidTransaction(txid, scriptOffset, scriptLength)
|
|
372
|
+
}
|
|
373
|
+
expect(script).toBeTruthy()
|
|
374
|
+
const hex = Utils.toHex(script!)
|
|
375
|
+
const hash = services.hashOutputScript(hex)
|
|
376
|
+
const outpoint = `${txid}.${vout}`
|
|
377
|
+
const or = await services.getUtxoStatus(hash, undefined, outpoint)
|
|
378
|
+
if (or.isUtxo && or.status === 'success') {
|
|
379
|
+
log += `${outpoint} ${or.isUtxo} ${or.status}\n`
|
|
380
|
+
validOutputIds.push(outputId)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
log += `offset ${offset}\n`
|
|
384
|
+
logger(log)
|
|
385
|
+
|
|
386
|
+
for (const outputId of validOutputIds) {
|
|
387
|
+
await storage.updateOutput(outputId, { spendable: true })
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (outputs.length < limit) break
|
|
391
|
+
offset += limit
|
|
392
|
+
}
|
|
393
|
+
await storage.destroy()
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
test('15 abort a transaction', async () => {
|
|
397
|
+
const { env, storage } = await _tu.createMainReviewSetup()
|
|
398
|
+
const refOrTxid = '42671b6c9b79cec03bf5be9105203589b8b092774a40b459fbd835e5fd582202'
|
|
399
|
+
const userId = 496
|
|
400
|
+
const auth = { userId, identityKey: '' }
|
|
401
|
+
const r = await storage.abortAction(auth, { reference: refOrTxid })
|
|
402
|
+
console.log(r)
|
|
403
|
+
await storage.destroy()
|
|
404
|
+
})
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
const testTxInputUtxoStatus = `010000003E63EAF142160AD52F3172D75305D0D495A99AD9F17A693017EF8630C86F37A200000000006A473044022004E94D9188B2CE1193969509F32B46F94A36DB2BB4FC0832936F937C59FDDA470220781E5A5AD34EE49C985E5177380D6D111546D7BCCBAAA219B292FB49400DB7C9C221021A67430A3C5F274D3563892965758D3DEAE67799DD47E28DA95FBD1013D3B302FFFFFFFF74B95869A62F82E50642B4B18C78321BC12858A640155C8DA34EC4043393CCA6000000006A4730440220680AEF159D6C158C703912A9FBA090A063A26D92DBDFB7F15D6026FB5EAC332E0220375559499733A35955CA5F562669C8A947624BF22A8475EC0CD2C488530BCBD1C22103F55B1909BFD6851773E7FA7E567B58BF586D1EF76D0DE00330EE7F05E19672C2FFFFFFFFCDA6E22336EA4F8898D56C85C022F35338A6CD9E8D14FC75EA39DEC3B78FB83E010000006B483045022100E2B532D81252E60465E694F40A67B8CC52CCEAA1992494AAE264E039ED4D471602204E5C65F74BB49D263C54E43CFE22C8AB39B8AEB89F64CFEF933E5EBE08C5EF6DC22103E4F28DF126FBE92CF4418EF16636D18D75F8FFEADF0D03A0339A53B4A37DDDF7FFFFFFFFE330B3BBCB5815DD6B2B03BA5105F71F09CB8C26344F67C7A5E082473DF75859030000006B483045022100EBF506D10F04EC171C6A598056F06946D0B6F244FD08AA3E5A2DABB2EAC01A2A02206E557D4D7048E19F1DE094C5BCB7FC507FEC7E13C419AE829AD9180BACE4D5D8C22102960CADC2656A19DAAF1FCC04F6CF235C0E83822336F3CD32D599A426DFF85114FFFFFFFF7A58F2A977D75EDC8D349AEC609DAEC3AB06C12CE83276FB986D0B36D37C3C3C090000006A47304402205B353BE3BBC19B3766D12D5268E34E34675EB8BB8DD7624A522C1A36C1A1F481022072DD8D7F11C5507781FE9C55931A95BB3FE0FF7748DB4D1765FB6DFCBDF27268C22103F051F897874F7365DBF96773EE4D54EEA289BF05EE1610FF8C7F52EBC15A8294FFFFFFFF2D1C1B9098484F91435CB9965F07886E30FB8D1EA7F221C9072DAD8AAD545B294C0000006A47304402205D42AC6A4CA02F7006781515E9DAB1101B2F8006193F7E3EEB61CDC3132EFDDE02203EB616AD39280D1A07E9B31D1E4BAF56F831AF95A21A16D304235DD7DC65CF20C22103F051F897874F7365DBF96773EE4D54EEA289BF05EE1610FF8C7F52EBC15A8294FFFFFFFF2D1C1B9098484F91435CB9965F07886E30FB8D1EA7F221C9072DAD8AAD545B29160000006B48304502210080AE055C991A3EFED069C3E0D22E984DAF0C2DDDE6C102280EAA6E7ABBA2E9A00220339DE057226FAD63D021A3167C3AEDA0447D49DFA782A59850F699012C44FA4DC221033F8A1AD07E37C12FCE914102509C9ABFC313F69D9329F5137FD2EA79F633C86CFFFFFFFFFBD56D01AAB9E6F7E73F0D6A232F4D73D552A933E3ECBFC2E4BD95F4ECF9A1C6020000006A473044022043AEAFBF8C63FC98CECFE79569BE2F0D94C02E44C2C50CAD37104C4EA0D0B8E4022072EA0F50DF429D15500F4F2795147256A40DEA751BECD6572E0C5AE51D6DF553C221033F8A1AD07E37C12FCE914102509C9ABFC313F69D9329F5137FD2EA79F633C86CFFFFFFFF1D6A18F2411362A374CE97D2480C54E21173A58C5E83D7679DB1BC5CA112A55D020000006A47304402204B5E9B9612F89CADC7BF2D7035BFFB1EE9127586F504D4C635B674D8A1BE000702207837EEC18E2BD808F58935C4C78685715B2C5A3D84AB39895F8DA1AA0F7E6A28C22102D7EAA52A92B311A96A0AEBB18CABFE3A9B17B82048ED1E3E58628A4959ED91B4FFFFFFFF4A2297374C26D0E5EE98C07FDA64DAD58577F89502835CD433EEC3191A66F380B30000006B483045022100CF83B0C64FD8ECA6761CC7BD3D72F2B38CC17B747C1E98F48DACD155B7CE9B3502202C696010E7673325CAEAE2E0D7F0BA8DC2EADC6FDB7A3779AA359820A16CD848C22102D7EAA52A92B311A96A0AEBB18CABFE3A9B17B82048ED1E3E58628A4959ED91B4FFFFFFFF589F60C44908602772131C5D457186E18F4D22D659353AC84F3A0795057F2378000000006B483045022100C4EC4D00EA39C2EBBA147752C67BB722B695777F00C462B7AE3E76467DB5EE9B02205402285B07031D4EA0FCCD298FED76F590243D1D9CE8B8C44F83F97B59691E9BC22103125E0DF790EAE42BFF3B6057A2699C534B3E4D08C1D3AFEC2AF4C10CC751EFD8FFFFFFFFB750A581EEA3A60079DE6D28FE07BAE3C7A63065D92DA936C67FE4C52F1C1DE6000000006A47304402201860470374A282FF58B6EE576A1EF46B60238131FD00D0C0C27777F8F76CAC4502204163110A54EB0B81C6F0791E363F3DF0F0A14C08F6A7AE2E8FC77B7713ED109BC22103125E0DF790EAE42BFF3B6057A2699C534B3E4D08C1D3AFEC2AF4C10CC751EFD8FFFFFFFF833F3725A47C30A4AD5EBE5EA46D9AED81D5213BA2B51DE74A8BF23B65AC99A39F0000006B483045022100F1B40B6D4053E817FC674872DB1B8FE8C64D625CF4974893846A490117D034C60220343365C584D60269BF7845AFD2B69B4CF230530091102B1493B32D7B73E0CA0FC22103125E0DF790EAE42BFF3B6057A2699C534B3E4D08C1D3AFEC2AF4C10CC751EFD8FFFFFFFF833F3725A47C30A4AD5EBE5EA46D9AED81D5213BA2B51DE74A8BF23B65AC99A39E0000006B483045022100A21CBDF75C58FAD76313F2CBE8D0E0DC1E3B5FCB9ECC61594A91D4F61218C85902202BB2250C3477EFC9D7C28F1D1E0ADB3296952671D340065ADA8B93A330C39244C22103584150A15E4D85DF54CFBBD822ACA5EEDE00D5DD8C32126FCBD51499519BA565FFFFFFFFA1DD547EAB22B19A49862C2ED7C3E059DBBB5307738F9D9581CED2B4AAB6B6D9010000006B483045022100A0918681C651851B91617C8E1C01074F2A0291EBB083AB2163D72FF565DD8590022008E27FC437A0DE19A3F39F3C2C3F1B3C1F508E52DC69ACC2CBF9D1774C7C4047C22103125E0DF790EAE42BFF3B6057A2699C534B3E4D08C1D3AFEC2AF4C10CC751EFD8FFFFFFFF0BB9D0E3A9CCEA73BC8682B66C559D6232265488647F0B7EEECE00BD0C2F5904000000006B483045022100C568678B624F6F04E8645AD8340638075E07AD4BCBB0FA9446B2153599B803C902204B9BD26BD58614360B86F95E9812E68A759450E64659AA5B8707FA629D12B438C22103125E0DF790EAE42BFF3B6057A2699C534B3E4D08C1D3AFEC2AF4C10CC751EFD8FFFFFFFF5367F929C9123A4853ED77A0087F72D135031A8E64C3D047976EFCD3807FC0D5010000006A47304402200B1F4939A427C65ED456B62158271F269C33740C5E4D9ED2F9E864E410F23511022059F10A7FEFE82CF89C274FE9486CFAEF7B148290386DDD3F6423280F0667EEF7C22103584150A15E4D85DF54CFBBD822ACA5EEDE00D5DD8C32126FCBD51499519BA565FFFFFFFF5367F929C9123A4853ED77A0087F72D135031A8E64C3D047976EFCD3807FC0D5000000006A473044022012D66417842DDF0079734B3885CE56D42B2309A49CFD1313895CE6401E67E47602200F8FCCBECEEC0546577872F4BA7B95EAF4621506238D88E89A0A0B12E46876DCC22103584150A15E4D85DF54CFBBD822ACA5EEDE00D5DD8C32126FCBD51499519BA565FFFFFFFF46CF567BCF79C0E845BC95A488DC8BEB8E3558783F21B30A2902F333D6080C3A000000006A47304402202DEBF679DE7F93DDABC84CC1953DC52570EF291F4BFE1C61840AAA2D3CDA0AF5022041C66B14238FE4CD4C5E7E3BF6BA2BDA031F7D4EACA3F15FC28DD6CDAF2B2E54C221036D9E146EDA0C9E01DF36F4735C39B29E8C8B58BFDB2BCF82E407A1CEEB8ED040FFFFFFFFA11701B6BC31DA3646DBAEBD0042AD7357B14A35B97461E9F2278DEB90FD6838D40000006A4730440220154EB1B8E54A660311C1A400F94F370B382BE9EA5B37836328BF2C2FADCFDD7C022006BE9C8336F56AE98135CBF6D87ABB47B3F5C38028E1438246078648CA031BF5C221036D9E146EDA0C9E01DF36F4735C39B29E8C8B58BFDB2BCF82E407A1CEEB8ED040FFFFFFFFA11701B6BC31DA3646DBAEBD0042AD7357B14A35B97461E9F2278DEB90FD6838D30000006B483045022100D7CD746B6352CDCF939870F2FC4B119B2F526171E00DA06ADB3359155E5BC03C022022E5126E535BE59FCF2AD6F6850B3F48DE7D5552D49468B00A01B728F4AB7239C221029C4787B4B8514206737095BB1C95E62BB901845E5AB8C4144B06E09C654F8F6CFFFFFFFFA11701B6BC31DA3646DBAEBD0042AD7357B14A35B97461E9F2278DEB90FD6838D20000006B483045022100CBC2A4BC0070EF066FDFC99D7214025E410C368D7711D1F30DB4D0A676C1D7B20220675CB5B255B882408C2797FFA5A25FE652F8B1D6E2CCBD8029905FDBAE88F9FEC22103346CEED4C7E38ECFDEF9DA13316C9549E2E3AB1BE03CEF2E1D799371C315897EFFFFFFFFCA40E64BC0512AD8EB45E5611A5482F609FD69D99C9E0AE4980D50C11B6C67D8000000006B483045022100E48A110972F0783E15EA0E89BD348D1531622872B0E35AB61B79A9098E3CFA5202206893582684F5CF2BDC6158EA4624B63788044E8142EA4247AD6979F66AFA7D48C221029C4787B4B8514206737095BB1C95E62BB901845E5AB8C4144B06E09C654F8F6CFFFFFFFFF47FA4B80212220A78327B2FE5F93263EA6659FFA6BD6D380C1D58C6739BE8D5010000006A473044022056F79F2D88910609ED1D2A83E86702A7794122D45C6433009BEBA328F60969E20220488D7D11D2DEED21A8A2034A537DF86A9319093DF782A54D1C49048D8A8028CEC2210364E1D7C8AB3D509207760BACF81BB050E67322EBF2E905FF309E89ACE13BE894FFFFFFFF1F6FCB9D335E553262F3FB1CA6A826DBBE9428DD579EA51BA6090C83A7D4FCDA010000006A47304402205C9C3FFC78210A7B93912FAC417775EE6DCD8B6794BE36D01C7D0BF36BC408D702201A253C7F4BD2464DED11A837C9EA628A97399632ED04C2FEA22CBD75579E58E8C2210364E1D7C8AB3D509207760BACF81BB050E67322EBF2E905FF309E89ACE13BE894FFFFFFFF09B0858061E61218B0BB5956508F643E3818FA1FBB1400ADA6D994704418DCD9010000006A47304402203FE198B7AB8F61546D62B35A4DF160DB438C84EFFD7067B46C60AF5F27E0CBB502205FB58F426A03427CDA37CCF5B63F672F5BFE71C7E8B791AFDEEACBD1D3595CB1C22103FB41089708436C88CF77E0700CB67ACDE37F255DC4CCDBD7637AA79307269630FFFFFFFF9B1A1B386F7D66899033F7B2AEB6A934CBA1BC2953AD4FE5E16A47EEC5F3FE23000000006A47304402202DDBBB9E92D1446A4F3890657F1F56EC2DC8F41DE864077CFDB41E6C99F75FDE02204553AC6BD3B9AE35DB4664BD18BF57B3E8E9BE84D76E40B78B77E760C36A064EC22103E080628C06E929C254B93A922BD42529A5E96491DFE0472AAF94928478B9EB60FFFFFFFF02FB55CA273FD7916E9C7B8F38D3F0287F9897980C840E0FA10F035DA33DAD47010000006B483045022100AC5FA70052293648A3BE5319C55B4E0A7E579F744CA04593F6EB88E0B88C1BA9022001B3419B5262022A8D5AADBEC1296167D436EE1808CD11CAC22C6B12B382CEB2C22103E080628C06E929C254B93A922BD42529A5E96491DFE0472AAF94928478B9EB60FFFFFFFF770E137F47D0C046AA1F02ED198F0F5EACBA78AED8A12D5B6AC9B169C75CC8ABB50000006A47304402204EBD05E2826D5263973B0C33AA32A6E5213C8378A16CF620E41E0AE27F04A5ED02201C38314E0755513CB720BDAAAACB495945C8B64873F04CCB0AB4ECE98C023543C22103E080628C06E929C254B93A922BD42529A5E96491DFE0472AAF94928478B9EB60FFFFFFFF770E137F47D0C046AA1F02ED198F0F5EACBA78AED8A12D5B6AC9B169C75CC8ABB40000006B483045022100CEE6BBBA8DFB309895A264091C9E9965EA71559F13DB22CE66DCD6A9E215E9DF0220355620462931985C870E5793C2F7222440CE468B1AD339BE4A85BADB81B25C08C22103D7558C265481BC9009884F2C6E629E7B6183D97538E9623503FC8CF5C7363D62FFFFFFFF249E0A85AC5C5F61771C6A7B1121C11FE2B68BCCA8734286AB936F10F0DF4C9E000000006B483045022100A1F45E58C823833DFA5BC5B7FE96618670911C9F1961B6E79CCBCC5D951859BB022034373BFF50DF19DD0E12736DAC6D9C4F5371C373CD6FB6CA0C07AF66AFD7F911C22103F9832BCBECE37C09BF91A46792F89C12C400F0E23F3B959CEA9EF1A9F5668888FFFFFFFF864243C3AC4F36396369D2A71FF4F0AB9C3BC0D3F12A5B396980542BE38C9E64330100006A473044022065A5B6C567A05E90B6C236678AEDBC6FE93371AC2F64D1EC0BF3F294EEC3A53202202E28C99E9E285DA66BAC4EEF042BABCD94A41E43A284F31A97D0A45CBE828A66C22103F9832BCBECE37C09BF91A46792F89C12C400F0E23F3B959CEA9EF1A9F5668888FFFFFFFF864243C3AC4F36396369D2A71FF4F0AB9C3BC0D3F12A5B396980542BE38C9E643501000069463043021F5601776FD074AB9A0FC636661D156CF07BF5B15B6648C5BC66D05DE4D3A663022048F33208CED52287867C6E56498553998ED9F5FF46FA5A5F2B14EC6F6C9F1FC6C221038948C2F32F21FF2E33B00D16E3204AF5EF888331C74D237709CA4D4654BBBB80FFFFFFFF864243C3AC4F36396369D2A71FF4F0AB9C3BC0D3F12A5B396980542BE38C9E64340100006B483045022100ED170557BCF179486B0CD35E56717721AA948941E84234F7CACC5EE3C24C3110022063B0CFBDB9C6C8F2AEBA01EFE48ED5B273006B8B6D238C1C1282763F7BA0852FC22102F72539E17B2A9FB12999AD5AEA4FEECB2CE50574B56B5CEEE4D02D8CD07090B7FFFFFFFF51386BF256B3987E0C6404D27D06E3E53B0DE6904A419F6B8DF038F13988A8CA000000006B483045022100E34C6EA96AF4701F0CF16E898E979EBC3EB214DDA8B485AEE811E21F1C34782D022047EAD42030B2E67B15B2A3417A0420D77467C71CA31AC06E759415E2ED1E73B0C221038948C2F32F21FF2E33B00D16E3204AF5EF888331C74D237709CA4D4654BBBB80FFFFFFFF11F69487F837BD1D30C88D6F89800760FD914CBEA11EFEFB97CC2EF8467FD29C000000006A473044022079A8AE9B2F18D6C8A8C57F925C8EDE9E7DC4E9B029A08FF04FB0E7955B18E8DA0220050B99D687C43AF8CADC311DB062309B2232D0A978AC6E39328A562D3965243DC221038948C2F32F21FF2E33B00D16E3204AF5EF888331C74D237709CA4D4654BBBB80FFFFFFFFE10CEAE7D2BB2D7C60DD853E6DF8540D352C6FCA363553690425F267F4E36BB5380000006B4830450221009CF2B05A6B673E2AFF83CDA2B52D2FEF073DC8DC84C544CB5F978532A626CC7502206B6F69D943286ED45E7A5F430DEE8C6475F95EB8E557A2E2C5785F60B4E5E5E3C221022586C020EC9DF598D68F69967E61123B8F487CEFF465C8A1A0BCD377C0D4C608FFFFFFFFFBC6C11521941FBBB72A0F3B68D609F66419586D47ED2F313C64181918A04A92010000006B483045022100BEDFA3ADCBF41A099F4372746682F305A5245E08FA137801E7D4EBDE8E7EDEED02206D15AFECC651B8F6C65B59B8844C2088AA154625746A8A02C617D99277D95895C22103987C11B7D23C49817D6164B9C57CE5C845BE9E11342EBCF19095A7486B9BF147FFFFFFFF5D08873B553F347F83F8B30740C5DCBB7586E22A121ADF1888DA6F23F2C253646D0000006A47304402202E6E19291842A0390CA9098510F686D993D02F7A5C01305E5B7EF075BBBEC92E022031C1E35D8DE8F62FA015249FAD699DCA3BD7D48C60FA262C4A25872A99885E98C22103987C11B7D23C49817D6164B9C57CE5C845BE9E11342EBCF19095A7486B9BF147FFFFFFFF5D08873B553F347F83F8B30740C5DCBB7586E22A121ADF1888DA6F23F2C253646C0000006A473044022010920B2B3465ECF21A685884AD54E041C54B0CC73DE7A988921C742B06BEB51302203DB46BD95FEBD29A69008A214A0E7ED65B6B49FB5C96DD086ED10851B7C55B3DC2210239F7060641B0E9A8ED1365420BA2987479ABD66206275067E4EAC21FDCE2AF5AFFFFFFFF73D4D99BA348D4DA8E7F221709280F16A14B4C1E72C1A0E24AD5FC8F09CEED7D010000006A4730440220584F82CBCD237083BE0B5C80645AB8A31C0EAD5C140BD5C299EA3B7270ADADF40220429CAD186E80F0936528B2A3313EEF8A0BC67403969880BF0C1E762FCF82A062C2210239F7060641B0E9A8ED1365420BA2987479ABD66206275067E4EAC21FDCE2AF5AFFFFFFFF0843CB3AD2622892163DF29617F45A799E09B667AD707AD6FE7D0C2FF6FA0248010000006B483045022100DE499AD82B27200F140417C92D2BB7223F4A51AA4E3B3EC0942FFADCA8572F990220587EA05565349E79CA85DFEEE6617335BF50DD56CC0A73434478B867927253D7C2210239F7060641B0E9A8ED1365420BA2987479ABD66206275067E4EAC21FDCE2AF5AFFFFFFFF7E3EFF23768186357CD9E23A3C5E64D7CCDF778D4625C5FD7AF8AA0BA26D18B1010000006A47304402201667B3A2445F77BCD6A4A9DCB87B052E50189F8F261847F165EA6AA8C30204B8022034A449DCEED01B782EEB764B1453A7696B6F45BCDF58F5A16242A27B40254A26C2210205EB0CF0442AC7CF95F237F83631F3A71A769F14070BFBA130E7F6446D0FDA89FFFFFFFF7BD7CA433910CD9CD3A31E3C526C8A08F56218ABEBB8FA7B6D7F9013770903B7060000006B483045022100CBE66D90AF66E7B2098644D489E761D2E1A017DA1BCF514F6EB9CC0D143D3E29022028C3D949EBEB493C630EBA6B94E963DEE224F82E0CAFA688DCE82BF2E3E33029C2210205EB0CF0442AC7CF95F237F83631F3A71A769F14070BFBA130E7F6446D0FDA89FFFFFFFFC06A85664B630EC529F066F082CD4ECE9C6D627B4A25FA052A4321CE201F5249000000006B483045022100B8E3DBB1B95253947D66224F2B56D4AD32CEE62862AA6079BBFDB2A29097384C02207B06BAFDD798EBFC1042952A214EE0095AC456E4EC7ADCD2D7643AC940E37808C22102E6A2C34586C6A2F9F9D8247622E03E2427D8DA8BAD7069B5FBD4BAB7CFD495BEFFFFFFFF5455D0E0DAF167EA4DD6268EBF681F5B627E3CDB95A64E45B46504B47DE7559B010000006A47304402202FB18936EAA9E7574D68B64FD3A72163DC02F36E76105F6230B69B9A8CE8186E02200669E0FF51A609CF52F2D484CF90DECC7E0F288815D889DD54A208FDAFCB0480C22102E6A2C34586C6A2F9F9D8247622E03E2427D8DA8BAD7069B5FBD4BAB7CFD495BEFFFFFFFF0FC11392D3D66CE589DBEE6396A9C91906E94E5FFB0F10582DD84DC27C139549010000006B483045022100B1B780C18EE1B24A67756E15ED487626247718743B25781E8DCEF385817EBA0A0220422935FE91405FD3E2834EBE03EA27DEA2AD73F2E5A32798D3EFAA28A11B0E45C22102D54A842BF3053DA8139191C78DD95859326551C14D33317232240E825AC86721FFFFFFFF5C81D63ACF4A9539158B16F116C9FE16E61AD2EAE8627B0DAF6E5E27D7065BCE4B0000006A473044022070BEAC59696981AB7E13CB99C8AA5EBDA64AB3B2CEFC4197760480B24473C62A02201AC5EA4E1AA854C7CF641A70D5629CE17D3101D0F29F383EBFD300D11B8355F7C22103E0C3031D39F82DCED6FE23F7DAEF43C1C2AA37279E6CACFCC3D65C20896EFAFEFFFFFFFFA832AAD47D0F6C088C259B108C1234866D824B63081D056889560A63987A9F61000000006B483045022100F67205F32BE5981277C403ADD7DDCF355760545FA5F07B5221AC51AD39B5D6240220015D5AC3AE684183E92F128C96B8C4FBE37D581A2238B55548D0FAE5188C93D0C221030A82429D655A883ABB84A6F494ED0F584FAE70AF76F6FFE089FC858DFF6791CAFFFFFFFF9F7AB7BD8B01B35936A0806314FBA6E05978B00B588809CBC1BFE440BE48F437010000006B483045022100B0E893E5300216E39CBA60AA01BBCF233024A364F6688305CBB5A23FD99A9DDB02200BE2E288377E83222C066A4647EEE4A0F8DB1289034F19C75B029071A74B1BB3C221028AA47294780FCE86047AD43B106B887101311EF2EC15CF8CC781A5E94E941B87FFFFFFFF437A577E1B156B11BA5D3D4F77883778B8A16344DE7A493337A48A4277E3501F640000006B4830450221008BDFE07288CC912878F66E451DA2067E02FD2169B32C42ADC226CA0AC588ABFC02207F3F185DB742C755F554539C2DDAE99DB84BF31198623F3D36B28A6040F13187C221028DC193FA0BAE51229C0D913B37B4B85E7D8657C67E6B39DE55F0F829F3E56F97FFFFFFFFEB46CAC62C55714409DC0CB9DEB430A28BDF64DE9F67D2A462E6901B4D633376010000006A47304402203627468E6F210ABD49276436DC5A76DF6160D25650C62F5943140AC70FECF39302202294C59CF141219551382ECCE8D529F346A88413070DC90FB11B3AFA24C9DDE5C2210375727B6DF18C46DA978E03F1197AD63F3A7A2EB59ECC6C808F01CF01DF4CC462FFFFFFFFFE263AF23E8A0656DA85D0E776CD26B77EB606869C41119CF0211DC3EB7FACD1210100006B483045022100967F8B5E10858E507C64F9DA6FF840133FD5A76E515C3CFDF88833E9819733F2022052B33CD8CD3AB5CF745C75136F2CDF675620BB94D09616117567FD22D08AD052C2210375727B6DF18C46DA978E03F1197AD63F3A7A2EB59ECC6C808F01CF01DF4CC462FFFFFFFFFE263AF23E8A0656DA85D0E776CD26B77EB606869C41119CF0211DC3EB7FACD1200100006B483045022100ADC229F8037EB7B3D08D6DE7A0DEAAE2874D7B943406D9ADAEC34899A7CC0B62022059DE20822F8E1DF474C0C763EAB20EB1AADC9DAC2EBB3D685CB24EC6917AFC49C221027ED09AC05B9215F00B6F8BE59CEC79284542F5E8C1D17AC660B2C296FCEE931BFFFFFFFF232740426EDFE1EA3337FB4438252AA67FB144C6CB1DAC76FEBB16BB954C6ABA000000006B483045022100DB65D8077D5EA9C886629F328BFCAC9ACBA3FF83E50EA18C360CE22CD6DC3BDC022001759AF276AFE21C13A66539008DC5F0469129A3FB7A51703B2FE416047C8A1CC221027ED09AC05B9215F00B6F8BE59CEC79284542F5E8C1D17AC660B2C296FCEE931BFFFFFFFF09537489C63ED62DF8D069AEFD16BF4775E1D9878F0BE9EAC4AC2CB3A8169DAE260000006B483045022100D0CAA6FD70BF80C6E936F4738221F874E9C620FE1CA96BC0D87F23FF863B33DE0220124B342E241E41C2645DC4181A75239618D267E64BBDAB7A72109BFAB89FE784C22102C4559C96B87528C3B2385DC63216B0EEE1E25524E9E45CBB7577DEF21B1D62B9FFFFFFFF3739FA73213ED1440431274667DDCEA593DFBDFADFF26F37359BC06492BBB0E59B0000006B48304502210099AA3BD609A06C875D0F584B0A6644387179ACB6F63C690C6FF20B650653259802205898DD42BC06A8F8D1A74A2F74CCBA7B0D6DCBDA51A9B7ADD12E5F4F13121CCFC2210366C2029F74160CBA941383501C988D37BF932629F97B4E07DF1A339EC25ADB71FFFFFFFFC34D896F7B4EAE1344A02398292A2FDDD464E15A0C3321FF17D3B96D92D8FB64340000006B483045022100F32667A5734DDA65A6DDF9DFA789907B1ABBEBB0062CD694FA6E2A57A13178A202205BAF300DFADA245B470BA87794219E8173723FF3AC6FEA06296D23297375BF45C2210268C6B69A5BC61E1F3452D5828D7D2D8FBD4AAC371665ADB17973198377DD10D4FFFFFFFFCFD345CB9C6D4574D28EF1E0704B2657434FBAE1521F27D9AE1E005039DF4D92940000006B483045022100F228CC33D6EAAE7C0631741D1D0DD1EE02ECF725DDEFB1D02C877B3E449AA588022052C50C407B0217EE829BC1392971198ED7D08D18A5ABF90C13D9A81F20D7EA65C2210265BD8F8378E28817B5CBE47B08E326FC9972F27D1A354A85F43888507B10A497FFFFFFFF4DFCB8A82E6BFA8EB78BA4E66F0142B49D685D3036094A7F490DB544007E2292560000006B483045022100A82557798CCA2E6D8F00FBB49A9DE767BB2079E90B615DF29E7F44A870BBA43C02207B2B038237D55F962046B8046E53DF428999D716EEC2B980A927ADD5AE3A607AC22102463CABC398AAC0B7239F1AB82D0794B4E9FF87D4DBBE8747E5A94586485013DCFFFFFFFFEAEACA9F9CDE43599A95F529769BE324C910E0BE55BC84E1F1E92F0DE60F82842A0000006A473044022041765D681A868D6898F1931ECA896B624C7796DF89A7C80004AEFCD4A84D0A19022053ABCE69D529BE59BBC859D4314C2E093FB2C24823001A396DCE4CD7B2F21AA7C2210364BB8517C6A28CF7253DAEBBBA7064A4216125DE6476426E74480A3371B92D42FFFFFFFF25DB850D2664BA6B4DEADC76366DA35C1780C4B937E6DF473C602B49C2F47688380100006A47304402202145BEFCBD10A3D97AF74E264AEFBB6931227FF723BE6A680D277B185E25919902205C1769C6BF8F036F57B092F428C06E39081AF979DE35415AF6C74B294BDD4211C22103B04A47F53CF3BB0F7B00088D453E36618148B9261FAEF8CE8F6B3FA3DFEFBDCAFFFFFFFF01031864CD2E0000001976A91465BD7B5E75C7450F77976954A91DE75C73BEB4CE88AC00000000`
|