@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
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
- });