@bsv/sdk 2.0.0-beta.0 → 2.0.1

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 (488) hide show
  1. package/dist/cjs/mod.js +1 -0
  2. package/dist/cjs/mod.js.map +1 -1
  3. package/dist/cjs/package.json +1 -1
  4. package/dist/cjs/src/auth/Peer.js +149 -74
  5. package/dist/cjs/src/auth/Peer.js.map +1 -1
  6. package/dist/cjs/src/auth/SessionManager.js.map +1 -1
  7. package/dist/cjs/src/auth/certificates/Certificate.js +18 -8
  8. package/dist/cjs/src/auth/certificates/Certificate.js.map +1 -1
  9. package/dist/cjs/src/auth/certificates/MasterCertificate.js +19 -9
  10. package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
  11. package/dist/cjs/src/auth/certificates/VerifiableCertificate.js +17 -7
  12. package/dist/cjs/src/auth/certificates/VerifiableCertificate.js.map +1 -1
  13. package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
  14. package/dist/cjs/src/auth/clients/AuthFetch.js +30 -10
  15. package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
  16. package/dist/cjs/src/auth/clients/__tests__/AuthFetch.test.js.map +1 -1
  17. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +17 -7
  18. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  19. package/dist/cjs/src/auth/transports/__tests__/SimplifiedFetchTransport.test.js +17 -7
  20. package/dist/cjs/src/auth/transports/__tests__/SimplifiedFetchTransport.test.js.map +1 -1
  21. package/dist/cjs/src/auth/utils/createNonce.js +18 -9
  22. package/dist/cjs/src/auth/utils/createNonce.js.map +1 -1
  23. package/dist/cjs/src/auth/utils/validateCertificates.js.map +1 -1
  24. package/dist/cjs/src/auth/utils/verifyNonce.js +18 -9
  25. package/dist/cjs/src/auth/utils/verifyNonce.js.map +1 -1
  26. package/dist/cjs/src/compat/BSM.js +17 -7
  27. package/dist/cjs/src/compat/BSM.js.map +1 -1
  28. package/dist/cjs/src/compat/ECIES.js +17 -7
  29. package/dist/cjs/src/compat/ECIES.js.map +1 -1
  30. package/dist/cjs/src/compat/HD.js +17 -7
  31. package/dist/cjs/src/compat/HD.js.map +1 -1
  32. package/dist/cjs/src/compat/Mnemonic.js +17 -7
  33. package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
  34. package/dist/cjs/src/compat/Utxo.js +1 -1
  35. package/dist/cjs/src/compat/Utxo.js.map +1 -1
  36. package/dist/cjs/src/compat/index.js +17 -7
  37. package/dist/cjs/src/compat/index.js.map +1 -1
  38. package/dist/cjs/src/identity/ContactsManager.js +1 -1
  39. package/dist/cjs/src/identity/ContactsManager.js.map +1 -1
  40. package/dist/cjs/src/identity/IdentityClient.js.map +1 -1
  41. package/dist/cjs/src/kvstore/GlobalKVStore.js +20 -10
  42. package/dist/cjs/src/kvstore/GlobalKVStore.js.map +1 -1
  43. package/dist/cjs/src/kvstore/LocalKVStore.js +17 -7
  44. package/dist/cjs/src/kvstore/LocalKVStore.js.map +1 -1
  45. package/dist/cjs/src/kvstore/kvStoreInterpreter.js +17 -7
  46. package/dist/cjs/src/kvstore/kvStoreInterpreter.js.map +1 -1
  47. package/dist/cjs/src/messages/EncryptedMessage.js +19 -0
  48. package/dist/cjs/src/messages/EncryptedMessage.js.map +1 -1
  49. package/dist/cjs/src/messages/SignedMessage.js.map +1 -1
  50. package/dist/cjs/src/messages/index.js +17 -7
  51. package/dist/cjs/src/messages/index.js.map +1 -1
  52. package/dist/cjs/src/overlay-tools/Historian.js.map +1 -1
  53. package/dist/cjs/src/overlay-tools/HostReputationTracker.js.map +1 -1
  54. package/dist/cjs/src/overlay-tools/LookupResolver.js +17 -7
  55. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  56. package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
  57. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +17 -7
  58. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  59. package/dist/cjs/src/overlay-tools/withDoubleSpendRetry.js +1 -2
  60. package/dist/cjs/src/overlay-tools/withDoubleSpendRetry.js.map +1 -1
  61. package/dist/cjs/src/primitives/AESGCM.js +77 -32
  62. package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
  63. package/dist/cjs/src/primitives/BigNumber.js +28 -54
  64. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  65. package/dist/cjs/src/primitives/Curve.js.map +1 -1
  66. package/dist/cjs/src/primitives/DRBG.js.map +1 -1
  67. package/dist/cjs/src/primitives/ECDSA.js +58 -24
  68. package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
  69. package/dist/cjs/src/primitives/Hash.js +6 -6
  70. package/dist/cjs/src/primitives/Hash.js.map +1 -1
  71. package/dist/cjs/src/primitives/JacobianPoint.js.map +1 -1
  72. package/dist/cjs/src/primitives/K256.js.map +1 -1
  73. package/dist/cjs/src/primitives/Mersenne.js.map +1 -1
  74. package/dist/cjs/src/primitives/MontgomoryMethod.js.map +1 -1
  75. package/dist/cjs/src/primitives/Point.js +63 -6
  76. package/dist/cjs/src/primitives/Point.js.map +1 -1
  77. package/dist/cjs/src/primitives/Polynomial.js.map +1 -1
  78. package/dist/cjs/src/primitives/PrivateKey.js +46 -9
  79. package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
  80. package/dist/cjs/src/primitives/PublicKey.js +1 -1
  81. package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
  82. package/dist/cjs/src/primitives/Random.js.map +1 -1
  83. package/dist/cjs/src/primitives/ReaderUint8Array.js +180 -0
  84. package/dist/cjs/src/primitives/ReaderUint8Array.js.map +1 -0
  85. package/dist/cjs/src/primitives/ReductionContext.js +35 -46
  86. package/dist/cjs/src/primitives/ReductionContext.js.map +1 -1
  87. package/dist/cjs/src/primitives/Schnorr.js.map +1 -1
  88. package/dist/cjs/src/primitives/Secp256r1.js.map +1 -1
  89. package/dist/cjs/src/primitives/Signature.js.map +1 -1
  90. package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
  91. package/dist/cjs/src/primitives/TransactionSignature.js +132 -17
  92. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  93. package/dist/cjs/src/primitives/WriterUint8Array.js +173 -0
  94. package/dist/cjs/src/primitives/WriterUint8Array.js.map +1 -0
  95. package/dist/cjs/src/primitives/hex.js +2 -3
  96. package/dist/cjs/src/primitives/hex.js.map +1 -1
  97. package/dist/cjs/src/primitives/index.js +17 -7
  98. package/dist/cjs/src/primitives/index.js.map +1 -1
  99. package/dist/cjs/src/primitives/utils.js +43 -16
  100. package/dist/cjs/src/primitives/utils.js.map +1 -1
  101. package/dist/cjs/src/registry/RegistryClient.js +2 -2
  102. package/dist/cjs/src/registry/RegistryClient.js.map +1 -1
  103. package/dist/cjs/src/remittance/CommsLayer.js +3 -0
  104. package/dist/cjs/src/remittance/CommsLayer.js.map +1 -0
  105. package/dist/cjs/src/remittance/IdentityLayer.js +3 -0
  106. package/dist/cjs/src/remittance/IdentityLayer.js.map +1 -0
  107. package/dist/cjs/src/remittance/RemittanceManager.js +1245 -0
  108. package/dist/cjs/src/remittance/RemittanceManager.js.map +1 -0
  109. package/dist/cjs/src/remittance/RemittanceModule.js +3 -0
  110. package/dist/cjs/src/remittance/RemittanceModule.js.map +1 -0
  111. package/dist/cjs/src/remittance/index.js +23 -0
  112. package/dist/cjs/src/remittance/index.js.map +1 -0
  113. package/dist/cjs/src/remittance/modules/BasicBRC29.js +225 -0
  114. package/dist/cjs/src/remittance/modules/BasicBRC29.js.map +1 -0
  115. package/dist/cjs/src/remittance/modules/index.js +18 -0
  116. package/dist/cjs/src/remittance/modules/index.js.map +1 -0
  117. package/dist/cjs/src/remittance/types.js +22 -0
  118. package/dist/cjs/src/remittance/types.js.map +1 -0
  119. package/dist/cjs/src/script/OP.js +15 -13
  120. package/dist/cjs/src/script/OP.js.map +1 -1
  121. package/dist/cjs/src/script/Script.js +80 -5
  122. package/dist/cjs/src/script/Script.js.map +1 -1
  123. package/dist/cjs/src/script/Spend.js +145 -53
  124. package/dist/cjs/src/script/Spend.js.map +1 -1
  125. package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
  126. package/dist/cjs/src/script/templates/PushDrop.js +21 -7
  127. package/dist/cjs/src/script/templates/PushDrop.js.map +1 -1
  128. package/dist/cjs/src/script/templates/RPuzzle.js.map +1 -1
  129. package/dist/cjs/src/storage/StorageDownloader.js.map +1 -1
  130. package/dist/cjs/src/storage/StorageUploader.js +17 -7
  131. package/dist/cjs/src/storage/StorageUploader.js.map +1 -1
  132. package/dist/cjs/src/storage/StorageUtils.js.map +1 -1
  133. package/dist/cjs/src/storage/index.js +17 -7
  134. package/dist/cjs/src/storage/index.js.map +1 -1
  135. package/dist/cjs/src/totp/totp.js.map +1 -1
  136. package/dist/cjs/src/transaction/Beef.js +85 -27
  137. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  138. package/dist/cjs/src/transaction/BeefParty.js.map +1 -1
  139. package/dist/cjs/src/transaction/BeefTx.js +32 -14
  140. package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
  141. package/dist/cjs/src/transaction/Broadcaster.js +2 -3
  142. package/dist/cjs/src/transaction/Broadcaster.js.map +1 -1
  143. package/dist/cjs/src/transaction/MerklePath.js +25 -6
  144. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  145. package/dist/cjs/src/transaction/Transaction.js +238 -27
  146. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  147. package/dist/cjs/src/transaction/broadcasters/ARC.js +23 -0
  148. package/dist/cjs/src/transaction/broadcasters/ARC.js.map +1 -1
  149. package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js +1 -2
  150. package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
  151. package/dist/cjs/src/transaction/broadcasters/Teranode.js.map +1 -1
  152. package/dist/cjs/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
  153. package/dist/cjs/src/transaction/chaintrackers/BlockHeadersService.js.map +1 -1
  154. package/dist/cjs/src/transaction/chaintrackers/DefaultChainTracker.js +1 -2
  155. package/dist/cjs/src/transaction/chaintrackers/DefaultChainTracker.js.map +1 -1
  156. package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
  157. package/dist/cjs/src/transaction/fee-models/LivePolicy.js.map +1 -1
  158. package/dist/cjs/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
  159. package/dist/cjs/src/transaction/http/BinaryFetchClient.js +2 -2
  160. package/dist/cjs/src/transaction/http/BinaryFetchClient.js.map +1 -1
  161. package/dist/cjs/src/transaction/http/DefaultHttpClient.js +1 -2
  162. package/dist/cjs/src/transaction/http/DefaultHttpClient.js.map +1 -1
  163. package/dist/cjs/src/transaction/http/NodejsHttpClient.js.map +1 -1
  164. package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -1
  165. package/dist/cjs/src/wallet/KeyDeriver.js.map +1 -1
  166. package/dist/cjs/src/wallet/ProtoWallet.js +1 -1
  167. package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
  168. package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
  169. package/dist/cjs/src/wallet/WalletError.js.map +1 -1
  170. package/dist/cjs/src/wallet/index.js +17 -7
  171. package/dist/cjs/src/wallet/index.js.map +1 -1
  172. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  173. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +17 -7
  174. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
  175. package/dist/cjs/src/wallet/substrates/ReactNativeWebView.js +17 -7
  176. package/dist/cjs/src/wallet/substrates/ReactNativeWebView.js.map +1 -1
  177. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +17 -7
  178. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  179. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +17 -7
  180. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  181. package/dist/cjs/src/wallet/substrates/XDM.js +17 -7
  182. package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
  183. package/dist/cjs/src/wallet/substrates/utils/toOriginHeader.js +1 -2
  184. package/dist/cjs/src/wallet/substrates/utils/toOriginHeader.js.map +1 -1
  185. package/dist/cjs/src/wallet/substrates/window.CWI.js.map +1 -1
  186. package/dist/cjs/src/wallet/validationHelpers.js +51 -41
  187. package/dist/cjs/src/wallet/validationHelpers.js.map +1 -1
  188. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  189. package/dist/esm/mod.js +1 -0
  190. package/dist/esm/mod.js.map +1 -1
  191. package/dist/esm/src/auth/Peer.js +132 -67
  192. package/dist/esm/src/auth/Peer.js.map +1 -1
  193. package/dist/esm/src/auth/SessionManager.js.map +1 -1
  194. package/dist/esm/src/auth/certificates/Certificate.js +1 -1
  195. package/dist/esm/src/auth/certificates/Certificate.js.map +1 -1
  196. package/dist/esm/src/auth/certificates/MasterCertificate.js +2 -2
  197. package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
  198. package/dist/esm/src/auth/certificates/VerifiableCertificate.js.map +1 -1
  199. package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
  200. package/dist/esm/src/auth/clients/AuthFetch.js +13 -3
  201. package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
  202. package/dist/esm/src/auth/clients/__tests__/AuthFetch.test.js.map +1 -1
  203. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  204. package/dist/esm/src/auth/transports/__tests__/SimplifiedFetchTransport.test.js.map +1 -1
  205. package/dist/esm/src/auth/utils/validateCertificates.js.map +1 -1
  206. package/dist/esm/src/compat/BSM.js.map +1 -1
  207. package/dist/esm/src/compat/ECIES.js.map +1 -1
  208. package/dist/esm/src/compat/HD.js.map +1 -1
  209. package/dist/esm/src/compat/Mnemonic.js.map +1 -1
  210. package/dist/esm/src/identity/ContactsManager.js +1 -1
  211. package/dist/esm/src/identity/ContactsManager.js.map +1 -1
  212. package/dist/esm/src/identity/IdentityClient.js.map +1 -1
  213. package/dist/esm/src/kvstore/GlobalKVStore.js +3 -3
  214. package/dist/esm/src/kvstore/GlobalKVStore.js.map +1 -1
  215. package/dist/esm/src/kvstore/LocalKVStore.js.map +1 -1
  216. package/dist/esm/src/kvstore/kvStoreInterpreter.js.map +1 -1
  217. package/dist/esm/src/messages/EncryptedMessage.js +19 -0
  218. package/dist/esm/src/messages/EncryptedMessage.js.map +1 -1
  219. package/dist/esm/src/messages/SignedMessage.js.map +1 -1
  220. package/dist/esm/src/overlay-tools/Historian.js.map +1 -1
  221. package/dist/esm/src/overlay-tools/HostReputationTracker.js.map +1 -1
  222. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  223. package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
  224. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  225. package/dist/esm/src/overlay-tools/withDoubleSpendRetry.js.map +1 -1
  226. package/dist/esm/src/primitives/AESGCM.js +71 -26
  227. package/dist/esm/src/primitives/AESGCM.js.map +1 -1
  228. package/dist/esm/src/primitives/BigNumber.js +28 -54
  229. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  230. package/dist/esm/src/primitives/Curve.js.map +1 -1
  231. package/dist/esm/src/primitives/DRBG.js.map +1 -1
  232. package/dist/esm/src/primitives/ECDSA.js +58 -24
  233. package/dist/esm/src/primitives/ECDSA.js.map +1 -1
  234. package/dist/esm/src/primitives/Hash.js.map +1 -1
  235. package/dist/esm/src/primitives/JacobianPoint.js.map +1 -1
  236. package/dist/esm/src/primitives/K256.js.map +1 -1
  237. package/dist/esm/src/primitives/Mersenne.js.map +1 -1
  238. package/dist/esm/src/primitives/MontgomoryMethod.js.map +1 -1
  239. package/dist/esm/src/primitives/Point.js +61 -4
  240. package/dist/esm/src/primitives/Point.js.map +1 -1
  241. package/dist/esm/src/primitives/Polynomial.js.map +1 -1
  242. package/dist/esm/src/primitives/PrivateKey.js +29 -2
  243. package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
  244. package/dist/esm/src/primitives/PublicKey.js +1 -1
  245. package/dist/esm/src/primitives/PublicKey.js.map +1 -1
  246. package/dist/esm/src/primitives/Random.js.map +1 -1
  247. package/dist/esm/src/primitives/ReaderUint8Array.js +176 -0
  248. package/dist/esm/src/primitives/ReaderUint8Array.js.map +1 -0
  249. package/dist/esm/src/primitives/ReductionContext.js +35 -46
  250. package/dist/esm/src/primitives/ReductionContext.js.map +1 -1
  251. package/dist/esm/src/primitives/Schnorr.js.map +1 -1
  252. package/dist/esm/src/primitives/Secp256r1.js.map +1 -1
  253. package/dist/esm/src/primitives/Signature.js.map +1 -1
  254. package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
  255. package/dist/esm/src/primitives/TransactionSignature.js +115 -10
  256. package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
  257. package/dist/esm/src/primitives/WriterUint8Array.js +169 -0
  258. package/dist/esm/src/primitives/WriterUint8Array.js.map +1 -0
  259. package/dist/esm/src/primitives/hex.js.map +1 -1
  260. package/dist/esm/src/primitives/utils.js +37 -11
  261. package/dist/esm/src/primitives/utils.js.map +1 -1
  262. package/dist/esm/src/registry/RegistryClient.js.map +1 -1
  263. package/dist/esm/src/remittance/CommsLayer.js +2 -0
  264. package/dist/esm/src/remittance/CommsLayer.js.map +1 -0
  265. package/dist/esm/src/remittance/IdentityLayer.js +2 -0
  266. package/dist/esm/src/remittance/IdentityLayer.js.map +1 -0
  267. package/dist/esm/src/remittance/RemittanceManager.js +1254 -0
  268. package/dist/esm/src/remittance/RemittanceManager.js.map +1 -0
  269. package/dist/esm/src/remittance/RemittanceModule.js +2 -0
  270. package/dist/esm/src/remittance/RemittanceModule.js.map +1 -0
  271. package/dist/esm/src/remittance/index.js +7 -0
  272. package/dist/esm/src/remittance/index.js.map +1 -0
  273. package/dist/esm/src/remittance/modules/BasicBRC29.js +227 -0
  274. package/dist/esm/src/remittance/modules/BasicBRC29.js.map +1 -0
  275. package/dist/esm/src/remittance/modules/index.js +2 -0
  276. package/dist/esm/src/remittance/modules/index.js.map +1 -0
  277. package/dist/esm/src/remittance/types.js +19 -0
  278. package/dist/esm/src/remittance/types.js.map +1 -0
  279. package/dist/esm/src/script/OP.js +15 -13
  280. package/dist/esm/src/script/OP.js.map +1 -1
  281. package/dist/esm/src/script/Script.js +80 -5
  282. package/dist/esm/src/script/Script.js.map +1 -1
  283. package/dist/esm/src/script/Spend.js +129 -46
  284. package/dist/esm/src/script/Spend.js.map +1 -1
  285. package/dist/esm/src/script/templates/P2PKH.js.map +1 -1
  286. package/dist/esm/src/script/templates/PushDrop.js +21 -7
  287. package/dist/esm/src/script/templates/PushDrop.js.map +1 -1
  288. package/dist/esm/src/script/templates/RPuzzle.js.map +1 -1
  289. package/dist/esm/src/storage/StorageDownloader.js.map +1 -1
  290. package/dist/esm/src/storage/StorageUploader.js.map +1 -1
  291. package/dist/esm/src/storage/StorageUtils.js.map +1 -1
  292. package/dist/esm/src/totp/totp.js.map +1 -1
  293. package/dist/esm/src/transaction/Beef.js +86 -28
  294. package/dist/esm/src/transaction/Beef.js.map +1 -1
  295. package/dist/esm/src/transaction/BeefParty.js.map +1 -1
  296. package/dist/esm/src/transaction/BeefTx.js +32 -14
  297. package/dist/esm/src/transaction/BeefTx.js.map +1 -1
  298. package/dist/esm/src/transaction/MerklePath.js +26 -7
  299. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  300. package/dist/esm/src/transaction/Transaction.js +239 -28
  301. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  302. package/dist/esm/src/transaction/broadcasters/ARC.js +23 -0
  303. package/dist/esm/src/transaction/broadcasters/ARC.js.map +1 -1
  304. package/dist/esm/src/transaction/broadcasters/Teranode.js.map +1 -1
  305. package/dist/esm/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
  306. package/dist/esm/src/transaction/chaintrackers/BlockHeadersService.js.map +1 -1
  307. package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
  308. package/dist/esm/src/transaction/fee-models/LivePolicy.js.map +1 -1
  309. package/dist/esm/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
  310. package/dist/esm/src/transaction/http/BinaryFetchClient.js.map +1 -1
  311. package/dist/esm/src/transaction/http/DefaultHttpClient.js.map +1 -1
  312. package/dist/esm/src/transaction/http/NodejsHttpClient.js.map +1 -1
  313. package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -1
  314. package/dist/esm/src/wallet/KeyDeriver.js.map +1 -1
  315. package/dist/esm/src/wallet/ProtoWallet.js +1 -1
  316. package/dist/esm/src/wallet/ProtoWallet.js.map +1 -1
  317. package/dist/esm/src/wallet/WalletClient.js.map +1 -1
  318. package/dist/esm/src/wallet/WalletError.js.map +1 -1
  319. package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  320. package/dist/esm/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
  321. package/dist/esm/src/wallet/substrates/ReactNativeWebView.js.map +1 -1
  322. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  323. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  324. package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
  325. package/dist/esm/src/wallet/substrates/utils/toOriginHeader.js.map +1 -1
  326. package/dist/esm/src/wallet/substrates/window.CWI.js.map +1 -1
  327. package/dist/esm/src/wallet/validationHelpers.js +1 -1
  328. package/dist/esm/src/wallet/validationHelpers.js.map +1 -1
  329. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  330. package/dist/types/mod.d.ts +1 -0
  331. package/dist/types/mod.d.ts.map +1 -1
  332. package/dist/types/src/auth/Peer.d.ts +12 -7
  333. package/dist/types/src/auth/Peer.d.ts.map +1 -1
  334. package/dist/types/src/auth/certificates/MasterCertificate.d.ts.map +1 -1
  335. package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
  336. package/dist/types/src/auth/types.d.ts +2 -0
  337. package/dist/types/src/auth/types.d.ts.map +1 -1
  338. package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts.map +1 -1
  339. package/dist/types/src/auth/utils/validateCertificates.d.ts.map +1 -1
  340. package/dist/types/src/compat/BSM.d.ts +1 -1
  341. package/dist/types/src/compat/BSM.d.ts.map +1 -1
  342. package/dist/types/src/messages/EncryptedMessage.d.ts +19 -0
  343. package/dist/types/src/messages/EncryptedMessage.d.ts.map +1 -1
  344. package/dist/types/src/messages/SignedMessage.d.ts.map +1 -1
  345. package/dist/types/src/primitives/AESGCM.d.ts +18 -0
  346. package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
  347. package/dist/types/src/primitives/BigNumber.d.ts +8 -0
  348. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  349. package/dist/types/src/primitives/ECDSA.d.ts +24 -0
  350. package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
  351. package/dist/types/src/primitives/Hash.d.ts +8 -8
  352. package/dist/types/src/primitives/Hash.d.ts.map +1 -1
  353. package/dist/types/src/primitives/Point.d.ts +1 -0
  354. package/dist/types/src/primitives/Point.d.ts.map +1 -1
  355. package/dist/types/src/primitives/PrivateKey.d.ts +27 -0
  356. package/dist/types/src/primitives/PrivateKey.d.ts.map +1 -1
  357. package/dist/types/src/primitives/Random.d.ts.map +1 -1
  358. package/dist/types/src/primitives/ReaderUint8Array.d.ts +32 -0
  359. package/dist/types/src/primitives/ReaderUint8Array.d.ts.map +1 -0
  360. package/dist/types/src/primitives/ReductionContext.d.ts +9 -0
  361. package/dist/types/src/primitives/ReductionContext.d.ts.map +1 -1
  362. package/dist/types/src/primitives/Secp256r1.d.ts.map +1 -1
  363. package/dist/types/src/primitives/TransactionSignature.d.ts +16 -4
  364. package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
  365. package/dist/types/src/primitives/WriterUint8Array.d.ts +54 -0
  366. package/dist/types/src/primitives/WriterUint8Array.d.ts.map +1 -0
  367. package/dist/types/src/primitives/utils.d.ts +19 -6
  368. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  369. package/dist/types/src/remittance/CommsLayer.d.ts +50 -0
  370. package/dist/types/src/remittance/CommsLayer.d.ts.map +1 -0
  371. package/dist/types/src/remittance/IdentityLayer.d.ts +35 -0
  372. package/dist/types/src/remittance/IdentityLayer.d.ts.map +1 -0
  373. package/dist/types/src/remittance/RemittanceManager.d.ts +452 -0
  374. package/dist/types/src/remittance/RemittanceManager.d.ts.map +1 -0
  375. package/dist/types/src/remittance/RemittanceModule.d.ts +106 -0
  376. package/dist/types/src/remittance/RemittanceModule.d.ts.map +1 -0
  377. package/dist/types/src/remittance/index.d.ts +7 -0
  378. package/dist/types/src/remittance/index.d.ts.map +1 -0
  379. package/dist/types/src/remittance/modules/BasicBRC29.d.ts +133 -0
  380. package/dist/types/src/remittance/modules/BasicBRC29.d.ts.map +1 -0
  381. package/dist/types/src/remittance/modules/index.d.ts +2 -0
  382. package/dist/types/src/remittance/modules/index.d.ts.map +1 -0
  383. package/dist/types/src/remittance/types.d.ts +238 -0
  384. package/dist/types/src/remittance/types.d.ts.map +1 -0
  385. package/dist/types/src/script/OP.d.ts +5 -3
  386. package/dist/types/src/script/OP.d.ts.map +1 -1
  387. package/dist/types/src/script/Script.d.ts.map +1 -1
  388. package/dist/types/src/script/Spend.d.ts +7 -0
  389. package/dist/types/src/script/Spend.d.ts.map +1 -1
  390. package/dist/types/src/script/templates/PushDrop.d.ts +3 -4
  391. package/dist/types/src/script/templates/PushDrop.d.ts.map +1 -1
  392. package/dist/types/src/storage/StorageUtils.d.ts.map +1 -1
  393. package/dist/types/src/transaction/Beef.d.ts +26 -9
  394. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  395. package/dist/types/src/transaction/BeefTx.d.ts +13 -6
  396. package/dist/types/src/transaction/BeefTx.d.ts.map +1 -1
  397. package/dist/types/src/transaction/MerklePath.d.ts +16 -3
  398. package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
  399. package/dist/types/src/transaction/Transaction.d.ts +58 -7
  400. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  401. package/dist/types/src/transaction/broadcasters/ARC.d.ts.map +1 -1
  402. package/dist/types/src/transaction/http/BinaryFetchClient.d.ts +0 -2
  403. package/dist/types/src/transaction/http/BinaryFetchClient.d.ts.map +1 -1
  404. package/dist/types/src/wallet/Wallet.interfaces.d.ts +5 -5
  405. package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -1
  406. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  407. package/dist/umd/bundle.js +13 -13
  408. package/dist/umd/bundle.js.map +1 -1
  409. package/docs/index.md +3 -1
  410. package/docs/reference/auth.md +8 -12
  411. package/docs/reference/primitives.md +260 -55
  412. package/docs/reference/remittance.md +2166 -0
  413. package/docs/reference/script.md +12 -4
  414. package/docs/reference/transaction.md +203 -34
  415. package/docs/reference/wallet.md +6 -5
  416. package/docs/remittance-getting-started.md +138 -0
  417. package/mod.ts +1 -0
  418. package/package.json +11 -1
  419. package/src/auth/Peer.ts +196 -85
  420. package/src/auth/__tests/Peer.test.ts +424 -257
  421. package/src/auth/clients/AuthFetch.ts +18 -3
  422. package/src/auth/types.ts +2 -0
  423. package/src/messages/EncryptedMessage.ts +19 -0
  424. package/src/overlay-tools/__tests/SHIPBroadcaster.test.ts +7 -0
  425. package/src/primitives/AESGCM.ts +75 -34
  426. package/src/primitives/BigNumber.ts +27 -31
  427. package/src/primitives/ECDSA.ts +41 -2
  428. package/src/primitives/PrivateKey.ts +27 -0
  429. package/src/primitives/ReaderUint8Array.ts +196 -0
  430. package/src/primitives/ReductionContext.ts +44 -48
  431. package/src/primitives/TransactionSignature.ts +129 -10
  432. package/src/primitives/WriterUint8Array.ts +195 -0
  433. package/src/primitives/__tests/AESGCM.test.ts +31 -0
  434. package/src/primitives/__tests/ECDSA.test.ts +16 -0
  435. package/src/primitives/__tests/ReaderUint8Array.test.ts +317 -0
  436. package/src/primitives/__tests/WriterUint8Array.test.ts +208 -0
  437. package/src/primitives/utils.ts +31 -4
  438. package/src/remittance/CommsLayer.ts +41 -0
  439. package/src/remittance/IdentityLayer.ts +32 -0
  440. package/src/remittance/RemittanceManager.ts +1672 -0
  441. package/src/remittance/RemittanceModule.ts +92 -0
  442. package/src/remittance/__tests/BasicBRC29.test.ts +188 -0
  443. package/src/remittance/__tests/RemittanceManager.test.ts +493 -0
  444. package/src/remittance/__tests/examples.ts +130 -0
  445. package/src/remittance/index.ts +6 -0
  446. package/src/remittance/modules/BasicBRC29.ts +361 -0
  447. package/src/remittance/modules/index.ts +1 -0
  448. package/src/remittance/types.ts +284 -0
  449. package/src/script/OP.ts +15 -13
  450. package/src/script/Script.ts +70 -5
  451. package/src/script/Spend.ts +128 -52
  452. package/src/script/__tests/Chronicle.test.ts +186 -0
  453. package/src/script/__tests/Script.test.ts +39 -6
  454. package/src/script/__tests/Spend.test.ts +1 -1
  455. package/src/script/__tests/SpendValildVectors.test.ts +63 -0
  456. package/src/script/__tests/lrshiftnum.test.ts +185 -0
  457. package/src/script/__tests/sighashTestData.ts +1031 -0
  458. package/src/script/__tests/spend.valid.vectors.ts +9 -16
  459. package/src/script/templates/PushDrop.ts +32 -17
  460. package/src/script/templates/__tests/PushDrop.test.ts +28 -0
  461. package/src/storage/__tests/StorageUploader.test.ts +1 -1
  462. package/src/transaction/Beef.ts +103 -40
  463. package/src/transaction/BeefTx.ts +38 -19
  464. package/src/transaction/MerklePath.ts +30 -9
  465. package/src/transaction/Transaction.ts +277 -38
  466. package/src/transaction/__tests/Beef.test.ts +77 -0
  467. package/src/transaction/__tests/Transaction.test.ts +641 -3
  468. package/src/transaction/broadcasters/ARC.ts +34 -7
  469. package/src/transaction/broadcasters/__tests/ARC.test.ts +98 -0
  470. package/src/wallet/Wallet.interfaces.ts +5 -5
  471. package/dist/cjs/src/storage/__test/StorageDownloader.test.js +0 -171
  472. package/dist/cjs/src/storage/__test/StorageDownloader.test.js.map +0 -1
  473. package/dist/cjs/src/storage/__test/StorageUploader.test.js +0 -163
  474. package/dist/cjs/src/storage/__test/StorageUploader.test.js.map +0 -1
  475. package/dist/cjs/src/storage/__test/StorageUtils.test.js +0 -97
  476. package/dist/cjs/src/storage/__test/StorageUtils.test.js.map +0 -1
  477. package/dist/esm/src/storage/__test/StorageDownloader.test.js +0 -166
  478. package/dist/esm/src/storage/__test/StorageDownloader.test.js.map +0 -1
  479. package/dist/esm/src/storage/__test/StorageUploader.test.js +0 -135
  480. package/dist/esm/src/storage/__test/StorageUploader.test.js.map +0 -1
  481. package/dist/esm/src/storage/__test/StorageUtils.test.js +0 -72
  482. package/dist/esm/src/storage/__test/StorageUtils.test.js.map +0 -1
  483. package/dist/types/src/storage/__test/StorageDownloader.test.d.ts +0 -2
  484. package/dist/types/src/storage/__test/StorageDownloader.test.d.ts.map +0 -1
  485. package/dist/types/src/storage/__test/StorageUploader.test.d.ts +0 -2
  486. package/dist/types/src/storage/__test/StorageUploader.test.d.ts.map +0 -1
  487. package/dist/types/src/storage/__test/StorageUtils.test.d.ts +0 -2
  488. package/dist/types/src/storage/__test/StorageUtils.test.d.ts.map +0 -1
