@unlink-xyz/core 0.1.2 → 0.1.3-canary.01ac52d

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 (367) 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 +56253 -0
  11. package/dist/browser/index.js.map +1 -0
  12. package/dist/browser/wallet/index.js +55974 -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 +35 -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 -5
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +9969 -16
  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 +9712 -0
  166. package/dist/wallet/index.js.map +1 -0
  167. package/dist/wallet/sdk.d.ts +47 -0
  168. package/dist/wallet/sdk.d.ts.map +1 -0
  169. package/dist/wallet/types.d.ts +455 -0
  170. package/dist/wallet/types.d.ts.map +1 -0
  171. package/dist/wallet/unlink-wallet.d.ts +186 -0
  172. package/dist/wallet/unlink-wallet.d.ts.map +1 -0
  173. package/package.json +39 -12
  174. package/.eslintrc.json +0 -4
  175. package/account/zkAccount.test.ts +0 -316
  176. package/account/zkAccount.ts +0 -222
  177. package/clients/broadcaster.ts +0 -67
  178. package/clients/http.ts +0 -94
  179. package/clients/indexer.ts +0 -150
  180. package/config.ts +0 -39
  181. package/core.ts +0 -17
  182. package/dist/account/railgun-imports-prototype.d.ts +0 -12
  183. package/dist/account/railgun-imports-prototype.d.ts.map +0 -1
  184. package/dist/account/railgun-imports-prototype.js +0 -30
  185. package/dist/account/zkAccount.d.ts.map +0 -1
  186. package/dist/account/zkAccount.js +0 -128
  187. package/dist/clients/broadcaster.js +0 -23
  188. package/dist/clients/http.js +0 -57
  189. package/dist/clients/indexer.js +0 -67
  190. package/dist/config.js +0 -29
  191. package/dist/core.js +0 -12
  192. package/dist/errors.js +0 -18
  193. package/dist/key-derivation/babyjubjub.d.ts +0 -9
  194. package/dist/key-derivation/babyjubjub.d.ts.map +0 -1
  195. package/dist/key-derivation/babyjubjub.js +0 -9
  196. package/dist/key-derivation/bech32.d.ts +0 -22
  197. package/dist/key-derivation/bech32.d.ts.map +0 -1
  198. package/dist/key-derivation/bech32.js +0 -86
  199. package/dist/key-derivation/bip32.d.ts +0 -17
  200. package/dist/key-derivation/bip32.d.ts.map +0 -1
  201. package/dist/key-derivation/bip32.js +0 -41
  202. package/dist/key-derivation/bip39.d.ts +0 -22
  203. package/dist/key-derivation/bip39.d.ts.map +0 -1
  204. package/dist/key-derivation/bip39.js +0 -56
  205. package/dist/key-derivation/bytes.d.ts +0 -19
  206. package/dist/key-derivation/bytes.d.ts.map +0 -1
  207. package/dist/key-derivation/bytes.js +0 -92
  208. package/dist/key-derivation/hash.d.ts +0 -3
  209. package/dist/key-derivation/hash.d.ts.map +0 -1
  210. package/dist/key-derivation/hash.js +0 -10
  211. package/dist/key-derivation/index.d.ts +0 -8
  212. package/dist/key-derivation/index.d.ts.map +0 -1
  213. package/dist/key-derivation/index.js +0 -7
  214. package/dist/key-derivation/wallet-node.d.ts +0 -45
  215. package/dist/key-derivation/wallet-node.d.ts.map +0 -1
  216. package/dist/key-derivation/wallet-node.js +0 -109
  217. package/dist/keys.js +0 -41
  218. package/dist/prover/config.js +0 -80
  219. package/dist/prover/index.js +0 -1
  220. package/dist/prover/prover.js +0 -274
  221. package/dist/prover/registry.js +0 -57
  222. package/dist/schema.js +0 -14
  223. package/dist/state/ciphertext-store.d.ts +0 -12
  224. package/dist/state/ciphertext-store.d.ts.map +0 -1
  225. package/dist/state/ciphertext-store.js +0 -25
  226. package/dist/state/hydrator.d.ts +0 -16
  227. package/dist/state/hydrator.d.ts.map +0 -1
  228. package/dist/state/hydrator.js +0 -18
  229. package/dist/state/index.js +0 -2
  230. package/dist/state/job-store.d.ts +0 -12
  231. package/dist/state/job-store.d.ts.map +0 -1
  232. package/dist/state/job-store.js +0 -118
  233. package/dist/state/jobs.d.ts +0 -50
  234. package/dist/state/jobs.d.ts.map +0 -1
  235. package/dist/state/jobs.js +0 -1
  236. package/dist/state/leaf-store.d.ts +0 -17
  237. package/dist/state/leaf-store.d.ts.map +0 -1
  238. package/dist/state/leaf-store.js +0 -35
  239. package/dist/state/merkle/hydrator.js +0 -36
  240. package/dist/state/merkle/index.js +0 -2
  241. package/dist/state/merkle/merkle-tree.js +0 -104
  242. package/dist/state/merkle-tree.d.ts +0 -34
  243. package/dist/state/merkle-tree.d.ts.map +0 -1
  244. package/dist/state/merkle-tree.js +0 -104
  245. package/dist/state/note-store.d.ts +0 -37
  246. package/dist/state/note-store.d.ts.map +0 -1
  247. package/dist/state/note-store.js +0 -133
  248. package/dist/state/nullifier-store.d.ts +0 -13
  249. package/dist/state/nullifier-store.d.ts.map +0 -1
  250. package/dist/state/nullifier-store.js +0 -21
  251. package/dist/state/records.d.ts +0 -57
  252. package/dist/state/records.d.ts.map +0 -1
  253. package/dist/state/records.js +0 -1
  254. package/dist/state/root-store.d.ts +0 -13
  255. package/dist/state/root-store.d.ts.map +0 -1
  256. package/dist/state/root-store.js +0 -30
  257. package/dist/state/store/ciphertext-store.js +0 -25
  258. package/dist/state/store/index.js +0 -8
  259. package/dist/state/store/job-store.js +0 -118
  260. package/dist/state/store/jobs.js +0 -1
  261. package/dist/state/store/leaf-store.js +0 -35
  262. package/dist/state/store/note-store.js +0 -142
  263. package/dist/state/store/nullifier-store.js +0 -30
  264. package/dist/state/store/records.js +0 -1
  265. package/dist/state/store/root-store.js +0 -30
  266. package/dist/state/store/store.js +0 -22
  267. package/dist/state/store.d.ts +0 -26
  268. package/dist/state/store.d.ts.map +0 -1
  269. package/dist/state/store.js +0 -19
  270. package/dist/state.d.ts +0 -83
  271. package/dist/state.d.ts.map +0 -1
  272. package/dist/state.js +0 -171
  273. package/dist/storage/index.js +0 -2
  274. package/dist/storage/indexeddb.js +0 -205
  275. package/dist/storage/memory.js +0 -87
  276. package/dist/transactions/deposit.js +0 -169
  277. package/dist/transactions/index.js +0 -4
  278. package/dist/transactions/note-sync.js +0 -320
  279. package/dist/transactions/reconcile.js +0 -39
  280. package/dist/transactions/shield.d.ts +0 -5
  281. package/dist/transactions/shield.d.ts.map +0 -1
  282. package/dist/transactions/shield.js +0 -93
  283. package/dist/transactions/transact.js +0 -561
  284. package/dist/transactions/types.d.ts +0 -114
  285. package/dist/transactions/types.d.ts.map +0 -1
  286. package/dist/transactions/types.js +0 -1
  287. package/dist/transactions/utils.d.ts +0 -10
  288. package/dist/transactions/utils.d.ts.map +0 -1
  289. package/dist/transactions/utils.js +0 -17
  290. package/dist/types.js +0 -1
  291. package/dist/utils/bigint.js +0 -29
  292. package/dist/utils/crypto.d.ts +0 -12
  293. package/dist/utils/crypto.d.ts.map +0 -1
  294. package/dist/utils/crypto.js +0 -39
  295. package/dist/utils/json-codec.js +0 -25
  296. package/dist/utils/polling.js +0 -6
  297. package/dist/utils/signature.js +0 -12
  298. package/dist/utils/time.d.ts +0 -2
  299. package/dist/utils/time.d.ts.map +0 -1
  300. package/dist/utils/time.js +0 -3
  301. package/dist/utils/validators.js +0 -70
  302. package/dist/utils/witness.d.ts +0 -11
  303. package/dist/utils/witness.d.ts.map +0 -1
  304. package/dist/utils/witness.js +0 -19
  305. package/errors.ts +0 -20
  306. package/index.ts +0 -17
  307. package/key-derivation/babyjubjub.ts +0 -11
  308. package/key-derivation/bech32.test.ts +0 -90
  309. package/key-derivation/bech32.ts +0 -124
  310. package/key-derivation/bip32.ts +0 -56
  311. package/key-derivation/bip39.ts +0 -76
  312. package/key-derivation/bytes.ts +0 -118
  313. package/key-derivation/hash.ts +0 -13
  314. package/key-derivation/index.ts +0 -7
  315. package/key-derivation/wallet-node.ts +0 -155
  316. package/keys.ts +0 -47
  317. package/prover/config.ts +0 -104
  318. package/prover/index.ts +0 -1
  319. package/prover/prover.integration.test.ts +0 -162
  320. package/prover/prover.test.ts +0 -309
  321. package/prover/prover.ts +0 -405
  322. package/prover/registry.test.ts +0 -90
  323. package/prover/registry.ts +0 -82
  324. package/schema.ts +0 -17
  325. package/setup-artifacts.sh +0 -57
  326. package/state/index.ts +0 -2
  327. package/state/merkle/hydrator.ts +0 -69
  328. package/state/merkle/index.ts +0 -12
  329. package/state/merkle/merkle-tree.test.ts +0 -50
  330. package/state/merkle/merkle-tree.ts +0 -163
  331. package/state/store/ciphertext-store.ts +0 -28
  332. package/state/store/index.ts +0 -24
  333. package/state/store/job-store.ts +0 -162
  334. package/state/store/jobs.ts +0 -64
  335. package/state/store/leaf-store.ts +0 -39
  336. package/state/store/note-store.ts +0 -177
  337. package/state/store/nullifier-store.ts +0 -39
  338. package/state/store/records.ts +0 -61
  339. package/state/store/root-store.ts +0 -34
  340. package/state/store/store.ts +0 -25
  341. package/state.test.ts +0 -235
  342. package/storage/index.ts +0 -3
  343. package/storage/indexeddb.test.ts +0 -99
  344. package/storage/indexeddb.ts +0 -235
  345. package/storage/memory.test.ts +0 -59
  346. package/storage/memory.ts +0 -93
  347. package/transactions/deposit.test.ts +0 -160
  348. package/transactions/deposit.ts +0 -227
  349. package/transactions/index.ts +0 -20
  350. package/transactions/note-sync.test.ts +0 -155
  351. package/transactions/note-sync.ts +0 -452
  352. package/transactions/reconcile.ts +0 -73
  353. package/transactions/transact.test.ts +0 -451
  354. package/transactions/transact.ts +0 -811
  355. package/transactions/types.ts +0 -141
  356. package/tsconfig.json +0 -14
  357. package/types/global.d.ts +0 -15
  358. package/types.ts +0 -24
  359. package/utils/async.ts +0 -15
  360. package/utils/bigint.ts +0 -34
  361. package/utils/crypto.test.ts +0 -69
  362. package/utils/crypto.ts +0 -58
  363. package/utils/json-codec.ts +0 -38
  364. package/utils/polling.ts +0 -6
  365. package/utils/signature.ts +0 -16
  366. package/utils/validators.test.ts +0 -64
  367. package/utils/validators.ts +0 -86
