@unlink-xyz/core 0.1.3 → 0.1.4

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 (369) hide show
  1. package/README.md +9 -0
  2. package/dist/account/{zkAccount.d.ts → account.d.ts} +36 -5
  3. package/dist/account/account.d.ts.map +1 -0
  4. package/dist/account/accounts.d.ts +42 -0
  5. package/dist/account/accounts.d.ts.map +1 -0
  6. package/dist/account/seed.d.ts +45 -0
  7. package/dist/account/seed.d.ts.map +1 -0
  8. package/dist/account/serialization.d.ts +6 -0
  9. package/dist/account/serialization.d.ts.map +1 -0
  10. package/dist/browser/index.js +56221 -0
  11. package/dist/browser/index.js.map +1 -0
  12. package/dist/browser/wallet/index.js +55942 -0
  13. package/dist/browser/wallet/index.js.map +1 -0
  14. package/dist/clients/broadcaster.d.ts +8 -2
  15. package/dist/clients/broadcaster.d.ts.map +1 -1
  16. package/dist/clients/http.d.ts +6 -0
  17. package/dist/clients/http.d.ts.map +1 -1
  18. package/dist/clients/indexer.d.ts +16 -0
  19. package/dist/clients/indexer.d.ts.map +1 -1
  20. package/dist/config.d.ts +30 -9
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/constants.d.ts +6 -0
  23. package/dist/constants.d.ts.map +1 -0
  24. package/dist/core.d.ts.map +1 -1
  25. package/dist/crypto/adapters/index.d.ts +17 -0
  26. package/dist/crypto/adapters/index.d.ts.map +1 -0
  27. package/dist/crypto/adapters/polyfills.d.ts +5 -0
  28. package/dist/crypto/adapters/polyfills.d.ts.map +1 -0
  29. package/dist/crypto/encrypt.d.ts +33 -0
  30. package/dist/crypto/encrypt.d.ts.map +1 -0
  31. package/dist/crypto/secure-memory.d.ts +25 -0
  32. package/dist/crypto/secure-memory.d.ts.map +1 -0
  33. package/dist/errors.d.ts +17 -0
  34. package/dist/errors.d.ts.map +1 -1
  35. package/dist/history/index.d.ts +3 -0
  36. package/dist/history/index.d.ts.map +1 -0
  37. package/dist/history/service.d.ts +46 -0
  38. package/dist/history/service.d.ts.map +1 -0
  39. package/dist/history/types.d.ts +21 -0
  40. package/dist/history/types.d.ts.map +1 -0
  41. package/dist/index.d.ts +16 -7
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +6721 -19
  44. package/dist/index.js.map +1 -0
  45. package/dist/keys/address.d.ts +13 -0
  46. package/dist/keys/address.d.ts.map +1 -0
  47. package/dist/keys/derive.d.ts +37 -0
  48. package/dist/keys/derive.d.ts.map +1 -0
  49. package/dist/keys/hex.d.ts +14 -0
  50. package/dist/keys/hex.d.ts.map +1 -0
  51. package/dist/keys/index.d.ts +5 -0
  52. package/dist/keys/index.d.ts.map +1 -0
  53. package/dist/keys/mnemonic.d.ts +6 -0
  54. package/dist/keys/mnemonic.d.ts.map +1 -0
  55. package/dist/keys.d.ts +5 -1
  56. package/dist/keys.d.ts.map +1 -1
  57. package/dist/prover/config.d.ts +53 -22
  58. package/dist/prover/config.d.ts.map +1 -1
  59. package/dist/prover/integrity.d.ts +20 -0
  60. package/dist/prover/integrity.d.ts.map +1 -0
  61. package/dist/prover/prover.d.ts +16 -20
  62. package/dist/prover/prover.d.ts.map +1 -1
  63. package/dist/prover/registry.d.ts +3 -30
  64. package/dist/prover/registry.d.ts.map +1 -1
  65. package/dist/state/merkle/hydrator.d.ts +21 -19
  66. package/dist/state/merkle/hydrator.d.ts.map +1 -1
  67. package/dist/state/merkle/index.d.ts +2 -2
  68. package/dist/state/merkle/index.d.ts.map +1 -1
  69. package/dist/state/merkle/merkle-tree.d.ts +8 -0
  70. package/dist/state/merkle/merkle-tree.d.ts.map +1 -1
  71. package/dist/state/store/ciphertext-store.d.ts +11 -0
  72. package/dist/state/store/ciphertext-store.d.ts.map +1 -1
  73. package/dist/state/store/history-store.d.ts +24 -0
  74. package/dist/state/store/history-store.d.ts.map +1 -0
  75. package/dist/state/store/index.d.ts +3 -2
  76. package/dist/state/store/index.d.ts.map +1 -1
  77. package/dist/state/store/job-store.d.ts +7 -7
  78. package/dist/state/store/job-store.d.ts.map +1 -1
  79. package/dist/state/store/jobs.d.ts +70 -25
  80. package/dist/state/store/jobs.d.ts.map +1 -1
  81. package/dist/state/store/leaf-store.d.ts +4 -0
  82. package/dist/state/store/leaf-store.d.ts.map +1 -1
  83. package/dist/state/store/note-store.d.ts +7 -7
  84. package/dist/state/store/note-store.d.ts.map +1 -1
  85. package/dist/state/store/nullifier-store.d.ts +9 -0
  86. package/dist/state/store/nullifier-store.d.ts.map +1 -1
  87. package/dist/state/store/records.d.ts +39 -2
  88. package/dist/state/store/records.d.ts.map +1 -1
  89. package/dist/state/store/root-store.d.ts.map +1 -1
  90. package/dist/state/store/store.d.ts +79 -27
  91. package/dist/state/store/store.d.ts.map +1 -1
  92. package/dist/storage/indexeddb.d.ts.map +1 -1
  93. package/dist/storage/memory.d.ts.map +1 -1
  94. package/dist/transactions/adapter.d.ts +31 -0
  95. package/dist/transactions/adapter.d.ts.map +1 -0
  96. package/dist/transactions/deposit.d.ts +12 -15
  97. package/dist/transactions/deposit.d.ts.map +1 -1
  98. package/dist/transactions/index.d.ts +9 -4
  99. package/dist/transactions/index.d.ts.map +1 -1
  100. package/dist/transactions/note-selection.d.ts +17 -0
  101. package/dist/transactions/note-selection.d.ts.map +1 -0
  102. package/dist/transactions/note-sync.d.ts +5 -33
  103. package/dist/transactions/note-sync.d.ts.map +1 -1
  104. package/dist/transactions/reconcile.d.ts +9 -11
  105. package/dist/transactions/reconcile.d.ts.map +1 -1
  106. package/dist/transactions/transact.d.ts +30 -22
  107. package/dist/transactions/transact.d.ts.map +1 -1
  108. package/dist/transactions/transaction-planner.d.ts +34 -0
  109. package/dist/transactions/transaction-planner.d.ts.map +1 -0
  110. package/dist/transactions/transfer-planner.d.ts +37 -0
  111. package/dist/transactions/transfer-planner.d.ts.map +1 -0
  112. package/dist/transactions/types/deposit.d.ts +67 -0
  113. package/dist/transactions/types/deposit.d.ts.map +1 -0
  114. package/dist/transactions/types/domain.d.ts +70 -0
  115. package/dist/transactions/types/domain.d.ts.map +1 -0
  116. package/dist/transactions/types/index.d.ts +18 -0
  117. package/dist/transactions/types/index.d.ts.map +1 -0
  118. package/dist/transactions/types/options.d.ts +54 -0
  119. package/dist/transactions/types/options.d.ts.map +1 -0
  120. package/dist/transactions/types/planning.d.ts +82 -0
  121. package/dist/transactions/types/planning.d.ts.map +1 -0
  122. package/dist/transactions/types/state-stores.d.ts +151 -0
  123. package/dist/transactions/types/state-stores.d.ts.map +1 -0
  124. package/dist/transactions/types/transact.d.ts +83 -0
  125. package/dist/transactions/types/transact.d.ts.map +1 -0
  126. package/dist/transactions/withdrawal-planner.d.ts +58 -0
  127. package/dist/transactions/withdrawal-planner.d.ts.map +1 -0
  128. package/dist/tsconfig.tsbuildinfo +1 -1
  129. package/dist/tsup.browser.config.d.ts +7 -0
  130. package/dist/tsup.browser.config.d.ts.map +1 -0
  131. package/dist/tsup.config.d.ts +8 -0
  132. package/dist/tsup.config.d.ts.map +1 -0
  133. package/dist/types.d.ts +1 -0
  134. package/dist/types.d.ts.map +1 -1
  135. package/dist/utils/amounts.d.ts +26 -0
  136. package/dist/utils/amounts.d.ts.map +1 -0
  137. package/dist/utils/async.d.ts +9 -0
  138. package/dist/utils/async.d.ts.map +1 -1
  139. package/dist/utils/async.js +38 -11
  140. package/dist/utils/async.js.map +1 -0
  141. package/dist/utils/bigint.d.ts +0 -2
  142. package/dist/utils/bigint.d.ts.map +1 -1
  143. package/dist/utils/format.d.ts +25 -0
  144. package/dist/utils/format.d.ts.map +1 -0
  145. package/dist/utils/notes.d.ts +15 -0
  146. package/dist/utils/notes.d.ts.map +1 -0
  147. package/dist/utils/polling.d.ts +5 -0
  148. package/dist/utils/polling.d.ts.map +1 -1
  149. package/dist/utils/random.d.ts +18 -0
  150. package/dist/utils/random.d.ts.map +1 -0
  151. package/dist/utils/signature.d.ts +6 -0
  152. package/dist/utils/signature.d.ts.map +1 -1
  153. package/dist/utils/validators.d.ts +21 -10
  154. package/dist/utils/validators.d.ts.map +1 -1
  155. package/dist/vitest.config.d.ts +3 -0
  156. package/dist/vitest.config.d.ts.map +1 -0
  157. package/dist/wallet/adapter.d.ts +21 -0
  158. package/dist/wallet/adapter.d.ts.map +1 -0
  159. package/dist/wallet/burner/service.d.ts +32 -0
  160. package/dist/wallet/burner/service.d.ts.map +1 -0
  161. package/dist/wallet/burner/types.d.ts +47 -0
  162. package/dist/wallet/burner/types.d.ts.map +1 -0
  163. package/dist/wallet/index.d.ts +20 -0
  164. package/dist/wallet/index.d.ts.map +1 -0
  165. package/dist/wallet/index.js +6462 -0
  166. package/dist/wallet/index.js.map +1 -0
  167. package/dist/wallet/sdk.d.ts +48 -0
  168. package/dist/wallet/sdk.d.ts.map +1 -0
  169. package/dist/wallet/types.d.ts +457 -0
  170. package/dist/wallet/types.d.ts.map +1 -0
  171. package/dist/wallet/unlink-wallet.d.ts +187 -0
  172. package/dist/wallet/unlink-wallet.d.ts.map +1 -0
  173. package/package.json +38 -15
  174. package/.eslintrc.json +0 -4
  175. package/account/zkAccount.test.ts +0 -316
  176. package/account/zkAccount.ts +0 -222
  177. package/circuits.json +0 -26
  178. package/clients/broadcaster.ts +0 -67
  179. package/clients/http.ts +0 -94
  180. package/clients/indexer.ts +0 -150
  181. package/config.ts +0 -39
  182. package/core.ts +0 -17
  183. package/dist/account/railgun-imports-prototype.d.ts +0 -12
  184. package/dist/account/railgun-imports-prototype.d.ts.map +0 -1
  185. package/dist/account/railgun-imports-prototype.js +0 -30
  186. package/dist/account/zkAccount.d.ts.map +0 -1
  187. package/dist/account/zkAccount.js +0 -128
  188. package/dist/circuits.json +0 -26
  189. package/dist/clients/broadcaster.js +0 -23
  190. package/dist/clients/http.js +0 -57
  191. package/dist/clients/indexer.js +0 -67
  192. package/dist/config.js +0 -29
  193. package/dist/core.js +0 -12
  194. package/dist/errors.js +0 -18
  195. package/dist/key-derivation/babyjubjub.d.ts +0 -9
  196. package/dist/key-derivation/babyjubjub.d.ts.map +0 -1
  197. package/dist/key-derivation/babyjubjub.js +0 -9
  198. package/dist/key-derivation/bech32.d.ts +0 -22
  199. package/dist/key-derivation/bech32.d.ts.map +0 -1
  200. package/dist/key-derivation/bech32.js +0 -86
  201. package/dist/key-derivation/bip32.d.ts +0 -17
  202. package/dist/key-derivation/bip32.d.ts.map +0 -1
  203. package/dist/key-derivation/bip32.js +0 -41
  204. package/dist/key-derivation/bip39.d.ts +0 -22
  205. package/dist/key-derivation/bip39.d.ts.map +0 -1
  206. package/dist/key-derivation/bip39.js +0 -56
  207. package/dist/key-derivation/bytes.d.ts +0 -19
  208. package/dist/key-derivation/bytes.d.ts.map +0 -1
  209. package/dist/key-derivation/bytes.js +0 -92
  210. package/dist/key-derivation/hash.d.ts +0 -3
  211. package/dist/key-derivation/hash.d.ts.map +0 -1
  212. package/dist/key-derivation/hash.js +0 -10
  213. package/dist/key-derivation/index.d.ts +0 -8
  214. package/dist/key-derivation/index.d.ts.map +0 -1
  215. package/dist/key-derivation/index.js +0 -7
  216. package/dist/key-derivation/wallet-node.d.ts +0 -45
  217. package/dist/key-derivation/wallet-node.d.ts.map +0 -1
  218. package/dist/key-derivation/wallet-node.js +0 -109
  219. package/dist/keys.js +0 -41
  220. package/dist/prover/config.js +0 -80
  221. package/dist/prover/index.js +0 -1
  222. package/dist/prover/prover.js +0 -274
  223. package/dist/prover/registry.js +0 -57
  224. package/dist/schema.js +0 -14
  225. package/dist/state/ciphertext-store.d.ts +0 -12
  226. package/dist/state/ciphertext-store.d.ts.map +0 -1
  227. package/dist/state/ciphertext-store.js +0 -25
  228. package/dist/state/hydrator.d.ts +0 -16
  229. package/dist/state/hydrator.d.ts.map +0 -1
  230. package/dist/state/hydrator.js +0 -18
  231. package/dist/state/index.js +0 -2
  232. package/dist/state/job-store.d.ts +0 -12
  233. package/dist/state/job-store.d.ts.map +0 -1
  234. package/dist/state/job-store.js +0 -118
  235. package/dist/state/jobs.d.ts +0 -50
  236. package/dist/state/jobs.d.ts.map +0 -1
  237. package/dist/state/jobs.js +0 -1
  238. package/dist/state/leaf-store.d.ts +0 -17
  239. package/dist/state/leaf-store.d.ts.map +0 -1
  240. package/dist/state/leaf-store.js +0 -35
  241. package/dist/state/merkle/hydrator.js +0 -36
  242. package/dist/state/merkle/index.js +0 -2
  243. package/dist/state/merkle/merkle-tree.js +0 -104
  244. package/dist/state/merkle-tree.d.ts +0 -34
  245. package/dist/state/merkle-tree.d.ts.map +0 -1
  246. package/dist/state/merkle-tree.js +0 -104
  247. package/dist/state/note-store.d.ts +0 -37
  248. package/dist/state/note-store.d.ts.map +0 -1
  249. package/dist/state/note-store.js +0 -133
  250. package/dist/state/nullifier-store.d.ts +0 -13
  251. package/dist/state/nullifier-store.d.ts.map +0 -1
  252. package/dist/state/nullifier-store.js +0 -21
  253. package/dist/state/records.d.ts +0 -57
  254. package/dist/state/records.d.ts.map +0 -1
  255. package/dist/state/records.js +0 -1
  256. package/dist/state/root-store.d.ts +0 -13
  257. package/dist/state/root-store.d.ts.map +0 -1
  258. package/dist/state/root-store.js +0 -30
  259. package/dist/state/store/ciphertext-store.js +0 -25
  260. package/dist/state/store/index.js +0 -8
  261. package/dist/state/store/job-store.js +0 -118
  262. package/dist/state/store/jobs.js +0 -1
  263. package/dist/state/store/leaf-store.js +0 -35
  264. package/dist/state/store/note-store.js +0 -142
  265. package/dist/state/store/nullifier-store.js +0 -30
  266. package/dist/state/store/records.js +0 -1
  267. package/dist/state/store/root-store.js +0 -30
  268. package/dist/state/store/store.js +0 -22
  269. package/dist/state/store.d.ts +0 -26
  270. package/dist/state/store.d.ts.map +0 -1
  271. package/dist/state/store.js +0 -19
  272. package/dist/state.d.ts +0 -83
  273. package/dist/state.d.ts.map +0 -1
  274. package/dist/state.js +0 -171
  275. package/dist/storage/index.js +0 -2
  276. package/dist/storage/indexeddb.js +0 -205
  277. package/dist/storage/memory.js +0 -87
  278. package/dist/transactions/deposit.js +0 -169
  279. package/dist/transactions/index.js +0 -4
  280. package/dist/transactions/note-sync.js +0 -320
  281. package/dist/transactions/reconcile.js +0 -39
  282. package/dist/transactions/shield.d.ts +0 -5
  283. package/dist/transactions/shield.d.ts.map +0 -1
  284. package/dist/transactions/shield.js +0 -93
  285. package/dist/transactions/transact.js +0 -561
  286. package/dist/transactions/types.d.ts +0 -114
  287. package/dist/transactions/types.d.ts.map +0 -1
  288. package/dist/transactions/types.js +0 -1
  289. package/dist/transactions/utils.d.ts +0 -10
  290. package/dist/transactions/utils.d.ts.map +0 -1
  291. package/dist/transactions/utils.js +0 -17
  292. package/dist/types.js +0 -1
  293. package/dist/utils/bigint.js +0 -29
  294. package/dist/utils/crypto.d.ts +0 -12
  295. package/dist/utils/crypto.d.ts.map +0 -1
  296. package/dist/utils/crypto.js +0 -39
  297. package/dist/utils/json-codec.js +0 -25
  298. package/dist/utils/polling.js +0 -6
  299. package/dist/utils/signature.js +0 -12
  300. package/dist/utils/time.d.ts +0 -2
  301. package/dist/utils/time.d.ts.map +0 -1
  302. package/dist/utils/time.js +0 -3
  303. package/dist/utils/validators.js +0 -70
  304. package/dist/utils/witness.d.ts +0 -11
  305. package/dist/utils/witness.d.ts.map +0 -1
  306. package/dist/utils/witness.js +0 -19
  307. package/errors.ts +0 -20
  308. package/index.ts +0 -21
  309. package/key-derivation/babyjubjub.ts +0 -11
  310. package/key-derivation/bech32.test.ts +0 -90
  311. package/key-derivation/bech32.ts +0 -124
  312. package/key-derivation/bip32.ts +0 -56
  313. package/key-derivation/bip39.ts +0 -76
  314. package/key-derivation/bytes.ts +0 -118
  315. package/key-derivation/hash.ts +0 -13
  316. package/key-derivation/index.ts +0 -7
  317. package/key-derivation/wallet-node.ts +0 -155
  318. package/keys.ts +0 -47
  319. package/prover/config.ts +0 -104
  320. package/prover/index.ts +0 -1
  321. package/prover/prover.integration.test.ts +0 -162
  322. package/prover/prover.test.ts +0 -309
  323. package/prover/prover.ts +0 -405
  324. package/prover/registry.test.ts +0 -90
  325. package/prover/registry.ts +0 -82
  326. package/schema.ts +0 -17
  327. package/setup-artifacts.sh +0 -57
  328. package/state/index.ts +0 -2
  329. package/state/merkle/hydrator.ts +0 -69
  330. package/state/merkle/index.ts +0 -12
  331. package/state/merkle/merkle-tree.test.ts +0 -50
  332. package/state/merkle/merkle-tree.ts +0 -163
  333. package/state/store/ciphertext-store.ts +0 -28
  334. package/state/store/index.ts +0 -24
  335. package/state/store/job-store.ts +0 -162
  336. package/state/store/jobs.ts +0 -64
  337. package/state/store/leaf-store.ts +0 -39
  338. package/state/store/note-store.ts +0 -177
  339. package/state/store/nullifier-store.ts +0 -39
  340. package/state/store/records.ts +0 -61
  341. package/state/store/root-store.ts +0 -34
  342. package/state/store/store.ts +0 -25
  343. package/state.test.ts +0 -235
  344. package/storage/index.ts +0 -3
  345. package/storage/indexeddb.test.ts +0 -99
  346. package/storage/indexeddb.ts +0 -235
  347. package/storage/memory.test.ts +0 -59
  348. package/storage/memory.ts +0 -93
  349. package/transactions/deposit.test.ts +0 -160
  350. package/transactions/deposit.ts +0 -227
  351. package/transactions/index.ts +0 -20
  352. package/transactions/note-sync.test.ts +0 -155
  353. package/transactions/note-sync.ts +0 -452
  354. package/transactions/reconcile.ts +0 -73
  355. package/transactions/transact.test.ts +0 -451
  356. package/transactions/transact.ts +0 -811
  357. package/transactions/types.ts +0 -141
  358. package/tsconfig.json +0 -15
  359. package/types/global.d.ts +0 -15
  360. package/types.ts +0 -24
  361. package/utils/async.ts +0 -15
  362. package/utils/bigint.ts +0 -34
  363. package/utils/crypto.test.ts +0 -69
  364. package/utils/crypto.ts +0 -58
  365. package/utils/json-codec.ts +0 -38
  366. package/utils/polling.ts +0 -6
  367. package/utils/signature.ts +0 -16
  368. package/utils/validators.test.ts +0 -64
  369. package/utils/validators.ts +0 -86
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../constants.ts","../errors.ts","../keys.ts","../storage/memory.ts","../storage/indexeddb.ts","../schema.ts","../core.ts","../state/merkle/merkle-tree.ts","../crypto/adapters/polyfills.ts","../crypto/adapters/index.ts","../keys/hex.ts","../keys/address.ts","../utils/bigint.ts","../utils/validators.ts","../state/merkle/hydrator.ts","../utils/json-codec.ts","../state/store/ciphertext-store.ts","../state/store/history-store.ts","../state/store/jobs.ts","../state/store/job-store.ts","../state/store/leaf-store.ts","../state/store/note-store.ts","../state/store/nullifier-store.ts","../state/store/root-store.ts","../state/store/store.ts","../crypto/secure-memory.ts","../utils/amounts.ts","../utils/notes.ts","../utils/random.ts","../utils/format.ts","../keys/derive.ts","../keys/mnemonic.ts","../utils/signature.ts","../account/account.ts","../history/service.ts","../transactions/deposit.ts","../clients/http.ts","../clients/indexer.ts","../prover/config.ts","../config.ts","../crypto/encrypt.ts","../utils/async.ts","../utils/polling.ts","../transactions/transact.ts","../clients/broadcaster.ts","../prover/prover.ts","../prover/integrity.ts","../../../zk/circuits.json","../prover/registry.ts","../transactions/adapter.ts","../transactions/note-selection.ts","../transactions/transaction-planner.ts","../transactions/withdrawal-planner.ts","../transactions/transfer-planner.ts","../transactions/reconcile.ts","../transactions/note-sync.ts","../wallet/types.ts","../account/serialization.ts","../account/accounts.ts","../account/seed.ts","../wallet/adapter.ts","../wallet/burner/service.ts","../wallet/sdk.ts","../wallet/unlink-wallet.ts"],"sourcesContent":["/**\n * Sentinel address for native ETH, matching the Solidity Constants.ETH_TOKEN.\n * Used as the token address in notes to indicate a native ETH deposit/withdrawal.\n */\nexport const ETH_TOKEN = \"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\";\n","import type { JobStatus } from \"./state/index.js\";\n\nexport class CoreError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CoreError\";\n }\n}\n\nexport class KeyValidationError extends CoreError {\n constructor(message: string) {\n super(message);\n this.name = \"KeyValidationError\";\n }\n}\n\nexport class SchemaMismatchError extends CoreError {\n constructor(current: number, expected: number) {\n super(`schema mismatch (current ${current}, expected ${expected})`);\n this.name = \"SchemaMismatchError\";\n }\n}\n\nexport class ValidationError extends CoreError {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\nexport class ProofError extends CoreError {\n constructor(message: string) {\n super(message);\n this.name = \"ProofError\";\n }\n}\n\nexport class InitializationError extends CoreError {\n constructor(message: string) {\n super(message);\n this.name = \"InitializationError\";\n }\n}\n\nexport class ReconcileError extends CoreError {\n public readonly status: JobStatus;\n constructor(message: string, status: JobStatus) {\n super(message);\n this.name = \"ReconcileError\";\n this.status = status;\n }\n}\n\nexport class AdapterError extends CoreError {\n constructor(message: string) {\n super(message);\n this.name = \"AdapterError\";\n }\n}\n","import { KeyValidationError } from \"./errors.js\";\n\nexport const RESERVED_PREFIXES = [\n \"meta:\",\n \"history:\",\n \"notes:\",\n \"leaves:\",\n \"roots:\",\n \"nullifiers:\",\n \"ciphertexts:\",\n \"jobs:\",\n \"proof_cache:\",\n \"cfg:\",\n \"idx:\",\n \"locks:\",\n] as const;\n\n/** Canonical builders for storage key namespaces used across core */\nexport const keys = {\n note: (c: number, i: number) => `notes:${c}:${i}`,\n historyEntry: (id: string) => `history:${id}`,\n historyPrefix: (chainId: number, mpk: string) => `history:${chainId}:${mpk}:`,\n historyMeta: (chainId: number, mpk: string) =>\n `history:${chainId}:${mpk}:__meta__`,\n leaf: (c: number, i: number) => `leaves:${c}:${i}`,\n ciphertext: (c: number, i: number) => `ciphertexts:${c}:${i}`,\n /** Track note indices that remain unspent for a given master public key (mpk acts as the account identifier). */\n unspent: (c: number, mpk: string, i: number) =>\n `idx:notes:unspent:${c}:${mpk}:${i}`,\n unspentPrefix: (c: number, mpk: string) => `idx:notes:unspent:${c}:${mpk}:`,\n nullifierObs: (c: number, n: string) => `nullifiers:${c}:${n}`,\n nullToIndex: (c: number, n: string) => `idx:nullifier:${c}:${n}`,\n nullifier: (c: number, n: string) => `nullifiers:${c}:${n}`,\n root: (c: number, value: string) => `roots:${c}:${value}`,\n latestRoot: (c: number) => `roots:latest:${c}`,\n rootCursor: (c: number) => `meta:roots:cursor:${c}`,\n cursor: (c: number) => `meta:sync:cursors:${c}`,\n aggregate: (c: number, a: string) => `idx:notes:agg:${c}:${a}`,\n job: (relayId: string) => `jobs:${relayId}`,\n rescanCursor: (c: number, mpk: string) => `meta:rescan:${c}:${mpk}`,\n};\n\nexport const MAX_KEY_LEN = 512;\n\nexport function validateKey(key: string) {\n if (!key) throw new KeyValidationError(\"key must not be empty\");\n if (key.length > MAX_KEY_LEN)\n throw new KeyValidationError(`key exceeds ${MAX_KEY_LEN}`);\n if (!RESERVED_PREFIXES.some((p) => key.startsWith(p)))\n throw new KeyValidationError(\n \"key must start with a reserved namespace prefix\",\n );\n}\n","/**\n * In-memory key/value storage for Unlink Core.\n *\n * What this is\n * - A minimal, process-local KV store backed by a `Map<string, Uint8Array>`.\n *\n * Why we implement it\n * - Fast, dependency-free storage for unit tests, demos, and ephemeral runs.\n * - Useful as a reference driver for the Storage interface.\n *\n * When to use\n * - Unit tests (deterministic, zero I/O).\n * - CLI/Node scripts that do not need persistence beyond process lifetime.\n * - Prototyping or sandboxing Core logic.\n *\n * Trade-offs\n * - 👍 Extremely fast; zero external APIs; simple to reason about.\n * - 👍 Great for isolation in tests; easy to snapshot/clone.\n * - ⚠️ No durability (data is lost on process exit).\n * - ⚠️ Per-process only; no cross-tab or reload survival.\n *\n */\n\nimport { CoreError } from \"../errors.js\";\nimport { validateKey } from \"../keys.js\";\nimport { BatchOp, Bytes, IterOptions, KvPair, Storage } from \"../types.js\";\n\nconst copy = (value: Bytes) => new Uint8Array(value);\n\nexport function createMemoryStorage(): Storage {\n const data = new Map<string, Bytes>();\n let schema = 0;\n\n return {\n async open() {},\n async get(k) {\n validateKey(k);\n return data.has(k) ? copy(data.get(k)!) : null;\n },\n async put(k, v) {\n validateKey(k);\n data.set(k, copy(v));\n },\n async delete(k) {\n validateKey(k);\n const value = data.get(k);\n if (value) {\n // We don't zeroize here by default since we don't know if this is sensitive data.\n data.delete(k);\n }\n },\n async batch(ops: BatchOp[]) {\n const draft = new Map(data);\n for (const op of ops) {\n if (op.put) {\n const [k, v] = op.put;\n validateKey(k);\n draft.set(k, copy(v));\n }\n if (op.del) {\n validateKey(op.del);\n draft.delete(op.del);\n }\n }\n data.clear();\n for (const [k, v] of draft.entries()) {\n data.set(k, copy(v));\n }\n },\n async iter(o: IterOptions = {}): Promise<KvPair[]> {\n if (o.start && o.end && o.start > o.end) {\n throw new CoreError(\"iter start bound must not exceed end bound\");\n }\n const all = [...data.entries()].map(([key, value]) => ({\n key,\n value: copy(value),\n }));\n let ks = all\n .filter(\n ({ key }) =>\n (!o.prefix || key.startsWith(o.prefix)) &&\n (!o.start || key >= o.start) &&\n (!o.end || key <= o.end),\n )\n .sort((a, b) => a.key.localeCompare(b.key));\n if (o.reverse) ks.reverse();\n if (o.limit) ks = ks.slice(0, o.limit);\n return ks;\n },\n async count(prefix?: string): Promise<number> {\n if (!prefix) return data.size;\n let n = 0;\n for (const key of data.keys()) {\n if (key.startsWith(prefix)) n++;\n }\n return n;\n },\n async getSchemaVersion() {\n return schema;\n },\n async setSchemaVersion(n: number) {\n schema = n;\n },\n };\n}\n","/**\n * IndexedDB-backed key/value storage for Unlink Core.\n *\n * What this is\n * - A durable, transactional KV store implemented on top of the browser's IndexedDB.\n * - Two object stores: \"kv\" for app data, \"meta\" for schema/versioning.\n *\n * Why we implement it\n * - We need persistent client-side state (notes, leaves, nullifiers, cfg, etc.) that survives reloads\n * and works in both web apps and browser extensions without introducing a new backend.\n *\n * When to use\n * - Browser UIs and extensions (MV2/MV3) where persistence is required.\n * - Any environment with a real IndexedDB (tests use `fake-indexeddb`).\n *\n * Trade-offs\n * - 👍 Durable, quota-managed, non-blocking, transactional writes (atomic batch).\n * - 👍 Works offline; no server dependency.\n * - ⚠️ Not natively available in Node/SSR; needs a polyfill for tests only.\n *\n */\n\nimport { CoreError } from \"../errors.js\";\nimport { validateKey } from \"../keys.js\";\nimport type { BatchOp, Bytes, IterOptions, KvPair, Storage } from \"../types.js\";\n\nconst DEFAULT_DB_NAME = \"unlink-core\";\nconst DB_VERSION = 1;\nconst KV_STORE = \"kv\";\nconst META_STORE = \"meta\";\nconst SCHEMA_KEY = \"schema_version\";\n\nconst copy = (value: Bytes) => new Uint8Array(value);\n\nfunction assertIndexedDb(): IDBFactory {\n if (typeof indexedDB === \"undefined\") {\n throw new CoreError(\"indexedDB is not available in this environment\");\n }\n return indexedDB;\n}\n\nexport type IndexedDbOptions = {\n name?: string;\n};\n\n// Translate IndexedDB's event-based transaction API into a promise that resolves\n// when the transaction completes or rejects on failure/abort.\nfunction txDone(tx: IDBTransaction): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n tx.oncomplete = () => resolve();\n tx.onerror = () =>\n reject(tx.error ?? new CoreError(\"indexedDB transaction failed\"));\n tx.onabort = () =>\n reject(tx.error ?? new CoreError(\"indexedDB transaction aborted\"));\n });\n}\n\nfunction wrapRequest<T>(request: IDBRequest<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n request.onsuccess = () => resolve(request.result);\n request.onerror = () =>\n reject(request.error ?? new CoreError(\"indexedDB request failed\"));\n });\n}\n\n// Coerce whatever IndexedDB gives us back into our Bytes type.\nfunction asBytes(raw: unknown): Bytes {\n if (raw instanceof Uint8Array) return copy(raw);\n if (raw instanceof ArrayBuffer) return copy(new Uint8Array(raw));\n if (ArrayBuffer.isView(raw)) {\n const view = raw as ArrayBufferView;\n const buf = view.buffer.slice(\n view.byteOffset,\n view.byteOffset + view.byteLength,\n );\n return copy(new Uint8Array(buf));\n }\n throw new CoreError(\"indexedDB value is not binary data\");\n}\n\n// Build an IDBKeyRange from the combination of prefix, start, and end.\n// All bounds are inclusive to match the existing iter() semantics.\n// Returns null when bounds are disjoint (empty result guaranteed).\nfunction buildKeyRange(options: IterOptions): IDBKeyRange | null | undefined {\n const { prefix, start, end } = options;\n\n let lower: string | undefined;\n let upper: string | undefined;\n\n if (prefix) {\n lower = prefix;\n upper = prefix + \"\\uffff\";\n }\n if (start) {\n lower = lower === undefined || start > lower ? start : lower;\n }\n if (end) {\n upper = upper === undefined || end < upper ? end : upper;\n }\n\n if (lower !== undefined && upper !== undefined) {\n if (lower > upper) return null;\n return IDBKeyRange.bound(lower, upper, false, false);\n }\n if (lower !== undefined) return IDBKeyRange.lowerBound(lower, false);\n if (upper !== undefined) return IDBKeyRange.upperBound(upper, false);\n return undefined;\n}\n\n// IndexedDB-backed implementation implementing the storage API.\nexport function createIndexedDbStorage(opts: IndexedDbOptions = {}): Storage {\n const name = opts.name ?? DEFAULT_DB_NAME;\n let db: IDBDatabase | null = null;\n\n // Lazy-open the database so we only touch IndexedDB when needed.\n async function ensureOpen(): Promise<IDBDatabase> {\n if (db) return db;\n\n // Guard for environments without IndexedDB (unit tests or SSR).\n const idb: IDBFactory = assertIndexedDb();\n\n const request = idb.open(name, DB_VERSION);\n // Versioned schema: create one store for kv entries and one for metadata.\n request.onupgradeneeded = () => {\n const upgradeDb = request.result;\n if (!upgradeDb.objectStoreNames.contains(KV_STORE)) {\n upgradeDb.createObjectStore(KV_STORE);\n }\n if (!upgradeDb.objectStoreNames.contains(META_STORE)) {\n upgradeDb.createObjectStore(META_STORE);\n }\n };\n db = await new Promise<IDBDatabase>((resolve, reject) => {\n request.onsuccess = () => resolve(request.result);\n request.onerror = () =>\n reject(request.error ?? new CoreError(\"indexedDB open failed\"));\n request.onblocked = () =>\n reject(new CoreError(\"indexedDB open request was blocked\"));\n });\n return db!;\n }\n\n // Start a transaction and give callers both the store and a completion promise.\n const getStore = async (\n storeName: string,\n mode: IDBTransactionMode,\n ): Promise<{ store: IDBObjectStore; done: Promise<void> }> => {\n const database = await ensureOpen();\n const tx = database.transaction(storeName, mode);\n const done = txDone(tx);\n return { store: tx.objectStore(storeName), done };\n };\n\n return {\n async open() {\n await ensureOpen();\n },\n\n async get(key: string) {\n validateKey(key);\n const { store, done } = await getStore(KV_STORE, \"readonly\");\n const result = await wrapRequest(store.get(key));\n await done;\n if (result === undefined) return null;\n return asBytes(result);\n },\n\n async put(key: string, value: Bytes) {\n validateKey(key);\n const { store, done } = await getStore(KV_STORE, \"readwrite\");\n await wrapRequest(store.put(copy(value), key)); // copy avoids shared mutation; revisit if this becomes costly\n await done;\n },\n\n async delete(key: string) {\n validateKey(key);\n const { store, done } = await getStore(KV_STORE, \"readwrite\");\n await wrapRequest(store.delete(key));\n await done;\n },\n\n async batch(ops: BatchOp[]) {\n // Execute the batch within a single transaction to preserve atomicity.\n const database = await ensureOpen();\n const tx = database.transaction(KV_STORE, \"readwrite\");\n const store = tx.objectStore(KV_STORE);\n const done = txDone(tx);\n try {\n // Replay the batch within a single transaction; validation failure aborts everything.\n for (const op of ops) {\n if (op.put) {\n const [key, value] = op.put;\n validateKey(key);\n store.put(copy(value), key); // copy avoids shared mutation; revisit if this becomes costly\n }\n if (op.del) {\n validateKey(op.del);\n store.delete(op.del);\n }\n }\n await done;\n } catch (err) {\n try {\n tx.abort();\n } catch {\n /* noop */\n }\n await done.catch(() => {});\n throw err;\n }\n },\n\n async iter(options: IterOptions = {}) {\n if (options.start && options.end && options.start > options.end) {\n throw new CoreError(\"iter start bound must not exceed end bound\");\n }\n\n const range = buildKeyRange(options);\n if (range === null) return [];\n\n const { store, done } = await getStore(KV_STORE, \"readonly\");\n const direction: IDBCursorDirection = options.reverse ? \"prev\" : \"next\";\n const limit = options.limit ?? Infinity;\n const results: KvPair[] = [];\n\n await new Promise<void>((resolve, reject) => {\n const request = store.openCursor(range, direction);\n request.onsuccess = () => {\n const cursor = request.result;\n if (!cursor || results.length >= limit) {\n resolve();\n return;\n }\n if (typeof cursor.key !== \"string\") {\n cursor.continue();\n return;\n }\n try {\n results.push({ key: cursor.key, value: asBytes(cursor.value) });\n } catch {\n // Skip records with corrupt/unreadable values (P2-07 resilience)\n cursor.continue();\n return;\n }\n cursor.continue();\n };\n request.onerror = () =>\n reject(request.error ?? new CoreError(\"indexedDB cursor failed\"));\n });\n\n await done;\n return results;\n },\n\n async count(prefix?: string) {\n const { store, done } = await getStore(KV_STORE, \"readonly\");\n const range = prefix\n ? IDBKeyRange.bound(prefix, prefix + \"\\uffff\", false, false)\n : undefined;\n const result = await wrapRequest(store.count(range));\n await done;\n return result;\n },\n\n async getSchemaVersion() {\n const { store, done } = await getStore(META_STORE, \"readonly\");\n const value = await wrapRequest<number | undefined>(\n store.get(SCHEMA_KEY),\n );\n await done;\n return value ?? 0;\n },\n\n async setSchemaVersion(version) {\n const { store, done } = await getStore(META_STORE, \"readwrite\");\n await wrapRequest(store.put(version, SCHEMA_KEY));\n await done;\n },\n };\n}\n","import { SchemaMismatchError } from \"./errors.js\";\nimport type { Storage } from \"./types.js\";\n\nexport const CORE_SCHEMA_VERSION = 1;\n\nexport async function migrate(storage: Storage) {\n await storage.open();\n const current = await storage.getSchemaVersion();\n if (current === 0) {\n // seed structures if needed\n await storage.setSchemaVersion(CORE_SCHEMA_VERSION);\n return;\n }\n if (current !== CORE_SCHEMA_VERSION) {\n throw new SchemaMismatchError(current, CORE_SCHEMA_VERSION);\n }\n}\n","import { InitializationError } from \"./errors.js\";\nimport { migrate } from \"./schema.js\";\nimport type { Storage } from \"./types.js\";\n\nexport type CoreDeps = {\n storage: Storage;\n rng: (n: number) => Uint8Array;\n};\n\nexport async function initCore(deps: CoreDeps) {\n if (!deps?.storage) throw new InitializationError(\"storage dep required\");\n if (!deps?.rng) throw new InitializationError(\"rng dep required\");\n\n await migrate(deps.storage);\n return {\n storage: deps.storage,\n rng: deps.rng,\n };\n}\n","import {\n IMT,\n IMTMerkleProof,\n type IMTHashFunction,\n type IMTNode,\n} from \"@zk-kit/imt\";\n\nimport { poseidon } from \"../../crypto/adapters/index.js\";\nimport { CoreError } from \"../../errors.js\";\nimport { FieldSize, Hex } from \"../../keys/hex.js\";\nimport { ensureChainId } from \"../../utils/validators.js\";\n\ntype BigIntTree = IMT & {\n root: bigint;\n zeroes: bigint[];\n leaves: bigint[];\n};\n\nexport type AddLeafResult = {\n index: number;\n root: string;\n};\n\nexport type MerkleProof = {\n root: string;\n leaf: string;\n pathElements: string[][];\n pathIndices: number[];\n leafIndex: number;\n};\n\nconst DEFAULT_DEPTH = 16;\nconst DEFAULT_ARITY = 2;\nconst ZERO_BYTE_LENGTH = FieldSize.SCALAR;\n\n// Simple adapter: IMTNode[] -> poseidon(bigint[])\nconst hash: IMTHashFunction = (values: IMTNode[]) =>\n poseidon(values.map((v) => BigInt(v)));\n\nconst formatNode = (value: bigint) =>\n Hex.fromBigInt(value, ZERO_BYTE_LENGTH, true);\n\nexport function createLocalMerkleTree() {\n const zeroLeaf = 0n;\n const capacity = 2 ** DEFAULT_DEPTH;\n const tree = new IMT(\n hash,\n DEFAULT_DEPTH,\n zeroLeaf,\n DEFAULT_ARITY,\n ) as BigIntTree;\n\n function addLeaf(value: bigint): AddLeafResult {\n if (tree.leaves.length >= capacity) {\n throw new CoreError(\"merkle tree is full\");\n }\n\n const insertedIndex = tree.leaves.length;\n tree.insert(value);\n\n return {\n index: insertedIndex,\n root: formatNode(tree.root),\n };\n }\n\n function getRoot() {\n return formatNode(tree.root);\n }\n\n function getLeafCount() {\n return tree.leaves.length;\n }\n\n function getLeaf(index: number) {\n const leaf = tree.leaves[index];\n if (leaf === undefined) {\n throw new CoreError(\"leaf does not exist in this tree\");\n }\n return formatNode(BigInt(leaf));\n }\n\n function createMerkleProof(index: number): IMTMerkleProof {\n return tree.createProof(index);\n }\n\n return {\n addLeaf,\n getRoot,\n getLeafCount,\n getLeaf,\n createMerkleProof,\n getZero(level: number) {\n if (level === tree.depth) {\n return getRoot();\n }\n const zero = tree.zeroes[level];\n if (zero === undefined) {\n throw new CoreError(\"invalid level\");\n }\n return formatNode(zero);\n },\n get depth() {\n return tree.depth;\n },\n get capacity() {\n return capacity;\n },\n };\n}\n\nexport type LocalMerkleTree = ReturnType<typeof createLocalMerkleTree>;\n\nexport type LocalMerkleTrees = {\n get(chainId: number): LocalMerkleTree | undefined;\n getOrCreate(chainId: number): LocalMerkleTree;\n addLeaf(chainId: number, value: bigint): AddLeafResult;\n createMerkleProof(chainId: number, index: number): IMTMerkleProof;\n getRoot(chainId: number): string;\n getLeafCount(chainId: number): number;\n reset(chainId: number): void;\n};\n\nexport function createMerkleTrees(): LocalMerkleTrees {\n const trees = new Map<number, LocalMerkleTree>();\n\n const resetTree = (chainId: number) => {\n ensureChainId(chainId);\n const tree = createLocalMerkleTree();\n trees.set(chainId, tree);\n return tree;\n };\n const getOrCreate = (chainId: number) => {\n ensureChainId(chainId);\n let tree = trees.get(chainId);\n if (!tree) {\n tree = resetTree(chainId);\n }\n return tree;\n };\n\n return {\n get(chainId) {\n ensureChainId(chainId);\n return trees.get(chainId);\n },\n getOrCreate,\n addLeaf(chainId, value) {\n return getOrCreate(chainId).addLeaf(value);\n },\n createMerkleProof(chainId, index) {\n return getOrCreate(chainId).createMerkleProof(index);\n },\n getRoot(chainId) {\n return getOrCreate(chainId).getRoot();\n },\n getLeafCount(chainId) {\n return getOrCreate(chainId).getLeafCount();\n },\n reset(chainId) {\n resetTree(chainId);\n },\n };\n}\n\n/**\n * Resolve merkle trees from options or create new instance.\n * @param opts - Options object that may contain merkle trees\n * @returns Merkle trees instance\n */\nexport function resolveMerkleTrees(opts?: {\n merkleTrees?: LocalMerkleTrees;\n}): LocalMerkleTrees {\n return opts?.merkleTrees ?? createMerkleTrees();\n}\n","/**\n * Browser polyfills for Node.js-specific APIs used by dependencies.\n */\n\nimport { Buffer } from \"buffer\";\n\n// Make Buffer available globally for dependencies that expect it\nif (typeof globalThis.Buffer === \"undefined\") {\n globalThis.Buffer = Buffer as typeof Buffer;\n}\n","/**\n * Crypto adapters for browser-compatible cryptographic operations.\n *\n * Exports:\n * - poseidon: Poseidon hash via poseidon-lite (circomlib-compatible)\n * - deriveSpendingPublicKey, signMessage, verifySignature: EdDSA from @zk-kit/eddsa-poseidon\n */\n\n// Polyfill must be the first import\nimport \"./polyfills.js\";\n\nimport {\n poseidon1,\n poseidon2,\n poseidon3,\n poseidon4,\n poseidon5,\n poseidon6,\n poseidon7,\n poseidon8,\n poseidon9,\n poseidon10,\n poseidon11,\n poseidon12,\n poseidon13,\n poseidon14,\n poseidon15,\n poseidon16,\n} from \"poseidon-lite\";\n\ntype PoseidonFn = (inputs: (bigint | number | string)[]) => bigint;\n\n// Index 0 unused — fns[n] handles n inputs\nconst fns: (PoseidonFn | undefined)[] = [\n undefined,\n poseidon1,\n poseidon2,\n poseidon3,\n poseidon4,\n poseidon5,\n poseidon6,\n poseidon7,\n poseidon8,\n poseidon9,\n poseidon10,\n poseidon11,\n poseidon12,\n poseidon13,\n poseidon14,\n poseidon15,\n poseidon16,\n];\n\n/**\n * Poseidon hash for arbitrary-length inputs, compatible with circomlib circuits.\n * - Arity 1-16: native poseidon-lite (matches circomlib exactly)\n * - Arity >16: sponge-style chaining — first 16 elements hashed natively,\n * then remaining absorbed in chunks of 15 with running accumulator\n */\nexport function poseidon(inputs: (bigint | number)[]): bigint {\n const n = inputs.length;\n if (n === 0) throw new Error(\"Poseidon: empty input\");\n if (n <= 16) return fns[n]!(inputs);\n\n // Chain: hash first 16, then absorb remaining in chunks of 15\n let acc = poseidon16(inputs.slice(0, 16));\n let i = 16;\n while (i < n) {\n const chunk = inputs.slice(i, i + 15);\n acc = fns[chunk.length + 1]!([acc, ...chunk]);\n i += 15;\n }\n return acc;\n}\n\nexport {\n derivePublicKey as deriveSpendingPublicKey,\n signMessage,\n verifySignature,\n} from \"@zk-kit/eddsa-poseidon\";\n","import { ValidationError } from \"../errors.js\";\n\nexport enum FieldSize {\n SCALAR = 32,\n}\n\nexport type HexInput =\n | string\n | number\n | bigint\n | Uint8Array\n | ArrayLike<number>;\n\nconst HEX_REGEX = /^[0-9a-f]*$/i;\n\nexport class Hex {\n static strip(value: string): string {\n return value.startsWith(\"0x\") ? value.slice(2) : value;\n }\n\n static encode(data: HexInput): string {\n if (typeof data === \"string\") return Hex.strip(data).toLowerCase();\n if (typeof data === \"number\" || typeof data === \"bigint\") {\n if (data < 0) throw new ValidationError(\"Cannot hexlify negative values\");\n const hex = data.toString(16);\n return hex.length % 2 === 0 ? hex : `0${hex}`;\n }\n return Hex.fromBytes(\n data instanceof Uint8Array ? data : Uint8Array.from(data),\n );\n }\n\n static fromBytes(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n\n static toBytes(hex: string): Uint8Array {\n const h = Hex.strip(hex).toLowerCase();\n if (h.length % 2 !== 0)\n throw new ValidationError(\"Hex string must have an even length\");\n if (!HEX_REGEX.test(h)) throw new ValidationError(\"Invalid hex string\");\n return Uint8Array.from({ length: h.length / 2 }, (_, i) =>\n parseInt(h.slice(i * 2, i * 2 + 2), 16),\n );\n }\n\n static toBigInt(hex: string): bigint {\n return BigInt(`0x${Hex.strip(hex)}`);\n }\n\n static padToSize(data: HexInput, size: FieldSize): string {\n const hex = Hex.encode(data);\n const target = size * 2;\n return hex.length > target\n ? hex.slice(0, target)\n : hex.padStart(target, \"0\");\n }\n\n static fromBigInt(value: bigint, size: FieldSize, prefix = false): string {\n const hex = value.toString(16).padStart(size * 2, \"0\");\n return prefix ? `0x${hex}` : hex;\n }\n}\n","import { bech32m } from \"@scure/base\";\n\nimport { ValidationError } from \"../errors.js\";\nimport { FieldSize, Hex } from \"./hex.js\";\n\nexport type Chain = { type: number; id: number };\nexport type AddressData = {\n masterPublicKey: bigint;\n viewingPublicKey: Uint8Array;\n chain?: Chain;\n version?: number;\n};\n\nconst VERSION = 1;\nconst LIMIT = 127;\nconst ALL_CHAINS = \"ffffffffffffffff\";\nconst PREFIX = \"0zk\";\nconst SALT = new TextEncoder().encode(\"unlink\");\n\nfunction xorWithSalt(hex: string): string {\n const bytes = Hex.toBytes(hex);\n const result = new Uint8Array(bytes.length);\n for (let i = 0; i < bytes.length; i++)\n result[i] = bytes[i]! ^ SALT[i % SALT.length]!;\n return Hex.fromBytes(result);\n}\n\nfunction chainToHex(chain?: Chain): string {\n if (!chain) return ALL_CHAINS;\n return (\n (chain.type & 0xff).toString(16).padStart(2, \"0\") +\n BigInt(chain.id).toString(16).padStart(14, \"0\")\n );\n}\n\nfunction hexToChain(hex: string): Chain | undefined {\n if (hex === ALL_CHAINS) return undefined;\n return {\n type: parseInt(hex.slice(0, 2), 16),\n id: parseInt(hex.slice(2), 16),\n };\n}\n\nexport function encodeAddress(data: AddressData): string {\n const ver = (data.version ?? VERSION).toString(16).padStart(2, \"0\");\n const mpk = Hex.fromBigInt(data.masterPublicKey, FieldSize.SCALAR);\n const vpk = Hex.padToSize(data.viewingPublicKey, FieldSize.SCALAR);\n const net = xorWithSalt(chainToHex(data.chain));\n return bech32m.encode(\n PREFIX,\n bech32m.toWords(Hex.toBytes(`${ver}${mpk}${net}${vpk}`)),\n LIMIT,\n );\n}\n\nexport function decodeAddress(address: string): AddressData {\n if (!address) throw new ValidationError(\"No address to decode\");\n\n const decoded = bech32m.decode(address as `${string}1${string}`, LIMIT);\n if (decoded.prefix !== PREFIX)\n throw new ValidationError(\"Invalid address prefix\");\n\n const hex = Hex.encode(bech32m.fromWords(decoded.words));\n if (hex.length !== 146)\n throw new ValidationError(\"Incorrect address payload length\");\n\n const version = parseInt(hex.slice(0, 2), 16);\n if (version !== VERSION)\n throw new ValidationError(\"Incorrect address version\");\n\n return {\n version,\n masterPublicKey: Hex.toBigInt(hex.slice(2, 66)),\n viewingPublicKey: Hex.toBytes(hex.slice(82, 146)),\n chain: hexToChain(xorWithSalt(hex.slice(66, 82))),\n };\n}\n","import { ValidationError } from \"../errors.js\";\nimport { FieldSize, Hex } from \"../keys/hex.js\";\n\n/**\n * BigInt helpers shared across transaction builders to keep formatting consistent.\n */\nexport function formatUint256(value: bigint): string {\n assertNonNegative(\"uint256\", value);\n return Hex.fromBigInt(value, FieldSize.SCALAR, true);\n}\n\nexport function parseHexToBigInt(value: string): bigint {\n return Hex.toBigInt(value);\n}\n\nexport function assertNonNegative(label: string, value: bigint): void {\n if (value < 0n) {\n throw new ValidationError(`${label} must be non-negative`);\n }\n}\n","import { ValidationError } from \"../errors.js\";\nimport { decodeAddress, type Chain } from \"../keys/address.js\";\nimport { WithdrawalNoteInput } from \"../transactions/types/index.js\";\nimport { assertNonNegative } from \"./bigint.js\";\n\nexport const SNARK_SCALAR_FIELD =\n 21_888_242_871_839_275_222_246_405_745_257_275_088_548_364_400_416_034_343_698_204_186_575_808_495_617n;\n\nexport function ensurePositiveInt(label: string, value: number) {\n if (!Number.isInteger(value) || value < 0) {\n throw new ValidationError(`${label} must be a non-negative integer`);\n }\n}\n\nexport function ensureChainId(chainId: number) {\n if (!Number.isInteger(chainId) || chainId <= 0) {\n throw new ValidationError(\"chainId must be a positive integer\");\n }\n}\n\n/** Guards master public key strings against empty values. */\nexport function ensureMpk(mpk: string) {\n if (typeof mpk !== \"string\" || mpk.length === 0) {\n throw new ValidationError(\"note mpk must be a non-empty string\");\n }\n}\n\nexport function ensureBigIntString(label: string, value: string) {\n let parsed: bigint;\n try {\n parsed = BigInt(value);\n } catch {\n throw new ValidationError(`${label} must be a base-10 bigint string`);\n }\n if (parsed < 0n) {\n throw new ValidationError(`${label} must be non-negative`);\n }\n}\n\nconst ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;\n\nexport function ensureAddress(label: string, value: string): `0x${string}` {\n if (typeof value !== \"string\" || !ADDRESS_REGEX.test(value)) {\n throw new ValidationError(\n `${label} must be a 0x-prefixed hex address, received: ${value}`,\n );\n }\n return value.toLowerCase() as `0x${string}`;\n}\n\n/** Confirms the bigint resides in the SNARK scalar field range. */\nexport function ensureFieldElement(label: string, value: bigint) {\n if (value < 0n) {\n throw new ValidationError(`${label} must be a non-negative field element`);\n }\n if (value >= SNARK_SCALAR_FIELD) {\n throw new ValidationError(\n `${label} must be less than the SNARK scalar field`,\n );\n }\n}\n\n/** Validates withdrawal note public data before encoding calldata. */\nexport function ensureWithdrawalInput(\n label: string,\n withdrawal: WithdrawalNoteInput | undefined,\n) {\n if (!withdrawal) {\n return undefined;\n }\n assertNonNegative(`${label}.npk`, withdrawal.npk);\n ensureFieldElement(`${label}.npk`, withdrawal.npk);\n assertNonNegative(`${label}.amount`, withdrawal.amount);\n ensureFieldElement(`${label}.amount`, withdrawal.amount);\n ensureAddress(`${label}.token`, withdrawal.token);\n return withdrawal;\n}\n\n/** Validates note parameters before producing a Poseidon commitment. */\nexport function ensureNoteCommitmentInput(\n label: string,\n note: { npk: bigint; amount: bigint; token: string },\n) {\n assertNonNegative(`${label}.npk`, note.npk);\n ensureFieldElement(`${label}.npk`, note.npk);\n assertNonNegative(`${label}.amount`, note.amount);\n if (note.amount === 0n) {\n throw new ValidationError(`${label}.amount must be greater than zero`);\n }\n ensureFieldElement(`${label}.amount`, note.amount);\n ensureAddress(`${label}.token`, note.token);\n return note;\n}\n\n/**\n * Parsed ZK address containing the master public key, viewing public key,\n * and optional chain info.\n */\nexport type ParsedZkAddress = {\n masterPublicKey: bigint;\n viewingPublicKey: Uint8Array;\n chain?: Chain;\n};\n\n/**\n * Parses a Bech32m ZK address (0zk1...) into its components.\n *\n * @param value - The Bech32m address string\n * @returns Parsed address with masterPublicKey, viewingPublicKey, and optional chain\n * @throws ValidationError if the address is invalid\n */\nexport function parseZkAddress(value: string): ParsedZkAddress {\n const trimmed = value.trim();\n\n try {\n const decoded = decodeAddress(trimmed);\n return {\n masterPublicKey: decoded.masterPublicKey,\n viewingPublicKey: decoded.viewingPublicKey,\n chain: decoded.chain,\n };\n } catch (err) {\n throw new ValidationError(\n `Invalid ZK address (expected 0zk1... format): ${err instanceof Error ? err.message : \"unknown error\"}`,\n );\n }\n}\n","import { CoreError } from \"../../errors.js\";\nimport { parseHexToBigInt } from \"../../utils/bigint.js\";\n\nexport type BatchLeafLoader = (\n chainId: number,\n) => Promise<{ commitment: string; index: number }[]>;\n\ntype TreesInterface = {\n reset(chainId: number): void;\n addLeaf(chainId: number, value: bigint): { index: number };\n getLeafCount?(chainId: number): number;\n};\n\nexport async function rebuildTreeFromStore({\n chainId,\n trees,\n loadLeaves,\n}: {\n chainId: number;\n trees: TreesInterface;\n loadLeaves: BatchLeafLoader;\n}) {\n trees.reset(chainId);\n\n const leaves = await loadLeaves(chainId);\n for (const leaf of leaves) {\n const { index } = trees.addLeaf(chainId, parseHexToBigInt(leaf.commitment));\n if (index !== leaf.index) {\n throw new CoreError(\n `stored leaves are inconsistent with local tree, expected ${leaf.index}, got ${index}`,\n );\n }\n }\n return leaves.length;\n}\n\nexport type HydrateChainParams = {\n chainId: number;\n trees: TreesInterface;\n loadLeaves: BatchLeafLoader;\n hydrated: Set<number>;\n};\n\n/**\n * Hydrate the in-memory merkle tree for a chain, skipping if already done.\n * Call `hydrated.delete(chainId)` to invalidate and force a rebuild.\n */\nexport async function hydrateChain({\n chainId,\n trees,\n loadLeaves,\n hydrated,\n}: HydrateChainParams): Promise<number> {\n if (hydrated.has(chainId)) {\n return trees.getLeafCount?.(chainId) ?? 0;\n }\n const count = await rebuildTreeFromStore({\n chainId,\n trees,\n loadLeaves,\n });\n hydrated.add(chainId);\n return count;\n}\n","import { CoreError } from \"../errors.js\";\nimport { validateKey } from \"../keys.js\";\nimport { Storage } from \"../types.js\";\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nexport type JsonRecord = { [key: string]: unknown };\n\nexport function encodeJson(value: JsonRecord): Uint8Array {\n return encoder.encode(JSON.stringify(value));\n}\n\nexport function decodeJson<T extends JsonRecord>(payload: Uint8Array): T {\n try {\n return JSON.parse(decoder.decode(payload)) as T;\n } catch {\n throw new CoreError(\"failed to decode stored state payload\");\n }\n}\n\nexport async function putJson(\n storage: Storage,\n key: string,\n record: JsonRecord,\n) {\n validateKey(key);\n await storage.put(key, encodeJson(record));\n}\n\nexport async function getJson<T extends JsonRecord>(\n storage: Storage,\n key: string,\n) {\n const payload = await storage.get(key);\n if (!payload) return null;\n return decodeJson<T>(payload);\n}\n","import { keys, validateKey } from \"../../keys.js\";\nimport type { Storage } from \"../../types.js\";\nimport { ensureChainId, ensurePositiveInt } from \"../../utils/validators.js\";\n\nexport function createCiphertextStore(storage: Storage) {\n return {\n /**\n * Store encrypted note payloads alongside their on-chain commitments.\n */\n async putCiphertext(chainId: number, index: number, payload: Uint8Array) {\n ensureChainId(chainId);\n ensurePositiveInt(\"ciphertext index\", index);\n const key = keys.ciphertext(chainId, index);\n validateKey(key);\n await storage.put(key, new Uint8Array(payload));\n },\n\n /**\n * Retrieve encrypted note payloads; returns null when the ciphertext is missing.\n */\n async getCiphertext(chainId: number, index: number) {\n ensureChainId(chainId);\n ensurePositiveInt(\"ciphertext index\", index);\n const data = await storage.get(keys.ciphertext(chainId, index));\n return data ? new Uint8Array(data) : null;\n },\n\n /**\n * Load all cached ciphertexts for a chain in index order.\n */\n async listCiphertexts(\n chainId: number,\n ): Promise<{ index: number; payload: Uint8Array }[]> {\n ensureChainId(chainId);\n const prefix = `ciphertexts:${chainId}:`;\n const entries = await storage.iter({ prefix });\n return entries\n .map(({ key, value }) => ({\n index: parseInt(key.slice(key.lastIndexOf(\":\") + 1), 10),\n payload: new Uint8Array(value),\n }))\n .sort((a, b) => a.index - b.index);\n },\n\n /**\n * Remove all cached ciphertexts for a chain.\n */\n async clearCiphertexts(chainId: number) {\n ensureChainId(chainId);\n const prefix = `ciphertexts:${chainId}:`;\n const entries = await storage.iter({ prefix });\n if (entries.length === 0) return;\n const deletions = entries.map(({ key }) => ({ del: key }));\n await storage.batch(deletions);\n },\n };\n}\n","import type { HistoryEntry } from \"../../history/types.js\";\nimport { keys } from \"../../keys.js\";\nimport type { Storage } from \"../../types.js\";\nimport {\n decodeJson,\n encodeJson,\n type JsonRecord,\n} from \"../../utils/json-codec.js\";\nimport { ensureChainId, ensureMpk } from \"../../utils/validators.js\";\n\ntype HistoryEntryRecord = HistoryEntry;\ntype HistoryMetaRecord = { v: 1; updatedAtMs: number };\n\nexport function createHistoryStore(storage: Storage) {\n async function putMeta(options: { chainId: number; mpk: string }) {\n await storage.put(\n keys.historyMeta(options.chainId, options.mpk),\n encodeJson({ v: 1, updatedAtMs: Date.now() } satisfies HistoryMetaRecord),\n );\n }\n\n return {\n async putHistoryEntry(entry: HistoryEntryRecord) {\n ensureChainId(entry.chainId);\n ensureMpk(entry.mpk);\n const key = keys.historyEntry(entry.id);\n await storage.put(key, encodeJson(entry as JsonRecord));\n },\n\n async hasHistorySnapshot(options: { chainId: number; mpk: string }) {\n ensureChainId(options.chainId);\n ensureMpk(options.mpk);\n const meta = await storage.get(\n keys.historyMeta(options.chainId, options.mpk),\n );\n return meta !== null;\n },\n\n async listHistoryEntries(options: { chainId: number; mpk: string }) {\n ensureChainId(options.chainId);\n ensureMpk(options.mpk);\n const prefix = keys.historyPrefix(options.chainId, options.mpk);\n const entries = await storage.iter({ prefix });\n const decoded = entries\n .filter(({ key }) => !key.endsWith(\":__meta__\"))\n .map(({ value }) => decodeJson<HistoryEntry>(value));\n decoded.sort((a, b) => {\n const at = a.timestamp ?? 0;\n const bt = b.timestamp ?? 0;\n if (at !== bt) return bt - at;\n return b.txHash.localeCompare(a.txHash);\n });\n return decoded;\n },\n\n async clearHistoryEntries(options: { chainId: number; mpk: string }) {\n ensureChainId(options.chainId);\n ensureMpk(options.mpk);\n const prefix = keys.historyPrefix(options.chainId, options.mpk);\n const existing = await storage.iter({ prefix });\n if (existing.length === 0) return;\n await storage.batch(existing.map(({ key }) => ({ del: key })));\n },\n\n async commitHistorySnapshot(options: { chainId: number; mpk: string }) {\n ensureChainId(options.chainId);\n ensureMpk(options.mpk);\n await putMeta(options);\n },\n };\n}\n","import type { HistoryAmount, HistoryKind } from \"../../history/types.js\";\nimport type { SerializedWitness } from \"../../transactions/types/domain.js\";\n\nexport type JobStatus =\n | \"pending\"\n | \"submitted\"\n | \"broadcasting\"\n | \"succeeded\"\n | \"failed\"\n | \"dead\";\n\nexport type JobKind = \"deposit\" | \"transfer\" | \"withdraw\" | \"adapter\";\n\nexport type JobRecordBase = {\n relayId: string;\n kind: JobKind;\n chainId: number;\n /** Master public key (hex string) for correlating jobs with history/account views. */\n mpk?: string;\n status: JobStatus;\n txHash?: string | null;\n createdAt: number;\n lastCheckedAt?: number;\n timeoutMs: number;\n error?: string | null;\n /**\n * Optional history preview so UIs can show pending/failed history rows before notes are indexed.\n * Amount deltas follow HistoryAmount semantics (positive receive, negative send).\n */\n historyPreview?: {\n kind: HistoryKind;\n amounts: HistoryAmount[];\n };\n};\n\n/**\n * Predicted commitment info for deposits.\n */\nexport type PredictedCommitment = {\n hex: string;\n token: string;\n amount: string;\n index?: number;\n root?: string;\n};\n\n/**\n * Record for tracking deposits\n */\nexport type DepositRecord = JobRecordBase & {\n kind: \"deposit\";\n /** Predicted commitments for each note */\n predictedCommitments: PredictedCommitment[];\n};\n\nexport type TransactContext = {\n index: number;\n nullifier: string;\n witness: SerializedWitness;\n root: string;\n};\n\nexport type TransactOutput = {\n hex: string;\n index: number;\n root?: string;\n};\n\n/**\n * Individual transaction info within a transact job.\n */\nexport type TransactJobTransaction = {\n token: string;\n nullifiers: string[];\n predictedCommitments: Array<{ hex: string; index?: number }>;\n /** For withdrawals: amount and recipient */\n withdrawal?: {\n amount: string;\n recipient: string;\n };\n};\n\n/** Fields shared by transfer and withdraw records */\ntype PoolTransactionFields = {\n poolAddress: string;\n calldata: string;\n /** Individual transactions in the batch */\n transactions: TransactJobTransaction[];\n};\n\nexport type TransferRecord = JobRecordBase &\n PoolTransactionFields & {\n kind: \"transfer\";\n };\n\nexport type WithdrawRecord = JobRecordBase &\n PoolTransactionFields & {\n kind: \"withdraw\";\n };\n\nexport type AdapterRecord = JobRecordBase &\n PoolTransactionFields & {\n kind: \"adapter\";\n adapterAddress: string;\n adapterCalldata: string;\n };\n\n/** Union of all pool transaction records */\nexport type PoolTransactionRecord =\n | TransferRecord\n | WithdrawRecord\n | AdapterRecord;\n\n/** Union of all job records */\nexport type JobRecord =\n | DepositRecord\n | TransferRecord\n | WithdrawRecord\n | AdapterRecord;\n\nexport const DEFAULT_JOB_TIMEOUT_MS = 5 * 60 * 1000;\n","import { CoreError } from \"../../errors.js\";\nimport { keys } from \"../../keys.js\";\nimport type { Storage } from \"../../types.js\";\nimport { decodeJson, encodeJson, getJson } from \"../../utils/json-codec.js\";\nimport {\n ensureAddress,\n ensureChainId,\n ensureMpk,\n ensurePositiveInt,\n} from \"../../utils/validators.js\";\nimport type {\n AdapterRecord,\n DepositRecord,\n JobKind,\n JobRecord,\n JobStatus,\n PoolTransactionRecord,\n} from \"../store/jobs.js\";\nimport { DEFAULT_JOB_TIMEOUT_MS } from \"../store/jobs.js\";\n\nconst VALID_STATUSES: JobStatus[] = [\n \"pending\",\n \"submitted\",\n \"broadcasting\",\n \"succeeded\",\n \"failed\",\n \"dead\",\n] as const;\n\nconst VALID_KINDS: JobKind[] = [\n \"deposit\",\n \"transfer\",\n \"withdraw\",\n \"adapter\",\n] as const;\n\nfunction assertStatus(status: string): asserts status is JobStatus {\n if (!VALID_STATUSES.includes(status as JobStatus)) {\n throw new CoreError(`invalid job status: ${status}`);\n }\n}\n\nfunction assertKind(kind: string): asserts kind is JobKind {\n if (!VALID_KINDS.includes(kind as JobKind)) {\n throw new CoreError(`invalid job kind: ${kind}`);\n }\n}\n\nfunction normalizeTimestamps<T extends JobRecord>(job: T): T {\n const createdAt =\n typeof job.createdAt === \"number\" && Number.isFinite(job.createdAt)\n ? job.createdAt\n : Date.now();\n const timeoutMs =\n typeof job.timeoutMs === \"number\" && job.timeoutMs > 0\n ? job.timeoutMs\n : DEFAULT_JOB_TIMEOUT_MS;\n\n return {\n ...job,\n createdAt,\n timeoutMs,\n };\n}\n\nfunction validatePoolTransactionRecord(job: PoolTransactionRecord) {\n ensureAddress(\"pool address\", job.poolAddress);\n if (!job.calldata) {\n throw new CoreError(\"calldata is required for pool transaction record\");\n }\n if (!Array.isArray(job.transactions) || !job.transactions.length) {\n throw new CoreError(\"transactions array is required\");\n }\n for (let i = 0; i < job.transactions.length; i++) {\n const tx = job.transactions[i]!;\n ensureAddress(`transaction token at ${i}`, tx.token);\n if (!Array.isArray(tx.nullifiers) || !tx.nullifiers.length) {\n throw new CoreError(`nullifiers array is required at index ${i}`);\n }\n // predictedCommitments can be empty for withdrawals with no change\n if (!Array.isArray(tx.predictedCommitments)) {\n throw new CoreError(\n `predicted commitments array is required at index ${i}`,\n );\n }\n // Only require non-empty commitments if there's no withdrawal\n if (!tx.predictedCommitments.length && !tx.withdrawal) {\n throw new CoreError(`predicted commitments are required at index ${i}`);\n }\n for (let j = 0; j < tx.predictedCommitments.length; j++) {\n const c = tx.predictedCommitments[j]!;\n if (!c.hex) {\n throw new CoreError(\n `predicted commitment hex is required at index ${i}.${j}`,\n );\n }\n }\n if (tx.withdrawal) {\n if (!tx.withdrawal.amount) {\n throw new CoreError(`withdrawal amount is required at index ${i}`);\n }\n if (!tx.withdrawal.recipient) {\n throw new CoreError(`withdrawal recipient is required at index ${i}`);\n }\n }\n }\n}\n\nfunction validateDepositRecord(job: DepositRecord) {\n if (\n !Array.isArray(job.predictedCommitments) ||\n !job.predictedCommitments.length\n ) {\n throw new CoreError(\"predicted commitments array is required for deposit\");\n }\n for (let i = 0; i < job.predictedCommitments.length; i++) {\n const c = job.predictedCommitments[i]!;\n if (!c.hex) {\n throw new CoreError(`predicted commitment hex is required at index ${i}`);\n }\n ensureAddress(`predicted commitment token at ${i}`, c.token);\n if (!c.amount) {\n throw new CoreError(\n `predicted commitment amount is required at index ${i}`,\n );\n }\n if (c.index !== undefined) {\n ensurePositiveInt(`predicted commitment index at ${i}`, c.index);\n }\n }\n}\n\nfunction validateAdapterRecord(job: AdapterRecord) {\n ensureAddress(\"adapter address\", job.adapterAddress);\n if (!job.adapterCalldata) {\n throw new CoreError(\"adapterCalldata is required for adapter record\");\n }\n}\n\nfunction validateJob(job: JobRecord) {\n if (!job.relayId) {\n throw new CoreError(\"relayId is required\");\n }\n ensureChainId(job.chainId);\n if (job.mpk !== undefined) {\n ensureMpk(job.mpk);\n }\n assertStatus(job.status);\n assertKind(job.kind);\n ensurePositiveInt(\"job createdAt\", job.createdAt);\n ensurePositiveInt(\"job timeoutMs\", job.timeoutMs);\n if (job.lastCheckedAt !== undefined) {\n ensurePositiveInt(\"job lastCheckedAt\", job.lastCheckedAt);\n }\n if (job.kind === \"deposit\") {\n validateDepositRecord(job);\n } else {\n validatePoolTransactionRecord(job as PoolTransactionRecord);\n if (job.kind === \"adapter\") {\n validateAdapterRecord(job as AdapterRecord);\n }\n }\n}\n\nfunction buildJobKey(relayId: string) {\n return keys.job(relayId);\n}\n\nexport function createJobStore(storage: Storage) {\n return {\n async putJob(job: JobRecord) {\n const normalized = normalizeTimestamps(job);\n validateJob(normalized);\n await storage.put(\n buildJobKey(normalized.relayId),\n encodeJson(normalized),\n );\n },\n\n async getJob(relayId: string) {\n return getJson<JobRecord>(storage, buildJobKey(relayId));\n },\n\n async listJobs(\n filter: {\n kind?: JobKind;\n statuses?: JobStatus[];\n } = {},\n ) {\n const entries = await storage.iter({ prefix: \"jobs:\" });\n const statuses = filter.statuses ?? VALID_STATUSES;\n const filtered = entries\n .map(({ value }) => decodeJson<JobRecord>(value))\n .filter(\n (job) =>\n (filter.kind === undefined || job.kind === filter.kind) &&\n statuses.includes(job.status),\n );\n filtered.sort((a, b) => a.createdAt - b.createdAt);\n return filtered;\n },\n\n async deleteJob(relayId: string) {\n await storage.delete(buildJobKey(relayId));\n },\n };\n}\n","import { keys } from \"../../keys.js\";\nimport type { Storage } from \"../../types.js\";\nimport { decodeJson, getJson, putJson } from \"../../utils/json-codec.js\";\nimport { ensureChainId, ensurePositiveInt } from \"../../utils/validators.js\";\nimport type { LeafRecord } from \"../store/records.js\";\n\nexport function createLeafStore(storage: Storage) {\n return {\n /**\n * Cache public leaf data pulled from the on-chain Merkle tree.\n */\n async putLeaf(leaf: LeafRecord) {\n ensureChainId(leaf.chainId);\n ensurePositiveInt(\"leaf index\", leaf.index);\n await putJson(storage, keys.leaf(leaf.chainId, leaf.index), leaf);\n },\n\n /**\n * Load a leaf commitment by tree index.\n */\n async getLeaf(chainId: number, index: number) {\n return getJson<LeafRecord>(storage, keys.leaf(chainId, index));\n },\n\n /**\n * Load all cached leaves for a chain in index order.\n */\n async listLeaves(chainId: number): Promise<LeafRecord[]> {\n const prefix = `leaves:${chainId}:`;\n const entries = await storage.iter({ prefix });\n return entries\n .map(({ value }) => decodeJson<LeafRecord>(value))\n .sort((a, b) => a.index - b.index);\n },\n\n /**\n * Remove all cached leaves for a chain.\n */\n async clearLeaves(chainId: number) {\n const prefix = `leaves:${chainId}:`;\n const entries = await storage.iter({ prefix });\n if (entries.length === 0) return;\n const deletions = entries.map(({ key }) => ({ del: key }));\n await storage.batch(deletions);\n },\n };\n}\n","import { CoreError } from \"../../errors.js\";\nimport { keys } from \"../../keys.js\";\nimport type { BatchOp, Storage } from \"../../types.js\";\nimport {\n decodeJson,\n encodeJson,\n getJson,\n type JsonRecord,\n} from \"../../utils/json-codec.js\";\nimport {\n ensureBigIntString,\n ensureChainId,\n ensureMpk,\n ensurePositiveInt,\n} from \"../../utils/validators.js\";\n// Note: Validation functions are used in persistNote() for write operations.\n// Read operations trust that callers have validated inputs at the SDK boundary.\nimport type { NoteInsert, NoteRecord } from \"../store/records.js\";\n\nexport const emptyBytes = () => new Uint8Array(0);\n\nexport function createNoteStore(storage: Storage) {\n const persistNote = async (record: NoteRecord) => {\n ensureChainId(record.chainId);\n ensurePositiveInt(\"note index\", record.index);\n ensureMpk(record.mpk);\n ensureBigIntString(\"note value\", record.value);\n if (record.createdAt !== undefined) {\n ensurePositiveInt(\"note createdAt\", record.createdAt);\n }\n if (record.spentAt !== undefined) {\n ensurePositiveInt(\"note spentAt\", record.spentAt);\n }\n if (\n record.createdTxHash !== undefined &&\n record.createdTxHash.length === 0\n ) {\n throw new CoreError(\"note createdTxHash must be a non-empty string\");\n }\n if (\n record.createdEventType !== undefined &&\n record.createdEventType.length === 0\n ) {\n throw new CoreError(\"note createdEventType must be a non-empty string\");\n }\n if (record.spentTxHash !== undefined && record.spentTxHash.length === 0) {\n throw new CoreError(\"note spentTxHash must be a non-empty string\");\n }\n\n const noteKey = keys.note(record.chainId, record.index);\n const previous = await getJson<NoteRecord>(storage, noteKey);\n\n const ops: BatchOp[] = [\n { put: [noteKey, encodeJson(record as JsonRecord)] },\n ];\n\n if (previous && previous.spentAt === undefined) {\n ops.push({\n del: keys.unspent(previous.chainId, previous.mpk, previous.index),\n });\n }\n\n if (record.spentAt === undefined) {\n // idx:notes:unspent functions as a set, so we only persist the sentinel bytes.\n ops.push({\n put: [\n keys.unspent(record.chainId, record.mpk, record.index),\n emptyBytes(),\n ],\n });\n } else {\n ops.push({\n del: keys.unspent(record.chainId, record.mpk, record.index),\n });\n }\n\n await storage.batch(ops);\n };\n\n const store = {\n /**\n * Upsert a note record and maintain the unspent-note index for fast balance queries.\n * If the note already exists and is marked as spent, preserve spentAt unless the caller\n * provides an explicit spentAt value (eg. upgrading from a local observation time to an\n * on-chain timestamp from the indexer).\n */\n async putNote(note: NoteInsert) {\n const noteKey = keys.note(note.chainId, note.index);\n const existing = await getJson<NoteRecord>(storage, noteKey);\n if (existing?.spentAt !== undefined && note.spentAt === undefined) {\n // Preserve spentAt if caller doesn't provide a value.\n await persistNote({ ...note, spentAt: existing.spentAt });\n } else {\n await persistNote({ ...note });\n }\n },\n\n /**\n * Fetch a note by (chainId, index) if it exists in local storage.\n */\n async getNote(chainId: number, index: number) {\n return getJson<NoteRecord>(storage, keys.note(chainId, index));\n },\n\n /**\n * List notes matching optional filters (by chainId, mpk) and spent state.\n */\n async listNotes(\n options: {\n chainId?: number;\n mpk?: string;\n token?: string;\n includeSpent?: boolean;\n } = {},\n ) {\n const { chainId, mpk, token, includeSpent = true } = options;\n const prefix = chainId !== undefined ? `notes:${chainId}:` : \"notes:\";\n const entries = await storage.iter({ prefix });\n const filtered = entries\n .map(({ value }) => decodeJson<NoteRecord>(value))\n .filter(\n (note) =>\n (chainId === undefined || note.chainId === chainId) &&\n (mpk === undefined || note.mpk === mpk) &&\n (token === undefined || note.token === token) &&\n (includeSpent || note.spentAt === undefined),\n );\n filtered.sort((a, b) => a.index - b.index);\n return filtered;\n },\n\n /**\n * Mark a cached note as spent by setting its timestamp and transaction hash.\n */\n async markNoteSpent(\n chainId: number,\n index: number,\n spentAt = Date.now(),\n spentTxHash?: string,\n ) {\n const existing = await store.getNote(chainId, index);\n if (!existing) {\n throw new CoreError(\"note not found\");\n }\n if (\n existing.spentAt === spentAt &&\n existing.spentTxHash === spentTxHash\n ) {\n return existing;\n }\n const updated: NoteRecord = { ...existing, spentAt, spentTxHash };\n await persistNote(updated);\n return updated;\n },\n\n /**\n * Drop the spent marker from a cached note, returning it to the unspent index.\n */\n async markNoteUnspent(chainId: number, index: number) {\n const existing = await store.getNote(chainId, index);\n if (!existing) {\n throw new CoreError(\"note not found\");\n }\n if (existing.spentAt === undefined) {\n return existing;\n }\n const updated: NoteRecord = { ...existing };\n delete updated.spentAt;\n await persistNote(updated);\n return updated;\n },\n\n /**\n * Remove all cached notes and their unspent indices for a chain.\n */\n async clearNotes(chainId: number) {\n const notePrefix = `notes:${chainId}:`;\n const noteEntries = await storage.iter({ prefix: notePrefix });\n\n // Also clear unspent indices for this chain (all mpks)\n const unspentPrefix = `idx:notes:unspent:${chainId}:`;\n const unspentEntries = await storage.iter({ prefix: unspentPrefix });\n\n if (noteEntries.length === 0 && unspentEntries.length === 0) return;\n\n const deletions = [\n ...noteEntries.map(({ key }) => ({ del: key })),\n ...unspentEntries.map(({ key }) => ({ del: key })),\n ];\n await storage.batch(deletions);\n },\n };\n\n return store;\n}\n","import { keys } from \"../../keys.js\";\nimport type { Storage } from \"../../types.js\";\nimport { getJson, putJson } from \"../../utils/json-codec.js\";\nimport { ensureChainId } from \"../../utils/validators.js\";\nimport type { NullifierRecord } from \"../store/records.js\";\n\nexport function createNullifierStore(storage: Storage) {\n return {\n /**\n * Record a nullifier observation so later syncs can de-duplicate work.\n */\n async putNullifier(nullifier: NullifierRecord) {\n ensureChainId(nullifier.chainId);\n await putJson(\n storage,\n keys.nullifier(nullifier.chainId, nullifier.nullifier),\n nullifier,\n );\n },\n\n /**\n * Lookup a previously observed nullifier by value.\n */\n async getNullifier(chainId: number, value: string) {\n return getJson<NullifierRecord>(storage, keys.nullifier(chainId, value));\n },\n\n /**\n * Count all nullifiers stored locally for a given chain.\n */\n async countNullifiers(chainId: number): Promise<number> {\n return storage.count(`nullifiers:${chainId}:`);\n },\n\n /**\n * Remove all cached nullifiers for a chain.\n */\n async clearNullifiers(chainId: number): Promise<void> {\n const prefix = `nullifiers:${chainId}:`;\n const entries = await storage.iter({ prefix });\n if (entries.length === 0) return;\n await storage.batch(entries.map(({ key }) => ({ del: key })));\n },\n\n /**\n * Remove cached nullifiers whose noteIndex >= fromIndex.\n * Used by partial resync to keep the count-based optimization accurate.\n */\n async clearNullifiersFromIndex(\n chainId: number,\n fromIndex: number,\n ): Promise<void> {\n const prefix = `nullifiers:${chainId}:`;\n const entries = await storage.iter({ prefix });\n const ops: { del: string }[] = [];\n for (const { key, value } of entries) {\n try {\n const record = JSON.parse(\n new TextDecoder().decode(value),\n ) as NullifierRecord;\n if (record.noteIndex === undefined || record.noteIndex >= fromIndex) {\n ops.push({ del: key });\n }\n } catch {\n // Malformed entry — skip\n }\n }\n if (ops.length > 0) await storage.batch(ops);\n },\n };\n}\n","import { CoreError } from \"../../errors.js\";\nimport { keys, validateKey } from \"../../keys.js\";\nimport type { Storage } from \"../../types.js\";\nimport { getJson, putJson } from \"../../utils/json-codec.js\";\nimport { ensureChainId } from \"../../utils/validators.js\";\nimport type { RootRecord } from \"../store/records.js\";\n\nexport function createRootStore(storage: Storage) {\n return {\n /**\n * Persist a historical root snapshot for proof generation.\n */\n async putRoot(root: RootRecord) {\n ensureChainId(root.chainId);\n if (typeof root.root !== \"string\" || root.root.length === 0) {\n throw new CoreError(\"root value must be a non-empty string\");\n }\n const key = keys.root(root.chainId, root.root);\n validateKey(key);\n await putJson(storage, key, root);\n },\n\n /**\n * Retrieve a root snapshot by Merkle root value.\n */\n async getRoot(chainId: number, value: string) {\n return getJson<RootRecord>(storage, keys.root(chainId, value));\n },\n };\n}\n","import type { HistoryEntry } from \"../../history/types.js\";\nimport { keys } from \"../../keys.js\";\nimport type { BatchOp, Storage } from \"../../types.js\";\nimport { encodeJson, type JsonRecord } from \"../../utils/json-codec.js\";\nimport { createCiphertextStore } from \"./ciphertext-store.js\";\nimport { createHistoryStore } from \"./history-store.js\";\nimport { createJobStore } from \"./job-store.js\";\nimport type { JobKind, JobRecord, JobStatus } from \"./jobs.js\";\nimport { createLeafStore } from \"./leaf-store.js\";\nimport { createNoteStore, emptyBytes } from \"./note-store.js\";\nimport { createNullifierStore } from \"./nullifier-store.js\";\nimport type {\n LeafRecord,\n NoteInsert,\n NoteRecord,\n NullifierRecord,\n RootRecord,\n} from \"./records.js\";\nimport { createRootStore } from \"./root-store.js\";\n\nexport interface StateStore {\n // Notes\n putNote(note: NoteInsert): Promise<void>;\n getNote(chainId: number, index: number): Promise<NoteRecord | null>;\n listNotes(options?: {\n chainId?: number;\n mpk?: string;\n token?: string;\n includeSpent?: boolean;\n }): Promise<NoteRecord[]>;\n markNoteSpent(\n chainId: number,\n index: number,\n spentAt?: number,\n spentTxHash?: string,\n ): Promise<NoteRecord>;\n markNoteUnspent(chainId: number, index: number): Promise<NoteRecord>;\n clearNotes(chainId: number): Promise<void>;\n\n // Nullifiers\n putNullifier(nullifier: NullifierRecord): Promise<void>;\n getNullifier(chainId: number, value: string): Promise<NullifierRecord | null>;\n countNullifiers(chainId: number): Promise<number>;\n clearNullifiers(chainId: number): Promise<void>;\n clearNullifiersFromIndex(chainId: number, fromIndex: number): Promise<void>;\n\n // Leaves\n putLeaf(leaf: LeafRecord): Promise<void>;\n getLeaf(chainId: number, index: number): Promise<LeafRecord | null>;\n listLeaves(chainId: number): Promise<LeafRecord[]>;\n clearLeaves(chainId: number): Promise<void>;\n\n // Roots\n putRoot(root: RootRecord): Promise<void>;\n getRoot(chainId: number, value: string): Promise<RootRecord | null>;\n\n // Ciphertexts\n putCiphertext(\n chainId: number,\n index: number,\n payload: Uint8Array,\n ): Promise<void>;\n getCiphertext(chainId: number, index: number): Promise<Uint8Array | null>;\n listCiphertexts(\n chainId: number,\n ): Promise<{ index: number; payload: Uint8Array }[]>;\n clearCiphertexts(chainId: number): Promise<void>;\n\n // Jobs\n putJob(job: JobRecord): Promise<void>;\n getJob(relayId: string): Promise<JobRecord | null>;\n listJobs(filter?: {\n kind?: JobKind;\n statuses?: JobStatus[];\n }): Promise<JobRecord[]>;\n deleteJob(relayId: string): Promise<void>;\n\n // History\n putHistoryEntry(entry: HistoryEntry): Promise<void>;\n hasHistorySnapshot(options: {\n chainId: number;\n mpk: string;\n }): Promise<boolean>;\n listHistoryEntries(options: {\n chainId: number;\n mpk: string;\n }): Promise<HistoryEntry[]>;\n clearHistoryEntries(options: { chainId: number; mpk: string }): Promise<void>;\n commitHistorySnapshot(options: {\n chainId: number;\n mpk: string;\n }): Promise<void>;\n\n // Atomic sync operations\n syncCommitment(params: {\n leaf: LeafRecord;\n ciphertext: { chainId: number; index: number; payload: Uint8Array };\n root: RootRecord;\n note?: NoteRecord;\n }): Promise<void>;\n\n syncCommitmentBatch(\n items: Array<{\n leaf: LeafRecord;\n ciphertext: { chainId: number; index: number; payload: Uint8Array };\n root: RootRecord;\n note?: NoteRecord;\n }>,\n ): Promise<void>;\n\n getRescanCursor(chainId: number, mpk: string): Promise<number | null>;\n setRescanCursor(chainId: number, mpk: string, value: number): Promise<void>;\n clearRescanCursors(chainId: number): Promise<void>;\n\n /** Clear notes, leaves, ciphertexts, and unspent indices for indices >= fromIndex. */\n clearChainDataFromIndex(chainId: number, fromIndex: number): Promise<void>;\n}\n\nexport function createStateStore(storage: Storage): StateStore {\n const notes = createNoteStore(storage);\n const nullifiers = createNullifierStore(storage);\n const leaves = createLeafStore(storage);\n const roots = createRootStore(storage);\n const ciphertexts = createCiphertextStore(storage);\n const jobs = createJobStore(storage);\n const history = createHistoryStore(storage);\n\n /**\n * Atomically store a commitment's leaf, ciphertext, root, and optionally note.\n * Uses storage.batch() for all-or-nothing semantics.\n */\n async function syncCommitment(params: {\n leaf: LeafRecord;\n ciphertext: { chainId: number; index: number; payload: Uint8Array };\n root: RootRecord;\n note?: NoteRecord;\n }): Promise<void> {\n const { leaf, ciphertext, root, note } = params;\n\n const ops: BatchOp[] = [\n // Leaf\n {\n put: [\n keys.leaf(leaf.chainId, leaf.index),\n encodeJson(leaf as JsonRecord),\n ],\n },\n // Ciphertext (raw bytes, not JSON)\n {\n put: [\n keys.ciphertext(ciphertext.chainId, ciphertext.index),\n ciphertext.payload,\n ],\n },\n // Root\n {\n put: [\n keys.root(root.chainId, root.root),\n encodeJson(root as JsonRecord),\n ],\n },\n ];\n\n // Note (if decryption succeeded)\n if (note) {\n ops.push({\n put: [\n keys.note(note.chainId, note.index),\n encodeJson(note as JsonRecord),\n ],\n });\n // Maintain unspent index\n if (note.spentAt === undefined) {\n ops.push({\n put: [keys.unspent(note.chainId, note.mpk, note.index), emptyBytes()],\n });\n }\n }\n\n await storage.batch(ops);\n }\n\n /**\n * Atomically store multiple commitments in a single batch write.\n * Same semantics as syncCommitment but amortizes the storage.batch() call.\n */\n async function syncCommitmentBatch(\n items: Array<{\n leaf: LeafRecord;\n ciphertext: { chainId: number; index: number; payload: Uint8Array };\n root: RootRecord;\n note?: NoteRecord;\n }>,\n ): Promise<void> {\n if (items.length === 0) return;\n const ops: BatchOp[] = [];\n for (const { leaf, ciphertext, root, note } of items) {\n ops.push({\n put: [\n keys.leaf(leaf.chainId, leaf.index),\n encodeJson(leaf as JsonRecord),\n ],\n });\n ops.push({\n put: [\n keys.ciphertext(ciphertext.chainId, ciphertext.index),\n ciphertext.payload,\n ],\n });\n ops.push({\n put: [\n keys.root(root.chainId, root.root),\n encodeJson(root as JsonRecord),\n ],\n });\n if (note) {\n ops.push({\n put: [\n keys.note(note.chainId, note.index),\n encodeJson(note as JsonRecord),\n ],\n });\n if (note.spentAt === undefined) {\n ops.push({\n put: [\n keys.unspent(note.chainId, note.mpk, note.index),\n emptyBytes(),\n ],\n });\n }\n }\n }\n await storage.batch(ops);\n }\n\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n\n async function getRescanCursor(\n chainId: number,\n mpk: string,\n ): Promise<number | null> {\n const raw = await storage.get(keys.rescanCursor(chainId, mpk));\n if (!raw) return null;\n return parseInt(decoder.decode(raw), 10);\n }\n\n async function setRescanCursor(\n chainId: number,\n mpk: string,\n value: number,\n ): Promise<void> {\n await storage.put(\n keys.rescanCursor(chainId, mpk),\n encoder.encode(String(value)),\n );\n }\n\n async function clearRescanCursors(chainId: number): Promise<void> {\n const prefix = `meta:rescan:${chainId}:`;\n const entries = await storage.iter({ prefix });\n if (entries.length === 0) return;\n const ops: BatchOp[] = entries.map(({ key }) => ({ del: key }));\n await storage.batch(ops);\n }\n\n /**\n * Clear notes, leaves, ciphertexts, and unspent indices for indices >= fromIndex.\n * Used by partial resync to remove stale tail data while preserving the valid prefix.\n *\n * Key formats (see keys.ts): notes:${c}:${i}, leaves:${c}:${i},\n * ciphertexts:${c}:${i}, idx:notes:unspent:${c}:${mpk}:${i}.\n * The index is always the last colon-separated segment.\n */\n async function clearChainDataFromIndex(\n chainId: number,\n fromIndex: number,\n ): Promise<void> {\n const prefixes = [\n `notes:${chainId}:`,\n `leaves:${chainId}:`,\n `ciphertexts:${chainId}:`,\n ];\n const ops: BatchOp[] = [];\n\n for (const prefix of prefixes) {\n const entries = await storage.iter({ prefix });\n for (const { key } of entries) {\n // Index is always the last colon-segment (see keys.ts key builders)\n const idx = parseInt(key.slice(key.lastIndexOf(\":\") + 1), 10);\n if (!isNaN(idx) && idx >= fromIndex) {\n ops.push({ del: key });\n }\n }\n }\n\n // Clear unspent index entries (key: idx:notes:unspent:${c}:${mpk}:${index})\n const unspentPrefix = `idx:notes:unspent:${chainId}:`;\n const unspentEntries = await storage.iter({ prefix: unspentPrefix });\n for (const { key } of unspentEntries) {\n // Index is always the last colon-segment (see keys.ts key builders)\n const idx = parseInt(key.slice(key.lastIndexOf(\":\") + 1), 10);\n if (!isNaN(idx) && idx >= fromIndex) {\n ops.push({ del: key });\n }\n }\n\n if (ops.length > 0) await storage.batch(ops);\n }\n\n return {\n ...notes,\n ...nullifiers,\n ...leaves,\n ...roots,\n ...ciphertexts,\n ...jobs,\n ...history,\n syncCommitment,\n syncCommitmentBatch,\n getRescanCursor,\n setRescanCursor,\n clearRescanCursors,\n clearChainDataFromIndex,\n };\n}\n","/**\n * IMPORTANT limitations:\n * - Garbage collection timing is unpredictable\n * - Strings are immutable\n * - No compiler enforcement to prevent copies\n */\n\n/**\n * Securely zeros out a Uint8Array's contents by overwriting with zeros.\n * This should be called on all sensitive cryptographic material after use\n *\n * @param bytes - The Uint8Array to zeroize (will be mutated in place)\n *\n * @example\n * ```typescript\n * const privateKey = derivePrivateKey(seed);\n * try {\n * const signature = sign(message, privateKey);\n * return signature;\n * } finally {\n * zeroize(privateKey); // Clear sensitive data\n * }\n * ```\n */\nexport function zeroize(bytes: Uint8Array): void {\n if (!bytes || bytes.length === 0) return;\n\n bytes.fill(0);\n}\n","import { ValidationError } from \"../errors.js\";\n\n/**\n * Parse a decimal string to bigint with specified decimals.\n *\n * @param value - Decimal string (e.g., \"10.5\", \"42\")\n * @param decimals - Number of decimal\n * @returns Amount as bigint in atomic units\n * @throws ValidationError if value is invalid or has too many decimal places\n *\n * @example\n * parseAmount(\"10.5\", 18) // Returns 10500000000000000000n\n * parseAmount(\"0.001\", 6) // Returns 1000n\n */\nexport function parseAmount(value: string, decimals: number): bigint {\n const trimmed = value.trim();\n\n if (!trimmed) {\n throw new ValidationError(\"Amount cannot be empty\");\n }\n\n if (!/^\\d*(\\.\\d*)?$/.test(trimmed)) {\n throw new ValidationError(\n \"Amount must be numeric and can include decimals (e.g., '10.5')\",\n );\n }\n\n const [rawWhole = \"0\", rawFraction = \"\"] = trimmed.split(\".\");\n const whole = rawWhole === \"\" ? \"0\" : rawWhole;\n\n if (rawFraction.length > decimals) {\n throw new ValidationError(\n `Amount supports up to ${decimals} decimal places; trim the fractional part`,\n );\n }\n\n // Pad fraction to full decimal places\n const fraction = rawFraction.padEnd(decimals, \"0\");\n const combined = `${whole}${fraction}`;\n\n // Remove leading zeros\n const normalized = combined.replace(/^0+(?=\\d)/, \"\");\n\n return normalized ? BigInt(normalized) : 0n;\n}\n\n/**\n * Format a bigint amount to a decimal string.\n *\n * @param amount - Amount in atomic units as bigint\n * @param decimals - Number of decimal places\n * @returns Human-readable decimal string\n *\n * @example\n * formatAmount(10500000000000000000n, 18) // Returns \"10.5\"\n * formatAmount(1000n, 6) // Returns \"0.001\"\n */\nexport function formatAmount(amount: bigint, decimals: number): string {\n if (amount < 0n) {\n throw new ValidationError(\"Amount must be non-negative\");\n }\n\n const amountStr = amount.toString().padStart(decimals + 1, \"0\");\n const wholePartEnd = amountStr.length - decimals;\n const wholePart = amountStr.slice(0, wholePartEnd) || \"0\";\n const fractionPart = amountStr.slice(wholePartEnd);\n\n // Remove trailing zeros from fraction\n const trimmedFraction = fractionPart.replace(/0+$/, \"\");\n\n return trimmedFraction ? `${wholePart}.${trimmedFraction}` : wholePart;\n}\n","/**\n * Minimal note shape required for balance computation.\n */\nexport type BalanceableNote = {\n token: string;\n value: bigint | string;\n};\n\n/**\n * Computes token balances from a list of notes.\n *\n * @param notes - Array of notes to compute balances from\n * @returns Record mapping token address to total balance\n */\nexport function computeBalances(\n notes: BalanceableNote[],\n): Record<string, bigint> {\n const totals: Record<string, bigint> = {};\n for (const note of notes) {\n const value =\n typeof note.value === \"bigint\" ? note.value : BigInt(note.value);\n totals[note.token] = (totals[note.token] ?? 0n) + value;\n }\n return totals;\n}\n","import { CoreError } from \"../errors.js\";\n\n/**\n * Generate a cryptographically secure random bigint.\n * @param bytes - Number of bytes of randomness (default: 32 for 256-bit)\n * @returns Random bigint\n */\nexport function randomBigint(bytes = 32): bigint {\n if (typeof globalThis.crypto?.getRandomValues !== \"function\") {\n throw new CoreError(\"crypto.getRandomValues is not available\");\n }\n const buffer = new Uint8Array(bytes);\n globalThis.crypto.getRandomValues(buffer);\n return BigInt(\n \"0x\" +\n Array.from(buffer)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\"),\n );\n}\n\n/**\n * Generate a cryptographically secure random hex string.\n * @param bytes - Number of bytes of randomness\n * @returns Random hex string with 0x prefix\n */\nexport function randomHex(bytes: number): `0x${string}` {\n return `0x${randomBigint(bytes)\n .toString(16)\n .padStart(bytes * 2, \"0\")}` as `0x${string}`;\n}\n\n/**\n * Generate a unique relay ID for transaction tracking.\n * Uses crypto.randomUUID() when available, falls back to 128-bit random hex.\n */\nexport function generateRelayId(prefix: string): string {\n return (\n globalThis.crypto?.randomUUID?.() ?? `${prefix}-${randomHex(16).slice(2)}`\n );\n}\n","import { ensureAddress } from \"./validators.js\";\n\n/**\n * Normalize and validate an Ethereum address.\n *\n * @param value - Address string to normalize\n * @returns Normalized lowercase address\n * @throws CoreError if the address is invalid\n *\n * @example\n * normalizeAddress(\"0xABC123...\") // Returns \"0xabc123...\"\n */\nexport function normalizeAddress(value: string): `0x${string}` {\n return ensureAddress(\"address\", value);\n}\n\n/**\n * Shorten a hex string for display.\n *\n * @param value - Hex string to shorten\n * @param chars - Number of characters to show at start/end (default: 4)\n * @returns Shortened string like \"0x1234…abcd\"\n *\n * @example\n * shortenHex(\"0x1234567890abcdef1234567890abcdef12345678\") // \"0x1234…5678\"\n * shortenHex(\"0x1234567890abcdef1234567890abcdef12345678\", 6) // \"0x123456…345678\"\n */\nexport function shortenHex(value: string, chars = 4): string {\n if (!value.startsWith(\"0x\") || value.length <= chars * 2 + 2) {\n return value;\n }\n return `${value.slice(0, chars + 2)}…${value.slice(-chars)}`;\n}\n\n// Re-export random utilities from dedicated module\nexport { randomHex, randomBigint } from \"./random.js\";\n","/**\n * Key derivation for Unlink wallets using SLIP-10.\n *\n * SLIP-10 is a standard for BIP-32-style HD key derivation on non-secp256k1 curves.\n * We use \"babyjubjub seed\" as the curve identifier (standard convention: \"<curve> seed\").\n *\n * Derivation paths (BIP-44 style):\n * - Spending: m/44'/1984'/0'/0'/{index}'\n * - Viewing: m/420'/1984'/0'/0'/{index}'\n *\n * @see https://github.com/satoshilabs/slips/blob/master/slip-0010.md\n */\nimport { ed25519 } from \"@noble/curves/ed25519.js\";\nimport { hmac } from \"@noble/hashes/hmac.js\";\nimport { sha512 } from \"@noble/hashes/sha2.js\";\n\nimport { deriveSpendingPublicKey, poseidon } from \"../crypto/adapters/index.js\";\nimport { ValidationError } from \"../errors.js\";\nimport { Hex } from \"./hex.js\";\n\n// SLIP-10 curve identifier (convention: \"<curve> seed\")\nconst CURVE_SEED = new TextEncoder().encode(\"babyjubjub seed\");\n\n// BIP-44 paths: m/purpose'/coin_type'/account'/change'/{index}'\n// 1984 = coin type for Unlink\nconst SPENDING_PATH = [44, 1984, 0, 0]; // + index\nconst VIEWING_PATH = [420, 1984, 0, 0]; // + index\n\nexport type SpendingPublicKey = [bigint, bigint];\nexport type SpendingKeyPair = {\n privateKey: Uint8Array;\n pubkey: SpendingPublicKey;\n};\nexport type ViewingKeyPair = { privateKey: Uint8Array; pubkey: Uint8Array };\n\nexport type AccountKeys = {\n spending: SpendingKeyPair;\n viewing: ViewingKeyPair;\n nullifyingKey: bigint;\n masterPublicKey: bigint;\n};\n\n/**\n * SLIP-10 master key derivation from seed.\n * I = HMAC-SHA512(Key = curve_seed, Data = seed)\n * Returns left 32 bytes as key, right 32 bytes as chain code.\n */\nfunction deriveMasterKey(seed: Uint8Array): {\n key: Uint8Array;\n chainCode: Uint8Array;\n} {\n const I = hmac(sha512, CURVE_SEED, seed);\n return {\n key: I.slice(0, 32),\n chainCode: I.slice(32, 64),\n };\n}\n\n/**\n * SLIP-10 hardened child key derivation.\n * For hardened keys (index >= 0x80000000), we use:\n * I = HMAC-SHA512(Key = chainCode, Data = 0x00 || key || index)\n */\nfunction deriveHardenedChild(\n key: Uint8Array,\n chainCode: Uint8Array,\n index: number,\n): { key: Uint8Array; chainCode: Uint8Array } {\n // Data = 0x00 || key (32 bytes) || index (4 bytes, big-endian)\n const data = new Uint8Array(37);\n data[0] = 0x00;\n data.set(key, 1);\n // Hardened index: original index + 0x80000000\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n view.setUint32(33, 0x80000000 + index, false); // big-endian\n\n const I = hmac(sha512, chainCode, data);\n return {\n key: I.slice(0, 32),\n chainCode: I.slice(32, 64),\n };\n}\n\n/**\n * Derive a key by traversing a BIP-32 path (all hardened).\n */\nfunction deriveKeyFromPath(seed: Uint8Array, path: number[]): Uint8Array {\n let { key, chainCode } = deriveMasterKey(seed);\n\n for (const index of path) {\n ({ key, chainCode } = deriveHardenedChild(key, chainCode, index));\n }\n\n return key;\n}\n\n/**\n * Derive spending key pair (BabyJubJub) for an account.\n */\nexport function deriveSpendingKeyPair(\n seed: Uint8Array,\n index: number,\n): SpendingKeyPair {\n const path = [...SPENDING_PATH, index];\n const privateKey = deriveKeyFromPath(seed, path);\n const pubkey = deriveSpendingPublicKey(privateKey) as SpendingPublicKey;\n return { privateKey, pubkey };\n}\n\n/**\n * Derive viewing key pair (Ed25519) for an account.\n */\nexport function deriveViewingKeyPair(\n seed: Uint8Array,\n index: number,\n): ViewingKeyPair {\n const path = [...VIEWING_PATH, index];\n const privateKey = deriveKeyFromPath(seed, path);\n const pubkey = ed25519.getPublicKey(privateKey);\n return { privateKey, pubkey };\n}\n\n/**\n * Compute nullifying key from viewing private key using Poseidon hash.\n */\nexport function computeNullifyingKey(viewingPrivateKey: Uint8Array): bigint {\n if (viewingPrivateKey.length !== 32) {\n throw new ValidationError(\"Viewing private key must be 32 bytes\");\n }\n return poseidon([Hex.toBigInt(Hex.fromBytes(viewingPrivateKey))]);\n}\n\n/**\n * Compute master public key from spending public key and nullifying key.\n * MPK = Poseidon(spendingPubkey[0], spendingPubkey[1], nullifyingKey)\n */\nexport function computeMasterPublicKey(\n spendingPubkey: SpendingPublicKey,\n nullifyingKey: bigint,\n): bigint {\n return poseidon([...spendingPubkey, nullifyingKey]);\n}\n\n/**\n * Derive all account keys from a seed.\n */\nexport function deriveAccountKeys(\n seed: Uint8Array,\n index: number,\n): AccountKeys {\n const spending = deriveSpendingKeyPair(seed, index);\n const viewing = deriveViewingKeyPair(seed, index);\n const nullifyingKey = computeNullifyingKey(viewing.privateKey);\n const masterPublicKey = computeMasterPublicKey(\n spending.pubkey,\n nullifyingKey,\n );\n\n return { spending, viewing, nullifyingKey, masterPublicKey };\n}\n","import {\n entropyToMnemonic,\n mnemonicToSeedSync,\n validateMnemonic,\n} from \"@scure/bip39\";\nimport { wordlist } from \"@scure/bip39/wordlists/english.js\";\n\nimport { Hex } from \"./hex.js\";\n\nexport class Mnemonic {\n static validate(mnemonic: string): boolean {\n return validateMnemonic(mnemonic, wordlist);\n }\n\n static toSeed(mnemonic: string, password: string = \"\"): string {\n const seed = mnemonicToSeedSync(mnemonic, password);\n return Hex.fromBytes(seed);\n }\n\n static fromEntropy(entropyHex: string): string {\n const entropy = Hex.toBytes(entropyHex);\n return entropyToMnemonic(entropy, wordlist);\n }\n}\n","import { signMessage } from \"../crypto/adapters/index.js\";\n\n/**\n * Generates an EdDSA signature over a poseidon-hashed message using the spending private key.\n * Used for transact public signal signing.\n *\n * The spendingPrivateKey parameter should be zeroized by the caller after use.\n *\n * @param spendingPrivateKey - The 32-byte spending private key (will not be mutated)\n * @param message - The bigint message to sign\n * @returns The EdDSA signature\n */\nexport function signTransactMessage(\n spendingPrivateKey: Uint8Array,\n message: bigint,\n): { R8: [bigint, bigint]; S: bigint } {\n return signMessage(spendingPrivateKey, message);\n}\n","import { zeroize } from \"../crypto/secure-memory.js\";\nimport { ValidationError } from \"../errors.js\";\nimport { encodeAddress } from \"../keys/address.js\";\nimport {\n deriveAccountKeys,\n type SpendingKeyPair,\n type ViewingKeyPair,\n} from \"../keys/derive.js\";\nimport { Hex } from \"../keys/hex.js\";\nimport { Mnemonic } from \"../keys/mnemonic.js\";\nimport type { Storage } from \"../types.js\";\nimport { signTransactMessage } from \"../utils/signature.js\";\n\nexport type MasterSeedCrypto = {\n encrypt(seed: Uint8Array): Promise<Uint8Array> | Uint8Array;\n decrypt(payload: Uint8Array): Promise<Uint8Array> | Uint8Array;\n};\n\nexport type GenerateMasterSeedOptions = {\n storage: Storage;\n rng: (n: number) => Uint8Array;\n crypto?: MasterSeedCrypto;\n overwrite?: boolean;\n mnemonicPassphrase: string;\n};\n\nexport const MASTER_SEED_LENGTH = 64;\nexport const MASTER_SEED_KEY = \"cfg:wallet:master_seed/v1\";\nexport const MASTER_MNEMONIC_KEY = \"cfg:wallet:master_mnemonic/v1\";\n\nconst MNEMONIC_ENTROPY_BYTES = 32;\n\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\n\nexport type Account = {\n spendingKeyPair: SpendingKeyPair;\n viewingKeyPair: ViewingKeyPair;\n nullifyingKey: bigint;\n masterPublicKey: bigint;\n /** Bech32m address (0zk1...) for this account */\n address: string;\n};\n\n/**\n * Read-only account identity — the fields needed by the transaction layer\n * without any signing capability. Both Account and MultisigAccount satisfy this.\n */\nexport type AccountView = {\n nullifyingKey: bigint;\n masterPublicKey: bigint;\n viewingKeyPair: ViewingKeyPair;\n address: string;\n};\n\n/**\n * Signing capability decoupled from account identity.\n * Async to support multi-round protocols (FROST), hardware wallets, etc.\n */\nexport type Signer = {\n publicKey: [bigint, bigint];\n sign(message: bigint): Promise<{ R8: [bigint, bigint]; S: bigint }>;\n};\n\n/**\n * Extract an AccountView from a full Account.\n */\nexport function toAccountView(account: Account): AccountView {\n return {\n nullifyingKey: account.nullifyingKey,\n masterPublicKey: account.masterPublicKey,\n viewingKeyPair: account.viewingKeyPair,\n address: account.address,\n };\n}\n\n/**\n * Create a Signer from a single spending key pair.\n */\nexport function createSingleKeySigner(\n privateKey: Uint8Array,\n pubkey: [bigint, bigint],\n): Signer {\n return {\n publicKey: pubkey,\n sign: async (message: bigint) => signTransactMessage(privateKey, message),\n };\n}\n\nexport function deriveAccount(\n masterSeed: Uint8Array,\n accountIndex: number = 0,\n): Account {\n const seed = normalizeMasterSeed(masterSeed);\n if (!Number.isInteger(accountIndex) || accountIndex < 0) {\n throw new ValidationError(\"accountIndex must be a non-negative integer\");\n }\n\n const keys = deriveAccountKeys(seed, accountIndex);\n const address = encodeAddress({\n masterPublicKey: keys.masterPublicKey,\n viewingPublicKey: keys.viewing.pubkey,\n });\n\n return {\n spendingKeyPair: keys.spending,\n viewingKeyPair: keys.viewing,\n nullifyingKey: keys.nullifyingKey,\n masterPublicKey: keys.masterPublicKey,\n address,\n };\n}\n\nexport function deriveAccountFromMnemonic(\n mnemonic: string,\n accountIndex: number = 0,\n password: string = \"\",\n): Account {\n const normalized = normalizeMnemonic(mnemonic);\n const seed = mnemonicToSeed(normalized, password);\n try {\n return deriveAccount(seed, accountIndex);\n } finally {\n zeroize(seed);\n }\n}\n\n/** Passthrough crypto, storage handles buffer isolation */\nconst identityMasterSeedCrypto: MasterSeedCrypto = {\n encrypt: (seed) => seed,\n decrypt: (payload) => payload,\n};\n\nexport async function generateMasterSeed({\n storage,\n rng,\n crypto = identityMasterSeedCrypto,\n overwrite = false,\n mnemonicPassphrase,\n}: GenerateMasterSeedOptions): Promise<Uint8Array> {\n if (!overwrite) {\n const existingSeed = await loadMasterSeed(storage, crypto);\n if (existingSeed) return existingSeed;\n\n const existingMnemonic = await loadMasterMnemonic(storage, crypto);\n if (existingMnemonic) {\n const seedFromMnemonic = mnemonicToSeed(\n existingMnemonic,\n mnemonicPassphrase,\n );\n await storeMasterSeed(storage, seedFromMnemonic, crypto);\n return seedFromMnemonic;\n }\n }\n\n const entropy = rng(MNEMONIC_ENTROPY_BYTES);\n if (entropy.length !== MNEMONIC_ENTROPY_BYTES) {\n throw new ValidationError(\n `mnemonic entropy must be ${MNEMONIC_ENTROPY_BYTES} bytes`,\n );\n }\n\n try {\n const mnemonic = Mnemonic.fromEntropy(Hex.fromBytes(entropy));\n await storeMasterMnemonic(storage, mnemonic, crypto);\n const seed = mnemonicToSeed(mnemonic, mnemonicPassphrase);\n await storeMasterSeed(storage, seed, crypto);\n return seed;\n } finally {\n zeroize(entropy);\n }\n}\n\nexport async function loadMasterSeed(\n storage: Storage,\n crypto: MasterSeedCrypto = identityMasterSeedCrypto,\n): Promise<Uint8Array | null> {\n const stored = await storage.get(MASTER_SEED_KEY);\n if (!stored) return null;\n const plaintext = await crypto.decrypt(stored);\n return normalizeMasterSeed(plaintext);\n}\n\nexport async function storeMasterSeed(\n storage: Storage,\n seed: Uint8Array,\n crypto: MasterSeedCrypto = identityMasterSeedCrypto,\n): Promise<void> {\n const normalized = normalizeMasterSeed(seed);\n const encrypted = await crypto.encrypt(normalized);\n if (!(encrypted instanceof Uint8Array)) {\n throw new ValidationError(\"master seed encryptor must return Uint8Array\");\n }\n await storage.put(MASTER_SEED_KEY, encrypted);\n}\n\nexport async function loadMasterMnemonic(\n storage: Storage,\n crypto: MasterSeedCrypto = identityMasterSeedCrypto,\n): Promise<string | null> {\n const stored = await storage.get(MASTER_MNEMONIC_KEY);\n if (!stored) return null;\n const plaintext = await crypto.decrypt(stored);\n try {\n const mnemonic = textDecoder.decode(plaintext);\n return normalizeMnemonic(mnemonic);\n } finally {\n zeroize(plaintext);\n }\n}\n\nexport type ImportMasterMnemonicOptions = {\n storage: Storage;\n mnemonic: string;\n crypto?: MasterSeedCrypto;\n overwrite?: boolean;\n password?: string;\n};\n\nexport async function importMasterMnemonic({\n storage,\n mnemonic,\n crypto = identityMasterSeedCrypto,\n overwrite = false,\n password = \"\",\n}: ImportMasterMnemonicOptions): Promise<Uint8Array> {\n if (!overwrite) {\n const existing = await loadMasterMnemonic(storage, crypto);\n if (existing) {\n throw new ValidationError(\n \"master mnemonic already exists; set overwrite to true to replace it\",\n );\n }\n }\n\n const normalized = normalizeMnemonic(mnemonic);\n const seed = mnemonicToSeed(normalized, password);\n await storeMasterMnemonic(storage, normalized, crypto);\n await storeMasterSeed(storage, seed, crypto);\n return seed;\n}\n\nexport async function storeMasterMnemonic(\n storage: Storage,\n mnemonic: string,\n crypto: MasterSeedCrypto = identityMasterSeedCrypto,\n): Promise<void> {\n const normalized = normalizeMnemonic(mnemonic);\n const encrypted = await crypto.encrypt(textEncoder.encode(normalized));\n if (!(encrypted instanceof Uint8Array)) {\n throw new ValidationError(\n \"master mnemonic encryptor must return Uint8Array\",\n );\n }\n await storage.put(MASTER_MNEMONIC_KEY, encrypted);\n}\n\n/** Validates seed format. Storage handles buffer isolation on put/get. */\nfunction normalizeMasterSeed(seed: Uint8Array): Uint8Array {\n if (!(seed instanceof Uint8Array)) {\n throw new ValidationError(\"master seed must be a Uint8Array\");\n }\n if (seed.length !== MASTER_SEED_LENGTH) {\n throw new ValidationError(\n `master seed must be ${MASTER_SEED_LENGTH} bytes`,\n );\n }\n return seed;\n}\n\nfunction normalizeMnemonic(mnemonic: string): string {\n const formatted = mnemonic.trim().replace(/\\s+/g, \" \");\n if (!Mnemonic.validate(formatted)) {\n throw new ValidationError(\"invalid BIP-39 mnemonic phrase\");\n }\n return formatted;\n}\n\nfunction mnemonicToSeed(mnemonic: string, password: string = \"\"): Uint8Array {\n const seedHex = Mnemonic.toSeed(mnemonic, password);\n return Hex.toBytes(seedHex);\n}\n","import type { JobKind, JobRecord, JobStatus } from \"../state/index.js\";\nimport type { NoteRecord } from \"../state/store/records.js\";\nimport { ensureChainId, ensureMpk } from \"../utils/validators.js\";\nimport type { HistoryEntry, HistoryKind, HistoryStatus } from \"./types.js\";\n\ntype HistoryStateStore = {\n listNotes(options?: {\n chainId?: number;\n mpk?: string;\n token?: string;\n includeSpent?: boolean;\n }): Promise<NoteRecord[]>;\n listJobs(filter?: {\n kind?: JobKind;\n statuses?: JobStatus[];\n }): Promise<JobRecord[]>;\n putHistoryEntry(entry: HistoryEntry): Promise<void>;\n commitHistorySnapshot(options: {\n chainId: number;\n mpk: string;\n }): Promise<void>;\n hasHistorySnapshot(options: {\n chainId: number;\n mpk: string;\n }): Promise<boolean>;\n listHistoryEntries(options: {\n chainId: number;\n mpk: string;\n }): Promise<HistoryEntry[]>;\n clearHistoryEntries(options: { chainId: number; mpk: string }): Promise<void>;\n};\n\nfunction addByToken(totals: Map<string, bigint>, token: string, delta: bigint) {\n totals.set(token, (totals.get(token) ?? 0n) + delta);\n}\n\nfunction maxTimestamp(\n notes: NoteRecord[],\n field: \"createdAt\" | \"spentAt\",\n): number | undefined {\n let max = 0;\n for (const note of notes) {\n const timestamp = note[field];\n if (timestamp !== undefined) max = Math.max(max, timestamp);\n }\n return max > 0 ? max : undefined;\n}\n\nconst STATUS_PRIORITY: Record<HistoryStatus, number> = {\n failed: 3,\n pending: 2,\n confirmed: 1,\n};\n\nfunction convertJobStatus(jobStatus: JobStatus): HistoryStatus {\n if (jobStatus === \"failed\" || jobStatus === \"dead\") return \"failed\";\n if (\n jobStatus === \"pending\" ||\n jobStatus === \"submitted\" ||\n jobStatus === \"broadcasting\"\n )\n return \"pending\";\n return \"confirmed\";\n}\n\nfunction mergeStatus(\n prev: HistoryStatus | undefined,\n next: HistoryStatus,\n): HistoryStatus {\n if (!prev) return next;\n return STATUS_PRIORITY[next] > STATUS_PRIORITY[prev] ? next : prev;\n}\n\nfunction computeEntryId(params: {\n chainId: number;\n mpk: string;\n txHash: string;\n kind: string;\n}) {\n return `${params.chainId}:${params.mpk}:${params.txHash}:${params.kind}`;\n}\n\ntype TransactionGroup = {\n created: NoteRecord[];\n spent: NoteRecord[];\n createdEventType?: string;\n};\n\ntype TokenAmounts = {\n createdTotals: Map<string, bigint>;\n spentTotals: Map<string, bigint>;\n netByToken: Map<string, bigint>;\n hasNetChange: boolean;\n};\n\nfunction groupNotesByTransaction(\n notes: NoteRecord[],\n): Map<string, TransactionGroup> {\n const byTx = new Map<string, TransactionGroup>();\n\n const ensureGroup = (txHash: string) => {\n const existing = byTx.get(txHash);\n if (existing) return existing;\n const next: TransactionGroup = {\n created: [],\n spent: [],\n createdEventType: undefined,\n };\n byTx.set(txHash, next);\n return next;\n };\n\n for (const note of notes) {\n if (note.createdTxHash) {\n const group = ensureGroup(note.createdTxHash);\n group.created.push(note);\n group.createdEventType ??= note.createdEventType;\n }\n if (note.spentTxHash) {\n const group = ensureGroup(note.spentTxHash);\n group.spent.push(note);\n }\n }\n\n return byTx;\n}\n\nfunction resolveJobStatuses(\n jobs: JobRecord[],\n chainId: number,\n mpk: string,\n): Map<string, HistoryStatus> {\n const statusByTxHash = new Map<string, HistoryStatus>();\n\n for (const job of jobs) {\n if (job.chainId !== chainId) continue;\n if (job.mpk && job.mpk !== mpk) continue;\n const txHash = job.txHash ?? undefined;\n if (!txHash) continue;\n const status = convertJobStatus(job.status);\n statusByTxHash.set(txHash, mergeStatus(statusByTxHash.get(txHash), status));\n }\n\n return statusByTxHash;\n}\n\nfunction aggregateAmounts(group: TransactionGroup): TokenAmounts {\n const createdTotals = new Map<string, bigint>();\n const spentTotals = new Map<string, bigint>();\n\n for (const note of group.created) {\n addByToken(createdTotals, note.token, BigInt(note.value));\n }\n for (const note of group.spent) {\n addByToken(spentTotals, note.token, BigInt(note.value));\n }\n\n const tokens = new Set<string>([\n ...createdTotals.keys(),\n ...spentTotals.keys(),\n ]);\n\n const netByToken = new Map<string, bigint>();\n let hasNetChange = false;\n for (const token of tokens) {\n const created = createdTotals.get(token) ?? 0n;\n const spent = spentTotals.get(token) ?? 0n;\n const net = created - spent;\n netByToken.set(token, net);\n if (net !== 0n) hasNetChange = true;\n }\n\n return { createdTotals, spentTotals, netByToken, hasNetChange };\n}\n\nfunction classifyTransaction(\n group: TransactionGroup,\n amounts: TokenAmounts,\n): HistoryKind | null {\n const isSelfSend = group.spent.length > 0 && !amounts.hasNetChange;\n\n if (isSelfSend) {\n return \"SelfSend\";\n } else if (group.spent.length > 0) {\n return \"Send\";\n } else if (group.created.length > 0) {\n return group.createdEventType === \"deposit\" ? \"Deposit\" : \"Receive\";\n }\n\n return null;\n}\n\nfunction computeFinalAmounts(\n kind: HistoryKind,\n amounts: TokenAmounts,\n): Map<string, bigint> {\n const finalTotals = new Map<string, bigint>();\n const tokens = new Set<string>([\n ...amounts.createdTotals.keys(),\n ...amounts.spentTotals.keys(),\n ]);\n\n if (kind === \"SelfSend\") {\n for (const token of tokens) finalTotals.set(token, 0n);\n } else if (kind === \"Send\" || kind === \"Withdraw\") {\n for (const [token, net] of amounts.netByToken.entries()) {\n if (net < 0n) finalTotals.set(token, net);\n }\n } else {\n for (const [token, net] of amounts.netByToken.entries()) {\n if (net > 0n) finalTotals.set(token, net);\n }\n }\n\n return finalTotals;\n}\n\nfunction selectTimestamp(\n kind: HistoryKind,\n group: TransactionGroup,\n): number | undefined {\n if (kind === \"Deposit\" || kind === \"Receive\") {\n return maxTimestamp(group.created, \"createdAt\");\n } else if (kind === \"Send\" || kind === \"SelfSend\" || kind === \"Withdraw\") {\n return (\n maxTimestamp(group.spent, \"spentAt\") ??\n maxTimestamp(group.created, \"createdAt\")\n );\n }\n return undefined;\n}\n\nfunction buildHistoryEntry(params: {\n chainId: number;\n mpk: string;\n txHash: string;\n kind: HistoryKind;\n status: HistoryStatus;\n timestamp: number | undefined;\n finalAmounts: Map<string, bigint>;\n group: TransactionGroup;\n}): HistoryEntry {\n return {\n id: computeEntryId({\n chainId: params.chainId,\n mpk: params.mpk,\n txHash: params.txHash,\n kind: params.kind,\n }),\n chainId: params.chainId,\n mpk: params.mpk,\n txHash: params.txHash,\n kind: params.kind,\n status: params.status,\n timestamp: params.timestamp,\n amounts: [...params.finalAmounts.entries()].map(([token, delta]) => ({\n token,\n delta: delta.toString(),\n })),\n details: {\n createdNoteCount: params.group.created.length,\n spentNoteCount: params.group.spent.length,\n createdEventType: params.group.createdEventType ?? \"unknown\",\n },\n };\n}\n\nexport function createHistoryService(stateStore: HistoryStateStore) {\n // Track pending rebuilds to prevent concurrent execution\n const pendingRebuilds = new Map<string, Promise<void>>();\n\n async function computeHistory(params: {\n chainId: number;\n mpk: string;\n includeSelfSends?: boolean;\n }) {\n ensureChainId(params.chainId);\n ensureMpk(params.mpk);\n\n // Fetch data\n const notes = await stateStore.listNotes({\n chainId: params.chainId,\n mpk: params.mpk,\n includeSpent: true,\n });\n\n const jobs = await stateStore.listJobs({\n statuses: [\n \"pending\",\n \"submitted\",\n \"broadcasting\",\n \"failed\",\n \"dead\",\n \"succeeded\",\n ],\n });\n\n // Group notes by transaction hash\n const byTx = groupNotesByTransaction(notes);\n\n // Resolve job statuses for each transaction\n const statusByTxHash = resolveJobStatuses(jobs, params.chainId, params.mpk);\n\n const entries: HistoryEntry[] = [];\n const confirmedTxHashes = new Set<string>();\n\n // Process each transaction group\n for (const [txHash, group] of byTx.entries()) {\n if (group.created.length === 0 && group.spent.length === 0) continue;\n\n // Aggregate amounts and compute net deltas\n const amounts = aggregateAmounts(group);\n\n // Classify transaction type\n const kind = classifyTransaction(group, amounts);\n if (!kind) continue;\n\n // Compute final amounts to display\n const finalAmounts = computeFinalAmounts(kind, amounts);\n if (finalAmounts.size === 0) continue;\n\n // Select appropriate timestamp\n const timestamp = selectTimestamp(kind, group);\n\n // Build history entry\n const entry = buildHistoryEntry({\n chainId: params.chainId,\n mpk: params.mpk,\n txHash,\n kind,\n status: statusByTxHash.get(txHash) ?? \"confirmed\",\n timestamp,\n finalAmounts,\n group,\n });\n\n confirmedTxHashes.add(txHash);\n entries.push(entry);\n }\n\n // Add pending job entries for transactions not yet indexed\n for (const job of jobs) {\n if (job.chainId !== params.chainId) continue;\n if (job.mpk && job.mpk !== params.mpk) continue;\n const txHash = job.txHash ?? undefined;\n if (!txHash) continue;\n if (confirmedTxHashes.has(txHash)) continue;\n if (!job.historyPreview) continue;\n if (job.status === \"succeeded\") continue;\n\n const status: HistoryStatus =\n job.status === \"failed\" || job.status === \"dead\" ? \"failed\" : \"pending\";\n\n entries.push({\n id: computeEntryId({\n chainId: params.chainId,\n mpk: params.mpk,\n txHash,\n kind: job.historyPreview.kind,\n }),\n chainId: params.chainId,\n mpk: params.mpk,\n txHash,\n kind: job.historyPreview.kind,\n status,\n timestamp: job.createdAt,\n amounts: job.historyPreview.amounts,\n details: {\n source: \"job\",\n jobKind: job.kind,\n },\n });\n }\n\n // Sort by timestamp descending\n entries.sort((a, b) => {\n const at = a.timestamp ?? 0;\n const bt = b.timestamp ?? 0;\n if (at !== bt) return bt - at;\n return b.txHash.localeCompare(a.txHash);\n });\n\n // Filter self-sends if needed (unified filtering point)\n return params.includeSelfSends\n ? entries\n : entries.filter((e) => e.kind !== \"SelfSend\");\n }\n\n async function computeAndPersist(params: { chainId: number; mpk: string }) {\n // Always compute with self-sends included for complete storage\n const allEntries = await computeHistory({\n chainId: params.chainId,\n mpk: params.mpk,\n includeSelfSends: true,\n });\n await stateStore.clearHistoryEntries({\n chainId: params.chainId,\n mpk: params.mpk,\n });\n await Promise.all(\n allEntries.map((entry) => stateStore.putHistoryEntry(entry)),\n );\n await stateStore.commitHistorySnapshot({\n chainId: params.chainId,\n mpk: params.mpk,\n });\n }\n\n return {\n async rebuildHistory(params: { chainId: number; mpk: string }) {\n const rebuildKey = `${params.chainId}:${params.mpk}`;\n\n // If a rebuild is already in progress, wait for it instead of starting a new one\n const existing = pendingRebuilds.get(rebuildKey);\n if (existing) {\n return existing;\n }\n\n // Start a new rebuild and track it\n const rebuildPromise = computeAndPersist(params).finally(() => {\n // Clean up when done\n pendingRebuilds.delete(rebuildKey);\n });\n\n pendingRebuilds.set(rebuildKey, rebuildPromise);\n return rebuildPromise;\n },\n\n async getHistory(params: {\n chainId: number;\n mpk: string;\n force?: boolean;\n includeSelfSends?: boolean;\n }) {\n ensureChainId(params.chainId);\n ensureMpk(params.mpk);\n\n // If rebuild in progress, wait for it\n const rebuildKey = `${params.chainId}:${params.mpk}`;\n const pendingRebuild = pendingRebuilds.get(rebuildKey);\n if (pendingRebuild) {\n await pendingRebuild;\n }\n\n if (params.force) {\n await computeAndPersist({\n chainId: params.chainId,\n mpk: params.mpk,\n });\n } else {\n // Check if we have persisted history\n const hasSnapshot = await stateStore.hasHistorySnapshot({\n chainId: params.chainId,\n mpk: params.mpk,\n });\n\n if (!hasSnapshot) {\n // First time - compute and persist\n await computeAndPersist({\n chainId: params.chainId,\n mpk: params.mpk,\n });\n }\n }\n\n // Always read from storage\n const stored = await stateStore.listHistoryEntries({\n chainId: params.chainId,\n mpk: params.mpk,\n });\n\n return params.includeSelfSends\n ? stored\n : stored.filter((e) => e.kind !== \"SelfSend\");\n },\n };\n}\n","import { Interface } from \"ethers\";\n\nimport { resolveFetch } from \"../clients/http.js\";\nimport { createIndexerClient } from \"../clients/indexer.js\";\nimport { createServiceConfig } from \"../config.js\";\nimport { ETH_TOKEN } from \"../constants.js\";\nimport {\n computeCommitment,\n deriveNpk,\n encryptNote,\n} from \"../crypto/encrypt.js\";\nimport { CoreError, InitializationError, ValidationError } from \"../errors.js\";\nimport { FieldSize, Hex } from \"../keys/hex.js\";\nimport {\n DEFAULT_JOB_TIMEOUT_MS,\n rebuildTreeFromStore,\n resolveMerkleTrees,\n type DepositRecord,\n} from \"../state/index.js\";\nimport { sleep } from \"../utils/async.js\";\nimport {\n DEFAULT_INITIAL_POLL_DELAY_MS,\n DEFAULT_POLL_INTERVAL_MS,\n DEFAULT_POLL_TIMEOUT_MS,\n MAX_POLL_INTERVAL_MS,\n} from \"../utils/polling.js\";\nimport { generateRelayId } from \"../utils/random.js\";\nimport type {\n BaseStateStore,\n DepositParams,\n DepositRelayResult,\n DepositSyncResult,\n NoteInput,\n ServiceOptions,\n} from \"./types/index.js\";\n\nexport const DEPOSIT_ABI = [\n \"function deposit(address _depositor, (uint256 npk, uint256 amount, address token)[] notes, (uint256 ephemeralKey, uint256[3] data)[] ciphertexts) payable\",\n] as const;\n\nconst depositInterface = new Interface(DEPOSIT_ABI);\n\n// ============================================================================\n// Internal helpers\n// ============================================================================\n\ntype ProcessedNote = {\n npk: bigint;\n commitmentHex: string;\n token: string;\n amount: bigint;\n encrypted: { ephemeralKey: bigint; data: [bigint, bigint, bigint] };\n};\n\n/**\n * Process notes: derive npk, compute commitment, and encrypt.\n */\nfunction processNotes(\n _account: DepositParams[\"account\"],\n _chainId: number,\n _poolAddress: string,\n _depositor: string,\n notes: NoteInput[],\n): ProcessedNote[] {\n return notes.map((note) => {\n const npk = deriveNpk(note);\n const commitment = computeCommitment(note, npk);\n const commitmentHex = Hex.fromBigInt(commitment, FieldSize.SCALAR, true);\n const encrypted = encryptNote(note, note.viewingPublicKey);\n\n return {\n npk,\n commitmentHex,\n token: note.token,\n amount: note.amount,\n encrypted,\n };\n });\n}\n\n/**\n * Build deposit calldata from processed notes.\n */\nfunction buildDepositCalldata(\n depositor: string,\n processedNotes: ProcessedNote[],\n): string {\n return depositInterface.encodeFunctionData(\"deposit\", [\n depositor,\n processedNotes.map((d) => ({\n npk: d.npk,\n amount: d.amount,\n token: d.token,\n })),\n processedNotes.map((d) => ({\n ephemeralKey: d.encrypted.ephemeralKey,\n data: d.encrypted.data,\n })),\n ]);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Prepare a deposit: compute commitments, build calldata, and persist pending job.\n * Accepts 1 or more notes in a single transaction.\n */\nexport async function deposit(\n store: BaseStateStore,\n req: DepositParams,\n): Promise<DepositRelayResult> {\n if (!req.notes?.length) {\n throw new ValidationError(\"At least one note is required for deposit\");\n }\n\n const processedNotes = processNotes(\n req.account,\n req.chainId,\n req.poolAddress,\n req.depositor,\n req.notes,\n );\n\n const calldata = buildDepositCalldata(req.depositor, processedNotes);\n const relayId = generateRelayId(\"dep\");\n\n const value = processedNotes\n .filter((n) => n.token.toLowerCase() === ETH_TOKEN.toLowerCase())\n .reduce((sum, n) => sum + n.amount, 0n);\n\n const job: DepositRecord = {\n relayId,\n kind: \"deposit\",\n chainId: req.chainId,\n status: \"pending\",\n txHash: null,\n createdAt: Date.now(),\n timeoutMs: DEFAULT_JOB_TIMEOUT_MS,\n predictedCommitments: processedNotes.map((d) => ({\n hex: d.commitmentHex,\n token: d.token,\n amount: d.amount.toString(),\n })),\n };\n\n await store.putJob(job);\n\n return {\n relayId,\n to: req.poolAddress,\n calldata,\n value,\n commitments: processedNotes.map((d) => ({\n commitment: d.commitmentHex,\n token: d.token,\n amount: d.amount,\n })),\n };\n}\n\n// ============================================================================\n// Sync helpers\n// ============================================================================\n\ntype SyncContext = {\n store: BaseStateStore;\n chainId: number;\n indexer: ReturnType<typeof createIndexerClient>;\n trees: ReturnType<typeof resolveMerkleTrees>;\n pollInterval: number;\n deadline: number;\n};\n\ntype SyncedCommitment = {\n index: number;\n commitment: string;\n root: string;\n txHash?: string | null;\n};\n\n/**\n * Poll for a single commitment and verify/persist it.\n */\nasync function pollAndVerifyCommitment(\n ctx: SyncContext,\n commitmentHex: string,\n): Promise<SyncedCommitment> {\n let delay = ctx.pollInterval;\n let record = null;\n\n while (Date.now() <= ctx.deadline) {\n record = await ctx.indexer.tryGetCommitment({\n chainId: ctx.chainId,\n commitment: commitmentHex,\n });\n if (record) break;\n await sleep(delay);\n delay = Math.min(delay * 2, MAX_POLL_INTERVAL_MS);\n }\n\n if (!record) {\n throw new CoreError(`commitment ${commitmentHex} not found before timeout`);\n }\n\n // Note: We intentionally do NOT verify or store the leaf here. The syncChain\n // flow handles leaf storage, merkle verification, and note decryption together.\n // If we verified the tree here, we'd need to keep it in sync across multiple\n // reconcile calls, and if we stored the leaf, syncChain would skip this index\n // and notes wouldn't be decrypted.\n //\n // The indexer's commitment record already contains the verified index and root,\n // which we return to the caller. The subsequent sync will verify consistency\n // when it processes this commitment.\n\n return {\n index: record.index,\n commitment: record.commitment,\n root: record.root,\n txHash: record.txHash,\n };\n}\n\n/**\n * Create sync context with common setup.\n */\nasync function createSyncContext(\n store: BaseStateStore,\n chainId: number,\n createdAt: number,\n opts: ServiceOptions,\n): Promise<SyncContext> {\n const fetchFn = resolveFetch(opts.fetch);\n if (!fetchFn) throw new InitializationError(\"fetch is required for sync\");\n\n const serviceConfig = createServiceConfig(opts.gatewayUrl);\n const trees = resolveMerkleTrees(opts);\n const indexer = createIndexerClient(serviceConfig.indexerBaseUrl, {\n fetch: fetchFn,\n });\n const pollInterval = opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const pollTimeout = opts.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;\n\n await rebuildTreeFromStore({\n chainId,\n trees,\n loadLeaves: store.listLeaves.bind(store),\n });\n\n // Calculate deadline BEFORE initial delay so pollTimeout is the total wait time\n const deadline = Date.now() + pollTimeout;\n\n // Wait initial delay for fresh deposits to reduce wasted 404 polls\n const initialDelay = opts.initialPollDelayMs ?? DEFAULT_INITIAL_POLL_DELAY_MS;\n const jobAge = Date.now() - createdAt;\n if (initialDelay > 0 && jobAge < initialDelay) {\n await sleep(initialDelay - jobAge);\n }\n\n return {\n store,\n chainId,\n indexer,\n trees,\n pollInterval,\n deadline,\n };\n}\n\n// ============================================================================\n// Sync Public API\n// ============================================================================\n\n/**\n * Wait for all commitments in a deposit to be indexed and update local state.\n * Works for both single and multi-note deposits.\n */\nexport async function syncDeposit(\n store: BaseStateStore,\n relayId: string,\n opts: ServiceOptions,\n): Promise<DepositSyncResult> {\n const jobRecord = await store.getJob(relayId);\n if (!jobRecord || jobRecord.kind !== \"deposit\")\n throw new CoreError(`unknown deposit relay ${relayId}`);\n const job = jobRecord as DepositRecord;\n\n const ctx = await createSyncContext(store, job.chainId, job.createdAt, opts);\n\n try {\n const syncedCommitments: SyncedCommitment[] = [];\n\n for (const predicted of job.predictedCommitments) {\n const synced = await pollAndVerifyCommitment(ctx, predicted.hex);\n syncedCommitments.push(synced);\n }\n\n const finalRoot = syncedCommitments[syncedCommitments.length - 1]!.root;\n\n // Update job status (syncChain handles root storage)\n await store.putJob({\n ...job,\n status: \"succeeded\",\n lastCheckedAt: Date.now(),\n txHash: syncedCommitments[0]?.txHash ?? job.txHash ?? null,\n predictedCommitments: job.predictedCommitments.map((p, i) => ({\n ...p,\n index: syncedCommitments[i]?.index,\n root: syncedCommitments[i]?.root,\n })),\n });\n\n return {\n chainId: job.chainId,\n commitments: syncedCommitments.map((s) => ({\n index: s.index,\n commitment: s.commitment,\n root: s.root,\n })),\n finalRoot,\n };\n } catch (error) {\n await store.putJob({\n ...job,\n status: \"failed\",\n lastCheckedAt: Date.now(),\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n}\n","import ky, { TimeoutError } from \"ky\";\n\nimport { InitializationError } from \"../errors.js\";\n\nexport type FetchLike = (\n input: RequestInfo | URL,\n init?: RequestInit,\n) => Promise<Response>;\n\n/**\n * Resolve fetch implementation from options or global.\n * @param providedFetch - Optional fetch implementation\n * @returns Fetch function or undefined if not available\n */\nexport function resolveFetch(\n providedFetch?: FetchLike,\n): typeof fetch | undefined {\n return providedFetch ?? (typeof fetch === \"function\" ? fetch : undefined);\n}\n\nexport type JsonHttpDeps = { fetch: FetchLike };\n\nexport type JsonRequestOptions = {\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n path: string;\n query?: Record<string, string | number | boolean | undefined>;\n json?: unknown;\n body?: BodyInit;\n headers?: HeadersInit;\n signal?: AbortSignal;\n};\n\nexport type JsonHttpClient = {\n request<T>(opts: JsonRequestOptions): Promise<T>;\n};\n\nexport class HttpError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.status = status;\n this.body = body;\n }\n}\n\nasync function readErrorBodySafe(res: Response) {\n try {\n return await res.clone().json();\n } catch {\n const text = await res.text();\n return text || null;\n }\n}\n\nexport function createJsonHttpClient(\n baseUrl: string,\n deps: JsonHttpDeps,\n): JsonHttpClient {\n if (!baseUrl) throw new InitializationError(\"baseUrl is required\");\n if (!deps?.fetch) throw new InitializationError(\"deps.fetch is required\");\n\n // Ensure `fetch` is invoked with a global `this` to avoid \"Illegal invocation\"\n // errors in some browser environments when the function is extracted. // TODO: can we fix this in another way?\n const fetchImpl: FetchLike = (...args) => deps.fetch.apply(globalThis, args);\n\n const api = ky.create({\n prefixUrl: baseUrl.replace(/\\/+$/, \"\"),\n fetch: fetchImpl,\n // Disable ky's automatic error throwing to prevent browser DevTools\n // from logging expected 404s as network errors\n throwHttpErrors: false,\n });\n\n return {\n async request<T>(opts: JsonRequestOptions): Promise<T> {\n let res: Response;\n try {\n res = await api(opts.path.replace(/^\\//, \"\"), {\n method: opts.method,\n searchParams: opts.query,\n json: opts.json,\n body: opts.body,\n headers: opts.headers,\n signal: opts.signal,\n });\n } catch (err) {\n // Only network-level errors reach here (timeout, connection refused, etc.)\n if (err instanceof TimeoutError) {\n throw new HttpError(\"HTTP timeout\", 408, null);\n }\n throw new HttpError(\n err instanceof Error ? err.message : \"Network error\",\n 0,\n null,\n );\n }\n\n // HTTP status errors handled outside try-catch - no redundant catch/rethrow\n if (!res.ok) {\n const body = await readErrorBodySafe(res);\n throw new HttpError(\n `HTTP ${res.status} ${res.statusText}`.trim(),\n res.status,\n body,\n );\n }\n\n return (await res.json()) as T;\n },\n };\n}\n","import type { FetchLike } from \"./http.js\";\nimport { createJsonHttpClient, HttpError } from \"./http.js\";\n\n// The HTTP API returns snake_case fields; the `Raw` helpers mirror that\n// payload exactly so we can normalize everything to camelCase in one place.\ntype CommitmentRecordRaw = {\n leaf_index: number;\n commitment: string;\n ephemeral_key: string;\n ciphertext: [string, string, string];\n root: string;\n tx_hash: string;\n inserted_at: number;\n event_type?: string;\n adapter_npk?: string;\n adapter_token?: string;\n adapter_amount?: string;\n adapter_random?: string;\n};\n\nexport type CommitmentRecord = {\n index: number;\n commitment: string;\n ephemeralKey: string;\n ciphertext: [string, string, string];\n root: string;\n txHash: string;\n insertedAt: number;\n eventType: string;\n adapterNpk?: string;\n adapterToken?: string;\n adapterAmount?: string;\n adapterRandom?: string;\n};\n\ntype NullifierRecordRaw = {\n nullifier: string;\n tx_hash: string;\n spent_at: number;\n chain_id: number;\n};\n\nexport type IndexerNullifierRecord = {\n nullifier: string;\n txHash: string;\n spentAt: number;\n chainId: number;\n};\n\ntype CommitmentBatchResponseRaw = {\n chain_id: number;\n commitments: CommitmentRecordRaw[];\n latest_root: string | null;\n};\n\nexport type CommitmentBatchResponse = {\n chainId: number;\n commitments: CommitmentRecord[];\n latestRoot: string | null;\n};\n\nexport type FetchCommitmentsParams = {\n chainId: number;\n start?: number;\n limit?: number;\n};\n\nexport type GetCommitmentParams = {\n chainId: number;\n commitment: string;\n};\n\nexport type GetNullifierParams = {\n chainId: number;\n nullifier: string;\n};\n\ntype NullifierCountResponseRaw = {\n chain_id: number;\n count: number;\n};\n\ntype CheckNullifiersRaw = {\n found: NullifierRecordRaw[];\n};\n\nexport type CheckNullifiersParams = {\n chainId: number;\n nullifiers: string[];\n};\n\ntype IndexerClientDeps = {\n fetch: FetchLike;\n};\n\nexport function createIndexerClient(baseUrl: string, deps: IndexerClientDeps) {\n const http = createJsonHttpClient(baseUrl, deps);\n\n const normalizeRecord = (record: CommitmentRecordRaw): CommitmentRecord => ({\n index: record.leaf_index,\n commitment: record.commitment,\n ephemeralKey: record.ephemeral_key,\n ciphertext: [...record.ciphertext] as [string, string, string],\n root: record.root,\n txHash: record.tx_hash,\n insertedAt: record.inserted_at,\n eventType: record.event_type ?? \"unknown\",\n adapterNpk: record.adapter_npk,\n adapterToken: record.adapter_token,\n adapterAmount: record.adapter_amount,\n adapterRandom: record.adapter_random,\n });\n\n const normalizeNullifierRecord = (\n record: NullifierRecordRaw,\n ): IndexerNullifierRecord => ({\n nullifier: record.nullifier,\n txHash: record.tx_hash,\n spentAt: record.spent_at,\n chainId: record.chain_id,\n });\n\n return {\n async fetchCommitmentBatch(\n params: FetchCommitmentsParams,\n ): Promise<CommitmentBatchResponse> {\n const raw = await http.request<CommitmentBatchResponseRaw>({\n method: \"GET\",\n path: `/chains/${params.chainId}/commitments`,\n query: {\n start: params.start,\n limit: params.limit,\n },\n });\n return {\n chainId: raw.chain_id,\n commitments: raw.commitments.map(normalizeRecord),\n latestRoot: raw.latest_root,\n };\n },\n async getCommitment(\n params: GetCommitmentParams,\n ): Promise<CommitmentRecord> {\n const raw = await http.request<CommitmentRecordRaw | null>({\n method: \"GET\",\n path: `/chains/${params.chainId}/commitments/${params.commitment}`,\n });\n if (!raw) {\n throw new HttpError(\"commitment not found\", 404, null);\n }\n return normalizeRecord(raw);\n },\n /**\n * Like getCommitment but returns null when the commitment doesn't exist.\n * Used for polling pending deposits without generating console errors.\n */\n async tryGetCommitment(\n params: GetCommitmentParams,\n ): Promise<CommitmentRecord | null> {\n const raw = await http.request<CommitmentRecordRaw | null>({\n method: \"GET\",\n path: `/chains/${params.chainId}/commitments/${params.commitment}`,\n });\n return raw ? normalizeRecord(raw) : null;\n },\n async getNullifier(\n params: GetNullifierParams,\n ): Promise<IndexerNullifierRecord | null> {\n const raw = await http.request<NullifierRecordRaw | null>({\n method: \"GET\",\n path: `/chains/${params.chainId}/nullifiers/${params.nullifier}`,\n });\n return raw ? normalizeNullifierRecord(raw) : null;\n },\n async checkNullifiers(\n params: CheckNullifiersParams,\n ): Promise<IndexerNullifierRecord[]> {\n const CHUNK_SIZE = 1000;\n if (params.nullifiers.length <= CHUNK_SIZE) {\n const raw = await http.request<CheckNullifiersRaw>({\n method: \"POST\",\n path: `/chains/${params.chainId}/nullifiers/check`,\n json: { nullifiers: params.nullifiers },\n });\n return raw.found.map(normalizeNullifierRecord);\n }\n\n // Chunk into batches of 1000, run sequentially to avoid overwhelming server\n const results: IndexerNullifierRecord[] = [];\n for (let i = 0; i < params.nullifiers.length; i += CHUNK_SIZE) {\n const chunk = params.nullifiers.slice(i, i + CHUNK_SIZE);\n const raw = await http.request<CheckNullifiersRaw>({\n method: \"POST\",\n path: `/chains/${params.chainId}/nullifiers/check`,\n json: { nullifiers: chunk },\n });\n results.push(...raw.found.map(normalizeNullifierRecord));\n }\n return results;\n },\n async getNullifierCount(chainId: number): Promise<number> {\n const raw = await http.request<NullifierCountResponseRaw>({\n method: \"GET\",\n path: `/chains/${chainId}/nullifiers/count`,\n });\n return raw.count;\n },\n };\n}\n","/**\n * Configuration for the prover system.\n * Handles artifact loading from Cloudflare R2 or local files\n * in Node.js development/test environments.\n */\n\nexport const DEFAULT_ARTIFACT_BASE_URL = \"https://artifacts.unlink.xyz\";\n\n/**\n * Artifact file types.\n */\nexport enum ArtifactType {\n WASM = \"joinsplit.wasm\",\n ZKEY = \"joinsplit.zkey\",\n VKEY = \"joinsplit.vkey.json\",\n}\n\n/**\n * Artifact source configuration.\n */\nexport interface ArtifactSourceConfig {\n /**\n * Base URL for artifact hosting.\n * Defaults to Cloudflare R2 CDN domain.\n */\n readonly baseUrl?: string;\n /**\n * Artifact version path segment.\n * Must be a pinned immutable version like `vabc12345` for remote mode.\n * Optional only when using local-only mode (`preferLocalFiles: true`).\n */\n readonly version?: string;\n /**\n * Node.js-only override to load local artifacts first.\n */\n readonly preferLocalFiles?: boolean;\n}\n\n/**\n * Fully-resolved artifact source configuration.\n */\nexport interface ResolvedArtifactSourceConfig {\n readonly baseUrl: string;\n readonly version?: string;\n readonly preferLocalFiles: boolean;\n}\n\nexport interface RemoteArtifactSourceConfig {\n readonly baseUrl: string;\n readonly version: string;\n}\n\nconst ARTIFACT_VERSION_SEGMENT_PATTERN = /^[A-Za-z0-9._-]+$/;\n\nexport function assertValidArtifactVersion(\n version: string,\n label = \"artifactSource.version\",\n): void {\n if (version.toLowerCase() === \"latest\") {\n throw new Error(`${label} must be an immutable version, not 'latest'`);\n }\n if (\n version === \".\" ||\n version === \"..\" ||\n version.includes(\"..\") ||\n !ARTIFACT_VERSION_SEGMENT_PATTERN.test(version)\n ) {\n throw new Error(\n `${label} must be a safe single path segment using [A-Za-z0-9._-] and must not contain '..'`,\n );\n }\n}\n\n/**\n * Resolve artifact source configuration with defaults.\n */\nexport function resolveArtifactSourceConfig(\n config?: ArtifactSourceConfig,\n): ResolvedArtifactSourceConfig {\n const baseUrl = (config?.baseUrl ?? DEFAULT_ARTIFACT_BASE_URL).replace(\n /\\/+$/,\n \"\",\n );\n const rawVersion = config?.version;\n const version =\n rawVersion === undefined\n ? undefined\n : rawVersion.replace(/^\\/+|\\/+$/g, \"\").trim();\n const preferLocalFiles = config?.preferLocalFiles ?? false;\n\n if (version === \"\") {\n throw new Error(\"artifactSource.version must be a non-empty string\");\n }\n if (version) {\n assertValidArtifactVersion(version);\n }\n if (!version && !preferLocalFiles) {\n throw new Error(\n \"artifactSource.version is required unless artifactSource.preferLocalFiles is true\",\n );\n }\n\n return {\n baseUrl,\n version,\n preferLocalFiles,\n };\n}\n\n/**\n * Require a remote-capable source (baseUrl + immutable version).\n */\nexport function requireRemoteArtifactSource(\n source: ResolvedArtifactSourceConfig,\n): RemoteArtifactSourceConfig {\n if (!source.version) {\n throw new Error(\n \"artifactSource.version is required when loading remote artifacts\",\n );\n }\n return {\n baseUrl: source.baseUrl,\n version: source.version,\n };\n}\n\n/**\n * Build R2 artifact URL for a given circuit and artifact type.\n * Format: `https://artifacts.unlink.xyz/<version>/<circuit>/<file>`.\n */\nexport function buildR2ArtifactUrl(\n circuitName: string,\n artifactType: ArtifactType,\n source: RemoteArtifactSourceConfig,\n): string {\n return `${source.baseUrl}/${source.version}/${circuitName}/${artifactType}`;\n}\n\n/**\n * Build R2 checksums manifest URL for a given circuit.\n * Format: `https://artifacts.unlink.xyz/<version>/<circuit>/checksums.json`.\n */\nexport function buildR2ChecksumsUrl(\n circuitName: string,\n source: RemoteArtifactSourceConfig,\n): string {\n return `${source.baseUrl}/${source.version}/${circuitName}/checksums.json`;\n}\n\n/**\n * Get relative path for local artifact loading\n * Used in Node.js environment when artifacts are bundled\n * @param circuitName Full circuit name (e.g., \"joinsplit_2x3_16\")\n * @param artifactType Type of artifact\n * @returns Relative path to artifact\n */\nexport function getLocalArtifactPath(\n circuitName: string,\n artifactType: ArtifactType,\n): string[] {\n // Return multiple candidate paths for different build scenarios\n return [\n // When compiled: dist/prover/ -> ../../artifacts/circuits/{circuit}/\n `../../artifacts/circuits/${circuitName}/${artifactType}`,\n // When in source: prover/ -> ../artifacts/circuits/{circuit}/\n `../artifacts/circuits/${circuitName}/${artifactType}`,\n ];\n}\n\n/**\n * Runtime detection utilities\n */\nexport const Runtime = {\n /**\n * Check if running in browser environment\n */\n isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n },\n\n /**\n * Check if running in Node.js environment\n */\n isNode(): boolean {\n return (\n typeof process !== \"undefined\" &&\n process.versions != null &&\n process.versions.node != null\n );\n },\n\n /**\n * Get environment description for debugging\n */\n getEnvironment(): string {\n if (this.isBrowser()) return \"browser\";\n if (this.isNode()) return \"node\";\n return \"unknown\";\n },\n};\n","/**\n * Environment types for SDK configuration.\n */\nimport { InitializationError } from \"./errors.js\";\nimport { DEFAULT_ARTIFACT_BASE_URL } from \"./prover/config.js\";\n\nexport type Environment = \"mainnet\" | \"testnet\" | \"local\";\n\n/**\n * Configuration for a specific environment.\n */\nexport interface EnvironmentConfig {\n gatewayUrl: string;\n poolAddress: string;\n artifactVersion: string;\n artifactBaseUrl?: string;\n}\n\n/**\n * Service configuration with broadcaster and indexer URLs.\n */\nexport interface ServiceConfig {\n broadcasterBaseUrl: string;\n indexerBaseUrl: string;\n}\n\nconst CONFIG_URL = \"https://config.unlink.xyz/networks.json\";\n\nfunction parseRequiredString(\n env: Environment,\n field: string,\n value: unknown,\n): string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new InitializationError(\n `Invalid SDK config for ${env}: ${field} must be a non-empty string`,\n );\n }\n return value.trim();\n}\n\nfunction parseOptionalString(\n env: Environment,\n field: string,\n value: unknown,\n): string | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new InitializationError(\n `Invalid SDK config for ${env}: ${field} must be a non-empty string when provided`,\n );\n }\n return value.trim();\n}\n\nfunction parseEnvironmentConfig(\n env: Environment,\n value: unknown,\n): EnvironmentConfig {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new InitializationError(\n `Invalid SDK config for ${env}: expected object`,\n );\n }\n\n const raw = value as Record<string, unknown>;\n const gatewayUrl = parseRequiredString(\n env,\n \"gatewayUrl\",\n raw.gatewayUrl,\n ).replace(/\\/+$/, \"\");\n const poolAddress = parseRequiredString(env, \"poolAddress\", raw.poolAddress);\n const artifactVersion = parseRequiredString(\n env,\n \"artifactVersion\",\n raw.artifactVersion,\n ).replace(/^\\/+|\\/+$/g, \"\");\n const artifactBaseUrl = parseOptionalString(\n env,\n \"artifactBaseUrl\",\n raw.artifactBaseUrl,\n )?.replace(/\\/+$/, \"\");\n\n return {\n gatewayUrl,\n poolAddress,\n artifactVersion,\n ...(artifactBaseUrl !== undefined\n ? { artifactBaseUrl }\n : { artifactBaseUrl: DEFAULT_ARTIFACT_BASE_URL }),\n };\n}\n\n/**\n * Fetch environment configuration from the hosted network config file.\n *\n * @param env - The environment to fetch config for\n * @returns Promise resolving to the environment configuration\n * @throws If fetch fails or environment is not found\n */\nexport async function fetchEnvironmentConfig(\n env: Environment,\n): Promise<EnvironmentConfig> {\n const res = await fetch(CONFIG_URL);\n if (!res.ok) {\n throw new InitializationError(`Failed to fetch SDK config: ${res.status}`);\n }\n const config = (await res.json()) as Record<string, unknown>;\n if (!config[env]) {\n throw new InitializationError(`Unknown environment: ${env}`);\n }\n return parseEnvironmentConfig(env, config[env]);\n}\n\n/**\n * Create service configuration from a gateway URL.\n *\n * @param gatewayUrl - The base gateway URL\n * @returns Service configuration with broadcaster and indexer URLs\n */\nexport function createServiceConfig(gatewayUrl: string): ServiceConfig {\n const baseUrl = gatewayUrl.replace(/\\/+$/, \"\");\n return {\n broadcasterBaseUrl: baseUrl + \"/broadcaster\",\n indexerBaseUrl: baseUrl + \"/indexer\",\n };\n}\n","import { ed25519, x25519 } from \"@noble/curves/ed25519.js\";\n\nimport { CoreError } from \"../errors.js\";\nimport { FieldSize, Hex } from \"../keys/hex.js\";\nimport type { Ciphertext, NoteInput } from \"../transactions/types/index.js\";\nimport { parseHexToBigInt } from \"../utils/bigint.js\";\nimport { SNARK_SCALAR_FIELD } from \"../utils/validators.js\";\nimport { poseidon } from \"./adapters/index.js\";\n\n/**\n * Derive a 3-element keystream from an ECDH shared secret.\n * keystream[i] = Poseidon(sharedSecretScalar, i)\n */\nfunction deriveKeystream(sharedSecret: Uint8Array): [bigint, bigint, bigint] {\n const scalar =\n BigInt(\"0x\" + Hex.fromBytes(sharedSecret)) % SNARK_SCALAR_FIELD;\n return [\n poseidon([scalar, 0n]),\n poseidon([scalar, 1n]),\n poseidon([scalar, 2n]),\n ];\n}\n\n/**\n * Encrypt a note for the holder of the given Ed25519 viewing public key.\n * Uses X25519 ECDH + field addition mod SNARK_SCALAR_FIELD.\n */\nexport function encryptNote(\n note: NoteInput,\n recipientViewingPubKey: Uint8Array,\n): Ciphertext {\n const recipientX25519 = ed25519.utils.toMontgomery(recipientViewingPubKey);\n const ephPriv = x25519.utils.randomSecretKey();\n const ephPub = x25519.getPublicKey(ephPriv);\n const sharedSecret = x25519.getSharedSecret(ephPriv, recipientX25519);\n\n const keystream = deriveKeystream(sharedSecret);\n const plaintext: [bigint, bigint, bigint] = [\n note.random,\n parseHexToBigInt(note.token),\n note.amount,\n ];\n\n return {\n ephemeralKey: BigInt(\"0x\" + Hex.fromBytes(ephPub)),\n data: [\n (plaintext[0] + keystream[0]) % SNARK_SCALAR_FIELD,\n (plaintext[1] + keystream[1]) % SNARK_SCALAR_FIELD,\n (plaintext[2] + keystream[2]) % SNARK_SCALAR_FIELD,\n ],\n };\n}\n\n/**\n * Decrypt a ciphertext using the recipient's Ed25519 viewing private key.\n * Reverses field addition: plaintext = (ciphertext - keystream + p) mod p\n *\n * **Important:** This decryption is unauthenticated. Callers MUST verify the\n * output by recomputing the commitment (Poseidon(npk, token, amount)) and\n * comparing it against the on-chain value. See note-sync.ts for the pattern.\n */\nexport function decryptNote(\n c: Ciphertext,\n viewingPrivKey: Uint8Array,\n): { random: bigint; token: string; amount: bigint } {\n const myX25519 = ed25519.utils.toMontgomerySecret(viewingPrivKey);\n const ephPub = Hex.toBytes(Hex.fromBigInt(c.ephemeralKey, FieldSize.SCALAR));\n const sharedSecret = x25519.getSharedSecret(myX25519, ephPub);\n\n const keystream = deriveKeystream(sharedSecret);\n\n const random =\n (c.data[0] - keystream[0] + SNARK_SCALAR_FIELD) % SNARK_SCALAR_FIELD;\n const tokenBigint =\n (c.data[1] - keystream[1] + SNARK_SCALAR_FIELD) % SNARK_SCALAR_FIELD;\n const amount =\n (c.data[2] - keystream[2] + SNARK_SCALAR_FIELD) % SNARK_SCALAR_FIELD;\n\n if (tokenBigint > 0xffffffffffffffffffffffffffffffffffffffffn) {\n throw new CoreError(\"Invalid Decrypt\");\n }\n\n return {\n random,\n token: \"0x\" + tokenBigint.toString(16).padStart(40, \"0\"),\n amount,\n };\n}\n\nexport function deriveCommitment(note: {\n npk: bigint;\n amount: bigint;\n token: string;\n}) {\n const tokenScalar = BigInt(note.token);\n return poseidon([note.npk, tokenScalar, note.amount]);\n}\n\n/**\n * Derive the nullifier public key (npk) from a note.\n */\nexport function deriveNpk(note: NoteInput) {\n return poseidon([note.mpk, note.random]);\n}\n\n/**\n * Compute the commitment for a note given its npk.\n */\nexport function computeCommitment(note: NoteInput, npk: bigint) {\n const tokenScalar = BigInt(note.token);\n return poseidon([npk, tokenScalar, note.amount]);\n}\n","import { HttpError } from \"../clients/http.js\";\n\n/**\n * Promise-based delay utility.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Type guard for HTTP 404 errors.\n */\nexport function isNotFoundError(err: unknown): err is HttpError {\n return err instanceof HttpError && err.status === 404;\n}\n\n/**\n * Race a promise against a timeout, rejecting if the timeout fires first.\n * Properly cleans up the timeout to avoid memory leaks.\n *\n * @param promise - The promise to race against the timeout\n * @param ms - Timeout in milliseconds\n * @param error - Error to throw on timeout (string message or Error instance)\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n error?: string | Error,\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n error instanceof Error\n ? error\n : new Error(error ?? `Operation timed out after ${ms}ms`),\n );\n }, ms);\n }),\n ]).finally(() => {\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n });\n}\n","/**\n * Shared polling configuration constants.\n */\nexport const DEFAULT_POLL_INTERVAL_MS = 500;\nexport const DEFAULT_POLL_TIMEOUT_MS = 30_000;\nexport const MAX_POLL_INTERVAL_MS = 5_000;\n/**\n * Initial delay before first poll for fresh deposits.\n * Reduces wasted 404 requests while commitment is being indexed.\n */\nexport const DEFAULT_INITIAL_POLL_DELAY_MS = 2_000;\n","import { IMTMerkleProof } from \"@zk-kit/imt\";\nimport { AbiCoder, Interface, keccak256 } from \"ethers\";\n\nimport type { AccountView, Signer } from \"../account/account.js\";\nimport { createBroadcasterClient } from \"../clients/broadcaster.js\";\nimport { resolveFetch } from \"../clients/http.js\";\nimport { CommitmentRecord, createIndexerClient } from \"../clients/indexer.js\";\nimport { createServiceConfig } from \"../config.js\";\nimport { poseidon } from \"../crypto/adapters/index.js\";\nimport { deriveCommitment, encryptNote } from \"../crypto/encrypt.js\";\nimport { CoreError, ProofError, ValidationError } from \"../errors.js\";\nimport {\n JoinsplitProofInput,\n proveTransaction,\n type ProverOptions,\n} from \"../prover/index.js\";\nimport {\n DEFAULT_JOB_TIMEOUT_MS,\n PoolTransactionRecord,\n rebuildTreeFromStore,\n resolveMerkleTrees,\n TransferRecord,\n WithdrawRecord,\n} from \"../state/index.js\";\nimport { isNotFoundError, sleep, withTimeout } from \"../utils/async.js\";\nimport { formatUint256, parseHexToBigInt } from \"../utils/bigint.js\";\nimport {\n DEFAULT_POLL_INTERVAL_MS,\n DEFAULT_POLL_TIMEOUT_MS,\n MAX_POLL_INTERVAL_MS,\n} from \"../utils/polling.js\";\nimport { generateRelayId } from \"../utils/random.js\";\nimport { SNARK_SCALAR_FIELD } from \"../utils/validators.js\";\nimport {\n Proof,\n SerializedWitness,\n ServiceOptions,\n TransactItem,\n TransactItemResult,\n TransactParams,\n TransactRelayResult,\n TransactStateStore,\n TransactSyncResult,\n} from \"./types/index.js\";\n\nexport const TRANSACT_ABI =\n \"function transact(((uint256[2] pA, uint256[2][2] pB, uint256[2] pC) proof, uint256 merkleRoot, uint256[] nullifierHashes, uint256[] newCommitments, (uint64 chainId, address poolAddress, uint256 adapterDataHash) context, (uint256 npk, uint256 amount, address token) withdrawal, (uint256 ephemeralKey, uint256[3] data)[] ciphertexts)[] _transactions)\";\n\n/** Default timeout for proof generation in milliseconds (60 seconds) */\nexport const DEFAULT_PROOF_TIMEOUT_MS = 60_000;\n\nconst transactInterface = new Interface([TRANSACT_ABI]);\nconst DEFAULT_WITHDRAWAL = {\n npk: 0n,\n amount: 0n,\n token: \"0x0000000000000000000000000000000000000000\",\n};\n\nexport function computeBoundParamsHash(\n chainId: number,\n poolAddress: string,\n adapterDataHash: bigint = 0n,\n): bigint {\n const coder = AbiCoder.defaultAbiCoder();\n const encoded = coder.encode(\n [\"uint64\", \"uint160\", \"uint256\"],\n [BigInt(chainId), BigInt(poolAddress), adapterDataHash],\n );\n return parseHexToBigInt(keccak256(encoded)) % SNARK_SCALAR_FIELD;\n}\n\nexport type AdapterExecutionCall = {\n to: string;\n data: string;\n value: bigint;\n};\n\nexport type AdapterExecutionReshield = {\n npk: bigint;\n random: bigint;\n token: string;\n minAmount: bigint;\n};\n\nexport function computeAdapterDataHash(params: {\n calls: AdapterExecutionCall[];\n reshields: AdapterExecutionReshield[];\n inputTokens: string[];\n nonce: bigint;\n deadline: bigint;\n chainId: number;\n}): bigint {\n const coder = AbiCoder.defaultAbiCoder();\n const encoded = coder.encode(\n [\n \"tuple(address to, bytes data, uint256 value)[]\",\n \"tuple(uint256 npk, uint256 random, address token, uint256 minAmount)[]\",\n \"address[]\",\n \"uint256\",\n \"uint256\",\n \"uint256\",\n ],\n [\n params.calls,\n params.reshields,\n params.inputTokens,\n params.nonce,\n params.deadline,\n BigInt(params.chainId),\n ],\n );\n return parseHexToBigInt(keccak256(encoded)) % SNARK_SCALAR_FIELD;\n}\n\nexport function serializeWitness(\n proof: IMTMerkleProof,\n index: number,\n): SerializedWitness {\n return {\n root: formatUint256(BigInt(proof.root)),\n leaf: formatUint256(BigInt(proof.leaf)),\n pathElements: proof.siblings.map((level: unknown[]) =>\n level.map((node: unknown) => formatUint256(BigInt(node as bigint))),\n ),\n pathIndices: proof.pathIndices ?? [],\n leafIndex: index,\n };\n}\n\nexport function deserializeWitness(s: SerializedWitness): IMTMerkleProof {\n return {\n root: parseHexToBigInt(s.root),\n leaf: parseHexToBigInt(s.leaf),\n siblings: s.pathElements.map((level) => level.map(parseHexToBigInt)),\n pathIndices: s.pathIndices,\n leafIndex: s.leafIndex,\n };\n}\n\n// ============================================================================\n// Internal: Single transaction proof generation\n// ============================================================================\n\ntype SingleTxResult = {\n proof: Proof;\n witnesses: IMTMerkleProof[];\n nullifiers: string[];\n predictedCommitments: string[];\n merkleRoot: string;\n token: string;\n withdrawal: typeof DEFAULT_WITHDRAWAL;\n ciphertexts: { data: [bigint, bigint, bigint] }[];\n contexts: Array<{\n index: number;\n nullifier: bigint;\n nullifierHex: string;\n witness: IMTMerkleProof;\n }>;\n outputs: Array<{ value: bigint; hex: string; index: number }>;\n inputNotes: Array<{ value: string | bigint; random: string | bigint }>;\n};\n\n/**\n * Build proof for a single transaction item.\n * This is the core proof generation logic extracted for parallelization.\n */\nasync function buildSingleTransactionProof(\n store: TransactStateStore,\n account: AccountView,\n signer: Signer,\n chainId: number,\n poolAddress: string,\n tx: TransactItem,\n trees: ReturnType<typeof resolveMerkleTrees>,\n baseIndex: number,\n opts: ServiceOptions,\n): Promise<SingleTxResult> {\n if (!tx.inputs?.length)\n throw new ValidationError(\"at least one input note is required\");\n\n // Build input contexts (witnesses + nullifiers)\n const contexts: {\n index: number;\n nullifier: bigint;\n nullifierHex: string;\n witness: IMTMerkleProof;\n }[] = [];\n let merkleRoot: string | undefined;\n\n for (const input of tx.inputs) {\n const note = await store.getNote(chainId, input.index);\n if (!note) throw new ValidationError(`note ${input.index} not found`);\n if (note.spentAt !== undefined)\n throw new ValidationError(`note ${input.index} already spent`);\n\n const tree = trees.getOrCreate(chainId);\n if (input.index >= tree.getLeafCount())\n throw new ValidationError(`note ${input.index} out of range`);\n\n const witness = tree.createMerkleProof(input.index);\n const root = formatUint256(BigInt(witness.root));\n if (merkleRoot && merkleRoot !== root)\n throw new ValidationError(\"inputs must share same merkle root\");\n merkleRoot = root;\n\n const nullifier = poseidon([account.nullifyingKey, BigInt(input.index)]);\n contexts.push({\n index: input.index,\n nullifier,\n nullifierHex: formatUint256(nullifier),\n witness,\n });\n }\n\n // Compute output commitments for regular notes\n const outputs = tx.outputs.map((o, i) => {\n const commitment = deriveCommitment({\n npk: poseidon([o.mpk, o.random]),\n amount: o.amount,\n token: o.token,\n });\n return {\n value: commitment,\n hex: formatUint256(commitment),\n index: baseIndex + i,\n };\n });\n\n // Handle withdrawal\n const withdrawal = tx.withdrawal ?? DEFAULT_WITHDRAWAL;\n const hasWithdrawal = withdrawal.amount > 0n;\n\n if (hasWithdrawal && withdrawal.token !== tx.token) {\n throw new ValidationError(\"Withdrawal token must match transaction token\");\n }\n\n const withdrawalCommitment = hasWithdrawal\n ? deriveCommitment({\n npk: withdrawal.npk,\n amount: withdrawal.amount,\n token: withdrawal.token,\n })\n : null;\n\n // Build arrays for circuit\n const allCommitmentsOut = hasWithdrawal\n ? [...outputs.map((o) => o.value), withdrawalCommitment!]\n : outputs.map((o) => o.value);\n\n const allNpkOut = hasWithdrawal\n ? [...tx.outputs.map((o) => poseidon([o.mpk, o.random])), withdrawal.npk]\n : tx.outputs.map((o) => poseidon([o.mpk, o.random]));\n\n const allValueOut = hasWithdrawal\n ? [...tx.outputs.map((o) => o.amount), withdrawal.amount]\n : tx.outputs.map((o) => o.amount);\n\n // Build prover input\n const adapterDataHash = tx.adapterDataHash ?? 0n;\n const boundParams = computeBoundParamsHash(\n chainId,\n poolAddress,\n adapterDataHash,\n );\n const pubSignals = [\n parseHexToBigInt(merkleRoot!),\n boundParams,\n ...contexts.map((c) => c.nullifier),\n ...allCommitmentsOut,\n ];\n\n const inputNotes = await Promise.all(\n tx.inputs.map((i) => store.getNote(chainId, i.index).then((n) => n!)),\n );\n\n const sig = await signer.sign(poseidon(pubSignals));\n\n const proofInput: JoinsplitProofInput = {\n merkleRoot: parseHexToBigInt(merkleRoot!),\n boundParamsHash: boundParams,\n nullifiers: contexts.map((c) => c.nullifier),\n commitmentsOut: allCommitmentsOut,\n token: BigInt(tx.token),\n publicKey: signer.publicKey,\n signature: [sig.R8[0], sig.R8[1], sig.S],\n randomIn: inputNotes.map((n) => BigInt(n.random)),\n valueIn: inputNotes.map((n) => BigInt(n.value)),\n pathElements: contexts.map((c) =>\n c.witness.siblings.map((level) => level.map((s: bigint) => s)),\n ),\n leavesIndices: contexts.map((c) => BigInt(c.index)),\n nullifyingKey: account.nullifyingKey,\n npkOut: allNpkOut,\n valueOut: allValueOut,\n };\n\n const proofTimeoutMs = opts.proofTimeoutMs ?? DEFAULT_PROOF_TIMEOUT_MS;\n const proverOptions: ProverOptions = {\n ...opts.prover,\n };\n\n const txProof = await withTimeout(\n proveTransaction(proofInput, proverOptions),\n proofTimeoutMs,\n new ProofError(`Proof generation timed out after ${proofTimeoutMs}ms`),\n ).catch((e) => {\n if (e instanceof ProofError) throw e;\n throw new ProofError(`Proof generation failed: ${e.message}`);\n });\n\n const proof: Proof = {\n pA: [BigInt(txProof.proof.pi_a[0]!), BigInt(txProof.proof.pi_a[1]!)],\n pB: [\n [BigInt(txProof.proof.pi_b[0]![1]!), BigInt(txProof.proof.pi_b[0]![0]!)],\n [BigInt(txProof.proof.pi_b[1]![1]!), BigInt(txProof.proof.pi_b[1]![0]!)],\n ],\n pC: [BigInt(txProof.proof.pi_c[0]!), BigInt(txProof.proof.pi_c[1]!)],\n pubSignals,\n };\n\n return {\n proof,\n witnesses: contexts.map((c) => c.witness),\n nullifiers: contexts.map((c) => c.nullifierHex),\n predictedCommitments: outputs.map((o) => o.hex),\n merkleRoot: merkleRoot!,\n token: tx.token,\n withdrawal,\n ciphertexts: tx.outputs.map((note) => {\n const encrypted = encryptNote(note, note.viewingPublicKey);\n return { ephemeralKey: encrypted.ephemeralKey, data: encrypted.data };\n }),\n contexts,\n outputs,\n inputNotes,\n };\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Execute private transaction(s): build ZK proofs (in parallel), encrypt outputs, and broadcast.\n * Accepts 1 or more transactions - single tx just passes [{...}].\n */\nexport async function transact(\n store: TransactStateStore,\n req: TransactParams,\n opts: ServiceOptions,\n): Promise<TransactRelayResult> {\n if (!req.transactions?.length)\n throw new ValidationError(\"at least one transaction is required\");\n\n const serviceConfig = createServiceConfig(opts.gatewayUrl);\n const trees = resolveMerkleTrees(opts);\n const fetchFn = resolveFetch(opts.fetch);\n const broadcaster = fetchFn\n ? createBroadcasterClient(serviceConfig.broadcasterBaseUrl, {\n fetch: fetchFn,\n })\n : null;\n const pollInterval = Math.min(\n opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS,\n MAX_POLL_INTERVAL_MS,\n );\n const pollTimeout = opts.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;\n\n await rebuildTreeFromStore({\n chainId: req.chainId,\n trees,\n loadLeaves: store.listLeaves.bind(store),\n });\n\n // Calculate base indices for each transaction's outputs\n let baseIndex = trees.getLeafCount(req.chainId);\n const baseIndices: number[] = [];\n for (const tx of req.transactions) {\n baseIndices.push(baseIndex);\n baseIndex += tx.outputs.length;\n }\n\n // Generate proofs in PARALLEL for all transactions\n const proofPromises = req.transactions.map((tx, i) =>\n buildSingleTransactionProof(\n store,\n req.account,\n req.signer,\n req.chainId,\n req.poolAddress,\n tx,\n trees,\n baseIndices[i]!,\n opts,\n ),\n );\n const results = await Promise.all(proofPromises);\n\n // Build combined calldata\n const calldata = transactInterface.encodeFunctionData(\"transact\", [\n results.map((r, i) => ({\n proof: { pA: r.proof.pA, pB: r.proof.pB, pC: r.proof.pC },\n merkleRoot: parseHexToBigInt(r.merkleRoot),\n nullifierHashes: r.contexts.map((c) => c.nullifier),\n newCommitments: r.proof.pubSignals.slice(\n 2 + r.contexts.length, // Skip root + boundParams + nullifiers\n r.withdrawal.amount > 0n\n ? r.proof.pubSignals.length - 1 // Exclude withdrawal commitment (not inserted into tree)\n : undefined,\n ),\n context: {\n chainId: BigInt(req.chainId),\n poolAddress: req.poolAddress,\n adapterDataHash: req.transactions[i]?.adapterDataHash ?? 0n,\n },\n withdrawal: r.withdrawal,\n ciphertexts: r.ciphertexts,\n })),\n ]);\n\n const relayId = generateRelayId(\"tx\");\n\n // Determine if this is a withdrawal (any transaction has withdrawal)\n const hasAnyWithdrawal = results.some((r) => r.withdrawal.amount > 0n);\n const historyKind = hasAnyWithdrawal ? \"Withdraw\" : \"Send\";\n\n // Compute net deltas per token for history preview\n const deltasByToken = new Map<string, bigint>();\n for (let i = 0; i < req.transactions.length; i++) {\n const tx = req.transactions[i]!;\n const r = results[i]!;\n\n const totalOutputsToRecipients = tx.outputs\n .filter((o) => o.owner === \"recipient\")\n .reduce((sum, o) => sum + o.amount, 0n);\n\n // For withdrawals: user loses the withdrawal amount\n // For sends: user loses what they send to recipients (change returns to them)\n const netDelta =\n r.withdrawal.amount > 0n\n ? -r.withdrawal.amount\n : -totalOutputsToRecipients;\n\n const existing = deltasByToken.get(tx.token) ?? 0n;\n deltasByToken.set(tx.token, existing + netDelta);\n }\n\n const jobBase = {\n relayId,\n chainId: req.chainId,\n status: \"pending\" as const,\n txHash: null,\n createdAt: Date.now(),\n timeoutMs: DEFAULT_JOB_TIMEOUT_MS,\n poolAddress: req.poolAddress,\n calldata,\n transactions: results.map((r, i) => {\n const tx = req.transactions[i]!;\n return {\n token: tx.token,\n nullifiers: r.nullifiers,\n predictedCommitments: r.outputs.map((o) => ({ hex: o.hex })),\n withdrawal:\n r.withdrawal.amount > 0n\n ? {\n amount: r.withdrawal.amount.toString(),\n recipient: r.withdrawal.npk.toString(),\n }\n : undefined,\n };\n }),\n historyPreview: {\n kind: historyKind as \"Send\" | \"Withdraw\",\n amounts: [...deltasByToken.entries()].map(([token, delta]) => ({\n token,\n delta: delta.toString(),\n })),\n },\n };\n\n const job: TransferRecord | WithdrawRecord = hasAnyWithdrawal\n ? { ...jobBase, kind: \"withdraw\" as const }\n : { ...jobBase, kind: \"transfer\" as const };\n\n // Submit to broadcaster (unless skipBroadcast is set, e.g. for swap adapter wrapping)\n let txHash: string | null = null;\n\n if (!opts.skipBroadcast && broadcaster) {\n const submission = await broadcaster.submitRelay({\n clientTxId: relayId,\n chainId: req.chainId,\n payload: { kind: \"call_data\", to: req.poolAddress, data: calldata },\n });\n if (!submission.accepted) {\n await store.putJob({\n ...job,\n status: \"failed\",\n lastCheckedAt: Date.now(),\n error: submission.message ?? \"broadcaster rejected\",\n });\n throw new CoreError(submission.message ?? \"broadcaster rejected\");\n }\n\n const deadline = Date.now() + pollTimeout;\n while (Date.now() <= deadline) {\n const status = await broadcaster.getRelayStatus(relayId);\n if (status.state === \"succeeded\") {\n txHash = status.txHash ?? null;\n break;\n }\n if (\n status.state === \"reverted\" ||\n status.state === \"failed\" ||\n status.state === \"dead\"\n ) {\n const relayError =\n status.error ??\n (status.state === \"reverted\"\n ? \"broadcaster relay reverted\"\n : \"broadcaster relay failed\");\n await store.putJob({\n ...job,\n status: \"failed\",\n lastCheckedAt: Date.now(),\n error: relayError,\n });\n throw new CoreError(relayError);\n }\n await sleep(pollInterval);\n }\n if (!txHash && Date.now() > deadline) {\n await store.putJob({\n ...job,\n status: \"failed\",\n lastCheckedAt: Date.now(),\n error: \"broadcaster relay timed out\",\n });\n throw new CoreError(\"broadcaster relay timed out\");\n }\n }\n\n if (opts.persistJob !== false) {\n await store.putJob({\n ...job,\n status: \"broadcasting\",\n txHash,\n });\n }\n\n // Build result with individual transaction results\n const transactionResults: TransactItemResult[] = results.map((r) => ({\n proof: r.proof,\n witnesses: r.witnesses,\n nullifiers: r.nullifiers,\n predictedCommitments: r.predictedCommitments,\n }));\n\n return {\n relayId,\n calldata,\n transactions: transactionResults,\n };\n}\n\n/**\n * Wait for a pending transaction to be indexed and update local state.\n */\nexport async function syncTransact(\n store: TransactStateStore,\n relayId: string,\n opts: ServiceOptions,\n): Promise<TransactSyncResult> {\n const record = await store.getJob(relayId);\n if (\n !record ||\n (record.kind !== \"transfer\" &&\n record.kind !== \"withdraw\" &&\n record.kind !== \"adapter\")\n )\n throw new CoreError(`unknown pool transaction relay ${relayId}`);\n const job = record as PoolTransactionRecord;\n\n const serviceConfig = createServiceConfig(opts.gatewayUrl);\n const trees = resolveMerkleTrees(opts);\n const fetchFn = resolveFetch(opts.fetch);\n const indexer = fetchFn\n ? createIndexerClient(serviceConfig.indexerBaseUrl, { fetch: fetchFn })\n : null;\n const pollInterval = Math.min(\n opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS,\n MAX_POLL_INTERVAL_MS,\n );\n const pollTimeout = opts.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;\n\n await rebuildTreeFromStore({\n chainId: job.chainId,\n trees,\n loadLeaves: store.listLeaves.bind(store),\n });\n\n // Collect all predicted commitments from all transactions\n const allPredictedOutputs = job.transactions.flatMap((tx) =>\n tx.predictedCommitments.map((c) => c.hex),\n );\n\n // Wait for indexed commitments\n const indexed: CommitmentRecord[] = [];\n if (indexer && allPredictedOutputs.length > 0) {\n const pending = new Set(allPredictedOutputs.map((h) => h.toLowerCase()));\n const deadline = Date.now() + pollTimeout;\n let delay = pollInterval;\n\n while (pending.size > 0 && Date.now() <= deadline) {\n for (const hex of [...pending]) {\n const rec = await indexer\n .getCommitment({ chainId: job.chainId, commitment: hex })\n .catch((e) => {\n if (!isNotFoundError(e)) throw e;\n return null;\n });\n if (rec) {\n indexed.push(rec);\n pending.delete(hex);\n }\n }\n if (pending.size > 0) {\n await sleep(delay);\n delay = Math.min(delay * 2, MAX_POLL_INTERVAL_MS);\n }\n }\n if (pending.size > 0) {\n await store.putJob({\n ...job,\n status: \"failed\",\n lastCheckedAt: Date.now(),\n error: \"commitments not indexed before timeout\",\n });\n throw new CoreError(\"commitments not indexed before timeout\");\n }\n }\n\n // Get latest root from indexed records (syncChain handles actual storage)\n const sortedIndexed = indexed.sort((a, b) => a.index - b.index);\n const latestRoot = sortedIndexed.at(-1)?.root ?? trees.getRoot(job.chainId);\n\n // Collect all nullifiers from all transactions and mark notes as spent\n const allNullifiers = job.transactions.flatMap((tx) => tx.nullifiers);\n const timestamp = Date.now();\n\n // Look up note indices by matching nullifiers to notes in the store\n const allNotes = await store.listNotes({\n chainId: job.chainId,\n includeSpent: true,\n });\n const nullifierToNoteIndex = new Map<string, number>();\n for (const note of allNotes) {\n if (note.nullifier) {\n nullifierToNoteIndex.set(note.nullifier, note.index);\n }\n }\n\n // Resolve every nullifier to its note index, fail fast if any is unknown\n const resolved: { nullifier: string; noteIndex: number }[] = [];\n for (const nullifier of allNullifiers) {\n const noteIndex = nullifierToNoteIndex.get(nullifier);\n if (noteIndex === undefined) {\n const short = nullifier.slice(0, 10) + \"…\";\n const error = `Unknown nullifier ${short} - note not found in local state. This may indicate a sync issue.`;\n await store.putJob({\n ...job,\n status: \"failed\",\n lastCheckedAt: Date.now(),\n error,\n });\n throw new CoreError(error);\n }\n resolved.push({ nullifier, noteIndex });\n }\n\n const txHash = job.txHash ?? undefined;\n await Promise.all(\n resolved.flatMap(({ nullifier, noteIndex }) => [\n store.putNullifier({ chainId: job.chainId, nullifier, noteIndex }),\n store.markNoteSpent(job.chainId, noteIndex, timestamp, txHash),\n ]),\n );\n\n await store.putJob({\n ...job,\n status: \"succeeded\",\n lastCheckedAt: timestamp,\n });\n\n return {\n chainId: job.chainId,\n root: latestRoot,\n nullifiers: allNullifiers,\n newCommitments: indexed.map((r) => r.commitment),\n txHash: job.txHash ?? undefined,\n indexedCommitments: indexed,\n };\n}\n","import type { FetchLike } from \"./http.js\";\nimport { createJsonHttpClient } from \"./http.js\";\n\nexport type BroadcasterRelayPayload = {\n kind: \"call_data\";\n to: string;\n data: string;\n};\n\nexport type SubmitRelayParams = {\n clientTxId: string;\n chainId: number;\n payload: BroadcasterRelayPayload;\n};\n\nexport type SubmitRelayResponse = {\n id: string;\n accepted: boolean;\n message?: string | null;\n};\n\nexport type RelayState =\n | \"pending\"\n | \"broadcasting\"\n | \"submitted\"\n | \"succeeded\"\n | \"reverted\"\n | \"failed\"\n | \"dead\";\n\nexport type TransactionReceipt = {\n blockNumber?: number;\n blockHash?: string;\n transactionIndex?: number;\n};\n\nexport type RelayStatusResponse = {\n id: string;\n state: RelayState;\n txHash?: string | null;\n receipt?: TransactionReceipt | null;\n error?: string | null;\n};\n\n// Internal type matching server's snake_case response\ntype RelayStatusRaw = {\n id: string;\n state: RelayState;\n tx_hash?: string | null;\n receipt?: TransactionReceipt | null;\n error?: string | null;\n};\n\ntype BroadcasterClientDeps = {\n fetch: FetchLike;\n};\n\nconst RELAY_STATUS_BATCH_LIMIT = 50;\n\nfunction toRelayStatusResponse(raw: RelayStatusRaw): RelayStatusResponse {\n return {\n id: raw.id,\n state: raw.state,\n txHash: raw.tx_hash,\n receipt: raw.receipt,\n error: raw.error,\n };\n}\n\nfunction chunkArray<T>(items: T[], chunkSize: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < items.length; i += chunkSize) {\n chunks.push(items.slice(i, i + chunkSize));\n }\n return chunks;\n}\n\nexport function createBroadcasterClient(\n baseUrl: string,\n deps: BroadcasterClientDeps,\n) {\n const http = createJsonHttpClient(baseUrl, deps);\n\n return {\n async submitRelay(params: SubmitRelayParams) {\n return http.request<SubmitRelayResponse>({\n method: \"POST\",\n path: \"/relays\",\n json: {\n client_tx_id: params.clientTxId,\n chain_id: params.chainId,\n ...params.payload,\n },\n });\n },\n\n async getRelayStatus(relayId: string): Promise<RelayStatusResponse> {\n const raw = await http.request<RelayStatusRaw>({\n method: \"GET\",\n path: `/relays/${relayId}`,\n });\n return toRelayStatusResponse(raw);\n },\n\n async getRelayStatusBatch(\n relayIds: string[],\n ): Promise<RelayStatusResponse[]> {\n if (relayIds.length === 0) return [];\n\n const chunks = chunkArray(relayIds, RELAY_STATUS_BATCH_LIMIT);\n\n const results = await Promise.all(\n chunks.map(async (chunk) => {\n const raw = await http.request<{ relays: RelayStatusRaw[] }>({\n method: \"GET\",\n path: `/relays/batch?ids=${chunk.join(\",\")}`,\n });\n return raw.relays.map(toRelayStatusResponse);\n }),\n );\n return results.flat();\n },\n };\n}\n","import { Groth16Proof, PublicSignals } from \"snarkjs\";\nimport * as snarkjs from \"snarkjs\";\n\nimport { ProofError } from \"../errors.js\";\nimport {\n ArtifactType,\n assertValidArtifactVersion,\n buildR2ArtifactUrl,\n buildR2ChecksumsUrl,\n getLocalArtifactPath,\n requireRemoteArtifactSource,\n resolveArtifactSourceConfig,\n Runtime,\n type ArtifactSourceConfig,\n type RemoteArtifactSourceConfig,\n type ResolvedArtifactSourceConfig,\n} from \"./config.js\";\nimport {\n ArtifactIntegrityError,\n isArtifactIntegrityError,\n parseChecksumsManifest,\n verifyArtifactIntegrity,\n} from \"./integrity.js\";\nimport {\n getCircuitConfig,\n SUPPORTED_CIRCUITS,\n type CircuitConfig,\n} from \"./registry.js\";\n\ninterface LoadedArtifacts {\n readonly wasm: Uint8Array;\n readonly zkey: Uint8Array;\n readonly vkey: VerificationKey;\n}\n\n// Cache loaded artifacts to avoid reloading large files on repeated calls.\nconst MAX_ARTIFACT_CACHE_ENTRIES = 8;\nconst artifactCache = new Map<string, LoadedArtifacts>();\n\nexport interface ProverOptions {\n /**\n * Artifact source selection for R2 pathing and local-first mode.\n */\n readonly artifactSource?: ArtifactSourceConfig;\n}\n\nexport interface JoinsplitProof {\n readonly proof: Groth16Proof;\n readonly publicSignals: PublicSignals;\n}\n\nexport interface VerificationKey {\n readonly protocol: string;\n readonly curve: string;\n readonly nPublic: number;\n readonly vk_alpha_1: string[];\n readonly vk_beta_2: string[][];\n readonly vk_gamma_2: string[][];\n readonly vk_delta_2: string[][];\n readonly vk_alphabeta_12: string[][][];\n readonly IC: string[][];\n}\n\nexport interface JoinsplitProofInput {\n readonly merkleRoot: bigint;\n readonly boundParamsHash: bigint;\n readonly nullifiers: bigint[];\n readonly commitmentsOut: bigint[];\n readonly token: bigint;\n readonly publicKey: bigint[];\n readonly signature: bigint[];\n readonly randomIn: bigint[];\n readonly valueIn: bigint[];\n readonly pathElements: bigint[][];\n readonly leavesIndices: bigint[];\n readonly nullifyingKey: bigint;\n readonly npkOut: bigint[];\n readonly valueOut: bigint[];\n}\n\n/**\n * Select the appropriate circuit based on input/output dimensions\n * @param inputs Number of inputs (nullifiers)\n * @param outputs Number of outputs (commitments)\n * @returns Circuit configuration\n * @throws ProofError if no matching circuit is found\n */\nfunction selectCircuit(inputs: number, outputs: number): CircuitConfig {\n const config = getCircuitConfig(inputs, outputs);\n\n if (!config) {\n throw new ProofError(\n `No circuit available for ${inputs} inputs and ${outputs} outputs. ` +\n `Supported circuits: ${SUPPORTED_CIRCUITS.join(\", \")}`,\n );\n }\n\n return config;\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction toProofError(error: unknown): ProofError {\n if (error instanceof ProofError) {\n return error;\n }\n return new ProofError(getErrorMessage(error));\n}\n\nfunction resolveArtifactSource(\n options?: ProverOptions,\n): ResolvedArtifactSourceConfig {\n return resolveArtifactSourceConfig(options?.artifactSource);\n}\n\nfunction resolveNodeRemoteFallbackSource(\n source: ResolvedArtifactSourceConfig,\n): RemoteArtifactSourceConfig | null {\n if (source.version) {\n return requireRemoteArtifactSource(source);\n }\n\n const envVersionRaw =\n typeof process !== \"undefined\" ? process.env.UNLINK_ARTIFACT_VERSION : \"\";\n const envVersion = (envVersionRaw ?? \"\").trim().replace(/^\\/+|\\/+$/g, \"\");\n\n if (envVersion.length === 0) {\n return null;\n }\n try {\n assertValidArtifactVersion(envVersion, \"UNLINK_ARTIFACT_VERSION\");\n } catch (error) {\n throw new ProofError(getErrorMessage(error));\n }\n\n return {\n baseUrl: source.baseUrl,\n version: envVersion,\n };\n}\n\nfunction getNodeFallbackVersionCacheHint(): string {\n const envVersionRaw =\n typeof process !== \"undefined\" ? process.env.UNLINK_ARTIFACT_VERSION : \"\";\n const envVersion = (envVersionRaw ?? \"\").trim().replace(/^\\/+|\\/+$/g, \"\");\n return envVersion.length > 0 ? envVersion : \"no-env-version\";\n}\n\nfunction getArtifactCacheKey(\n circuitName: string,\n source: ResolvedArtifactSourceConfig,\n): string {\n const nodeFallbackVersion =\n Runtime.isNode() && source.preferLocalFiles && !source.version\n ? getNodeFallbackVersionCacheHint()\n : \"n/a\";\n\n return [\n Runtime.getEnvironment(),\n circuitName,\n source.baseUrl,\n source.version ?? \"no-version\",\n source.preferLocalFiles ? \"local-first\" : \"remote-first\",\n `node-fallback:${nodeFallbackVersion}`,\n ].join(\"|\");\n}\n\nfunction cacheArtifacts(\n cacheKey: string,\n artifacts: LoadedArtifacts,\n): LoadedArtifacts {\n if (artifactCache.has(cacheKey)) {\n artifactCache.delete(cacheKey);\n }\n artifactCache.set(cacheKey, artifacts);\n\n while (artifactCache.size > MAX_ARTIFACT_CACHE_ENTRIES) {\n const oldestKey = artifactCache.keys().next().value as string | undefined;\n if (!oldestKey) {\n break;\n }\n artifactCache.delete(oldestKey);\n }\n\n return artifacts;\n}\n\nfunction readCachedArtifacts(cacheKey: string): LoadedArtifacts | undefined {\n const cached = artifactCache.get(cacheKey);\n if (!cached) {\n return undefined;\n }\n\n // Refresh recency for LRU behavior.\n artifactCache.delete(cacheKey);\n artifactCache.set(cacheKey, cached);\n return cached;\n}\n\n/**\n * Fetch circuit artifacts from remote artifact host or local files.\n */\nasync function fetchCircuitArtifacts(\n circuitName: string,\n options?: ProverOptions,\n): Promise<LoadedArtifacts> {\n const source = resolveArtifactSource(options);\n const cacheKey = getArtifactCacheKey(circuitName, source);\n\n const cachedArtifacts = readCachedArtifacts(cacheKey);\n if (cachedArtifacts) {\n return cachedArtifacts;\n }\n\n if (Runtime.isBrowser()) {\n if (source.preferLocalFiles) {\n throw new ProofError(\n \"artifactSource.preferLocalFiles is only supported in Node.js\",\n );\n }\n\n const remoteArtifacts = await fetchFromRemoteSources(\n circuitName,\n requireRemoteArtifactSource(source),\n );\n return cacheArtifacts(cacheKey, remoteArtifacts);\n }\n\n if (Runtime.isNode()) {\n if (source.preferLocalFiles) {\n try {\n const localArtifacts = await fetchFromLocalFiles(circuitName);\n return cacheArtifacts(cacheKey, localArtifacts);\n } catch (localError) {\n const remoteSource = resolveNodeRemoteFallbackSource(source);\n if (!remoteSource) {\n throw new ProofError(\n `failed to load artifacts for ${circuitName}. ` +\n `Local error: ${getErrorMessage(localError)}. ` +\n \"Remote fallback disabled because no pinned artifact version is configured. \" +\n \"Set artifactSource.version or UNLINK_ARTIFACT_VERSION.\",\n );\n }\n try {\n const remoteArtifacts = await fetchFromRemoteSources(\n circuitName,\n remoteSource,\n );\n return cacheArtifacts(cacheKey, remoteArtifacts);\n } catch (remoteError) {\n throw new ProofError(\n `failed to load artifacts for ${circuitName}. ` +\n `Local error: ${getErrorMessage(localError)}. ` +\n `Remote error: ${getErrorMessage(remoteError)}`,\n );\n }\n }\n }\n\n const remoteSource = requireRemoteArtifactSource(source);\n try {\n const remoteArtifacts = await fetchFromRemoteSources(\n circuitName,\n remoteSource,\n );\n return cacheArtifacts(cacheKey, remoteArtifacts);\n } catch (remoteError) {\n // Remote-first mode never falls back to local files to avoid silent drift.\n if (\n remoteError instanceof ProofError ||\n isArtifactIntegrityError(remoteError)\n ) {\n throw remoteError;\n }\n throw new ProofError(\n `failed to load artifacts for ${circuitName}. ` +\n `Remote error: ${getErrorMessage(remoteError)}`,\n );\n }\n }\n\n throw new ProofError(`unsupported runtime: ${Runtime.getEnvironment()}`);\n}\n\nasync function fetchFromRemoteSources(\n circuitName: string,\n source: RemoteArtifactSourceConfig,\n): Promise<LoadedArtifacts> {\n try {\n return await fetchFromR2(circuitName, source);\n } catch (error) {\n if (error instanceof ProofError) {\n throw error;\n }\n throw new ProofError(\n `failed to fetch artifacts for ${circuitName} from ` +\n `${source.baseUrl}/${source.version}: ${getErrorMessage(error)}`,\n );\n }\n}\n\nasync function fetchFromR2(\n circuitName: string,\n source: RemoteArtifactSourceConfig,\n): Promise<LoadedArtifacts> {\n const checksumsUrl = buildR2ChecksumsUrl(circuitName, source);\n const checksumsRes = await fetch(checksumsUrl);\n\n if (!checksumsRes.ok) {\n throw new ProofError(\n `failed to fetch checksums manifest for ${circuitName} from ${checksumsUrl}. ` +\n `Status: ${checksumsRes.status}`,\n );\n }\n\n let checksumsJson: unknown;\n try {\n checksumsJson = await checksumsRes.json();\n } catch (error) {\n throw new ArtifactIntegrityError(\n `invalid checksums manifest JSON for ${circuitName}: ${getErrorMessage(error)}`,\n );\n }\n const checksums = parseChecksumsManifest(\n checksumsJson,\n circuitName,\n source.version,\n );\n\n const wasmUrl = buildR2ArtifactUrl(circuitName, ArtifactType.WASM, source);\n const zkeyUrl = buildR2ArtifactUrl(circuitName, ArtifactType.ZKEY, source);\n const vkeyUrl = buildR2ArtifactUrl(circuitName, ArtifactType.VKEY, source);\n\n const [wasmRes, zkeyRes, vkeyRes] = await Promise.all([\n fetch(wasmUrl),\n fetch(zkeyUrl),\n fetch(vkeyUrl),\n ]);\n\n if (!wasmRes.ok || !zkeyRes.ok || !vkeyRes.ok) {\n throw new ProofError(\n `failed to fetch artifacts for ${circuitName} from ${source.baseUrl}/${source.version}. ` +\n `Status: wasm=${wasmRes.status}, zkey=${zkeyRes.status}, vkey=${vkeyRes.status}`,\n );\n }\n\n const [wasm, zkey, vkeyBytes] = await Promise.all([\n wasmRes.arrayBuffer().then((buffer) => new Uint8Array(buffer)),\n zkeyRes.arrayBuffer().then((buffer) => new Uint8Array(buffer)),\n vkeyRes.arrayBuffer().then((buffer) => new Uint8Array(buffer)),\n ]);\n\n await Promise.all([\n verifyArtifactIntegrity(checksums, circuitName, ArtifactType.WASM, wasm),\n verifyArtifactIntegrity(checksums, circuitName, ArtifactType.ZKEY, zkey),\n verifyArtifactIntegrity(\n checksums,\n circuitName,\n ArtifactType.VKEY,\n vkeyBytes,\n ),\n ]);\n\n const vkeyText = new TextDecoder().decode(vkeyBytes);\n let vkey: VerificationKey;\n try {\n vkey = JSON.parse(vkeyText) as VerificationKey;\n } catch (error) {\n throw new ArtifactIntegrityError(\n `invalid verification key JSON for ${circuitName}: ${getErrorMessage(error)}`,\n );\n }\n\n return { wasm, zkey, vkey };\n}\n\nasync function fetchFromLocalFiles(\n circuitName: string,\n): Promise<LoadedArtifacts> {\n const wasmCandidates = getLocalArtifactPath(circuitName, ArtifactType.WASM);\n const zkeyCandidates = getLocalArtifactPath(circuitName, ArtifactType.ZKEY);\n const vkeyCandidates = getLocalArtifactPath(circuitName, ArtifactType.VKEY);\n\n let wasm: Uint8Array | undefined;\n let zkey: Uint8Array | undefined;\n let vkey: VerificationKey | undefined;\n\n let wasmLoaded = false;\n for (const candidate of wasmCandidates) {\n try {\n wasm = await readBinaryResource(candidate);\n wasmLoaded = true;\n break;\n } catch {\n // Try next candidate.\n }\n }\n\n if (!wasmLoaded) {\n throw new ProofError(\n `Could not find WASM artifact for ${circuitName}. ` +\n `Please run 'pnpm run build:all' in the circuits package.`,\n );\n }\n\n let zkeyLoaded = false;\n for (const candidate of zkeyCandidates) {\n try {\n zkey = await readBinaryResource(candidate);\n zkeyLoaded = true;\n break;\n } catch {\n // Try next candidate.\n }\n }\n\n if (!zkeyLoaded) {\n throw new ProofError(\n `Could not find zkey artifact for ${circuitName}. ` +\n `Please run 'pnpm run build:all' in the circuits package.`,\n );\n }\n\n let vkeyLoaded = false;\n for (const candidate of vkeyCandidates) {\n try {\n const vkeyText = await readTextResource(candidate);\n vkey = JSON.parse(vkeyText);\n vkeyLoaded = true;\n break;\n } catch {\n // Try next candidate.\n }\n }\n\n if (!vkeyLoaded) {\n throw new ProofError(\n `Could not find verification key for ${circuitName}. ` +\n `Please run 'pnpm run build:all' in the circuits package.`,\n );\n }\n\n return { wasm: wasm!, zkey: zkey!, vkey: vkey! };\n}\n\nasync function readBinaryResource(relativePath: string): Promise<Uint8Array> {\n const url = new URL(relativePath, import.meta.url);\n\n try {\n if (url.protocol === \"file:\") {\n const fs = (await import(\"fs\")).default;\n const readPromise: Promise<Buffer> = new Promise((resolve, reject) => {\n fs.readFile(url.pathname, (err, data) => {\n if (err) {\n reject(err);\n } else {\n resolve(data);\n }\n });\n });\n const buf = await readPromise;\n return new Uint8Array(buf);\n }\n const response = await fetch(url);\n if (!response.ok) {\n throw new ProofError(\n `failed to fetch ${relativePath}: ${response.statusText}`,\n );\n }\n return new Uint8Array(await response.arrayBuffer());\n } catch (error) {\n throw new ProofError(\n `failed to read binary resource ${relativePath}: ${\n (error as Error).message\n }`,\n );\n }\n}\n\nasync function readTextResource(relativePath: string): Promise<string> {\n const url = new URL(relativePath, import.meta.url);\n if (url.protocol === \"file:\") {\n const fs = (await import(\"fs\")).default;\n const readPromise: Promise<Buffer> = new Promise((resolve, reject) => {\n fs.readFile(url.pathname, (err, data) => {\n if (err) {\n reject(err);\n } else {\n resolve(data);\n }\n });\n });\n const buf = await readPromise;\n return buf.toString(\"utf-8\");\n }\n\n const response = await fetch(url);\n if (!response.ok) {\n throw new ProofError(\n `failed to fetch ${relativePath}: ${response.statusText}`,\n );\n }\n return response.text();\n}\n\nexport async function proveTransaction(\n input: JoinsplitProofInput,\n options?: ProverOptions,\n): Promise<JoinsplitProof> {\n try {\n const nInputs = input.nullifiers.length;\n const nOutputs = input.commitmentsOut.length;\n\n const circuit = selectCircuit(nInputs, nOutputs);\n\n const { wasm, vkey, zkey } = await fetchCircuitArtifacts(\n circuit.name,\n options,\n );\n\n const inputSignals = input as unknown as Record<\n string,\n bigint | bigint[] | string\n >;\n\n const { proof, publicSignals } = await snarkjs.groth16.fullProve(\n inputSignals,\n wasm,\n zkey,\n );\n\n const isValid = await snarkjs.groth16.verify(vkey, publicSignals, proof);\n if (!isValid) {\n throw new ProofError(\"generated proof is invalid\");\n }\n\n return {\n proof,\n publicSignals,\n };\n } catch (error) {\n throw new ProofError(\n \"proof generation failed: \" + toProofError(error).message,\n );\n }\n}\n\n/**\n * Get verification key for a specific circuit configuration.\n */\nexport async function getVerificationKey(\n inputs: number,\n outputs: number,\n options?: ProverOptions,\n): Promise<VerificationKey> {\n try {\n const circuit = selectCircuit(inputs, outputs);\n const { vkey } = await fetchCircuitArtifacts(circuit.name, options);\n return vkey;\n } catch (error) {\n throw new ProofError(\n \"failed to load verification key: \" + toProofError(error).message,\n );\n }\n}\n\n/**\n * Verify a proof with public signals.\n * Auto-detects the circuit from the public signals structure.\n */\nexport async function verifyProof(\n proof: Groth16Proof,\n publicSignals: PublicSignals,\n options?: ProverOptions,\n): Promise<boolean> {\n try {\n const totalLength = publicSignals.length;\n const variableCount = totalLength - 2;\n\n let vkey: VerificationKey | null = null;\n for (const circuitKey of SUPPORTED_CIRCUITS) {\n const parts = circuitKey.split(\"x\");\n const config = getCircuitConfig(parseInt(parts[0]!), parseInt(parts[1]!));\n if (config && config.inputs + config.outputs === variableCount) {\n const artifacts = await fetchCircuitArtifacts(config.name, options);\n vkey = artifacts.vkey;\n break;\n }\n }\n\n if (!vkey) {\n throw new ProofError(\n `Could not determine circuit from ${totalLength} public signals`,\n );\n }\n\n return await snarkjs.groth16.verify(vkey, publicSignals, proof);\n } catch (error) {\n throw new ProofError(\n \"proof verification failed: \" + toProofError(error).message,\n );\n }\n}\n\n/**\n * Verify a proof with explicit circuit specification.\n * Preferred method when you know the circuit dimensions.\n */\nexport async function verifyProofWithCircuit(\n proof: Groth16Proof,\n publicSignals: PublicSignals,\n inputs: number,\n outputs: number,\n options?: ProverOptions,\n): Promise<boolean> {\n try {\n const circuit = selectCircuit(inputs, outputs);\n const { vkey } = await fetchCircuitArtifacts(circuit.name, options);\n return await snarkjs.groth16.verify(vkey, publicSignals, proof);\n } catch (error) {\n throw new ProofError(\n \"proof verification failed: \" + toProofError(error).message,\n );\n }\n}\n","import { ProofError } from \"../errors.js\";\nimport { ArtifactType } from \"./config.js\";\n\nexport class ArtifactIntegrityError extends ProofError {\n constructor(message: string) {\n super(message);\n this.name = \"ArtifactIntegrityError\";\n }\n}\n\nexport function isArtifactIntegrityError(\n error: unknown,\n): error is ArtifactIntegrityError {\n return error instanceof ArtifactIntegrityError;\n}\n\ninterface ChecksumEntry {\n readonly sha256: string;\n readonly size: number;\n}\n\nexport interface ChecksumsManifest {\n readonly version: string;\n readonly circuit: string;\n readonly generated: string;\n readonly files: Record<string, ChecksumEntry>;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction parseChecksumEntry(value: unknown, fileName: string): ChecksumEntry {\n if (!isObject(value)) {\n throw new ArtifactIntegrityError(\n `checksums.json entry for ${fileName} must be an object`,\n );\n }\n\n const sha256 = value.sha256;\n if (typeof sha256 !== \"string\" || !/^[a-fA-F0-9]{64}$/.test(sha256)) {\n throw new ArtifactIntegrityError(\n `checksums.json entry for ${fileName} must include a valid sha256`,\n );\n }\n\n const size = value.size;\n if (typeof size !== \"number\" || !Number.isSafeInteger(size) || size < 0) {\n throw new ArtifactIntegrityError(\n `checksums.json entry for ${fileName} must include a valid size`,\n );\n }\n\n return {\n sha256: sha256.toLowerCase(),\n size,\n };\n}\n\nexport function parseChecksumsManifest(\n rawManifest: unknown,\n expectedCircuitName: string,\n expectedVersion: string,\n): ChecksumsManifest {\n if (!isObject(rawManifest)) {\n throw new ArtifactIntegrityError(\"checksums.json must be a JSON object\");\n }\n\n const version = rawManifest.version;\n if (typeof version !== \"string\" || version.length === 0) {\n throw new ArtifactIntegrityError(\"checksums.json is missing version\");\n }\n if (version !== expectedVersion) {\n throw new ArtifactIntegrityError(\n `checksums.json version mismatch: expected ${expectedVersion}, got ${version}`,\n );\n }\n\n const circuit = rawManifest.circuit;\n if (typeof circuit !== \"string\" || circuit.length === 0) {\n throw new ArtifactIntegrityError(\"checksums.json is missing circuit\");\n }\n\n if (circuit !== expectedCircuitName) {\n throw new ArtifactIntegrityError(\n `checksums.json circuit mismatch: expected ${expectedCircuitName}, got ${circuit}`,\n );\n }\n\n const generated = rawManifest.generated;\n if (typeof generated !== \"string\" || generated.length === 0) {\n throw new ArtifactIntegrityError(\n \"checksums.json is missing generated timestamp\",\n );\n }\n\n const filesRaw = rawManifest.files;\n if (!isObject(filesRaw)) {\n throw new ArtifactIntegrityError(\"checksums.json is missing files map\");\n }\n\n const files: Record<string, ChecksumEntry> = {};\n for (const [name, entry] of Object.entries(filesRaw)) {\n files[name] = parseChecksumEntry(entry, name);\n }\n\n return {\n version,\n circuit,\n generated,\n files,\n };\n}\n\nfunction toHex(bytes: Uint8Array): string {\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\n \"\",\n );\n}\n\nasync function sha256Hex(data: Uint8Array): Promise<string> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new ArtifactIntegrityError(\"SHA-256 is unavailable in this runtime\");\n }\n\n // Force an ArrayBuffer-backed view to satisfy WebCrypto BufferSource typing.\n const digestInput = Uint8Array.from(data);\n const digest = await subtle.digest(\"SHA-256\", digestInput);\n return toHex(new Uint8Array(digest));\n}\n\nexport async function verifyArtifactIntegrity(\n manifest: ChecksumsManifest,\n circuitName: string,\n artifactType: ArtifactType,\n content: Uint8Array,\n): Promise<void> {\n const entry = manifest.files[artifactType];\n if (!entry) {\n throw new ArtifactIntegrityError(\n `checksums.json for ${circuitName} is missing ${artifactType}`,\n );\n }\n\n if (content.byteLength !== entry.size) {\n throw new ArtifactIntegrityError(\n `artifact size mismatch for ${circuitName}/${artifactType}: expected ${entry.size}, got ${content.byteLength}`,\n );\n }\n\n const digest = await sha256Hex(content);\n if (digest !== entry.sha256) {\n throw new ArtifactIntegrityError(\n `artifact hash mismatch for ${circuitName}/${artifactType}: expected ${entry.sha256}, got ${digest}`,\n );\n }\n}\n","{\n \"joinsplit_1x1_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [1, 1, 16]\n },\n \"joinsplit_1x2_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [1, 2, 16]\n },\n \"joinsplit_2x1_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [2, 1, 16]\n },\n \"joinsplit_2x2_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [2, 2, 16]\n },\n \"joinsplit_2x3_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [2, 3, 16]\n },\n \"joinsplit_3x1_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [3, 1, 16]\n },\n \"joinsplit_3x2_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [3, 2, 16]\n },\n \"joinsplit_3x3_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [3, 3, 16]\n },\n \"joinsplit_4x1_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [4, 1, 16]\n },\n \"joinsplit_4x2_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [4, 2, 16]\n },\n \"joinsplit_5x1_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [5, 1, 16]\n },\n \"joinsplit_5x2_16\": {\n \"file\": \"joinsplit\",\n \"template\": \"JoinSplit\",\n \"pubs\": [\"merkleRoot\", \"boundParamsHash\", \"nullifiers\", \"commitmentsOut\"],\n \"params\": [5, 2, 16]\n }\n}\n","import circuitsJson from \"../circuits.json\" with { type: \"json\" };\n\nexport interface CircuitConfig {\n readonly name: string;\n readonly inputs: number;\n readonly outputs: number;\n readonly depth: number;\n}\n\n// Build registry from circuits.json — keyed by \"NxM\" (inputs x outputs)\nconst registry: Record<string, CircuitConfig> = {};\nfor (const [name, def] of Object.entries(circuitsJson)) {\n const params = (def as { params: number[] }).params;\n const inputs = params[0]!;\n const outputs = params[1]!;\n const depth = params[2]!;\n registry[`${inputs}x${outputs}`] = { name, inputs, outputs, depth };\n}\n\nexport const CIRCUIT_REGISTRY = registry as Record<string, CircuitConfig>;\n\nexport type CircuitKey = keyof typeof CIRCUIT_REGISTRY & string;\n\nexport const SUPPORTED_CIRCUITS = Object.keys(CIRCUIT_REGISTRY);\n\nexport function getCircuitConfig(\n inputs: number,\n outputs: number,\n): CircuitConfig | undefined {\n return CIRCUIT_REGISTRY[`${inputs}x${outputs}`];\n}\n\nexport function isCircuitSupported(inputs: number, outputs: number): boolean {\n return getCircuitConfig(inputs, outputs) !== undefined;\n}\n","import { Interface } from \"ethers\";\n\nimport { AdapterError } from \"../errors.js\";\nimport { ensureAddress } from \"../utils/validators.js\";\nimport type {\n AdapterExecutionCall,\n AdapterExecutionReshield,\n} from \"./transact.js\";\n\nexport type {\n AdapterExecutionCall,\n AdapterExecutionReshield,\n} from \"./transact.js\";\n\nexport const ADAPTER_EXECUTE_ABI = [\n \"function execute(bytes _transactData, (address to, bytes data, uint256 value)[] _calls, (uint256 npk, uint256 random, address token, uint256 minAmount)[] _reshields, address[] _inputTokens, uint256 _nonce, uint256 _deadline)\",\n] as const;\n\nconst adapterInterface = new Interface(ADAPTER_EXECUTE_ABI);\nconst approveInterface = new Interface([\n \"function approve(address spender, uint256 amount)\",\n]);\nconst HEX_DATA_REGEX = /^0x[0-9a-fA-F]*$/;\n\nexport type BuildCallParams = {\n to: string;\n abi: string;\n functionName: string;\n args: unknown[];\n value?: bigint;\n};\n\nexport type EncodeAdapterExecuteParams = {\n transactCalldata: string;\n calls: AdapterExecutionCall[];\n reshields: AdapterExecutionReshield[];\n inputTokens: string[];\n nonce: bigint;\n deadline: bigint;\n};\n\nfunction ensureNonNegative(label: string, value: bigint): bigint {\n if (value < 0n) {\n throw new AdapterError(`${label} must be non-negative`);\n }\n return value;\n}\n\nfunction ensureHexData(label: string, value: string): string {\n if (\n typeof value !== \"string\" ||\n !HEX_DATA_REGEX.test(value) ||\n value.length % 2 !== 0\n ) {\n throw new AdapterError(`${label} must be 0x-prefixed even-length hex data`);\n }\n return value;\n}\n\nfunction normalizeCall(\n call: AdapterExecutionCall,\n index: number,\n): AdapterExecutionCall {\n const to = ensureAddress(`calls[${index}].to`, call.to);\n const data = ensureHexData(`calls[${index}].data`, call.data);\n const value = ensureNonNegative(`calls[${index}].value`, call.value);\n return { to, data, value };\n}\n\nfunction normalizeReshield(\n reshield: AdapterExecutionReshield,\n index: number,\n): AdapterExecutionReshield {\n const token = ensureAddress(`reshields[${index}].token`, reshield.token);\n const npk = ensureNonNegative(`reshields[${index}].npk`, reshield.npk);\n const random = ensureNonNegative(\n `reshields[${index}].random`,\n reshield.random,\n );\n const minAmount = ensureNonNegative(\n `reshields[${index}].minAmount`,\n reshield.minAmount,\n );\n\n return { npk, random, token, minAmount };\n}\n\n/**\n * Build a single adapter call from ABI metadata.\n */\nexport function buildCall(params: BuildCallParams): AdapterExecutionCall {\n const to = ensureAddress(\"call.to\", params.to);\n if (typeof params.abi !== \"string\" || params.abi.trim().length === 0) {\n throw new AdapterError(\"call.abi must be a non-empty ABI fragment string\");\n }\n if (\n typeof params.functionName !== \"string\" ||\n params.functionName.trim().length === 0\n ) {\n throw new AdapterError(\"call.functionName must be a non-empty string\");\n }\n if (!Array.isArray(params.args)) {\n throw new AdapterError(\"call.args must be an array\");\n }\n\n const value = ensureNonNegative(\"call.value\", params.value ?? 0n);\n\n let iface: Interface;\n try {\n iface = new Interface([params.abi]);\n } catch (err) {\n throw new AdapterError(\n `invalid ABI fragment for call: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n let data: string;\n try {\n data = iface.encodeFunctionData(params.functionName, params.args);\n } catch (err) {\n throw new AdapterError(\n `failed to encode ${params.functionName}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n return { to, data, value };\n}\n\n/**\n * Build a standard ERC-20 approve call for adapter execution.\n */\nexport function buildApproveCall(\n token: string,\n spender: string,\n amount: bigint,\n): AdapterExecutionCall {\n const normalizedToken = ensureAddress(\"token\", token);\n const normalizedSpender = ensureAddress(\"spender\", spender);\n const normalizedAmount = ensureNonNegative(\"amount\", amount);\n\n const data = approveInterface.encodeFunctionData(\"approve\", [\n normalizedSpender,\n normalizedAmount,\n ]);\n\n return {\n to: normalizedToken,\n data,\n value: 0n,\n };\n}\n\n/**\n * Encode `UnlinkAdapter.execute(...)` calldata.\n */\nexport function encodeAdapterExecute(\n params: EncodeAdapterExecuteParams,\n): string {\n const transactCalldata = ensureHexData(\n \"transactCalldata\",\n params.transactCalldata,\n );\n const calls = params.calls.map((call, i) => normalizeCall(call, i));\n const reshields = params.reshields.map((reshield, i) =>\n normalizeReshield(reshield, i),\n );\n const inputTokens = params.inputTokens.map((token, i) =>\n ensureAddress(`inputTokens[${i}]`, token),\n );\n const nonce = ensureNonNegative(\"nonce\", params.nonce);\n const deadline = ensureNonNegative(\"deadline\", params.deadline);\n\n return adapterInterface.encodeFunctionData(\"execute\", [\n transactCalldata,\n calls,\n reshields,\n inputTokens,\n nonce,\n deadline,\n ]);\n}\n","import { ValidationError } from \"../errors.js\";\nimport { CIRCUIT_REGISTRY } from \"../prover/registry.js\";\nimport type {\n SelectableNote,\n SelectionOptions,\n SelectionResult,\n} from \"./types/index.js\";\n\n/** Maximum inputs supported by available circuits */\nconst MAX_CIRCUIT_INPUTS = Math.max(\n ...Object.values(CIRCUIT_REGISTRY).map((c) => c.inputs),\n);\n\n/** Maximum outputs supported by available circuits */\nconst MAX_CIRCUIT_OUTPUTS = Math.max(\n ...Object.values(CIRCUIT_REGISTRY).map((c) => c.outputs),\n);\n\n/**\n * Get the value of a note as bigint.\n * Handles both bigint and string values for NoteRecord compatibility.\n */\nfunction getNoteValue<T>(note: SelectableNote<T>): bigint {\n return typeof note.value === \"bigint\" ? note.value : BigInt(note.value);\n}\n\ntype Solution<T> = {\n notes: SelectableNote<T>[];\n sum: bigint;\n};\n\n/**\n * Select notes for a transaction with consolidation-first strategy.\n *\n * Priorities:\n * 1. Consolidation - prefer spending more small notes\n * 2. Minimize change - find combinations with less overshoot\n * 3. Respect maxInputs constraint\n *\n * @param notes - Available unspent notes (caller filters by token)\n * @param totalNeeded - Total amount needed for all recipients\n * @param options - Selection options\n * @returns Selection result with notes and amounts\n * @throws ValidationError if insufficient balance or constraints can't be met\n */\nexport function selectNotesForAmount<T>(\n notes: SelectableNote<T>[],\n totalNeeded: bigint,\n options?: SelectionOptions,\n): SelectionResult<T> {\n const maxInputs = options?.maxInputs ?? MAX_CIRCUIT_INPUTS;\n const maxOutputs = options?.maxOutputs ?? MAX_CIRCUIT_OUTPUTS;\n const recipientCount = options?.recipientCount ?? 1;\n\n // Validate inputs\n if (totalNeeded <= 0n) {\n throw new ValidationError(\"Amount must be positive\");\n }\n if (!notes.length) {\n throw new ValidationError(\"No notes available\");\n }\n // Validate output constraints: recipients + potential change <= maxOutputs\n // Change is needed when selected sum > totalNeeded (almost always)\n // So we conservatively assume change will be needed\n if (recipientCount + 1 > maxOutputs) {\n throw new ValidationError(\n `Too many recipients: ${recipientCount} recipients + change exceeds maxOutputs (${maxOutputs})`,\n );\n }\n\n // Check total balance\n const totalAvailable = notes.reduce((sum, n) => sum + getNoteValue(n), 0n);\n if (totalAvailable < totalNeeded) {\n throw new ValidationError(\"Insufficient balance\");\n }\n\n // Sort ascending for consolidation preference (smallest first)\n const sortedAsc = [...notes].sort((a, b) => {\n const aVal = getNoteValue(a);\n const bVal = getNoteValue(b);\n return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;\n });\n\n // Phase 1: Try greedy smallest-first\n let baseline = greedySelect(sortedAsc, totalNeeded, maxInputs);\n\n // Phase 2: If greedy smallest-first didn't work, try largest-first as fallback\n if (baseline.sum < totalNeeded) {\n const sortedDesc = [...sortedAsc].reverse();\n baseline = greedySelect(sortedDesc, totalNeeded, maxInputs);\n }\n\n // Phase 3: If we have a valid baseline, use branch-and-bound to optimize\n // Only run B&B on a subset of notes to keep it fast\n let optimized: Solution<T>;\n if (baseline.sum >= totalNeeded) {\n // Limit B&B to reasonable subset for performance (30 smallest notes)\n const maxNotesForBnB = Math.min(sortedAsc.length, 30);\n const notesForBnB = sortedAsc.slice(0, maxNotesForBnB);\n optimized = findOptimalSelection(\n notesForBnB,\n totalNeeded,\n maxInputs,\n baseline,\n );\n } else {\n optimized = baseline;\n }\n\n // If no valid solution found\n if (optimized.sum < totalNeeded) {\n throw new ValidationError(\"Cannot meet amount within maxInputs constraint\");\n }\n\n return {\n selected: optimized.notes,\n totalInput: optimized.sum,\n totalNeeded,\n change: optimized.sum - totalNeeded,\n };\n}\n\n/**\n * Greedy selection: accumulate notes until threshold met.\n * Returns a partial solution if it can't meet the target.\n */\nfunction greedySelect<T>(\n sorted: SelectableNote<T>[],\n target: bigint,\n maxInputs: number,\n): Solution<T> {\n const selected: SelectableNote<T>[] = [];\n let sum = 0n;\n\n for (const note of sorted) {\n if (sum >= target) break;\n if (selected.length >= maxInputs) break;\n selected.push(note);\n sum += getNoteValue(note);\n }\n\n return { notes: selected, sum };\n}\n\n/**\n * Compare two solutions.\n * Returns true if (candidate) is better than (best).\n *\n * Priority 0: Prefer valid solutions (sum >= target)\n * Priority 1: Prefer more notes (consolidation)\n * Priority 2: Prefer less change\n */\nfunction isBetterSolution<T>(\n candidate: Solution<T>,\n best: Solution<T>,\n target: bigint,\n): boolean {\n const candidateValid = candidate.sum >= target;\n const bestValid = best.sum >= target;\n\n // Priority 0: Prefer valid solutions\n if (candidateValid && !bestValid) return true;\n if (!candidateValid && bestValid) return false;\n if (!candidateValid && !bestValid) {\n // Neither valid - prefer higher sum (closer to target)\n return candidate.sum > best.sum;\n }\n\n // Both valid - apply consolidation + change minimization\n const candidateChange = candidate.sum - target;\n const bestChange = best.sum - target;\n\n // Priority 1: Prefer more notes (consolidation)\n if (candidate.notes.length > best.notes.length) return true;\n if (candidate.notes.length < best.notes.length) return false;\n\n // Priority 2: Prefer less change\n return candidateChange < bestChange;\n}\n\n/**\n * Branch-and-bound search for optimal selection.\n *\n * Explores the solution space with aggressive pruning:\n * - Stop when sum >= target (don't over-select beyond what's needed)\n * - Stop when remaining notes can't reach target\n * - Stop when maxInputs exceeded\n * - Early termination when we find a solution with maxInputs notes and exact match\n */\nfunction findOptimalSelection<T>(\n sorted: SelectableNote<T>[],\n target: bigint,\n maxInputs: number,\n baseline: Solution<T>,\n): Solution<T> {\n let best = baseline;\n let foundOptimal = false;\n\n // Precompute remaining sums for pruning\n const remainingSums: bigint[] = new Array<bigint>(sorted.length + 1).fill(0n);\n for (let i = sorted.length - 1; i >= 0; i--) {\n const nextSum = remainingSums[i + 1] ?? 0n;\n const note = sorted[i];\n const noteValue = note ? getNoteValue(note) : 0n;\n remainingSums[i] = nextSum + noteValue;\n }\n\n function search(\n index: number,\n selected: SelectableNote<T>[],\n sum: bigint,\n ): void {\n // Early exit if we found optimal solution\n if (foundOptimal) return;\n\n // Pruning: too many notes selected\n if (selected.length > maxInputs) return;\n\n // Found valid solution, now comparing with best\n if (sum >= target) {\n const candidate = { notes: selected, sum };\n if (isBetterSolution(candidate, best, target)) {\n best = { notes: [...selected], sum };\n // Check if this is optimal (maxInputs notes with exact match)\n if (selected.length === maxInputs && sum === target) {\n foundOptimal = true;\n }\n }\n // Don't add more notes once target is met\n return;\n }\n\n // Pruning: can't reach target with remaining notes\n const remaining = remainingSums[index] ?? 0n;\n if (sum + remaining < target) return;\n\n // Pruning: reached end of notes\n if (index >= sorted.length) return;\n\n // Pruning: can't possibly beat best's note count\n const remainingSlots = maxInputs - selected.length;\n const remainingNotes = sorted.length - index;\n if (\n selected.length + Math.min(remainingSlots, remainingNotes) <\n best.notes.length\n ) {\n // Even selecting all remaining notes won't beat best's count\n // Only skip if best is already valid\n if (best.sum >= target) return;\n }\n\n const currentNote = sorted[index];\n if (!currentNote) return;\n\n // Try including current note (explore this branch first for consolidation)\n search(\n index + 1,\n [...selected, currentNote],\n sum + getNoteValue(currentNote),\n );\n\n // Try excluding current note\n search(index + 1, selected, sum);\n }\n\n search(0, [], 0n);\n\n return best;\n}\n","import { poseidon } from \"../crypto/adapters/index.js\";\nimport { ProofError, ValidationError } from \"../errors.js\";\nimport { CIRCUIT_REGISTRY, type CircuitConfig } from \"../prover/registry.js\";\nimport { randomBigint } from \"../utils/random.js\";\nimport { selectNotesForAmount } from \"./note-selection.js\";\nimport type {\n NoteInput,\n PlannedOutput,\n Recipient,\n SelectableNote,\n TransactionPlan,\n} from \"./types/index.js\";\n\n/**\n * Select the smallest circuit that fits the given input/output counts.\n */\nfunction selectCircuitForTransaction(\n inputCount: number,\n outputCount: number,\n): CircuitConfig {\n // Sort circuits by total size (inputs + outputs) ascending\n const circuits = Object.values(CIRCUIT_REGISTRY).sort(\n (a, b) => a.inputs + a.outputs - (b.inputs + b.outputs),\n );\n\n const circuit = circuits.find(\n (c) => c.inputs >= inputCount && c.outputs >= outputCount,\n );\n\n if (!circuit) {\n throw new ProofError(\n `No circuit supports ${inputCount} inputs and ${outputCount} outputs. ` +\n `Available: ${circuits.map((c) => `${c.inputs}x${c.outputs}`).join(\", \")}`,\n );\n }\n\n return circuit;\n}\n\n/**\n * Generate a planned output note with derived npk and commitment.\n */\nfunction generateOutput(\n mpk: bigint,\n amount: bigint,\n token: string,\n owner: \"recipient\" | \"self\",\n viewingPublicKey: Uint8Array,\n): PlannedOutput {\n const random = randomBigint();\n const npk = poseidon([mpk, random]);\n const tokenScalar = BigInt(token);\n const commitment = poseidon([npk, tokenScalar, amount]);\n\n return {\n mpk,\n random,\n token,\n amount,\n owner,\n viewingPublicKey,\n npk,\n commitment,\n };\n}\n\n/**\n * Plan a transaction: select notes, choose circuit, generate outputs.\n *\n * This function handles:\n * 1. Note selection using consolidation-first algorithm\n * 2. Circuit selection (smallest that fits)\n * 3. Output generation with cryptographic derivations\n *\n * @param notes - Available unspent notes (pre-filtered by token/chain by caller)\n * @param recipients - List of recipients with their amounts\n * @param senderMpk - Sender's master public key (for change output)\n * @param token - Token address being transferred\n * @returns Complete transaction plan ready for building TransactRequest\n * @throws ValidationError if insufficient balance, no valid circuit, or other constraints fail\n *\n * @example\n * ```typescript\n * const plan = planTransaction(\n * spendableNotes,\n * [{ mpk: recipientMpk, amount: 100n }],\n * senderMpk,\n * \"0x...\",\n * );\n * // plan.inputs - selected notes to spend\n * // plan.outputs - generated outputs (recipient + change)\n * // plan.circuit - circuit to use for proof\n * ```\n */\nexport function planTransaction<\n T extends { index: number; value: bigint | string },\n>(\n notes: SelectableNote<T>[],\n recipients: Recipient[],\n senderMpk: bigint,\n token: string,\n senderViewingPubKey: Uint8Array,\n): TransactionPlan<T> {\n // Validate inputs\n if (!recipients.length) {\n throw new ValidationError(\"At least one recipient is required\");\n }\n\n // Validate each recipient has a positive amount\n for (let i = 0; i < recipients.length; i++) {\n const recipient = recipients[i];\n if (recipient && recipient.amount <= 0n) {\n throw new ValidationError(\n `Recipient at index ${i} has invalid amount: ${recipient.amount}. All recipients must have amount > 0`,\n );\n }\n }\n\n const totalSent = recipients.reduce((sum, r) => sum + r.amount, 0n);\n\n // Select notes using consolidation-first algorithm\n // Note: maxInputs/maxOutputs defaults are derived from CIRCUIT_REGISTRY in selectNotesForAmount\n const selection = selectNotesForAmount(notes, totalSent, {\n recipientCount: recipients.length,\n });\n\n const { selected: inputs, totalInput, change } = selection;\n\n // Determine output count: 1 per recipient + 1 for change (if any)\n const outputCount = recipients.length + (change > 0n ? 1 : 0);\n\n // Select smallest fitting circuit\n const circuit = selectCircuitForTransaction(inputs.length, outputCount);\n\n // Generate outputs\n const outputs: PlannedOutput[] = [];\n\n // Recipient outputs\n for (const recipient of recipients) {\n outputs.push(\n generateOutput(\n recipient.mpk,\n recipient.amount,\n token,\n \"recipient\",\n recipient.viewingPublicKey,\n ),\n );\n }\n\n // Change output (if any)\n if (change > 0n) {\n outputs.push(\n generateOutput(senderMpk, change, token, \"self\", senderViewingPubKey),\n );\n }\n\n // Create outputNotes for TransactParams (without derived fields, but with owner metadata)\n const outputNotes: NoteInput[] = outputs.map((o) => ({\n mpk: o.mpk,\n random: o.random,\n token: o.token,\n amount: o.amount,\n owner: o.owner,\n viewingPublicKey: o.viewingPublicKey,\n }));\n\n return {\n inputs,\n outputs,\n outputNotes,\n circuit,\n totalInput,\n totalSent,\n change,\n token,\n };\n}\n","import { ProofError, ValidationError } from \"../errors.js\";\nimport { CIRCUIT_REGISTRY, type CircuitConfig } from \"../prover/registry.js\";\nimport { randomBigint } from \"../utils/random.js\";\nimport { selectNotesForAmount } from \"./note-selection.js\";\nimport type {\n NoteInput,\n SelectableNote,\n WithdrawalNoteInput,\n} from \"./types/index.js\";\n\n/**\n * Result of planning a withdrawal transaction.\n */\nexport type WithdrawalPlan<T> = {\n /** Selected input notes to spend */\n inputs: SelectableNote<T>[];\n /** Output notes (change only, if any) */\n outputNotes: NoteInput[];\n /** Withdrawal specification */\n withdrawal: WithdrawalNoteInput;\n /** Selected circuit configuration */\n circuit: CircuitConfig;\n /** Total input amount from selected notes */\n totalInput: bigint;\n /** Amount being withdrawn */\n withdrawAmount: bigint;\n /** Change amount returned to sender */\n change: bigint;\n /** Token address */\n token: string;\n};\n\n/**\n * Input for a single withdrawal in a batch.\n */\nexport type WithdrawalInput = {\n token: string;\n amount: bigint;\n recipient: string;\n};\n\n/**\n * Select the smallest circuit that fits the given input/output counts.\n * For withdrawals, outputs = change only (0 or 1).\n */\nfunction selectCircuitForWithdrawal(\n inputCount: number,\n outputCount: number,\n): CircuitConfig {\n // Sort circuits by total size (inputs + outputs) ascending\n const circuits = Object.values(CIRCUIT_REGISTRY).sort(\n (a, b) => a.inputs + a.outputs - (b.inputs + b.outputs),\n );\n\n const circuit = circuits.find(\n (c) => c.inputs >= inputCount && c.outputs >= outputCount,\n );\n\n if (!circuit) {\n throw new ProofError(\n `No circuit supports ${inputCount} inputs and ${outputCount} outputs. ` +\n `Available: ${circuits.map((c) => `${c.inputs}x${c.outputs}`).join(\", \")}`,\n );\n }\n\n return circuit;\n}\n\n/**\n * Plan a single withdrawal transaction. Used internally by `planWithdrawals`.\n */\nfunction planSingleWithdrawal<\n T extends { index: number; value: bigint | string },\n>(\n notes: SelectableNote<T>[],\n withdrawAmount: bigint,\n recipientAddress: string,\n senderMpk: bigint,\n token: string,\n senderViewingPubKey: Uint8Array,\n): WithdrawalPlan<T> {\n if (withdrawAmount <= 0n) {\n throw new ValidationError(\"Withdrawal amount must be positive\");\n }\n\n const selection = selectNotesForAmount(notes, withdrawAmount, {\n recipientCount: 0,\n });\n\n const { selected: inputs, totalInput, change } = selection;\n const changeOutputCount = change > 0n ? 1 : 0;\n const outputCount = changeOutputCount + 1;\n const circuit = selectCircuitForWithdrawal(inputs.length, outputCount);\n\n const outputNotes: NoteInput[] = [];\n if (change > 0n) {\n const random = randomBigint();\n outputNotes.push({\n mpk: senderMpk,\n random,\n token,\n amount: change,\n viewingPublicKey: senderViewingPubKey,\n });\n }\n\n const withdrawal: WithdrawalNoteInput = {\n npk: BigInt(recipientAddress),\n amount: withdrawAmount,\n token,\n };\n\n return {\n inputs,\n outputNotes,\n withdrawal,\n circuit,\n totalInput,\n withdrawAmount,\n change,\n token,\n };\n}\n\n/**\n * Plan withdrawal transaction(s).\n * Accepts 1 or more withdrawals. When multiple withdrawals use the same token,\n * notes are tracked across withdrawals to avoid double-spending.\n *\n * @param notes - Available unspent notes (all tokens)\n * @param withdrawals - Withdrawals to plan (each with token, amount, recipient)\n * @param senderMpk - Sender's master public key (for change outputs)\n * @returns Array of withdrawal plans, one per withdrawal input\n *\n * @example\n * ```typescript\n * // Single withdrawal\n * const [plan] = planWithdrawals(notes, [{ token, amount: 100n, recipient: \"0x...\" }], mpk);\n *\n * // Multiple withdrawals (possibly same token)\n * const plans = planWithdrawals(notes, [\n * { token: ETH, amount: 100n, recipient: \"0x...\" },\n * { token: USDC, amount: 50n, recipient: \"0x...\" },\n * ], mpk);\n * ```\n */\nexport function planWithdrawals<\n T extends { index: number; value: bigint | string },\n>(\n notes: SelectableNote<T>[],\n withdrawals: WithdrawalInput[],\n senderMpk: bigint,\n senderViewingPubKey: Uint8Array,\n): WithdrawalPlan<T>[] {\n if (!withdrawals.length) {\n throw new ValidationError(\"At least one withdrawal is required\");\n }\n\n // Validate all withdrawals upfront\n for (const w of withdrawals) {\n if (w.amount <= 0n) {\n throw new ValidationError(\n `Invalid withdrawal amount for ${w.token}: ${w.amount}`,\n );\n }\n }\n\n // Pre-validate total balances per token (use normalized tokens for comparison)\n const requiredByToken = new Map<string, bigint>();\n for (const w of withdrawals) {\n const tokenLower = w.token.toLowerCase();\n const existing = requiredByToken.get(tokenLower) ?? 0n;\n requiredByToken.set(tokenLower, existing + w.amount);\n }\n\n for (const [tokenLower, required] of requiredByToken) {\n const available = notes\n .filter(\n (n) =>\n (n as unknown as { token: string }).token.toLowerCase() ===\n tokenLower,\n )\n .reduce((sum, n) => sum + BigInt(n.value), 0n);\n if (available < required) {\n throw new ValidationError(\n `Insufficient balance for ${tokenLower}: need ${required}, have ${available}`,\n );\n }\n }\n\n // Track used note indices per token to avoid double-spending\n const usedNotesByToken = new Map<string, Set<number>>();\n\n const plans: WithdrawalPlan<T>[] = [];\n\n for (const w of withdrawals) {\n const tokenLower = w.token.toLowerCase();\n\n // Get available notes for this token, excluding already-used ones\n const usedIndices = usedNotesByToken.get(tokenLower) ?? new Set();\n const availableNotes = notes.filter(\n (n) =>\n (n as unknown as { token: string }).token.toLowerCase() ===\n tokenLower && !usedIndices.has(n.index),\n );\n\n // Plan this withdrawal (pass original token for output)\n const plan = planSingleWithdrawal(\n availableNotes,\n w.amount,\n w.recipient,\n senderMpk,\n w.token,\n senderViewingPubKey,\n );\n\n // Mark selected notes as used\n if (!usedNotesByToken.has(tokenLower)) {\n usedNotesByToken.set(tokenLower, new Set());\n }\n for (const input of plan.inputs) {\n usedNotesByToken.get(tokenLower)!.add(input.index);\n }\n\n plans.push(plan);\n }\n\n return plans;\n}\n","import { ValidationError } from \"../errors.js\";\nimport { planTransaction } from \"./transaction-planner.js\";\nimport type { SelectableNote, TransactionPlan } from \"./types/index.js\";\n\n/**\n * Input for a single transfer in a batch.\n */\nexport type TransferInput = {\n token: string;\n amount: bigint;\n recipientMpk: bigint;\n recipientViewingPubKey: Uint8Array;\n};\n\n/**\n * Plan transfer transaction(s).\n * Accepts 1 or more transfers. When multiple transfers use the same token,\n * notes are tracked across transfers to avoid double-spending.\n *\n * @param notes - Available unspent notes (all tokens)\n * @param transfers - Transfers to plan (each with token, amount, recipientMpk)\n * @param senderMpk - Sender's master public key (for change outputs)\n * @returns Array of transaction plans, one per transfer input\n *\n * @example\n * ```typescript\n * // Single transfer\n * const [plan] = planTransfers(notes, [{ token, amount: 100n, recipientMpk }], senderMpk);\n *\n * // Multiple transfers (possibly same token)\n * const plans = planTransfers(notes, [\n * { token: ETH, amount: 100n, recipientMpk: recipient1Mpk },\n * { token: USDC, amount: 50n, recipientMpk: recipient2Mpk },\n * ], senderMpk);\n * ```\n */\nexport function planTransfers<\n T extends { index: number; value: bigint | string },\n>(\n notes: SelectableNote<T>[],\n transfers: TransferInput[],\n senderMpk: bigint,\n senderViewingPubKey: Uint8Array,\n): TransactionPlan<T>[] {\n if (!transfers.length) {\n throw new ValidationError(\"At least one transfer is required\");\n }\n\n // Validate all transfers upfront\n for (const t of transfers) {\n if (!t.token) {\n throw new ValidationError(\n `Missing token address in transfer: ${JSON.stringify(t)}`,\n );\n }\n // Convert amount to bigint if needed (handles string amounts from frontend)\n const amount =\n typeof t.amount === \"bigint\" ? t.amount : BigInt(t.amount as string);\n if (amount <= 0n) {\n throw new ValidationError(\n `Invalid transfer amount for ${t.token}: ${t.amount}`,\n );\n }\n // Update amount to bigint for downstream use\n (t as { amount: bigint }).amount = amount;\n }\n\n // Pre-validate total balances per token (use normalized tokens for comparison)\n const requiredByToken = new Map<string, bigint>();\n for (const t of transfers) {\n const tokenLower = t.token.toLowerCase();\n const existing = requiredByToken.get(tokenLower) ?? 0n;\n requiredByToken.set(tokenLower, existing + t.amount);\n }\n\n for (const [tokenLower, required] of requiredByToken) {\n const available = notes\n .filter((n) => {\n const noteToken = (n as unknown as { token?: string }).token;\n return noteToken && noteToken.toLowerCase() === tokenLower;\n })\n .reduce((sum, n) => sum + BigInt(n.value), 0n);\n if (available < required) {\n throw new ValidationError(\n `Insufficient balance for ${tokenLower}: need ${required}, have ${available}`,\n );\n }\n }\n\n // Track used note indices per token to avoid double-spending\n const usedNotesByToken = new Map<string, Set<number>>();\n\n const plans: TransactionPlan<T>[] = [];\n\n for (const t of transfers) {\n const tokenLower = t.token.toLowerCase();\n\n // Get available notes for this token, excluding already-used ones\n const usedIndices = usedNotesByToken.get(tokenLower) ?? new Set();\n const availableNotes = notes.filter((n) => {\n const noteToken = (n as unknown as { token?: string }).token;\n return (\n noteToken &&\n noteToken.toLowerCase() === tokenLower &&\n !usedIndices.has(n.index)\n );\n });\n\n // Plan this transfer using the existing planTransaction function\n const plan = planTransaction(\n availableNotes,\n [\n {\n mpk: t.recipientMpk,\n amount: t.amount,\n viewingPublicKey: t.recipientViewingPubKey,\n },\n ],\n senderMpk,\n t.token,\n senderViewingPubKey,\n );\n\n // Mark selected notes as used\n if (!usedNotesByToken.has(tokenLower)) {\n usedNotesByToken.set(tokenLower, new Set());\n }\n for (const input of plan.inputs) {\n usedNotesByToken.get(tokenLower)!.add(input.index);\n }\n\n plans.push(plan);\n }\n\n return plans;\n}\n","import { CoreError, ReconcileError } from \"../errors.js\";\nimport type { JobKind, JobRecord, JobStatus } from \"../state/index.js\";\nimport type {\n BaseStateStore,\n DepositSyncResult,\n TransactSyncResult,\n} from \"./types/index.js\";\n\ntype ReconcilerDeps = {\n stateStore: BaseStateStore;\n depositClient: {\n syncPendingDeposit: (relayId: string) => Promise<DepositSyncResult>;\n };\n transactService: {\n syncPendingTransact: (relayId: string) => Promise<TransactSyncResult>;\n };\n};\n\nconst ACTIVE_STATUSES: JobStatus[] = [\"pending\", \"submitted\", \"broadcasting\"];\n\nexport function createJobReconciler(deps: ReconcilerDeps) {\n const { stateStore, depositClient, transactService } = deps;\n\n async function markChecked(job: JobRecord, err?: unknown) {\n const latest = (await stateStore.getJob(job.relayId)) ?? job;\n const message =\n err instanceof Error\n ? err.message\n : err !== undefined\n ? String(err)\n : null;\n await stateStore.putJob({\n ...latest,\n lastCheckedAt: Date.now(),\n ...(message ? { error: message } : {}),\n });\n }\n\n async function markDead(job: JobRecord, reason: string) {\n const latest = (await stateStore.getJob(job.relayId)) ?? job;\n if (latest.status === \"succeeded\") return;\n await stateStore.putJob({\n ...latest,\n status: \"dead\",\n lastCheckedAt: Date.now(),\n error: reason,\n });\n }\n\n function isTimedOut(job: JobRecord) {\n return Date.now() - job.createdAt > job.timeoutMs;\n }\n\n async function reconcileJob(job: JobRecord) {\n const latest = (await stateStore.getJob(job.relayId)) ?? job;\n if (!ACTIVE_STATUSES.includes(latest.status)) {\n if (latest.status === \"failed\" || latest.status === \"dead\") {\n throw new ReconcileError(\n latest.error ?? `job ${latest.status}`,\n latest.status,\n );\n }\n // Job already succeeded (e.g. auto-sync reconciled it).\n // Re-run sync (idempotent) to return a valid result.\n if (latest.kind === \"deposit\") {\n return depositClient.syncPendingDeposit(latest.relayId);\n }\n return transactService.syncPendingTransact(latest.relayId);\n }\n if (latest.status !== \"succeeded\" && isTimedOut(latest)) {\n await markDead(latest, \"job timed out\");\n const current = await stateStore.getJob(latest.relayId);\n if (current?.status === \"succeeded\") {\n // Job succeeded between markDead check — re-sync (idempotent).\n if (current.kind === \"deposit\") {\n return depositClient.syncPendingDeposit(current.relayId);\n }\n return transactService.syncPendingTransact(current.relayId);\n }\n throw new ReconcileError(\"job timed out\", \"dead\");\n }\n if (latest.kind === \"deposit\") {\n return depositClient.syncPendingDeposit(latest.relayId);\n }\n return transactService.syncPendingTransact(latest.relayId);\n }\n\n async function reconcileRelay(relayId: string) {\n const job = await stateStore.getJob(relayId);\n if (!job) {\n throw new CoreError(`unknown relay ${relayId}`);\n }\n try {\n const res = await reconcileJob(job);\n await markChecked(job);\n return res;\n } catch (err) {\n await markChecked(job, err);\n throw err;\n }\n }\n\n async function reconcileAll(\n filter: {\n kind?: JobKind;\n statuses?: JobStatus[];\n } = {},\n ) {\n const jobs = await stateStore.listJobs({\n kind: filter.kind,\n statuses: filter.statuses ?? ACTIVE_STATUSES,\n });\n const results = [];\n for (const job of jobs) {\n try {\n const res = await reconcileJob(job);\n await markChecked(job);\n results.push(res);\n } catch (err) {\n await markChecked(job, err);\n // Allow caller to decide how to handle errors; we keep going.\n results.push(err);\n }\n }\n return results;\n }\n\n return {\n reconcileRelay,\n reconcileAll,\n };\n}\n","import type { AccountView } from \"../account/account.js\";\nimport { createIndexerClient } from \"../clients/indexer.js\";\nimport type {\n CommitmentRecord,\n IndexerNullifierRecord,\n} from \"../clients/indexer.js\";\nimport { createServiceConfig } from \"../config.js\";\nimport { poseidon } from \"../crypto/adapters/index.js\";\nimport { decryptNote } from \"../crypto/encrypt.js\";\nimport { CoreError, InitializationError } from \"../errors.js\";\nimport { FieldSize, Hex } from \"../keys/hex.js\";\nimport {\n createMerkleTrees,\n hydrateChain,\n rebuildTreeFromStore,\n type NoteRecord,\n} from \"../state/index.js\";\nimport { formatUint256, parseHexToBigInt } from \"../utils/bigint.js\";\nimport { ensureChainId } from \"../utils/validators.js\";\nimport type {\n Ciphertext,\n NoteSyncOptions,\n NoteSyncStateStore,\n} from \"./types/index.js\";\n\nconst DEFAULT_BATCH_SIZE = 256;\n\nexport type { NoteSyncOptions, NoteSyncStateStore };\n\ntype ChainSyncStatus = {\n inFlight: boolean;\n lastSuccess: number | null;\n lastError?: string;\n};\n\ntype AdapterCommitmentRecord = {\n index: number;\n commitment: string;\n txHash?: string;\n insertedAt?: number;\n eventType?: string;\n adapterNpk?: string;\n adapterToken?: string;\n adapterAmount?: string;\n adapterRandom?: string;\n};\n\nfunction buildCiphertext(\n ephemeralKey: string,\n bytes: [string, string, string],\n): Ciphertext {\n return {\n ephemeralKey: parseHexToBigInt(ephemeralKey),\n data: [\n parseHexToBigInt(bytes[0]),\n parseHexToBigInt(bytes[1]),\n parseHexToBigInt(bytes[2]),\n ],\n };\n}\n\nfunction encodeCiphertext(ciphertext: Ciphertext): Uint8Array {\n // 4 fields: ephemeralKey + 3 data values\n const payload = new Uint8Array(FieldSize.SCALAR * 4);\n payload.set(Hex.toBytes(formatUint256(ciphertext.ephemeralKey)), 0);\n ciphertext.data.forEach((value, index) => {\n const start = (index + 1) * FieldSize.SCALAR;\n payload.set(Hex.toBytes(formatUint256(value)), start);\n });\n return payload;\n}\n\nexport function createNoteSyncService(\n stateStore: NoteSyncStateStore,\n options: NoteSyncOptions = {},\n) {\n const trees = options.merkleTrees ?? createMerkleTrees();\n const limit = options.limit ?? DEFAULT_BATCH_SIZE;\n const status = new Map<number, ChainSyncStatus>();\n const hydrated = new Set<number>();\n\n // Initialize indexer client\n let indexerClient = options.indexerClient;\n if (!indexerClient) {\n const fetchImpl =\n options.fetch ?? (typeof fetch === \"function\" ? fetch : undefined);\n if (!fetchImpl) {\n throw new InitializationError(\n \"fetch dependency is required to sync indexer commitments\",\n );\n }\n if (!options.gatewayUrl) {\n throw new InitializationError(\n \"gatewayUrl is required to sync indexer commitments\",\n );\n }\n const serviceConfig = createServiceConfig(options.gatewayUrl);\n indexerClient = createIndexerClient(serviceConfig.indexerBaseUrl, {\n fetch: fetchImpl,\n });\n }\n\n function createNoteRecord(params: {\n chainId: number;\n index: number;\n commitment: string;\n token: string;\n amount: bigint;\n npk: bigint;\n mpk: bigint;\n random: bigint;\n nullifier: string;\n createdTxHash?: string;\n createdEventType?: string;\n createdAt?: number;\n spentAt?: number;\n spentTxHash?: string;\n }): NoteRecord {\n const {\n chainId,\n index,\n commitment,\n token,\n amount,\n npk,\n mpk,\n random,\n nullifier,\n createdTxHash,\n createdEventType,\n createdAt,\n spentAt,\n spentTxHash,\n } = params;\n const base: NoteRecord = {\n chainId,\n index,\n token,\n value: amount.toString(),\n commitment,\n npk: formatUint256(npk),\n mpk: formatUint256(mpk),\n random: formatUint256(random),\n nullifier,\n createdTxHash,\n createdEventType,\n createdAt,\n spentTxHash,\n };\n return spentAt === undefined ? base : { ...base, spentAt };\n }\n\n // Try to reconstruct a note from an adapter deposit event.\n // Adapter deposits have zero ciphertext; the indexer returns npk, token, amount, random directly.\n function tryReconstructAdapterNote(\n chainId: number,\n record: AdapterCommitmentRecord,\n account: AccountView,\n ): NoteRecord | null {\n if (\n !record.adapterNpk ||\n !record.adapterToken ||\n !record.adapterAmount ||\n !record.adapterRandom\n ) {\n return null;\n }\n\n const eventNpk = parseHexToBigInt(record.adapterNpk);\n const eventRandom = parseHexToBigInt(record.adapterRandom);\n const eventAmount = parseHexToBigInt(record.adapterAmount);\n const eventToken = record.adapterToken.toLowerCase();\n\n // Check if npk matches this account: npk should equal poseidon([mpk, random])\n const derivedNpk = poseidon([account.masterPublicKey, eventRandom]);\n if (derivedNpk !== eventNpk) {\n return null;\n }\n\n // Verify commitment: poseidon([npk, uint160(token), amount])\n const commitment = poseidon([eventNpk, BigInt(eventToken), eventAmount]);\n if (commitment !== parseHexToBigInt(record.commitment)) {\n return null;\n }\n\n const nullifier = poseidon([account.nullifyingKey, BigInt(record.index)]);\n const nullifierHex = formatUint256(nullifier);\n\n return createNoteRecord({\n chainId,\n index: record.index,\n commitment: record.commitment,\n token: eventToken,\n amount: eventAmount,\n npk: eventNpk,\n mpk: account.masterPublicKey,\n random: eventRandom,\n nullifier: nullifierHex,\n createdTxHash: record.txHash,\n createdEventType: record.eventType,\n createdAt:\n record.insertedAt != null ? record.insertedAt * 1000 : undefined,\n });\n }\n\n // Try to decrypt a note. Returns the note record if successful, null otherwise.\n function tryDecryptNoteRecord(\n chainId: number,\n record: CommitmentRecord,\n account: AccountView,\n ): NoteRecord | null {\n // Adapter deposits have zero ciphertext — reconstruct from event fields\n if (record.eventType === \"adapter_deposit\") {\n return tryReconstructAdapterNote(chainId, record, account);\n }\n\n const ciphertext = buildCiphertext(record.ephemeralKey, record.ciphertext);\n // Withdrawal commitments have zero ephemeral key — not decryptable\n if (ciphertext.ephemeralKey === 0n) {\n return null;\n }\n let note;\n try {\n note = decryptNote(ciphertext, account.viewingKeyPair.privateKey);\n } catch (e: unknown) {\n // Trial decryption: expected to fail for notes not belonging to this account\n if (!(e instanceof Error)) throw e;\n return null;\n }\n const random = note.random;\n const amount = note.amount;\n const token = note.token;\n const npk = poseidon([account.masterPublicKey, random]);\n const commitment = poseidon([npk, BigInt(token), amount]);\n if (commitment !== parseHexToBigInt(record.commitment)) {\n return null;\n }\n\n const nullifier = poseidon([account.nullifyingKey, BigInt(record.index)]);\n const nullifierHex = formatUint256(nullifier);\n\n return createNoteRecord({\n chainId,\n index: record.index,\n commitment: record.commitment,\n token,\n amount,\n npk,\n mpk: account.masterPublicKey,\n random,\n nullifier: nullifierHex,\n createdTxHash: record.txHash,\n createdEventType: record.eventType,\n createdAt:\n record.insertedAt != null ? record.insertedAt * 1000 : undefined,\n });\n }\n\n // Pulls commitments from the indexer, updating local tree and notes atomically.\n // Uses batch nullifier check to avoid individual 404-generating queries.\n async function ingestFrom(\n chainId: number,\n start: number,\n account: AccountView,\n ) {\n let cursor = start;\n for (;;) {\n const batch = await indexerClient!.fetchCommitmentBatch({\n chainId,\n start: cursor,\n limit,\n });\n\n if (batch.commitments.length === 0) {\n break;\n }\n\n // Phase 1: Process commitments — add to tree + collect batch write items\n const decryptedNotes: NoteRecord[] = [];\n const batchItems: Array<\n Parameters<typeof stateStore.syncCommitmentBatch>[0][number]\n > = [];\n\n for (const record of batch.commitments) {\n const expectedIndex = trees.getLeafCount(chainId);\n if (record.index !== expectedIndex) {\n throw new CoreError(\n `indexed commitments out of order: expected index ${expectedIndex}, got ${record.index} (cursor=${cursor})`,\n );\n }\n\n const value = Hex.toBigInt(record.commitment);\n const { index } = trees.addLeaf(chainId, value);\n if (index !== record.index) {\n throw new CoreError(\"local merkle tree desynchronized\");\n }\n\n const noteRecord = tryDecryptNoteRecord(chainId, record, account);\n const ciphertext = buildCiphertext(\n record.ephemeralKey,\n record.ciphertext,\n );\n const ciphertextBytes = encodeCiphertext(ciphertext);\n\n batchItems.push({\n leaf: {\n chainId,\n index: record.index,\n commitment: record.commitment,\n txHash: record.txHash,\n eventType: record.eventType,\n adapterNpk: record.adapterNpk,\n adapterToken: record.adapterToken,\n adapterAmount: record.adapterAmount,\n adapterRandom: record.adapterRandom,\n insertedAt: record.insertedAt,\n },\n ciphertext: {\n chainId,\n index: record.index,\n payload: ciphertextBytes,\n },\n root: { chainId, root: record.root },\n note: noteRecord ?? undefined,\n });\n\n if (noteRecord) {\n decryptedNotes.push(noteRecord);\n }\n\n cursor = record.index + 1;\n }\n\n // Flush all commitment writes in a single batch\n await stateStore.syncCommitmentBatch(batchItems);\n\n // Phase 2: Batch nullifier check for decrypted notes\n if (decryptedNotes.length > 0) {\n const notesToCheck: NoteRecord[] = [];\n for (const note of decryptedNotes) {\n const existing = await stateStore.getNote(chainId, note.index);\n if (existing?.spentAt !== undefined) {\n await stateStore.putNullifier({\n chainId,\n nullifier: note.nullifier,\n noteIndex: note.index,\n });\n } else {\n notesToCheck.push(note);\n }\n }\n\n if (notesToCheck.length > 0) {\n const spentNullifiers: IndexerNullifierRecord[] =\n await indexerClient!.checkNullifiers({\n chainId,\n nullifiers: notesToCheck.map((n) => n.nullifier),\n });\n const spentMap = new Map(\n spentNullifiers.map((n) => [n.nullifier, n]),\n );\n\n for (const note of notesToCheck) {\n const spent = spentMap.get(note.nullifier);\n if (spent) {\n const spentAtMs = spent.spentAt * 1000;\n await stateStore.putNullifier({\n chainId,\n nullifier: note.nullifier,\n noteIndex: note.index,\n });\n await stateStore.markNoteSpent(\n chainId,\n note.index,\n spentAtMs,\n spent.txHash,\n );\n }\n }\n }\n }\n }\n }\n\n // ── Tiered chain-state diagnosis ──────────────────────────────────────────\n //\n // Tier 1 (2 API calls): compare first + last local commitment against indexer.\n // Both match → consistent (incremental sync).\n // Tier 2 (O(log N) API calls): binary search for the divergence point when\n // the first commitment matches but the tail doesn't (e.g. reorg).\n // Tier 3 (1 API call): first commitment differs or indexer empty → full wipe.\n\n type SyncDiagnosis =\n | { kind: \"consistent\" }\n | { kind: \"full-divergence\" }\n | { kind: \"partial-divergence\"; validPrefix: number };\n\n async function diagnoseChainState(\n chainId: number,\n localCount: number,\n ): Promise<SyncDiagnosis> {\n // Tier 1: compare first commitment\n const firstBatch = await indexerClient!.fetchCommitmentBatch({\n chainId,\n start: 0,\n limit: 1,\n });\n const localFirst = await stateStore.getLeaf(chainId, 0);\n\n if (firstBatch.commitments.length === 0 || !localFirst) {\n return { kind: \"full-divergence\" };\n }\n if (firstBatch.commitments[0].commitment !== localFirst.commitment) {\n return { kind: \"full-divergence\" };\n }\n\n // Single-leaf shortcut: first matches and there's only one local leaf.\n if (localCount === 1) {\n return { kind: \"consistent\" };\n }\n\n // Compare last local commitment\n const lastBatch = await indexerClient!.fetchCommitmentBatch({\n chainId,\n start: localCount - 1,\n limit: 1,\n });\n const localLast = await stateStore.getLeaf(chainId, localCount - 1);\n\n if (\n lastBatch.commitments.length > 0 &&\n localLast &&\n lastBatch.commitments[0].commitment === localLast.commitment\n ) {\n return { kind: \"consistent\" };\n }\n\n // Tier 2: binary search for divergence point\n const divergePoint = await findDivergencePoint(chainId, 1, localCount - 1);\n return { kind: \"partial-divergence\", validPrefix: divergePoint };\n }\n\n async function findDivergencePoint(\n chainId: number,\n low: number,\n high: number,\n ): Promise<number> {\n while (low < high) {\n const mid = Math.floor((low + high) / 2);\n const batch = await indexerClient!.fetchCommitmentBatch({\n chainId,\n start: mid,\n limit: 1,\n });\n const localLeaf = await stateStore.getLeaf(chainId, mid);\n\n if (\n batch.commitments.length > 0 &&\n localLeaf &&\n batch.commitments[0].commitment === localLeaf.commitment\n ) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return low;\n }\n\n // Clears stale tail data and re-ingests from the divergence point.\n async function partialResync(\n chainId: number,\n fromIndex: number,\n account: AccountView,\n ) {\n hydrated.delete(chainId);\n await Promise.all([\n stateStore.clearChainDataFromIndex(chainId, fromIndex),\n stateStore.clearNullifiersFromIndex(chainId, fromIndex),\n stateStore.clearRescanCursors(chainId),\n ]);\n trees.reset(chainId);\n await rebuildTreeFromStore({\n chainId,\n trees,\n loadLeaves: stateStore.listLeaves.bind(stateStore),\n });\n hydrated.add(chainId);\n await ingestFrom(chainId, fromIndex, account);\n }\n\n // Clears local state for a chain and rehydrates fully from the indexer.\n async function fullResync(chainId: number, account: AccountView) {\n hydrated.delete(chainId);\n trees.reset(chainId);\n await Promise.all([\n stateStore.clearLeaves(chainId),\n stateStore.clearNotes(chainId),\n stateStore.clearCiphertexts(chainId),\n stateStore.clearNullifiers(chainId),\n stateStore.clearRescanCursors(chainId),\n ]);\n await ingestFrom(chainId, 0, account);\n }\n\n // Decode a stored ciphertext (4 x 32-byte values) into a Ciphertext object\n function decodeCiphertext(payload: Uint8Array): Ciphertext {\n const ephemeralKey = Hex.toBigInt(\n Hex.fromBytes(payload.slice(0, FieldSize.SCALAR)),\n );\n const data: bigint[] = [];\n for (let i = 0; i < 3; i++) {\n const start = (i + 1) * FieldSize.SCALAR;\n const end = start + FieldSize.SCALAR;\n const slice = payload.slice(start, end);\n data.push(Hex.toBigInt(Hex.fromBytes(slice)));\n }\n return { ephemeralKey, data: data as [bigint, bigint, bigint] };\n }\n\n // Re-scan stored ciphertexts for a new account, using batch nullifier checks.\n // Adapter deposits are reconstructed from locally cached event fields when available.\n async function rescanCiphertextsForAccount(\n chainId: number,\n account: AccountView,\n leafCount: number,\n fromIndex = 0,\n ) {\n const accountMpk = formatUint256(account.masterPublicKey);\n\n type PendingNote = {\n note: NoteRecord;\n baseParams: Parameters<typeof createNoteRecord>[0];\n };\n const pendingNotes: PendingNote[] = [];\n\n // Batch-load all data upfront instead of per-index awaits\n const [allNotes, allCiphertexts, allLeaves] = await Promise.all([\n stateStore.listNotes({ chainId, mpk: accountMpk }),\n stateStore.listCiphertexts(chainId),\n stateStore.listLeaves(chainId),\n ]);\n const noteSet = new Set(allNotes.map((n) => n.index));\n const ctMap = new Map(allCiphertexts.map((c) => [c.index, c.payload]));\n const leafMap = new Map(allLeaves.map((l) => [l.index, l]));\n const adapterRecords = new Map<number, AdapterCommitmentRecord>();\n const missingAdapterIndices: number[] = [];\n\n for (let index = fromIndex; index < leafCount; index++) {\n const leaf = leafMap.get(index);\n if (!leaf || leaf.eventType !== \"adapter_deposit\") continue;\n if (\n leaf.adapterNpk &&\n leaf.adapterToken &&\n leaf.adapterAmount &&\n leaf.adapterRandom\n ) {\n adapterRecords.set(index, {\n index,\n commitment: leaf.commitment,\n txHash: leaf.txHash,\n insertedAt: leaf.insertedAt,\n eventType: leaf.eventType ?? \"adapter_deposit\",\n adapterNpk: leaf.adapterNpk,\n adapterToken: leaf.adapterToken,\n adapterAmount: leaf.adapterAmount,\n adapterRandom: leaf.adapterRandom,\n });\n } else {\n missingAdapterIndices.push(index);\n }\n }\n\n if (missingAdapterIndices.length > 0) {\n const missingSet = new Set(missingAdapterIndices);\n const minIndex = missingAdapterIndices[0]!;\n const maxIndex = missingAdapterIndices[missingAdapterIndices.length - 1]!;\n let cursor = minIndex;\n\n while (cursor <= maxIndex && missingSet.size > 0) {\n const batch = await indexerClient!.fetchCommitmentBatch({\n chainId,\n start: cursor,\n limit,\n });\n if (batch.commitments.length === 0) break;\n for (const record of batch.commitments) {\n if (!missingSet.has(record.index)) continue;\n adapterRecords.set(record.index, record);\n missingSet.delete(record.index);\n }\n cursor = batch.commitments[batch.commitments.length - 1]!.index + 1;\n }\n }\n\n for (let index = fromIndex; index < leafCount; index++) {\n if (noteSet.has(index)) continue;\n\n const ciphertextBytes = ctMap.get(index);\n\n const leaf = leafMap.get(index);\n if (!leaf) continue;\n\n // Adapter deposits: reconstruct from cached metadata or batched indexer fallback\n if (leaf.eventType === \"adapter_deposit\") {\n const record = adapterRecords.get(index);\n if (record) {\n const adapterNote = tryReconstructAdapterNote(\n chainId,\n record,\n account,\n );\n if (adapterNote) {\n const baseParams = {\n chainId,\n index,\n commitment: record.commitment,\n token: adapterNote.token,\n amount: BigInt(adapterNote.value),\n npk: parseHexToBigInt(adapterNote.npk),\n mpk: account.masterPublicKey,\n random: parseHexToBigInt(adapterNote.random),\n nullifier: adapterNote.nullifier,\n createdTxHash: record.txHash || leaf.txHash,\n createdEventType: record.eventType || leaf.eventType,\n createdAt:\n record.insertedAt != null\n ? record.insertedAt * 1000\n : leaf.insertedAt != null\n ? leaf.insertedAt * 1000\n : undefined,\n };\n pendingNotes.push({ note: adapterNote, baseParams });\n }\n }\n continue;\n }\n\n if (!ciphertextBytes) continue;\n\n const ciphertext = decodeCiphertext(ciphertextBytes);\n // Withdrawal commitments have zero ephemeral key — not decryptable\n if (ciphertext.ephemeralKey === 0n) continue;\n let note;\n try {\n note = decryptNote(ciphertext, account.viewingKeyPair.privateKey);\n } catch (e: unknown) {\n // Trial decryption: expected to fail for notes not belonging to this account\n if (!(e instanceof Error)) throw e;\n continue;\n }\n\n const npk = poseidon([account.masterPublicKey, note.random]);\n const commitment = poseidon([npk, BigInt(note.token), note.amount]);\n if (commitment !== parseHexToBigInt(leaf.commitment)) continue;\n\n const nullifier = poseidon([account.nullifyingKey, BigInt(index)]);\n const nullifierHex = formatUint256(nullifier);\n\n const baseNoteParams = {\n chainId,\n index,\n commitment: leaf.commitment,\n token: note.token,\n amount: note.amount,\n npk,\n mpk: account.masterPublicKey,\n random: note.random,\n nullifier: nullifierHex,\n createdTxHash: leaf.txHash,\n createdEventType: leaf.eventType,\n createdAt: leaf.insertedAt != null ? leaf.insertedAt * 1000 : undefined,\n };\n\n pendingNotes.push({\n note: createNoteRecord(baseNoteParams),\n baseParams: baseNoteParams,\n });\n }\n\n if (pendingNotes.length > 0) {\n const spentNullifiers: IndexerNullifierRecord[] =\n await indexerClient!.checkNullifiers({\n chainId,\n nullifiers: pendingNotes.map((p) => p.note.nullifier),\n });\n const spentMap = new Map(spentNullifiers.map((n) => [n.nullifier, n]));\n\n for (const { note, baseParams } of pendingNotes) {\n const spent = spentMap.get(note.nullifier);\n if (spent) {\n await stateStore.putNullifier({\n chainId,\n nullifier: note.nullifier,\n noteIndex: note.index,\n });\n await stateStore.putNote(\n createNoteRecord({\n ...baseParams,\n spentAt: spent.spentAt * 1000,\n spentTxHash: spent.txHash,\n }),\n );\n } else {\n await stateStore.putNote(note);\n }\n }\n }\n }\n\n // Check existing unspent notes for nullification using batch check.\n async function checkExistingNotesForNullification(\n chainId: number,\n account: AccountView,\n ) {\n const accountMpk = formatUint256(account.masterPublicKey);\n const unspentNotes = await stateStore.listNotes({\n chainId,\n mpk: accountMpk,\n includeSpent: false,\n });\n\n if (unspentNotes.length === 0) return;\n\n const spentNullifiers: IndexerNullifierRecord[] =\n await indexerClient!.checkNullifiers({\n chainId,\n nullifiers: unspentNotes.map((n) => n.nullifier),\n });\n const spentMap = new Map(spentNullifiers.map((n) => [n.nullifier, n]));\n\n for (const note of unspentNotes) {\n const spent = spentMap.get(note.nullifier);\n if (spent) {\n await stateStore.putNullifier({\n chainId,\n nullifier: note.nullifier,\n noteIndex: note.index,\n });\n await stateStore.markNoteSpent(\n chainId,\n note.index,\n spent.spentAt * 1000,\n spent.txHash,\n );\n }\n }\n }\n\n /**\n * Syncs a single chain into local state, optionally forcing a full rebuild.\n */\n async function syncChain(\n chainId: number,\n account: AccountView,\n opts: { forceFullResync?: boolean } = {},\n ): Promise<void> {\n ensureChainId(chainId);\n const current = status.get(chainId) ?? {\n inFlight: false,\n lastSuccess: null,\n };\n if (current.inFlight) return;\n status.set(chainId, { ...current, inFlight: true, lastError: undefined });\n\n try {\n const start = opts.forceFullResync\n ? 0\n : await hydrateChain({\n chainId,\n trees,\n loadLeaves: stateStore.listLeaves.bind(stateStore),\n hydrated,\n });\n\n if (opts.forceFullResync) {\n await fullResync(chainId, account);\n } else if (start > 0) {\n try {\n const diagnosis = await diagnoseChainState(chainId, start);\n switch (diagnosis.kind) {\n case \"consistent\":\n try {\n await ingestFrom(chainId, start, account);\n } catch (err) {\n console.warn(\n `[note-sync] incremental ingest failed for chain ${chainId}, falling back to full resync:`,\n err,\n );\n await fullResync(chainId, account);\n }\n break;\n case \"partial-divergence\":\n await partialResync(chainId, diagnosis.validPrefix, account);\n break;\n case \"full-divergence\":\n await fullResync(chainId, account);\n break;\n }\n } catch (err) {\n console.warn(\n `[note-sync] chain diagnosis failed for chain ${chainId}, falling back to full resync:`,\n err,\n );\n await fullResync(chainId, account);\n }\n } else {\n // start === 0, fresh first sync\n try {\n await ingestFrom(chainId, 0, account);\n } catch (err) {\n console.warn(\n `[note-sync] initial ingest failed for chain ${chainId}, falling back to full resync:`,\n err,\n );\n await fullResync(chainId, account);\n }\n }\n\n // Rescan ciphertexts for multi-account support (only new leaves)\n const accountMpk = formatUint256(account.masterPublicKey);\n const leafCount = trees.getLeafCount(chainId);\n if (leafCount > 0 && !opts.forceFullResync) {\n const lastScanned = await stateStore.getRescanCursor(\n chainId,\n accountMpk,\n );\n if (lastScanned === null || lastScanned < leafCount) {\n await rescanCiphertextsForAccount(\n chainId,\n account,\n leafCount,\n lastScanned ?? 0,\n );\n await stateStore.setRescanCursor(chainId, accountMpk, leafCount);\n }\n }\n\n // Check if any existing unspent notes have been nullified\n await checkExistingNotesForNullification(chainId, account);\n\n status.set(chainId, { inFlight: false, lastSuccess: Date.now() });\n } catch (err) {\n status.set(chainId, {\n inFlight: false,\n lastSuccess: current.lastSuccess ?? null,\n lastError: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n }\n\n /**\n * Syncs multiple chains sequentially.\n */\n async function syncChains(\n chainIds: number[],\n account: AccountView,\n opts?: { forceFullResync?: boolean },\n ): Promise<void> {\n for (const chainId of chainIds) {\n await syncChain(chainId, account, opts);\n }\n }\n\n function getStatus() {\n return status;\n }\n\n return {\n syncChain,\n syncChains,\n getStatus,\n };\n}\n","import type { Account, AccountView, Signer } from \"../account/account.js\";\nimport type { SeedService } from \"../account/seed.js\";\nimport type {\n RelayState,\n RelayStatusResponse,\n} from \"../clients/broadcaster.js\";\nimport type { Environment } from \"../config.js\";\nimport type { initCore } from \"../core.js\";\nimport type { HistoryEntry } from \"../history/types.js\";\nimport type { NoteRecord } from \"../state/store/records.js\";\nimport type {\n AdapterExecutionCall,\n AdapterExecutionReshield,\n WithdrawalPlan,\n} from \"../transactions/index.js\";\nimport type {\n DepositRelayResult,\n DepositSyncResult,\n NoteInput,\n TransactionPlan,\n TransactRelayResult,\n TransactSyncResult,\n WithdrawalNoteInput,\n} from \"../transactions/types/index.js\";\nimport type { Storage } from \"../types.js\";\nimport type { BurnerAPI } from \"./burner/types.js\";\n\nexport const ACCOUNT_RECORD_VERSION = 1;\nexport const BIGINT_RADIX = 16;\n\nexport type CoreSDK = Awaited<ReturnType<typeof initCore>>;\n\nexport type WalletDeps = {\n core: CoreSDK;\n fetch: typeof globalThis.fetch;\n};\n\n/**\n * Account info without private keys, safe for display.\n */\nexport type AccountInfo = {\n index: number;\n masterPublicKey: bigint;\n /** Bech32m address (0zk1...) */\n address: string;\n};\n\n/**\n * Seed management API for mnemonic/master seed operations.\n * Derived from SeedService, excluding internal getMasterSeed method.\n */\nexport type SeedAPI = Omit<SeedService, \"getMasterSeed\">;\n\n/**\n * Account management API for multi-account support.\n */\nexport type WalletAccountAPI = {\n /**\n * List all derived accounts (index + mpk only).\n */\n list(): Promise<AccountInfo[]>;\n\n /**\n * Get full Account by index.\n */\n get(index: number): Promise<Account | null>;\n\n /**\n * Derive and persist a new account.\n * @param index Optional specific index, otherwise uses next available\n */\n create(index?: number): Promise<Account>;\n\n /**\n * Get the currently active account.\n */\n getActive(): Promise<Account | null>;\n\n /**\n * Get the currently active account index.\n */\n getActiveIndex(): Promise<number | null>;\n\n /**\n * Switch to a different account.\n * @throws If account at index doesn't exist\n */\n setActive(index: number): Promise<void>;\n};\n\n// Deposit types\n// Named differently from core's DepositParams to avoid collision\nexport type WalletDepositParams = {\n chainId: number;\n poolAddress: string;\n depositor: string;\n deposits: Array<{\n token: string;\n amount: bigint;\n }>;\n /** Override account for multisig deposits (defaults to active account). */\n account?: AccountView;\n};\n\nexport type WalletDepositResult = DepositRelayResult;\n\nexport type WalletDepositAPI = {\n /**\n * Request a deposit (1 or more tokens).\n */\n request(params: WalletDepositParams): Promise<WalletDepositResult>;\n /**\n * Wait for deposit to be confirmed on-chain.\n */\n reconcile(relayId: string): Promise<DepositSyncResult>;\n};\n\nexport type WalletNoteInsert = {\n chainId: number;\n index: number;\n token: string;\n amount: bigint;\n commitment: string;\n npk: bigint;\n mpk: bigint;\n random: bigint;\n nullifier: bigint;\n};\n\nexport type WalletNoteAPI = {\n import(note: WalletNoteInsert): Promise<void>;\n list(\n chainId: number,\n overrides?: { account: AccountView },\n ): Promise<NoteRecord[]>;\n};\n\nexport type WalletSyncAPI = {\n syncChain(\n chainId: number,\n account: AccountView,\n opts?: { forceFullResync?: boolean },\n ): Promise<void>;\n syncChains(\n chainIds: number[],\n account: AccountView,\n opts?: { forceFullResync?: boolean },\n ): Promise<void>;\n startAutoSync(intervalMs?: number): Promise<void>;\n stopAutoSync(): void;\n};\n\nexport type WalletTxAPI = {\n /**\n * Get the status of a transaction from the broadcaster.\n * @param txId - The transaction ID returned from deposit, transfer, or withdraw operations\n */\n getStatus(txId: string): Promise<RelayStatusResponse>;\n /**\n * Start tracking a transaction for status updates.\n * Emits 'tx-status-changed' events when the transaction state changes.\n * Tracking automatically stops when the transaction reaches a terminal state.\n * @param txId - The transaction ID to track\n */\n track(txId: string): void;\n /**\n * Stop tracking a transaction.\n * @param txId - The transaction ID to stop tracking\n */\n untrack(txId: string): void;\n};\n\nexport type SignerOverride = {\n signer: Signer;\n account: AccountView;\n};\n\nexport type WalletTransactAPI = {\n transact(\n params: {\n chainId: number;\n poolAddress: string;\n transactions: Array<{\n token: string;\n inputs: Array<{ index: number }>;\n outputs: NoteInput[];\n withdrawal?: WithdrawalNoteInput;\n adapterDataHash?: bigint;\n }>;\n },\n opts?: { skipBroadcast?: boolean },\n overrides?: SignerOverride,\n ): Promise<TransactRelayResult>;\n reconcile(relayId: string): Promise<TransactSyncResult>;\n};\n\nexport type InputTokenSpec = {\n token: string;\n amount: bigint;\n};\n\nexport type ReshieldInput = {\n token: string;\n minAmount: bigint;\n};\n\nexport type WalletAdapterExecuteParams = {\n chainId: number;\n poolAddress: string;\n adapterAddress: string;\n inputs: InputTokenSpec[];\n calls: AdapterExecutionCall[];\n reshields: ReshieldInput[];\n deadline?: bigint;\n};\n\nexport type AdapterExecuteResult = {\n relayId: string;\n adapterCalldata: string;\n transactCalldata: string;\n transactResult: TransactRelayResult;\n reshields: AdapterExecutionReshield[];\n};\n\nexport type WalletAdapterAPI = {\n execute(\n params: WalletAdapterExecuteParams,\n opts?: { skipBroadcast?: boolean },\n overrides?: SignerOverride,\n ): Promise<AdapterExecuteResult>;\n};\n\nexport type WalletHistoryAPI = {\n list(\n chainId: number,\n options?: { includeSelfSends?: boolean },\n overrides?: { account: AccountView },\n ): Promise<HistoryEntry[]>;\n};\n\n// High-level transfer types\nexport type TransferParams = {\n chainId: number;\n poolAddress: string;\n transfers: Array<{\n token: string;\n recipient: string; // Unlink address (0zk1... bech32m)\n amount: bigint;\n }>;\n};\n\nexport type TransferPlanResult<T = NoteRecord> = TransactionPlan<T>[];\n\nexport type TransferResult = {\n relayId: string;\n plans: TransferPlanResult;\n transactResult: TransactRelayResult;\n};\n\n// High-level withdraw types\nexport type WithdrawParams = {\n chainId: number;\n poolAddress: string;\n withdrawals: Array<{\n token: string;\n amount: bigint;\n recipient: string; // EOA address\n }>;\n};\n\nexport type WithdrawPlanResult<T = NoteRecord> = WithdrawalPlan<T>[];\n\nexport type WithdrawResult = {\n relayId: string;\n plans: WithdrawPlanResult;\n transactResult: TransactRelayResult;\n};\n\nexport type WalletBalanceAPI = {\n /**\n * Get balances for all tokens on a chain.\n */\n list(\n chainId: number,\n overrides?: { account: AccountView },\n ): Promise<Record<string, bigint>>;\n /**\n * Get balance for a specific token on a chain.\n */\n get(\n chainId: number,\n token: string,\n overrides?: { account: AccountView },\n ): Promise<bigint>;\n};\n\nexport type WalletTransferAPI = {\n /**\n * High-level transfer: 1 or more transfers.\n * SDK handles note selection, circuit selection, and proof generation.\n * Generates proofs in parallel and submits as one atomic operation.\n */\n send(\n params: TransferParams,\n overrides?: SignerOverride,\n ): Promise<TransferResult>;\n /**\n * Get a transfer plan without executing.\n * Useful for showing the user what will happen before confirming.\n */\n plan(\n params: TransferParams,\n account?: AccountView,\n ): Promise<TransferPlanResult>;\n /**\n * Execute a pre-built transfer plan.\n */\n execute(\n plans: TransferPlanResult,\n params: Pick<TransferParams, \"chainId\" | \"poolAddress\">,\n overrides?: SignerOverride,\n ): Promise<TransferResult>;\n};\n\nexport type WalletWithdrawAPI = {\n /**\n * High-level withdraw: 1 or more withdrawals.\n * SDK handles note selection, circuit selection, and proof generation.\n * Generates proofs in parallel and submits as one atomic operation.\n */\n send(\n params: WithdrawParams,\n overrides?: SignerOverride,\n ): Promise<WithdrawResult>;\n /**\n * Get a withdrawal plan without executing.\n * Useful for showing the user what will happen before confirming.\n */\n plan(\n params: WithdrawParams,\n account?: AccountView,\n ): Promise<WithdrawPlanResult>;\n /**\n * Execute a pre-built withdrawal plan.\n */\n execute(\n plans: WithdrawPlanResult,\n params: Pick<WithdrawParams, \"chainId\" | \"poolAddress\">,\n overrides?: SignerOverride,\n ): Promise<WithdrawResult>;\n};\n\nexport type TxStatusChangedEvent = {\n type: \"tx-status-changed\";\n txId: string;\n state: RelayState;\n previousState: RelayState | null;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n};\n\nexport type WalletSDKEvent =\n | { type: \"notes-updated\"; chainId: number }\n | { type: \"sync-error\"; error: string }\n | { type: \"wallet-created\" }\n | { type: \"account-created\"; index: number }\n | { type: \"account-switched\"; index: number }\n | TxStatusChangedEvent;\n\nexport type WalletSDK = {\n seed: SeedAPI;\n accounts: WalletAccountAPI;\n balances: WalletBalanceAPI;\n /** Burner accounts — BIP-44 derived EOAs for DeFi interactions */\n burner: BurnerAPI;\n /** Private DeFi adapter execution flow */\n adapter: WalletAdapterAPI;\n deposit: WalletDepositAPI;\n history: WalletHistoryAPI;\n notes: WalletNoteAPI;\n transact: WalletTransactAPI;\n transfer: WalletTransferAPI;\n withdraw: WalletWithdrawAPI;\n events: {\n on(fn: (event: WalletSDKEvent) => void): () => void;\n };\n sync: WalletSyncAPI;\n tx: WalletTxAPI;\n};\n\n// Burner plugin types — re-exported from dedicated module\nexport type { BurnerAPI };\nexport type {\n BurnerAccount,\n BurnerFundParams,\n BurnerSendParams,\n BurnerSweepToPoolParams,\n} from \"./burner/types.js\";\n\n// ===== UnlinkWallet types (simplified, no chainId/poolAddress per-call) =====\n\n/**\n * Configuration for UnlinkWallet.create().\n * Either provide explicit gatewayUrl + poolAddress, or an environment to auto-resolve.\n */\nexport type UnlinkWalletConfig =\n | {\n /** Chain ID for the target blockchain */\n chainId: number;\n /** Explicit gateway URL */\n gatewayUrl: string;\n /** Pool contract address */\n poolAddress: string;\n /** Direct chain RPC for burner EOA transactions. Defaults to gatewayUrl. */\n chainRpcUrl?: string;\n /** Storage backend (auto-detected in browser, required in Node) */\n storage?: Storage;\n /** Random number generator (auto-detected via crypto.getRandomValues) */\n rng?: (n: number) => Uint8Array;\n /** Fetch implementation (defaults to globalThis.fetch) */\n fetch?: typeof globalThis.fetch;\n /** Prover/artifact source configuration */\n prover?: ProverConfig;\n /** Disable auto-sync scheduler (default: true). Set false for CLI/script usage. */\n autoSync?: boolean;\n }\n | {\n /** Chain ID for the target blockchain */\n chainId: number;\n /** Environment to auto-resolve gateway URL and pool address */\n environment: Environment;\n /** Pool contract address override (defaults to environment config) */\n poolAddress?: string;\n /** Direct chain RPC for burner EOA transactions. Defaults to gatewayUrl. */\n chainRpcUrl?: string;\n /** Storage backend (auto-detected in browser, required in Node) */\n storage?: Storage;\n /** Random number generator (auto-detected via crypto.getRandomValues) */\n rng?: (n: number) => Uint8Array;\n /** Fetch implementation (defaults to globalThis.fetch) */\n fetch?: typeof globalThis.fetch;\n /** Prover/artifact source configuration */\n prover?: ProverConfig;\n /** Disable auto-sync scheduler (default: true). Set false for CLI/script usage. */\n autoSync?: boolean;\n };\n\n/**\n * Prover configuration for artifact source.\n * Matches ServiceOptions[\"prover\"] shape.\n */\nexport type ProverConfig = {\n artifactSource?: {\n baseUrl?: string;\n version?: string;\n preferLocalFiles?: boolean;\n };\n};\n\n/**\n * Deposit params without chainId/poolAddress (baked into UnlinkWallet).\n */\nexport type SimpleDepositParams = {\n /** On-chain depositor EOA address */\n depositor: string;\n /** Tokens and amounts to deposit */\n deposits: Array<{\n token: string;\n amount: bigint;\n }>;\n /** Override account for multisig deposits (defaults to active account). */\n account?: AccountView;\n};\n\n/**\n * Transfer params without chainId/poolAddress (baked into UnlinkWallet).\n */\nexport type SimpleTransferParams = {\n /** Transfers to execute atomically */\n transfers: Array<{\n token: string;\n /** Unlink address (0zk1... bech32m) */\n recipient: string;\n amount: bigint;\n }>;\n};\n\n/**\n * Withdraw params without chainId/poolAddress (baked into UnlinkWallet).\n */\nexport type SimpleWithdrawParams = {\n /** Withdrawals to execute atomically */\n withdrawals: Array<{\n token: string;\n amount: bigint;\n /** EOA address to receive funds */\n recipient: string;\n }>;\n};\n\n/**\n * Burner fund params without chainId/poolAddress (baked into UnlinkWallet).\n */\nexport type SimpleBurnerFundParams = {\n token: string;\n amount: bigint;\n};\n\n/**\n * Burner sweep-to-pool params without chainId/poolAddress (baked into UnlinkWallet).\n */\nexport type SimpleBurnerSweepToPoolParams = {\n token: string;\n /** Amount to sweep; omit to sweep full token balance */\n amount?: bigint;\n};\n\n/**\n * Advanced transact params without chainId/poolAddress (baked into UnlinkWallet).\n * For raw JoinSplit transaction building.\n */\nexport type SimpleTransactParams = {\n transactions: Array<{\n token: string;\n inputs: Array<{ index: number }>;\n outputs: NoteInput[];\n withdrawal?: WithdrawalNoteInput;\n adapterDataHash?: bigint;\n }>;\n};\n\nexport type SimpleAdapterExecuteParams = {\n adapterAddress: string;\n inputs: InputTokenSpec[];\n calls: AdapterExecutionCall[];\n reshields: ReshieldInput[];\n deadline?: bigint;\n};\n\nexport type StoredAccountRecord = {\n version: typeof ACCOUNT_RECORD_VERSION;\n spendingKeyPair: {\n privateKey: number[];\n pubkey: [string, string];\n };\n viewingKeyPair: {\n privateKey: number[];\n pubkey: number[];\n };\n nullifyingKey: string;\n masterPublicKey: string;\n address: string;\n};\n","import { formatUint256 } from \"../utils/bigint.js\";\nimport {\n ACCOUNT_RECORD_VERSION,\n BIGINT_RADIX,\n type StoredAccountRecord,\n} from \"../wallet/types.js\";\nimport type { Account } from \"./account.js\";\n\nexport { formatUint256 };\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nconst encodeBigInt = (value: bigint): string => value.toString(BIGINT_RADIX);\nconst decodeBigInt = (value: string): bigint => BigInt(`0x${value}`);\n\nexport function serializeAccountRecord(account: Account): Uint8Array {\n const record: StoredAccountRecord = {\n version: ACCOUNT_RECORD_VERSION,\n spendingKeyPair: {\n privateKey: Array.from(account.spendingKeyPair.privateKey),\n pubkey: [\n encodeBigInt(account.spendingKeyPair.pubkey[0]),\n encodeBigInt(account.spendingKeyPair.pubkey[1]),\n ],\n },\n viewingKeyPair: {\n privateKey: Array.from(account.viewingKeyPair.privateKey),\n pubkey: Array.from(account.viewingKeyPair.pubkey),\n },\n nullifyingKey: encodeBigInt(account.nullifyingKey),\n masterPublicKey: encodeBigInt(account.masterPublicKey),\n address: account.address,\n };\n return encoder.encode(JSON.stringify(record));\n}\n\nexport function deserializeAccountRecord(payload: Uint8Array): Account {\n const parsed = JSON.parse(decoder.decode(payload)) as StoredAccountRecord;\n if (parsed.version !== ACCOUNT_RECORD_VERSION) {\n throw new Error(`unsupported wallet account version ${parsed.version}`);\n }\n\n const spendingPubkey: [bigint, bigint] = [\n decodeBigInt(parsed.spendingKeyPair.pubkey[0]),\n decodeBigInt(parsed.spendingKeyPair.pubkey[1]),\n ];\n\n const viewingPubkey = Uint8Array.from(parsed.viewingKeyPair.pubkey);\n const masterPublicKey = decodeBigInt(parsed.masterPublicKey);\n\n const address = parsed.address;\n\n return {\n spendingKeyPair: {\n privateKey: Uint8Array.from(parsed.spendingKeyPair.privateKey),\n pubkey: spendingPubkey,\n },\n viewingKeyPair: {\n privateKey: Uint8Array.from(parsed.viewingKeyPair.privateKey),\n pubkey: viewingPubkey,\n },\n nullifyingKey: decodeBigInt(parsed.nullifyingKey),\n masterPublicKey,\n address,\n };\n}\n","import { ValidationError } from \"../errors.js\";\nimport type { Storage } from \"../types.js\";\nimport type { AccountInfo } from \"../wallet/types.js\";\nimport { deriveAccount as deriveAccountFn, type Account } from \"./account.js\";\nimport {\n deserializeAccountRecord,\n serializeAccountRecord,\n} from \"./serialization.js\";\n\nexport const DERIVED_ACCOUNTS_KEY = \"cfg:wallet:derived_accounts\";\nexport const ACTIVE_ACCOUNT_INDEX_KEY = \"cfg:wallet:active_account_index\";\nexport const ACCOUNT_KEY_PREFIX = \"cfg:wallet:account:\";\n\nexport type AccountsServiceDeps = {\n storage: Storage;\n deriveAccount: typeof deriveAccountFn;\n getMasterSeed: () => Promise<Uint8Array>;\n};\n\nexport type AccountsService = {\n /**\n * List all derived accounts (index + mpk only, safe to display).\n */\n list(): Promise<AccountInfo[]>;\n\n /**\n * Get full Account by index (null if not derived yet).\n */\n get(index: number): Promise<Account | null>;\n\n /**\n * Derive and persist a new account at the specified index.\n * If index is not specified, uses the next available index.\n * @throws If the index is already used\n */\n create(index?: number): Promise<Account>;\n\n /**\n * Get the currently active account (null if none).\n */\n getActive(): Promise<Account | null>;\n\n /**\n * Get the currently active account index (null if none).\n */\n getActiveIndex(): Promise<number | null>;\n\n /**\n * Switch to a different account by index.\n * @throws If the account at the given index doesn't exist\n */\n setActive(index: number): Promise<void>;\n};\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nfunction accountKey(index: number): string {\n return `${ACCOUNT_KEY_PREFIX}${index}`;\n}\n\nfunction encodeIndices(indices: number[]): Uint8Array {\n return encoder.encode(JSON.stringify(indices));\n}\n\nfunction decodeIndices(data: Uint8Array): number[] {\n return JSON.parse(decoder.decode(data)) as number[];\n}\n\nfunction encodeIndex(index: number): Uint8Array {\n return encoder.encode(JSON.stringify(index));\n}\n\nfunction decodeIndex(data: Uint8Array): number {\n return JSON.parse(decoder.decode(data)) as number;\n}\n\nexport function createAccountsService(\n deps: AccountsServiceDeps,\n): AccountsService {\n const { storage, deriveAccount, getMasterSeed } = deps;\n\n async function getDerivedIndices(): Promise<number[]> {\n const stored = await storage.get(DERIVED_ACCOUNTS_KEY);\n if (!stored) return [];\n return decodeIndices(stored);\n }\n\n async function setDerivedIndices(indices: number[]): Promise<void> {\n await storage.put(DERIVED_ACCOUNTS_KEY, encodeIndices(indices));\n }\n\n async function loadAccount(index: number): Promise<Account | null> {\n const stored = await storage.get(accountKey(index));\n if (!stored) return null;\n return deserializeAccountRecord(stored);\n }\n\n async function persistAccount(\n index: number,\n account: Account,\n ): Promise<void> {\n await storage.put(accountKey(index), serializeAccountRecord(account));\n }\n\n async function list(): Promise<AccountInfo[]> {\n const indices = await getDerivedIndices();\n const accounts: AccountInfo[] = [];\n\n for (const index of indices) {\n const account = await loadAccount(index);\n if (account) {\n accounts.push({\n index,\n masterPublicKey: account.masterPublicKey,\n address: account.address,\n });\n }\n }\n\n return accounts;\n }\n\n async function get(index: number): Promise<Account | null> {\n const indices = await getDerivedIndices();\n if (!indices.includes(index)) return null;\n return loadAccount(index);\n }\n\n async function create(index?: number): Promise<Account> {\n const indices = await getDerivedIndices();\n\n // Determine the index to use\n let targetIndex: number;\n if (index !== undefined) {\n if (indices.includes(index)) {\n throw new ValidationError(`Account at index ${index} already exists`);\n }\n targetIndex = index;\n } else {\n // Use next available index\n targetIndex = indices.length > 0 ? Math.max(...indices) + 1 : 0;\n }\n\n // Derive the account\n const masterSeed = await getMasterSeed();\n const account = deriveAccount(masterSeed, targetIndex);\n\n // Persist the account (storage handles buffer isolation)\n await persistAccount(targetIndex, account);\n\n // Update the indices list\n const newIndices = [...indices, targetIndex].sort((a, b) => a - b);\n await setDerivedIndices(newIndices);\n\n // If this is the first account, set it as active\n if (indices.length === 0) {\n await setActive(targetIndex);\n }\n\n return account;\n }\n\n async function getActiveIndex(): Promise<number | null> {\n const stored = await storage.get(ACTIVE_ACCOUNT_INDEX_KEY);\n if (!stored) return null;\n return decodeIndex(stored);\n }\n\n async function getActive(): Promise<Account | null> {\n const activeIndex = await getActiveIndex();\n if (activeIndex === null) return null;\n return loadAccount(activeIndex);\n }\n\n async function setActive(index: number): Promise<void> {\n const indices = await getDerivedIndices();\n if (!indices.includes(index)) {\n throw new ValidationError(\n `Cannot set active: account at index ${index} does not exist`,\n );\n }\n await storage.put(ACTIVE_ACCOUNT_INDEX_KEY, encodeIndex(index));\n }\n\n return {\n list,\n get,\n create,\n getActive,\n getActiveIndex,\n setActive,\n };\n}\n","import { ValidationError } from \"../errors.js\";\nimport type { Storage } from \"../types.js\";\nimport {\n generateMasterSeed,\n importMasterMnemonic,\n loadMasterMnemonic,\n loadMasterSeed,\n MASTER_MNEMONIC_KEY,\n MASTER_SEED_KEY,\n type MasterSeedCrypto,\n} from \"./account.js\";\nimport {\n ACCOUNT_KEY_PREFIX,\n ACTIVE_ACCOUNT_INDEX_KEY,\n DERIVED_ACCOUNTS_KEY,\n} from \"./accounts.js\";\n\nexport type SeedServiceDeps = {\n storage: Storage;\n rng: (n: number) => Uint8Array;\n crypto?: MasterSeedCrypto;\n};\n\nexport type SeedService = {\n /**\n * Check if a wallet exists (has mnemonic stored).\n */\n exists(): Promise<boolean>;\n\n /**\n * Create a new wallet. Generates a BIP-39 mnemonic and derives the master seed.\n * Returns the mnemonic so the user can back it up.\n * @throws If a wallet already exists (use import with overwrite instead)\n */\n create(): Promise<{ mnemonic: string }>;\n\n /**\n * Import an existing BIP-39 mnemonic.\n * @throws If the mnemonic is invalid\n * @throws If a wallet already exists and overwrite is false\n */\n importMnemonic(\n mnemonic: string,\n opts?: { overwrite?: boolean },\n ): Promise<void>;\n\n /**\n * Export the stored mnemonic for backup.\n * @throws If no wallet exists\n */\n exportMnemonic(): Promise<string>;\n\n /**\n * Get the master seed (for account derivation).\n * @throws If no wallet exists\n */\n getMasterSeed(): Promise<Uint8Array>;\n\n /**\n * Delete all wallet data. This is destructive and cannot be undone.\n */\n delete(): Promise<void>;\n};\n\nexport function createSeedService(deps: SeedServiceDeps): SeedService {\n const { storage, rng, crypto } = deps;\n\n async function exists(): Promise<boolean> {\n const mnemonic = await loadMasterMnemonic(storage, crypto);\n return mnemonic !== null;\n }\n\n async function create(): Promise<{ mnemonic: string }> {\n // Check if wallet already exists\n const walletExists = await exists();\n if (walletExists) {\n throw new ValidationError(\n \"Wallet already exists. Use import with overwrite option to replace it.\",\n );\n }\n\n // Generate new mnemonic and seed\n await generateMasterSeed({\n storage,\n rng,\n crypto,\n mnemonicPassphrase: \"\",\n overwrite: false,\n });\n\n // Load and return the mnemonic so user can back it up\n const mnemonic = await loadMasterMnemonic(storage, crypto);\n if (!mnemonic) {\n throw new ValidationError(\"Failed to create wallet: mnemonic not stored\");\n }\n\n return { mnemonic };\n }\n\n async function importMnemonic(\n mnemonic: string,\n opts?: { overwrite?: boolean },\n ): Promise<void> {\n const overwrite = opts?.overwrite ?? false;\n\n // Check if wallet already exists\n if (!overwrite) {\n const walletExists = await exists();\n if (walletExists) {\n throw new ValidationError(\n \"Wallet already exists. Use overwrite option to replace it.\",\n );\n }\n }\n\n // Import the mnemonic first\n await importMasterMnemonic({\n storage,\n mnemonic,\n crypto,\n overwrite,\n password: \"\",\n });\n\n // Clear account data after successful import to avoid data loss on failure\n if (overwrite) {\n await clearAccountData();\n }\n }\n\n async function exportMnemonic(): Promise<string> {\n const mnemonic = await loadMasterMnemonic(storage, crypto);\n if (!mnemonic) {\n throw new ValidationError(\n \"No wallet exists. Create or import a wallet first.\",\n );\n }\n return mnemonic;\n }\n\n async function getMasterSeed(): Promise<Uint8Array> {\n const seed = await loadMasterSeed(storage, crypto);\n if (!seed) {\n throw new ValidationError(\n \"No wallet exists. Create or import a wallet first.\",\n );\n }\n return seed;\n }\n\n async function clearAccountData(): Promise<void> {\n // Delete all account records by prefix\n const accountRecords = await storage.iter({ prefix: ACCOUNT_KEY_PREFIX });\n for (const { key } of accountRecords) {\n await storage.delete(key);\n }\n // Clear metadata keys\n await storage.delete(DERIVED_ACCOUNTS_KEY);\n await storage.delete(ACTIVE_ACCOUNT_INDEX_KEY);\n }\n\n async function deleteWallet(): Promise<void> {\n // Clear all wallet data\n await storage.delete(MASTER_MNEMONIC_KEY);\n await storage.delete(MASTER_SEED_KEY);\n await clearAccountData();\n }\n\n return {\n exists,\n create,\n importMnemonic,\n exportMnemonic,\n getMasterSeed,\n delete: deleteWallet,\n };\n}\n","import type { Account, AccountView, Signer } from \"../account/account.js\";\nimport { formatUint256 } from \"../account/serialization.js\";\nimport type { createBroadcasterClient } from \"../clients/broadcaster.js\";\nimport { poseidon } from \"../crypto/adapters/index.js\";\nimport { AdapterError } from \"../errors.js\";\nimport { DEFAULT_JOB_TIMEOUT_MS } from \"../state/store/jobs.js\";\nimport { encodeAdapterExecute } from \"../transactions/adapter.js\";\nimport {\n computeAdapterDataHash,\n transact,\n type AdapterExecutionCall,\n type AdapterExecutionReshield,\n} from \"../transactions/transact.js\";\nimport type {\n ServiceOptions,\n TransactRelayResult,\n TransactStateStore,\n} from \"../transactions/types/index.js\";\nimport { planWithdrawals } from \"../transactions/withdrawal-planner.js\";\nimport { generateRelayId, randomBigint } from \"../utils/random.js\";\nimport {\n ensureAddress,\n ensureChainId,\n SNARK_SCALAR_FIELD,\n} from \"../utils/validators.js\";\nimport type {\n AdapterExecuteResult,\n InputTokenSpec,\n ReshieldInput,\n SignerOverride,\n WalletAdapterAPI,\n WalletAdapterExecuteParams,\n} from \"./types.js\";\n\nconst DEFAULT_DEADLINE_WINDOW_SECONDS = 600n;\nconst HEX_DATA_REGEX = /^0x[0-9a-fA-F]*$/;\n\ntype BroadcasterClient = Pick<\n ReturnType<typeof createBroadcasterClient>,\n \"submitRelay\"\n>;\n\ntype NormalizedInputTokenSpec = {\n token: `0x${string}`;\n amount: bigint;\n};\n\nexport type AdapterServiceDeps = {\n stateStore: TransactStateStore;\n txOpts: ServiceOptions;\n broadcasterClient: BroadcasterClient;\n requireActiveAccount: () => Promise<Account>;\n requireSigner: (account: AccountView) => Signer;\n planWithdrawalsFn?: typeof planWithdrawals;\n transactFn?: typeof transact;\n randomBigintFn?: () => bigint;\n nowFn?: () => number;\n};\n\nfunction ensureHexData(label: string, value: string): string {\n if (\n typeof value !== \"string\" ||\n !HEX_DATA_REGEX.test(value) ||\n value.length % 2 !== 0\n ) {\n throw new AdapterError(`${label} must be 0x-prefixed even-length hex data`);\n }\n return value;\n}\n\nfunction normalizeCall(\n call: AdapterExecutionCall,\n index: number,\n): AdapterExecutionCall {\n const to = ensureAddress(`calls[${index}].to`, call.to);\n const data = ensureHexData(`calls[${index}].data`, call.data);\n if (call.value < 0n) {\n throw new AdapterError(`calls[${index}].value must be non-negative`);\n }\n\n return {\n to,\n data,\n value: call.value,\n };\n}\n\nfunction normalizeInputSpec(\n input: InputTokenSpec,\n index: number,\n): NormalizedInputTokenSpec {\n const token = ensureAddress(`inputs[${index}].token`, input.token);\n if (input.amount <= 0n) {\n throw new AdapterError(`inputs[${index}].amount must be greater than zero`);\n }\n\n return {\n token,\n amount: input.amount,\n };\n}\n\nfunction normalizeReshieldSpec(\n reshield: ReshieldInput,\n index: number,\n): ReshieldInput {\n const token = ensureAddress(`reshields[${index}].token`, reshield.token);\n if (reshield.minAmount < 0n) {\n throw new AdapterError(\n `reshields[${index}].minAmount must be non-negative`,\n );\n }\n\n return {\n token,\n minAmount: reshield.minAmount,\n };\n}\n\nfunction randomFieldElement(randomBigintFn: () => bigint): bigint {\n const value = randomBigintFn() % SNARK_SCALAR_FIELD;\n return value < 0n ? value + SNARK_SCALAR_FIELD : value;\n}\n\nexport function createAdapterService(\n deps: AdapterServiceDeps,\n): WalletAdapterAPI {\n const planWithdrawalsImpl = deps.planWithdrawalsFn ?? planWithdrawals;\n const transactImpl = deps.transactFn ?? transact;\n const randomBigintImpl = deps.randomBigintFn ?? randomBigint;\n const nowImpl = deps.nowFn ?? Date.now;\n\n return {\n async execute(\n params: WalletAdapterExecuteParams,\n opts?: { skipBroadcast?: boolean },\n overrides?: SignerOverride,\n ): Promise<AdapterExecuteResult> {\n ensureChainId(params.chainId);\n const poolAddress = ensureAddress(\"poolAddress\", params.poolAddress);\n const adapterAddress = ensureAddress(\n \"adapterAddress\",\n params.adapterAddress,\n );\n\n if (!params.inputs.length) {\n throw new AdapterError(\"at least one input token is required\");\n }\n if (!params.calls.length) {\n throw new AdapterError(\"at least one adapter call is required\");\n }\n if (!params.reshields.length) {\n throw new AdapterError(\"at least one reshield output is required\");\n }\n\n const inputs = params.inputs.map((input, i) =>\n normalizeInputSpec(input, i),\n );\n\n const seenTokens = new Set<string>();\n for (const input of inputs) {\n const lower = input.token.toLowerCase();\n if (seenTokens.has(lower)) {\n throw new AdapterError(\n `duplicate input token ${input.token}; combine amounts per token instead`,\n );\n }\n seenTokens.add(lower);\n }\n\n const calls = params.calls.map((call, i) => normalizeCall(call, i));\n const reshieldSpecs = params.reshields.map((reshield, i) =>\n normalizeReshieldSpec(reshield, i),\n );\n\n const account = overrides?.account ?? (await deps.requireActiveAccount());\n const signer = overrides?.signer ?? deps.requireSigner(account);\n const nowSeconds = BigInt(Math.floor(nowImpl() / 1000));\n const deadline =\n params.deadline ?? nowSeconds + DEFAULT_DEADLINE_WINDOW_SECONDS;\n if (deadline <= nowSeconds) {\n throw new AdapterError(\"deadline must be in the future\");\n }\n\n const executionCalls = calls;\n\n const reshields: AdapterExecutionReshield[] = reshieldSpecs.map(\n (reshield) => {\n const random = randomFieldElement(randomBigintImpl);\n const npk = poseidon([account.masterPublicKey, random]);\n return {\n npk,\n random,\n token: reshield.token,\n minAmount: reshield.minAmount,\n };\n },\n );\n\n const inputTokens = inputs.map((input) => input.token);\n const nonce = randomFieldElement(randomBigintImpl);\n const adapterDataHash = computeAdapterDataHash({\n calls: executionCalls,\n reshields,\n inputTokens,\n nonce,\n deadline,\n chainId: params.chainId,\n });\n\n const notes = await deps.stateStore.listNotes({\n chainId: params.chainId,\n mpk: formatUint256(account.masterPublicKey),\n includeSpent: false,\n });\n\n const withdrawalPlans = planWithdrawalsImpl(\n notes,\n inputs.map((input) => ({\n token: input.token,\n amount: input.amount,\n recipient: adapterAddress,\n })),\n account.masterPublicKey,\n account.viewingKeyPair.pubkey,\n );\n\n const transactResult: TransactRelayResult = await transactImpl(\n deps.stateStore,\n {\n account,\n signer,\n chainId: params.chainId,\n poolAddress,\n transactions: withdrawalPlans.map((plan) => ({\n token: plan.token,\n inputs: plan.inputs.map((note) => ({ index: note.index })),\n outputs: plan.outputNotes,\n withdrawal: plan.withdrawal,\n adapterDataHash,\n })),\n },\n {\n ...deps.txOpts,\n skipBroadcast: true,\n persistJob: false,\n },\n );\n\n const adapterCalldata = encodeAdapterExecute({\n transactCalldata: transactResult.calldata,\n calls: executionCalls,\n reshields,\n inputTokens,\n nonce,\n deadline,\n });\n\n if (opts?.skipBroadcast) {\n return {\n relayId: transactResult.relayId,\n adapterCalldata,\n transactCalldata: transactResult.calldata,\n transactResult,\n reshields,\n };\n }\n\n const relayId = generateRelayId(\"adapter\");\n const submission = await deps.broadcasterClient.submitRelay({\n clientTxId: relayId,\n chainId: params.chainId,\n payload: {\n kind: \"call_data\",\n to: adapterAddress,\n data: adapterCalldata,\n },\n });\n\n if (!submission.accepted) {\n throw new AdapterError(submission.message ?? \"broadcaster rejected\");\n }\n\n await deps.stateStore.putJob({\n relayId,\n kind: \"adapter\",\n chainId: params.chainId,\n mpk: formatUint256(account.masterPublicKey),\n status: \"broadcasting\",\n txHash: null,\n createdAt: nowImpl(),\n timeoutMs: DEFAULT_JOB_TIMEOUT_MS,\n poolAddress,\n calldata: transactResult.calldata,\n transactions: withdrawalPlans.map((plan, i) => ({\n token: plan.token,\n nullifiers: transactResult.transactions[i]?.nullifiers ?? [],\n predictedCommitments: (\n transactResult.transactions[i]?.predictedCommitments ?? []\n ).map((hex) => ({ hex })),\n withdrawal: {\n amount: plan.withdrawal.amount.toString(),\n recipient: adapterAddress,\n },\n })),\n adapterAddress,\n adapterCalldata,\n historyPreview: {\n kind: \"Withdraw\",\n amounts: inputs.map((input) => ({\n token: input.token,\n delta: (-input.amount).toString(),\n })),\n },\n });\n\n return {\n relayId,\n adapterCalldata,\n transactCalldata: transactResult.calldata,\n transactResult,\n reshields,\n };\n },\n };\n}\n","import {\n Contract,\n HDNodeWallet,\n Interface,\n JsonRpcProvider,\n Wallet,\n} from \"ethers\";\nimport type { TransactionResponse } from \"ethers\";\n\nimport { zeroize } from \"../../crypto/secure-memory.js\";\nimport type { WithdrawResult } from \"../types.js\";\nimport type {\n BurnerAccount,\n BurnerAPI,\n BurnerFundParams,\n BurnerSendParams,\n BurnerSweepToPoolParams,\n} from \"./types.js\";\n\n/** Standard BIP-44 path prefix for Ethereum (MetaMask-compatible) */\nconst BIP44_ETH_PREFIX = \"m/44'/60'/0'/0\";\n\nexport type BurnerServiceDeps = {\n chainRpcUrl: string;\n getMasterSeed: () => Promise<Uint8Array>;\n /** Withdraw from shielded pool to fund a burner address */\n withdrawToAddress: (params: {\n chainId: number;\n poolAddress: string;\n withdrawals: Array<{ token: string; amount: bigint; recipient: string }>;\n }) => Promise<WithdrawResult>;\n /** Build a deposit calldata to sweep tokens back into the pool */\n requestDeposit: (params: {\n chainId: number;\n poolAddress: string;\n depositor: string;\n deposits: Array<{ token: string; amount: bigint }>;\n }) => Promise<{ to: string; calldata: string }>;\n};\n\nexport type BurnerService = BurnerAPI;\n\n// Minimal ERC-20 ABI for balance checking\nconst ERC20_BALANCE_OF = \"function balanceOf(address) view returns (uint256)\";\n\nexport function createBurnerService(deps: BurnerServiceDeps): BurnerService {\n const { chainRpcUrl, getMasterSeed, withdrawToAddress, requestDeposit } =\n deps;\n const provider = new JsonRpcProvider(chainRpcUrl);\n\n // In-memory caches\n const wallets = new Map<number, Wallet>();\n const nonces = new Map<string, number>();\n\n async function getWallet(index: number): Promise<Wallet> {\n if (!Number.isInteger(index) || index < 0) {\n throw new Error(`Invalid burner index: ${index}`);\n }\n const cached = wallets.get(index);\n if (cached) return cached;\n\n const seed = await getMasterSeed();\n try {\n const hd = HDNodeWallet.fromSeed(seed);\n const derived = hd.derivePath(`${BIP44_ETH_PREFIX}/${index}`);\n const wallet = new Wallet(derived.privateKey, provider);\n\n wallets.set(index, wallet);\n return wallet;\n } finally {\n zeroize(seed);\n }\n }\n\n // --- Public API ---\n\n async function addressOf(index: number): Promise<BurnerAccount> {\n const wallet = await getWallet(index);\n return { address: wallet.address, index };\n }\n\n async function send(\n index: number,\n tx: BurnerSendParams,\n ): Promise<{ txHash: string }> {\n const wallet = await getWallet(index);\n const addrLower = wallet.address.toLowerCase();\n\n // Use locally tracked nonce to avoid stale provider cache\n const nonce =\n nonces.get(addrLower) ??\n (await provider.getTransactionCount(wallet.address));\n\n const response: TransactionResponse = await wallet.sendTransaction({\n to: tx.to,\n data: tx.data,\n value: tx.value,\n gasLimit: tx.gasLimit,\n nonce,\n });\n\n // Increment immediately after submission — a submitted tx consumes the\n // nonce on-chain whether it succeeds or reverts. If sendTransaction itself\n // throws (network error, gas estimation), we never reach here so the nonce\n // stays unchanged.\n nonces.set(addrLower, nonce + 1);\n\n await response.wait();\n return { txHash: response.hash };\n }\n\n async function exportKey(index: number): Promise<string> {\n const wallet = await getWallet(index);\n return wallet.privateKey;\n }\n\n async function getTokenBalance(\n address: string,\n token: string,\n ): Promise<bigint> {\n const iface = new Interface([ERC20_BALANCE_OF]);\n const contract = new Contract(token, iface, provider);\n const bal = await contract.getFunction(\"balanceOf\")(address);\n return BigInt(bal ?? 0);\n }\n\n async function getBalance(address: string): Promise<bigint> {\n const bal = await provider.getBalance(address);\n return BigInt(bal ?? 0);\n }\n\n async function fund(\n index: number,\n params: BurnerFundParams,\n ): Promise<WithdrawResult> {\n const { address } = await addressOf(index);\n return withdrawToAddress({\n chainId: params.chainId,\n poolAddress: params.poolAddress,\n withdrawals: [\n { token: params.token, amount: params.amount, recipient: address },\n ],\n });\n }\n\n async function sweepToPool(\n index: number,\n params: BurnerSweepToPoolParams,\n ): Promise<{ txHash: string }> {\n const { address } = await addressOf(index);\n\n // Resolve amount (full balance if omitted)\n const amount =\n params.amount ?? (await getTokenBalance(address, params.token));\n if (amount === 0n) {\n throw new Error(\"No token balance to sweep\");\n }\n\n // Build deposit calldata\n const depositResult = await requestDeposit({\n chainId: params.chainId,\n poolAddress: params.poolAddress,\n depositor: address,\n deposits: [{ token: params.token, amount }],\n });\n\n // Approve pool to spend tokens\n const erc20Iface = new Interface([\n \"function approve(address spender, uint256 amount)\",\n ]);\n const approveData = erc20Iface.encodeFunctionData(\"approve\", [\n params.poolAddress,\n amount,\n ]);\n await send(index, { to: params.token, data: approveData });\n\n // Execute deposit tx from burner\n const { txHash } = await send(index, {\n to: depositResult.to,\n data: depositResult.calldata,\n });\n\n return { txHash };\n }\n\n return {\n addressOf,\n send,\n exportKey,\n getTokenBalance,\n getBalance,\n fund,\n sweepToPool,\n };\n}\n","import {\n createSingleKeySigner,\n deriveAccount,\n type Account,\n type AccountView,\n} from \"../account/account.js\";\nimport {\n createAccountsService,\n type AccountsService,\n} from \"../account/accounts.js\";\nimport { createSeedService, type SeedService } from \"../account/seed.js\";\nimport { formatUint256 } from \"../account/serialization.js\";\nimport {\n createBroadcasterClient,\n type RelayState,\n type RelayStatusResponse,\n} from \"../clients/broadcaster.js\";\nimport { createIndexerClient } from \"../clients/indexer.js\";\nimport {\n createServiceConfig,\n fetchEnvironmentConfig,\n type Environment,\n} from \"../config.js\";\nimport { initCore } from \"../core.js\";\nimport { InitializationError } from \"../errors.js\";\nimport { createHistoryService } from \"../history/service.js\";\nimport { createMerkleTrees } from \"../state/merkle/index.js\";\nimport type { NoteRecord } from \"../state/store/records.js\";\nimport { createStateStore } from \"../state/store/store.js\";\nimport { createIndexedDbStorage } from \"../storage/indexeddb.js\";\nimport {\n createJobReconciler,\n createNoteSyncService,\n deposit,\n planTransfers,\n planWithdrawals,\n syncDeposit,\n syncTransact,\n transact,\n type DepositSyncResult,\n type NoteInput,\n type ServiceOptions,\n type TransactSyncResult,\n type WithdrawalNoteInput,\n} from \"../transactions/index.js\";\nimport { computeBalances } from \"../utils/notes.js\";\nimport { ensureChainId, parseZkAddress } from \"../utils/validators.js\";\nimport { createAdapterService } from \"./adapter.js\";\nimport { createBurnerService, type BurnerService } from \"./burner/service.js\";\nimport type {\n AccountInfo,\n BurnerAccount,\n BurnerFundParams,\n BurnerSendParams,\n BurnerSweepToPoolParams,\n SignerOverride,\n TransferParams,\n TransferPlanResult,\n TransferResult,\n TxStatusChangedEvent,\n WalletDepositParams,\n WalletDepositResult,\n WalletDeps,\n WalletNoteInsert,\n WalletSDK,\n WalletSDKEvent,\n WithdrawParams,\n WithdrawPlanResult,\n WithdrawResult,\n} from \"./types.js\";\n\nconst DEFAULT_SYNC_INTERVAL_MS = 5_000;\n\nfunction resolveWalletProverConfig(\n prover?: ServiceOptions[\"prover\"],\n): ServiceOptions[\"prover\"] {\n if (prover !== undefined) {\n return prover;\n }\n\n if (typeof process !== \"undefined\" && process.versions?.node) {\n const envVersion = (process.env.UNLINK_ARTIFACT_VERSION ?? \"\")\n .trim()\n .replace(/^\\/+|\\/+$/g, \"\");\n const envBaseUrl = (process.env.UNLINK_ARTIFACT_BASE_URL ?? \"\")\n .trim()\n .replace(/\\/+$/, \"\");\n\n // Node defaults to local-first only when no pinned env version is configured.\n // If a pinned version is present, prefer remote-first to avoid silently using stale local artifacts.\n return {\n artifactSource: {\n ...(envVersion.length === 0 ? { preferLocalFiles: true } : {}),\n ...(envBaseUrl.length > 0 ? { baseUrl: envBaseUrl } : {}),\n ...(envVersion.length > 0 ? { version: envVersion } : {}),\n },\n };\n }\n\n return undefined;\n}\n\nfunction createEventBus() {\n const listeners = new Set<(event: WalletSDKEvent) => void>();\n return {\n on(fn: (event: WalletSDKEvent) => void) {\n listeners.add(fn);\n return () => listeners.delete(fn);\n },\n emit(event: WalletSDKEvent) {\n listeners.forEach((fn) => {\n try {\n fn(event);\n } catch (err) {\n console.error(\"[sdk] event handler failed\", err);\n }\n });\n },\n };\n}\n\nfunction createSyncScheduler(\n run: () => Promise<void>,\n onError?: (err: unknown) => void,\n) {\n let timer: ReturnType<typeof setInterval> | null = null;\n let running = false;\n\n const tick = async () => {\n if (running) return;\n running = true;\n try {\n await run();\n } catch (err) {\n console.error(\"[sdk] auto-sync failed\", err);\n onError?.(err);\n } finally {\n running = false;\n }\n };\n\n return {\n start(intervalMs = DEFAULT_SYNC_INTERVAL_MS) {\n if (timer) return;\n timer = setInterval(tick, intervalMs);\n void tick();\n },\n stop() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n },\n };\n}\n\nconst TERMINAL_TX_STATES: readonly RelayState[] = [\n \"succeeded\",\n \"reverted\",\n \"failed\",\n \"dead\",\n];\n\nconst TX_POLL_INTERVAL_MS = 2_000;\n\ntype TrackedTx = {\n state: RelayState | null;\n txHash?: string;\n blockNumber?: number;\n error?: string;\n};\n\nfunction createTxTracker(\n broadcasterClient: ReturnType<typeof createBroadcasterClient>,\n emit: (event: TxStatusChangedEvent) => void,\n) {\n const tracked = new Map<string, TrackedTx>();\n let timer: ReturnType<typeof setInterval> | null = null;\n let polling = false;\n\n const pollTracked = async () => {\n if (polling || tracked.size === 0) return;\n polling = true;\n\n try {\n const txIds = [...tracked.keys()];\n const responses = await broadcasterClient.getRelayStatusBatch(txIds);\n const responseMap = new Map(responses.map((r) => [r.id, r]));\n\n for (const txId of txIds) {\n const prev = tracked.get(txId);\n if (!prev) continue;\n\n const response = responseMap.get(txId);\n if (!response) continue;\n\n const newState = response.state;\n if (prev.state !== newState) {\n emit({\n type: \"tx-status-changed\",\n txId,\n state: newState,\n previousState: prev.state,\n txHash: response.txHash ?? undefined,\n blockNumber: response.receipt?.blockNumber,\n error: response.error ?? undefined,\n });\n\n tracked.set(txId, {\n state: newState,\n txHash: response.txHash ?? undefined,\n blockNumber: response.receipt?.blockNumber,\n error: response.error ?? undefined,\n });\n\n if (TERMINAL_TX_STATES.includes(newState)) {\n tracked.delete(txId);\n }\n }\n }\n } catch (err) {\n console.error(\"[sdk] failed to poll tx status batch:\", err);\n } finally {\n polling = false;\n }\n\n // Stop timer if nothing left to track\n if (tracked.size === 0 && timer) {\n clearInterval(timer);\n timer = null;\n }\n };\n\n const ensureTimer = () => {\n if (!timer && tracked.size > 0) {\n timer = setInterval(pollTracked, TX_POLL_INTERVAL_MS);\n // Immediate first poll\n void pollTracked();\n }\n };\n\n return {\n track(txId: string) {\n if (!txId?.trim()) return;\n if (!tracked.has(txId)) {\n tracked.set(txId, { state: null });\n ensureTimer();\n }\n },\n untrack(txId: string) {\n tracked.delete(txId);\n if (tracked.size === 0 && timer) {\n clearInterval(timer);\n timer = null;\n }\n },\n stop() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n tracked.clear();\n },\n };\n}\n\n/**\n * @internal Use {@link UnlinkWallet.create} instead.\n */\nexport function createWalletSDK(\n deps: WalletDeps,\n options: {\n chainId?: number;\n /** Gateway URL for relayed transactions (indexer, broadcaster) */\n gatewayUrl: string;\n /** Direct chain RPC for burner EOA transactions. Defaults to gatewayUrl. */\n chainRpcUrl?: string;\n prover?: ServiceOptions[\"prover\"];\n /** Disable auto-sync scheduler (default: true). Set false for CLI/script usage. */\n autoSync?: boolean;\n },\n): WalletSDK {\n if (!deps || deps.core === undefined || deps.core === null) {\n throw new InitializationError(\"core dependency is required\");\n }\n if (!deps.fetch) {\n throw new InitializationError(\"fetch dependency is required\");\n }\n if (!options?.gatewayUrl) {\n throw new InitializationError(\"gatewayUrl is required\");\n }\n\n const fetchImpl = deps.fetch;\n const { storage, rng } = deps.core;\n const stateStore = createStateStore(storage);\n const merkleTrees = createMerkleTrees();\n const serviceConfig = createServiceConfig(options.gatewayUrl);\n\n // Shared options for transaction operations\n const txOpts: ServiceOptions = {\n fetch: fetchImpl,\n merkleTrees,\n gatewayUrl: options.gatewayUrl,\n prover: resolveWalletProverConfig(options.prover),\n };\n\n const indexerClient = createIndexerClient(serviceConfig.indexerBaseUrl, {\n fetch: fetchImpl,\n });\n const broadcasterClient = createBroadcasterClient(\n serviceConfig.broadcasterBaseUrl,\n { fetch: fetchImpl },\n );\n const syncService = createNoteSyncService(stateStore, {\n merkleTrees,\n indexerClient,\n fetch: fetchImpl,\n });\n const historyService = createHistoryService(stateStore);\n const events = createEventBus();\n const txTracker = createTxTracker(broadcasterClient, events.emit);\n const reconciler = createJobReconciler({\n stateStore,\n depositClient: {\n syncPendingDeposit: (relayId: string) =>\n syncDeposit(stateStore, relayId, txOpts),\n },\n transactService: {\n syncPendingTransact: (relayId: string) =>\n syncTransact(stateStore, relayId, txOpts),\n },\n });\n const seedService: SeedService = createSeedService({\n storage,\n rng,\n });\n const accountsService: AccountsService = createAccountsService({\n storage,\n deriveAccount,\n getMasterSeed: () => seedService.getMasterSeed(),\n });\n const chainRpcUrl = options.chainRpcUrl ?? options.gatewayUrl;\n\n const configuredChainId = options?.chainId ?? null;\n const scheduler = createSyncScheduler(\n async () => {\n if (!configuredChainId) {\n console.warn(\"[sdk] no chain id configured; skipping auto-sync\");\n return;\n }\n\n // Check if wallet and account exist before syncing\n const walletExists = await seedService.exists();\n if (!walletExists) {\n // No wallet yet, skip sync\n return;\n }\n\n const account = await accountsService.getActive();\n if (!account) {\n // No active account, skip sync\n return;\n }\n\n const mpk = formatUint256(account.masterPublicKey);\n console.log(\"[sdk] auto-syncing chain\", configuredChainId);\n await syncService.syncChains([configuredChainId], account);\n await reconciler.reconcileAll();\n await historyService.rebuildHistory({ chainId: configuredChainId, mpk });\n events.emit({ type: \"notes-updated\", chainId: configuredChainId });\n },\n (err) => {\n events.emit({\n type: \"sync-error\",\n error: err instanceof Error ? err.message : String(err),\n });\n },\n );\n\n // Helper to get active account or throw\n async function requireActiveAccount(): Promise<Account> {\n const account = await accountsService.getActive();\n if (!account) {\n throw new Error(\"No active account. Create an account first.\");\n }\n return account;\n }\n\n function requireSigner(\n acct: AccountView,\n ): ReturnType<typeof createSingleKeySigner> {\n if (!(\"spendingKeyPair\" in acct)) {\n throw new Error(\n \"No signer: account has no spending key and no SignerOverride was provided\",\n );\n }\n const { spendingKeyPair } = acct as Account;\n return createSingleKeySigner(\n spendingKeyPair.privateKey,\n spendingKeyPair.pubkey,\n );\n }\n\n const adapterService = createAdapterService({\n stateStore,\n txOpts,\n broadcasterClient,\n requireActiveAccount,\n requireSigner,\n });\n\n // Only auto-start scheduler if chain ID is configured and autoSync is not disabled.\n // CLI/scripts set autoSync=false to prevent the scheduler from racing with manual sync.\n if (configuredChainId && options.autoSync !== false) {\n scheduler.start();\n }\n\n // --- Burner plugin (self-contained, easy to remove) ---\n let burnerService: BurnerService | undefined;\n function getBurnerService(): BurnerService {\n if (!burnerService) {\n burnerService = createBurnerService({\n chainRpcUrl,\n getMasterSeed: () => seedService.getMasterSeed(),\n withdrawToAddress: (p) => sdk.withdraw.send(p),\n requestDeposit: (p) => sdk.deposit.request(p),\n });\n }\n return burnerService;\n }\n\n const sdk: WalletSDK = {\n seed: {\n async exists(): Promise<boolean> {\n return seedService.exists();\n },\n async create(): Promise<{ mnemonic: string }> {\n const result = await seedService.create();\n events.emit({ type: \"wallet-created\" });\n return result;\n },\n async importMnemonic(\n mnemonic: string,\n opts?: { overwrite?: boolean },\n ): Promise<void> {\n await seedService.importMnemonic(mnemonic, opts);\n if (opts?.overwrite) {\n burnerService = undefined;\n }\n events.emit({ type: \"wallet-created\" });\n },\n async exportMnemonic(): Promise<string> {\n return seedService.exportMnemonic();\n },\n async delete(): Promise<void> {\n scheduler.stop();\n txTracker.stop();\n burnerService = undefined;\n await seedService.delete();\n },\n },\n accounts: {\n async list(): Promise<AccountInfo[]> {\n return accountsService.list();\n },\n async get(index: number): Promise<Account | null> {\n return accountsService.get(index);\n },\n async create(index?: number): Promise<Account> {\n const account = await accountsService.create(index);\n const accounts = await accountsService.list();\n const createdAccount = accounts.find(\n (a) => a.masterPublicKey === account.masterPublicKey,\n );\n if (!createdAccount) {\n throw new Error(\"Failed to find newly created account\");\n }\n events.emit({\n type: \"account-created\",\n index: createdAccount.index,\n });\n return account;\n },\n async getActive(): Promise<Account | null> {\n return accountsService.getActive();\n },\n async getActiveIndex(): Promise<number | null> {\n return accountsService.getActiveIndex();\n },\n async setActive(index: number): Promise<void> {\n await accountsService.setActive(index);\n events.emit({ type: \"account-switched\", index });\n },\n },\n burner: {\n async addressOf(index: number): Promise<BurnerAccount> {\n return getBurnerService().addressOf(index);\n },\n async send(\n index: number,\n tx: BurnerSendParams,\n ): Promise<{ txHash: string }> {\n return getBurnerService().send(index, tx);\n },\n async exportKey(index: number): Promise<string> {\n return getBurnerService().exportKey(index);\n },\n async fund(\n index: number,\n params: BurnerFundParams,\n ): Promise<WithdrawResult> {\n await requireActiveAccount();\n return getBurnerService().fund(index, params);\n },\n async getTokenBalance(address: string, token: string): Promise<bigint> {\n return getBurnerService().getTokenBalance(address, token);\n },\n async getBalance(address: string): Promise<bigint> {\n return getBurnerService().getBalance(address);\n },\n async sweepToPool(\n index: number,\n params: BurnerSweepToPoolParams,\n ): Promise<{ txHash: string }> {\n await requireActiveAccount();\n return getBurnerService().sweepToPool(index, params);\n },\n },\n adapter: {\n execute: async (params, opts, overrides) =>\n adapterService.execute(params, opts, overrides),\n },\n balances: {\n async list(\n chainId: number,\n overrides?: { account: AccountView },\n ): Promise<Record<string, bigint>> {\n ensureChainId(chainId);\n const account = overrides?.account ?? (await requireActiveAccount());\n const notes = await stateStore.listNotes({\n chainId,\n mpk: formatUint256(account.masterPublicKey),\n includeSpent: false,\n });\n return computeBalances(notes);\n },\n async get(\n chainId: number,\n token: string,\n overrides?: { account: AccountView },\n ): Promise<bigint> {\n const balances = await this.list(chainId, overrides);\n return balances[token.toLowerCase()] ?? 0n;\n },\n },\n deposit: {\n async request(params: WalletDepositParams): Promise<WalletDepositResult> {\n ensureChainId(params.chainId);\n const account = params.account ?? (await requireActiveAccount());\n\n // Generate randoms for each note using configured rng\n const notes = params.deposits.map((d) => {\n const randomBytes = rng(32);\n const random = BigInt(\n \"0x\" +\n [...randomBytes]\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\"),\n );\n return {\n mpk: account.masterPublicKey,\n random,\n token: d.token,\n amount: d.amount,\n viewingPublicKey: account.viewingKeyPair.pubkey,\n };\n });\n\n return deposit(stateStore, {\n account,\n chainId: params.chainId,\n poolAddress: params.poolAddress,\n depositor: params.depositor,\n notes,\n });\n },\n async reconcile(relayId: string): Promise<DepositSyncResult> {\n const result = (await reconciler.reconcileRelay(\n relayId,\n )) as DepositSyncResult;\n const account = await requireActiveAccount();\n await historyService.rebuildHistory({\n chainId: result.chainId,\n mpk: formatUint256(account.masterPublicKey),\n });\n return result;\n },\n },\n history: {\n async list(\n chainId: number,\n options?: { includeSelfSends?: boolean },\n overrides?: { account: AccountView },\n ) {\n ensureChainId(chainId);\n const account = overrides?.account ?? (await requireActiveAccount());\n return historyService.getHistory({\n chainId,\n mpk: formatUint256(account.masterPublicKey),\n includeSelfSends: options?.includeSelfSends,\n });\n },\n },\n notes: {\n async import(note: WalletNoteInsert) {\n ensureChainId(note.chainId);\n const mpk = formatUint256(note.mpk);\n await stateStore.putNote({\n chainId: note.chainId,\n index: note.index,\n token: note.token,\n value: note.amount.toString(),\n commitment: note.commitment,\n npk: formatUint256(note.npk),\n mpk: formatUint256(note.mpk),\n random: formatUint256(note.random),\n nullifier: formatUint256(note.nullifier),\n });\n await historyService.rebuildHistory({ chainId: note.chainId, mpk });\n },\n async list(\n chainId: number,\n overrides?: { account: AccountView },\n ): Promise<NoteRecord[]> {\n ensureChainId(chainId);\n const account = overrides?.account ?? (await requireActiveAccount());\n return stateStore.listNotes({\n chainId,\n mpk: formatUint256(account.masterPublicKey),\n includeSpent: true,\n });\n },\n },\n transact: {\n async transact(\n params: {\n chainId: number;\n poolAddress: string;\n transactions: Array<{\n token: string;\n inputs: Array<{ index: number }>;\n outputs: NoteInput[];\n withdrawal?: WithdrawalNoteInput;\n adapterDataHash?: bigint;\n }>;\n },\n opts?: { skipBroadcast?: boolean },\n overrides?: SignerOverride,\n ) {\n const acct = overrides?.account ?? (await requireActiveAccount());\n const signer = overrides?.signer ?? requireSigner(acct);\n return transact(\n stateStore,\n {\n account: acct,\n signer,\n chainId: params.chainId,\n poolAddress: params.poolAddress,\n transactions: params.transactions,\n },\n { ...txOpts, ...opts },\n );\n },\n reconcile: async (relayId: string) => {\n const result = (await reconciler.reconcileRelay(\n relayId,\n )) as TransactSyncResult;\n const account = await requireActiveAccount();\n await historyService.rebuildHistory({\n chainId: result.chainId,\n mpk: formatUint256(account.masterPublicKey),\n });\n return result;\n },\n },\n transfer: {\n async plan(\n params: TransferParams,\n account?: AccountView,\n ): Promise<TransferPlanResult> {\n ensureChainId(params.chainId);\n\n // Get sender account for change outputs\n const acct = account ?? (await requireActiveAccount());\n\n // Get all unspent notes for the active account\n const notes = await stateStore.listNotes({\n chainId: params.chainId,\n mpk: formatUint256(acct.masterPublicKey),\n includeSpent: false,\n });\n\n // Plan the transfers (handles note tracking across multiple transfers)\n return planTransfers(\n notes,\n params.transfers.map((t) => {\n const parsed = parseZkAddress(t.recipient);\n return {\n token: t.token,\n amount: t.amount,\n recipientMpk: parsed.masterPublicKey,\n recipientViewingPubKey: parsed.viewingPublicKey,\n };\n }),\n acct.masterPublicKey,\n acct.viewingKeyPair.pubkey,\n );\n },\n async execute(\n plans: TransferPlanResult,\n params: Pick<TransferParams, \"chainId\" | \"poolAddress\">,\n overrides?: SignerOverride,\n ): Promise<TransferResult> {\n const acct = overrides?.account ?? (await requireActiveAccount());\n const signer = overrides?.signer ?? requireSigner(acct);\n\n // Build transaction params from individual plans\n const transactions = plans.map((plan) => ({\n token: plan.token,\n inputs: plan.inputs.map((note: NoteRecord) => ({\n index: note.index,\n })),\n outputs: plan.outputNotes,\n }));\n\n // Execute with parallel proof generation\n const transactResult = await transact(\n stateStore,\n {\n account: acct,\n signer,\n chainId: params.chainId,\n poolAddress: params.poolAddress,\n transactions,\n },\n txOpts,\n );\n\n return {\n relayId: transactResult.relayId,\n plans,\n transactResult,\n };\n },\n async send(\n params: TransferParams,\n overrides?: SignerOverride,\n ): Promise<TransferResult> {\n const plans = await this.plan(params, overrides?.account);\n return this.execute(plans, params, overrides);\n },\n },\n withdraw: {\n async plan(\n params: WithdrawParams,\n account?: AccountView,\n ): Promise<WithdrawPlanResult> {\n ensureChainId(params.chainId);\n\n // Get sender account for change outputs\n const acct = account ?? (await requireActiveAccount());\n\n // Get all unspent notes for the active account\n const notes = await stateStore.listNotes({\n chainId: params.chainId,\n mpk: formatUint256(acct.masterPublicKey),\n includeSpent: false,\n });\n\n // Plan the withdrawals (handles note tracking across multiple withdrawals)\n return planWithdrawals(\n notes,\n params.withdrawals.map((w) => ({\n token: w.token,\n amount: w.amount,\n recipient: w.recipient,\n })),\n acct.masterPublicKey,\n acct.viewingKeyPair.pubkey,\n );\n },\n async execute(\n plans: WithdrawPlanResult,\n params: Pick<WithdrawParams, \"chainId\" | \"poolAddress\">,\n overrides?: SignerOverride,\n ): Promise<WithdrawResult> {\n const acct = overrides?.account ?? (await requireActiveAccount());\n const signer = overrides?.signer ?? requireSigner(acct);\n\n // Build transaction params from individual plans\n const transactions = plans.map((plan) => ({\n token: plan.token,\n inputs: plan.inputs.map((note: NoteRecord) => ({\n index: note.index,\n })),\n outputs: plan.outputNotes,\n withdrawal: plan.withdrawal,\n }));\n\n // Execute with parallel proof generation\n const transactResult = await transact(\n stateStore,\n {\n account: acct,\n signer,\n chainId: params.chainId,\n poolAddress: params.poolAddress,\n transactions,\n },\n txOpts,\n );\n\n return {\n relayId: transactResult.relayId,\n plans,\n transactResult,\n };\n },\n async send(\n params: WithdrawParams,\n overrides?: SignerOverride,\n ): Promise<WithdrawResult> {\n const plans = await this.plan(params, overrides?.account);\n return this.execute(plans, params, overrides);\n },\n },\n events: {\n on: (fn: (event: WalletSDKEvent) => void) => events.on(fn),\n },\n sync: {\n async syncChain(\n chainId: number,\n account: AccountView,\n opts?: { forceFullResync?: boolean },\n ) {\n await syncService.syncChain(chainId, account, opts);\n await historyService.rebuildHistory({\n chainId,\n mpk: formatUint256(account.masterPublicKey),\n });\n events.emit({ type: \"notes-updated\", chainId });\n },\n async syncChains(\n chainIds: number[],\n account: AccountView,\n opts?: { forceFullResync?: boolean },\n ) {\n await syncService.syncChains(chainIds, account, opts);\n await Promise.all(\n chainIds.map((chainId) =>\n historyService.rebuildHistory({\n chainId,\n mpk: formatUint256(account.masterPublicKey),\n }),\n ),\n );\n chainIds.forEach((id) =>\n events.emit({ type: \"notes-updated\", chainId: id }),\n );\n },\n async startAutoSync(intervalMs?: number) {\n console.log(\"[sdk] starting auto-sync\");\n scheduler.start(intervalMs);\n },\n stopAutoSync() {\n scheduler.stop();\n },\n },\n tx: {\n async getStatus(txId: string): Promise<RelayStatusResponse> {\n // Broadcaster accepts both relay_id (ULID) and client_tx_id (UUID)\n return broadcasterClient.getRelayStatus(txId);\n },\n track(txId: string): void {\n txTracker.track(txId);\n },\n untrack(txId: string): void {\n txTracker.untrack(txId);\n },\n },\n };\n\n return sdk;\n}\n\n/**\n * Options for createBrowserWalletSDK.\n * Either provide explicit gatewayUrl + poolAddress, or environment to auto-resolve.\n */\nexport type BrowserWalletOptions =\n | {\n chainId?: number;\n gatewayUrl: string;\n poolAddress: string;\n prover?: ServiceOptions[\"prover\"];\n }\n | {\n chainId?: number;\n environment: Environment;\n poolAddress?: string;\n prover?: ServiceOptions[\"prover\"];\n };\n\n/**\n * Result from createBrowserWalletSDK including SDK and resolved config.\n */\nexport type BrowserWalletResult = {\n sdk: WalletSDK;\n config: {\n gatewayUrl: string;\n poolAddress: string;\n artifactVersion?: string;\n artifactBaseUrl?: string;\n };\n};\n\n/**\n * @internal Use {@link UnlinkWallet.create} instead.\n */\nexport async function createBrowserWalletSDK(\n options: BrowserWalletOptions,\n): Promise<BrowserWalletResult> {\n let gatewayUrl: string;\n let poolAddress: string;\n let prover = options.prover;\n\n if (\"gatewayUrl\" in options) {\n // Explicit config provided\n gatewayUrl = options.gatewayUrl;\n poolAddress = options.poolAddress;\n\n if (\n typeof window !== \"undefined\" &&\n !options.prover?.artifactSource?.version\n ) {\n throw new InitializationError(\n \"prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use environment mode or provide a pinned artifact version.\",\n );\n }\n } else {\n // Resolve from environment\n const envConfig = await fetchEnvironmentConfig(options.environment);\n gatewayUrl = envConfig.gatewayUrl;\n poolAddress = options.poolAddress ?? envConfig.poolAddress;\n prover = {\n artifactSource: {\n baseUrl:\n options.prover?.artifactSource?.baseUrl ?? envConfig.artifactBaseUrl,\n version:\n options.prover?.artifactSource?.version ?? envConfig.artifactVersion,\n preferLocalFiles: options.prover?.artifactSource?.preferLocalFiles,\n },\n };\n }\n\n const storage = createIndexedDbStorage({ name: \"unlink-wallet\" });\n const rng = (n: number) => {\n if (!globalThis.crypto?.getRandomValues) {\n throw new Error(\n \"crypto.getRandomValues unavailable; provide rng manually\",\n );\n }\n return globalThis.crypto.getRandomValues(new Uint8Array(n));\n };\n const core = await initCore({ storage, rng });\n const sdk = createWalletSDK(\n {\n core,\n fetch: globalThis.fetch,\n },\n { chainId: options.chainId, gatewayUrl, prover },\n );\n return {\n sdk,\n config: {\n gatewayUrl,\n poolAddress,\n artifactVersion: prover?.artifactSource?.version,\n artifactBaseUrl: prover?.artifactSource?.baseUrl,\n },\n };\n}\n","import type { Account, AccountView } from \"../account/account.js\";\nimport type { RelayStatusResponse } from \"../clients/broadcaster.js\";\nimport { fetchEnvironmentConfig } from \"../config.js\";\nimport { initCore } from \"../core.js\";\nimport { InitializationError } from \"../errors.js\";\nimport type { HistoryEntry } from \"../history/types.js\";\nimport type { NoteRecord } from \"../state/store/records.js\";\nimport { createIndexedDbStorage } from \"../storage/indexeddb.js\";\nimport type {\n DepositRelayResult,\n DepositSyncResult,\n TransactRelayResult,\n TransactSyncResult,\n} from \"../transactions/types/index.js\";\nimport type { Storage } from \"../types.js\";\nimport type { BurnerAccount, BurnerSendParams } from \"./burner/types.js\";\nimport { createWalletSDK } from \"./sdk.js\";\nimport type {\n AdapterExecuteResult,\n SignerOverride,\n SimpleAdapterExecuteParams,\n SimpleBurnerFundParams,\n SimpleBurnerSweepToPoolParams,\n SimpleDepositParams,\n SimpleTransactParams,\n SimpleTransferParams,\n SimpleWithdrawParams,\n TransferPlanResult,\n TransferResult,\n UnlinkWalletConfig,\n WalletAccountAPI,\n WalletSDK,\n WalletSDKEvent,\n WithdrawPlanResult,\n WithdrawResult,\n} from \"./types.js\";\n\n/**\n * High-level wallet API that bakes `chainId` and `poolAddress` at construction time.\n *\n * Replaces `createWalletSDK` / `createBrowserWalletSDK` with a single entry point\n * that absorbs initialization (storage, rng, core migration, environment resolution).\n *\n * @example\n * ```ts\n * // Browser (auto-detects IndexedDB + crypto.getRandomValues):\n * const wallet = await UnlinkWallet.create({\n * chainId: 11155111,\n * environment: \"testnet\",\n * });\n *\n * // Node (explicit storage):\n * const wallet = await UnlinkWallet.create({\n * chainId: 1,\n * poolAddress: \"0x...\",\n * gatewayUrl: \"https://...\",\n * storage: createSqliteStorage({ path: \"wallet.db\" }),\n * });\n *\n * // Operations — no chainId/poolAddress needed:\n * await wallet.seed.create();\n * await wallet.accounts.create();\n * await wallet.deposit({ depositor: \"0x...\", deposits: [{ token, amount }] });\n * await wallet.transfer({ transfers: [{ token, recipient, amount }] });\n * await wallet.getBalances();\n * await wallet.sync();\n * ```\n */\nexport class UnlinkWallet {\n /** @internal */\n private readonly sdk: WalletSDK;\n\n /** Chain ID this wallet operates on. */\n readonly chainId: number;\n\n /** Pool contract address this wallet transacts with. */\n readonly poolAddress: string;\n\n private constructor(sdk: WalletSDK, chainId: number, poolAddress: string) {\n this.sdk = sdk;\n this.chainId = chainId;\n this.poolAddress = poolAddress;\n }\n\n /**\n * Create a new UnlinkWallet instance.\n *\n * Handles all initialization internally:\n * - Resolves environment config (if using `environment` instead of explicit URLs)\n * - Auto-detects storage (IndexedDB in browser) and rng (crypto.getRandomValues)\n * - Runs schema migration via `initCore()`\n * - Creates the internal SDK\n */\n static async create(config: UnlinkWalletConfig): Promise<UnlinkWallet> {\n let gatewayUrl: string;\n let poolAddress: string;\n let proverConfig = config.prover;\n\n if (\"gatewayUrl\" in config) {\n gatewayUrl = config.gatewayUrl;\n poolAddress = config.poolAddress;\n\n // Browser mode with explicit URL requires pinned artifact version\n if (\n typeof window !== \"undefined\" &&\n !config.prover?.artifactSource?.version\n ) {\n throw new InitializationError(\n \"prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. \" +\n \"Use environment mode or provide a pinned artifact version.\",\n );\n }\n } else {\n const envConfig = await fetchEnvironmentConfig(config.environment);\n gatewayUrl = envConfig.gatewayUrl;\n poolAddress = config.poolAddress ?? envConfig.poolAddress;\n proverConfig = {\n artifactSource: {\n baseUrl:\n config.prover?.artifactSource?.baseUrl ?? envConfig.artifactBaseUrl,\n version:\n config.prover?.artifactSource?.version ?? envConfig.artifactVersion,\n preferLocalFiles: config.prover?.artifactSource?.preferLocalFiles,\n },\n };\n }\n\n const storage = config.storage ?? detectStorage();\n const rng = config.rng ?? defaultRng;\n const fetchImpl = config.fetch ?? globalThis.fetch;\n\n const core = await initCore({ storage, rng });\n const sdk = createWalletSDK(\n { core, fetch: fetchImpl },\n {\n chainId: config.chainId,\n gatewayUrl,\n chainRpcUrl: config.chainRpcUrl,\n prover: proverConfig,\n autoSync: config.autoSync,\n },\n );\n\n return new UnlinkWallet(sdk, config.chainId, poolAddress);\n }\n\n // ===== Seed Lifecycle =====\n\n /** Seed management (create, import, export, delete mnemonic). */\n get seed(): WalletSDK[\"seed\"] {\n return this.sdk.seed;\n }\n\n // ===== Account Management =====\n\n /** Account management (create, list, switch accounts). */\n get accounts(): WalletAccountAPI {\n return this.sdk.accounts;\n }\n\n // ===== Core Operations =====\n\n /**\n * Request a deposit (1 or more tokens).\n * Returns calldata the depositor must submit on-chain via their EOA.\n */\n async deposit(params: SimpleDepositParams): Promise<DepositRelayResult> {\n return this.sdk.deposit.request({\n chainId: this.chainId,\n poolAddress: this.poolAddress,\n depositor: params.depositor,\n deposits: params.deposits,\n account: params.account,\n });\n }\n\n /** Wait for a deposit to be confirmed on-chain. */\n async confirmDeposit(relayId: string): Promise<DepositSyncResult> {\n return this.sdk.deposit.reconcile(relayId);\n }\n\n /**\n * Execute a private transfer (1 or more recipients).\n * Handles note selection, circuit selection, and proof generation automatically.\n */\n async transfer(\n params: SimpleTransferParams,\n overrides?: SignerOverride,\n ): Promise<TransferResult> {\n return this.sdk.transfer.send(\n {\n chainId: this.chainId,\n poolAddress: this.poolAddress,\n transfers: params.transfers,\n },\n overrides,\n );\n }\n\n /**\n * Get a transfer plan without executing (for preview/confirmation UIs).\n */\n async planTransfer(\n params: SimpleTransferParams,\n account?: AccountView,\n ): Promise<TransferPlanResult> {\n return this.sdk.transfer.plan(\n {\n chainId: this.chainId,\n poolAddress: this.poolAddress,\n transfers: params.transfers,\n },\n account,\n );\n }\n\n /** Execute a pre-built transfer plan. */\n async executeTransfer(\n plans: TransferPlanResult,\n overrides?: SignerOverride,\n ): Promise<TransferResult> {\n return this.sdk.transfer.execute(\n plans,\n { chainId: this.chainId, poolAddress: this.poolAddress },\n overrides,\n );\n }\n\n /**\n * Execute a withdrawal (1 or more recipients).\n * Handles note selection, circuit selection, and proof generation automatically.\n */\n async withdraw(\n params: SimpleWithdrawParams,\n overrides?: SignerOverride,\n ): Promise<WithdrawResult> {\n return this.sdk.withdraw.send(\n {\n chainId: this.chainId,\n poolAddress: this.poolAddress,\n withdrawals: params.withdrawals,\n },\n overrides,\n );\n }\n\n /**\n * Get a withdrawal plan without executing (for preview/confirmation UIs).\n */\n async planWithdraw(\n params: SimpleWithdrawParams,\n account?: AccountView,\n ): Promise<WithdrawPlanResult> {\n return this.sdk.withdraw.plan(\n {\n chainId: this.chainId,\n poolAddress: this.poolAddress,\n withdrawals: params.withdrawals,\n },\n account,\n );\n }\n\n /** Execute a pre-built withdrawal plan. */\n async executeWithdraw(\n plans: WithdrawPlanResult,\n overrides?: SignerOverride,\n ): Promise<WithdrawResult> {\n return this.sdk.withdraw.execute(\n plans,\n { chainId: this.chainId, poolAddress: this.poolAddress },\n overrides,\n );\n }\n\n /** Wait for a transfer or withdrawal to be confirmed on-chain. */\n async confirmTransaction(relayId: string): Promise<TransactSyncResult> {\n return this.sdk.transact.reconcile(relayId);\n }\n\n // ===== Queries =====\n\n /**\n * Get balance for a specific token (defaults to all tokens if no token specified).\n * @param token Token address. If omitted, returns balance for all tokens via getBalances().\n */\n async getBalance(\n token: string,\n overrides?: { account: AccountView },\n ): Promise<bigint> {\n return this.sdk.balances.get(this.chainId, token, overrides);\n }\n\n /** Get balances for all tokens. */\n async getBalances(overrides?: {\n account: AccountView;\n }): Promise<Record<string, bigint>> {\n return this.sdk.balances.list(this.chainId, overrides);\n }\n\n /** Get transaction history. */\n async getHistory(\n options?: { includeSelfSends?: boolean },\n overrides?: { account: AccountView },\n ): Promise<HistoryEntry[]> {\n return this.sdk.history.list(this.chainId, options, overrides);\n }\n\n /** Get UTXO notes for the active account (or override account). */\n async getNotes(overrides?: { account: AccountView }): Promise<NoteRecord[]> {\n return this.sdk.notes.list(this.chainId, overrides);\n }\n\n // ===== Sync =====\n\n /**\n * Sync notes from the blockchain.\n * Automatically resolves the active account (no need to pass it).\n */\n async sync(\n options?: { forceFullResync?: boolean },\n overrides?: { account: AccountView },\n ): Promise<void> {\n const account = overrides?.account ?? (await this.requireActiveAccount());\n return this.sdk.sync.syncChain(this.chainId, account, options);\n }\n\n /** Start auto-sync at the given interval (default: 5000ms). */\n startAutoSync(intervalMs?: number): void {\n void this.sdk.sync.startAutoSync(intervalMs);\n }\n\n /** Stop auto-sync. */\n stopAutoSync(): void {\n this.sdk.sync.stopAutoSync();\n }\n\n // ===== Transaction Status =====\n\n /** Get the current status of a transaction. */\n async getTxStatus(txId: string): Promise<RelayStatusResponse> {\n return this.sdk.tx.getStatus(txId);\n }\n\n /** Start tracking a transaction for status-changed events. */\n trackTx(txId: string): void {\n this.sdk.tx.track(txId);\n }\n\n /** Stop tracking a transaction. */\n untrackTx(txId: string): void {\n this.sdk.tx.untrack(txId);\n }\n\n // ===== Events =====\n\n /**\n * Subscribe to wallet events (notes-updated, sync-error, tx-status-changed, etc.).\n * @returns Unsubscribe function.\n */\n on(listener: (event: WalletSDKEvent) => void): () => void {\n return this.sdk.events.on(listener);\n }\n\n // ===== Burner =====\n\n /**\n * Burner account operations (BIP-44 derived EOAs for DeFi interactions).\n * chainId/poolAddress are injected automatically for fund/sweepToPool.\n */\n readonly burner = {\n /** Derive burner address for a given index. */\n addressOf: (index: number): Promise<BurnerAccount> => {\n return this.sdk.burner.addressOf(index);\n },\n\n /** Send a transaction from burner at index. */\n send: (\n index: number,\n tx: BurnerSendParams,\n ): Promise<{ txHash: string }> => {\n return this.sdk.burner.send(index, tx);\n },\n\n /** Export the raw private key (0x-prefixed hex) for wallet import. */\n exportKey: (index: number): Promise<string> => {\n return this.sdk.burner.exportKey(index);\n },\n\n /** Withdraw from shielded pool to fund this burner. */\n fund: (\n index: number,\n params: SimpleBurnerFundParams,\n ): Promise<WithdrawResult> => {\n return this.sdk.burner.fund(index, {\n chainId: this.chainId,\n poolAddress: this.poolAddress,\n token: params.token,\n amount: params.amount,\n });\n },\n\n /** Approve + deposit tokens from burner back into shielded pool. */\n sweepToPool: (\n index: number,\n params: SimpleBurnerSweepToPoolParams,\n ): Promise<{ txHash: string }> => {\n return this.sdk.burner.sweepToPool(index, {\n chainId: this.chainId,\n poolAddress: this.poolAddress,\n token: params.token,\n amount: params.amount,\n });\n },\n\n /** Get ERC-20 token balance of any address. */\n getTokenBalance: (address: string, token: string): Promise<bigint> => {\n return this.sdk.burner.getTokenBalance(address, token);\n },\n\n /** Get native ETH balance of any address. */\n getBalance: (address: string): Promise<bigint> => {\n return this.sdk.burner.getBalance(address);\n },\n };\n\n // ===== Adapter =====\n\n /**\n * Private DeFi adapter operations.\n * chainId/poolAddress are injected automatically.\n */\n readonly adapter = {\n /**\n * Execute an atomic unshield -> call(s) -> reshield flow through an adapter.\n */\n execute: (\n params: SimpleAdapterExecuteParams,\n opts?: { skipBroadcast?: boolean },\n overrides?: SignerOverride,\n ): Promise<AdapterExecuteResult> => {\n return this.sdk.adapter.execute(\n {\n chainId: this.chainId,\n poolAddress: this.poolAddress,\n adapterAddress: params.adapterAddress,\n inputs: params.inputs,\n calls: params.calls,\n reshields: params.reshields,\n deadline: params.deadline,\n },\n opts,\n overrides,\n );\n },\n };\n\n // ===== Advanced =====\n\n /**\n * Advanced escape hatch for raw JoinSplit transaction building.\n * Use this for custom transaction construction (e.g. swap adapters).\n */\n readonly advanced = {\n /** Build and submit raw JoinSplit transactions. */\n transact: (\n params: SimpleTransactParams,\n opts?: { skipBroadcast?: boolean },\n ): Promise<TransactRelayResult> => {\n return this.sdk.transact.transact(\n {\n chainId: this.chainId,\n poolAddress: this.poolAddress,\n transactions: params.transactions,\n },\n opts,\n );\n },\n\n /** Wait for a raw transaction to be confirmed on-chain. */\n reconcile: (relayId: string): Promise<TransactSyncResult> => {\n return this.sdk.transact.reconcile(relayId);\n },\n };\n\n // ===== Private Helpers =====\n\n private async requireActiveAccount(): Promise<Account> {\n const account = await this.sdk.accounts.getActive();\n if (!account) {\n throw new Error(\"No active account. Create an account first.\");\n }\n return account;\n }\n}\n\n// ===== Auto-detection helpers =====\n\nfunction detectStorage(): Storage {\n if (\n typeof globalThis.indexedDB !== \"undefined\" &&\n typeof globalThis.window !== \"undefined\"\n ) {\n return createIndexedDbStorage({ name: \"unlink-wallet\" });\n }\n throw new InitializationError(\n \"No storage backend detected. In Node.js, provide a storage option \" +\n \"(e.g. createSqliteStorage or createMemoryStorage).\",\n );\n}\n\nconst defaultRng = (n: number): Uint8Array => {\n if (!globalThis.crypto?.getRandomValues) {\n throw new InitializationError(\n \"crypto.getRandomValues unavailable. Provide a custom rng in config.\",\n );\n }\n return globalThis.crypto.getRandomValues(new Uint8Array(n));\n};\n"],"mappings":"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","names":["copy","FieldSize","encoder","decoder","keys","ed25519","ed25519","Interface","remoteSource","Interface","Interface","Interface","encoder","decoder","encoder","decoder","deriveAccount","HEX_DATA_REGEX","ensureHexData","normalizeCall","Interface","Interface","options"]}