@bsv/sdk 2.1.0 → 2.1.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 (383) hide show
  1. package/README.md +7 -7
  2. package/dist/cjs/package.json +1 -1
  3. package/dist/cjs/src/auth/Peer.js +8 -13
  4. package/dist/cjs/src/auth/Peer.js.map +1 -1
  5. package/dist/cjs/src/auth/SessionManager.js +4 -7
  6. package/dist/cjs/src/auth/SessionManager.js.map +1 -1
  7. package/dist/cjs/src/auth/certificates/MasterCertificate.js +1 -1
  8. package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
  9. package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js +1 -1
  10. package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
  11. package/dist/cjs/src/auth/clients/AuthFetch.js +32 -32
  12. package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
  13. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +4 -4
  14. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  15. package/dist/cjs/src/compat/ECIES.js +29 -34
  16. package/dist/cjs/src/compat/ECIES.js.map +1 -1
  17. package/dist/cjs/src/compat/HD.js +9 -4
  18. package/dist/cjs/src/compat/HD.js.map +1 -1
  19. package/dist/cjs/src/compat/Mnemonic.js +12 -12
  20. package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
  21. package/dist/cjs/src/identity/ContactsManager.js +172 -232
  22. package/dist/cjs/src/identity/ContactsManager.js.map +1 -1
  23. package/dist/cjs/src/identity/IdentityClient.js +122 -55
  24. package/dist/cjs/src/identity/IdentityClient.js.map +1 -1
  25. package/dist/cjs/src/kvstore/GlobalKVStore.js +30 -31
  26. package/dist/cjs/src/kvstore/GlobalKVStore.js.map +1 -1
  27. package/dist/cjs/src/kvstore/LocalKVStore.js +9 -9
  28. package/dist/cjs/src/kvstore/LocalKVStore.js.map +1 -1
  29. package/dist/cjs/src/kvstore/kvStoreInterpreter.js +2 -2
  30. package/dist/cjs/src/kvstore/kvStoreInterpreter.js.map +1 -1
  31. package/dist/cjs/src/messages/SignedMessage.js +1 -1
  32. package/dist/cjs/src/messages/SignedMessage.js.map +1 -1
  33. package/dist/cjs/src/overlay-tools/Historian.js +1 -1
  34. package/dist/cjs/src/overlay-tools/Historian.js.map +1 -1
  35. package/dist/cjs/src/overlay-tools/LookupResolver.js +139 -46
  36. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  37. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +75 -146
  38. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  39. package/dist/cjs/src/primitives/AESGCM.js +2 -2
  40. package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
  41. package/dist/cjs/src/primitives/BigNumber.js +164 -148
  42. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  43. package/dist/cjs/src/primitives/Curve.js +17 -15
  44. package/dist/cjs/src/primitives/Curve.js.map +1 -1
  45. package/dist/cjs/src/primitives/ECDSA.js +12 -7
  46. package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
  47. package/dist/cjs/src/primitives/Hash.js +140 -56
  48. package/dist/cjs/src/primitives/Hash.js.map +1 -1
  49. package/dist/cjs/src/primitives/JacobianPoint.js +8 -8
  50. package/dist/cjs/src/primitives/JacobianPoint.js.map +1 -1
  51. package/dist/cjs/src/primitives/K256.js +3 -3
  52. package/dist/cjs/src/primitives/K256.js.map +1 -1
  53. package/dist/cjs/src/primitives/Point.js +36 -40
  54. package/dist/cjs/src/primitives/Point.js.map +1 -1
  55. package/dist/cjs/src/primitives/PrivateKey.js +4 -4
  56. package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
  57. package/dist/cjs/src/primitives/PublicKey.js +4 -4
  58. package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
  59. package/dist/cjs/src/primitives/Random.js +10 -14
  60. package/dist/cjs/src/primitives/Random.js.map +1 -1
  61. package/dist/cjs/src/primitives/ReaderUint8Array.js +6 -6
  62. package/dist/cjs/src/primitives/ReaderUint8Array.js.map +1 -1
  63. package/dist/cjs/src/primitives/Schnorr.js +2 -2
  64. package/dist/cjs/src/primitives/Schnorr.js.map +1 -1
  65. package/dist/cjs/src/primitives/Secp256r1.js +2 -1
  66. package/dist/cjs/src/primitives/Secp256r1.js.map +1 -1
  67. package/dist/cjs/src/primitives/Signature.js +8 -8
  68. package/dist/cjs/src/primitives/Signature.js.map +1 -1
  69. package/dist/cjs/src/primitives/TransactionSignature.js +20 -21
  70. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  71. package/dist/cjs/src/primitives/utils.js +39 -46
  72. package/dist/cjs/src/primitives/utils.js.map +1 -1
  73. package/dist/cjs/src/registry/RegistryClient.js +31 -23
  74. package/dist/cjs/src/registry/RegistryClient.js.map +1 -1
  75. package/dist/cjs/src/remittance/RemittanceManager.js +19 -18
  76. package/dist/cjs/src/remittance/RemittanceManager.js.map +1 -1
  77. package/dist/cjs/src/remittance/modules/BasicBRC29.js.map +1 -1
  78. package/dist/cjs/src/script/Script.js +93 -170
  79. package/dist/cjs/src/script/Script.js.map +1 -1
  80. package/dist/cjs/src/script/ScriptEvaluationError.js +2 -2
  81. package/dist/cjs/src/script/ScriptEvaluationError.js.map +1 -1
  82. package/dist/cjs/src/script/Spend.js +14 -12
  83. package/dist/cjs/src/script/Spend.js.map +1 -1
  84. package/dist/cjs/src/script/templates/PushDrop.js +22 -18
  85. package/dist/cjs/src/script/templates/PushDrop.js.map +1 -1
  86. package/dist/cjs/src/script/templates/RPuzzle.js +2 -4
  87. package/dist/cjs/src/script/templates/RPuzzle.js.map +1 -1
  88. package/dist/cjs/src/storage/StorageDownloader.js +42 -9
  89. package/dist/cjs/src/storage/StorageDownloader.js.map +1 -1
  90. package/dist/cjs/src/totp/totp.js +1 -1
  91. package/dist/cjs/src/totp/totp.js.map +1 -1
  92. package/dist/cjs/src/transaction/Beef.js +239 -192
  93. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  94. package/dist/cjs/src/transaction/BeefConstants.js +19 -0
  95. package/dist/cjs/src/transaction/BeefConstants.js.map +1 -0
  96. package/dist/cjs/src/transaction/BeefTx.js +12 -12
  97. package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
  98. package/dist/cjs/src/transaction/MerklePath.js +4 -4
  99. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  100. package/dist/cjs/src/transaction/Transaction.js +49 -52
  101. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  102. package/dist/cjs/src/transaction/fee-models/SatoshisPerKilobyte.js +1 -1
  103. package/dist/cjs/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
  104. package/dist/cjs/src/transaction/http/BinaryFetchClient.js +9 -9
  105. package/dist/cjs/src/transaction/http/BinaryFetchClient.js.map +1 -1
  106. package/dist/cjs/src/transaction/http/DefaultHttpClient.js +9 -9
  107. package/dist/cjs/src/transaction/http/DefaultHttpClient.js.map +1 -1
  108. package/dist/cjs/src/wallet/CachedKeyDeriver.js +1 -1
  109. package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -1
  110. package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
  111. package/dist/cjs/src/wallet/WalletError.js.map +1 -1
  112. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js +5 -4
  113. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  114. package/dist/cjs/src/wallet/substrates/ReactNativeWebView.js +9 -9
  115. package/dist/cjs/src/wallet/substrates/ReactNativeWebView.js.map +1 -1
  116. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +92 -92
  117. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  118. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +387 -711
  119. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  120. package/dist/cjs/src/wallet/substrates/XDM.js +4 -4
  121. package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
  122. package/dist/cjs/src/wallet/substrates/window.CWI.js +2 -2
  123. package/dist/cjs/src/wallet/substrates/window.CWI.js.map +1 -1
  124. package/dist/cjs/src/wallet/validationHelpers.js +9 -9
  125. package/dist/cjs/src/wallet/validationHelpers.js.map +1 -1
  126. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  127. package/dist/esm/src/auth/Peer.js +25 -13
  128. package/dist/esm/src/auth/Peer.js.map +1 -1
  129. package/dist/esm/src/auth/SessionManager.js +4 -7
  130. package/dist/esm/src/auth/SessionManager.js.map +1 -1
  131. package/dist/esm/src/auth/certificates/MasterCertificate.js +1 -1
  132. package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
  133. package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js +1 -1
  134. package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
  135. package/dist/esm/src/auth/clients/AuthFetch.js +32 -32
  136. package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
  137. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +4 -4
  138. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  139. package/dist/esm/src/compat/ECIES.js +29 -34
  140. package/dist/esm/src/compat/ECIES.js.map +1 -1
  141. package/dist/esm/src/compat/HD.js +9 -4
  142. package/dist/esm/src/compat/HD.js.map +1 -1
  143. package/dist/esm/src/compat/Mnemonic.js +12 -12
  144. package/dist/esm/src/compat/Mnemonic.js.map +1 -1
  145. package/dist/esm/src/identity/ContactsManager.js +172 -232
  146. package/dist/esm/src/identity/ContactsManager.js.map +1 -1
  147. package/dist/esm/src/identity/IdentityClient.js +122 -55
  148. package/dist/esm/src/identity/IdentityClient.js.map +1 -1
  149. package/dist/esm/src/kvstore/GlobalKVStore.js +30 -31
  150. package/dist/esm/src/kvstore/GlobalKVStore.js.map +1 -1
  151. package/dist/esm/src/kvstore/LocalKVStore.js +9 -9
  152. package/dist/esm/src/kvstore/LocalKVStore.js.map +1 -1
  153. package/dist/esm/src/kvstore/kvStoreInterpreter.js +2 -2
  154. package/dist/esm/src/kvstore/kvStoreInterpreter.js.map +1 -1
  155. package/dist/esm/src/messages/SignedMessage.js +1 -1
  156. package/dist/esm/src/messages/SignedMessage.js.map +1 -1
  157. package/dist/esm/src/overlay-tools/Historian.js +1 -1
  158. package/dist/esm/src/overlay-tools/Historian.js.map +1 -1
  159. package/dist/esm/src/overlay-tools/LookupResolver.js +139 -46
  160. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  161. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js +74 -146
  162. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  163. package/dist/esm/src/primitives/AESGCM.js +2 -2
  164. package/dist/esm/src/primitives/AESGCM.js.map +1 -1
  165. package/dist/esm/src/primitives/BigNumber.js +167 -154
  166. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  167. package/dist/esm/src/primitives/Curve.js +17 -15
  168. package/dist/esm/src/primitives/Curve.js.map +1 -1
  169. package/dist/esm/src/primitives/ECDSA.js +12 -7
  170. package/dist/esm/src/primitives/ECDSA.js.map +1 -1
  171. package/dist/esm/src/primitives/Hash.js +140 -56
  172. package/dist/esm/src/primitives/Hash.js.map +1 -1
  173. package/dist/esm/src/primitives/JacobianPoint.js +8 -8
  174. package/dist/esm/src/primitives/JacobianPoint.js.map +1 -1
  175. package/dist/esm/src/primitives/K256.js +3 -3
  176. package/dist/esm/src/primitives/K256.js.map +1 -1
  177. package/dist/esm/src/primitives/Point.js +36 -40
  178. package/dist/esm/src/primitives/Point.js.map +1 -1
  179. package/dist/esm/src/primitives/PrivateKey.js +4 -4
  180. package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
  181. package/dist/esm/src/primitives/PublicKey.js +4 -4
  182. package/dist/esm/src/primitives/PublicKey.js.map +1 -1
  183. package/dist/esm/src/primitives/Random.js +10 -14
  184. package/dist/esm/src/primitives/Random.js.map +1 -1
  185. package/dist/esm/src/primitives/ReaderUint8Array.js +6 -6
  186. package/dist/esm/src/primitives/ReaderUint8Array.js.map +1 -1
  187. package/dist/esm/src/primitives/Schnorr.js +1 -1
  188. package/dist/esm/src/primitives/Schnorr.js.map +1 -1
  189. package/dist/esm/src/primitives/Secp256r1.js +2 -1
  190. package/dist/esm/src/primitives/Secp256r1.js.map +1 -1
  191. package/dist/esm/src/primitives/Signature.js +8 -8
  192. package/dist/esm/src/primitives/Signature.js.map +1 -1
  193. package/dist/esm/src/primitives/TransactionSignature.js +20 -21
  194. package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
  195. package/dist/esm/src/primitives/utils.js +39 -48
  196. package/dist/esm/src/primitives/utils.js.map +1 -1
  197. package/dist/esm/src/registry/RegistryClient.js +31 -23
  198. package/dist/esm/src/registry/RegistryClient.js.map +1 -1
  199. package/dist/esm/src/remittance/RemittanceManager.js +19 -18
  200. package/dist/esm/src/remittance/RemittanceManager.js.map +1 -1
  201. package/dist/esm/src/remittance/modules/BasicBRC29.js.map +1 -1
  202. package/dist/esm/src/script/Script.js +93 -170
  203. package/dist/esm/src/script/Script.js.map +1 -1
  204. package/dist/esm/src/script/ScriptEvaluationError.js +2 -2
  205. package/dist/esm/src/script/ScriptEvaluationError.js.map +1 -1
  206. package/dist/esm/src/script/Spend.js +14 -12
  207. package/dist/esm/src/script/Spend.js.map +1 -1
  208. package/dist/esm/src/script/templates/PushDrop.js +4 -3
  209. package/dist/esm/src/script/templates/PushDrop.js.map +1 -1
  210. package/dist/esm/src/script/templates/RPuzzle.js +2 -4
  211. package/dist/esm/src/script/templates/RPuzzle.js.map +1 -1
  212. package/dist/esm/src/storage/StorageDownloader.js +1 -1
  213. package/dist/esm/src/storage/StorageDownloader.js.map +1 -1
  214. package/dist/esm/src/totp/totp.js +1 -1
  215. package/dist/esm/src/totp/totp.js.map +1 -1
  216. package/dist/esm/src/transaction/Beef.js +229 -186
  217. package/dist/esm/src/transaction/Beef.js.map +1 -1
  218. package/dist/esm/src/transaction/BeefConstants.js +16 -0
  219. package/dist/esm/src/transaction/BeefConstants.js.map +1 -0
  220. package/dist/esm/src/transaction/BeefTx.js +3 -3
  221. package/dist/esm/src/transaction/BeefTx.js.map +1 -1
  222. package/dist/esm/src/transaction/MerklePath.js +4 -4
  223. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  224. package/dist/esm/src/transaction/Transaction.js +49 -52
  225. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  226. package/dist/esm/src/transaction/fee-models/SatoshisPerKilobyte.js +1 -1
  227. package/dist/esm/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
  228. package/dist/esm/src/transaction/http/BinaryFetchClient.js +9 -9
  229. package/dist/esm/src/transaction/http/BinaryFetchClient.js.map +1 -1
  230. package/dist/esm/src/transaction/http/DefaultHttpClient.js +9 -9
  231. package/dist/esm/src/transaction/http/DefaultHttpClient.js.map +1 -1
  232. package/dist/esm/src/wallet/CachedKeyDeriver.js +1 -1
  233. package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -1
  234. package/dist/esm/src/wallet/WalletClient.js.map +1 -1
  235. package/dist/esm/src/wallet/WalletError.js.map +1 -1
  236. package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js +5 -4
  237. package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  238. package/dist/esm/src/wallet/substrates/ReactNativeWebView.js +9 -9
  239. package/dist/esm/src/wallet/substrates/ReactNativeWebView.js.map +1 -1
  240. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +92 -92
  241. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  242. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +387 -711
  243. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  244. package/dist/esm/src/wallet/substrates/XDM.js +4 -4
  245. package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
  246. package/dist/esm/src/wallet/substrates/window.CWI.js +2 -2
  247. package/dist/esm/src/wallet/substrates/window.CWI.js.map +1 -1
  248. package/dist/esm/src/wallet/validationHelpers.js +9 -9
  249. package/dist/esm/src/wallet/validationHelpers.js.map +1 -1
  250. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  251. package/dist/types/src/auth/Peer.d.ts +13 -0
  252. package/dist/types/src/auth/Peer.d.ts.map +1 -1
  253. package/dist/types/src/auth/SessionManager.d.ts.map +1 -1
  254. package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
  255. package/dist/types/src/compat/ECIES.d.ts.map +1 -1
  256. package/dist/types/src/compat/HD.d.ts.map +1 -1
  257. package/dist/types/src/identity/ContactsManager.d.ts +18 -0
  258. package/dist/types/src/identity/ContactsManager.d.ts.map +1 -1
  259. package/dist/types/src/identity/IdentityClient.d.ts +47 -8
  260. package/dist/types/src/identity/IdentityClient.d.ts.map +1 -1
  261. package/dist/types/src/kvstore/GlobalKVStore.d.ts.map +1 -1
  262. package/dist/types/src/overlay-tools/LookupResolver.d.ts +59 -1
  263. package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
  264. package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts +18 -3
  265. package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts.map +1 -1
  266. package/dist/types/src/primitives/BigNumber.d.ts +13 -3
  267. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  268. package/dist/types/src/primitives/Curve.d.ts.map +1 -1
  269. package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
  270. package/dist/types/src/primitives/Hash.d.ts +3 -3
  271. package/dist/types/src/primitives/Hash.d.ts.map +1 -1
  272. package/dist/types/src/primitives/JacobianPoint.d.ts +3 -1
  273. package/dist/types/src/primitives/JacobianPoint.d.ts.map +1 -1
  274. package/dist/types/src/primitives/Point.d.ts.map +1 -1
  275. package/dist/types/src/primitives/Random.d.ts +2 -2
  276. package/dist/types/src/primitives/Random.d.ts.map +1 -1
  277. package/dist/types/src/primitives/ReaderUint8Array.d.ts.map +1 -1
  278. package/dist/types/src/primitives/Schnorr.d.ts +2 -1
  279. package/dist/types/src/primitives/Schnorr.d.ts.map +1 -1
  280. package/dist/types/src/primitives/Secp256r1.d.ts.map +1 -1
  281. package/dist/types/src/primitives/utils.d.ts +2 -4
  282. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  283. package/dist/types/src/registry/RegistryClient.d.ts.map +1 -1
  284. package/dist/types/src/remittance/RemittanceManager.d.ts.map +1 -1
  285. package/dist/types/src/remittance/modules/BasicBRC29.d.ts.map +1 -1
  286. package/dist/types/src/script/Script.d.ts +15 -8
  287. package/dist/types/src/script/Script.d.ts.map +1 -1
  288. package/dist/types/src/script/Spend.d.ts.map +1 -1
  289. package/dist/types/src/script/templates/PushDrop.d.ts +3 -1
  290. package/dist/types/src/script/templates/PushDrop.d.ts.map +1 -1
  291. package/dist/types/src/script/templates/RPuzzle.d.ts.map +1 -1
  292. package/dist/types/src/transaction/Beef.d.ts +46 -8
  293. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  294. package/dist/types/src/transaction/BeefConstants.d.ts +15 -0
  295. package/dist/types/src/transaction/BeefConstants.d.ts.map +1 -0
  296. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  297. package/dist/types/src/wallet/CachedKeyDeriver.d.ts.map +1 -1
  298. package/dist/types/src/wallet/KeyDeriver.d.ts +1 -1
  299. package/dist/types/src/wallet/KeyDeriver.d.ts.map +1 -1
  300. package/dist/types/src/wallet/Wallet.interfaces.d.ts +2 -2
  301. package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -1
  302. package/dist/types/src/wallet/WalletClient.d.ts +7 -7
  303. package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
  304. package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts +7 -7
  305. package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts.map +1 -1
  306. package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts +36 -7
  307. package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts.map +1 -1
  308. package/dist/types/src/wallet/substrates/window.CWI.d.ts +8 -8
  309. package/dist/types/src/wallet/substrates/window.CWI.d.ts.map +1 -1
  310. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  311. package/dist/umd/bundle.js +3 -3
  312. package/package.json +1 -1
  313. package/src/auth/Peer.ts +26 -13
  314. package/src/auth/SessionManager.ts +4 -7
  315. package/src/auth/certificates/MasterCertificate.ts +1 -1
  316. package/src/auth/certificates/__tests/CompletedProtoWallet.ts +1 -1
  317. package/src/auth/clients/AuthFetch.ts +41 -41
  318. package/src/auth/transports/SimplifiedFetchTransport.ts +4 -4
  319. package/src/compat/ECIES.ts +29 -34
  320. package/src/compat/HD.ts +10 -5
  321. package/src/compat/Mnemonic.ts +11 -11
  322. package/src/compat/__tests/HD.test.ts +19 -0
  323. package/src/identity/ContactsManager.ts +194 -257
  324. package/src/identity/IdentityClient.ts +155 -66
  325. package/src/identity/__tests/IdentityClient.test.ts +25 -1
  326. package/src/kvstore/GlobalKVStore.ts +31 -32
  327. package/src/kvstore/LocalKVStore.ts +8 -8
  328. package/src/kvstore/kvStoreInterpreter.ts +2 -2
  329. package/src/messages/SignedMessage.ts +1 -1
  330. package/src/overlay-tools/Historian.ts +1 -1
  331. package/src/overlay-tools/LookupResolver.ts +182 -45
  332. package/src/overlay-tools/SHIPBroadcaster.ts +92 -168
  333. package/src/primitives/AESGCM.ts +2 -2
  334. package/src/primitives/BigNumber.ts +122 -113
  335. package/src/primitives/Curve.ts +16 -15
  336. package/src/primitives/ECDSA.ts +10 -8
  337. package/src/primitives/Hash.ts +152 -53
  338. package/src/primitives/JacobianPoint.ts +13 -11
  339. package/src/primitives/K256.ts +3 -3
  340. package/src/primitives/Point.ts +35 -38
  341. package/src/primitives/PrivateKey.ts +3 -3
  342. package/src/primitives/PublicKey.ts +3 -3
  343. package/src/primitives/Random.ts +11 -14
  344. package/src/primitives/ReaderUint8Array.ts +7 -7
  345. package/src/primitives/Schnorr.ts +2 -1
  346. package/src/primitives/Secp256r1.ts +2 -1
  347. package/src/primitives/Signature.ts +8 -8
  348. package/src/primitives/TransactionSignature.ts +16 -16
  349. package/src/primitives/utils.ts +37 -47
  350. package/src/registry/RegistryClient.ts +25 -25
  351. package/src/remittance/RemittanceManager.ts +17 -18
  352. package/src/remittance/modules/BasicBRC29.ts +2 -5
  353. package/src/script/Script.ts +114 -170
  354. package/src/script/ScriptEvaluationError.ts +2 -2
  355. package/src/script/Spend.ts +14 -15
  356. package/src/script/templates/PushDrop.ts +5 -3
  357. package/src/script/templates/RPuzzle.ts +2 -4
  358. package/src/storage/StorageDownloader.ts +1 -1
  359. package/src/totp/totp.ts +1 -1
  360. package/src/transaction/Beef.ts +241 -203
  361. package/src/transaction/BeefConstants.ts +16 -0
  362. package/src/transaction/BeefTx.ts +3 -3
  363. package/src/transaction/MerklePath.ts +4 -4
  364. package/src/transaction/Transaction.ts +48 -51
  365. package/src/transaction/fee-models/SatoshisPerKilobyte.ts +1 -1
  366. package/src/transaction/http/BinaryFetchClient.ts +8 -8
  367. package/src/transaction/http/DefaultHttpClient.ts +8 -8
  368. package/src/wallet/CachedKeyDeriver.ts +8 -6
  369. package/src/wallet/KeyDeriver.ts +1 -1
  370. package/src/wallet/Wallet.interfaces.ts +2 -4
  371. package/src/wallet/WalletClient.ts +8 -8
  372. package/src/wallet/WalletError.ts +1 -1
  373. package/src/wallet/__tests/WalletClient.substrate.test.ts +10 -6
  374. package/src/wallet/substrates/HTTPWalletJSON.ts +22 -21
  375. package/src/wallet/substrates/ReactNativeWebView.ts +9 -9
  376. package/src/wallet/substrates/WalletWireProcessor.ts +83 -83
  377. package/src/wallet/substrates/WalletWireTransceiver.ts +528 -938
  378. package/src/wallet/substrates/XDM.ts +4 -4
  379. package/src/wallet/substrates/__tests/HTTPWalletJSON.test.ts +38 -25
  380. package/src/wallet/substrates/__tests/ReactNativeWebView.test.ts +174 -0
  381. package/src/wallet/substrates/__tests/window.CWI.test.ts +256 -0
  382. package/src/wallet/substrates/window.CWI.ts +10 -10
  383. package/src/wallet/validationHelpers.ts +9 -9
