@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
@@ -1,309 +0,0 @@
1
- import { access } from "fs/promises";
2
- import { dirname, join } from "path";
3
- import { fileURLToPath } from "url";
4
- import * as snarkjs from "snarkjs";
5
- import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
6
-
7
- import { CoreError } from "../errors.js";
8
- import {
9
- getVerificationKey,
10
- proveTransaction,
11
- verifyProof,
12
- type JoinsplitProofInput,
13
- } from "./prover.js";
14
-
15
- // Mock snarkjs module
16
- vi.mock("snarkjs");
17
-
18
- // Test helpers
19
- function createMockInput(
20
- overrides?: Partial<JoinsplitProofInput>,
21
- ): JoinsplitProofInput {
22
- return {
23
- merkleRoot: 1n,
24
- boundParamsHash: 2n,
25
- nullifiers: [3n, 4n],
26
- commitmentsOut: [5n, 6n, 7n],
27
- token: 8n,
28
- publicKey: [9n, 10n],
29
- signature: [11n, 11n, 11n],
30
- randomIn: [12n, 13n],
31
- valueIn: [14n, 15n],
32
- pathElements: [[0n], [0n]],
33
- leavesIndices: [16n, 17n],
34
- nullifyingKey: 18n,
35
- npkOut: [19n, 20n, 21n],
36
- valueOut: [22n, 23n, 24n],
37
- ...overrides,
38
- };
39
- }
40
-
41
- function createMockProof() {
42
- return {
43
- pi_a: ["1", "2", "3"],
44
- pi_b: [
45
- ["4", "5"],
46
- ["6", "7"],
47
- ["8", "9"],
48
- ],
49
- pi_c: ["10", "11", "12"],
50
- protocol: "groth16" as const,
51
- curve: "bn128" as const,
52
- };
53
- }
54
-
55
- function createMockPublicSignals() {
56
- // 2x3 circuit has 7 public signals: [root, hash, nullifier1, nullifier2, commit1, commit2, commit3]
57
- return ["25", "26", "27", "28", "29", "30", "31"];
58
- }
59
-
60
- describe("prover", () => {
61
- beforeAll(async () => {
62
- const __filename = fileURLToPath(import.meta.url);
63
- const __dirname = dirname(__filename);
64
-
65
- // Check if artifacts exist for 2x3 circuit (used in these tests)
66
- try {
67
- await access(
68
- join(
69
- __dirname,
70
- "../artifacts/circuits/joinsplit_2x3_16/joinsplit.wasm",
71
- ),
72
- );
73
- await access(
74
- join(
75
- __dirname,
76
- "../artifacts/circuits/joinsplit_2x3_16/joinsplit.zkey",
77
- ),
78
- );
79
- await access(
80
- join(
81
- __dirname,
82
- "../artifacts/circuits/joinsplit_2x3_16/joinsplit.vkey.json",
83
- ),
84
- );
85
- } catch (error) {
86
- throw new Error(
87
- "Circuit artifacts not found. Please run 'pnpm run circuits:build' first.",
88
- );
89
- }
90
-
91
- // Mock verify to return true by default (proveTransaction calls it internally)
92
- const verifyMock = vi.mocked(snarkjs.groth16.verify);
93
- verifyMock.mockResolvedValue(true);
94
- });
95
-
96
- afterEach(() => {
97
- vi.clearAllMocks();
98
- });
99
-
100
- describe("getVerificationKey", () => {
101
- it("loads and returns the verification key", async () => {
102
- // Test uses 2 inputs, 3 outputs (see createMockInput)
103
- const vkey = await getVerificationKey(2, 3);
104
-
105
- expect(vkey).toBeDefined();
106
- expect(vkey.protocol).toBe("groth16");
107
- expect(vkey.curve).toBe("bn128");
108
- expect(vkey.nPublic).toBe(7); // 2 (root + hash) + 2 (nullifiers) + 3 (commitments) = 7
109
- expect(vkey.vk_alpha_1).toBeInstanceOf(Array);
110
- expect(vkey.vk_beta_2).toBeInstanceOf(Array);
111
- expect(vkey.vk_gamma_2).toBeInstanceOf(Array);
112
- expect(vkey.vk_delta_2).toBeInstanceOf(Array);
113
- expect(vkey.vk_alphabeta_12).toBeInstanceOf(Array);
114
- expect(vkey.IC).toBeInstanceOf(Array);
115
- expect(vkey.IC.length).toBe(8); // nPublic + 1
116
- });
117
- });
118
-
119
- describe("fetchArtifact", () => {
120
- it("successfully loads wasm and zkey files", async () => {
121
- const mockInput = createMockInput();
122
- const mockProof = createMockProof();
123
- const mockPublicSignals = createMockPublicSignals();
124
-
125
- const fullProveMock = vi.mocked(snarkjs.groth16.fullProve);
126
- fullProveMock.mockResolvedValue({
127
- proof: mockProof,
128
- publicSignals: mockPublicSignals,
129
- });
130
-
131
- // This should not throw file loading errors
132
- const result = await proveTransaction(mockInput);
133
-
134
- expect(result).toBeDefined();
135
- expect(result.proof).toEqual(mockProof);
136
- expect(result.publicSignals).toEqual(mockPublicSignals);
137
-
138
- // Verify fullProve was called with buffers (artifacts were loaded)
139
- expect(fullProveMock).toHaveBeenCalledTimes(1);
140
- const call = fullProveMock.mock.calls[0];
141
- expect(call[1]).toBeInstanceOf(Uint8Array); // wasm bytes
142
- expect(call[2]).toBeInstanceOf(Uint8Array); // zkey bytes
143
- });
144
- });
145
-
146
- describe("proveTransaction", () => {
147
- it("generates proof with valid input", async () => {
148
- const mockInput = createMockInput({
149
- merkleRoot: 100n,
150
- });
151
-
152
- const mockProof = createMockProof();
153
- const mockPublicSignals = createMockPublicSignals();
154
-
155
- const fullProveMock = vi.mocked(snarkjs.groth16.fullProve);
156
- fullProveMock.mockResolvedValue({
157
- proof: mockProof,
158
- publicSignals: mockPublicSignals,
159
- });
160
-
161
- const result = await proveTransaction(mockInput);
162
-
163
- expect(result.proof).toEqual(mockProof);
164
- expect(result.publicSignals).toEqual(mockPublicSignals);
165
- expect(fullProveMock).toHaveBeenCalledTimes(1);
166
-
167
- // Verify the call was made with input signals and file buffers
168
- const call = fullProveMock.mock.calls[0];
169
- expect(call[0]).toBeDefined(); // inputSignals
170
- expect(call[1]).toBeInstanceOf(Uint8Array); // wasm bytes
171
- expect(call[2]).toBeInstanceOf(Uint8Array); // zkey bytes
172
- });
173
-
174
- it("wraps errors with CoreError", async () => {
175
- const mockInput = createMockInput({
176
- nullifiers: [3n],
177
- commitmentsOut: [4n],
178
- randomIn: [9n],
179
- valueIn: [10n],
180
- pathElements: [[0n]],
181
- leavesIndices: [11n],
182
- npkOut: [13n],
183
- valueOut: [14n],
184
- });
185
-
186
- const mockError = new Error("snarkjs internal error");
187
- const fullProveMock = vi.mocked(snarkjs.groth16.fullProve);
188
- fullProveMock.mockRejectedValue(mockError);
189
-
190
- await expect(proveTransaction(mockInput)).rejects.toThrow(CoreError);
191
- await expect(proveTransaction(mockInput)).rejects.toThrow(
192
- "proof generation failed: snarkjs internal error",
193
- );
194
- });
195
- });
196
-
197
- describe("verifyProof", () => {
198
- it("verifies a valid proof successfully", async () => {
199
- const mockProof = createMockProof();
200
- const mockPublicSignals = createMockPublicSignals();
201
-
202
- const verifyMock = vi.mocked(snarkjs.groth16.verify);
203
- verifyMock.mockResolvedValue(true);
204
-
205
- const result = await verifyProof(mockProof, mockPublicSignals);
206
-
207
- expect(result).toBe(true);
208
- expect(verifyMock).toHaveBeenCalledTimes(1);
209
-
210
- // Verify it was called with vkey, publicSignals, and proof
211
- const call = verifyMock.mock.calls[0];
212
- expect(call[0]).toBeDefined(); // vkey
213
- expect(call[1]).toEqual(mockPublicSignals);
214
- expect(call[2]).toEqual(mockProof);
215
- });
216
-
217
- it("returns false for invalid proof", async () => {
218
- const mockProof = createMockProof();
219
- const mockPublicSignals = createMockPublicSignals();
220
-
221
- const verifyMock = vi.mocked(snarkjs.groth16.verify);
222
- verifyMock.mockResolvedValue(false);
223
-
224
- const result = await verifyProof(mockProof, mockPublicSignals);
225
-
226
- expect(result).toBe(false);
227
- });
228
-
229
- it("wraps errors with CoreError", async () => {
230
- const mockProof = createMockProof();
231
- const mockPublicSignals = createMockPublicSignals();
232
-
233
- const mockError = new Error("verification error");
234
- const verifyMock = vi.mocked(snarkjs.groth16.verify);
235
- verifyMock.mockRejectedValue(mockError);
236
-
237
- await expect(verifyProof(mockProof, mockPublicSignals)).rejects.toThrow(
238
- CoreError,
239
- );
240
- await expect(verifyProof(mockProof, mockPublicSignals)).rejects.toThrow(
241
- "proof verification failed",
242
- );
243
- });
244
-
245
- it("completes full prove and verify workflow", async () => {
246
- const mockInput = createMockInput();
247
- const mockProof = createMockProof();
248
- const mockPublicSignals = createMockPublicSignals();
249
-
250
- // Mock proof generation
251
- const fullProveMock = vi.mocked(snarkjs.groth16.fullProve);
252
- fullProveMock.mockResolvedValue({
253
- proof: mockProof,
254
- publicSignals: mockPublicSignals,
255
- });
256
-
257
- // Mock verification
258
- const verifyMock = vi.mocked(snarkjs.groth16.verify);
259
- verifyMock.mockResolvedValue(true);
260
-
261
- // Generate proof
262
- const proofResult = await proveTransaction(mockInput);
263
-
264
- // Verify proof
265
- const verificationResult = await verifyProof(
266
- proofResult.proof,
267
- proofResult.publicSignals,
268
- );
269
-
270
- expect(verificationResult).toBe(true);
271
- expect(fullProveMock).toHaveBeenCalledTimes(1);
272
- expect(verifyMock).toHaveBeenCalledTimes(2); // 1 internal + 1 explicit
273
- });
274
- });
275
-
276
- describe("artifact caching", () => {
277
- it("loads artifacts only once across multiple calls", async () => {
278
- const mockInput = createMockInput();
279
- const mockProof = createMockProof();
280
- const mockPublicSignals = createMockPublicSignals();
281
-
282
- const fullProveMock = vi.mocked(snarkjs.groth16.fullProve);
283
- fullProveMock.mockResolvedValue({
284
- proof: mockProof,
285
- publicSignals: mockPublicSignals,
286
- });
287
-
288
- const verifyMock = vi.mocked(snarkjs.groth16.verify);
289
- verifyMock.mockResolvedValue(true);
290
-
291
- // Make multiple calls
292
- await proveTransaction(mockInput);
293
- await proveTransaction(mockInput);
294
- await getVerificationKey(2, 3); // 2 inputs, 3 outputs
295
- await verifyProof(mockProof, mockPublicSignals);
296
-
297
- // All functions should work and be called
298
- expect(fullProveMock).toHaveBeenCalledTimes(2);
299
- expect(verifyMock).toHaveBeenCalledTimes(3); // 2 internal + 1 explicit
300
-
301
- // Verify artifacts are being reused (same Uint8Array instances)
302
- const firstCall = fullProveMock.mock.calls[0];
303
- const secondCall = fullProveMock.mock.calls[1];
304
-
305
- expect(firstCall[1]).toBe(secondCall[1]); // Same wasm buffer instance
306
- expect(firstCall[2]).toBe(secondCall[2]); // Same zkey buffer instance
307
- });
308
- });
309
- });
package/prover/prover.ts DELETED
@@ -1,405 +0,0 @@
1
- import { Groth16Proof, PublicSignals } from "snarkjs";
2
- import * as snarkjs from "snarkjs";
3
-
4
- import { CoreError } from "../errors.js";
5
- import {
6
- ArtifactType,
7
- buildArtifactUrl,
8
- DEFAULT_CONFIG,
9
- getLocalArtifactPath,
10
- Runtime,
11
- } from "./config.js";
12
- import {
13
- getCircuitConfig,
14
- SUPPORTED_CIRCUITS,
15
- type CircuitConfig,
16
- } from "./registry.js";
17
-
18
- // Cache for loaded artifacts to avoid reloading 18MB of files on every call
19
- // Now keyed by circuit name to support multiple circuits
20
- const artifactCache: Record<
21
- string,
22
- {
23
- wasm: Uint8Array;
24
- zkey: Uint8Array;
25
- vkey: VerificationKey;
26
- }
27
- > = {};
28
-
29
- export interface JoinsplitProof {
30
- readonly proof: Groth16Proof;
31
- readonly publicSignals: PublicSignals;
32
- }
33
-
34
- export interface VerificationKey {
35
- readonly protocol: string;
36
- readonly curve: string;
37
- readonly nPublic: number;
38
- readonly vk_alpha_1: string[];
39
- readonly vk_beta_2: string[][];
40
- readonly vk_gamma_2: string[][];
41
- readonly vk_delta_2: string[][];
42
- readonly vk_alphabeta_12: string[][][];
43
- readonly IC: string[][];
44
- }
45
-
46
- export interface JoinsplitProofInput {
47
- readonly merkleRoot: bigint;
48
- readonly boundParamsHash: bigint;
49
- readonly nullifiers: bigint[];
50
- readonly commitmentsOut: bigint[];
51
- readonly token: bigint;
52
- readonly publicKey: bigint[];
53
- readonly signature: bigint[];
54
- readonly randomIn: bigint[];
55
- readonly valueIn: bigint[];
56
- readonly pathElements: bigint[][];
57
- readonly leavesIndices: bigint[];
58
- readonly nullifyingKey: bigint;
59
- readonly npkOut: bigint[];
60
- readonly valueOut: bigint[];
61
- }
62
-
63
- /**
64
- * Select the appropriate circuit based on input/output dimensions
65
- * @param inputs Number of inputs (nullifiers)
66
- * @param outputs Number of outputs (commitments)
67
- * @returns Circuit configuration
68
- * @throws CoreError if no matching circuit is found
69
- */
70
- function selectCircuit(inputs: number, outputs: number): CircuitConfig {
71
- const config = getCircuitConfig(inputs, outputs);
72
-
73
- if (!config) {
74
- throw new CoreError(
75
- `No circuit available for ${inputs} inputs and ${outputs} outputs. ` +
76
- `Supported circuits: ${SUPPORTED_CIRCUITS.join(", ")}`,
77
- );
78
- }
79
-
80
- return config;
81
- }
82
-
83
- /**
84
- * Fetch circuit artifacts for a specific circuit
85
- * Supports both browser (remote) and Node.js (local) environments
86
- * @param circuitName Full circuit name (e.g., "joinsplit_2x3_16")
87
- * @returns Artifacts object with wasm, zkey, and vkey
88
- */
89
- async function fetchCircuitArtifacts(circuitName: string) {
90
- // Check cache first
91
- if (artifactCache[circuitName]) {
92
- return artifactCache[circuitName];
93
- }
94
-
95
- let wasm: Uint8Array | undefined;
96
- let zkey: Uint8Array | undefined;
97
- let vkey: VerificationKey | undefined;
98
-
99
- // Browser environment: fetch from artifact server
100
- if (Runtime.isBrowser()) {
101
- try {
102
- const baseUrl = DEFAULT_CONFIG.rpcUrl;
103
-
104
- const wasmUrl = buildArtifactUrl(circuitName, ArtifactType.WASM, baseUrl);
105
- const zkeyUrl = buildArtifactUrl(circuitName, ArtifactType.ZKEY, baseUrl);
106
- const vkeyUrl = buildArtifactUrl(circuitName, ArtifactType.VKEY, baseUrl);
107
-
108
- const [wasmRes, zkeyRes, vkeyRes] = await Promise.all([
109
- fetch(wasmUrl),
110
- fetch(zkeyUrl),
111
- fetch(vkeyUrl),
112
- ]);
113
-
114
- if (!wasmRes.ok || !zkeyRes.ok || !vkeyRes.ok) {
115
- throw new CoreError(
116
- `Failed to fetch artifacts for ${circuitName} from ${baseUrl}. ` +
117
- `Status: wasm=${wasmRes.status}, zkey=${zkeyRes.status}, vkey=${vkeyRes.status}`,
118
- );
119
- }
120
-
121
- wasm = new Uint8Array(await wasmRes.arrayBuffer());
122
- zkey = new Uint8Array(await zkeyRes.arrayBuffer());
123
- vkey = await vkeyRes.json();
124
- } catch (error) {
125
- throw new CoreError(
126
- `Failed to fetch artifacts from server for ${circuitName}: ${(error as Error).message}`,
127
- );
128
- }
129
- }
130
- // Node.js environment: try local file paths
131
- else {
132
- const wasmCandidates = getLocalArtifactPath(circuitName, ArtifactType.WASM);
133
- const zkeyCandidates = getLocalArtifactPath(circuitName, ArtifactType.ZKEY);
134
- const vkeyCandidates = getLocalArtifactPath(circuitName, ArtifactType.VKEY);
135
-
136
- let wasmLoaded = false;
137
- for (const candidate of wasmCandidates) {
138
- try {
139
- wasm = await readBinaryResource(candidate);
140
- wasmLoaded = true;
141
- break;
142
- } catch {
143
- // Try next candidate
144
- }
145
- }
146
-
147
- if (!wasmLoaded) {
148
- throw new CoreError(
149
- `Could not find WASM artifact for ${circuitName}. ` +
150
- `Please run 'pnpm run build:all' in the circuits package.`,
151
- );
152
- }
153
-
154
- // Load zkey
155
- let zkeyLoaded = false;
156
- for (const candidate of zkeyCandidates) {
157
- try {
158
- zkey = await readBinaryResource(candidate);
159
- zkeyLoaded = true;
160
- break;
161
- } catch {
162
- // Try next candidate
163
- }
164
- }
165
-
166
- if (!zkeyLoaded) {
167
- throw new CoreError(
168
- `Could not find zkey artifact for ${circuitName}. ` +
169
- `Please run 'pnpm run build:all' in the circuits package.`,
170
- );
171
- }
172
-
173
- // Load vkey
174
- let vkeyLoaded = false;
175
- for (const candidate of vkeyCandidates) {
176
- try {
177
- const vkeyText = await readTextResource(candidate);
178
- vkey = JSON.parse(vkeyText);
179
- vkeyLoaded = true;
180
- break;
181
- } catch {
182
- // Try next candidate
183
- }
184
- }
185
-
186
- if (!vkeyLoaded) {
187
- throw new CoreError(
188
- `Could not find verification key for ${circuitName}. ` +
189
- `Please run 'pnpm run build:all' in the circuits package.`,
190
- );
191
- }
192
- }
193
-
194
- // Verify all artifacts were loaded
195
- if (!wasm || !zkey || !vkey) {
196
- throw new CoreError(
197
- `Failed to load all artifacts for ${circuitName}. ` +
198
- `Missing: ${!wasm ? "wasm " : ""}${!zkey ? "zkey " : ""}${!vkey ? "vkey" : ""}`,
199
- );
200
- }
201
-
202
- // Cache the artifacts for future calls
203
- // TypeScript now knows these are defined after the check above
204
- const artifacts = { wasm, zkey, vkey };
205
- artifactCache[circuitName] = artifacts;
206
-
207
- return artifacts;
208
- }
209
-
210
- async function readBinaryResource(relativePath: string): Promise<Uint8Array> {
211
- const url = new URL(relativePath, import.meta.url);
212
-
213
- try {
214
- if (url.protocol === "file:") {
215
- const fs = (await import("fs")).default;
216
- const readPromise: Promise<Buffer> = new Promise((resolve, reject) => {
217
- fs.readFile(url.pathname, (err, data) => {
218
- if (err) {
219
- reject(err);
220
- } else {
221
- resolve(data);
222
- }
223
- });
224
- });
225
- const buf = await readPromise;
226
- return new Uint8Array(buf);
227
- }
228
- const response = await fetch(url);
229
- if (!response.ok) {
230
- throw new CoreError(
231
- `failed to fetch ${relativePath}: ${response.statusText}`,
232
- );
233
- }
234
- return new Uint8Array(await response.arrayBuffer());
235
- } catch (error) {
236
- throw new CoreError(
237
- `failed to read binary resource ${relativePath}: ${
238
- (error as Error).message
239
- }`,
240
- );
241
- }
242
- }
243
-
244
- async function readTextResource(relativePath: string): Promise<string> {
245
- const url = new URL(relativePath, import.meta.url);
246
- if (url.protocol === "file:") {
247
- const fs = (await import("fs")).default;
248
- const readPromise: Promise<Buffer> = new Promise((resolve, reject) => {
249
- fs.readFile(url.pathname, (err, data) => {
250
- if (err) {
251
- reject(err);
252
- } else {
253
- resolve(data);
254
- }
255
- });
256
- });
257
- const buf = await readPromise;
258
- return buf.toString("utf-8");
259
- }
260
-
261
- const response = await fetch(url);
262
- if (!response.ok) {
263
- throw new CoreError(
264
- `failed to fetch ${relativePath}: ${response.statusText}`,
265
- );
266
- }
267
- return response.text();
268
- }
269
-
270
- export async function proveTransaction(
271
- input: JoinsplitProofInput,
272
- ): Promise<JoinsplitProof> {
273
- try {
274
- // Auto-detect circuit based on input dimensions
275
- const nInputs = input.nullifiers.length;
276
- const nOutputs = input.commitmentsOut.length;
277
-
278
- const circuit = selectCircuit(nInputs, nOutputs);
279
-
280
- // Fetch circuit artifacts (wasm and zkey)
281
- const { wasm, vkey, zkey } = await fetchCircuitArtifacts(circuit.name);
282
-
283
- const inputSignals = input as unknown as Record<
284
- string,
285
- bigint | bigint[] | string
286
- >;
287
-
288
- const { proof, publicSignals } = await snarkjs.groth16.fullProve(
289
- inputSignals,
290
- wasm,
291
- zkey,
292
- );
293
-
294
- // Additional verification step (optional)
295
- const isValid = await snarkjs.groth16.verify(vkey, publicSignals, proof);
296
- if (!isValid) {
297
- throw new CoreError("generated proof is invalid");
298
- }
299
-
300
- return {
301
- proof,
302
- publicSignals,
303
- };
304
- } catch (error) {
305
- throw new CoreError("proof generation failed: " + (error as Error).message);
306
- }
307
- }
308
-
309
- /**
310
- * Get verification key for a specific circuit configuration
311
- * @param inputs Number of inputs (nullifiers)
312
- * @param outputs Number of outputs (commitments)
313
- * @returns Verification key for the circuit
314
- */
315
- export async function getVerificationKey(
316
- inputs: number,
317
- outputs: number,
318
- ): Promise<VerificationKey> {
319
- try {
320
- const circuit = selectCircuit(inputs, outputs);
321
- const { vkey } = await fetchCircuitArtifacts(circuit.name);
322
- return vkey;
323
- } catch (error) {
324
- throw new CoreError(
325
- "failed to load verification key: " + (error as Error).message,
326
- );
327
- }
328
- }
329
-
330
- /**
331
- * Verify a proof with public signals
332
- * Auto-detects the circuit from the public signals structure
333
- * @param proof Groth16 proof
334
- * @param publicSignals Public signals array
335
- * @returns True if proof is valid
336
- */
337
- export async function verifyProof(
338
- proof: Groth16Proof,
339
- publicSignals: PublicSignals,
340
- ): Promise<boolean> {
341
- try {
342
- // Public signals structure: [merkleRoot, boundParamsHash, ...nullifiers, ...commitments]
343
- // We need to determine the circuit from the length
344
- // This is tricky without additional context, so we'll need to try to infer
345
- // or require explicit circuit specification
346
-
347
- // For now, extract nullifier and commitment counts from the public signals
348
- // The caller should know this information, but we can make an educated guess
349
- // based on the total length and circuit registry
350
-
351
- // Length = 2 (root + hash) + nInputs + nOutputs
352
- const totalLength = publicSignals.length;
353
- const variableCount = totalLength - 2; // Remove merkleRoot and boundParamsHash
354
-
355
- // Try to find a matching circuit
356
- let vkey: VerificationKey | null = null;
357
- for (const circuitKey of SUPPORTED_CIRCUITS) {
358
- const parts = circuitKey.split("x");
359
- const config = getCircuitConfig(parseInt(parts[0]!), parseInt(parts[1]!));
360
- if (config && config.inputs + config.outputs === variableCount) {
361
- const artifacts = await fetchCircuitArtifacts(config.name);
362
- vkey = artifacts.vkey;
363
- break;
364
- }
365
- }
366
-
367
- if (!vkey) {
368
- throw new CoreError(
369
- `Could not determine circuit from ${totalLength} public signals`,
370
- );
371
- }
372
-
373
- return await snarkjs.groth16.verify(vkey, publicSignals, proof);
374
- } catch (error) {
375
- throw new CoreError(
376
- "proof verification failed: " + (error as Error).message,
377
- );
378
- }
379
- }
380
-
381
- /**
382
- * Verify a proof with explicit circuit specification
383
- * Preferred method when you know the circuit dimensions
384
- * @param proof Groth16 proof
385
- * @param publicSignals Public signals array
386
- * @param inputs Number of inputs (nullifiers)
387
- * @param outputs Number of outputs (commitments)
388
- * @returns True if proof is valid
389
- */
390
- export async function verifyProofWithCircuit(
391
- proof: Groth16Proof,
392
- publicSignals: PublicSignals,
393
- inputs: number,
394
- outputs: number,
395
- ): Promise<boolean> {
396
- try {
397
- const circuit = selectCircuit(inputs, outputs);
398
- const { vkey } = await fetchCircuitArtifacts(circuit.name);
399
- return await snarkjs.groth16.verify(vkey, publicSignals, proof);
400
- } catch (error) {
401
- throw new CoreError(
402
- "proof verification failed: " + (error as Error).message,
403
- );
404
- }
405
- }