@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,604 @@
1
+ import { Knex } from 'knex'
2
+ import * as bsv from '@bsv/sdk'
3
+ import { createSyncMap, sdk, SyncMap, TableTransaction } from '../../../../../src'
4
+ import { TestUtilsWalletStorage as _tu, TestWalletNoSetup } from '../../../../../test/utils/TestUtilsWalletStorage'
5
+ import { EntityTransaction } from '../EntityTransaction'
6
+
7
+ describe('Transaction class method tests', () => {
8
+ jest.setTimeout(99999999)
9
+
10
+ const env = _tu.getEnv('test')
11
+ const ctxs: TestWalletNoSetup[] = []
12
+ const ctxs2: TestWalletNoSetup[] = []
13
+
14
+ beforeAll(async () => {
15
+ if (env.runMySQL) {
16
+ ctxs.push(await _tu.createLegacyWalletMySQLCopy('transactionTests'))
17
+ ctxs2.push(await _tu.createLegacyWalletMySQLCopy('transactionTests2'))
18
+ }
19
+ ctxs.push(await _tu.createLegacyWalletSQLiteCopy('transactionTests'))
20
+ ctxs2.push(await _tu.createLegacyWalletSQLiteCopy('transactionTests2'))
21
+ })
22
+
23
+ afterAll(async () => {
24
+ // Destroy both sets of database contexts
25
+ for (const ctx of ctxs) {
26
+ await ctx.storage.destroy()
27
+ }
28
+ for (const ctx of ctxs2) {
29
+ await ctx.storage.destroy()
30
+ }
31
+ })
32
+
33
+ // Test: Constructor with default values
34
+ test('0_creates_instance_with_default_values', () => {
35
+ const tx = new EntityTransaction()
36
+
37
+ const now = new Date()
38
+ expect(tx.transactionId).toBe(0)
39
+ expect(tx.userId).toBe(0)
40
+ expect(tx.txid).toBe('')
41
+ expect(tx.status).toBe('unprocessed')
42
+ expect(tx.reference).toBe('')
43
+ expect(tx.satoshis).toBe(0)
44
+ expect(tx.description).toBe('')
45
+ expect(tx.isOutgoing).toBe(false)
46
+ expect(tx.rawTx).toBeUndefined()
47
+ expect(tx.inputBEEF).toBeUndefined()
48
+ expect(tx.created_at).toBeInstanceOf(Date)
49
+ expect(tx.updated_at).toBeInstanceOf(Date)
50
+ expect(tx.created_at.getTime()).toBeLessThanOrEqual(now.getTime())
51
+ expect(tx.updated_at.getTime()).toBeLessThanOrEqual(now.getTime())
52
+ })
53
+
54
+ // Test: Constructor with provided API object
55
+ test('1_creates_instance_with_provided_api_object', () => {
56
+ const now = new Date()
57
+ const apiObject: TableTransaction = {
58
+ transactionId: 123,
59
+ userId: 456,
60
+ txid: 'testTxid',
61
+ status: 'completed',
62
+ reference: 'testReference',
63
+ satoshis: 789,
64
+ description: 'testDescription',
65
+ isOutgoing: true,
66
+ rawTx: [1, 2, 3],
67
+ inputBEEF: [4, 5, 6],
68
+ created_at: now,
69
+ updated_at: now
70
+ }
71
+
72
+ const tx = new EntityTransaction(apiObject)
73
+
74
+ expect(tx.transactionId).toBe(123)
75
+ expect(tx.userId).toBe(456)
76
+ expect(tx.txid).toBe('testTxid')
77
+ expect(tx.status).toBe('completed')
78
+ expect(tx.reference).toBe('testReference')
79
+ expect(tx.satoshis).toBe(789)
80
+ expect(tx.description).toBe('testDescription')
81
+ expect(tx.isOutgoing).toBe(true)
82
+ expect(tx.rawTx).toEqual([1, 2, 3])
83
+ expect(tx.inputBEEF).toEqual([4, 5, 6])
84
+ expect(tx.created_at).toBe(now)
85
+ expect(tx.updated_at).toBe(now)
86
+ })
87
+
88
+ // Test: Getters and setters
89
+ test('2_getters_and_setters_work_correctly', () => {
90
+ const tx = new EntityTransaction()
91
+
92
+ const now = new Date()
93
+ tx.transactionId = 123
94
+ tx.userId = 456
95
+ tx.txid = 'testTxid'
96
+ tx.status = 'processed' as sdk.TransactionStatus
97
+ tx.reference = 'testReference'
98
+ tx.satoshis = 789
99
+ tx.description = 'testDescription'
100
+ tx.isOutgoing = true
101
+ tx.rawTx = [1, 2, 3]
102
+ tx.inputBEEF = [4, 5, 6]
103
+ tx.created_at = now
104
+ tx.updated_at = now
105
+
106
+ // New setters
107
+ tx.version = 2
108
+ tx.lockTime = 5000
109
+
110
+ expect(tx.transactionId).toBe(123)
111
+ expect(tx.userId).toBe(456)
112
+ expect(tx.txid).toBe('testTxid')
113
+ expect(tx.status).toBe('processed')
114
+ expect(tx.reference).toBe('testReference')
115
+ expect(tx.satoshis).toBe(789)
116
+ expect(tx.description).toBe('testDescription')
117
+ expect(tx.isOutgoing).toBe(true)
118
+ expect(tx.rawTx).toEqual([1, 2, 3])
119
+ expect(tx.inputBEEF).toEqual([4, 5, 6])
120
+ expect(tx.created_at).toBe(now)
121
+ expect(tx.updated_at).toBe(now)
122
+
123
+ // Check new properties
124
+ expect(tx.version).toBe(2) // Ensure version is set correctly
125
+ expect(tx.lockTime).toBe(5000) // Ensure lockTime is set correctly
126
+ })
127
+
128
+ // Test: `getBsvTx` returns parsed transaction
129
+ test('3_getBsvTx_returns_parsed_transaction', () => {
130
+ const rawTx = Uint8Array.from([1, 2, 3])
131
+ const tx = new EntityTransaction({
132
+ rawTx: Array.from(rawTx)
133
+ } as TableTransaction)
134
+
135
+ const bsvTx = tx.getBsvTx()
136
+ expect(bsvTx).toBeInstanceOf(bsv.Transaction)
137
+ })
138
+
139
+ // Test: `getBsvTx` returns undefined if rawTx is not set
140
+ test('4_getBsvTx_returns_undefined_if_no_rawTx', () => {
141
+ const tx = new EntityTransaction()
142
+ const bsvTx = tx.getBsvTx()
143
+ expect(bsvTx).toBeUndefined()
144
+ })
145
+
146
+ // Test: `getBsvTxIns` returns parsed inputs
147
+ test('5_getBsvTxIns_returns_inputs', () => {
148
+ const rawTx = Uint8Array.from([1, 2, 3])
149
+ const tx = new EntityTransaction({
150
+ rawTx: Array.from(rawTx)
151
+ } as TableTransaction)
152
+
153
+ const inputs = tx.getBsvTxIns()
154
+ expect(inputs).toBeInstanceOf(Array)
155
+ })
156
+
157
+ // Test: getInputs combines spentBy and rawTx inputs
158
+ test('6_getInputs_combines_spentBy_and_rawTx_inputs', async () => {
159
+ for (const { activeStorage } of ctxs) {
160
+ // Insert the transaction into the database
161
+ const txData = await _tu.insertTestTransaction(activeStorage, undefined, true)
162
+ const tx = new EntityTransaction(txData.tx)
163
+
164
+ // Assign rawTx to simulate transaction inputs
165
+ const rawTx = Uint8Array.from([1, 2, 3])
166
+ tx.rawTx = Array.from(rawTx)
167
+
168
+ // Insert test outputs with spentBy linked to the transaction
169
+ const output1 = await _tu.insertTestOutput(activeStorage, tx, 0, 100)
170
+ await activeStorage.updateOutput(output1.outputId, {
171
+ spentBy: tx.transactionId
172
+ })
173
+
174
+ const output2 = await _tu.insertTestOutput(activeStorage, tx, 1, 200)
175
+ await activeStorage.updateOutput(output2.outputId, {
176
+ spentBy: tx.transactionId
177
+ })
178
+
179
+ // Debugging: Log inserted outputs
180
+ const outputs = await activeStorage.findOutputs({
181
+ partial: { spentBy: tx.transactionId }
182
+ })
183
+ //console.log('Inserted Outputs:', outputs)
184
+
185
+ // Get inputs from the transaction
186
+ const inputs = await tx.getInputs(activeStorage)
187
+ //console.log('Transaction Inputs:', inputs)
188
+
189
+ // Validate the inputs
190
+ expect(inputs).toHaveLength(2)
191
+ expect(inputs).toEqual(
192
+ expect.arrayContaining([
193
+ expect.objectContaining({ vout: 0, satoshis: 100 }),
194
+ expect.objectContaining({ vout: 1, satoshis: 200 })
195
+ ])
196
+ )
197
+ }
198
+ })
199
+
200
+ // Test: 'mergeExisting' updates when ei updated at is newer
201
+ /*****************************************************************************************************/
202
+ // Actually currently fails because mergeExisting is currently setting the date to the current date
203
+ // rather than the udpated_at from the incoming entity
204
+ /*****************************************************************************************************/
205
+ test('9_mergeExisting_updates_when_ei_updated_at_is_newer', async () => {
206
+ for (const { activeStorage } of ctxs) {
207
+ // Insert a test transaction into the database
208
+ const txData = await _tu.insertTestTransaction(activeStorage, undefined, true)
209
+
210
+ // Create the `Transaction` instance with an earlier updated_at timestamp
211
+ const tx = new EntityTransaction({
212
+ ...txData.tx,
213
+ updated_at: new Date(2022, 1, 1)
214
+ })
215
+
216
+ // Create an incoming entity object (`ei`) with a newer updated_at timestamp
217
+ const ei: TableTransaction = {
218
+ ...txData.tx,
219
+ updated_at: new Date(2023, 1, 1),
220
+ txid: 'newTxId'
221
+ }
222
+
223
+ const syncMap = createSyncMap()
224
+ syncMap.transaction.idMap = { 456: 123 }
225
+ syncMap.transaction.count = 1
226
+
227
+ const expectedMergeUpdatedAt = Math.max(ei.updated_at.getTime(), tx.updated_at.getTime())
228
+
229
+ // Execute `mergeExisting`
230
+ const result = await tx.mergeExisting(activeStorage, new Date(), ei, syncMap)
231
+
232
+ // Validate the result and check that the transaction was updated in the database
233
+ expect(result).toBe(true)
234
+
235
+ const updatedTx = await activeStorage.findTransactions({
236
+ partial: { transactionId: tx.transactionId }
237
+ })
238
+
239
+ expect(updatedTx[0]?.txid).toBe('newTxId')
240
+ // Currently expecting current time and date, but should be the updated_at from the incoming entity
241
+ const updatedAtTime = updatedTx[0]?.updated_at.getTime()
242
+ expect(updatedAtTime).toBe(expectedMergeUpdatedAt)
243
+ }
244
+ })
245
+
246
+ // Test: getBsvTx handles undefined rawTx
247
+ test('10_getBsvTx_handles_undefined_rawTx', () => {
248
+ const tx = new EntityTransaction() // No rawTx provided
249
+ const bsvTx = tx.getBsvTx()
250
+ expect(bsvTx).toBeUndefined()
251
+ })
252
+
253
+ // Test: getInputs handles storage lookups and input merging
254
+ test('11_getInputs_handles_storage_lookups_and_input_merging', async () => {
255
+ for (const { activeStorage } of ctxs) {
256
+ // Insert a test transaction into the database
257
+ const { tx } = await _tu.insertTestTransaction(activeStorage, undefined, true)
258
+
259
+ // Create a Transaction instance with the inserted transaction's data
260
+ const transaction = new EntityTransaction(tx)
261
+
262
+ // Insert known inputs into the database and set the `spentBy` column to the transaction ID
263
+ const input1 = await _tu.insertTestOutput(activeStorage, tx, 0, 100) // vout = 0
264
+ const input2 = await _tu.insertTestOutput(activeStorage, tx, 2, 200) // vout = 2
265
+ input1.spentBy = tx.transactionId
266
+ input2.spentBy = tx.transactionId
267
+
268
+ // Update the outputs in the database to reflect `spentBy`
269
+ await activeStorage.updateOutput(input1.outputId, input1)
270
+ await activeStorage.updateOutput(input2.outputId, input2)
271
+
272
+ // Simulate external input for rawTx parsing
273
+ const externalInput = await _tu.insertTestOutput(
274
+ activeStorage,
275
+ tx, // Reference the same transaction
276
+ 3, // vout = 3
277
+ 150 // Satoshis
278
+ )
279
+
280
+ // Assign rawTx to the transaction and simulate `getBsvTxIns` behavior
281
+ transaction.rawTx = Array.from(Uint8Array.from([1, 2, 3]))
282
+ transaction.getBsvTxIns = () => [
283
+ {
284
+ sourceTXID: externalInput.txid,
285
+ sourceOutputIndex: 3
286
+ } as bsv.TransactionInput
287
+ ]
288
+
289
+ // Call `getInputs` to retrieve and merge inputs
290
+ const inputs = await transaction.getInputs(activeStorage)
291
+
292
+ // Validate the merged inputs
293
+ expect(inputs).toHaveLength(3) // Known inputs + external input
294
+ expect(inputs).toEqual(
295
+ expect.arrayContaining([
296
+ expect.objectContaining({ outputId: input1.outputId }),
297
+ expect.objectContaining({ outputId: input2.outputId }),
298
+ expect.objectContaining({ txid: externalInput.txid, vout: 3 })
299
+ ])
300
+ )
301
+ }
302
+ })
303
+
304
+ // Test: getProvendTx retrieves proven transaction
305
+ test('15_getProvenTx_retrieves_proven_transaction', async () => {
306
+ for (const { activeStorage } of ctxs) {
307
+ // Insert a test proven transaction into the storage
308
+ const provenTx = await _tu.insertTestProvenTx(activeStorage)
309
+
310
+ // Create a Transaction instance with a valid provenTxId
311
+ const tx = new EntityTransaction({
312
+ provenTxId: provenTx.provenTxId
313
+ } as TableTransaction)
314
+
315
+ // Retrieve the ProvenTx using the getProvenTx method
316
+ const retrievedProvenTx = await tx.getProvenTx(activeStorage)
317
+
318
+ // Assert the retrieved ProvenTx is defined and matches the expected values
319
+ expect(retrievedProvenTx).toBeDefined()
320
+ expect(retrievedProvenTx?.provenTxId).toBe(provenTx.provenTxId)
321
+ }
322
+ })
323
+
324
+ // Test: getProvenTx returns undefined when provenTxId is not set
325
+ test('16_getProvenTx_returns_undefined_when_provenTxId_is_not_set', async () => {
326
+ for (const { activeStorage } of ctxs) {
327
+ // Create a Transaction instance with no provenTxId
328
+ const tx = new EntityTransaction()
329
+
330
+ // Attempt to retrieve a ProvenTx
331
+ const retrievedProvenTx = await tx.getProvenTx(activeStorage)
332
+
333
+ // Assert the result is undefined
334
+ expect(retrievedProvenTx).toBeUndefined()
335
+ }
336
+ })
337
+
338
+ // Test: getProvenTx returns undefined when no matching ProvenTx is found
339
+ test('17_getProvenTx_returns_undefined_when_no_matching_ProvenTx_is_found', async () => {
340
+ for (const { activeStorage } of ctxs) {
341
+ // Create a Transaction instance with a provenTxId that doesn't exist in storage
342
+ const tx = new EntityTransaction({ provenTxId: 9999 } as TableTransaction) // Use an ID unlikely to exist
343
+
344
+ // Attempt to retrieve a ProvenTx
345
+ const retrievedProvenTx = await tx.getProvenTx(activeStorage)
346
+
347
+ // Assert the result is undefined
348
+ expect(retrievedProvenTx).toBeUndefined()
349
+ }
350
+ })
351
+
352
+ // Test: getInputs merges known inputs correctly
353
+ test('18_getInputs_merges_known_inputs_correctly', async () => {
354
+ for (const { activeStorage } of ctxs) {
355
+ // Step 1: Insert a Transaction
356
+ const { tx } = await _tu.insertTestTransaction(activeStorage, undefined, true)
357
+
358
+ // Step 2: Insert outputs associated with the transaction
359
+ const output1 = await _tu.insertTestOutput(activeStorage, tx, 0, 100) // vout = 0
360
+ const output2 = await _tu.insertTestOutput(activeStorage, tx, 1, 200) // vout = 1
361
+
362
+ // Step 3: Create a Transaction instance with rawTx
363
+ const rawTx = Uint8Array.from([1, 2, 3]) // Example raw transaction
364
+ const transaction = new EntityTransaction({
365
+ ...tx,
366
+ rawTx: Array.from(rawTx)
367
+ } as TableTransaction)
368
+
369
+ // Step 4: Simulate rawTx inputs
370
+ transaction.getBsvTxIns = () => [
371
+ {
372
+ sourceTXID: output1.txid,
373
+ sourceOutputIndex: output1.vout
374
+ } as bsv.TransactionInput,
375
+ {
376
+ sourceTXID: output2.txid,
377
+ sourceOutputIndex: output2.vout
378
+ } as bsv.TransactionInput
379
+ ]
380
+
381
+ // Step 5: Call `getInputs` to retrieve and merge known inputs
382
+ const inputs = await transaction.getInputs(activeStorage)
383
+
384
+ // Step 6: Assertions
385
+ expect(inputs).toHaveLength(2) // Ensure both outputs are retrieved
386
+ expect(inputs).toEqual(
387
+ expect.arrayContaining([
388
+ expect.objectContaining({ outputId: output1.outputId }), // vout = 0
389
+ expect.objectContaining({ outputId: output2.outputId }) // vout = 1
390
+ ])
391
+ )
392
+ }
393
+ })
394
+
395
+ // Test: getVersion returns API version
396
+ test('19_get_version_returns_api_version', () => {
397
+ const tx = new EntityTransaction({ version: 2 } as TableTransaction)
398
+ expect(tx.version).toBe(2)
399
+ })
400
+
401
+ // Test: getLockTime returns API lockTime
402
+ test('20_get_lockTime_returns_api_lockTime', () => {
403
+ const tx = new EntityTransaction({ lockTime: 500 } as TableTransaction)
404
+ expect(tx.lockTime).toBe(500)
405
+ })
406
+
407
+ // Test: set id updates transactionId
408
+ test('21_set_id_updates_transactionId', () => {
409
+ const tx = new EntityTransaction()
410
+ tx.id = 123
411
+ expect(tx.transactionId).toBe(123)
412
+ })
413
+
414
+ // Test: get entityName returns correct value
415
+ test('22_get_entityName_returns_correct_value', () => {
416
+ const tx = new EntityTransaction()
417
+ expect(tx.entityName).toBe('transaction')
418
+ })
419
+
420
+ // Test: get entityTable returns correct value
421
+ test('23_get_entityTable_returns_correct_value', () => {
422
+ const tx = new EntityTransaction()
423
+ expect(tx.entityTable).toBe('transactions')
424
+ })
425
+
426
+ // Test: `equals` returns false for mismatched other properties
427
+ test('25_equals_returns_false_for_mismatched_other_properties', async () => {
428
+ for (const { activeStorage } of ctxs) {
429
+ // Insert a test transaction to use as the baseline
430
+ const txData = await _tu.insertTestTransaction(activeStorage, undefined, true)
431
+
432
+ const syncMap = createSyncMap()
433
+ syncMap.transaction.idMap = {
434
+ [txData.tx.transactionId]: txData.tx.transactionId
435
+ }
436
+ syncMap.transaction.count = 1
437
+
438
+ const tx = new EntityTransaction({
439
+ ...txData.tx, // Base transaction
440
+ version: 2,
441
+ lockTime: 500,
442
+ satoshis: 789,
443
+ txid: 'txid1',
444
+ rawTx: [1, 2, 3],
445
+ inputBEEF: [4, 5, 6],
446
+ description: 'desc1',
447
+ status: 'completed',
448
+ reference: 'ref1'
449
+ } as TableTransaction)
450
+
451
+ const other = {
452
+ transactionId: txData.tx.transactionId, // Matching transactionId
453
+ reference: 'ref1', // Matching reference
454
+ version: 1, // Different version
455
+ lockTime: 100, // Different lockTime
456
+ status: 'unprocessed', // Different status
457
+ satoshis: 100, // Different satoshis
458
+ description: 'desc2', // Different description
459
+ txid: 'txid2', // Different txid
460
+ rawTx: [7, 8, 9], // Different rawTx
461
+ inputBEEF: [10, 11, 12] // Different inputBEEF
462
+ } as TableTransaction
463
+
464
+ expect(tx.equals(other, syncMap)).toBe(false) // Should return false due to mismatched properties
465
+ }
466
+ })
467
+
468
+ // Test: `getInputs` handles known and unknown inputs
469
+ test('26_getInputs_handles_known_and_unknown_inputs', async () => {
470
+ for (const { activeStorage } of ctxs) {
471
+ // Step 1: Insert a Transaction into the database
472
+ const { tx } = await _tu.insertTestTransaction(activeStorage, undefined, true)
473
+
474
+ // Step 2: Insert test outputs associated with the transaction
475
+ const output1 = await _tu.insertTestOutput(activeStorage, tx, 0, 100) // vout = 0, satoshis = 100
476
+ const output2 = await _tu.insertTestOutput(activeStorage, tx, 1, 200) // vout = 1, satoshis = 200
477
+
478
+ // Step 3: Simulate rawTx inputs directly without creating a Transaction instance
479
+ const rawTxInputs = [
480
+ { sourceTXID: tx.txid, sourceOutputIndex: 0 },
481
+ { sourceTXID: tx.txid, sourceOutputIndex: 1 }
482
+ ]
483
+
484
+ // Step 4: Query the inputs from storage individually
485
+ const inputs = await Promise.all(
486
+ rawTxInputs.map(input =>
487
+ activeStorage.findOutputs({
488
+ partial: {
489
+ transactionId: tx.transactionId,
490
+ vout: input.sourceOutputIndex
491
+ }
492
+ })
493
+ )
494
+ )
495
+
496
+ // Flatten the array of inputs (since `findOutputs` likely returns arrays for each query)
497
+ const flattenedInputs = inputs.flat()
498
+
499
+ // Step 5: Assertions
500
+ expect(flattenedInputs).toHaveLength(2) // Ensure both outputs are retrieved
501
+ expect(flattenedInputs).toEqual(
502
+ expect.arrayContaining([
503
+ expect.objectContaining({ outputId: output1.outputId }), // vout = 0
504
+ expect.objectContaining({ outputId: output2.outputId }) // vout = 1
505
+ ])
506
+ )
507
+ }
508
+ })
509
+
510
+ // Test: equals identifies matching entities
511
+ test('27_equals_identifies_matching_entities', async () => {
512
+ const ctx1 = ctxs[0]
513
+ const ctx2 = ctxs2[0]
514
+
515
+ // Insert a transaction into the first database
516
+ const tx1 = new EntityTransaction({
517
+ transactionId: 405,
518
+ userId: 1,
519
+ txid: 'txid1',
520
+ created_at: new Date('2023-01-01'),
521
+ updated_at: new Date('2023-01-02'),
522
+ status: 'completed',
523
+ reference: 'ref1',
524
+ isOutgoing: true,
525
+ satoshis: 789,
526
+ description: 'desc1',
527
+ version: 2,
528
+ lockTime: 500,
529
+ rawTx: [1, 2, 3],
530
+ inputBEEF: [4, 5, 6]
531
+ })
532
+
533
+ await ctx1.activeStorage.insertTransaction(tx1.toApi())
534
+
535
+ // Insert a matching transaction into the second database
536
+ const tx2 = new EntityTransaction({
537
+ transactionId: 405,
538
+ userId: 1, // Matching userId
539
+ txid: 'txid1', // Matching txid
540
+ created_at: new Date('2023-01-01'),
541
+ updated_at: new Date('2023-01-02'),
542
+ status: 'completed', // Matching status
543
+ reference: 'ref1', // Matching reference
544
+ isOutgoing: true, // Matching isOutgoing
545
+ satoshis: 789, // Matching satoshis
546
+ description: 'desc1', // Matching description
547
+ version: 2, // Matching version
548
+ lockTime: 500, // Matching lockTime
549
+ rawTx: [1, 2, 3], // Matching rawTx
550
+ inputBEEF: [4, 5, 6] // Matching inputBEEF
551
+ })
552
+ await ctx2.activeStorage.insertTransaction(tx2.toApi())
553
+
554
+ const syncMap = createSyncMap()
555
+ syncMap.transaction.idMap = { [tx1.transactionId]: tx2.transactionId }
556
+ syncMap.transaction.count = 1
557
+
558
+ // Verify the transactions match
559
+ expect(tx1.equals(tx2.toApi(), syncMap)).toBe(true)
560
+ })
561
+
562
+ // Test: `equals` identifies non-matching entities
563
+ test('28_equals_identifies_non_matching_entities', async () => {
564
+ const ctx1 = ctxs[0]
565
+ const ctx2 = ctxs2[0]
566
+
567
+ // Insert a transaction into the first database
568
+ const tx1 = new EntityTransaction({
569
+ transactionId: 303,
570
+ userId: 1,
571
+ txid: 'tx456',
572
+ created_at: new Date('2023-01-01'),
573
+ updated_at: new Date('2023-01-02'),
574
+ status: 'unprocessed', // Default status
575
+ reference: 'ref125',
576
+ isOutgoing: false, // Default isOutgoing
577
+ satoshis: 0, // Default satoshis
578
+ description: '' // Default description
579
+ })
580
+ await ctx1.activeStorage.insertTransaction(tx1.toApi())
581
+
582
+ // Insert a non-matching transaction into the second database
583
+ const tx2 = new EntityTransaction({
584
+ transactionId: 304,
585
+ userId: 1,
586
+ txid: 'tx789',
587
+ created_at: new Date('2023-01-01'),
588
+ updated_at: new Date('2023-01-02'),
589
+ status: 'unprocessed', // Default status
590
+ reference: 'ref126',
591
+ isOutgoing: false, // Default isOutgoing
592
+ satoshis: 0, // Default satoshis
593
+ description: '' // Default description
594
+ })
595
+ await ctx2.activeStorage.insertTransaction(tx2.toApi())
596
+
597
+ const syncMap = createSyncMap()
598
+ syncMap.transaction.idMap = { [tx1.transactionId]: tx2.transactionId }
599
+ syncMap.transaction.count = 1
600
+
601
+ // Verify the transactions do not match
602
+ expect(tx1.equals(tx2.toApi(), syncMap)).toBe(false)
603
+ })
604
+ })