@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,566 @@
1
+ import WebSocket from 'ws'
2
+ import { convertWocToBlockHeaderHex, WhatsOnChain } from '../../../providers/WhatsOnChain'
3
+ import { wait } from '../../../../utility/utilityHelpers'
4
+ import { Chain } from '../../../../sdk/types'
5
+ import { BlockHeader } from '../../../../sdk/WalletServices.interfaces'
6
+
7
+ export type StopListenerToken = { stop: (() => void) | undefined }
8
+
9
+ async function getWhatsOnChainTipHeight(chain: Chain = 'main', apiKey?: string): Promise<number> {
10
+ const config = apiKey ? { apiKey } : {}
11
+ const woc = new WhatsOnChain(chain, config)
12
+ const chainInfo = await woc.getChainInfo()
13
+ return chainInfo.blocks
14
+ }
15
+
16
+ /**
17
+ * High speed WebSocket based based old block header listener
18
+ * @param fromHeight
19
+ * @param enqueue returns headers received from WebSocket service
20
+ * @param error notifies of abnormal events, return false to close websocket, true to ignore the error.
21
+ * @param stop an object with a stop property which gets set to a method to stop listener
22
+ * @param chain 'test' | 'main'
23
+ * @param idleWait how many milliseconds to timeout between completion checks.
24
+ * @returns true on normal completion, false if should restart if no error received.
25
+ */
26
+ export async function WocHeadersBulkListener(
27
+ fromHeight: number,
28
+ toHeight: number,
29
+ enqueue: (header: BlockHeader) => void,
30
+ error: (code: number, message: string) => boolean,
31
+ stop: StopListenerToken,
32
+ chain: Chain,
33
+ logger: (...args: any[]) => void = () => {},
34
+ idleWait = 5000
35
+ ): Promise<boolean> {
36
+ //logger(`WocHeadersBulkListener from ${fromHeight} to ${toHeight} on ${chain} chain`)
37
+
38
+ let done = false
39
+ let count = 0
40
+ let ping = 0
41
+ let ok = false
42
+ let wsIsOpen = false
43
+
44
+ function stopNow(): void {
45
+ ok = true
46
+ if (wsIsOpen) {
47
+ wsIsOpen = false
48
+ ws.close()
49
+ } else done = true
50
+ }
51
+
52
+ stop.stop = stopNow
53
+
54
+ const webSocketUrl =
55
+ chain === 'test'
56
+ ? `wss://socket-v2-testnet.whatsonchain.com/websocket/blockheaders/history?from=${fromHeight}&to=${toHeight}`
57
+ : `wss://socket-v2.whatsonchain.com/websocket/blockheaders/history?from=${fromHeight}&to=${toHeight}`
58
+
59
+ function processData(rawData) {
60
+ if (rawData.length === 0) {
61
+ ping++
62
+ return
63
+ }
64
+
65
+ const typicalrawDataAsOf20250710BufferThatParsesTo = `{
66
+ "channel": "blockHeaders",
67
+ "pub": {
68
+ "data": {
69
+ "version": 635068416,
70
+ "previousblockhash": "000000000000000005f5778823b824dedf49a503aac60ae153471a3e737d1b1b",
71
+ "merkleroot": "617e2ce2c1348ec1b35ac727cad8bdec33b1b4b983bb00ba2583af4fe1e25ef7",
72
+ "time": 1752133908,
73
+ "bits": 403904562,
74
+ "nonce": 1932754962,
75
+ "hash": "00000000000000000670c88b898aadf911ecf4bc6ba4b71f9b319df47f022b8a",
76
+ "height": 904889
77
+ }
78
+ }
79
+ }`
80
+ // Earlier data formats...
81
+ // "{\"channel\":\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\",\"data\":{\"data\":{\"hash\":\"00000000000000000ce16106e2100b893f3da5989ef23cbac52eb568cf803dc1\",\"confirmations\":8,\"size\":3345869,\"height\":779890,\"version\":939515904,\"versionHex\":\"37ffe000\",\"merkleroot\":\"92e3d1d72d432c9216d296839eaa675b6ffb40ccf6e1a02229caf3d769dc0a5f\",\"txcount\":10757,\"time\":1676851109,\"mediantime\":1676849009,\"nonce\":4216995243,\"bits\":\"180e38cb\",\"difficulty\":77310268438.5808,\"chainwork\":\"00000000000000000000000000000000000000000142d5cf97c0ed497eae1066\",\"previousblockhash\":\"0000000000000000053d26b7b35a76bf2b672428bae591bc033ae99f9873697a\",\"nextblockhash\":\"000000000000000000e1a110376966033507953d50ade86eadef7226843f3349\"}}}"
82
+
83
+ // Returned rawData may be a Buffer...
84
+ const data = JSON.parse(rawData)
85
+ switch (data.type || 0) {
86
+ case 0:
87
+ // last wocHeader has empty string for nextBlockHash
88
+ // eslint-disable-next-line no-case-declarations
89
+ if (!done) {
90
+ const json = JSON.stringify(data)
91
+ if (json === '{}') {
92
+ ws.send('ping')
93
+ } else if (data.connect) {
94
+ logger(json)
95
+ } else if (data.pub) {
96
+ //logger(json)
97
+ const wocHeader = data.pub.data
98
+ if (wocHeader) {
99
+ const header = convertWocToBlockHeaderHex(wocHeader)
100
+ enqueue(header)
101
+ count++
102
+ if (header.height >= toHeight) {
103
+ ok = true
104
+ done = true
105
+ ws.close()
106
+ }
107
+ }
108
+ } else {
109
+ error(42, `unknown data ${json}`)
110
+ }
111
+ }
112
+ break
113
+ case 3:
114
+ break // Unsubscribe "{\"type\":3,\"channel\":\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\",\"data\":{}}"
115
+ case 5:
116
+ break // console.log('subscribed to a channel ' + data.channel)
117
+ case 6:
118
+ break // subscribe "{\"type\":6,\"data\":{\"client\":\"c91c044b-66f5-4172-b509-82c11a41d7fc\",\"subs\":{\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\":{}},\"session\":\"d8693511-5bc8-4815-beb6-8ae1bdaaf3a6\"}}"
119
+ case 7:
120
+ // If you don't close after unsubscribe or end of headers, after a delay, this is received.
121
+ // "{\"type\":7,\"data\":{\"code\":200,\"reason\":\"Data Delivered\"}}"
122
+ error(data.data.code, JSON.stringify(data.data))
123
+ ws.close()
124
+ break
125
+ default:
126
+ error(42, `unknown rawData ${rawData}`)
127
+ ws.close()
128
+ }
129
+ }
130
+
131
+ const ws = new WebSocket(webSocketUrl)
132
+
133
+ ws.onopen = function (this, evt) {
134
+ //logger(`WoC ${new Date().toISOString()} addHeaders from ${fromHeight} on ${chain}`)
135
+ // This is required to trigger connect on server side.
136
+ ws.send(JSON.stringify({}))
137
+ wsIsOpen = true
138
+ }
139
+
140
+ ws.onerror = function (this, evt) {
141
+ // if (evt.message.startsWith('getaddrinfo ENOTFOUND')) {
142
+ let code = -1
143
+ switch (evt.message) {
144
+ case 'Unexpected server response: 403':
145
+ code = 403
146
+ break
147
+ case 'Unexpected server response: 404':
148
+ code = 404
149
+ break
150
+ default:
151
+ break
152
+ }
153
+ const ignoreError = error(code, evt.message)
154
+ if (!ignoreError) ws.close()
155
+ }
156
+
157
+ ws.onclose = function (this, ev) {
158
+ // ok should be true if we got the last header, false otherwise.
159
+ // error will have been called with anything abnormal...
160
+ //logger(`WoC ${new Date().toISOString()} addHeaders input service closed`)
161
+ done = true
162
+ }
163
+
164
+ ws.onmessage = function (this, ev) {
165
+ // console.log("onmessage:", JSON.stringify(ev.data));
166
+ processData(ev.data)
167
+ }
168
+
169
+ // Allow this many wait repetitions for first header, then expect the headers to keep coming
170
+ const firstHeaderCycles = 12
171
+ let waitCycles = 0
172
+
173
+ while (!done) {
174
+ const qlPreWait = count
175
+ await wait(idleWait)
176
+ const qlPostWait = count
177
+
178
+ if (waitCycles > firstHeaderCycles && !done && qlPreWait === 0 && (qlPreWait === qlPostWait || ping > 0)) {
179
+ // Web socket didn't close normally but we aren't getting any new headers
180
+ // Assume a broken connection
181
+ error(-2, 'unexpectedly went idle')
182
+ done = true
183
+ }
184
+
185
+ ping = 0
186
+ waitCycles++
187
+ }
188
+
189
+ //logger(`WoC ${new Date().toISOString()} ${count} headers added`)
190
+
191
+ return ok
192
+ }
193
+ /* v1
194
+ onmessage: "{\"type\":6,\"data\":{\"client\":\"c91c044b-66f5-4172-b509-82c11a41d7fc\",\"subs\":{\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\":{}},\"session\":\"d8693511-5bc8-4815-beb6-8ae1bdaaf3a6\"}}"
195
+ onmessage: "{\"channel\":\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\",\"data\":{\"data\":{\"hash\":\"00000000000000000ce16106e2100b893f3da5989ef23cbac52eb568cf803dc1\",\"confirmations\":8,\"size\":3345869,\"height\":779890,\"version\":939515904,\"versionHex\":\"37ffe000\",\"merkleroot\":\"92e3d1d72d432c9216d296839eaa675b6ffb40ccf6e1a02229caf3d769dc0a5f\",\"txcount\":10757,\"time\":1676851109,\"mediantime\":1676849009,\"nonce\":4216995243,\"bits\":\"180e38cb\",\"difficulty\":77310268438.5808,\"chainwork\":\"00000000000000000000000000000000000000000142d5cf97c0ed497eae1066\",\"previousblockhash\":\"0000000000000000053d26b7b35a76bf2b672428bae591bc033ae99f9873697a\",\"nextblockhash\":\"000000000000000000e1a110376966033507953d50ade86eadef7226843f3349\"}}}"
196
+ onmessage: "{\"channel\":\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\",\"data\":{\"data\":{\"hash\":\"000000000000000000e1a110376966033507953d50ade86eadef7226843f3349\",\"confirmations\":7,\"size\":615786,\"height\":779891,\"version\":809197568,\"versionHex\":\"303b6000\",\"merkleroot\":\"8f5df85a6fafe2d28c679ff1221c3ba331af8f361ba70752e700d2d6382e194e\",\"txcount\":1967,\"time\":1676851242,\"mediantime\":1676849070,\"nonce\":4059160917,\"bits\":\"180e4320\",\"difficulty\":77091494195.17546,\"chainwork\":\"00000000000000000000000000000000000000000142d5e18ad5b99177e0f584\",\"previousblockhash\":\"00000000000000000ce16106e2100b893f3da5989ef23cbac52eb568cf803dc1\",\"nextblockhash\":\"000000000000000002630b7972c23795326392d9c8b4b19aa1ca4753a3fb9ccd\"}}}"
197
+ ...
198
+ onmessage: "{\"channel\":\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\",\"data\":{\"data\":{\"hash\":\"00000000000000000af46a48dec514ff3a4ad9eb6710590ee0385778698241e7\",\"confirmations\":1,\"size\":5119462,\"height\":779897,\"version\":805298176,\"versionHex\":\"2fffe000\",\"merkleroot\":\"3f9b260f6802a3e218366dba3b478dd01703b1b71b12861f838409fbe47fcfba\",\"txcount\":11625,\"time\":1676856449,\"mediantime\":1676852429,\"nonce\":755767059,\"bits\":\"180e6ac7\",\"difficulty\":76263251756.43698,\"chainwork\":\"00000000000000000000000000000000000000000142d64c49fecded8e8be674\",\"previousblockhash\":\"000000000000000000f5b8d6cf1ec6632fd365427600d5acc4c558ce858a8b5a\",\"nextblockhash\":\"\"}}}"
199
+ onmessage: "{\"type\":3,\"channel\":\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\",\"data\":{}}"
200
+ onmessage: "{\"type\":7,\"data\":{\"code\":200,\"reason\":\"Data Delivered\"}}"
201
+ */
202
+
203
+ /** v2
204
+ {
205
+ "message": {
206
+ "data": {
207
+ "version": 872415232,
208
+ "previousblockhash": "00000000000000000ea1f9ba0817a0f922ee227be306fd9097a4e76caf5ff411",
209
+ "merkleroot": "dcd7efb3c39e8e2d597e4757b9a49c98f52f77a6df39d1d5936ac3abb2559944",
210
+ "time": 1750182239,
211
+ "bits": 403926191,
212
+ "nonce": 1043732575,
213
+ "hash": "0000000000000000032d09ca772ca5b3bc5b90a79a5bbcc4a05c99fb6d3b23d8",
214
+ "height": 901658
215
+ }
216
+ }
217
+ }
218
+ */
219
+
220
+ export async function WocHeadersBulkListener_test(): Promise<void> {
221
+ try {
222
+ const chains: Chain[] = ['main', 'test']
223
+ // eslint-disable-next-line prefer-const
224
+ const stop: StopListenerToken = { stop: undefined }
225
+
226
+ for (const chain of chains) {
227
+ const apiKey: string | undefined = undefined
228
+
229
+ const tipHeight = await getWhatsOnChainTipHeight(chain, apiKey)
230
+
231
+ let errors = 0
232
+ while (
233
+ errors === 0 &&
234
+ !(await WocHeadersBulkListener(
235
+ tipHeight - 3,
236
+ tipHeight,
237
+ header => console.log(JSON.stringify(header)),
238
+ (code, message) => {
239
+ errors++
240
+ console.log(`code ${code} message ${message}`)
241
+ return true
242
+ },
243
+ stop,
244
+ chain,
245
+ console.log.bind(console),
246
+ 5000
247
+ ))
248
+ ) {
249
+ console.log('restarting WoC addHeaders')
250
+ }
251
+ }
252
+ } catch (err) {
253
+ console.log(err)
254
+ }
255
+ }
256
+
257
+ /**
258
+ * High speed WebSocket based based new block header listener
259
+ * @param enqueue returns headers received from WebSocket service
260
+ * @param error notifies of abnormal events, return false to close websocket, true to ignore the error.
261
+ * @param stop an object with a stop property which gets set to a method to stop listener
262
+ * @param chain 'test' | 'main'
263
+ * @param idleWait without any input, after this many milliseconds, assume dead service and exit.
264
+ * @returns true only if exit caused by `stop`
265
+ */
266
+ export async function WocHeadersLiveListener(
267
+ enqueue: (header: BlockHeader) => void,
268
+ error: (code: number, message: string) => boolean,
269
+ stop: StopListenerToken,
270
+ chain: Chain,
271
+ logger: (...args: any[]) => void,
272
+ idleWait = 100000
273
+ ): Promise<boolean> {
274
+ let count = 0
275
+ let ok = false
276
+ let done = false
277
+ let wsIsOpen = false
278
+
279
+ let msecsWithoutPing = 0
280
+
281
+ function stopNow(): void {
282
+ ok = true
283
+ if (wsIsOpen) {
284
+ wsIsOpen = false
285
+ ws.close()
286
+ } else done = true
287
+ }
288
+
289
+ stop.stop = stopNow
290
+
291
+ const webSocketUrl =
292
+ chain === 'test'
293
+ ? 'wss://socket-v2-testnet.whatsonchain.com/websocket/blockHeaders'
294
+ : 'wss://socket-v2.whatsonchain.com/websocket/blockHeaders'
295
+
296
+ function processData(rawData) {
297
+ if (rawData.length === 0) {
298
+ // Ping
299
+ return
300
+ }
301
+ // rawData may be a Buffer...
302
+ const data = JSON.parse(rawData)
303
+ const json = JSON.stringify(data)
304
+ switch (data.type || 0) {
305
+ case 0:
306
+ // "{\"channel\":\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\",\"data\":{\"data\":{\"hash\":\"00000000000000000ce16106e2100b893f3da5989ef23cbac52eb568cf803dc1\",\"confirmations\":8,\"size\":3345869,\"height\":779890,\"version\":939515904,\"versionHex\":\"37ffe000\",\"merkleroot\":\"92e3d1d72d432c9216d296839eaa675b6ffb40ccf6e1a02229caf3d769dc0a5f\",\"txcount\":10757,\"time\":1676851109,\"mediantime\":1676849009,\"nonce\":4216995243,\"bits\":\"180e38cb\",\"difficulty\":77310268438.5808,\"chainwork\":\"00000000000000000000000000000000000000000142d5cf97c0ed497eae1066\",\"previousblockhash\":\"0000000000000000053d26b7b35a76bf2b672428bae591bc033ae99f9873697a\",\"nextblockhash\":\"000000000000000000e1a110376966033507953d50ade86eadef7226843f3349\"}}}"
307
+ // last wocHeader has empty string for nextBlockHash
308
+ // eslint-disable-next-line no-case-declarations
309
+ if (!done) {
310
+ if (json === '{}') {
311
+ ws.send('ping')
312
+ } else {
313
+ //logger(JSON.stringify(data))
314
+ const wocHeader = data.pub?.data || data.data?.data
315
+ if (wocHeader) {
316
+ const header = convertWocToBlockHeaderHex(wocHeader)
317
+ enqueue(header)
318
+ count++
319
+ } else {
320
+ error(42, `unknown data ${json}`)
321
+ }
322
+ }
323
+ }
324
+ break
325
+ case 3:
326
+ break // Unsubscribe "{\"type\":3,\"channel\":\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\",\"data\":{}}"
327
+ case 5:
328
+ break // console.log('subscribed to a channel ' + data.channel)
329
+ case 6:
330
+ break // subscribe "{\"type\":6,\"data\":{\"client\":\"c91c044b-66f5-4172-b509-82c11a41d7fc\",\"subs\":{\"woc#c91c044b-66f5-4172-b509-82c11a41d7fc\":{}},\"session\":\"d8693511-5bc8-4815-beb6-8ae1bdaaf3a6\"}}"
331
+ case 7:
332
+ // If you don't close after unsubscribe or end of headers, after a delay, this is received.
333
+ // "{\"type\":7,\"data\":{\"code\":200,\"reason\":\"Data Delivered\"}}"
334
+ error(data.data.code, JSON.stringify(data.data))
335
+ ws.close()
336
+ break
337
+ default:
338
+ error(42, `unknown data ${json}`)
339
+ ws.close()
340
+ }
341
+ }
342
+
343
+ const ws = new WebSocket(webSocketUrl)
344
+
345
+ /*
346
+ function startPing() {
347
+ const pingInterval = setInterval(() => {
348
+ if (ws.readyState === WebSocket.OPEN) {
349
+ ws.send('ping');
350
+ }
351
+ }, 30000); // Ping every 30 seconds
352
+ }
353
+ */
354
+
355
+ ws.onopen = function (this, evt) {
356
+ //logger(`WoC ${new Date().toISOString()} listening for new headers`)
357
+ // This is required to trigger connect on server side.
358
+ ws.send(JSON.stringify({}))
359
+ wsIsOpen = true
360
+ }
361
+
362
+ ws.onerror = function (this, evt) {
363
+ // if (evt.message.startsWith('getaddrinfo ENOTFOUND')) {
364
+ let code = -1
365
+ switch (evt.message) {
366
+ case 'Unexpected server response: 403':
367
+ code = 403
368
+ break
369
+ case 'Unexpected server response: 404':
370
+ code = 404
371
+ break
372
+ default:
373
+ break
374
+ }
375
+ const ignoreError = error(code, evt.message)
376
+ if (!ignoreError) ws.close()
377
+ }
378
+
379
+ ws.onclose = function (this, ev) {
380
+ // ok should be true if we got the last header, false otherwise.
381
+ // error will have been called with anything abnormal...
382
+ //logger(`WoC ${new Date().toISOString()} listening for new headers service closed`)
383
+ done = true
384
+ }
385
+
386
+ ws.onmessage = function (this, ev) {
387
+ // console.log("onmessage:", JSON.stringify(ev.data));
388
+ processData(ev.data)
389
+ msecsWithoutPing = 0
390
+ }
391
+
392
+ //startPing()
393
+
394
+ const waitMsecs = 1000
395
+ let sinceLastSentPing = 0
396
+
397
+ while (!done) {
398
+ await wait(waitMsecs)
399
+
400
+ msecsWithoutPing += waitMsecs
401
+ sinceLastSentPing += waitMsecs
402
+
403
+ if (sinceLastSentPing > 10000) {
404
+ ws.send('ping')
405
+ sinceLastSentPing = 0
406
+ }
407
+ }
408
+
409
+ return ok
410
+ }
411
+
412
+ export async function WocHeadersLiveListener_test(): Promise<void> {
413
+ try {
414
+ const chain = 'main'
415
+ const stop: StopListenerToken = { stop: undefined }
416
+
417
+ let errors = 0
418
+ while (
419
+ errors === 0 &&
420
+ !(await WocHeadersLiveListener(
421
+ header => console.log(JSON.stringify(header)),
422
+ (code, message) => {
423
+ errors++
424
+ console.log(`code ${code} message ${message}`)
425
+ return true
426
+ },
427
+ stop,
428
+ chain,
429
+ console.log.bind(console),
430
+ 100000
431
+ ))
432
+ ) {
433
+ console.log('restarting WoC addHeaders')
434
+ }
435
+ } catch (err) {
436
+ console.log(err)
437
+ }
438
+ }
439
+
440
+ /**
441
+ * v1 json data format:
442
+ *
443
+ {
444
+ "hash": "0000000000000000010cb155a44577ff3541940ec4355c026dc2706fb7e261d6",
445
+ "confirmations": 4,
446
+ "size": 1229956,
447
+ "height": 676421,
448
+ "version": 541065216,
449
+ "versionHex": "20400000",
450
+ "merkleroot": "e2f64e87c0362314b65dc28b4367c41d904c22b891b652951779336ef735386b",
451
+ "txcount": 654,
452
+ "time": 1614534798,
453
+ "mediantime": 1614527058,
454
+ "nonce": 610133701,
455
+ "bits": "180d359d",
456
+ "difficulty": 83235621087.7299,
457
+ "chainwork": "00000000000000000000000000000000000000000127d3854a414d8ec8f53190",
458
+ "previousblockhash": "00000000000000000428ca33597675bd85f5a2ef464ba25e4db7b4a74d898d33",
459
+ "nextblockhash": "00000000000000000cb40c1d850dece5cd3747e08a1e4066ef887251388c4ae6",
460
+ "coinbaseTx": {
461
+ "hex": "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff410345520a2f7461616c2e636f6d2f506c656173652070617920302e3520736174732f627974652c20696e666f407461616c2e636f6d6eead6b0ad91f2ce86be0400ffffffff0176674325000000001976a9148e9170be3f733a9773c907517fb9b786f1c884c688ac00000000",
462
+ "txid": "13686a10870d23b4c94642bf0b78d6630e2640fc0de83bc30af835d96bb17482",
463
+ "hash": "13686a10870d23b4c94642bf0b78d6630e2640fc0de83bc30af835d96bb17482",
464
+ "size": 150,
465
+ "version": 1,
466
+ "locktime": 0,
467
+ "vin": [
468
+ {
469
+ "coinbase": "0345520a2f7461616c2e636f6d2f506c656173652070617920302e3520736174732f627974652c20696e666f407461616c2e636f6d6eead6b0ad91f2ce86be0400",
470
+ "sequence": 4294967295
471
+ }
472
+ ],
473
+ "vout": [
474
+ {
475
+ "value": 6.2517439,
476
+ "n": 0,
477
+ "scriptPubKey": {
478
+ "asm": "OP_DUP OP_HASH160 8e9170be3f733a9773c907517fb9b786f1c884c6 OP_EQUALVERIFY OP_CHECKSIG",
479
+ "hex": "76a9148e9170be3f733a9773c907517fb9b786f1c884c688ac",
480
+ "reqSigs": 1,
481
+ "type": "pubkeyhash",
482
+ "addresses": [
483
+ "1DzqBck9oyCBzxJbbje2s15deZis6BeATi"
484
+ ],
485
+ "isTruncated": false
486
+ }
487
+ }
488
+ ],
489
+ "blockhash": "0000000000000000010cb155a44577ff3541940ec4355c026dc2706fb7e261d6",
490
+ "confirmations": 4,
491
+ "time": 1614534798,
492
+ "blocktime": 1614534798
493
+ }
494
+ }
495
+ */
496
+
497
+ /**
498
+ * v2 json data format:
499
+ {
500
+ "channel": "woc:blockHeader",
501
+ "pub": {
502
+ "data": {
503
+
504
+ "hash": "000000000000000007405fd882e9d4bf3d7b2388010081fe443ee1e323d8a668",
505
+ "confirmations": 1,
506
+ "size": 368170789,
507
+ "height": 892466,
508
+ "version": 939524096,
509
+ "versionHex": "38000000",
510
+ "merkleroot": "b0ac43a40a42775d8f533a8eda00bed3257e12a5fca3c8cade47188e6b7aa382",
511
+ "txcount": 9230,
512
+ "time": 1744648860,
513
+ "mediantime": 1744645401,
514
+ "nonce": 2893086732,
515
+ "bits": "181246e3",
516
+ "difficulty": 60157618395.71893,
517
+ "chainwork": "00000000000000000000000000000000000000000164d487adbc2b84d47d2831",
518
+ "previousblockhash": "0000000000000000090fa4de4c971b0b3609acc1061b2020d22dc8d8bf72746a",
519
+ "nextblockhash": "",
520
+ "coinbaseTx": {
521
+ "hex": "...",
522
+ "txid": "1932aa0229b6b44be4b749b9e7279c02136374e2e77b4e890db761f8e74d2111",
523
+ "hash": "1932aa0229b6b44be4b749b9e7279c02136374e2e77b4e890db761f8e74d2111",
524
+ "size": 111,
525
+ "version": 1,
526
+ "locktime": 0,
527
+ "vin": [
528
+ {
529
+ "n": 0,
530
+ "coinbase": "03329e0d2f7461616c2e636f6d2fb9df41e723a18d95e09d0200",
531
+ "sequence": 4294967295
532
+ }
533
+ ],
534
+ "vout": [
535
+ {
536
+ "value": 3.13276008,
537
+ "n": 0,
538
+ "scriptPubKey": {
539
+ "asm": "OP_DUP OP_HASH160 522cf9e7626d9bd8729e5a1398ece40dad1b6a2f OP_EQUALVERIFY OP_CHECKSIG",
540
+ "hex": "...",
541
+ "reqSigs": 1,
542
+ "type": "pubkeyhash",
543
+ "addresses": [
544
+ "18VWHjMt4ixHddPPbs6righWTs3Sg2QNcn"
545
+ ],
546
+ "isTruncated": false
547
+ },
548
+ "scripthash": "1981f116576960fab6ac9a71ba3c12e4f98c2d9b34532bdb40f2e8cc03337fa2"
549
+ }
550
+ ],
551
+ "blockhash": "000000000000000007405fd882e9d4bf3d7b2388010081fe443ee1e323d8a668",
552
+ "confirmations": 1,
553
+ "time": 1744648860,
554
+ "blocktime": 1744648860,
555
+
556
+ // New properties in v2
557
+ "blockheight": 892466,
558
+ "vincount": 1,
559
+ "voutcount": 1,
560
+ "voutvalue": 3.13276008
561
+ },
562
+ "totalFees": 0.007760080000000169
563
+ }
564
+ }
565
+ }
566
+ */