@@ -221,6 +221,42 @@ describe('Peer class mutual authentication and certificate exchange', () => {
221
221
  walletB = new CompletedProtoWallet(bobPrivKey)
222
222
  })
223
223
 
224
+ afterEach(() => {
225
+ // Clean up any pending certificate validation promises to prevent hanging tests
226
+ if (alice != null) {
227
+ const aliceAny = alice as any
228
+ if (aliceAny.certificateValidationPromises != null) {
229
+ aliceAny.certificateValidationPromises.forEach(
230
+ (promiseHandlers: { resolve: () => void, reject: (error: Error) => void }) => {
231
+ promiseHandlers.reject(new Error('Test cleanup'))
232
+ }
233
+ )
234
+ aliceAny.certificateValidationPromises.clear()
235
+ }
236
+ // Clear all listener callbacks to prevent memory leaks
237
+ aliceAny.onGeneralMessageReceivedCallbacks?.clear()
238
+ aliceAny.onCertificatesReceivedCallbacks?.clear()
239
+ aliceAny.onCertificateRequestReceivedCallbacks?.clear()
240
+ aliceAny.onInitialResponseReceivedCallbacks?.clear()
241
+ }
242
+ if (bob != null) {
243
+ const bobAny = bob as any
244
+ if (bobAny.certificateValidationPromises != null) {
245
+ bobAny.certificateValidationPromises.forEach(
246
+ (promiseHandlers: { resolve: () => void, reject: (error: Error) => void }) => {
247
+ promiseHandlers.reject(new Error('Test cleanup'))
248
+ }
249
+ )
250
+ bobAny.certificateValidationPromises.clear()
251
+ }
252
+ // Clear all listener callbacks to prevent memory leaks
253
+ bobAny.onGeneralMessageReceivedCallbacks?.clear()
254
+ bobAny.onCertificatesReceivedCallbacks?.clear()
255
+ bobAny.onCertificateRequestReceivedCallbacks?.clear()
256
+ bobAny.onInitialResponseReceivedCallbacks?.clear()
257
+ }
258
+ })
259
+
224
260
  it('Neither Alice nor Bob request certificates, mutual authentication completes successfully', async () => {
225
261
  setupPeers(
226
262
  false,
@@ -328,6 +364,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
328
364
  )
329
365
 
330
366
  const { bobReceivedCertificates } = setupPeers(false, true)
367
+
331
368
  await mockGetVerifiableCertificates(
332
369
  aliceVerifiableCertificate,
333
370
  undefined,
@@ -335,32 +372,11 @@ describe('Peer class mutual authentication and certificate exchange', () => {
335
372
  bobPubKey
336
373
  )
337
374
 
338
- const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
339
- bob.listenForGeneralMessages((senderPublicKey, payload) => {
340
- // Wrap async logic in an IIFE so the callback remains synchronous.
341
- (async () => {
342
- await bobReceivedCertificates
343
-
344
- if (certificatesReceivedByBob !== undefined && certificatesReceivedByBob.length > 0) {
345
- // Use a for...of loop instead of forEach with an async callback.
346
- for (const cert of certificatesReceivedByBob) {
347
- // Decrypt to ensure it has the correct fields.
348
- // const decryptedFields = await cert.decryptFields(walletB)
349
- if (cert.certifier !== 'bob') {
350
- // console.log('Bob accepted the message:', Utils.toUTF8(payload))
351
- // console.log('Decrypted fields:', decryptedFields)
352
- }
353
- }
354
- }
355
- resolve()
356
- })().catch((e) => {
357
- // console.error(e)
358
- })
359
- })
360
- })
375
+ // Initiate handshake ONLY
376
+ await alice.getAuthenticatedSession(bobPubKey)
361
377
 
362
- await alice.toPeer(Utils.toArray('Hello Bob!'))
363
- await bobReceivedGeneralMessage
378
+ // Wait for Bob to receive Alice's certificates
379
+ await bobReceivedCertificates
364
380
 
365
381
  expect(certificatesReceivedByAlice).toEqual([])
366
382
  expect(certificatesReceivedByBob).toEqual([aliceVerifiableCertificate])
@@ -418,16 +434,10 @@ describe('Peer class mutual authentication and certificate exchange', () => {
418
434
  })
419
435
 
420
436
  it('Alice requests Bob to present his library card before lending him a book', async () => {
421
- const alicePubKey = (await walletA.getPublicKey({ identityKey: true }))
422
- .publicKey
423
- const bobPubKey = (await walletB.getPublicKey({ identityKey: true }))
424
- .publicKey
437
+ const alicePubKey = (await walletA.getPublicKey({ identityKey: true })).publicKey
438
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
425
439
 
426
- // Bob's certificate includes his library card number
427
- const bobMasterCertificate = await createMasterCertificate(
428
- walletB,
429
- bobFields
430
- )
440
+ const bobMasterCertificate = await createMasterCertificate(walletB, bobFields)
431
441
  const bobVerifiableCertificate = await createVerifiableCertificate(
432
442
  bobMasterCertificate,
433
443
  walletB,
@@ -435,7 +445,6 @@ describe('Peer class mutual authentication and certificate exchange', () => {
435
445
  ['libraryCardNumber']
436
446
  )
437
447
 
438
- // Alice requires Bob to present his library card number
439
448
  const aliceCertificatesToRequest = {
440
449
  certifiers: [certifierPublicKey],
441
450
  types: { [certificateType]: ['libraryCardNumber'] }
@@ -444,6 +453,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
444
453
  const { aliceReceivedCertificates } = setupPeers(true, false, {
445
454
  aliceCertsToRequest: aliceCertificatesToRequest
446
455
  })
456
+
447
457
  await mockGetVerifiableCertificates(
448
458
  undefined,
449
459
  bobVerifiableCertificate,
@@ -453,39 +463,19 @@ describe('Peer class mutual authentication and certificate exchange', () => {
453
463
 
454
464
  const aliceAcceptedLibraryCard = jest.fn()
455
465
 
456
- alice.listenForCertificatesReceived((senderPublicKey, certificates) => {
457
- (async () => {
458
- for (const cert of certificates) {
459
- // Decrypt Bob's certificate fields
460
- const decryptedFields = await cert.decryptFields(walletA)
461
-
462
- // Check and use the decrypted fields
463
- if (
464
- Object.keys(decryptedFields).length !== 0 &&
465
- typeof decryptedFields.libraryCardNumber !== 'undefined'
466
- ) {
467
- // console.log(
468
- // `Alice received Bob's library card number: ${decryptedFields.libraryCardNumber}`
469
- // )
470
- aliceAcceptedLibraryCard()
471
- }
466
+ alice.listenForCertificatesReceived(async (_sender, certificates) => {
467
+ for (const cert of certificates) {
468
+ const decrypted = await cert.decryptFields(walletA)
469
+ if (decrypted.libraryCardNumber !== undefined) {
470
+ aliceAcceptedLibraryCard()
472
471
  }
473
- })().catch(e => { console.error(e) })
472
+ }
474
473
  })
475
474
 
476
- const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
477
- bob.listenForGeneralMessages((senderPublicKey, payload) => {
478
- // console.log('Bob received message from Alice:', Utils.toUTF8(payload))
479
- resolve()
480
- })
481
- })
475
+ // 🔑 Correct trigger: certificate request, NOT general message
476
+ await alice.requestCertificates(aliceCertificatesToRequest, bobPubKey)
482
477
 
483
- // Alice sends a message to Bob requesting his library card before lending him a book
484
- await alice.toPeer(
485
- Utils.toArray('Please present your library card to borrow a book.')
486
- )
487
478
  await aliceReceivedCertificates
488
- await bobReceivedGeneralMessage
489
479
 
490
480
  expect(aliceAcceptedLibraryCard).toHaveBeenCalled()
491
481
  expect(certificatesReceivedByAlice).toEqual([bobVerifiableCertificate])
@@ -501,6 +491,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
501
491
  const aliceMasterCertificate = await createMasterCertificate(walletA, {
502
492
  name: 'Alice'
503
493
  })
494
+
504
495
  const aliceVerifiableCertificate = await createVerifiableCertificate(
505
496
  aliceMasterCertificate,
506
497
  walletA,
@@ -509,6 +500,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
509
500
  )
510
501
 
511
502
  const { bobReceivedCertificates } = setupPeers(false, true)
503
+
512
504
  await mockGetVerifiableCertificates(
513
505
  aliceVerifiableCertificate,
514
506
  undefined,
@@ -516,45 +508,23 @@ describe('Peer class mutual authentication and certificate exchange', () => {
516
508
  bobPubKey
517
509
  )
518
510
 
519
- const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
520
- bob.listenForGeneralMessages((senderPublicKey, payload) => {
521
- (async () => {
522
- await bobReceivedCertificates
523
- // console.log('Bob received message:', Utils.toUTF8(payload))
524
-
525
- // Bob requests additional certificates after initial communication
526
- await bob.requestCertificates(certificatesToRequest, senderPublicKey)
527
- resolve()
528
- })().catch(e => { console.error(e) })
529
- })
530
- })
531
-
532
- // Initial communication from Alice
533
- await alice.toPeer(Utils.toArray('Hello Bob!'))
534
- await bobReceivedGeneralMessage
511
+ // ---- Initial communication = handshake + initial cert exchange
512
+ await alice.getAuthenticatedSession(bobPubKey)
513
+ await bobReceivedCertificates
535
514
 
536
- // Listen for certificates received from the additional request
515
+ // ---- Bob requests additional certificates AFTER validation
537
516
  const bobReceivedAdditionalCertificates = new Promise<void>((resolve) => {
538
- bob.listenForCertificatesReceived((senderPublicKey, certificates) => {
539
- (async () => {
540
- if (certificates.length > 0) {
541
- // Decrypt to confirm
542
- for (const cert of certificates) {
543
- const decrypted = await cert.decryptFields(walletB)
544
- // console.log(
545
- // 'Bob received additional certificates from Alice:',
546
- // cert
547
- // )
548
- // console.log('Decrypted fields:', decrypted)
549
- }
550
- resolve()
517
+ bob.listenForCertificatesReceived(async (senderPublicKey, certificates) => {
518
+ if (certificates.length > 0) {
519
+ for (const cert of certificates) {
520
+ await cert.decryptFields(walletB)
551
521
  }
552
- })().catch((error) => {
553
- console.error(error)
554
- })
522
+ resolve()
523
+ }
555
524
  })
556
525
  })
557
526
 
527
+ await bob.requestCertificates(certificatesToRequest, alicePubKey)
558
528
  await bobReceivedAdditionalCertificates
559
529
 
560
530
  expect(certificatesReceivedByBob).toEqual([aliceVerifiableCertificate])
@@ -566,11 +536,11 @@ describe('Peer class mutual authentication and certificate exchange', () => {
566
536
  const bobPubKey = (await walletB.getPublicKey({ identityKey: true }))
567
537
  .publicKey
568
538
 
569
- // Alice's certificate includes her membership status
570
539
  const aliceMasterCertificate = await createMasterCertificate(walletA, {
571
540
  ...aliceFields,
572
541
  membershipStatus: 'Gold'
573
542
  })
543
+
574
544
  const aliceVerifiableCertificate = await createVerifiableCertificate(
575
545
  aliceMasterCertificate,
576
546
  walletA,
@@ -578,7 +548,6 @@ describe('Peer class mutual authentication and certificate exchange', () => {
578
548
  ['membershipStatus']
579
549
  )
580
550
 
581
- // Bob requires Alice to present her membership status
582
551
  const bobCertificatesToRequest = {
583
552
  certifiers: [certifierPublicKey],
584
553
  types: { [certificateType]: ['membershipStatus'] }
@@ -587,6 +556,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
587
556
  const { bobReceivedCertificates } = setupPeers(false, true, {
588
557
  bobCertsToRequest: bobCertificatesToRequest
589
558
  })
559
+
590
560
  await mockGetVerifiableCertificates(
591
561
  aliceVerifiableCertificate,
592
562
  undefined,
@@ -597,40 +567,26 @@ describe('Peer class mutual authentication and certificate exchange', () => {
597
567
  const bobAcceptedMembershipStatus = jest.fn()
598
568
 
599
569
  const waitForCerts = new Promise<void>((resolve) => {
600
- bob.listenForCertificatesReceived((senderPublicKey, certificates) => {
601
- (async () => {
602
- for (const cert of certificates) {
603
- // Decrypt Alice's certificate fields
604
- const decryptedFields = await cert.decryptFields(walletB)
605
- if (typeof decryptedFields.membershipStatus !== 'undefined') {
606
- // console.log(
607
- // `Bob received Alice's membership status: ${decryptedFields.membershipStatus}`
608
- // )
609
- bobAcceptedMembershipStatus()
610
- resolve()
611
- }
570
+ bob.listenForCertificatesReceived(async (_, certificates) => {
571
+ for (const cert of certificates) {
572
+ const decryptedFields = await cert.decryptFields(walletB)
573
+ if (decryptedFields.membershipStatus === 'Gold') {
574
+ bobAcceptedMembershipStatus()
575
+ resolve()
612
576
  }
613
- })().catch((error) => {
614
- console.error('Error processing certificates:', error)
615
- })
616
- }
617
- )
618
- })
619
-
620
- const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
621
- bob.listenForGeneralMessages((senderPublicKey, payload) => {
622
- // console.log('Bob received message from Alice:', Utils.toUTF8(payload))
623
- resolve()
577
+ }
624
578
  })
625
579
  })
626
580
 
627
- // Alice sends a message to Bob requesting access to premium content
581
+ // ---- INITIAL COMMUNICATION = handshake + certificate exchange
582
+ await alice.getAuthenticatedSession(bobPubKey)
583
+ await bobReceivedCertificates
584
+ await waitForCerts
585
+
586
+ // ---- OPTIONAL: now Alice can request premium content
628
587
  await alice.toPeer(
629
588
  Utils.toArray('I would like to access the premium content.')
630
589
  )
631
- await bobReceivedCertificates
632
- await bobReceivedGeneralMessage
633
- await waitForCerts
634
590
 
635
591
  expect(bobAcceptedMembershipStatus).toHaveBeenCalled()
636
592
  expect(certificatesReceivedByBob).toEqual([aliceVerifiableCertificate])
@@ -638,12 +594,9 @@ describe('Peer class mutual authentication and certificate exchange', () => {
638
594
  }, 15000)
639
595
 
640
596
  it("Both peers require each other's driver's license before carpooling", async () => {
641
- const alicePubKey = (await walletA.getPublicKey({ identityKey: true }))
642
- .publicKey
643
- const bobPubKey = (await walletB.getPublicKey({ identityKey: true }))
644
- .publicKey
597
+ const alicePubKey = (await walletA.getPublicKey({ identityKey: true })).publicKey
598
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
645
599
 
646
- // Both Alice and Bob have driver's license certificates
647
600
  const aliceMasterCertificate = await createMasterCertificate(walletA, {
648
601
  ...aliceFields,
649
602
  driversLicenseNumber: 'DLA123456'
@@ -666,7 +619,6 @@ describe('Peer class mutual authentication and certificate exchange', () => {
666
619
  ['driversLicenseNumber']
667
620
  )
668
621
 
669
- // Both peers require the driver's license number
670
622
  const certificatesToRequestDriversLicense = {
671
623
  certifiers: [certifierPublicKey],
672
624
  types: { [certificateType]: ['driversLicenseNumber'] }
@@ -680,6 +632,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
680
632
  bobCertsToRequest: certificatesToRequestDriversLicense
681
633
  }
682
634
  )
635
+
683
636
  await mockGetVerifiableCertificates(
684
637
  aliceVerifiableCertificate,
685
638
  bobVerifiableCertificate,
@@ -687,91 +640,31 @@ describe('Peer class mutual authentication and certificate exchange', () => {
687
640
  bobPubKey
688
641
  )
689
642
 
690
- const aliceAcceptedBobDL = jest.fn()
691
- const bobAcceptedAliceDL = jest.fn()
692
-
693
- const waitForAliceToAcceptBobDL = new Promise<void>((resolve) => {
694
- alice.listenForCertificatesReceived((senderPublicKey, certificates) => {
695
- (async () => {
696
- for (const cert of certificates) {
697
- const decryptedFields = await cert.decryptFields(walletA)
698
- if (decryptedFields.driversLicenseNumber !== undefined) {
699
- // console.log(
700
- // `Alice received Bob's driver's license number: ${decryptedFields.driversLicenseNumber}`
701
- // )
702
- aliceAcceptedBobDL()
703
- resolve()
704
- }
705
- }
706
- })().catch(e => { })
707
- }
708
- )
709
- })
710
-
711
- const waitForBobToAcceptAliceDL = new Promise<void>((resolve) => {
712
- bob.listenForCertificatesReceived((senderPublicKey, certificates) => {
713
- (async () => {
714
- for (const cert of certificates) {
715
- const decryptedFields = await cert.decryptFields(walletB)
716
- if (decryptedFields.driversLicenseNumber !== undefined) {
717
- // console.log(
718
- // `Bob received Alice's driver's license number: ${decryptedFields.driversLicenseNumber}`
719
- // )
720
- bobAcceptedAliceDL()
721
- resolve()
722
- }
723
- }
724
- })().catch(e => { })
725
- }
726
- )
727
- })
728
-
729
- const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
730
- bob.listenForGeneralMessages((senderPublicKey, payload) => {
731
- (async () => {
732
- // console.log('Bob received message from Alice:', Utils.toUTF8(payload))
733
- await bob.toPeer(
734
- Utils.toArray('Looking forward to carpooling!'),
735
- senderPublicKey
736
- )
737
- resolve()
738
- })().catch(e => { })
739
- })
740
- })
741
-
742
- const aliceReceivedGeneralMessage = new Promise<void>((resolve) => {
743
- alice.listenForGeneralMessages((senderPublicKey, payload) => {
744
- // console.log('Alice received message from Bob:', Utils.toUTF8(payload))
745
- resolve()
746
- })
747
- })
748
-
749
- // Alice initiates the conversation
750
- await alice.toPeer(
751
- Utils.toArray("Please share your driver's license number for carpooling.")
752
- )
643
+ // 🔑 Step 1: Alice requests Bob's cert
644
+ await alice.requestCertificates(certificatesToRequestDriversLicense, bobPubKey)
753
645
  await aliceReceivedCertificates
754
- await bobReceivedCertificates
755
- await bobReceivedGeneralMessage
756
- await aliceReceivedGeneralMessage
757
646
 
758
- // Wait for both sides to fully accept each other's certificate
759
- await waitForAliceToAcceptBobDL
760
- await waitForBobToAcceptAliceDL
647
+ // 🔑 Step 2: Bob requests Alice's cert
648
+ await bob.requestCertificates(certificatesToRequestDriversLicense, alicePubKey)
649
+ await bobReceivedCertificates
761
650
 
762
- expect(aliceAcceptedBobDL).toHaveBeenCalled()
763
- expect(bobAcceptedAliceDL).toHaveBeenCalled()
764
651
  expect(certificatesReceivedByAlice).toEqual([bobVerifiableCertificate])
765
652
  expect(certificatesReceivedByBob).toEqual([aliceVerifiableCertificate])
653
+
654
+ // 🔓 Step 3: NOW general messages are allowed
655
+ const bobReceivedMessage = new Promise<void>((resolve) => {
656
+ bob.listenForGeneralMessages(() => resolve())
657
+ })
658
+
659
+ await alice.toPeer(Utils.toArray('Ready to carpool!'), bobPubKey)
660
+ await bobReceivedMessage
766
661
  }, 20000)
767
662
 
768
663
  it('Peers accept partial certificates if at least one required field is present', async () => {
769
- const alicePubKey = (await walletA.getPublicKey({ identityKey: true }))
770
- .publicKey
771
- const bobPubKey = (await walletB.getPublicKey({ identityKey: true }))
772
- .publicKey
664
+ const alicePubKey = (await walletA.getPublicKey({ identityKey: true })).publicKey
665
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
773
666
 
774
- // Alice's certificate contains 'name' and 'email'; Bob's contains only 'email'
667
+ // Alice has name+email, Bob has only email
775
668
  const aliceMasterCertificate = await createMasterCertificate(walletA, {
776
669
  name: 'Alice',
777
670
  email: 'alice@example.com'
@@ -806,6 +699,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
806
699
  bobCertsToRequest: partialCertificatesToRequest
807
700
  }
808
701
  )
702
+
809
703
  await mockGetVerifiableCertificates(
810
704
  aliceVerifiableCertificate,
811
705
  bobVerifiableCertificate,
@@ -813,63 +707,36 @@ describe('Peer class mutual authentication and certificate exchange', () => {
813
707
  bobPubKey
814
708
  )
815
709
 
816
- const aliceAcceptedPartialCert = jest.fn()
817
- const bobAcceptedPartialCert = jest.fn()
818
-
819
- const waitForAlicePartialCert = new Promise<void>((resolve) => {
820
- alice.listenForCertificatesReceived((senderPublicKey, certificates) => {
821
- (async () => {
822
- for (const cert of certificates) {
823
- const decryptedFields = await cert.decryptFields(walletA)
824
- if (decryptedFields.email !== undefined || decryptedFields.name !== undefined) {
825
- // console.log(
826
- // `Alice received Bob's certificate with fields: ${Object.keys(decryptedFields).join(', ')}`
827
- // )
828
- aliceAcceptedPartialCert()
829
- resolve()
830
- }
831
- }
832
- })().catch(e => { })
833
- })
834
- })
835
-
836
- const waitForBobPartialCert = new Promise<void>((resolve) => {
837
- bob.listenForCertificatesReceived((senderPublicKey, certificates) => {
838
- (async () => {
839
- for (const cert of certificates) {
840
- const decryptedFields = await cert.decryptFields(walletB)
841
- if (decryptedFields.email !== undefined || decryptedFields.name !== undefined) {
842
- // console.log(
843
- // `Bob received Alice's certificate with fields: ${Object.keys(decryptedFields).join(', ')}`
844
- // )
845
- bobAcceptedPartialCert()
846
- resolve()
847
- }
848
- }
849
- })().catch(e => { })
850
- })
851
- })
852
-
853
- const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
854
- bob.listenForGeneralMessages((senderPublicKey, payload) => {
855
- // console.log('Bob received message:', Utils.toUTF8(payload))
856
- resolve()
857
- })
858
- })
710
+ // --- Exchange certs explicitly (no general messages yet) ---
711
+ await alice.requestCertificates(partialCertificatesToRequest, bobPubKey)
712
+ await bob.requestCertificates(partialCertificatesToRequest, alicePubKey)
859
713
 
860
- await alice.toPeer(Utils.toArray('Hello Bob!'))
861
714
  await aliceReceivedCertificates
862
715
  await bobReceivedCertificates
863
- await bobReceivedGeneralMessage
864
716
 
865
- // Wait for both sides to fully accept the partial cert
866
- await waitForAlicePartialCert
867
- await waitForBobPartialCert
717
+ // --- Validate "partial" acceptance by decrypting on each side ---
718
+ const aliceDecrypted = await certificatesReceivedByAlice![0].decryptFields(walletA)
719
+ const bobDecrypted = await certificatesReceivedByBob![0].decryptFields(walletB)
720
+
721
+ // Alice received Bob's cert which only has email, but request was name+email
722
+ expect(aliceDecrypted.email).toBeDefined()
723
+ // (Bob did not reveal name, so it may be undefined)
724
+ expect(aliceDecrypted.name).toBeUndefined()
725
+
726
+ // Bob received Alice's cert which has both name+email
727
+ expect(bobDecrypted.email).toBeDefined()
728
+ expect(bobDecrypted.name).toBeDefined()
868
729
 
869
- expect(aliceAcceptedPartialCert).toHaveBeenCalled()
870
- expect(bobAcceptedPartialCert).toHaveBeenCalled()
871
730
  expect(certificatesReceivedByAlice).toEqual([bobVerifiableCertificate])
872
731
  expect(certificatesReceivedByBob).toEqual([aliceVerifiableCertificate])
732
+
733
+ // --- Optional: now general messages should work (since validation happened) ---
734
+ const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
735
+ bob.listenForGeneralMessages(() => resolve())
736
+ })
737
+
738
+ await alice.toPeer(Utils.toArray('Hello Bob!'), bobPubKey)
739
+ await bobReceivedGeneralMessage
873
740
  }, 20000)
874
741
 
875
742
  describe('Transport Error Handling', () => {
@@ -1056,4 +923,304 @@ describe('Peer class mutual authentication and certificate exchange', () => {
1056
923
  }
1057
924
  }, 15000)
1058
925
  })
926
+
927
+ describe('Certificate gating for general messages', () => {
928
+ it('rejects incoming general messages before certificate validation', async () => {
929
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
930
+
931
+ setupPeers(false, true) // Bob requires certs
932
+
933
+ // Prevent Alice from auto-sending certificate response
934
+ // This keeps Bob in "certs required but not validated" state
935
+ alice.listenForCertificatesRequested(() => {
936
+ // Intentionally do nothing (no auto-response)
937
+ })
938
+
939
+ let received = false
940
+ bob.listenForGeneralMessages(() => {
941
+ received = true
942
+ })
943
+
944
+ // Send message — Bob will wait for certificates that never arrive
945
+ try {
946
+ await alice.toPeer(Utils.toArray('Hello Bob!'), bobPubKey)
947
+ } catch {
948
+ // swallow — error is expected but not part of assertion
949
+ }
950
+
951
+ // Allow transport handlers to run
952
+ await new Promise(r => setTimeout(r, 50))
953
+
954
+ // Message must NOT be delivered since certificates haven't been validated
955
+ expect(received).toBe(false)
956
+ })
957
+
958
+ it('blocks outgoing messages until certificates are validated', async () => {
959
+ setupPeers(true, false) // Alice requires certs from Bob
960
+
961
+ // Prevent Bob from auto-supplying certificates during the handshake.
962
+ // This keeps Alice in "certs required but not validated" state.
963
+ bob.listenForCertificatesRequested(() => {
964
+ // Intentionally do nothing (no auto-response)
965
+ })
966
+
967
+ await expect(
968
+ alice.toPeer(Utils.toArray('Hello Bob!'))
969
+ ).rejects.toThrow('certificate validation')
970
+ })
971
+
972
+ it('allows general messages after certificate validation completes', async () => {
973
+ const alicePubKey = (await walletA.getPublicKey({ identityKey: true })).publicKey
974
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
975
+
976
+ const bobMasterCert = await createMasterCertificate(walletB, { name: 'Bob' })
977
+ const bobCert = await createVerifiableCertificate(
978
+ bobMasterCert,
979
+ walletB,
980
+ alicePubKey,
981
+ ['name']
982
+ )
983
+
984
+ // Alice requires certs from Bob
985
+ const { aliceReceivedCertificates } = setupPeers(true, false)
986
+
987
+ // Bob will provide his cert to Alice when asked
988
+ await mockGetVerifiableCertificates(
989
+ undefined,
990
+ bobCert,
991
+ alicePubKey,
992
+ bobPubKey
993
+ )
994
+
995
+ // Trigger handshake + cert exchange WITHOUT sending a general message
996
+ await alice.toPeer(Utils.toArray('handshake'), bobPubKey)
997
+
998
+ // Wait until Alice has validated Bob's certificate
999
+ await aliceReceivedCertificates
1000
+
1001
+ // Now general messages must be allowed
1002
+ const received = new Promise<void>((resolve) => {
1003
+ bob.listenForGeneralMessages(() => resolve())
1004
+ })
1005
+
1006
+ await alice.toPeer(Utils.toArray('Hello Bob!'), bobPubKey)
1007
+ await received
1008
+ })
1009
+
1010
+ it('times out waiting for certificate validation after 30 seconds', async () => {
1011
+ jest.useFakeTimers()
1012
+
1013
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
1014
+
1015
+ setupPeers(false, true) // Bob requires certs
1016
+
1017
+ // Prevent Alice from auto-sending certificate response
1018
+ alice.listenForCertificatesRequested(() => {
1019
+ // Intentionally do nothing (no auto-response)
1020
+ })
1021
+
1022
+ // Send message - this will cause Bob to wait for certificates
1023
+ const messagePromise = alice.toPeer(Utils.toArray('Hello Bob!'), bobPubKey)
1024
+
1025
+ // Allow the handshake to complete but not certificate validation
1026
+ await jest.advanceTimersByTimeAsync(100)
1027
+
1028
+ // Advance time past the 30 second timeout
1029
+ await jest.advanceTimersByTimeAsync(30000)
1030
+
1031
+ // The message should eventually fail with timeout error
1032
+ // Note: The error may be caught internally, so we just verify no message was delivered
1033
+ try {
1034
+ await messagePromise
1035
+ } catch {
1036
+ // Expected - timeout or other error
1037
+ }
1038
+
1039
+ jest.useRealTimers()
1040
+ }, 35000)
1041
+
1042
+ it('resolves certificate validation promise when certificates arrive mid-wait', async () => {
1043
+ const alicePubKey = (await walletA.getPublicKey({ identityKey: true })).publicKey
1044
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
1045
+
1046
+ const aliceMasterCert = await createMasterCertificate(walletA, aliceFields)
1047
+ const aliceCert = await createVerifiableCertificate(
1048
+ aliceMasterCert,
1049
+ walletA,
1050
+ bobPubKey,
1051
+ ['name']
1052
+ )
1053
+
1054
+ setupPeers(false, true) // Bob requires certs from Alice
1055
+
1056
+ // Set up delayed certificate response from Alice
1057
+ let certificateRequestReceived = false
1058
+ let sendCertificates: (() => Promise<void>) | undefined
1059
+
1060
+ alice.listenForCertificatesRequested((peerIdentityKey) => {
1061
+ certificateRequestReceived = true
1062
+ // Store the function to send certificates later
1063
+ sendCertificates = async () => {
1064
+ await alice.sendCertificateResponse(peerIdentityKey, [aliceCert])
1065
+ }
1066
+ })
1067
+
1068
+ let messageReceived = false
1069
+ bob.listenForGeneralMessages(() => {
1070
+ messageReceived = true
1071
+ })
1072
+
1073
+ // Start sending message - Bob will wait for certificates
1074
+ const messagePromise = alice.toPeer(Utils.toArray('Hello Bob!'), bobPubKey)
1075
+
1076
+ // Wait a bit for the handshake to progress
1077
+ await new Promise(r => setTimeout(r, 50))
1078
+
1079
+ // Verify certificate request was received
1080
+ expect(certificateRequestReceived).toBe(true)
1081
+
1082
+ // Now send the certificates - this should resolve Bob's waiting promise
1083
+ if (sendCertificates != null) {
1084
+ await sendCertificates()
1085
+ }
1086
+
1087
+ // Wait for message delivery
1088
+ await messagePromise
1089
+
1090
+ // Allow callbacks to run
1091
+ await new Promise(r => setTimeout(r, 50))
1092
+
1093
+ // Message should now be delivered
1094
+ expect(messageReceived).toBe(true)
1095
+ })
1096
+
1097
+ it('cleans up timeout when certificate validation promise resolves', async () => {
1098
+ const alicePubKey = (await walletA.getPublicKey({ identityKey: true })).publicKey
1099
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
1100
+
1101
+ const aliceMasterCert = await createMasterCertificate(walletA, aliceFields)
1102
+ const aliceCert = await createVerifiableCertificate(
1103
+ aliceMasterCert,
1104
+ walletA,
1105
+ bobPubKey,
1106
+ ['name']
1107
+ )
1108
+
1109
+ setupPeers(false, true) // Bob requires certs from Alice
1110
+
1111
+ // Mock to provide certificates
1112
+ await mockGetVerifiableCertificates(
1113
+ aliceCert,
1114
+ undefined,
1115
+ alicePubKey,
1116
+ bobPubKey
1117
+ )
1118
+
1119
+ const received = new Promise<void>((resolve) => {
1120
+ bob.listenForGeneralMessages(() => resolve())
1121
+ })
1122
+
1123
+ // Send message - certificates will be provided automatically
1124
+ await alice.toPeer(Utils.toArray('Hello Bob!'), bobPubKey)
1125
+
1126
+ // Wait for message to be received
1127
+ await received
1128
+
1129
+ // If we get here without hanging, the timeout was properly cleaned up
1130
+ // (otherwise the test would hang waiting for the 30s timeout)
1131
+ })
1132
+
1133
+ it('throws error when session nonce is null during certificate validation wait', async () => {
1134
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
1135
+
1136
+ setupPeers(false, true) // Bob requires certs
1137
+
1138
+ // Prevent Alice from auto-sending certificate response
1139
+ alice.listenForCertificatesRequested(() => {
1140
+ // Intentionally do nothing
1141
+ })
1142
+
1143
+ // First, let the handshake complete normally
1144
+ // Send a message to establish the session
1145
+ try {
1146
+ await alice.toPeer(Utils.toArray('Initial'), bobPubKey)
1147
+ } catch {
1148
+ // Ignore - handshake may fail since we're blocking certs
1149
+ }
1150
+
1151
+ // Wait for handshake to progress
1152
+ await new Promise(r => setTimeout(r, 50))
1153
+
1154
+ // Now spy on bob's sessionManager.getSession to return session without sessionNonce
1155
+ // This simulates a corrupted session state
1156
+ const originalGetSession = bob.sessionManager.getSession.bind(bob.sessionManager)
1157
+ jest.spyOn(bob.sessionManager, 'getSession').mockImplementation((nonce: string) => {
1158
+ const session = originalGetSession(nonce)
1159
+ if (session != null) {
1160
+ // Return a session with undefined sessionNonce but requiring certificates
1161
+ return {
1162
+ ...session,
1163
+ sessionNonce: undefined,
1164
+ certificatesRequired: true,
1165
+ certificatesValidated: false
1166
+ }
1167
+ }
1168
+ return session
1169
+ })
1170
+
1171
+ // Send another message - this should trigger the null session nonce error path
1172
+ try {
1173
+ await alice.toPeer(Utils.toArray('Hello Bob!'), bobPubKey)
1174
+ } catch {
1175
+ // Error is expected - either from null nonce check or other validation
1176
+ }
1177
+
1178
+ // Allow transport handlers to run
1179
+ await new Promise(r => setTimeout(r, 50))
1180
+
1181
+ // Restore the original implementation
1182
+ jest.restoreAllMocks()
1183
+ })
1184
+
1185
+ it('handles reject callback in certificate validation promise', async () => {
1186
+ const bobPubKey = (await walletB.getPublicKey({ identityKey: true })).publicKey
1187
+
1188
+ setupPeers(false, true) // Bob requires certs
1189
+
1190
+ // Prevent Alice from auto-sending certificate response
1191
+ alice.listenForCertificatesRequested(() => {
1192
+ // Intentionally do nothing
1193
+ })
1194
+
1195
+ let messageReceived = false
1196
+ bob.listenForGeneralMessages(() => {
1197
+ messageReceived = true
1198
+ })
1199
+
1200
+ // Access the private certificateValidationPromises map
1201
+ const bobAny = bob as any
1202
+
1203
+ // Send message - Bob will wait for certificates
1204
+ alice.toPeer(Utils.toArray('Hello Bob!'), bobPubKey).catch(() => {
1205
+ // Ignore errors from Alice's side
1206
+ })
1207
+
1208
+ // Wait for the handshake to progress and promise to be registered
1209
+ await new Promise(r => setTimeout(r, 100))
1210
+
1211
+ // Find and call the reject function on the stored promise
1212
+ const promises = bobAny.certificateValidationPromises as Map<string, { resolve: () => void, reject: (error: Error) => void }>
1213
+ if (promises.size > 0) {
1214
+ const [, promiseHandlers] = [...promises.entries()][0]
1215
+ // Call reject with an error - this covers lines 918-919
1216
+ promiseHandlers.reject(new Error('Test rejection'))
1217
+ }
1218
+
1219
+ // Allow time for the rejection to be processed
1220
+ await new Promise(r => setTimeout(r, 50))
1221
+
1222
+ // Message should NOT be delivered because the promise was rejected
1223
+ expect(messageReceived).toBe(false)
1224
+ })
1225
+ })
1059
1226
  })