@@ -18,6 +18,30 @@ import { PrivateKey, Utils } from '../primitives/index.js'
18
18
  import { LookupResolver, SHIPBroadcaster, TopicBroadcaster, withDoubleSpendRetry } from '../overlay-tools/index.js'
19
19
  import { ContactsManager, Contact } from './ContactsManager.js'
20
20
 
21
+ /** Options for {@link IdentityClient.resolveByIdentityKey}. */
22
+ export interface ResolveByIdentityKeyOptions {
23
+ /** Default `true`. If `false`, contacts are skipped and the overlay is queried directly. */
24
+ overrideWithContacts?: boolean
25
+ /**
26
+ * Default `false`. When `true`, fire contacts and overlay in parallel (legacy behavior) instead
27
+ * of short-circuiting on a contacts hit. Use when callers specifically need a fresh overlay
28
+ * answer alongside the contact record.
29
+ */
30
+ parallel?: boolean
31
+ }
32
+
33
+ /** Options for {@link IdentityClient.resolveByAttributes}. */
34
+ export interface ResolveByAttributesOptions {
35
+ /** Default `true`. If `false`, contacts are skipped and the overlay is queried directly. */
36
+ overrideWithContacts?: boolean
37
+ /**
38
+ * Default `false`. When `true`, fire contacts and overlay in parallel (legacy behavior). The
39
+ * contacts-first path tries to match the supplied attributes against the locally-stored
40
+ * contacts; if any contact matches every attribute, the overlay is skipped.
41
+ */
42
+ parallel?: boolean
43
+ }
44
+
21
45
  /**
22
46
  * IdentityClient lets you discover who others are, and let the world know who you are.
23
47
  */