package/storage/memory.ts DELETED
@@ -1,93 +0,0 @@
1
- /**
2
- * In-memory key/value storage for Unlink Core.
3
- *
4
- * What this is
5
- * - A minimal, process-local KV store backed by a `Map<string, Uint8Array>`.
6
- *
7
- * Why we implement it
8
- * - Fast, dependency-free storage for unit tests, demos, and ephemeral runs.
9
- * - Useful as a reference driver for the Storage interface.
10
- *
11
- * When to use
12
- * - Unit tests (deterministic, zero I/O).
13
- * - CLI/Node scripts that do not need persistence beyond process lifetime.
14
- * - Prototyping or sandboxing Core logic.
15
- *
16
- * Trade-offs
17
- * - 👍 Extremely fast; zero external APIs; simple to reason about.
18
- * - 👍 Great for isolation in tests; easy to snapshot/clone.
19
- * - ⚠️ No durability (data is lost on process exit).
20
- * - ⚠️ Per-process only; no cross-tab or reload survival.
21
- *
22
- */
23
-
24
- import { CoreError } from "../errors.js";
25
- import { validateKey } from "../keys.js";
26
- import { BatchOp, Bytes, IterOptions, KvPair, Storage } from "../types.js";
27
-
28
- const copy = (value: Bytes) => new Uint8Array(value);
29
-
30
- export function createMemoryStorage(): Storage {
31
- const data = new Map<string, Bytes>();
32
- let schema = 0;
33
-
34
- return {
35
- async open() {},
36
- async get(k) {
37
- validateKey(k);
38
- return data.has(k) ? copy(data.get(k)!) : null;
39
- },
40
- async put(k, v) {
41
- validateKey(k);
42
- data.set(k, copy(v));
43
- },
44
- async delete(k) {
45
- validateKey(k);
46
- data.delete(k);
47
- },
48
- async batch(ops: BatchOp[]) {
49
- const draft = new Map(data);
50
- for (const op of ops) {
51
- if (op.put) {
52
- const [k, v] = op.put;
53
- validateKey(k);
54
- draft.set(k, copy(v));
55
- }
56
- if (op.del) {
57
- validateKey(op.del);
58
- draft.delete(op.del);
59
- }
60
- }
61
- data.clear();
62
- for (const [k, v] of draft.entries()) {
63
- data.set(k, copy(v));
64
- }
65
- },
66
- async iter(o: IterOptions = {}): Promise<KvPair[]> {
67
- if (o.start && o.end && o.start > o.end) {
68
- throw new CoreError("iter start bound must not exceed end bound");
69
- }
70
- const all = [...data.entries()].map(([key, value]) => ({
71
- key,
72
- value: copy(value),
73
- }));
74
- let ks = all
75
- .filter(
76
- ({ key }) =>
77
- (!o.prefix || key.startsWith(o.prefix)) &&
78
- (!o.start || key >= o.start) &&
79
- (!o.end || key <= o.end),
80
- )
81
- .sort((a, b) => a.key.localeCompare(b.key));
82
- if (o.reverse) ks.reverse();
83
- if (o.limit) ks = ks.slice(0, o.limit);
84
- return ks;
85
- },
86
- async getSchemaVersion() {
87
- return schema;
88
- },
89
- async setSchemaVersion(n: number) {
90
- schema = n;
91
- },
92
- };
93
- }
@@ -1,160 +0,0 @@
1
- import { eddsa, poseidon } from "@railgun-community/circomlibjs";
2
- import { Interface } from "ethers";
3
- import { beforeEach, describe, expect, it } from "vitest";
4
-
5
- import {
6
- createMockFetch,
7
- createMockIndexer,
8
- } from "../../test-utils/mock-indexer.js";
9
- import { ZkAccount } from "../account/zkAccount.js";
10
- import { ByteLength, ByteUtils } from "../key-derivation/bytes.js";
11
- import { createStateStore } from "../state/index.js";
12
- import { createMemoryStorage } from "../storage/index.js";
13
- import { createDepositClient, DEPOSIT_ABI } from "./deposit.js";
14
-
15
- const chainId = 1;
16
- const poolAddress = "0x1111111111111111111111111111111111111111";
17
- const depositor = "0x2222222222222222222222222222222222222222";
18
- const token = "0x3333333333333333333333333333333333333333";
19
-
20
- const mockPrivateKey = Buffer.from(new Uint8Array(32).fill(1));
21
- const mockPublicKey = eddsa.prv2pub(mockPrivateKey);
22
- const mockNullifyingKey = 987n;
23
- const mockMpk = poseidon([
24
- mockPublicKey[0],
25
- mockPublicKey[1],
26
- mockNullifyingKey,
27
- ]);
28
- const mockZkAccount: ZkAccount = {
29
- spendingKeyPair: {
30
- privateKey: mockPrivateKey,
31
- pubkey: mockPublicKey,
32
- },
33
- viewingKeyPair: {
34
- privateKey: Buffer.from(new Uint8Array(32).fill(2)),
35
- pubkey: Buffer.from(new Uint8Array(32).fill(3)),
36
- },
37
- nullifyingKey: mockNullifyingKey,
38
- masterPublicKey: mockMpk,
39
- };
40
-
41
- const depositInterface = new Interface(DEPOSIT_ABI);
42
-
43
- describe.skip("deposit client", () => {
44
- let state: ReturnType<typeof createStateStore>;
45
- let client: ReturnType<typeof createDepositClient>;
46
- let fetchMock: ReturnType<typeof createMockFetch>;
47
- let indexer: ReturnType<typeof createMockIndexer>;
48
-
49
- beforeEach(async () => {
50
- const storage = createMemoryStorage();
51
- await storage.open();
52
- state = createStateStore(storage);
53
- indexer = createMockIndexer();
54
- fetchMock = createMockFetch(indexer);
55
- client = createDepositClient(state, { fetch: fetchMock });
56
- });
57
-
58
- it("builds calldata, enqueues relay, and syncs state via indexer", async () => {
59
- const request = {
60
- zkAccount: mockZkAccount,
61
- chainId,
62
- poolAddress,
63
- depositor,
64
- note: {
65
- mpk: 7n,
66
- random: 8n,
67
- amount: 5n,
68
- token,
69
- },
70
- } as const;
71
-
72
- const expectedNpk = poseidon([request.note.mpk, request.note.random]);
73
- const expectedCommitment = poseidon([
74
- expectedNpk,
75
- BigInt(token),
76
- request.note.amount,
77
- ]);
78
- const expectedCommitmentHex = ByteUtils.nToHex(
79
- expectedCommitment,
80
- ByteLength.UINT_256,
81
- true,
82
- );
83
-
84
- const relay = await client.request(request);
85
- expect(relay.commitment).toBe(expectedCommitmentHex);
86
- indexer.publish(chainId, relay.commitment);
87
- const result = await client.syncPendingDeposit(relay.relayId);
88
-
89
- expect(result.chainId).toBe(chainId);
90
- expect(result.index).toBe(0);
91
- expect(result.commitment).toBe(expectedCommitmentHex);
92
- expect(result.root).toMatch(/^0x[0-9a-f]+$/);
93
-
94
- const decoded = depositInterface.decodeFunctionData(
95
- "deposit",
96
- relay.calldata,
97
- );
98
- expect(decoded[0]).toBe(depositor);
99
- expect(decoded[1][0].npk).toBe(expectedNpk);
100
- expect(decoded[1][0].amount).toBe(request.note.amount);
101
- expect(decoded[1][0].token).toBe(token);
102
-
103
- const storedLeaf = await state.getLeaf(chainId, result.index);
104
- expect(storedLeaf?.commitment).toBe(result.commitment);
105
-
106
- const storedRoot = await state.getRoot(chainId, result.root);
107
- expect(storedRoot?.root).toBe(result.root);
108
- });
109
-
110
- it("tracks indexes per chain independently", async () => {
111
- const firstNote = { mpk: 1n, random: 2n, amount: 2n, token };
112
- const firstRequest = await client.request({
113
- zkAccount: mockZkAccount,
114
- chainId,
115
- poolAddress,
116
- depositor,
117
- note: firstNote,
118
- });
119
- indexer.publish(chainId, firstRequest.commitment);
120
- const first = await client.syncPendingDeposit(firstRequest.relayId);
121
-
122
- const secondNote = { mpk: 3n, random: 4n, amount: 4n, token };
123
- const secondRequest = await client.request({
124
- zkAccount: mockZkAccount,
125
- chainId,
126
- poolAddress,
127
- depositor,
128
- note: secondNote,
129
- });
130
- indexer.publish(chainId, secondRequest.commitment);
131
- const second = await client.syncPendingDeposit(secondRequest.relayId);
132
-
133
- const otherNote = { mpk: 5n, random: 6n, amount: 6n, token };
134
- const otherRequest = await client.request({
135
- zkAccount: mockZkAccount,
136
- chainId: 10,
137
- poolAddress,
138
- depositor,
139
- note: otherNote,
140
- });
141
- indexer.publish(10, otherRequest.commitment);
142
- const otherChain = await client.syncPendingDeposit(otherRequest.relayId);
143
-
144
- expect(first.index).toBe(0);
145
- expect(second.index).toBe(1);
146
- expect(otherChain.index).toBe(0);
147
- });
148
-
149
- it("rejects invalid chain ids", async () => {
150
- await expect(
151
- client.request({
152
- zkAccount: mockZkAccount,
153
- chainId: 0,
154
- poolAddress,
155
- depositor,
156
- note: { mpk: 1n, random: 1n, amount: 1n, token },
157
- }),
158
- ).rejects.toThrow("chainId must be a positive integer");
159
- });
160
- });
@@ -1,227 +0,0 @@
1
- import { Interface } from "ethers";
2
- import { v4 as uuidv4 } from "uuid";
3
-
4
- import { FetchLike } from "../clients/http.js";
5
- import { CommitmentRecord, createIndexerClient } from "../clients/indexer.js";
6
- import { serviceConfig } from "../config.js";
7
- import { ByteLength, ByteUtils } from "../key-derivation/bytes.js";
8
- import {
9
- createMerkleTrees,
10
- DEFAULT_JOB_TIMEOUT_MS,
11
- LocalMerkleTrees,
12
- rebuildTreeFromStore,
13
- type PendingDepositJob,
14
- } from "../state/index.js";
15
- import { isNotFoundError, sleep } from "../utils/async.js";
16
- import { parseHexToBigInt } from "../utils/bigint.js";
17
- import { computeCommitment, deriveNpk, encryptNote } from "../utils/crypto.js";
18
- import {
19
- DEFAULT_POLL_INTERVAL_MS,
20
- DEFAULT_POLL_TIMEOUT_MS,
21
- MAX_POLL_INTERVAL_MS,
22
- } from "../utils/polling.js";
23
- import { ensureAddress, ensureChainId } from "../utils/validators.js";
24
- import type {
25
- DepositRelayResult,
26
- DepositRequest,
27
- DepositStateStore,
28
- DepositSyncResult,
29
- } from "./types.js";
30
-
31
- export const DEPOSIT_ABI = [
32
- "function deposit(address _depositor, (uint256 npk, uint256 amount, address token)[] notes, (uint256[3] data)[] ciphertexts)",
33
- ] as const;
34
- const depositInterface = new Interface(DEPOSIT_ABI);
35
-
36
- type DepositClientOptions = {
37
- merkleTrees?: LocalMerkleTrees;
38
- fetch: FetchLike;
39
- pollIntervalMs?: number;
40
- pollTimeoutMs?: number;
41
- };
42
-
43
- function validateDepositRequest(request: DepositRequest) {
44
- ensureChainId(request.chainId);
45
- ensureAddress("pool address", request.poolAddress);
46
- ensureAddress("depositor", request.depositor);
47
- ensureAddress("token", request.note.token);
48
-
49
- if (request.note.mpk < 0n) {
50
- throw new Error("mpk must be non-negative");
51
- }
52
- if (request.note.random < 0n) {
53
- throw new Error("random must be non-negative");
54
- }
55
- if (request.note.amount < 0n) {
56
- throw new Error("amount must be non-negative");
57
- }
58
- const tokenScalar = BigInt(request.note.token);
59
- if (tokenScalar < 0n) {
60
- throw new Error("token must map to non-negative scalar");
61
- }
62
- }
63
-
64
- export function createDepositClient(
65
- stateStore: DepositStateStore,
66
- options: DepositClientOptions,
67
- ) {
68
- if (!stateStore) {
69
- throw new Error("stateStore dependency is required");
70
- }
71
-
72
- const merkleTrees = options.merkleTrees ?? createMerkleTrees();
73
- const indexerClient = createIndexerClient(serviceConfig.indexerBaseUrl, {
74
- fetch: options.fetch,
75
- });
76
-
77
- function buildCalldata(request: DepositRequest, npk: bigint) {
78
- return depositInterface.encodeFunctionData("deposit", [
79
- request.depositor,
80
- [
81
- // TODO(julienbrs) handle multiple notes
82
- {
83
- npk: npk,
84
- amount: request.note.amount,
85
- token: request.note.token,
86
- },
87
- ],
88
- [
89
- {
90
- data: encryptNote(request.note).data,
91
- },
92
- ],
93
- ]);
94
- }
95
-
96
- async function persistDepositSuccess(
97
- job: PendingDepositJob,
98
- record: CommitmentRecord,
99
- indexedRoot: string,
100
- ) {
101
- await Promise.all([
102
- stateStore.putLeaf({
103
- chainId: job.chainId,
104
- index: record.index,
105
- commitment: record.commitment,
106
- }),
107
- stateStore.putRoot({
108
- chainId: job.chainId,
109
- root: indexedRoot,
110
- }),
111
- stateStore.putPendingJob({
112
- ...job,
113
- status: "succeeded",
114
- lastCheckedAt: Date.now(),
115
- txHash: record.txHash ?? job.txHash ?? null,
116
- predictedCommitment: {
117
- ...job.predictedCommitment,
118
- index: record.index,
119
- root: indexedRoot,
120
- },
121
- }),
122
- ]);
123
- }
124
-
125
- return {
126
- async request(request: DepositRequest): Promise<DepositRelayResult> {
127
- validateDepositRequest(request);
128
-
129
- const npk = deriveNpk(request);
130
- const calldata = buildCalldata(request, npk);
131
- const commitment = computeCommitment(request, npk);
132
- const commitmentHex = ByteUtils.nToHex(
133
- commitment,
134
- ByteLength.UINT_256,
135
- true,
136
- );
137
- const relayId = uuidv4();
138
- const job: PendingDepositJob = {
139
- relayId,
140
- kind: "deposit",
141
- chainId: request.chainId,
142
- status: "pending",
143
- broadcasterRelayId: null,
144
- txHash: null,
145
- createdAt: Date.now(),
146
- timeoutMs: DEFAULT_JOB_TIMEOUT_MS,
147
- predictedCommitment: {
148
- hex: commitmentHex,
149
- },
150
- };
151
- await stateStore.putPendingJob(job);
152
- return { relayId, calldata, commitment: commitmentHex };
153
- },
154
-
155
- async syncPendingDeposit(relayId: string): Promise<DepositSyncResult> {
156
- const job = await stateStore.getPendingJob(relayId);
157
- if (!job || job.kind !== "deposit") {
158
- throw new Error(`unknown deposit relay ${relayId}`);
159
- }
160
- await rebuildTreeFromStore({
161
- chainId: job.chainId,
162
- trees: merkleTrees,
163
- loadLeaf: stateStore.getLeaf.bind(stateStore),
164
- });
165
- const commitmentHex = job.predictedCommitment.hex;
166
- const record = await waitForCommitment(job.chainId, commitmentHex);
167
- const { index, root: indexedRoot } = record;
168
-
169
- const commitmentValue = parseHexToBigInt(commitmentHex);
170
- const { index: localIndex, root: localRoot } = merkleTrees.addLeaf(
171
- job.chainId,
172
- commitmentValue,
173
- );
174
- // TODO: if local state drift detected, need to re-sync since last correct state
175
- if (localIndex !== index) {
176
- throw new Error(
177
- "local merkle tree desynchronized (index mismatch), local index: " +
178
- localIndex +
179
- ", indexed index: " +
180
- index,
181
- );
182
- }
183
- if (localRoot.toLowerCase() !== indexedRoot.toLowerCase()) {
184
- throw new Error(
185
- "local merkle tree desynchronized (root mismatch), local root: " +
186
- localRoot +
187
- ", indexed root: " +
188
- indexedRoot,
189
- );
190
- }
191
-
192
- await persistDepositSuccess(job, record, indexedRoot);
193
- return {
194
- chainId: job.chainId,
195
- index,
196
- commitment: record.commitment,
197
- root: indexedRoot,
198
- };
199
- },
200
- };
201
-
202
- async function waitForCommitment(
203
- chainId: number,
204
- commitmentHex: string,
205
- ): Promise<CommitmentRecord> {
206
- const timeout = options.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;
207
- const startedAt = Date.now();
208
- let delay = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
209
-
210
- while (Date.now() - startedAt <= timeout) {
211
- try {
212
- const record = await indexerClient.getCommitment({
213
- chainId,
214
- commitment: commitmentHex,
215
- });
216
- if (record) return record;
217
- } catch (err) {
218
- if (!isNotFoundError(err)) {
219
- throw err;
220
- }
221
- }
222
- await sleep(delay);
223
- delay = Math.min(delay * 2, MAX_POLL_INTERVAL_MS);
224
- }
225
- throw new Error("commitment not found in indexer before timeout");
226
- }
227
- }
@@ -1,20 +0,0 @@
1
- export { createDepositClient } from "./deposit.js";
2
- export { createTransactService } from "./transact.js";
3
- export { createJobReconciler } from "./reconcile.js";
4
- export { createNoteSyncService } from "./note-sync.js";
5
- export type { NoteSyncStateStore } from "./note-sync.js";
6
- export type {
7
- DepositRelayResult,
8
- DepositNoteInput,
9
- DepositRequest,
10
- DepositSyncResult,
11
- DepositStateStore,
12
- Proof,
13
- OutputNoteInput,
14
- SpendNoteReference,
15
- TransactRelayResult,
16
- TransactRequest,
17
- TransactSyncResult,
18
- TransactStateStore,
19
- WithdrawalNoteInput,
20
- } from "./types.js";
@@ -1,155 +0,0 @@
1
- import "fake-indexeddb/auto";
2
-
3
- import { poseidon } from "@railgun-community/circomlibjs";
4
- import { createMemoryStorage, createStateStore, ZkAccount } from "@unlink/core";
5
- import { describe, expect, it } from "vitest";
6
-
7
- import {
8
- createMockFetch,
9
- createMockIndexer,
10
- } from "../../test-utils/mock-indexer.js";
11
- import { ByteLength, ByteUtils } from "../key-derivation/bytes.js";
12
- import { formatUint256 } from "../utils/bigint.js";
13
- import { encryptNote } from "../utils/crypto.js";
14
- import { createNoteSyncService } from "./note-sync.js";
15
-
16
- const chainId = 1;
17
- const token = "0x1111111111111111111111111111111111111111";
18
- const random = 0x5n;
19
- const amount = 10n;
20
- const masterPublicKey = 0x1234567890abcdefn;
21
- const account: ZkAccount = {
22
- spendingKeyPair: {
23
- privateKey: new Uint8Array(32),
24
- pubkey: [0n, 0n],
25
- },
26
- viewingKeyPair: {
27
- privateKey: new Uint8Array(32),
28
- pubkey: new Uint8Array(32),
29
- },
30
- nullifyingKey: 777n,
31
- masterPublicKey,
32
- };
33
-
34
- function cipherToHexSet(ciphertext: ReturnType<typeof encryptNote>) {
35
- return ciphertext.data.map((value) => formatUint256(value)) as [
36
- string,
37
- string,
38
- string,
39
- ];
40
- }
41
-
42
- function ciphertextToBytes(ciphertext: ReturnType<typeof encryptNote>) {
43
- const payload = new Uint8Array(ByteLength.UINT_256 * ciphertext.data.length);
44
- ciphertext.data.forEach((value, index) => {
45
- const start = index * ByteLength.UINT_256;
46
- payload.set(ByteUtils.hexStringToBytes(formatUint256(value)), start);
47
- });
48
- return payload;
49
- }
50
-
51
- describe("note sync service", () => {
52
- it("stores decryptable notes", async () => {
53
- const storage = createMemoryStorage();
54
- await storage.open();
55
- const state = createStateStore(storage);
56
- const indexer = createMockIndexer();
57
- const fetchMock = createMockFetch(indexer);
58
- const service = createNoteSyncService(state, { fetch: fetchMock });
59
-
60
- const npk = poseidon([masterPublicKey, random]);
61
- const commitmentValue = poseidon([npk, BigInt(token), amount]);
62
- const commitmentHex = formatUint256(commitmentValue);
63
- const ciphertext = encryptNote({
64
- mpk: masterPublicKey,
65
- random,
66
- amount,
67
- token,
68
- });
69
- const ciphertextHex = cipherToHexSet(ciphertext);
70
-
71
- indexer.publish(chainId, commitmentHex, ciphertextHex);
72
- const syncedNotes = await service.sync(chainId, account);
73
-
74
- expect(syncedNotes).toHaveLength(1);
75
- const storedNote = await state.getNote(chainId, 0);
76
- expect(storedNote?.commitment).toBe(commitmentHex);
77
- expect(storedNote?.mpk).toBe(formatUint256(masterPublicKey));
78
- expect(storedNote?.token).toBe(token);
79
- expect(storedNote?.value).toBe(amount.toString());
80
-
81
- const storedCiphertext = await state.getCiphertext(chainId, 0);
82
- expect(storedCiphertext).not.toBeNull();
83
- expect(storedCiphertext).toEqual(ciphertextToBytes(ciphertext));
84
-
85
- const leaf = await state.getLeaf(chainId, 0);
86
- expect(leaf?.commitment).toBe(commitmentHex);
87
-
88
- expect(syncedNotes[0]?.commitment).toBe(commitmentHex);
89
- });
90
-
91
- it("ignores ciphertexts for other accounts", async () => {
92
- const storage = createMemoryStorage();
93
- await storage.open();
94
- const state = createStateStore(storage);
95
- const indexer = createMockIndexer();
96
- const fetchMock = createMockFetch(indexer);
97
- const service = createNoteSyncService(state, { fetch: fetchMock });
98
-
99
- const otherMpk = masterPublicKey + 1n;
100
- const npk = poseidon([otherMpk, random]);
101
- const commitmentValue = poseidon([npk, BigInt(token), amount]);
102
- const commitmentHex = formatUint256(commitmentValue);
103
- const ciphertext = encryptNote({
104
- mpk: otherMpk,
105
- random,
106
- amount,
107
- token,
108
- });
109
- const ciphertextHex = cipherToHexSet(ciphertext);
110
-
111
- indexer.publish(chainId, commitmentHex, ciphertextHex);
112
- const syncedNotes = await service.sync(chainId, account);
113
-
114
- expect(syncedNotes).toHaveLength(0);
115
- expect(await state.getNote(chainId, 0)).toBeNull();
116
- expect(await state.getCiphertext(chainId, 0)).toBeNull();
117
- });
118
-
119
- it("marks notes as spent when nullifier exists on-chain", async () => {
120
- const storage = createMemoryStorage();
121
- await storage.open();
122
- const state = createStateStore(storage);
123
- const indexer = createMockIndexer();
124
- const fetchMock = createMockFetch(indexer);
125
- const service = createNoteSyncService(state, { fetch: fetchMock });
126
-
127
- const npk = poseidon([masterPublicKey, random]);
128
- const commitmentValue = poseidon([npk, BigInt(token), amount]);
129
- const commitmentHex = formatUint256(commitmentValue);
130
- const ciphertext = encryptNote({
131
- mpk: masterPublicKey,
132
- random,
133
- amount,
134
- token,
135
- });
136
- const ciphertextHex = cipherToHexSet(ciphertext);
137
-
138
- // Compute the nullifier that would be created for this note
139
- const nullifier = poseidon([account.nullifyingKey, BigInt(0)]);
140
- const nullifierHex = formatUint256(nullifier);
141
-
142
- // Publish commitment and mark nullifier as spent on-chain
143
- indexer.publish(chainId, commitmentHex, ciphertextHex);
144
- indexer.spendNullifier(chainId, nullifierHex);
145
-
146
- // Sync and verify note is marked as spent
147
- const syncedNotes = await service.sync(chainId, account);
148
- expect(syncedNotes).toHaveLength(1);
149
-
150
- const storedNote = await state.getNote(chainId, 0);
151
- expect(storedNote?.commitment).toBe(commitmentHex);
152
- expect(storedNote?.spentAt).toBeDefined();
153
- expect(storedNote?.spentAt).toBeGreaterThan(0);
154
- });
155
- });