@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,573 @@
1
+ import { validateAgainstDirtyHashes } from './dirtyHashes'
2
+ import { BigNumber, Hash, Utils } from '@bsv/sdk'
3
+ import { asArray, asString } from '../../../../utility/utilityHelpers.noBuffer'
4
+ import { doubleSha256BE } from '../../../../utility/utilityHelpers'
5
+ import { Chain } from '../../../../sdk/types'
6
+ import { ChaintracksFsApi } from '../Api/ChaintracksFsApi'
7
+ import { ReaderUint8Array } from '../../../../utility/ReaderUint8Array'
8
+ import { BulkHeaderFileInfo } from './BulkHeaderFile'
9
+ import { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'
10
+ import { isKnownValidBulkHeaderFile } from './validBulkHeaderFilesByFileHash'
11
+ import { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../../../sdk/WERR_errors'
12
+ import { BaseBlockHeader, BlockHeader } from '../../../../sdk/WalletServices.interfaces'
13
+
14
+ /**
15
+ * Computes sha256 hash of file contents read as bytes with no encoding.
16
+ * @param filepath Full filepath to file.
17
+ * @param bufferSize Optional read buffer size to use. Defaults to 80,000 bytes. Currently ignored.
18
+ * @returns `{hash, length}` where `hash` is base64 string form of file hash and `length` is file length in bytes.
19
+ */
20
+ export async function sha256HashOfBinaryFile(
21
+ fs: ChaintracksFsApi,
22
+ filepath: string,
23
+ bufferSize = 80000
24
+ ): Promise<{ hash: string; length: number }> {
25
+ const sha256 = new Hash.SHA256()
26
+ const bytes = await fs.readFile(filepath)
27
+ const length = bytes.length
28
+ sha256.update(asArray(bytes))
29
+ return { hash: Utils.toBase64(sha256.digest()), length }
30
+ }
31
+
32
+ /**
33
+ * Validates the contents of a bulk header file.
34
+ * @param bf BulkHeaderFileInfo containing `data` to validate.
35
+ * @param prevHash Required previous header hash.
36
+ * @param prevChainWork Required previous chain work.
37
+ * @param fetch Optional ChaintracksFetchApi instance for fetching data.
38
+ * @returns Validated BulkHeaderFileInfo with `validated` set to true.
39
+ */
40
+ export async function validateBulkFileData(
41
+ bf: BulkHeaderFileInfo,
42
+ prevHash: string,
43
+ prevChainWork: string,
44
+ fetch?: ChaintracksFetchApi
45
+ ): Promise<BulkHeaderFileInfo> {
46
+ const vbf = { ...bf }
47
+
48
+ if (!vbf.data && vbf.sourceUrl && fetch) {
49
+ const url = fetch.pathJoin(vbf.sourceUrl, vbf.fileName)
50
+ vbf.data = await fetch.download(url)
51
+ }
52
+
53
+ if (!vbf.data) throw new WERR_INVALID_OPERATION(`bulk file ${vbf.fileName} data is unavailable`)
54
+
55
+ if (vbf.count <= 0)
56
+ throw new WERR_INVALID_PARAMETER('bf.count', `expected count to be greater than 0, but got ${vbf.count}`)
57
+
58
+ if (vbf.data.length !== vbf.count * 80)
59
+ throw new WERR_INVALID_PARAMETER(
60
+ 'bf.data',
61
+ `bulk file ${vbf.fileName} data length ${vbf.data.length} does not match expected count ${vbf.count}`
62
+ )
63
+
64
+ vbf.fileHash = asString(Hash.sha256(asArray(vbf.data)), 'base64')
65
+ if (bf.fileHash && bf.fileHash !== vbf.fileHash)
66
+ throw new WERR_INVALID_PARAMETER('bf.fileHash', `expected ${bf.fileHash} but got ${vbf.fileHash}`)
67
+
68
+ if (!isKnownValidBulkHeaderFile(vbf)) {
69
+ const { lastHeaderHash, lastChainWork } = validateBufferOfHeaders(vbf.data, prevHash, 0, undefined, prevChainWork)
70
+ vbf.lastHash = lastHeaderHash
71
+ vbf.lastChainWork = lastChainWork!
72
+ if (vbf.firstHeight === 0) {
73
+ validateGenesisHeader(vbf.data, vbf.chain!)
74
+ }
75
+ }
76
+ vbf.validated = true
77
+
78
+ return vbf
79
+ }
80
+
81
+ /**
82
+ * Validate headers contained in an array of bytes. The headers must be consecutive block headers, 80 bytes long,
83
+ * where the hash of each header equals the previousHash of the following header.
84
+ * @param buffer Buffer of headers to be validated.
85
+ * @param previousHash Expected previousHash of first header.
86
+ * @param offset Optional starting offset within `buffer`.
87
+ * @param count Optional number of headers to validate. Validates to end of buffer if missing.
88
+ * @returns Header hash of last header validated or previousHash if there where none.
89
+ */
90
+ export function validateBufferOfHeaders(
91
+ buffer: Uint8Array,
92
+ previousHash: string,
93
+ offset = 0,
94
+ count = -1,
95
+ previousChainWork?: string
96
+ ): { lastHeaderHash: string; lastChainWork: string | undefined } {
97
+ if (count < 0) count = Math.floor((buffer.length - offset) / 80)
98
+ count = Math.max(0, count)
99
+ let lastHeaderHash = previousHash
100
+ let lastChainWork = previousChainWork
101
+ for (let i = 0; i < count; i++) {
102
+ const headerStart = offset + i * 80
103
+ const headerEnd = headerStart + 80
104
+ if (headerEnd > buffer.length) {
105
+ throw new WERR_INVALID_PARAMETER(
106
+ 'buffer',
107
+ `multiple of 80 bytes long. header ${i} missing bytes for header at offset ${headerStart} in buffer of length ${buffer.length}`
108
+ )
109
+ }
110
+ const header = buffer.slice(headerStart, headerEnd)
111
+ const h = deserializeBaseBlockHeader(header)
112
+ const hashPrev = asString(header.slice(4, 36).reverse())
113
+ if (lastHeaderHash !== hashPrev)
114
+ throw { message: `header ${i} invalid previousHash ${lastHeaderHash} vs ${hashPrev}` }
115
+ lastHeaderHash = asString(doubleSha256BE(header))
116
+ validateAgainstDirtyHashes(lastHeaderHash)
117
+ if (lastChainWork) {
118
+ lastChainWork = addWork(lastChainWork, convertBitsToWork(h.bits))
119
+ }
120
+ }
121
+ return { lastHeaderHash, lastChainWork }
122
+ }
123
+
124
+ /**
125
+ * Verifies that buffer begins with valid genesis block header for the specified chain.
126
+ * @param buffer
127
+ * @param chain
128
+ */
129
+ export function validateGenesisHeader(buffer: Uint8Array, chain: Chain): void {
130
+ const header = buffer.slice(0, 80)
131
+ const h = deserializeBlockHeader(header, 0, 0)
132
+ const gh = genesisHeader(chain)
133
+ if (
134
+ h.bits !== gh.bits ||
135
+ h.previousHash !== gh.previousHash ||
136
+ h.merkleRoot !== gh.merkleRoot ||
137
+ h.time !== gh.time ||
138
+ h.nonce !== gh.nonce ||
139
+ h.version !== gh.version ||
140
+ h.height !== gh.height ||
141
+ h.hash !== gh.hash
142
+ ) {
143
+ throw new WERR_INVALID_PARAMETER('buffer', `genesis header for chain ${chain}`)
144
+ }
145
+ }
146
+
147
+ /**
148
+ * @param work chainWork as a BigNumber
149
+ * @returns Converted chainWork value from BN to hex string of 32 bytes.
150
+ */
151
+ export function workBNtoBuffer(work: BigNumber): string {
152
+ return work.toString(16).padStart(64, '0')
153
+ }
154
+
155
+ /**
156
+ * Returns true if work1 is more work (greater than) work2
157
+ */
158
+ export function isMoreWork(work1: string, work2: string): boolean {
159
+ return new BigNumber(asArray(work1), 16).gt(new BigNumber(asArray(work2), 16))
160
+ }
161
+
162
+ /**
163
+ * Add two Buffer encoded chainwork values
164
+ * @returns Sum of work1 + work2 as Buffer encoded chainWork value
165
+ */
166
+ export function addWork(work1: string, work2: string): string {
167
+ const sum = new BigNumber(work1, 16).add(new BigNumber(work2, 16))
168
+ return workBNtoBuffer(sum)
169
+ }
170
+
171
+ /**
172
+ * Subtract Buffer encoded chainwork values
173
+ * @returns work1 - work2 as Buffer encoded chainWork value
174
+ */
175
+ export function subWork(work1: string, work2: string): string {
176
+ const sum = new BigNumber(work1, 16).sub(new BigNumber(work2, 16))
177
+ return workBNtoBuffer(sum)
178
+ }
179
+
180
+ /**
181
+ * Computes "target" value for 4 byte Bitcoin block header "bits" value.
182
+ * @param bits number or converted from Buffer using `readUint32LE`
183
+ * @returns 32 byte Buffer with "target" value
184
+ */
185
+ export function convertBitsToTarget(bits: number | number[]): BigNumber {
186
+ if (Array.isArray(bits)) bits = readUInt32LE(bits, 0)
187
+
188
+ const shift = (bits >> 24) & 0xff
189
+ const data = bits & 0x007fffff
190
+
191
+ const target = new BigNumber(data)
192
+ if (shift <= 3) {
193
+ target.iushrn(8 * (3 - shift))
194
+ } else {
195
+ target.iushln(8 * (shift - 3))
196
+ }
197
+
198
+ return target
199
+ }
200
+
201
+ /**
202
+ * Computes "chainWork" value for 4 byte Bitcoin block header "bits" value.
203
+ * @param bits number or converted from Buffer using `readUint32LE`
204
+ * @returns 32 byte Buffer with "chainWork" value
205
+ */
206
+ export function convertBitsToWork(bits: number | number[]): string {
207
+ const target = convertBitsToTarget(bits)
208
+
209
+ // convert target to work
210
+ const work = target.notn(256).div(target.addn(1)).addn(1)
211
+
212
+ return work.toString(16).padStart(64, '0')
213
+ }
214
+
215
+ export function deserializeBaseBlockHeaders(
216
+ buffer: number[] | Uint8Array,
217
+ offset = 0,
218
+ count?: number | undefined
219
+ ): BaseBlockHeader[] {
220
+ const headers: BaseBlockHeader[] = []
221
+ while ((!count || headers.length < count) && offset + 80 <= buffer.length && offset >= 0) {
222
+ headers.push(deserializeBaseBlockHeader(buffer, offset))
223
+ offset += 80
224
+ }
225
+ return headers
226
+ }
227
+
228
+ export function deserializeBlockHeaders(
229
+ firstHeight: number,
230
+ buffer: number[] | Uint8Array,
231
+ offset = 0,
232
+ count?: number | undefined
233
+ ): BlockHeader[] {
234
+ const headers: BlockHeader[] = []
235
+ let nextHeight = firstHeight
236
+ while ((!count || headers.length < count) && offset + 80 <= buffer.length && offset >= 0) {
237
+ const baseBuffer = buffer.slice(offset, offset + 80)
238
+ const base = deserializeBaseBlockHeader(baseBuffer)
239
+ const header = {
240
+ ...base,
241
+ height: nextHeight++,
242
+ hash: asString(blockHash(baseBuffer))
243
+ }
244
+ headers.push(header)
245
+ offset += 80
246
+ }
247
+ return headers
248
+ }
249
+
250
+ /**
251
+ * Given a block header, ensures that its format is correct. This does not
252
+ * check its difficulty or validity relative to the chain of headers.
253
+ *
254
+ * Throws on format errors.
255
+ *
256
+ * @param The header to validate
257
+ *
258
+ * @returns true if the header is correctly formatted
259
+ */
260
+ export function validateHeaderFormat(header: BlockHeader): void {
261
+ const ALLOWED_KEYS = {
262
+ version: true,
263
+ previousHash: true,
264
+ merkleRoot: true,
265
+ time: true,
266
+ bits: true,
267
+ nonce: true,
268
+ height: true,
269
+ hash: true
270
+ }
271
+
272
+ const UINT_MAX = 0xffffffff
273
+
274
+ /**
275
+ * Root object checks
276
+ */
277
+ if (typeof header === 'undefined') {
278
+ throw new Error('Missing header.')
279
+ }
280
+ if (typeof header !== 'object') {
281
+ throw new Error('Header must be an object.')
282
+ }
283
+ if (!Object.keys(header).every(key => ALLOWED_KEYS[key])) {
284
+ throw new Error('Header contains extra properties.')
285
+ }
286
+
287
+ /**
288
+ * Version
289
+ */
290
+ if (typeof header.version !== 'number') {
291
+ throw new Error('Header version must be a number.')
292
+ }
293
+ if (!Number.isInteger(header.version)) {
294
+ throw new Error('Header version must be an integer.')
295
+ }
296
+ if (header.version < 0 || header.version > UINT_MAX) {
297
+ throw new Error(`Header version must be between 0 and ${UINT_MAX}.`)
298
+ }
299
+
300
+ /**
301
+ * Height
302
+ */
303
+ if (typeof header.height !== 'number') {
304
+ throw new Error('Header height must be a number.')
305
+ }
306
+ if (!Number.isInteger(header.height)) {
307
+ throw new Error('Header height must be an integer.')
308
+ }
309
+ if (header.height < 0 || header.height > UINT_MAX / 2) {
310
+ throw new Error(`Header version must be between 0 and ${UINT_MAX / 2}.`)
311
+ }
312
+
313
+ /**
314
+ * Previous hash
315
+ */
316
+ if (header.previousHash.length !== 64) {
317
+ throw new Error('Header previousHash must be 32 hex bytes.')
318
+ }
319
+
320
+ /**
321
+ * Merkle root
322
+ */
323
+ if (header.merkleRoot.length !== 64) {
324
+ throw new Error('Header merkleRoot must be 32 hex bytes.')
325
+ }
326
+
327
+ /**
328
+ * Time
329
+ */
330
+ if (typeof header.time !== 'number') {
331
+ throw new Error('Header time must be a number.')
332
+ }
333
+ if (!Number.isInteger(header.time)) {
334
+ throw new Error('Header time must be an integer.')
335
+ }
336
+ if (header.time < 0 || header.time > UINT_MAX) {
337
+ throw new Error(`Header time must be between 0 and ${UINT_MAX}.`)
338
+ }
339
+
340
+ /**
341
+ * Bits
342
+ */
343
+ if (typeof header.bits !== 'number') {
344
+ throw new Error('Header bits must be a number.')
345
+ }
346
+ if (!Number.isInteger(header.bits)) {
347
+ throw new Error('Header bits must be an integer.')
348
+ }
349
+ if (header.bits < 0 || header.bits > UINT_MAX) {
350
+ throw new Error(`Header bits must be between 0 and ${UINT_MAX}.`)
351
+ }
352
+
353
+ /**
354
+ * Nonce
355
+ */
356
+ if (typeof header.nonce !== 'number') {
357
+ throw new Error('Header nonce must be a number.')
358
+ }
359
+ if (!Number.isInteger(header.nonce)) {
360
+ throw new Error('Header nonce must be an integer.')
361
+ }
362
+ if (header.nonce < 0 || header.nonce > UINT_MAX) {
363
+ throw new Error(`Header nonce must be between 0 and ${UINT_MAX}.`)
364
+ }
365
+
366
+ /**
367
+ * Hash
368
+ */
369
+ if (header.hash.length !== 64) {
370
+ throw new Error('Header hash must be 32 hex bytes.')
371
+ }
372
+ if (header.hash !== asString(blockHash(header))) {
373
+ throw new Error('Header hash is invalid.')
374
+ }
375
+ }
376
+
377
+ /**
378
+ * Ensures that a header has a valid proof-of-work
379
+ * Requires chain is 'main'
380
+ *
381
+ * @param header The header to validate
382
+ *
383
+ * @returns true if the header is valid
384
+ */
385
+ export function validateHeaderDifficulty(hash: Buffer, bits: number) {
386
+ const hashBN = new BigNumber(asArray(hash))
387
+
388
+ const target = convertBitsToTarget(bits)
389
+
390
+ if (hashBN.lte(target)) return true
391
+
392
+ throw new Error('Block hash is not less than specified target.')
393
+ }
394
+
395
+ /**
396
+ * Computes double sha256 hash of bitcoin block header
397
+ * bytes are reversed to bigendian order
398
+ *
399
+ * If header is a Buffer, it is required to 80 bytes long
400
+ * and in standard block header serialized encoding.
401
+ *
402
+ * @returns doule sha256 hash of header bytes reversed
403
+ * @publicbody
404
+ */
405
+ export function blockHash(header: BaseBlockHeader | number[] | Uint8Array): string {
406
+ const a = !Array.isArray(header) && !(header instanceof Uint8Array) ? serializeBaseBlockHeader(header) : header
407
+ if (a.length !== 80) throw new Error('Block header must be 80 bytes long.')
408
+ return asString(doubleSha256BE(a))
409
+ }
410
+
411
+ /**
412
+ * Serializes a block header as an 80 byte Buffer.
413
+ * The exact serialized format is defined in the Bitcoin White Paper
414
+ * such that computing a double sha256 hash of the buffer computes
415
+ * the block hash for the header.
416
+ * @returns 80 byte Buffer
417
+ * @publicbody
418
+ */
419
+ export function serializeBaseBlockHeader(header: BaseBlockHeader, buffer?: number[], offset?: number): number[] {
420
+ const writer = new Utils.Writer()
421
+ writer.writeUInt32LE(header.version)
422
+ writer.write(asArray(header.previousHash).reverse())
423
+ writer.write(asArray(header.merkleRoot).reverse())
424
+ writer.writeUInt32LE(header.time)
425
+ writer.writeUInt32LE(header.bits)
426
+ writer.writeUInt32LE(header.nonce)
427
+ const data = writer.toArray()
428
+ if (buffer) {
429
+ offset ||= 0
430
+ for (let i = 0; i < data.length; i++) {
431
+ if (offset + i >= buffer.length) {
432
+ throw new Error(`Buffer overflow at offset ${offset + i} for data length ${data.length}`)
433
+ }
434
+ buffer[offset + i] = data[i]
435
+ }
436
+ }
437
+ return data
438
+ }
439
+
440
+ export function serializeBaseBlockHeaders(headers: BlockHeader[]): Uint8Array {
441
+ const data = new Uint8Array(headers.length * 80)
442
+ let i = -1
443
+ for (const header of headers) {
444
+ i++
445
+ const d = serializeBaseBlockHeader(header)
446
+ data.set(d, i * 80)
447
+ }
448
+ return data
449
+ }
450
+
451
+ /**
452
+ * Deserialize a BaseBlockHeader from an 80 byte buffer
453
+ * @publicbody
454
+ */
455
+ export function deserializeBaseBlockHeader(buffer: number[] | Uint8Array, offset = 0): BaseBlockHeader {
456
+ const reader = ReaderUint8Array.makeReader(buffer, offset)
457
+ const header: BaseBlockHeader = {
458
+ version: reader.readUInt32LE(),
459
+ previousHash: asString(reader.read(32).reverse()),
460
+ merkleRoot: asString(reader.read(32).reverse()),
461
+ time: reader.readUInt32LE(),
462
+ bits: reader.readUInt32LE(),
463
+ nonce: reader.readUInt32LE()
464
+ }
465
+ return header
466
+ }
467
+
468
+ export function deserializeBlockHeader(buffer: number[] | Uint8Array, offset = 0, height: number): BlockHeader {
469
+ const base = deserializeBaseBlockHeader(buffer, offset)
470
+ const header: BlockHeader = {
471
+ ...base,
472
+ height,
473
+ hash: asString(doubleSha256BE(buffer.slice(offset, offset + 80)))
474
+ }
475
+ return header
476
+ }
477
+
478
+ /**
479
+ * Returns the genesis block for the specified chain.
480
+ * @publicbody
481
+ */
482
+ export function genesisHeader(chain: Chain): BlockHeader {
483
+ return chain === 'main'
484
+ ? {
485
+ version: 1,
486
+ previousHash: '0000000000000000000000000000000000000000000000000000000000000000',
487
+ merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
488
+ time: 1231006505,
489
+ bits: 486604799,
490
+ nonce: 2083236893,
491
+ height: 0,
492
+ hash: '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'
493
+ }
494
+ : {
495
+ version: 1,
496
+ previousHash: '0000000000000000000000000000000000000000000000000000000000000000',
497
+ merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
498
+ time: 1296688602,
499
+ bits: 486604799,
500
+ nonce: 414098458,
501
+ height: 0,
502
+ hash: '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943'
503
+ }
504
+ }
505
+
506
+ /**
507
+ * Returns the genesis block for the specified chain.
508
+ * @publicbody
509
+ */
510
+ export function genesisBuffer(chain: Chain): number[] {
511
+ return serializeBaseBlockHeader(genesisHeader(chain))
512
+ }
513
+
514
+ /**
515
+ * Returns a copy of a Buffer with byte order reversed.
516
+ * @returns new buffer with byte order reversed.
517
+ * @publicbody
518
+ */
519
+ export function swapByteOrder(buffer: number[]): number[] {
520
+ return buffer.slice().reverse()
521
+ }
522
+
523
+ /**
524
+ * @param num a number value in the Uint32 value range
525
+ * @param littleEndian true for little-endian byte order in Buffer
526
+ * @returns four byte buffer with Uint32 number encoded
527
+ * @publicbody
528
+ */
529
+ export function convertUint32ToBuffer(n: number, littleEndian = true): number[] {
530
+ const a = [
531
+ n & 0xff, // lowest byte
532
+ (n >> 8) & 0xff,
533
+ (n >> 16) & 0xff,
534
+ (n >> 24) & 0xff // highest byte
535
+ ]
536
+ return littleEndian ? a : a.reverse()
537
+ }
538
+
539
+ export function writeUInt32LE(n: number, a: number[] | Uint8Array, offset: number): number {
540
+ a[offset++] = n & 0xff // lowest byte
541
+ a[offset++] = (n >> 8) & 0xff
542
+ a[offset++] = (n >> 16) & 0xff
543
+ a[offset++] = (n >> 24) & 0xff // highest byte
544
+ return offset
545
+ }
546
+
547
+ export function writeUInt32BE(n: number, a: number[] | Uint8Array, offset: number): number {
548
+ a[offset++] = (n >> 24) & 0xff // highest byte
549
+ a[offset++] = (n >> 16) & 0xff
550
+ a[offset++] = (n >> 8) & 0xff
551
+ a[offset++] = n & 0xff // lowest byte
552
+ return offset
553
+ }
554
+
555
+ export function readUInt32LE(a: number[] | Uint8Array, offset: number): number {
556
+ return a[offset++] | (a[offset++] << 8) | (a[offset++] << 16) | (a[offset++] << 24)
557
+ }
558
+
559
+ export function readUInt32BE(a: number[] | Uint8Array, offset: number): number {
560
+ return (a[offset++] << 24) | (a[offset++] << 16) | (a[offset++] << 8) | a[offset++]
561
+ }
562
+
563
+ /**
564
+ * @param buffer four byte buffer with Uint32 number encoded
565
+ * @param littleEndian true for little-endian byte order in Buffer
566
+ * @returns a number value in the Uint32 value range
567
+ * @publicbody
568
+ */
569
+ export function convertBufferToUint32(buffer: number[] | Uint8Array, littleEndian = true): number {
570
+ const a = littleEndian ? buffer : buffer.slice().reverse()
571
+ const n = a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24)
572
+ return n
573
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * These hashes are for blocks that are to known to have violated the Bitcoin
3
+ * protocol. Regardless of the amount of proof-of-work that chains built on top
4
+ * of them may have accumulated, they cannot be considered valid Bitcoin blocks.
5
+ *
6
+ * In the first instance, segregating witness data from transactions is not
7
+ * part of the design of Bitcoin.
8
+ *
9
+ * In the second instance, adding new opcodes to be used when evaluating
10
+ * scripts is also not allowed.
11
+ */
12
+ export const dirtyHashes = {
13
+ // Block 478,558 with hash of 0000000000000000011865af4122fe3b144e2cbeea86142e8ff2fb4107352d43 was the last block shared by BSV, BCH and BTC
14
+ // Block 478,559 with hash of 00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148 was the first block of the BTC Segwit chain.
15
+ // Block 478,559 with hash of 000000000000000000651ef99cb9fcbe0dadde1d424bd9f15ff20136191a5eec was the valid Bitcoin block shared by BSV and BCH.
16
+ '00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148':
17
+ 'This is the first header of the invalid SegWit chain.',
18
+ '0000000000000000004626ff6e3b936941d341c5932ece4357eeccac44e6d56c':
19
+ 'This is the first header of the invalid ABC chain.'
20
+ }
21
+
22
+ /**
23
+ * Throws Error if blockHash is in the dirtyHashes list.
24
+ */
25
+ export function validateAgainstDirtyHashes(blockHash: string): void {
26
+ if (dirtyHashes[blockHash]) {
27
+ throw new Error(`Not adding a header with a dirty hash: ${dirtyHashes[blockHash]}`)
28
+ }
29
+ }