@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.
Files changed (390) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/.env.template +22 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  4. package/.github/ISSUE_TEMPLATE/discussion.md +24 -0
  5. package/.github/pull_request_template.md +22 -0
  6. package/.github/workflows/push.yaml +145 -0
  7. package/.prettierrc +10 -0
  8. package/CHANGELOG.md +280 -0
  9. package/CONTRIBUTING.md +89 -0
  10. package/README.md +43 -0
  11. package/docs/README.md +85 -0
  12. package/docs/client.md +19627 -0
  13. package/docs/monitor.md +953 -0
  14. package/docs/open-rpc/index.html +46 -0
  15. package/docs/services.md +6377 -0
  16. package/docs/setup.md +1268 -0
  17. package/docs/storage.md +5367 -0
  18. package/docs/wallet.md +19626 -0
  19. package/jest.config.ts +25 -0
  20. package/license.md +28 -0
  21. package/out/tsconfig.all.tsbuildinfo +1 -0
  22. package/package.json +63 -0
  23. package/src/CWIStyleWalletManager.ts +1999 -0
  24. package/src/Setup.ts +579 -0
  25. package/src/SetupClient.ts +322 -0
  26. package/src/SetupWallet.ts +108 -0
  27. package/src/SimpleWalletManager.ts +526 -0
  28. package/src/Wallet.ts +1169 -0
  29. package/src/WalletAuthenticationManager.ts +153 -0
  30. package/src/WalletLogger.ts +213 -0
  31. package/src/WalletPermissionsManager.ts +3660 -0
  32. package/src/WalletSettingsManager.ts +114 -0
  33. package/src/__tests/CWIStyleWalletManager.test.d.ts.map +1 -0
  34. package/src/__tests/CWIStyleWalletManager.test.js.map +1 -0
  35. package/src/__tests/CWIStyleWalletManager.test.ts +675 -0
  36. package/src/__tests/WalletPermissionsManager.callbacks.test.ts +323 -0
  37. package/src/__tests/WalletPermissionsManager.checks.test.ts +844 -0
  38. package/src/__tests/WalletPermissionsManager.encryption.test.ts +412 -0
  39. package/src/__tests/WalletPermissionsManager.fixtures.ts +307 -0
  40. package/src/__tests/WalletPermissionsManager.flows.test.ts +462 -0
  41. package/src/__tests/WalletPermissionsManager.initialization.test.ts +300 -0
  42. package/src/__tests/WalletPermissionsManager.pmodules.test.ts +798 -0
  43. package/src/__tests/WalletPermissionsManager.proxying.test.ts +724 -0
  44. package/src/__tests/WalletPermissionsManager.tokens.test.ts +503 -0
  45. package/src/index.all.ts +27 -0
  46. package/src/index.client.ts +25 -0
  47. package/src/index.mobile.ts +21 -0
  48. package/src/index.ts +1 -0
  49. package/src/monitor/Monitor.ts +412 -0
  50. package/src/monitor/MonitorDaemon.ts +188 -0
  51. package/src/monitor/README.md +3 -0
  52. package/src/monitor/__test/MonitorDaemon.man.test.ts +45 -0
  53. package/src/monitor/tasks/TaskCheckForProofs.ts +243 -0
  54. package/src/monitor/tasks/TaskCheckNoSends.ts +73 -0
  55. package/src/monitor/tasks/TaskClock.ts +33 -0
  56. package/src/monitor/tasks/TaskFailAbandoned.ts +54 -0
  57. package/src/monitor/tasks/TaskMonitorCallHistory.ts +26 -0
  58. package/src/monitor/tasks/TaskNewHeader.ts +93 -0
  59. package/src/monitor/tasks/TaskPurge.ts +68 -0
  60. package/src/monitor/tasks/TaskReorg.ts +89 -0
  61. package/src/monitor/tasks/TaskReviewStatus.ts +48 -0
  62. package/src/monitor/tasks/TaskSendWaiting.ts +122 -0
  63. package/src/monitor/tasks/TaskSyncWhenIdle.ts +26 -0
  64. package/src/monitor/tasks/TaskUnFail.ts +151 -0
  65. package/src/monitor/tasks/WalletMonitorTask.ts +47 -0
  66. package/src/sdk/CertOpsWallet.ts +18 -0
  67. package/src/sdk/PrivilegedKeyManager.ts +372 -0
  68. package/src/sdk/README.md +13 -0
  69. package/src/sdk/WERR_errors.ts +234 -0
  70. package/src/sdk/WalletError.ts +170 -0
  71. package/src/sdk/WalletErrorFromJson.ts +80 -0
  72. package/src/sdk/WalletServices.interfaces.ts +700 -0
  73. package/src/sdk/WalletSigner.interfaces.ts +11 -0
  74. package/src/sdk/WalletStorage.interfaces.ts +606 -0
  75. package/src/sdk/__test/CertificateLifeCycle.test.ts +131 -0
  76. package/src/sdk/__test/PrivilegedKeyManager.test.ts +738 -0
  77. package/src/sdk/__test/WalletError.test.ts +318 -0
  78. package/src/sdk/__test/validationHelpers.test.ts +21 -0
  79. package/src/sdk/index.ts +10 -0
  80. package/src/sdk/types.ts +226 -0
  81. package/src/services/README.md +11 -0
  82. package/src/services/ServiceCollection.ts +248 -0
  83. package/src/services/Services.ts +603 -0
  84. package/src/services/__tests/ARC.man.test.ts +123 -0
  85. package/src/services/__tests/ARC.timeout.man.test.ts +79 -0
  86. package/src/services/__tests/ArcGorillaPool.man.test.ts +108 -0
  87. package/src/services/__tests/arcServices.test.ts +8 -0
  88. package/src/services/__tests/bitrails.test.ts +56 -0
  89. package/src/services/__tests/getMerklePath.test.ts +15 -0
  90. package/src/services/__tests/getRawTx.test.ts +13 -0
  91. package/src/services/__tests/postBeef.test.ts +104 -0
  92. package/src/services/__tests/verifyBeef.test.ts +50 -0
  93. package/src/services/chaintracker/BHServiceClient.ts +212 -0
  94. package/src/services/chaintracker/ChaintracksChainTracker.ts +71 -0
  95. package/src/services/chaintracker/__tests/ChaintracksChainTracker.test.ts +33 -0
  96. package/src/services/chaintracker/__tests/ChaintracksServiceClient.test.ts +29 -0
  97. package/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.ts +72 -0
  98. package/src/services/chaintracker/chaintracks/Api/BulkIngestorApi.ts +83 -0
  99. package/src/services/chaintracker/chaintracks/Api/BulkStorageApi.ts +92 -0
  100. package/src/services/chaintracker/chaintracks/Api/ChaintracksApi.ts +64 -0
  101. package/src/services/chaintracker/chaintracks/Api/ChaintracksClientApi.ts +189 -0
  102. package/src/services/chaintracker/chaintracks/Api/ChaintracksFetchApi.ts +18 -0
  103. package/src/services/chaintracker/chaintracks/Api/ChaintracksFsApi.ts +58 -0
  104. package/src/services/chaintracker/chaintracks/Api/ChaintracksStorageApi.ts +386 -0
  105. package/src/services/chaintracker/chaintracks/Api/LiveIngestorApi.ts +25 -0
  106. package/src/services/chaintracker/chaintracks/Chaintracks.ts +609 -0
  107. package/src/services/chaintracker/chaintracks/ChaintracksService.ts +199 -0
  108. package/src/services/chaintracker/chaintracks/ChaintracksServiceClient.ts +154 -0
  109. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.ts +176 -0
  110. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDN.ts +174 -0
  111. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDNBabbage.ts +18 -0
  112. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.ts +113 -0
  113. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainWs.ts +81 -0
  114. package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.ts +86 -0
  115. package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.ts +59 -0
  116. package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.ts +104 -0
  117. package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainWs.ts +66 -0
  118. package/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.ts +566 -0
  119. package/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.ts +219 -0
  120. package/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorCDNBabbage.test.ts +54 -0
  121. package/src/services/chaintracker/chaintracks/Ingest/__tests/LiveIngestorWhatsOnChainPoll.test.ts +33 -0
  122. package/src/services/chaintracker/chaintracks/Ingest/__tests/WhatsOnChainServices.test.ts +124 -0
  123. package/src/services/chaintracker/chaintracks/Storage/BulkStorageBase.ts +92 -0
  124. package/src/services/chaintracker/chaintracks/Storage/ChaintracksKnexMigrations.ts +104 -0
  125. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.ts +382 -0
  126. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.ts +574 -0
  127. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.ts +438 -0
  128. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageMemory.ts +29 -0
  129. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.ts +304 -0
  130. package/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageIdb.test.ts +102 -0
  131. package/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageKnex.test.ts +45 -0
  132. package/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.ts +77 -0
  133. package/src/services/chaintracker/chaintracks/__tests/ChaintracksClientApi.test.ts +192 -0
  134. package/src/services/chaintracker/chaintracks/__tests/LocalCdnServer.ts +75 -0
  135. package/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.ts +62 -0
  136. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNetBlockHeaders.json +1 -0
  137. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_0.headers +0 -0
  138. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_1.headers +0 -0
  139. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_2.headers +0 -0
  140. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_3.headers +0 -0
  141. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNetBlockHeaders.json +1 -0
  142. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_0.headers +0 -0
  143. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_1.headers +0 -0
  144. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_2.headers +0 -0
  145. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_3.headers +0 -0
  146. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNetBlockHeaders.json +1 -0
  147. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_0.headers +0 -0
  148. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_1.headers +0 -0
  149. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_2.headers +0 -0
  150. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_3.headers +0 -0
  151. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNetBlockHeaders.json +1 -0
  152. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_0.headers +0 -0
  153. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_1.headers +0 -0
  154. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_2.headers +0 -0
  155. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_3.headers +0 -0
  156. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_4.headers +0 -0
  157. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNetBlockHeaders.json +1 -0
  158. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_0.headers +0 -0
  159. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_1.headers +0 -0
  160. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_2.headers +0 -0
  161. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_3.headers +0 -0
  162. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_4.headers +0 -0
  163. package/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.ts +92 -0
  164. package/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.ts +111 -0
  165. package/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.ts +91 -0
  166. package/src/services/chaintracker/chaintracks/createIdbChaintracks.ts +60 -0
  167. package/src/services/chaintracker/chaintracks/createKnexChaintracks.ts +65 -0
  168. package/src/services/chaintracker/chaintracks/createNoDbChaintracks.ts +60 -0
  169. package/src/services/chaintracker/chaintracks/index.all.ts +12 -0
  170. package/src/services/chaintracker/chaintracks/index.client.ts +4 -0
  171. package/src/services/chaintracker/chaintracks/index.mobile.ts +37 -0
  172. package/src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts +975 -0
  173. package/src/services/chaintracker/chaintracks/util/BulkFileDataReader.ts +60 -0
  174. package/src/services/chaintracker/chaintracks/util/BulkFilesReader.ts +336 -0
  175. package/src/services/chaintracker/chaintracks/util/BulkHeaderFile.ts +247 -0
  176. package/src/services/chaintracker/chaintracks/util/ChaintracksFetch.ts +69 -0
  177. package/src/services/chaintracker/chaintracks/util/ChaintracksFs.ts +141 -0
  178. package/src/services/chaintracker/chaintracks/util/HeightRange.ts +153 -0
  179. package/src/services/chaintracker/chaintracks/util/SingleWriterMultiReaderLock.ts +76 -0
  180. package/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.ts +304 -0
  181. package/src/services/chaintracker/chaintracks/util/__tests/ChaintracksFetch.test.ts +60 -0
  182. package/src/services/chaintracker/chaintracks/util/__tests/HeightRange.test.ts +67 -0
  183. package/src/services/chaintracker/chaintracks/util/__tests/SingleWriterMultiReaderLock.test.ts +49 -0
  184. package/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.ts +573 -0
  185. package/src/services/chaintracker/chaintracks/util/dirtyHashes.ts +29 -0
  186. package/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.ts +432 -0
  187. package/src/services/chaintracker/index.all.ts +4 -0
  188. package/src/services/chaintracker/index.client.ts +4 -0
  189. package/src/services/chaintracker/index.mobile.ts +4 -0
  190. package/src/services/createDefaultWalletServicesOptions.ts +77 -0
  191. package/src/services/index.ts +1 -0
  192. package/src/services/processingErrors/arcSuccessError.json +76 -0
  193. package/src/services/providers/ARC.ts +350 -0
  194. package/src/services/providers/Bitails.ts +256 -0
  195. package/src/services/providers/SdkWhatsOnChain.ts +83 -0
  196. package/src/services/providers/WhatsOnChain.ts +883 -0
  197. package/src/services/providers/__tests/WhatsOnChain.test.ts +242 -0
  198. package/src/services/providers/__tests/exchangeRates.test.ts +18 -0
  199. package/src/services/providers/exchangeRates.ts +265 -0
  200. package/src/services/providers/getBeefForTxid.ts +369 -0
  201. package/src/signer/README.md +5 -0
  202. package/src/signer/WalletSigner.ts +17 -0
  203. package/src/signer/methods/acquireDirectCertificate.ts +52 -0
  204. package/src/signer/methods/buildSignableTransaction.ts +183 -0
  205. package/src/signer/methods/completeSignedTransaction.ts +117 -0
  206. package/src/signer/methods/createAction.ts +172 -0
  207. package/src/signer/methods/internalizeAction.ts +106 -0
  208. package/src/signer/methods/proveCertificate.ts +43 -0
  209. package/src/signer/methods/signAction.ts +54 -0
  210. package/src/storage/README.md +14 -0
  211. package/src/storage/StorageIdb.ts +2304 -0
  212. package/src/storage/StorageKnex.ts +1425 -0
  213. package/src/storage/StorageProvider.ts +810 -0
  214. package/src/storage/StorageReader.ts +194 -0
  215. package/src/storage/StorageReaderWriter.ts +432 -0
  216. package/src/storage/StorageSyncReader.ts +34 -0
  217. package/src/storage/WalletStorageManager.ts +943 -0
  218. package/src/storage/__test/StorageIdb.test.ts +43 -0
  219. package/src/storage/__test/WalletStorageManager.test.ts +275 -0
  220. package/src/storage/__test/adminStats.man.test.ts +89 -0
  221. package/src/storage/__test/getBeefForTransaction.test.ts +385 -0
  222. package/src/storage/index.all.ts +11 -0
  223. package/src/storage/index.client.ts +7 -0
  224. package/src/storage/index.mobile.ts +6 -0
  225. package/src/storage/methods/ListActionsSpecOp.ts +70 -0
  226. package/src/storage/methods/ListOutputsSpecOp.ts +129 -0
  227. package/src/storage/methods/__test/GenerateChange/generateChangeSdk.test.ts +1057 -0
  228. package/src/storage/methods/__test/GenerateChange/randomValsUsed1.ts +20 -0
  229. package/src/storage/methods/__test/offsetKey.test.ts +274 -0
  230. package/src/storage/methods/attemptToPostReqsToNetwork.ts +389 -0
  231. package/src/storage/methods/createAction.ts +947 -0
  232. package/src/storage/methods/generateChange.ts +556 -0
  233. package/src/storage/methods/getBeefForTransaction.ts +139 -0
  234. package/src/storage/methods/getSyncChunk.ts +293 -0
  235. package/src/storage/methods/internalizeAction.ts +562 -0
  236. package/src/storage/methods/listActionsIdb.ts +183 -0
  237. package/src/storage/methods/listActionsKnex.ts +226 -0
  238. package/src/storage/methods/listCertificates.ts +73 -0
  239. package/src/storage/methods/listOutputsIdb.ts +203 -0
  240. package/src/storage/methods/listOutputsKnex.ts +263 -0
  241. package/src/storage/methods/offsetKey.ts +89 -0
  242. package/src/storage/methods/processAction.ts +420 -0
  243. package/src/storage/methods/purgeData.ts +251 -0
  244. package/src/storage/methods/purgeDataIdb.ts +10 -0
  245. package/src/storage/methods/reviewStatus.ts +101 -0
  246. package/src/storage/methods/reviewStatusIdb.ts +43 -0
  247. package/src/storage/methods/utils.Buffer.ts +33 -0
  248. package/src/storage/methods/utils.ts +56 -0
  249. package/src/storage/remoting/StorageClient.ts +567 -0
  250. package/src/storage/remoting/StorageMobile.ts +544 -0
  251. package/src/storage/remoting/StorageServer.ts +291 -0
  252. package/src/storage/remoting/__test/StorageClient.test.ts +113 -0
  253. package/src/storage/schema/KnexMigrations.ts +489 -0
  254. package/src/storage/schema/StorageIdbSchema.ts +150 -0
  255. package/src/storage/schema/entities/EntityBase.ts +210 -0
  256. package/src/storage/schema/entities/EntityCertificate.ts +188 -0
  257. package/src/storage/schema/entities/EntityCertificateField.ts +136 -0
  258. package/src/storage/schema/entities/EntityCommission.ts +148 -0
  259. package/src/storage/schema/entities/EntityOutput.ts +290 -0
  260. package/src/storage/schema/entities/EntityOutputBasket.ts +153 -0
  261. package/src/storage/schema/entities/EntityOutputTag.ts +121 -0
  262. package/src/storage/schema/entities/EntityOutputTagMap.ts +123 -0
  263. package/src/storage/schema/entities/EntityProvenTx.ts +319 -0
  264. package/src/storage/schema/entities/EntityProvenTxReq.ts +580 -0
  265. package/src/storage/schema/entities/EntitySyncState.ts +389 -0
  266. package/src/storage/schema/entities/EntityTransaction.ts +306 -0
  267. package/src/storage/schema/entities/EntityTxLabel.ts +121 -0
  268. package/src/storage/schema/entities/EntityTxLabelMap.ts +123 -0
  269. package/src/storage/schema/entities/EntityUser.ts +112 -0
  270. package/src/storage/schema/entities/MergeEntity.ts +73 -0
  271. package/src/storage/schema/entities/__tests/CertificateFieldTests.test.ts +353 -0
  272. package/src/storage/schema/entities/__tests/CertificateTests.test.ts +354 -0
  273. package/src/storage/schema/entities/__tests/CommissionTests.test.ts +371 -0
  274. package/src/storage/schema/entities/__tests/OutputBasketTests.test.ts +278 -0
  275. package/src/storage/schema/entities/__tests/OutputTagMapTests.test.ts +242 -0
  276. package/src/storage/schema/entities/__tests/OutputTagTests.test.ts +288 -0
  277. package/src/storage/schema/entities/__tests/OutputTests.test.ts +464 -0
  278. package/src/storage/schema/entities/__tests/ProvenTxReqTests.test.ts +340 -0
  279. package/src/storage/schema/entities/__tests/ProvenTxTests.test.ts +504 -0
  280. package/src/storage/schema/entities/__tests/SyncStateTests.test.ts +288 -0
  281. package/src/storage/schema/entities/__tests/TransactionTests.test.ts +604 -0
  282. package/src/storage/schema/entities/__tests/TxLabelMapTests.test.ts +361 -0
  283. package/src/storage/schema/entities/__tests/TxLabelTests.test.ts +198 -0
  284. package/src/storage/schema/entities/__tests/stampLogTests.test.ts +90 -0
  285. package/src/storage/schema/entities/__tests/usersTests.test.ts +340 -0
  286. package/src/storage/schema/entities/index.ts +16 -0
  287. package/src/storage/schema/tables/TableCertificate.ts +21 -0
  288. package/src/storage/schema/tables/TableCertificateField.ts +12 -0
  289. package/src/storage/schema/tables/TableCommission.ts +13 -0
  290. package/src/storage/schema/tables/TableMonitorEvent.ts +9 -0
  291. package/src/storage/schema/tables/TableOutput.ts +64 -0
  292. package/src/storage/schema/tables/TableOutputBasket.ts +12 -0
  293. package/src/storage/schema/tables/TableOutputTag.ts +10 -0
  294. package/src/storage/schema/tables/TableOutputTagMap.ts +9 -0
  295. package/src/storage/schema/tables/TableProvenTx.ts +14 -0
  296. package/src/storage/schema/tables/TableProvenTxReq.ts +65 -0
  297. package/src/storage/schema/tables/TableSettings.ts +17 -0
  298. package/src/storage/schema/tables/TableSyncState.ts +18 -0
  299. package/src/storage/schema/tables/TableTransaction.ts +54 -0
  300. package/src/storage/schema/tables/TableTxLabel.ts +10 -0
  301. package/src/storage/schema/tables/TableTxLabelMap.ts +9 -0
  302. package/src/storage/schema/tables/TableUser.ts +16 -0
  303. package/src/storage/schema/tables/index.ts +16 -0
  304. package/src/storage/sync/StorageMySQLDojoReader.ts +696 -0
  305. package/src/storage/sync/index.ts +1 -0
  306. package/src/utility/Format.ts +133 -0
  307. package/src/utility/README.md +3 -0
  308. package/src/utility/ReaderUint8Array.ts +187 -0
  309. package/src/utility/ScriptTemplateBRC29.ts +73 -0
  310. package/src/utility/__tests/utilityHelpers.noBuffer.test.ts +109 -0
  311. package/src/utility/aggregateResults.ts +68 -0
  312. package/src/utility/identityUtils.ts +159 -0
  313. package/src/utility/index.all.ts +7 -0
  314. package/src/utility/index.client.ts +7 -0
  315. package/src/utility/parseTxScriptOffsets.ts +29 -0
  316. package/src/utility/stampLog.ts +69 -0
  317. package/src/utility/tscProofToMerklePath.ts +48 -0
  318. package/src/utility/utilityHelpers.buffer.ts +34 -0
  319. package/src/utility/utilityHelpers.noBuffer.ts +60 -0
  320. package/src/utility/utilityHelpers.ts +275 -0
  321. package/src/wab-client/WABClient.ts +94 -0
  322. package/src/wab-client/__tests/WABClient.man.test.ts +59 -0
  323. package/src/wab-client/auth-method-interactors/AuthMethodInteractor.ts +47 -0
  324. package/src/wab-client/auth-method-interactors/DevConsoleInteractor.ts +73 -0
  325. package/src/wab-client/auth-method-interactors/PersonaIDInteractor.ts +35 -0
  326. package/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.ts +72 -0
  327. package/syncVersions.js +71 -0
  328. package/test/Wallet/StorageClient/storageClient.man.test.ts +75 -0
  329. package/test/Wallet/action/abortAction.test.ts +47 -0
  330. package/test/Wallet/action/createAction.test.ts +299 -0
  331. package/test/Wallet/action/createAction2.test.ts +1273 -0
  332. package/test/Wallet/action/createActionToGenerateBeefs.man.test.ts +293 -0
  333. package/test/Wallet/action/internalizeAction.a.test.ts +286 -0
  334. package/test/Wallet/action/internalizeAction.test.ts +682 -0
  335. package/test/Wallet/action/relinquishOutput.test.ts +37 -0
  336. package/test/Wallet/certificate/acquireCertificate.test.ts +298 -0
  337. package/test/Wallet/certificate/listCertificates.test.ts +346 -0
  338. package/test/Wallet/construct/Wallet.constructor.test.ts +57 -0
  339. package/test/Wallet/get/getHeaderForHeight.test.ts +82 -0
  340. package/test/Wallet/get/getHeight.test.ts +52 -0
  341. package/test/Wallet/get/getKnownTxids.test.ts +86 -0
  342. package/test/Wallet/get/getNetwork.test.ts +27 -0
  343. package/test/Wallet/get/getVersion.test.ts +27 -0
  344. package/test/Wallet/list/listActions.test.ts +279 -0
  345. package/test/Wallet/list/listActions2.test.ts +1381 -0
  346. package/test/Wallet/list/listCertificates.test.ts +118 -0
  347. package/test/Wallet/list/listOutputs.test.ts +447 -0
  348. package/test/Wallet/live/walletLive.man.test.ts +521 -0
  349. package/test/Wallet/local/localWallet.man.test.ts +93 -0
  350. package/test/Wallet/local/localWallet2.man.test.ts +277 -0
  351. package/test/Wallet/signAction/mountaintop.man.test.ts +130 -0
  352. package/test/Wallet/specOps/specOps.man.test.ts +220 -0
  353. package/test/Wallet/support/janitor.man.test.ts +40 -0
  354. package/test/Wallet/support/operations.man.test.ts +407 -0
  355. package/test/Wallet/support/reqErrorReview.2025.05.06.man.test.ts +347 -0
  356. package/test/Wallet/sync/Wallet.sync.test.ts +215 -0
  357. package/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.ts +203 -0
  358. package/test/Wallet/sync/setActive.test.ts +170 -0
  359. package/test/WalletClient/LocalKVStore.man.test.ts +114 -0
  360. package/test/WalletClient/WERR.man.test.ts +35 -0
  361. package/test/bsv-ts-sdk/LocalKVStore.test.ts +102 -0
  362. package/test/checkDB.ts +57 -0
  363. package/test/checkdb +0 -0
  364. package/test/examples/backup.man.test.ts +59 -0
  365. package/test/examples/pushdrop.test.ts +282 -0
  366. package/test/monitor/Monitor.test.ts +620 -0
  367. package/test/services/Services.test.ts +263 -0
  368. package/test/storage/KnexMigrations.test.ts +86 -0
  369. package/test/storage/StorageMySQLDojoReader.man.test.ts +60 -0
  370. package/test/storage/count.test.ts +177 -0
  371. package/test/storage/find.test.ts +195 -0
  372. package/test/storage/findLegacy.test.ts +67 -0
  373. package/test/storage/idb/allocateChange.test.ts +251 -0
  374. package/test/storage/idb/count.test.ts +158 -0
  375. package/test/storage/idb/find.test.ts +177 -0
  376. package/test/storage/idb/idbSpeed.test.ts +36 -0
  377. package/test/storage/idb/insert.test.ts +268 -0
  378. package/test/storage/idb/transactionAbort.test.ts +108 -0
  379. package/test/storage/idb/update.test.ts +999 -0
  380. package/test/storage/insert.test.ts +278 -0
  381. package/test/storage/update.test.ts +1021 -0
  382. package/test/storage/update2.test.ts +897 -0
  383. package/test/utils/TestUtilsWalletStorage.ts +2526 -0
  384. package/test/utils/localWalletMethods.ts +363 -0
  385. package/test/utils/removeFailedFromDatabase.sql +17 -0
  386. package/ts2md.json +44 -0
  387. package/tsconfig.all.json +31 -0
  388. package/tsconfig.client.json +29 -0
  389. package/tsconfig.json +17 -0
  390. 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,7 @@
1
+ export * from './stampLog'
2
+ export * from './ScriptTemplateBRC29'
3
+ export * from './parseTxScriptOffsets'
4
+ export * from './tscProofToMerklePath'
5
+ export * from './utilityHelpers'
6
+
7
+ export * from './utilityHelpers.buffer'
@@ -0,0 +1,7 @@
1
+ export * from './stampLog'
2
+ export * from './ScriptTemplateBRC29'
3
+ export * from './parseTxScriptOffsets'
4
+ export * from './tscProofToMerklePath'
5
+ export * from './utilityHelpers'
6
+
7
+ export * from './utilityHelpers.noBuffer'
@@ -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
+ }