@unlink-xyz/core 0.1.2 → 0.1.3-canary.0877bfe

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 (350) hide show
  1. package/dist/account/{zkAccount.d.ts → account.d.ts} +7 -5
  2. package/dist/account/account.d.ts.map +1 -0
  3. package/dist/account/{zkAccount.js → account.js} +57 -43
  4. package/dist/browser/index.js +108202 -0
  5. package/dist/browser/index.js.map +1 -0
  6. package/dist/circuits.json +74 -0
  7. package/dist/clients/broadcaster.d.ts +7 -2
  8. package/dist/clients/broadcaster.d.ts.map +1 -1
  9. package/dist/clients/broadcaster.js +9 -1
  10. package/dist/clients/http.d.ts +6 -0
  11. package/dist/clients/http.d.ts.map +1 -1
  12. package/dist/clients/http.js +24 -9
  13. package/dist/clients/indexer.d.ts +11 -0
  14. package/dist/clients/indexer.d.ts.map +1 -1
  15. package/dist/clients/indexer.js +40 -11
  16. package/dist/config.d.ts +28 -9
  17. package/dist/config.d.ts.map +1 -1
  18. package/dist/config.js +33 -26
  19. package/dist/constants.d.ts +6 -0
  20. package/dist/constants.d.ts.map +1 -0
  21. package/dist/constants.js +5 -0
  22. package/dist/core.d.ts.map +1 -1
  23. package/dist/core.js +5 -2
  24. package/dist/crypto-adapters/auto-init.d.ts +2 -0
  25. package/dist/crypto-adapters/auto-init.d.ts.map +1 -0
  26. package/dist/crypto-adapters/auto-init.js +7 -0
  27. package/dist/crypto-adapters/index.d.ts +22 -0
  28. package/dist/crypto-adapters/index.d.ts.map +1 -0
  29. package/dist/crypto-adapters/index.js +47 -0
  30. package/dist/crypto-adapters/polyfills.d.ts +5 -0
  31. package/dist/crypto-adapters/polyfills.d.ts.map +1 -0
  32. package/dist/crypto-adapters/polyfills.js +8 -0
  33. package/dist/errors.d.ts +9 -0
  34. package/dist/errors.d.ts.map +1 -1
  35. package/dist/errors.js +18 -0
  36. package/dist/history/index.d.ts +3 -0
  37. package/dist/history/index.d.ts.map +1 -0
  38. package/dist/history/index.js +2 -0
  39. package/dist/history/service.d.ts +46 -0
  40. package/dist/history/service.d.ts.map +1 -0
  41. package/dist/history/service.js +354 -0
  42. package/dist/history/types.d.ts +21 -0
  43. package/dist/history/types.d.ts.map +1 -0
  44. package/dist/index.d.ts +12 -5
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +11 -4
  47. package/dist/keys/address.d.ts +13 -0
  48. package/dist/keys/address.d.ts.map +1 -0
  49. package/dist/keys/address.js +55 -0
  50. package/dist/keys/derive.d.ts +37 -0
  51. package/dist/keys/derive.d.ts.map +1 -0
  52. package/dist/keys/derive.js +112 -0
  53. package/dist/keys/hex.d.ts +17 -0
  54. package/dist/keys/hex.d.ts.map +1 -0
  55. package/dist/keys/hex.js +66 -0
  56. package/dist/keys/index.d.ts +5 -0
  57. package/dist/keys/index.d.ts.map +1 -0
  58. package/dist/keys/index.js +4 -0
  59. package/dist/keys/mnemonic.d.ts +8 -0
  60. package/dist/keys/mnemonic.d.ts.map +1 -0
  61. package/dist/keys/mnemonic.js +23 -0
  62. package/dist/keys.d.ts +4 -1
  63. package/dist/keys.d.ts.map +1 -1
  64. package/dist/keys.js +4 -0
  65. package/dist/prover/config.d.ts +1 -15
  66. package/dist/prover/config.d.ts.map +1 -1
  67. package/dist/prover/config.js +1 -11
  68. package/dist/prover/prover.d.ts +15 -4
  69. package/dist/prover/prover.d.ts.map +1 -1
  70. package/dist/prover/prover.js +115 -98
  71. package/dist/prover/registry.d.ts +3 -30
  72. package/dist/prover/registry.d.ts.map +1 -1
  73. package/dist/prover/registry.js +12 -51
  74. package/dist/state/merkle/hydrator.d.ts.map +1 -1
  75. package/dist/state/merkle/hydrator.js +3 -2
  76. package/dist/state/merkle/index.d.ts +1 -1
  77. package/dist/state/merkle/index.d.ts.map +1 -1
  78. package/dist/state/merkle/index.js +1 -1
  79. package/dist/state/merkle/merkle-tree.d.ts +8 -0
  80. package/dist/state/merkle/merkle-tree.d.ts.map +1 -1
  81. package/dist/state/merkle/merkle-tree.js +16 -7
  82. package/dist/state/store/ciphertext-store.d.ts +4 -0
  83. package/dist/state/store/ciphertext-store.d.ts.map +1 -1
  84. package/dist/state/store/ciphertext-store.js +12 -0
  85. package/dist/state/store/history-store.d.ts +24 -0
  86. package/dist/state/store/history-store.d.ts.map +1 -0
  87. package/dist/state/store/history-store.js +53 -0
  88. package/dist/state/store/index.d.ts +3 -2
  89. package/dist/state/store/index.d.ts.map +1 -1
  90. package/dist/state/store/index.js +1 -0
  91. package/dist/state/store/job-store.d.ts +7 -7
  92. package/dist/state/store/job-store.d.ts.map +1 -1
  93. package/dist/state/store/job-store.js +65 -39
  94. package/dist/state/store/jobs.d.ts +65 -18
  95. package/dist/state/store/jobs.d.ts.map +1 -1
  96. package/dist/state/store/leaf-store.d.ts.map +1 -1
  97. package/dist/state/store/leaf-store.js +0 -3
  98. package/dist/state/store/note-store.d.ts +7 -7
  99. package/dist/state/store/note-store.d.ts.map +1 -1
  100. package/dist/state/store/note-store.js +38 -34
  101. package/dist/state/store/nullifier-store.d.ts +9 -0
  102. package/dist/state/store/nullifier-store.d.ts.map +1 -1
  103. package/dist/state/store/nullifier-store.js +32 -2
  104. package/dist/state/store/records.d.ts +31 -2
  105. package/dist/state/store/records.d.ts.map +1 -1
  106. package/dist/state/store/root-store.d.ts.map +1 -1
  107. package/dist/state/store/root-store.js +0 -4
  108. package/dist/state/store/store.d.ts +61 -27
  109. package/dist/state/store/store.d.ts.map +1 -1
  110. package/dist/state/store/store.js +92 -1
  111. package/dist/storage/indexeddb.js +1 -1
  112. package/dist/storage/memory.d.ts.map +1 -1
  113. package/dist/storage/memory.js +5 -1
  114. package/dist/transactions/deposit.d.ts +12 -15
  115. package/dist/transactions/deposit.d.ts.map +1 -1
  116. package/dist/transactions/deposit.js +203 -152
  117. package/dist/transactions/index.d.ts +7 -4
  118. package/dist/transactions/index.d.ts.map +1 -1
  119. package/dist/transactions/index.js +7 -2
  120. package/dist/transactions/note-selection.d.ts +17 -0
  121. package/dist/transactions/note-selection.d.ts.map +1 -0
  122. package/dist/transactions/note-selection.js +201 -0
  123. package/dist/transactions/note-sync.d.ts +5 -33
  124. package/dist/transactions/note-sync.d.ts.map +1 -1
  125. package/dist/transactions/note-sync.js +320 -155
  126. package/dist/transactions/reconcile.d.ts +10 -12
  127. package/dist/transactions/reconcile.d.ts.map +1 -1
  128. package/dist/transactions/reconcile.js +53 -7
  129. package/dist/transactions/transact.d.ts +13 -24
  130. package/dist/transactions/transact.d.ts.map +1 -1
  131. package/dist/transactions/transact.js +393 -507
  132. package/dist/transactions/transaction-planner.d.ts +34 -0
  133. package/dist/transactions/transaction-planner.d.ts.map +1 -0
  134. package/dist/transactions/transaction-planner.js +116 -0
  135. package/dist/transactions/transfer-planner.d.ts +36 -0
  136. package/dist/transactions/transfer-planner.d.ts.map +1 -0
  137. package/dist/transactions/transfer-planner.js +85 -0
  138. package/dist/transactions/types/deposit.d.ts +67 -0
  139. package/dist/transactions/types/deposit.d.ts.map +1 -0
  140. package/dist/transactions/types/domain.d.ts +67 -0
  141. package/dist/transactions/types/domain.d.ts.map +1 -0
  142. package/dist/transactions/types/domain.js +4 -0
  143. package/dist/transactions/types/index.d.ts +18 -0
  144. package/dist/transactions/types/index.d.ts.map +1 -0
  145. package/dist/transactions/types/index.js +17 -0
  146. package/dist/transactions/types/options.d.ts +45 -0
  147. package/dist/transactions/types/options.d.ts.map +1 -0
  148. package/dist/transactions/types/options.js +1 -0
  149. package/dist/transactions/types/planning.d.ts +80 -0
  150. package/dist/transactions/types/planning.d.ts.map +1 -0
  151. package/dist/transactions/types/planning.js +1 -0
  152. package/dist/transactions/types/state-stores.d.ts +103 -0
  153. package/dist/transactions/types/state-stores.d.ts.map +1 -0
  154. package/dist/transactions/types/state-stores.js +1 -0
  155. package/dist/transactions/types/transact.d.ts +76 -0
  156. package/dist/transactions/types/transact.d.ts.map +1 -0
  157. package/dist/transactions/types/transact.js +1 -0
  158. package/dist/transactions/withdrawal-planner.d.ts +58 -0
  159. package/dist/transactions/withdrawal-planner.d.ts.map +1 -0
  160. package/dist/transactions/withdrawal-planner.js +128 -0
  161. package/dist/tsconfig.tsbuildinfo +1 -1
  162. package/dist/tsup.browser.config.d.ts +7 -0
  163. package/dist/tsup.browser.config.d.ts.map +1 -0
  164. package/dist/tsup.browser.config.js +34 -0
  165. package/dist/utils/amounts.d.ts +39 -0
  166. package/dist/utils/amounts.d.ts.map +1 -0
  167. package/dist/utils/amounts.js +89 -0
  168. package/dist/utils/async.d.ts +9 -0
  169. package/dist/utils/async.d.ts.map +1 -1
  170. package/dist/utils/async.js +24 -0
  171. package/dist/utils/bigint.js +7 -7
  172. package/dist/utils/crypto.d.ts +11 -5
  173. package/dist/utils/crypto.d.ts.map +1 -1
  174. package/dist/utils/crypto.js +12 -6
  175. package/dist/utils/format.d.ts +25 -0
  176. package/dist/utils/format.d.ts.map +1 -0
  177. package/dist/utils/format.js +33 -0
  178. package/dist/utils/json-codec.js +1 -1
  179. package/dist/utils/notes.d.ts +15 -0
  180. package/dist/utils/notes.d.ts.map +1 -0
  181. package/dist/utils/notes.js +14 -0
  182. package/dist/utils/polling.d.ts +5 -0
  183. package/dist/utils/polling.d.ts.map +1 -1
  184. package/dist/utils/polling.js +5 -0
  185. package/dist/utils/random.d.ts +13 -0
  186. package/dist/utils/random.d.ts.map +1 -0
  187. package/dist/utils/random.js +27 -0
  188. package/dist/utils/secure-memory.d.ts +25 -0
  189. package/dist/utils/secure-memory.d.ts.map +1 -0
  190. package/dist/utils/secure-memory.js +28 -0
  191. package/dist/utils/signature.d.ts +6 -0
  192. package/dist/utils/signature.d.ts.map +1 -1
  193. package/dist/utils/signature.js +8 -6
  194. package/dist/utils/validators.d.ts +21 -10
  195. package/dist/utils/validators.d.ts.map +1 -1
  196. package/dist/utils/validators.js +37 -11
  197. package/dist/vitest.config.d.ts +3 -0
  198. package/dist/vitest.config.d.ts.map +1 -0
  199. package/dist/vitest.config.js +13 -0
  200. package/package.json +28 -11
  201. package/.eslintrc.json +0 -4
  202. package/account/zkAccount.test.ts +0 -316
  203. package/account/zkAccount.ts +0 -222
  204. package/clients/broadcaster.ts +0 -67
  205. package/clients/http.ts +0 -94
  206. package/clients/indexer.ts +0 -150
  207. package/config.ts +0 -39
  208. package/core.ts +0 -17
  209. package/dist/account/railgun-imports-prototype.d.ts +0 -12
  210. package/dist/account/railgun-imports-prototype.d.ts.map +0 -1
  211. package/dist/account/railgun-imports-prototype.js +0 -30
  212. package/dist/account/zkAccount.d.ts.map +0 -1
  213. package/dist/key-derivation/babyjubjub.d.ts +0 -9
  214. package/dist/key-derivation/babyjubjub.d.ts.map +0 -1
  215. package/dist/key-derivation/babyjubjub.js +0 -9
  216. package/dist/key-derivation/bech32.d.ts +0 -22
  217. package/dist/key-derivation/bech32.d.ts.map +0 -1
  218. package/dist/key-derivation/bech32.js +0 -86
  219. package/dist/key-derivation/bip32.d.ts +0 -17
  220. package/dist/key-derivation/bip32.d.ts.map +0 -1
  221. package/dist/key-derivation/bip32.js +0 -41
  222. package/dist/key-derivation/bip39.d.ts +0 -22
  223. package/dist/key-derivation/bip39.d.ts.map +0 -1
  224. package/dist/key-derivation/bip39.js +0 -56
  225. package/dist/key-derivation/bytes.d.ts +0 -19
  226. package/dist/key-derivation/bytes.d.ts.map +0 -1
  227. package/dist/key-derivation/bytes.js +0 -92
  228. package/dist/key-derivation/hash.d.ts +0 -3
  229. package/dist/key-derivation/hash.d.ts.map +0 -1
  230. package/dist/key-derivation/hash.js +0 -10
  231. package/dist/key-derivation/index.d.ts +0 -8
  232. package/dist/key-derivation/index.d.ts.map +0 -1
  233. package/dist/key-derivation/index.js +0 -7
  234. package/dist/key-derivation/wallet-node.d.ts +0 -45
  235. package/dist/key-derivation/wallet-node.d.ts.map +0 -1
  236. package/dist/key-derivation/wallet-node.js +0 -109
  237. package/dist/state/ciphertext-store.d.ts +0 -12
  238. package/dist/state/ciphertext-store.d.ts.map +0 -1
  239. package/dist/state/ciphertext-store.js +0 -25
  240. package/dist/state/hydrator.d.ts +0 -16
  241. package/dist/state/hydrator.d.ts.map +0 -1
  242. package/dist/state/hydrator.js +0 -18
  243. package/dist/state/job-store.d.ts +0 -12
  244. package/dist/state/job-store.d.ts.map +0 -1
  245. package/dist/state/job-store.js +0 -118
  246. package/dist/state/jobs.d.ts +0 -50
  247. package/dist/state/jobs.d.ts.map +0 -1
  248. package/dist/state/jobs.js +0 -1
  249. package/dist/state/leaf-store.d.ts +0 -17
  250. package/dist/state/leaf-store.d.ts.map +0 -1
  251. package/dist/state/leaf-store.js +0 -35
  252. package/dist/state/merkle-tree.d.ts +0 -34
  253. package/dist/state/merkle-tree.d.ts.map +0 -1
  254. package/dist/state/merkle-tree.js +0 -104
  255. package/dist/state/note-store.d.ts +0 -37
  256. package/dist/state/note-store.d.ts.map +0 -1
  257. package/dist/state/note-store.js +0 -133
  258. package/dist/state/nullifier-store.d.ts +0 -13
  259. package/dist/state/nullifier-store.d.ts.map +0 -1
  260. package/dist/state/nullifier-store.js +0 -21
  261. package/dist/state/records.d.ts +0 -57
  262. package/dist/state/records.d.ts.map +0 -1
  263. package/dist/state/root-store.d.ts +0 -13
  264. package/dist/state/root-store.d.ts.map +0 -1
  265. package/dist/state/root-store.js +0 -30
  266. package/dist/state/store.d.ts +0 -26
  267. package/dist/state/store.d.ts.map +0 -1
  268. package/dist/state/store.js +0 -19
  269. package/dist/state.d.ts +0 -83
  270. package/dist/state.d.ts.map +0 -1
  271. package/dist/state.js +0 -171
  272. package/dist/transactions/shield.d.ts +0 -5
  273. package/dist/transactions/shield.d.ts.map +0 -1
  274. package/dist/transactions/shield.js +0 -93
  275. package/dist/transactions/types.d.ts +0 -114
  276. package/dist/transactions/types.d.ts.map +0 -1
  277. package/dist/transactions/utils.d.ts +0 -10
  278. package/dist/transactions/utils.d.ts.map +0 -1
  279. package/dist/transactions/utils.js +0 -17
  280. package/dist/utils/time.d.ts +0 -2
  281. package/dist/utils/time.d.ts.map +0 -1
  282. package/dist/utils/time.js +0 -3
  283. package/dist/utils/witness.d.ts +0 -11
  284. package/dist/utils/witness.d.ts.map +0 -1
  285. package/dist/utils/witness.js +0 -19
  286. package/errors.ts +0 -20
  287. package/index.ts +0 -17
  288. package/key-derivation/babyjubjub.ts +0 -11
  289. package/key-derivation/bech32.test.ts +0 -90
  290. package/key-derivation/bech32.ts +0 -124
  291. package/key-derivation/bip32.ts +0 -56
  292. package/key-derivation/bip39.ts +0 -76
  293. package/key-derivation/bytes.ts +0 -118
  294. package/key-derivation/hash.ts +0 -13
  295. package/key-derivation/index.ts +0 -7
  296. package/key-derivation/wallet-node.ts +0 -155
  297. package/keys.ts +0 -47
  298. package/prover/config.ts +0 -104
  299. package/prover/index.ts +0 -1
  300. package/prover/prover.integration.test.ts +0 -162
  301. package/prover/prover.test.ts +0 -309
  302. package/prover/prover.ts +0 -405
  303. package/prover/registry.test.ts +0 -90
  304. package/prover/registry.ts +0 -82
  305. package/schema.ts +0 -17
  306. package/setup-artifacts.sh +0 -57
  307. package/state/index.ts +0 -2
  308. package/state/merkle/hydrator.ts +0 -69
  309. package/state/merkle/index.ts +0 -12
  310. package/state/merkle/merkle-tree.test.ts +0 -50
  311. package/state/merkle/merkle-tree.ts +0 -163
  312. package/state/store/ciphertext-store.ts +0 -28
  313. package/state/store/index.ts +0 -24
  314. package/state/store/job-store.ts +0 -162
  315. package/state/store/jobs.ts +0 -64
  316. package/state/store/leaf-store.ts +0 -39
  317. package/state/store/note-store.ts +0 -177
  318. package/state/store/nullifier-store.ts +0 -39
  319. package/state/store/records.ts +0 -61
  320. package/state/store/root-store.ts +0 -34
  321. package/state/store/store.ts +0 -25
  322. package/state.test.ts +0 -235
  323. package/storage/index.ts +0 -3
  324. package/storage/indexeddb.test.ts +0 -99
  325. package/storage/indexeddb.ts +0 -235
  326. package/storage/memory.test.ts +0 -59
  327. package/storage/memory.ts +0 -93
  328. package/transactions/deposit.test.ts +0 -160
  329. package/transactions/deposit.ts +0 -227
  330. package/transactions/index.ts +0 -20
  331. package/transactions/note-sync.test.ts +0 -155
  332. package/transactions/note-sync.ts +0 -452
  333. package/transactions/reconcile.ts +0 -73
  334. package/transactions/transact.test.ts +0 -451
  335. package/transactions/transact.ts +0 -811
  336. package/transactions/types.ts +0 -141
  337. package/tsconfig.json +0 -14
  338. package/types/global.d.ts +0 -15
  339. package/types.ts +0 -24
  340. package/utils/async.ts +0 -15
  341. package/utils/bigint.ts +0 -34
  342. package/utils/crypto.test.ts +0 -69
  343. package/utils/crypto.ts +0 -58
  344. package/utils/json-codec.ts +0 -38
  345. package/utils/polling.ts +0 -6
  346. package/utils/signature.ts +0 -16
  347. package/utils/validators.test.ts +0 -64
  348. package/utils/validators.ts +0 -86
  349. /package/dist/{transactions → history}/types.js +0 -0
  350. /package/dist/{state/records.js → transactions/types/deposit.js} +0 -0
@@ -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
- });