@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,37 @@
1
+ import { RelinquishOutputArgs } from '@bsv/sdk'
2
+ import { sdk, StorageKnex } from '../../../src/index.all'
3
+ import { _tu, expectToThrowWERR, TestWalletNoSetup } from '../../utils/TestUtilsWalletStorage'
4
+ import { getBeefForTransaction } from '../../../src/storage/methods/getBeefForTransaction'
5
+
6
+ describe('RelinquishOutputArgs tests', () => {
7
+ jest.setTimeout(99999999)
8
+
9
+ const env = _tu.getEnv('test')
10
+ const ctxs: TestWalletNoSetup[] = []
11
+
12
+ beforeAll(async () => {
13
+ if (env.runMySQL) ctxs.push(await _tu.createLegacyWalletMySQLCopy('relinquishActionTests'))
14
+ ctxs.push(await _tu.createLegacyWalletSQLiteCopy('relinquishActionTests'))
15
+ })
16
+
17
+ afterAll(async () => {
18
+ for (const ctx of ctxs) {
19
+ await ctx.storage.destroy()
20
+ }
21
+ })
22
+
23
+ test('1_default', async () => {
24
+ const outputTxid = '2795b293c698b2244147aaba745db887a632d21990c474df46d842ec3e52f122'
25
+ const expectedResult = { relinquished: true }
26
+
27
+ for (const { wallet, activeStorage: storage } of ctxs) {
28
+ const args: RelinquishOutputArgs = {
29
+ basket: 'default',
30
+ output: `${outputTxid}.0`
31
+ }
32
+
33
+ const r1 = await wallet.relinquishOutput(args)
34
+ await expect(Promise.resolve(r1)).resolves.toEqual(expectedResult)
35
+ }
36
+ })
37
+ })
@@ -0,0 +1,298 @@
1
+ import {
2
+ AcquireCertificateArgs,
3
+ Certificate,
4
+ MasterCertificate,
5
+ ProtoWallet,
6
+ ProveCertificateArgs,
7
+ VerifiableCertificate
8
+ } from '@bsv/sdk'
9
+ import { _tu, expectToThrowWERR } from '../../utils/TestUtilsWalletStorage'
10
+ import { sdk, Wallet } from '../../../src/index.all'
11
+
12
+ describe('acquireCertificate tests', () => {
13
+ jest.setTimeout(99999999)
14
+
15
+ test('00', () => {})
16
+ if (_tu.noEnv('test')) return
17
+
18
+ const env = _tu.getEnv('test')
19
+
20
+ beforeAll(async () => {})
21
+
22
+ afterAll(async () => {})
23
+
24
+ test('1 invalid params', async () => {
25
+ const { wallet, storage } = await _tu.createLegacyWalletSQLiteCopy('acquireCertificate1')
26
+
27
+ const invalidArgs: AcquireCertificateArgs[] = [
28
+ {
29
+ type: '',
30
+ certifier: '',
31
+ acquisitionProtocol: 'direct',
32
+ fields: {}
33
+ }
34
+ // Oh so many things to test...
35
+ ]
36
+
37
+ for (const args of invalidArgs) {
38
+ await expectToThrowWERR(sdk.WERR_INVALID_PARAMETER, () => wallet.acquireCertificate(args))
39
+ }
40
+
41
+ await storage.destroy()
42
+ })
43
+
44
+ test('2 acquireCertificate listCertificate proveCertificate', async () => {
45
+ const { wallet, storage } = await _tu.createSQLiteTestWallet({
46
+ databaseName: 'acquireCertificate2',
47
+ dropAll: true
48
+ })
49
+
50
+ // Make a test certificate from a random certifier for the wallet's identityKey
51
+ const subject = wallet.keyDeriver.identityKey
52
+ const { cert: wcert, certifier } = _tu.makeSampleCert(subject)
53
+
54
+ // Act as the certifier: create a wallet for them...
55
+ const certifierWallet = new ProtoWallet(certifier)
56
+
57
+ const cert = new Certificate(
58
+ wcert.type,
59
+ wcert.serialNumber,
60
+ wcert.subject,
61
+ wcert.certifier,
62
+ wcert.revocationOutpoint,
63
+ wcert.fields
64
+ )
65
+
66
+ const r1 = await MasterCertificate.createCertificateFields(certifierWallet, subject, cert.fields)
67
+ const signedCert = new Certificate(
68
+ wcert.type,
69
+ wcert.serialNumber,
70
+ wcert.subject,
71
+ wcert.certifier,
72
+ wcert.revocationOutpoint,
73
+ r1.certificateFields
74
+ )
75
+ await signedCert.sign(certifierWallet)
76
+
77
+ const c = signedCert
78
+ // args object to create a new certificate via 'direct' protocol.
79
+ const args: AcquireCertificateArgs = {
80
+ serialNumber: c.serialNumber,
81
+ signature: c.signature,
82
+ privileged: false,
83
+ privilegedReason: undefined,
84
+
85
+ type: c.type,
86
+ certifier: c.certifier,
87
+ acquisitionProtocol: 'direct',
88
+ fields: c.fields,
89
+ keyringForSubject: r1.masterKeyring,
90
+ keyringRevealer: 'certifier',
91
+ revocationOutpoint: c.revocationOutpoint
92
+ }
93
+ // store the new signed certificate in user's wallet
94
+ const r = await wallet.acquireCertificate(args)
95
+ expect(r.serialNumber).toBe(c.serialNumber)
96
+
97
+ // Attempt to retrieve it... since
98
+ // the certifier is random this should
99
+ // always be unique :-)
100
+ const lcs = await wallet.listCertificates({
101
+ certifiers: [cert.certifier],
102
+ types: []
103
+ })
104
+ expect(lcs.certificates.length).toBe(1)
105
+ const lc = lcs.certificates[0]
106
+ // the result should be encrypted.
107
+ expect(lc.fields['name']).not.toBe('Alice')
108
+
109
+ // Use proveCertificate to obtain a decryption keyring:
110
+ const pkrArgs: ProveCertificateArgs = {
111
+ certificate: { serialNumber: lc.serialNumber },
112
+ fieldsToReveal: ['name'],
113
+ verifier: subject
114
+ }
115
+ const pkr = await wallet.proveCertificate(pkrArgs)
116
+
117
+ const veriCert = new VerifiableCertificate(
118
+ lc.type,
119
+ lc.serialNumber,
120
+ lc.subject,
121
+ lc.certifier,
122
+ lc.revocationOutpoint,
123
+ lc.fields,
124
+ pkr.keyringForVerifier,
125
+ lc.signature
126
+ )
127
+
128
+ const r4 = await veriCert.decryptFields(wallet)
129
+ expect(r4['name']).toBe('Alice')
130
+
131
+ const certs = await wallet.listCertificates({ types: [], certifiers: [] })
132
+ for (const cert of certs.certificates) {
133
+ const rr = await wallet.relinquishCertificate({
134
+ type: cert.type,
135
+ serialNumber: cert.serialNumber,
136
+ certifier: cert.certifier
137
+ })
138
+ expect(rr.relinquished).toBe(true)
139
+ }
140
+ await storage.destroy()
141
+ })
142
+
143
+ test('3 privileged acquireCertificate listCertificate proveCertificate', async () => {
144
+ const { wallet, storage } = await _tu.createSQLiteTestWallet({
145
+ databaseName: 'acquireCertificate3',
146
+ privKeyHex: '42'.repeat(32),
147
+ dropAll: true
148
+ })
149
+
150
+ // Make a test certificate from a random certifier for the wallet's identityKey
151
+
152
+ // Certificate issued to the privileged key must use the privilegedKeyManager's identityKey
153
+ const subject = (await wallet.privilegedKeyManager!.getPublicKey({ identityKey: true })).publicKey
154
+ const { cert: wcert, certifier } = _tu.makeSampleCert(subject)
155
+
156
+ // Act as the certifier: create a wallet for them...
157
+ const certifierWallet = new ProtoWallet(certifier)
158
+
159
+ const cert = new Certificate(
160
+ wcert.type,
161
+ wcert.serialNumber,
162
+ wcert.subject,
163
+ wcert.certifier,
164
+ wcert.revocationOutpoint,
165
+ wcert.fields
166
+ )
167
+
168
+ const r1 = await MasterCertificate.createCertificateFields(certifierWallet, subject, cert.fields)
169
+ const signedCert = new Certificate(
170
+ wcert.type,
171
+ wcert.serialNumber,
172
+ wcert.subject,
173
+ wcert.certifier,
174
+ wcert.revocationOutpoint,
175
+ r1.certificateFields
176
+ )
177
+ await signedCert.sign(certifierWallet)
178
+
179
+ const c = signedCert
180
+
181
+ // args object to create a new certificate via 'direct' protocol.
182
+ const args: AcquireCertificateArgs = {
183
+ serialNumber: c.serialNumber,
184
+ signature: c.signature,
185
+ privileged: true,
186
+ privilegedReason: 'access to my penthouse',
187
+
188
+ type: c.type,
189
+ certifier: c.certifier,
190
+ acquisitionProtocol: 'direct',
191
+ fields: c.fields,
192
+ keyringForSubject: r1.masterKeyring,
193
+ keyringRevealer: 'certifier',
194
+ revocationOutpoint: c.revocationOutpoint
195
+ }
196
+ // store the new signed certificate in user's wallet
197
+ const r = await wallet.acquireCertificate(args)
198
+ expect(r.serialNumber).toBe(c.serialNumber)
199
+
200
+ // Attempt to retrieve it... since
201
+ // the certifier is random this should
202
+ // always be unique :-)
203
+ const lcs = await wallet.listCertificates({
204
+ certifiers: [cert.certifier],
205
+ types: []
206
+ })
207
+ expect(lcs.certificates.length).toBe(1)
208
+ const lc = lcs.certificates[0]
209
+ // the result should be encrypted.
210
+ expect(lc.fields['name']).not.toBe('Alice')
211
+
212
+ // Use proveCertificate to obtain a decryption keyring:
213
+ const pkrArgs: ProveCertificateArgs = {
214
+ certificate: { serialNumber: lc.serialNumber },
215
+ fieldsToReveal: ['name'],
216
+ verifier: subject,
217
+ privileged: true,
218
+ privilegedReason: 'more cheese'
219
+ }
220
+ const pkr = await wallet.proveCertificate(pkrArgs)
221
+
222
+ const veriCert = new VerifiableCertificate(
223
+ lc.type,
224
+ lc.serialNumber,
225
+ lc.subject,
226
+ lc.certifier,
227
+ lc.revocationOutpoint,
228
+ lc.fields,
229
+ pkr.keyringForVerifier,
230
+ lc.signature
231
+ )
232
+
233
+ const r4 = await veriCert.decryptFields(wallet, true, 'more cheese')
234
+ expect(r4['name']).toBe('Alice')
235
+
236
+ const certs = await wallet.listCertificates({ types: [], certifiers: [] })
237
+ for (const cert of certs.certificates) {
238
+ const rr = await wallet.relinquishCertificate({
239
+ type: cert.type,
240
+ serialNumber: cert.serialNumber,
241
+ certifier: cert.certifier
242
+ })
243
+ expect(rr.relinquished).toBe(true)
244
+ }
245
+
246
+ // Also cleans up the privilegedKeyManager
247
+ await wallet.destroy()
248
+ })
249
+
250
+ /**
251
+ * NOTE: This test requires a generic-certifier-backend to be running
252
+ * with the following configuration:
253
+ *
254
+ * type: 'h53Tvo8w3nqeF2cPyuRUc/B+gjPXJ3gPS2PKFBZfpDw=',
255
+ * certifierIdentityKey: '02be1093d98689b5a5bb49cefff5d98a390213cc5b0a5cd57459407f86a963325f',
256
+ */
257
+ test.skip('acquireCertificate via issuance', async () => {
258
+ const { wallet, storage } = await _tu.createSQLiteTestWallet({
259
+ databaseName: 'acquireCertificate2',
260
+ dropAll: true
261
+ })
262
+ // Attributes to get certified
263
+ const fields = {
264
+ name: 'Bob',
265
+ email: 'bob@projectbabbage.com'
266
+ }
267
+
268
+ // args object to create a new certificate via 'issuance' protocol.
269
+ const args: AcquireCertificateArgs = {
270
+ type: 'h53Tvo8w3nqeF2cPyuRUc/B+gjPXJ3gPS2PKFBZfpDw=',
271
+ certifier: '02be1093d98689b5a5bb49cefff5d98a390213cc5b0a5cd57459407f86a963325f',
272
+ certifierUrl: 'http://localhost:3998',
273
+ acquisitionProtocol: 'issuance',
274
+ fields: fields
275
+ }
276
+ // store the new signed certificate in user's wallet
277
+ const r = await wallet.acquireCertificate(args)
278
+ const certificatesFound = await wallet.listCertificates({
279
+ certifiers: [args.certifier],
280
+ types: []
281
+ })
282
+ expect(certificatesFound.certificates.length).toBe(1)
283
+ const lc = certificatesFound.certificates[0]
284
+ // the result should be encrypted.
285
+ expect(lc.fields['name']).not.toBe('Alice')
286
+
287
+ // const certs = await wallet.listCertificates({ types: [], certifiers: [] })
288
+ for (const cert of certificatesFound.certificates) {
289
+ const rr = await wallet.relinquishCertificate({
290
+ type: cert.type,
291
+ serialNumber: cert.serialNumber,
292
+ certifier: cert.certifier
293
+ })
294
+ expect(rr.relinquished).toBe(true)
295
+ }
296
+ await storage.destroy()
297
+ })
298
+ })
@@ -0,0 +1,346 @@
1
+ import { OriginatorDomainNameStringUnder250Bytes, Validation } from '@bsv/sdk'
2
+ import { listCertificates } from '../../../src/storage/methods/listCertificates'
3
+ import { StorageProvider } from '../../../src/storage/StorageProvider'
4
+ import { sdk, TableCertificate, TableCertificateField } from '../../../src/index.all'
5
+ import { TrxToken } from '../../../src/sdk'
6
+
7
+ jest.mock('../../../src/storage/StorageProvider')
8
+
9
+ describe('listCertificates', () => {
10
+ let mockStorage: jest.Mocked<StorageProvider>
11
+ let auth: sdk.AuthId
12
+
13
+ // This is a valid, minimal set of arguments for listCertificates
14
+ let vargs: Validation.ValidListCertificatesArgs
15
+ let originator: OriginatorDomainNameStringUnder250Bytes | undefined
16
+
17
+ // Helper so we can easily mock the transaction call
18
+ const mockTransaction = async <T>(callback: (trx: TrxToken) => Promise<T>): Promise<T> => {
19
+ // We simulate the transaction by simply calling back immediately
20
+ // with an empty object as trx token.
21
+ return callback({} as unknown as TrxToken)
22
+ }
23
+
24
+ beforeEach(() => {
25
+ // Create a fresh mock of the storage
26
+ mockStorage = {
27
+ // We only need to mock the methods that are actually used by listCertificates
28
+ transaction: jest.fn().mockImplementation(mockTransaction),
29
+ findCertificates: jest.fn(),
30
+ findCertificateFields: jest.fn(),
31
+ countCertificates: jest.fn()
32
+ } as unknown as jest.Mocked<StorageProvider>
33
+
34
+ // Auth with a valid user ID
35
+ auth = {
36
+ identityKey: 'myIdentityKey',
37
+ userId: 123
38
+ }
39
+
40
+ // Minimal valid vargs with default limit=10, offset=0, no partial filter
41
+ vargs = {
42
+ partial: undefined,
43
+ certifiers: [],
44
+ types: [],
45
+ limit: 10,
46
+ offset: 0,
47
+ privileged: false
48
+ }
49
+
50
+ // By default we set it to undefined
51
+ originator = undefined
52
+ })
53
+
54
+ afterEach(() => {
55
+ jest.clearAllMocks()
56
+ })
57
+
58
+ test('should return an empty result when no certificates are found', async () => {
59
+ // Setup mocks
60
+ mockStorage.findCertificates.mockResolvedValueOnce([]) // no certs returned
61
+
62
+ // Execute
63
+ const result = await listCertificates(mockStorage, auth, vargs, originator)
64
+
65
+ // Verify
66
+ expect(mockStorage.transaction).toHaveBeenCalledTimes(1)
67
+ expect(mockStorage.findCertificates).toHaveBeenCalledTimes(1)
68
+ expect(mockStorage.findCertificateFields).not.toHaveBeenCalled()
69
+ expect(mockStorage.countCertificates).not.toHaveBeenCalled() // no need to call if 0 < limit
70
+
71
+ expect(result).toEqual({
72
+ totalCertificates: 0,
73
+ certificates: []
74
+ })
75
+ })
76
+
77
+ test('should return exactly the number of certificates if they are fewer than the limit', async () => {
78
+ // Suppose we have 2 certificates
79
+ const fakeCerts: TableCertificate[] = [
80
+ {
81
+ certificateId: 1,
82
+ userId: 123,
83
+ type: 'base64Type1',
84
+ serialNumber: 'serial1',
85
+ certifier: 'abcdef01',
86
+ subject: '12345678',
87
+ verifier: undefined,
88
+ revocationOutpoint: 'abcd1234.0',
89
+ signature: 'deadbeef01',
90
+ isDeleted: false,
91
+ created_at: new Date(),
92
+ updated_at: new Date()
93
+ },
94
+ {
95
+ certificateId: 2,
96
+ userId: 123,
97
+ type: 'base64Type2',
98
+ serialNumber: 'serial2',
99
+ certifier: 'abcdef02',
100
+ subject: '23456789',
101
+ verifier: undefined,
102
+ revocationOutpoint: 'abcd5678.1',
103
+ signature: 'deadbeef02',
104
+ isDeleted: false,
105
+ created_at: new Date(),
106
+ updated_at: new Date()
107
+ }
108
+ ]
109
+
110
+ // Suppose each cert has some fields
111
+ const fakeFieldsForCert1: TableCertificateField[] = [
112
+ {
113
+ certificateId: 1,
114
+ userId: 123,
115
+ fieldName: 'field1',
116
+ fieldValue: 'value1',
117
+ masterKey: 'mkey1',
118
+ created_at: new Date(),
119
+ updated_at: new Date()
120
+ }
121
+ ]
122
+
123
+ const fakeFieldsForCert2: TableCertificateField[] = [
124
+ {
125
+ certificateId: 2,
126
+ userId: 123,
127
+ fieldName: 'fieldA',
128
+ fieldValue: 'valueA',
129
+ masterKey: 'mkeyA',
130
+ created_at: new Date(),
131
+ updated_at: new Date()
132
+ }
133
+ ]
134
+
135
+ mockStorage.findCertificates.mockResolvedValueOnce(fakeCerts)
136
+ // Make sure we return correct fields for each certificate
137
+ mockStorage.findCertificateFields.mockImplementation(async (args: sdk.FindCertificateFieldsArgs) => {
138
+ if (args.partial?.certificateId === 1) return fakeFieldsForCert1
139
+ if (args.partial?.certificateId === 2) return fakeFieldsForCert2
140
+ return []
141
+ })
142
+
143
+ // The returned certs are length=2, which is < limit(10). So we do not call countCertificates
144
+ // Setup a spied or mocked value just in case
145
+ mockStorage.countCertificates.mockResolvedValueOnce(10)
146
+
147
+ // Execute
148
+ const result = await listCertificates(mockStorage, auth, vargs)
149
+
150
+ // Verify
151
+ expect(mockStorage.transaction).toHaveBeenCalledTimes(1)
152
+ expect(mockStorage.findCertificates).toHaveBeenCalledTimes(1)
153
+ expect(mockStorage.findCertificateFields).toHaveBeenCalledTimes(2)
154
+ expect(mockStorage.countCertificates).not.toHaveBeenCalled() // Because 2 < 10
155
+
156
+ expect(result.certificates.length).toBe(2)
157
+ expect(result.totalCertificates).toBe(2)
158
+
159
+ // Ensure the fields are included
160
+ expect(result.certificates[0]).toEqual({
161
+ type: 'base64Type1',
162
+ subject: '12345678',
163
+ serialNumber: 'serial1',
164
+ certifier: 'abcdef01',
165
+ revocationOutpoint: 'abcd1234.0',
166
+ signature: 'deadbeef01',
167
+ verifier: undefined,
168
+ fields: { field1: 'value1' },
169
+ keyring: { field1: 'mkey1' }
170
+ })
171
+ expect(result.certificates[1]).toEqual({
172
+ type: 'base64Type2',
173
+ subject: '23456789',
174
+ serialNumber: 'serial2',
175
+ certifier: 'abcdef02',
176
+ revocationOutpoint: 'abcd5678.1',
177
+ signature: 'deadbeef02',
178
+ verifier: undefined,
179
+ fields: { fieldA: 'valueA' },
180
+ keyring: { fieldA: 'mkeyA' }
181
+ })
182
+ })
183
+
184
+ test('should call countCertificates when the returned certificates length is equal to limit', async () => {
185
+ // We want exactly 'limit' items returned, so the function calls countCertificates
186
+ vargs.limit = 2 // set limit to 2
187
+ const fakeCerts: TableCertificate[] = [
188
+ {
189
+ certificateId: 11,
190
+ userId: 123,
191
+ type: 'base64Type',
192
+ serialNumber: 'sn',
193
+ certifier: 'abcdef01',
194
+ subject: 'deadbeef01',
195
+ verifier: undefined,
196
+ revocationOutpoint: '0000.0',
197
+ signature: 'abcdabcd',
198
+ isDeleted: false,
199
+ created_at: new Date(),
200
+ updated_at: new Date()
201
+ },
202
+ {
203
+ certificateId: 22,
204
+ userId: 123,
205
+ type: 'base64Type',
206
+ serialNumber: 'sn2',
207
+ certifier: 'abcdef02',
208
+ subject: 'deadbeef02',
209
+ verifier: undefined,
210
+ revocationOutpoint: '0001.0',
211
+ signature: 'ef01ef01',
212
+ isDeleted: false,
213
+ created_at: new Date(),
214
+ updated_at: new Date()
215
+ }
216
+ ]
217
+
218
+ // Suppose each cert has no fields
219
+ mockStorage.findCertificateFields.mockResolvedValue([])
220
+
221
+ // We return exactly 2 certs, which is == limit
222
+ mockStorage.findCertificates.mockResolvedValueOnce(fakeCerts)
223
+
224
+ // So the code should call countCertificates
225
+ mockStorage.countCertificates.mockResolvedValueOnce(25)
226
+
227
+ // Execute
228
+ const result = await listCertificates(mockStorage, auth, vargs)
229
+
230
+ // Verify
231
+ expect(mockStorage.findCertificates).toHaveBeenCalledTimes(1)
232
+ expect(mockStorage.findCertificateFields).toHaveBeenCalledTimes(2)
233
+ expect(mockStorage.countCertificates).toHaveBeenCalledTimes(1)
234
+
235
+ // We expect totalCertificates = 25 from countCertificates
236
+ expect(result.totalCertificates).toBe(25)
237
+ expect(result.certificates.length).toBe(2)
238
+ })
239
+
240
+ test('should handle transaction failure by throwing an error', async () => {
241
+ // If the transaction or the underlying findCertificates call fails, we rethrow
242
+ const error = new Error('Database error')
243
+ mockStorage.transaction.mockRejectedValueOnce(error)
244
+
245
+ await expect(listCertificates(mockStorage, auth, vargs)).rejects.toThrow('Database error')
246
+
247
+ // Verify mocks
248
+ expect(mockStorage.transaction).toHaveBeenCalledTimes(1)
249
+ expect(mockStorage.findCertificates).not.toHaveBeenCalled()
250
+ expect(mockStorage.findCertificateFields).not.toHaveBeenCalled()
251
+ expect(mockStorage.countCertificates).not.toHaveBeenCalled()
252
+ })
253
+
254
+ test('should handle scenario userId is undefined', async () => {
255
+ // Although typically userId is required, let's see what happens
256
+ // If userId is undefined, partial: { userId: undefined, isDeleted: false } is used
257
+ // The storage call might or might not blow up. We'll test that the code still calls the transaction
258
+ // We rely on the underlying findCertificates to throw or return an empty array.
259
+ auth.userId = undefined
260
+
261
+ mockStorage.findCertificates.mockResolvedValueOnce([])
262
+
263
+ const result = await listCertificates(mockStorage, auth, vargs)
264
+ expect(result).toEqual({
265
+ totalCertificates: 0,
266
+ certificates: []
267
+ })
268
+
269
+ // We see a normal call
270
+ expect(mockStorage.transaction).toHaveBeenCalledTimes(1)
271
+ expect(mockStorage.findCertificates).toHaveBeenCalledTimes(1)
272
+ // The partial would have userId: undefined
273
+ const arg0 = mockStorage.findCertificates.mock.calls[0][0]
274
+ expect(arg0.partial).toEqual({
275
+ userId: undefined,
276
+ isDeleted: false
277
+ })
278
+ })
279
+
280
+ test('if returned certificate count is bigger than limit, still only returns limit items but sets total using countCertificates', async () => {
281
+ // For completeness, if the storage findCertificates method returns exactly "limit" items,
282
+ // we do a count. But let's pretend it can return exactly limit or a bit more (some storages might do that incorrectly).
283
+ // We'll only test the scenario that triggers the "else" path. Already tested an =limit scenario above,
284
+ // but let's confirm the coverage if the function doesn't rely on partial storage returning partial results.
285
+ vargs.limit = 2
286
+
287
+ const cA: TableCertificate = {
288
+ certificateId: 100,
289
+ userId: 123,
290
+ type: 'zzz',
291
+ serialNumber: 'snA',
292
+ certifier: 'cA',
293
+ subject: 'sA',
294
+ verifier: undefined,
295
+ revocationOutpoint: 'nope.0',
296
+ signature: 'sigA',
297
+ isDeleted: false,
298
+ created_at: new Date(),
299
+ updated_at: new Date()
300
+ }
301
+ const cB: TableCertificate = {
302
+ certificateId: 101,
303
+ userId: 123,
304
+ type: 'yyy',
305
+ serialNumber: 'snB',
306
+ certifier: 'cB',
307
+ subject: 'sB',
308
+ verifier: undefined,
309
+ revocationOutpoint: 'nope.1',
310
+ signature: 'sigB',
311
+ isDeleted: false,
312
+ created_at: new Date(),
313
+ updated_at: new Date()
314
+ }
315
+ const cC: TableCertificate = {
316
+ certificateId: 102,
317
+ userId: 123,
318
+ type: 'xxx',
319
+ serialNumber: 'snC',
320
+ certifier: 'cC',
321
+ subject: 'sC',
322
+ verifier: undefined,
323
+ revocationOutpoint: 'nope.2',
324
+ signature: 'sigC',
325
+ isDeleted: false,
326
+ created_at: new Date(),
327
+ updated_at: new Date()
328
+ }
329
+
330
+ // Suppose the storage returned 3 items even though we only want 2.
331
+ // The code uses them all in memory, but sees length=3 which is > limit=2
332
+ // The line checks if (r.certificates.length < paged.limit). That is false, so it calls countCertificates.
333
+ mockStorage.findCertificates.mockResolvedValueOnce([cA, cB, cC])
334
+
335
+ // Fields are none
336
+ mockStorage.findCertificateFields.mockResolvedValue([])
337
+
338
+ // We want to see it call countCertificates
339
+ mockStorage.countCertificates.mockResolvedValueOnce(999)
340
+
341
+ const result = await listCertificates(mockStorage, auth, vargs)
342
+
343
+ expect(result.certificates.length).toBe(3)
344
+ expect(result.totalCertificates).toBe(999) // from countCertificates
345
+ })
346
+ })