@@ -69,7 +93,8 @@ export class IdentityClient {
69
93
  certificate.signature
70
94
  )
71
95
  await masterCert.verify()
72
- } catch (error) {
96
+ } catch (_certVerificationError) {
97
+ // Low-level cert error details are suppressed — surface a user-facing message only
73
98
  throw new Error('Public reveal failed: Certificate verification failed!')
74
99
  }
75
100
 
@@ -97,7 +122,7 @@ export class IdentityClient {
97
122
  true,
98
123
  true
99
124
  )
100
- // TODO: Consider verification and if this is necessary
125
+ // Consider verification and if this is necessary
101
126
  // counterpartyCanVerifyMyOwnership: true
102
127
 
103
128
  const { tx } = await this.wallet.createAction(
@@ -130,67 +155,124 @@ export class IdentityClient {
130
155
  /**
131
156
  * Resolves displayable identity certificates, issued to a given identity key by a trusted certifier.
132
157
  *
133
- * @param {DiscoverByIdentityKeyArgs} args - Arguments for requesting the discovery based on the identity key.
134
- * @param {boolean} [overrideWithContacts=true] - Whether to override the results with personal contacts if available.
135
- * @returns {Promise<DisplayableIdentity[]>} The promise resolves to displayable identities.
158
+ * By default, contacts are consulted first and the overlay is only queried on a contacts miss.
159
+ * Pass `{ parallel: true }` to fire both in parallel (the legacy behavior, useful when callers
160
+ * specifically want a fresh overlay answer even when a contact exists).
161
+ *
162
+ * @param args - Arguments for requesting the discovery based on the identity key.
163
+ * @param overrideWithContacts - Whether to consult personal contacts. Default true. When `false`,
164
+ * contacts are skipped entirely and the overlay is queried directly. Boolean kept for legacy
165
+ * call sites; new code should prefer the options-object form.
166
+ * @returns The promise resolves to displayable identities.
136
167
  */
137
168
  async resolveByIdentityKey (
138
169
  args: DiscoverByIdentityKeyArgs,
139
- overrideWithContacts = true
170
+ overrideWithContacts: boolean | ResolveByIdentityKeyOptions = true
140
171
  ): Promise<DisplayableIdentity[]> {
141
- // Run both queries in parallel for better performance
172
+ const opts: ResolveByIdentityKeyOptions =
173
+ typeof overrideWithContacts === 'boolean'
174
+ ? { overrideWithContacts }
175
+ : { overrideWithContacts: true, ...overrideWithContacts }
176
+ const useContacts = opts.overrideWithContacts !== false
177
+ const parallel = opts.parallel === true
178
+
179
+ if (useContacts && !parallel) {
180
+ const contacts = await this.contactsManager.getContacts(args.identityKey)
181
+ if (contacts.length > 0) return contacts
182
+
183
+ const certificatesResult = await this.wallet.discoverByIdentityKey(args, this.originator)
184
+ const certs = certificatesResult?.certificates ?? []
185
+ return certs.map((cert) => IdentityClient.parseIdentity(cert))
186
+ }
187
+
142
188
  const [contacts, certificatesResult] = await Promise.all([
143
- overrideWithContacts
189
+ useContacts
144
190
  ? this.contactsManager.getContacts(args.identityKey)
145
- : Promise.resolve([]),
191
+ : Promise.resolve([] as Contact[]),
146
192
  this.wallet.discoverByIdentityKey(args, this.originator)
147
193
  ])
148
194
 
149
- // Override results with personal contacts if available
150
- if (contacts.length > 0) {
151
- return contacts
152
- }
153
-
195
+ if (contacts.length > 0) return contacts
154
196
  const certs = certificatesResult?.certificates ?? []
155
- return certs.map((cert) => {
156
- return IdentityClient.parseIdentity(cert)
157
- })
197
+ return certs.map((cert) => IdentityClient.parseIdentity(cert))
158
198
  }
159
199
 
160
200
  /**
161
201
  * Resolves displayable identity certificates by specific identity attributes, issued by a trusted entity.
162
202
  *
163
- * @param {DiscoverByAttributesArgs} args - Attributes and optional parameters used to discover certificates.
164
- * @param {boolean} [overrideWithContacts=true] - Whether to override the results with personal contacts if available.
165
- * @returns {Promise<DisplayableIdentity[]>} The promise resolves to displayable identities.
203
+ * By default, contacts are consulted first: if any contact matches, the overlay call is skipped
204
+ * entirely. Set `parallel: true` to keep the legacy parallel behavior.
205
+ *
206
+ * @param args - Attributes and optional parameters used to discover certificates.
207
+ * @param overrideWithContacts - Whether to consult personal contacts. Default true. Boolean kept
208
+ * for legacy call sites; new code should prefer the options-object form.
209
+ * @returns The promise resolves to displayable identities.
166
210
  */
167
211
  async resolveByAttributes (
168
212
  args: DiscoverByAttributesArgs,
169
- overrideWithContacts = true
213
+ overrideWithContacts: boolean | ResolveByAttributesOptions = true
170
214
  ): Promise<DisplayableIdentity[]> {
171
- // Run both queries in parallel for better performance
215
+ const opts: ResolveByAttributesOptions =
216
+ typeof overrideWithContacts === 'boolean'
217
+ ? { overrideWithContacts }
218
+ : { overrideWithContacts: true, ...overrideWithContacts }
219
+ const useContacts = opts.overrideWithContacts !== false
220
+ const parallel = opts.parallel === true
221
+
222
+ if (useContacts && !parallel) {
223
+ const contacts = await this.contactsManager.getContacts()
224
+ const matches = this.matchContactsByAttributes(contacts, args)
225
+ if (matches.length > 0) return matches
226
+
227
+ const certificatesResult = await this.wallet.discoverByAttributes(args, this.originator)
228
+ const certs = certificatesResult?.certificates ?? []
229
+ const contactByKey = new Map<PubKeyHex, Contact>(
230
+ contacts.map((contact) => [contact.identityKey, contact] as const)
231
+ )
232
+ return certs.map(
233
+ (cert) => contactByKey.get(cert.subject) ?? IdentityClient.parseIdentity(cert)
234
+ )
235
+ }
236
+
172
237
  const [contacts, certificatesResult] = await Promise.all([
173
- overrideWithContacts
174
- ? this.contactsManager.getContacts()
175
- : Promise.resolve([]),
238
+ useContacts ? this.contactsManager.getContacts() : Promise.resolve([] as Contact[]),
176
239
  this.wallet.discoverByAttributes(args, this.originator)
177
240
  ])
178
241
 
179
- // Fast lookup by identityKey
180
242
  const contactByKey = new Map<PubKeyHex, Contact>(
181
243
  contacts.map((contact) => [contact.identityKey, contact] as const)
182
244
  )
183
-
184
- // Guard if certificates might be absent
185
245
  const certs = certificatesResult?.certificates ?? []
186
-
187
- // Parse certificates and substitute with contacts where available
188
246
  return certs.map(
189
- (cert) =>
190
- contactByKey.get(cert.subject) ?? IdentityClient.parseIdentity(cert)
247
+ (cert) => contactByKey.get(cert.subject) ?? IdentityClient.parseIdentity(cert)
191
248
  )
192
249
  }
193
250
 
251
+ /**
252
+ * Best-effort match of contacts against a `DiscoverByAttributesArgs.attributes` shape.
253
+ * Used by the contacts-first path of {@link resolveByAttributes} to decide whether the overlay
254
+ * can be skipped. Compares string-valued attributes against same-named fields on the contact's
255
+ * decrypted record. Returns the subset of contacts that match every supplied attribute.
256
+ */
257
+ private matchContactsByAttributes (
258
+ contacts: Contact[],
259
+ args: DiscoverByAttributesArgs
260
+ ): Contact[] {
261
+ const attrs = (args).attributes
262
+ if (attrs == null || typeof attrs !== 'object' || Array.isArray(attrs)) return []
263
+ const entries = Object.entries(attrs as Record<string, unknown>).filter(
264
+ ([, v]) => typeof v === 'string' && v.length > 0
265
+ ) as Array<[string, string]>
266
+ if (entries.length === 0) return []
267
+ return contacts.filter((contact) => {
268
+ const bag: Record<string, unknown> = {
269
+ name: contact.name,
270
+ identityKey: contact.identityKey
271
+ }
272
+ return entries.every(([k, v]) => typeof bag[k] === 'string' && (bag[k] as string).toLowerCase() === v.toLowerCase())
273
+ })
274
+ }
275
+
194
276
  /**
195
277
  * Remove public certificate revelation from overlay services by spending the identity token
196
278
  * @param serialNumber - Unique serial number of the certificate to revoke revelation
@@ -346,42 +428,42 @@ export class IdentityClient {
346
428
  avatarURL = decryptedFields.profilePhoto
347
429
  badgeLabel = `X account certified by ${certifierInfo.name}`
348
430
  badgeIconURL = certifierInfo.iconUrl
349
- badgeClickURL = 'https://socialcert.net' // TODO Make a specific page for this.
431
+ badgeClickURL = 'https://socialcert.net' // (no dedicated page yet)
350
432
  break
351
433
  case KNOWN_IDENTITY_TYPES.discordCert:
352
434
  name = decryptedFields.userName
353
435
  avatarURL = decryptedFields.profilePhoto
354
436
  badgeLabel = `Discord account certified by ${certifierInfo.name}`
355
437
  badgeIconURL = certifierInfo.iconUrl
356
- badgeClickURL = 'https://socialcert.net' // TODO Make a specific page for this.
438
+ badgeClickURL = 'https://socialcert.net' // (no dedicated page yet)
357
439
  break
358
440
  case KNOWN_IDENTITY_TYPES.emailCert:
359
441
  name = decryptedFields.email
360
442
  avatarURL = 'XUTZxep7BBghAJbSBwTjNfmcsDdRFs5EaGEgkESGSgjJVYgMEizu'
361
443
  badgeLabel = `Email certified by ${certifierInfo.name}`
362
444
  badgeIconURL = certifierInfo.iconUrl
363
- badgeClickURL = 'https://socialcert.net' // TODO Make a specific page for this.
445
+ badgeClickURL = 'https://socialcert.net' // (no dedicated page yet)
364
446
  break
365
447
  case KNOWN_IDENTITY_TYPES.phoneCert:
366
448
  name = decryptedFields.phoneNumber
367
449
  avatarURL = 'XUTLxtX3ELNUwRhLwL7kWNGbdnFM8WG2eSLv84J7654oH8HaJWrU'
368
450
  badgeLabel = `Phone certified by ${certifierInfo.name}`
369
451
  badgeIconURL = certifierInfo.iconUrl
370
- badgeClickURL = 'https://socialcert.net' // TODO Make a specific page for this.
452
+ badgeClickURL = 'https://socialcert.net' // (no dedicated page yet)
371
453
  break
372
454
  case KNOWN_IDENTITY_TYPES.identiCert:
373
455
  name = `${decryptedFields.firstName} ${decryptedFields.lastName}`
374
456
  avatarURL = decryptedFields.profilePhoto
375
457
  badgeLabel = `Government ID certified by ${certifierInfo.name}`
376
458
  badgeIconURL = certifierInfo.iconUrl
377
- badgeClickURL = 'https://identicert.me' // TODO Make a specific page for this.
459
+ badgeClickURL = 'https://identicert.me' // (no dedicated page yet)
378
460
  break
379
461
  case KNOWN_IDENTITY_TYPES.registrant:
380
462
  name = decryptedFields.name
381
463
  avatarURL = decryptedFields.icon
382
464
  badgeLabel = `Entity certified by ${certifierInfo.name}`
383
465
  badgeIconURL = certifierInfo.iconUrl
384
- badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' // TODO: Make this doc page exist
466
+ badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' // (no dedicated page yet)
385
467
  break
386
468
  case KNOWN_IDENTITY_TYPES.coolCert:
387
469
  name = decryptedFields.cool === 'true' ? 'Cool Person!' : 'Not cool!'
@@ -392,14 +474,14 @@ export class IdentityClient {
392
474
  badgeLabel =
393
475
  'Represents the ability for anyone to access this information.'
394
476
  badgeIconURL = 'XUUV39HVPkpmMzYNTx7rpKzJvXfeiVyQWg2vfSpjBAuhunTCA9uG'
395
- badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' // TODO: Make this doc page exist
477
+ badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' // (no dedicated page yet)
396
478
  break
397
479
  case KNOWN_IDENTITY_TYPES.self:
398
480
  name = 'You'
399
481
  avatarURL = 'XUT9jHGk2qace148jeCX5rDsMftkSGYKmigLwU2PLLBc7Hm63VYR'
400
482
  badgeLabel = 'Represents your ability to access this information.'
401
483
  badgeIconURL = 'XUUV39HVPkpmMzYNTx7rpKzJvXfeiVyQWg2vfSpjBAuhunTCA9uG'
402
- badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' // TODO: Make this doc page exist
484
+ badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' // (no dedicated page yet)
403
485
  break
404
486
  default: {
405
487
  const parsed = IdentityClient.tryToParseGenericIdentity(
@@ -455,34 +537,41 @@ export class IdentityClient {
455
537
  // Try to construct a name from common field patterns
456
538
  const firstName = decryptedFields.firstName
457
539
  const lastName = decryptedFields.lastName
458
- const fullName =
459
- IdentityClient.hasValue(firstName) && IdentityClient.hasValue(lastName)
460
- ? `${firstName} ${lastName}`
461
- : IdentityClient.hasValue(firstName)
462
- ? firstName
463
- : IdentityClient.hasValue(lastName)
464
- ? lastName
465
- : undefined
466
-
467
- const name = IdentityClient.hasValue(decryptedFields.name)
468
- ? decryptedFields.name
469
- : IdentityClient.hasValue(decryptedFields.userName)
470
- ? decryptedFields.userName
471
- : (fullName ??
472
- (IdentityClient.hasValue(decryptedFields.email)
473
- ? decryptedFields.email
474
- : defaultIdentity.name))
540
+ let fullName: string | undefined
541
+ if (IdentityClient.hasValue(firstName) && IdentityClient.hasValue(lastName)) {
542
+ fullName = `${firstName} ${lastName}`
543
+ } else if (IdentityClient.hasValue(firstName)) {
544
+ fullName = firstName
545
+ } else if (IdentityClient.hasValue(lastName)) {
546
+ fullName = lastName
547
+ }
548
+
549
+ let name: string | undefined
550
+ if (IdentityClient.hasValue(decryptedFields.name)) {
551
+ name = decryptedFields.name
552
+ } else if (IdentityClient.hasValue(decryptedFields.userName)) {
553
+ name = decryptedFields.userName
554
+ } else if (fullName !== undefined) {
555
+ name = fullName
556
+ } else if (IdentityClient.hasValue(decryptedFields.email)) {
557
+ name = decryptedFields.email
558
+ } else {
559
+ name = defaultIdentity.name
560
+ }
475
561
 
476
562
  // Try to find an avatar/photo from common field names
477
- const avatarURL = IdentityClient.hasValue(decryptedFields.profilePhoto)
478
- ? decryptedFields.profilePhoto
479
- : IdentityClient.hasValue(decryptedFields.avatar)
480
- ? decryptedFields.avatar
481
- : IdentityClient.hasValue(decryptedFields.icon)
482
- ? decryptedFields.icon
483
- : IdentityClient.hasValue(decryptedFields.photo)
484
- ? decryptedFields.photo
485
- : defaultIdentity.avatarURL
563
+ let avatarURL: string | undefined
564
+ if (IdentityClient.hasValue(decryptedFields.profilePhoto)) {
565
+ avatarURL = decryptedFields.profilePhoto
566
+ } else if (IdentityClient.hasValue(decryptedFields.avatar)) {
567
+ avatarURL = decryptedFields.avatar
568
+ } else if (IdentityClient.hasValue(decryptedFields.icon)) {
569
+ avatarURL = decryptedFields.icon
570
+ } else if (IdentityClient.hasValue(decryptedFields.photo)) {
571
+ avatarURL = decryptedFields.photo
572
+ } else {
573
+ avatarURL = defaultIdentity.avatarURL
574
+ }
486
575
 
487
576
  // Generate badge information
488
577
  const badgeLabel = IdentityClient.hasValue(certifierInfo?.name)
@@ -264,7 +264,31 @@ describe('IdentityClient', () => {
264
264
 
265
265
  expect(identities).toHaveLength(1)
266
266
  expect(identities[0].name).toBe('Alice Smith (Personal Contact)') // Contact should be returned, not discovered identity
267
- // Both calls fire in parallel, but contacts take priority in the result
267
+ // New default: contacts-first short-circuit the overlay is skipped entirely on a contacts hit.
268
+ expect(walletMock.discoverByIdentityKey).not.toHaveBeenCalled()
269
+ })
270
+
271
+ it('should still call the overlay when parallel: true is passed', async () => {
272
+ const contact = {
273
+ name: 'Alice Smith (Personal Contact)',
274
+ identityKey: 'alice-identity-key',
275
+ avatarURL: 'alice-avatar.png',
276
+ abbreviatedKey: 'alice-i...',
277
+ badgeIconURL: '',
278
+ badgeLabel: '',
279
+ badgeClickURL: ''
280
+ }
281
+ const mockContactsManager = identityClient['contactsManager']
282
+ mockContactsManager.getContacts = jest.fn().mockResolvedValue([contact])
283
+ walletMock.discoverByIdentityKey = jest.fn().mockResolvedValue({ certificates: [] })
284
+
285
+ const identities = await identityClient.resolveByIdentityKey(
286
+ { identityKey: 'alice-identity-key' },
287
+ { parallel: true }
288
+ )
289
+
290
+ expect(identities).toHaveLength(1)
291
+ expect(identities[0].name).toBe('Alice Smith (Personal Contact)')
268
292
  expect(walletMock.discoverByIdentityKey).toHaveBeenCalled()
269
293
  })
270
294
  })
@@ -146,7 +146,7 @@ export class GlobalKVStore {
146
146
  throw new Error('Key must be a non-empty string.')
147
147
  }
148
148
  if (typeof value !== 'string') {
149
- throw new Error('Value must be a string.')
149
+ throw new TypeError('Value must be a string.')
150
150
  }
151
151
 
152
152
  const controller = await this.getIdentityKey()
@@ -186,7 +186,30 @@ export class GlobalKVStore {
186
186
  const existingEntries = await this.queryOverlay({ key, controller }, { includeToken: true })
187
187
  const existingToken = existingEntries.length > 0 ? existingEntries[0].token : undefined
188
188
 
189
- if (existingToken != null) {
189
+ if (existingToken == null) {
190
+ // Create new token
191
+ const { tx } = await this.wallet.createAction({
192
+ description: tokenSetDescription,
193
+ outputs: [{
194
+ satoshis: tokenAmount ?? this.config.tokenAmount as number,
195
+ lockingScript: lockingScript.toHex(),
196
+ outputDescription: 'KVStore token'
197
+ }],
198
+ options: {
199
+ acceptDelayedBroadcast: this.config.acceptDelayedBroadcast,
200
+ noSend: this.config.overlayBroadcast,
201
+ randomizeOutputs: false
202
+ }
203
+ }, this.config.originator)
204
+
205
+ if (tx == null) {
206
+ throw new Error('Failed to create transaction')
207
+ }
208
+
209
+ const transaction = Transaction.fromAtomicBEEF(tx)
210
+ await this.submitToOverlay(transaction)
211
+ return `${transaction.id('hex')}.0`
212
+ } else {
190
213
  // Update existing token
191
214
  const inputs: CreateActionInput[] = [{
192
215
  outpoint: `${existingToken.txid}.${existingToken.outputIndex}`,
@@ -239,29 +262,6 @@ export class GlobalKVStore {
239
262
  const transaction = Transaction.fromAtomicBEEF(finalTx)
240
263
  await this.submitToOverlay(transaction)
241
264
  return `${transaction.id('hex')}.0`
242
- } else {
243
- // Create new token
244
- const { tx } = await this.wallet.createAction({
245
- description: tokenSetDescription,
246
- outputs: [{
247
- satoshis: tokenAmount ?? this.config.tokenAmount as number,
248
- lockingScript: lockingScript.toHex(),
249
- outputDescription: 'KVStore token'
250
- }],
251
- options: {
252
- acceptDelayedBroadcast: this.config.acceptDelayedBroadcast,
253
- noSend: this.config.overlayBroadcast,
254
- randomizeOutputs: false
255
- }
256
- }, this.config.originator)
257
-
258
- if (tx == null) {
259
- throw new Error('Failed to create transaction')
260
- }
261
-
262
- const transaction = Transaction.fromAtomicBEEF(tx)
263
- await this.submitToOverlay(transaction)
264
- return `${transaction.id('hex')}.0`
265
265
  }
266
266
  }, this.topicBroadcaster)
267
267
 
@@ -421,9 +421,7 @@ export class GlobalKVStore {
421
421
  * @private
422
422
  */
423
423
  private async getIdentityKey (): Promise<PubKeyHex> {
424
- if (this.cachedIdentityKey == null) {
425
- this.cachedIdentityKey = (await this.wallet.getPublicKey({ identityKey: true }, this.config.originator)).publicKey
426
- }
424
+ this.cachedIdentityKey ??= (await this.wallet.getPublicKey({ identityKey: true }, this.config.originator)).publicKey
427
425
  return this.cachedIdentityKey
428
426
  }
429
427
 
@@ -467,13 +465,13 @@ export class GlobalKVStore {
467
465
  const signature = decoded.fields.pop() as number[]
468
466
  try {
469
467
  await anyoneWallet.verifySignature({
470
- data: decoded.fields.reduce((a, e) => [...a, ...e], []),
468
+ data: decoded.fields.flat(),
471
469
  signature,
472
470
  counterparty: Utils.toHex(decoded.fields[kvProtocol.controller]),
473
471
  protocolID: JSON.parse(Utils.toUTF8(decoded.fields[kvProtocol.protocolID])),
474
472
  keyID: Utils.toUTF8(decoded.fields[kvProtocol.key])
475
473
  })
476
- } catch (error) {
474
+ } catch (_signatureVerificationError) {
477
475
  // Skip all outputs that fail signature verification
478
476
  continue
479
477
  }
@@ -483,7 +481,7 @@ export class GlobalKVStore {
483
481
  if (hasTagsField && decoded.fields[kvProtocol.tags] != null) {
484
482
  try {
485
483
  tags = JSON.parse(Utils.toUTF8(decoded.fields[kvProtocol.tags]))
486
- } catch (e) {
484
+ } catch (_tagsParseError) {
487
485
  // If tags parsing fails, continue without tags
488
486
  tags = undefined
489
487
  }
@@ -514,7 +512,8 @@ export class GlobalKVStore {
514
512
  }
515
513
 
516
514
  entries.push(entry)
517
- } catch (error) {
515
+ } catch (_malformedOutputError) {
516
+ // Skip malformed or undecodable outputs rather than failing the entire query
518
517
  continue
519
518
  }
520
519
  }
@@ -155,7 +155,7 @@ export default class LocalKVStore {
155
155
  if (outputs.length === 0) {
156
156
  return r
157
157
  }
158
- const output = outputs.slice(-1)[0]
158
+ const output = outputs.at(-1)!
159
159
  r.outpoint = output.outpoint
160
160
  let field: number[]
161
161
  try {
@@ -169,23 +169,23 @@ export default class LocalKVStore {
169
169
  } catch (error) {
170
170
  throw new Error(`Invalid value found. You need to call set to collapse the corrupted state (or relinquish the corrupted ${outputs[0].outpoint} output from the ${this.context} basket) before you can get this value again. Original error: ${error instanceof Error ? error.message : String(error)}`)
171
171
  }
172
- if (!this.encrypt) {
173
- r.value = Utils.toUTF8(field)
174
- } else {
172
+ if (this.encrypt) {
175
173
  const { plaintext } = await this.wallet.decrypt({
176
174
  ...this.getProtocol(key),
177
175
  ciphertext: field
178
176
  }, this.originator)
179
177
  r.value = Utils.toUTF8(plaintext)
178
+ } else {
179
+ r.value = Utils.toUTF8(field)
180
180
  }
181
181
  return r
182
182
  }
183
183
 
184
184
  private getInputs (outputs: WalletOutput[]): CreateActionInput[] {
185
185
  const inputs: CreateActionInput[] = []
186
- for (let i = 0; i < outputs.length; i++) {
186
+ for (const output of outputs) {
187
187
  inputs.push({
188
- outpoint: outputs[i].outpoint,
188
+ outpoint: output.outpoint,
189
189
  unlockingScriptLength: 74,
190
190
  inputDescription: 'Previous key-value token'
191
191
  })
@@ -197,7 +197,7 @@ export default class LocalKVStore {
197
197
  const p = this.getProtocol(key)
198
198
  const tx = Transaction.fromAtomicBEEF(atomicBEEF)
199
199
  const spends: Record<number, SignActionSpend> = {}
200
- for (let i = 0; i < outputs.length; i++) {
200
+ for (const [i] of outputs.entries()) {
201
201
  const unlocker = pushdrop.unlock(p.protocolID, p.keyID, 'self')
202
202
  const unlockingScript = await unlocker.sign(tx, i)
203
203
  spends[i] = {
@@ -328,7 +328,7 @@ export default class LocalKVStore {
328
328
  }
329
329
  }, this.originator)
330
330
  if (typeof signableTransaction !== 'object') {
331
- throw new Error('Wallet did not return a signable transaction when expected.')
331
+ throw new TypeError('Wallet did not return a signable transaction when expected.')
332
332
  }
333
333
  const spends = await this.getSpends(key, outputs, pushdrop, signableTransaction.tx)
334
334
  const { txid } = await this.wallet.signAction({
@@ -25,8 +25,8 @@ export interface KVContext { key: string, protocolID: WalletProtocol }
25
25
  export const kvStoreInterpreter: InterpreterFunction<string, KVContext> = async (transaction: Transaction, outputIndex: number, ctx?: KVContext): Promise<string | undefined> => {
26
26
  try {
27
27
  const output = transaction.outputs[outputIndex]
28
- if (output == null || output.lockingScript == null) return undefined
29
- if (ctx == null || ctx.key == null) return undefined
28
+ if (output?.lockingScript == null) return undefined
29
+ if (ctx?.key == null) return undefined
30
30
 
31
31
  // Decode the KVStore token
32
32
  const decoded = PushDrop.decode(output.lockingScript)
@@ -72,7 +72,7 @@ export const verify = (
72
72
  const verifierRest = reader.read(32)
73
73
  const verifierDER = toHex([verifierFirst, ...verifierRest])
74
74
  if (typeof recipient !== 'object') {
75
- throw new Error(
75
+ throw new TypeError(
76
76
  `This signature can only be verified with knowledge of a specific private key. The associated public key is: ${verifierDER}`
77
77
  )
78
78
  }
@@ -181,7 +181,7 @@ export class Historian<T, C = unknown> {
181
181
 
182
182
  // History is built in reverse chronological order during traversal,
183
183
  // so we reverse it to return oldest-first
184
- const chronological = history.reverse()
184
+ const chronological = history.toReversed()
185
185
 
186
186
  if (this.historyCache != null) {
187
187
  const cacheKey = this.historyKey(startTransaction, context)