@veilo/sdk-core 0.1.17 → 0.4.0

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 (218) hide show
  1. package/README.md +1296 -272
  2. package/SHIELD_INTEGRATION.md +143 -0
  3. package/config.d.ts +2 -0
  4. package/config.js +4 -0
  5. package/dist/cjs/client.d.ts +407 -0
  6. package/dist/cjs/client.js +951 -0
  7. package/dist/cjs/compactNote.d.ts +107 -0
  8. package/dist/cjs/compactNote.js +167 -0
  9. package/dist/cjs/config.d.ts +82 -0
  10. package/dist/cjs/config.js +57 -0
  11. package/dist/cjs/events.d.ts +77 -0
  12. package/dist/cjs/events.js +167 -0
  13. package/dist/cjs/idl/privacy_pool.d.ts +5 -0
  14. package/dist/cjs/idl/privacy_pool.js +15218 -0
  15. package/dist/cjs/idl/privacy_pool.json +10313 -0
  16. package/dist/cjs/index.d.ts +16 -0
  17. package/dist/cjs/index.js +67 -0
  18. package/dist/cjs/merkle.d.ts +77 -0
  19. package/dist/cjs/merkle.js +156 -0
  20. package/dist/cjs/poseidon.d.ts +29 -0
  21. package/dist/cjs/poseidon.js +100 -0
  22. package/dist/cjs/program.d.ts +37 -0
  23. package/dist/cjs/program.js +61 -0
  24. package/dist/cjs/proof.d.ts +183 -0
  25. package/dist/cjs/proof.js +292 -0
  26. package/dist/cjs/prover.d.ts +54 -0
  27. package/dist/cjs/prover.js +112 -0
  28. package/dist/cjs/random.d.ts +16 -0
  29. package/dist/cjs/random.js +28 -0
  30. package/dist/cjs/relayer.d.ts +318 -0
  31. package/dist/cjs/relayer.js +257 -0
  32. package/dist/cjs/retry.d.ts +32 -0
  33. package/dist/cjs/retry.js +75 -0
  34. package/dist/cjs/shield/alt.d.ts +87 -0
  35. package/dist/cjs/shield/alt.js +194 -0
  36. package/dist/cjs/shield/computeBudget.d.ts +61 -0
  37. package/dist/cjs/shield/computeBudget.js +64 -0
  38. package/dist/cjs/shield/errors.d.ts +58 -0
  39. package/dist/cjs/shield/errors.js +121 -0
  40. package/dist/cjs/shield/finalize.d.ts +45 -0
  41. package/dist/cjs/shield/finalize.js +119 -0
  42. package/dist/cjs/shield/index.d.ts +35 -0
  43. package/dist/cjs/shield/index.js +68 -0
  44. package/dist/cjs/shield/ix.d.ts +54 -0
  45. package/dist/cjs/shield/ix.js +119 -0
  46. package/dist/cjs/shield/owner.d.ts +36 -0
  47. package/dist/cjs/shield/owner.js +126 -0
  48. package/dist/cjs/shield/ports.d.ts +43 -0
  49. package/dist/cjs/shield/ports.js +153 -0
  50. package/dist/cjs/shield/preflight.d.ts +30 -0
  51. package/dist/cjs/shield/preflight.js +154 -0
  52. package/dist/cjs/shield/shield.d.ts +68 -0
  53. package/dist/cjs/shield/shield.js +499 -0
  54. package/dist/cjs/shield/types.d.ts +202 -0
  55. package/dist/cjs/shield/types.js +2 -0
  56. package/dist/cjs/utxo.d.ts +235 -0
  57. package/dist/cjs/utxo.js +407 -0
  58. package/dist/esm/client.d.ts +407 -0
  59. package/dist/esm/client.js +891 -0
  60. package/dist/esm/compactNote.d.ts +107 -0
  61. package/dist/esm/compactNote.js +156 -0
  62. package/dist/esm/config.d.ts +82 -0
  63. package/dist/esm/config.js +51 -0
  64. package/dist/esm/events.d.ts +77 -0
  65. package/dist/esm/events.js +129 -0
  66. package/dist/esm/idl/privacy_pool.d.ts +5 -0
  67. package/dist/esm/idl/privacy_pool.js +15216 -0
  68. package/dist/esm/idl/privacy_pool.json +10313 -0
  69. package/dist/esm/index.d.ts +16 -0
  70. package/dist/esm/index.js +29 -0
  71. package/dist/esm/merkle.d.ts +77 -0
  72. package/dist/esm/merkle.js +151 -0
  73. package/dist/esm/package.json +1 -0
  74. package/dist/esm/poseidon.d.ts +29 -0
  75. package/dist/esm/poseidon.js +87 -0
  76. package/dist/esm/program.d.ts +37 -0
  77. package/dist/esm/program.js +53 -0
  78. package/dist/esm/proof.d.ts +183 -0
  79. package/dist/esm/proof.js +281 -0
  80. package/dist/esm/prover.d.ts +54 -0
  81. package/dist/esm/prover.js +75 -0
  82. package/dist/esm/random.d.ts +16 -0
  83. package/dist/esm/random.js +21 -0
  84. package/dist/esm/relayer.d.ts +318 -0
  85. package/dist/esm/relayer.js +249 -0
  86. package/dist/esm/retry.d.ts +32 -0
  87. package/dist/esm/retry.js +71 -0
  88. package/dist/esm/shield/alt.d.ts +87 -0
  89. package/dist/esm/shield/alt.js +186 -0
  90. package/dist/esm/shield/computeBudget.d.ts +61 -0
  91. package/dist/esm/shield/computeBudget.js +61 -0
  92. package/dist/esm/shield/errors.d.ts +58 -0
  93. package/dist/esm/shield/errors.js +115 -0
  94. package/dist/esm/shield/finalize.d.ts +45 -0
  95. package/dist/esm/shield/finalize.js +83 -0
  96. package/dist/esm/shield/index.d.ts +35 -0
  97. package/dist/esm/shield/index.js +32 -0
  98. package/dist/esm/shield/ix.d.ts +54 -0
  99. package/dist/esm/shield/ix.js +82 -0
  100. package/dist/esm/shield/owner.d.ts +36 -0
  101. package/dist/esm/shield/owner.js +122 -0
  102. package/dist/esm/shield/ports.d.ts +43 -0
  103. package/dist/esm/shield/ports.js +147 -0
  104. package/dist/esm/shield/preflight.d.ts +30 -0
  105. package/dist/esm/shield/preflight.js +151 -0
  106. package/dist/esm/shield/shield.d.ts +68 -0
  107. package/dist/esm/shield/shield.js +492 -0
  108. package/dist/esm/shield/types.d.ts +202 -0
  109. package/dist/esm/shield/types.js +1 -0
  110. package/dist/esm/utxo.d.ts +235 -0
  111. package/dist/esm/utxo.js +382 -0
  112. package/dist/src/client.d.ts +407 -0
  113. package/dist/src/client.js +951 -0
  114. package/dist/src/compactNote.d.ts +107 -0
  115. package/dist/src/compactNote.js +167 -0
  116. package/dist/src/config.d.ts +82 -0
  117. package/dist/src/config.js +57 -0
  118. package/dist/src/events.d.ts +77 -0
  119. package/dist/src/events.js +167 -0
  120. package/dist/src/idl/privacy_pool.d.ts +5 -0
  121. package/dist/src/idl/privacy_pool.js +15218 -0
  122. package/dist/src/index.d.ts +16 -0
  123. package/dist/src/index.js +67 -0
  124. package/dist/src/merkle.d.ts +77 -0
  125. package/dist/src/merkle.js +156 -0
  126. package/dist/src/poseidon.d.ts +29 -0
  127. package/dist/src/poseidon.js +100 -0
  128. package/dist/src/program.d.ts +37 -0
  129. package/dist/src/program.js +61 -0
  130. package/dist/src/proof.d.ts +183 -0
  131. package/dist/src/proof.js +292 -0
  132. package/dist/src/prover.d.ts +54 -0
  133. package/dist/src/prover.js +112 -0
  134. package/dist/src/random.d.ts +16 -0
  135. package/dist/src/random.js +28 -0
  136. package/dist/src/relayer.d.ts +318 -0
  137. package/dist/src/relayer.js +257 -0
  138. package/dist/src/retry.d.ts +32 -0
  139. package/dist/src/retry.js +75 -0
  140. package/dist/src/shield/alt.d.ts +87 -0
  141. package/dist/src/shield/alt.js +194 -0
  142. package/dist/src/shield/computeBudget.d.ts +61 -0
  143. package/dist/src/shield/computeBudget.js +64 -0
  144. package/dist/src/shield/errors.d.ts +58 -0
  145. package/dist/src/shield/errors.js +121 -0
  146. package/dist/src/shield/finalize.d.ts +45 -0
  147. package/dist/src/shield/finalize.js +119 -0
  148. package/dist/src/shield/index.d.ts +35 -0
  149. package/dist/src/shield/index.js +68 -0
  150. package/dist/src/shield/ix.d.ts +54 -0
  151. package/dist/src/shield/ix.js +119 -0
  152. package/dist/src/shield/owner.d.ts +36 -0
  153. package/dist/src/shield/owner.js +126 -0
  154. package/dist/src/shield/ports.d.ts +43 -0
  155. package/dist/src/shield/ports.js +153 -0
  156. package/dist/src/shield/preflight.d.ts +30 -0
  157. package/dist/src/shield/preflight.js +154 -0
  158. package/dist/src/shield/shield.d.ts +68 -0
  159. package/dist/src/shield/shield.js +499 -0
  160. package/dist/src/shield/types.d.ts +202 -0
  161. package/dist/src/shield/types.js +2 -0
  162. package/dist/src/utxo.d.ts +235 -0
  163. package/dist/src/utxo.js +407 -0
  164. package/dist/tests/compact-note.test.d.ts +1 -0
  165. package/dist/tests/compact-note.test.js +173 -0
  166. package/dist/tests/config.test.d.ts +1 -0
  167. package/dist/tests/config.test.js +102 -0
  168. package/dist/tests/edge-cases.test.d.ts +1 -0
  169. package/dist/tests/edge-cases.test.js +220 -0
  170. package/dist/tests/encryption.test.d.ts +1 -0
  171. package/dist/tests/encryption.test.js +215 -0
  172. package/dist/tests/events.test.d.ts +1 -0
  173. package/dist/tests/events.test.js +78 -0
  174. package/dist/tests/multi-tree.test.d.ts +1 -0
  175. package/dist/tests/multi-tree.test.js +405 -0
  176. package/dist/tests/pda.test.d.ts +1 -0
  177. package/dist/tests/pda.test.js +229 -0
  178. package/dist/tests/poseidon-builder-parity.test.d.ts +1 -0
  179. package/dist/tests/poseidon-builder-parity.test.js +72 -0
  180. package/dist/tests/poseidon.test.d.ts +1 -0
  181. package/dist/tests/poseidon.test.js +142 -0
  182. package/dist/tests/proof.test.d.ts +1 -0
  183. package/dist/tests/proof.test.js +296 -0
  184. package/dist/tests/relayer.test.d.ts +1 -0
  185. package/dist/tests/relayer.test.js +271 -0
  186. package/dist/tests/sdk.integration.test.d.ts +1 -0
  187. package/dist/tests/sdk.integration.test.js +330 -0
  188. package/dist/tests/shield-owner.test.d.ts +1 -0
  189. package/dist/tests/shield-owner.test.js +89 -0
  190. package/dist/tests/shield-preflight.test.d.ts +1 -0
  191. package/dist/tests/shield-preflight.test.js +87 -0
  192. package/dist/tests/shield-realproof.test.d.ts +1 -0
  193. package/dist/tests/shield-realproof.test.js +272 -0
  194. package/dist/tests/shield.test.d.ts +1 -0
  195. package/dist/tests/shield.test.js +403 -0
  196. package/dist/tests/utxo.test.d.ts +1 -0
  197. package/dist/tests/utxo.test.js +140 -0
  198. package/package.json +105 -11
  199. package/poseidon.d.ts +2 -0
  200. package/poseidon.js +4 -0
  201. package/proof.d.ts +2 -0
  202. package/proof.js +4 -0
  203. package/prover.d.ts +2 -0
  204. package/prover.js +4 -0
  205. package/shield.d.ts +2 -0
  206. package/shield.js +4 -0
  207. package/src/client.ts +0 -352
  208. package/src/config.ts +0 -13
  209. package/src/index.ts +0 -6
  210. package/src/merkle.ts +0 -178
  211. package/src/note.ts +0 -193
  212. package/src/poseidon.ts +0 -62
  213. package/src/proof.ts +0 -170
  214. package/test/script.js +0 -0
  215. package/test-tsconfig.json +0 -19
  216. package/tests/note.test.ts +0 -50
  217. package/tests/sdk.integration.test.ts +0 -210
  218. package/tsconfig.json +0 -18
@@ -0,0 +1,16 @@
1
+ export * from "./client.js";
2
+ export * from "./utxo.js";
3
+ export * from "./config.js";
4
+ export * from "./merkle.js";
5
+ export * from "./proof.js";
6
+ export * from "./events.js";
7
+ export { createVeiloProgram, createReadonlyVeiloProgram, PRIVACY_POOL_IDL, PRIVACY_POOL_PROGRAM_ID, } from "./program.js";
8
+ export * from "./shield/index.js";
9
+ export { createTransactionProver, verifyProof } from "./prover.js";
10
+ export type { CircuitArtifacts } from "./prover.js";
11
+ export * from "./compactNote.js";
12
+ export { randomBytes, randomBytes32 } from "./random.js";
13
+ export * from "./relayer.js";
14
+ export { withRpcRetry, DEFAULT_RPC_RETRY } from "./retry.js";
15
+ export type { RpcRetryPolicy } from "./retry.js";
16
+ export { initPoseidon, getPoseidon, BN254_FR_MODULUS, bytesToBigIntBE, bigIntToBytesBE, frToBigInt, poseidon1, poseidon2, poseidon3, poseidon4, pubkeyToField, } from "./poseidon.js";
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.pubkeyToField = exports.poseidon4 = exports.poseidon3 = exports.poseidon2 = exports.poseidon1 = exports.frToBigInt = exports.bigIntToBytesBE = exports.bytesToBigIntBE = exports.BN254_FR_MODULUS = exports.getPoseidon = exports.initPoseidon = exports.DEFAULT_RPC_RETRY = exports.withRpcRetry = exports.randomBytes32 = exports.randomBytes = exports.verifyProof = exports.createTransactionProver = exports.PRIVACY_POOL_PROGRAM_ID = exports.PRIVACY_POOL_IDL = exports.createReadonlyVeiloProgram = exports.createVeiloProgram = void 0;
18
+ // Core client functions
19
+ __exportStar(require("./client.js"), exports);
20
+ // UTXO types and functions (replaces note.ts)
21
+ __exportStar(require("./utxo.js"), exports);
22
+ // Configuration constants and types
23
+ __exportStar(require("./config.js"), exports);
24
+ // Merkle tree implementation
25
+ __exportStar(require("./merkle.js"), exports);
26
+ // Proof types and helpers
27
+ __exportStar(require("./proof.js"), exports);
28
+ // On-chain event scanning and tree reconstruction
29
+ __exportStar(require("./events.js"), exports);
30
+ // Program factory and IDL
31
+ var program_js_1 = require("./program.js");
32
+ Object.defineProperty(exports, "createVeiloProgram", { enumerable: true, get: function () { return program_js_1.createVeiloProgram; } });
33
+ Object.defineProperty(exports, "createReadonlyVeiloProgram", { enumerable: true, get: function () { return program_js_1.createReadonlyVeiloProgram; } });
34
+ Object.defineProperty(exports, "PRIVACY_POOL_IDL", { enumerable: true, get: function () { return program_js_1.PRIVACY_POOL_IDL; } });
35
+ Object.defineProperty(exports, "PRIVACY_POOL_PROGRAM_ID", { enumerable: true, get: function () { return program_js_1.PRIVACY_POOL_PROGRAM_ID; } });
36
+ // Wallet-agnostic shielding — build an unsigned deposit for any external wallet
37
+ __exportStar(require("./shield/index.js"), exports);
38
+ // Proof generation (requires snarkjs peer dependency)
39
+ var prover_js_1 = require("./prover.js");
40
+ Object.defineProperty(exports, "createTransactionProver", { enumerable: true, get: function () { return prover_js_1.createTransactionProver; } });
41
+ Object.defineProperty(exports, "verifyProof", { enumerable: true, get: function () { return prover_js_1.verifyProof; } });
42
+ // Compact note ciphers — the on-chain payload that makes notes recoverable
43
+ // from chain data alone, without any relayer involvement.
44
+ __exportStar(require("./compactNote.js"), exports);
45
+ // Cross-platform CSPRNG (no node:crypto import — safe in browser bundles)
46
+ var random_js_1 = require("./random.js");
47
+ Object.defineProperty(exports, "randomBytes", { enumerable: true, get: function () { return random_js_1.randomBytes; } });
48
+ Object.defineProperty(exports, "randomBytes32", { enumerable: true, get: function () { return random_js_1.randomBytes32; } });
49
+ // Relayer API client
50
+ __exportStar(require("./relayer.js"), exports);
51
+ // RPC retry / resilience
52
+ var retry_js_1 = require("./retry.js");
53
+ Object.defineProperty(exports, "withRpcRetry", { enumerable: true, get: function () { return retry_js_1.withRpcRetry; } });
54
+ Object.defineProperty(exports, "DEFAULT_RPC_RETRY", { enumerable: true, get: function () { return retry_js_1.DEFAULT_RPC_RETRY; } });
55
+ // Poseidon hash functions
56
+ var poseidon_js_1 = require("./poseidon.js");
57
+ Object.defineProperty(exports, "initPoseidon", { enumerable: true, get: function () { return poseidon_js_1.initPoseidon; } });
58
+ Object.defineProperty(exports, "getPoseidon", { enumerable: true, get: function () { return poseidon_js_1.getPoseidon; } });
59
+ Object.defineProperty(exports, "BN254_FR_MODULUS", { enumerable: true, get: function () { return poseidon_js_1.BN254_FR_MODULUS; } });
60
+ Object.defineProperty(exports, "bytesToBigIntBE", { enumerable: true, get: function () { return poseidon_js_1.bytesToBigIntBE; } });
61
+ Object.defineProperty(exports, "bigIntToBytesBE", { enumerable: true, get: function () { return poseidon_js_1.bigIntToBytesBE; } });
62
+ Object.defineProperty(exports, "frToBigInt", { enumerable: true, get: function () { return poseidon_js_1.frToBigInt; } });
63
+ Object.defineProperty(exports, "poseidon1", { enumerable: true, get: function () { return poseidon_js_1.poseidon1; } });
64
+ Object.defineProperty(exports, "poseidon2", { enumerable: true, get: function () { return poseidon_js_1.poseidon2; } });
65
+ Object.defineProperty(exports, "poseidon3", { enumerable: true, get: function () { return poseidon_js_1.poseidon3; } });
66
+ Object.defineProperty(exports, "poseidon4", { enumerable: true, get: function () { return poseidon_js_1.poseidon4; } });
67
+ Object.defineProperty(exports, "pubkeyToField", { enumerable: true, get: function () { return poseidon_js_1.pubkeyToField; } });
@@ -0,0 +1,77 @@
1
+ export type MerklePath = {
2
+ /** Index of the leaf in the tree (0-based) */
3
+ leafIndex: number;
4
+ /** Sibling hashes from leaf level up to (but not including) the root */
5
+ path: Uint8Array[];
6
+ /**
7
+ * 0 = current node is left child, sibling is right
8
+ * 1 = current node is right child, sibling is left
9
+ * (matches your Circom `pathIndices` semantics)
10
+ */
11
+ indices: number[];
12
+ };
13
+ /**
14
+ * Circuit-compatible Merkle path format.
15
+ * The pathIndex is used directly (circuit converts to bits internally via Num2Bits).
16
+ */
17
+ export type CircuitMerklePath = {
18
+ /** Leaf index (circuit converts to bits internally) */
19
+ pathIndex: number;
20
+ /** Sibling hashes as field elements */
21
+ pathElements: bigint[];
22
+ };
23
+ export type Bytes32 = Uint8Array;
24
+ /**
25
+ * Fixed-depth binary Merkle tree over BN254 Fr:
26
+ * - Leaves and internal nodes are 32-byte big-endian Fr elements.
27
+ * - Hash is Poseidon(2)(left, right).
28
+ * - Unfilled leaves use the Poseidon zero chain:
29
+ * zero[0] = 0
30
+ * zero[i+1] = Poseidon(zero[i], zero[i])
31
+ *
32
+ * Depth must match:
33
+ * - Circom WithdrawCircuit(depth)
34
+ * - Rust MERKLE_TREE_HEIGHT
35
+ */
36
+ export declare class MerkleTree {
37
+ readonly depth: number;
38
+ readonly zeroes: Uint8Array[];
39
+ readonly layers: Uint8Array[][];
40
+ nextIndex: number;
41
+ constructor(depth?: number);
42
+ get capacity(): number;
43
+ get root(): Uint8Array;
44
+ /**
45
+ * Insert a leaf and recompute the path up to the root.
46
+ * Returns the leaf index and the new root.
47
+ */
48
+ insert(leaf: Uint8Array): {
49
+ index: number;
50
+ root: Uint8Array;
51
+ };
52
+ /**
53
+ * Return Merkle proof (path + indices) for a given leaf index.
54
+ * This feeds directly into the Circom `MerklePathVerifier(depth)`:
55
+ * - `pathElements[i]` = sibling
56
+ * - `pathIndices[i]` = 0/1 as defined above
57
+ */
58
+ getPath(index: number): MerklePath;
59
+ /**
60
+ * Return Merkle proof in circuit-compatible format.
61
+ * The circuit uses pathIndex directly and converts to bits via Num2Bits(levels).
62
+ */
63
+ getCircuitPath(index: number): CircuitMerklePath;
64
+ }
65
+ /**
66
+ * The Poseidon zero chain: `z[0] = 0`, `z[i+1] = Poseidon(z[i], z[i])`.
67
+ *
68
+ * This is the `zeroes` array a `MerkleTree` builds in its constructor, without
69
+ * the tree. Deposits need a Merkle path for their dummy inputs, but the circuit
70
+ * disables the path check when a input amount is zero (`enabled <== 1 - IsZero(amount)`
71
+ * in transaction.circom), so the values are never constrained — only their
72
+ * count is.
73
+ *
74
+ * Allocating a full depth-22 `MerkleTree` for this costs ~130 MB and several
75
+ * seconds. This costs 22 hashes. Any deposit-shaped transaction should use it.
76
+ */
77
+ export declare function poseidonZeroChain(depth?: number): Uint8Array[];
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MerkleTree = void 0;
4
+ exports.poseidonZeroChain = poseidonZeroChain;
5
+ const poseidon_js_1 = require("./poseidon.js");
6
+ // Poseidon-based hash of two 32-byte field elements.
7
+ function hashPair(left, right) {
8
+ if (left.length !== 32 || right.length !== 32) {
9
+ throw new Error("hashPair expects 32-byte inputs");
10
+ }
11
+ const poseidon = (0, poseidon_js_1.getPoseidon)();
12
+ const lf = (0, poseidon_js_1.bytesToBigIntBE)(left) % poseidon_js_1.BN254_FR_MODULUS;
13
+ const rf = (0, poseidon_js_1.bytesToBigIntBE)(right) % poseidon_js_1.BN254_FR_MODULUS;
14
+ const fe = poseidon([lf, rf]);
15
+ const outBig = (0, poseidon_js_1.frToBigInt)(fe) % poseidon_js_1.BN254_FR_MODULUS;
16
+ return (0, poseidon_js_1.bigIntToBytesBE)(outBig);
17
+ }
18
+ /**
19
+ * Fixed-depth binary Merkle tree over BN254 Fr:
20
+ * - Leaves and internal nodes are 32-byte big-endian Fr elements.
21
+ * - Hash is Poseidon(2)(left, right).
22
+ * - Unfilled leaves use the Poseidon zero chain:
23
+ * zero[0] = 0
24
+ * zero[i+1] = Poseidon(zero[i], zero[i])
25
+ *
26
+ * Depth must match:
27
+ * - Circom WithdrawCircuit(depth)
28
+ * - Rust MERKLE_TREE_HEIGHT
29
+ */
30
+ class MerkleTree {
31
+ constructor(depth = 22) {
32
+ this.depth = depth;
33
+ this.zeroes = [];
34
+ this.layers = [];
35
+ // zero[0] = 0 (Fr), then zero[i+1] = Poseidon(zero[i], zero[i])
36
+ let zero = (0, poseidon_js_1.bigIntToBytesBE)(0n);
37
+ this.zeroes.push(zero);
38
+ for (let level = 1; level <= depth; level++) {
39
+ zero = hashPair(zero, zero);
40
+ this.zeroes.push(zero);
41
+ }
42
+ // Allocate layers:
43
+ // level 0: 2^depth leaves
44
+ // level 1: 2^(depth-1) parents
45
+ // ...
46
+ // level depth: 1 root
47
+ for (let level = 0; level <= depth; level++) {
48
+ const size = 1 << (depth - level);
49
+ if (!Number.isSafeInteger(size) || size <= 0) {
50
+ throw new Error(`Invalid MerkleTree depth=${depth}, level=${level}, size=${size}`);
51
+ }
52
+ const arr = new Array(size);
53
+ for (let i = 0; i < size; i++) {
54
+ arr[i] = this.zeroes[level];
55
+ }
56
+ this.layers.push(arr);
57
+ }
58
+ this.nextIndex = 0;
59
+ }
60
+ get capacity() {
61
+ return 1 << this.depth;
62
+ }
63
+ get root() {
64
+ return this.layers[this.depth][0];
65
+ }
66
+ /**
67
+ * Insert a leaf and recompute the path up to the root.
68
+ * Returns the leaf index and the new root.
69
+ */
70
+ insert(leaf) {
71
+ if (leaf.length !== 32) {
72
+ throw new Error("leaf must be 32 bytes");
73
+ }
74
+ const index = this.nextIndex;
75
+ if (index >= this.capacity) {
76
+ throw new Error("Merkle tree is full");
77
+ }
78
+ // Set leaf
79
+ this.layers[0][index] = leaf;
80
+ // Bubble up
81
+ let idx = index;
82
+ for (let level = 1; level <= this.depth; level++) {
83
+ const parentIndex = Math.floor(idx / 2);
84
+ const leftIndex = parentIndex * 2;
85
+ const rightIndex = leftIndex + 1;
86
+ const left = this.layers[level - 1][leftIndex];
87
+ const right = rightIndex < this.layers[level - 1].length
88
+ ? this.layers[level - 1][rightIndex]
89
+ : this.zeroes[level - 1];
90
+ this.layers[level][parentIndex] = hashPair(left, right);
91
+ idx = parentIndex;
92
+ }
93
+ this.nextIndex++;
94
+ return { index, root: this.root };
95
+ }
96
+ /**
97
+ * Return Merkle proof (path + indices) for a given leaf index.
98
+ * This feeds directly into the Circom `MerklePathVerifier(depth)`:
99
+ * - `pathElements[i]` = sibling
100
+ * - `pathIndices[i]` = 0/1 as defined above
101
+ */
102
+ getPath(index) {
103
+ if (index < 0 || index >= this.capacity) {
104
+ throw new Error("index out of range");
105
+ }
106
+ const path = [];
107
+ const indices = [];
108
+ let idx = index;
109
+ for (let level = 0; level < this.depth; level++) {
110
+ const isRight = idx % 2 === 1;
111
+ const siblingIndex = isRight ? idx - 1 : idx + 1;
112
+ const sibling = siblingIndex < this.layers[level].length
113
+ ? this.layers[level][siblingIndex]
114
+ : this.zeroes[level];
115
+ path.push(sibling);
116
+ // 0 = current is left, 1 = current is right
117
+ indices.push(isRight ? 1 : 0);
118
+ idx = Math.floor(idx / 2);
119
+ }
120
+ return { leafIndex: index, path, indices };
121
+ }
122
+ /**
123
+ * Return Merkle proof in circuit-compatible format.
124
+ * The circuit uses pathIndex directly and converts to bits via Num2Bits(levels).
125
+ */
126
+ getCircuitPath(index) {
127
+ const merklePath = this.getPath(index);
128
+ return {
129
+ pathIndex: index,
130
+ pathElements: merklePath.path.map((p) => (0, poseidon_js_1.bytesToBigIntBE)(p) % poseidon_js_1.BN254_FR_MODULUS),
131
+ };
132
+ }
133
+ }
134
+ exports.MerkleTree = MerkleTree;
135
+ /**
136
+ * The Poseidon zero chain: `z[0] = 0`, `z[i+1] = Poseidon(z[i], z[i])`.
137
+ *
138
+ * This is the `zeroes` array a `MerkleTree` builds in its constructor, without
139
+ * the tree. Deposits need a Merkle path for their dummy inputs, but the circuit
140
+ * disables the path check when a input amount is zero (`enabled <== 1 - IsZero(amount)`
141
+ * in transaction.circom), so the values are never constrained — only their
142
+ * count is.
143
+ *
144
+ * Allocating a full depth-22 `MerkleTree` for this costs ~130 MB and several
145
+ * seconds. This costs 22 hashes. Any deposit-shaped transaction should use it.
146
+ */
147
+ function poseidonZeroChain(depth = 22) {
148
+ const zeroes = [];
149
+ let zero = (0, poseidon_js_1.bigIntToBytesBE)(0n);
150
+ zeroes.push(zero);
151
+ for (let level = 1; level <= depth; level++) {
152
+ zero = hashPair(zero, zero);
153
+ zeroes.push(zero);
154
+ }
155
+ return zeroes;
156
+ }
@@ -0,0 +1,29 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ /** Poseidon hash function type from circomlibjs. */
3
+ export type PoseidonFn = ((inputs: bigint[]) => any) & {
4
+ F: {
5
+ toObject: (e: any) => bigint;
6
+ };
7
+ };
8
+ /** Initialize the Poseidon hash instance. Must be called once before using any UTXO/merkle/proof helpers. */
9
+ export declare function initPoseidon(): Promise<void>;
10
+ /** Get the initialized Poseidon instance. Throws if `initPoseidon()` has not been called. */
11
+ export declare function getPoseidon(): PoseidonFn;
12
+ /** The BN254 (alt_bn128) scalar field modulus. All Poseidon outputs are reduced modulo this value. */
13
+ export declare const BN254_FR_MODULUS: bigint;
14
+ /** Convert a big-endian byte array to a bigint. */
15
+ export declare function bytesToBigIntBE(bytes: Uint8Array): bigint;
16
+ /** Convert a bigint to a 32-byte big-endian array. */
17
+ export declare function bigIntToBytesBE(x: bigint): Uint8Array;
18
+ /** Convert ffjavascript field element → bigint safely */
19
+ export declare function frToBigInt(fe: any): bigint;
20
+ /** Poseidon hash with 1 input - used for keypair derivation: pubkey = Poseidon(privateKey) */
21
+ export declare function poseidon1(a: bigint): bigint;
22
+ /** Poseidon hash with 2 inputs */
23
+ export declare function poseidon2(a: bigint, b: bigint): bigint;
24
+ /** Poseidon hash with 3 inputs - used for signature: Poseidon(privateKey, commitment, pathIndex) */
25
+ export declare function poseidon3(a: bigint, b: bigint, c: bigint): bigint;
26
+ /** Poseidon hash with 4 inputs - used for UTXO commitment: Poseidon(amount, pubkey, blinding, mintAddress) */
27
+ export declare function poseidon4(a: bigint, b: bigint, c: bigint, d: bigint): bigint;
28
+ /** Convert a Solana PublicKey to a BN254 field element */
29
+ export declare function pubkeyToField(pubkey: PublicKey): bigint;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BN254_FR_MODULUS = void 0;
4
+ exports.initPoseidon = initPoseidon;
5
+ exports.getPoseidon = getPoseidon;
6
+ exports.bytesToBigIntBE = bytesToBigIntBE;
7
+ exports.bigIntToBytesBE = bigIntToBytesBE;
8
+ exports.frToBigInt = frToBigInt;
9
+ exports.poseidon1 = poseidon1;
10
+ exports.poseidon2 = poseidon2;
11
+ exports.poseidon3 = poseidon3;
12
+ exports.poseidon4 = poseidon4;
13
+ exports.pubkeyToField = pubkeyToField;
14
+ const circomlibjs_1 = require("circomlibjs");
15
+ let poseidonInstance = null;
16
+ /** Initialize the Poseidon hash instance. Must be called once before using any UTXO/merkle/proof helpers. */
17
+ async function initPoseidon() {
18
+ poseidonInstance = (await (0, circomlibjs_1.buildPoseidonReference)());
19
+ }
20
+ /** Get the initialized Poseidon instance. Throws if `initPoseidon()` has not been called. */
21
+ function getPoseidon() {
22
+ if (!poseidonInstance) {
23
+ throw new Error("Poseidon not initialized. Call initPoseidon() once before using utxo/merkle/proof helpers.");
24
+ }
25
+ return poseidonInstance;
26
+ }
27
+ /** The BN254 (alt_bn128) scalar field modulus. All Poseidon outputs are reduced modulo this value. */
28
+ exports.BN254_FR_MODULUS = BigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
29
+ /** Convert a big-endian byte array to a bigint. */
30
+ function bytesToBigIntBE(bytes) {
31
+ let x = 0n;
32
+ for (const b of bytes) {
33
+ x = (x << 8n) | BigInt(b);
34
+ }
35
+ return x;
36
+ }
37
+ /** Convert a bigint to a 32-byte big-endian array. */
38
+ function bigIntToBytesBE(x) {
39
+ const out = new Uint8Array(32);
40
+ let v = x;
41
+ for (let i = 31; i >= 0; i--) {
42
+ out[i] = Number(v & 0xffn);
43
+ v >>= 8n;
44
+ }
45
+ return out;
46
+ }
47
+ /** Convert ffjavascript field element → bigint safely */
48
+ function frToBigInt(fe) {
49
+ const poseidon = getPoseidon();
50
+ const F = poseidon.F;
51
+ if (typeof fe === "bigint") {
52
+ return fe;
53
+ }
54
+ if (F && typeof F.toObject === "function") {
55
+ // This is how ffjavascript exposes the underlying BigInt
56
+ return F.toObject(fe);
57
+ }
58
+ // Fallback: treat as decimal string
59
+ return BigInt(fe.toString());
60
+ }
61
+ // -----------------------------------------------------------------------------
62
+ // Helper functions for variable-arity Poseidon hashing
63
+ // -----------------------------------------------------------------------------
64
+ /** Poseidon hash with 1 input - used for keypair derivation: pubkey = Poseidon(privateKey) */
65
+ function poseidon1(a) {
66
+ const poseidon = getPoseidon();
67
+ const fe = poseidon([a % exports.BN254_FR_MODULUS]);
68
+ return frToBigInt(fe) % exports.BN254_FR_MODULUS;
69
+ }
70
+ /** Poseidon hash with 2 inputs */
71
+ function poseidon2(a, b) {
72
+ const poseidon = getPoseidon();
73
+ const fe = poseidon([a % exports.BN254_FR_MODULUS, b % exports.BN254_FR_MODULUS]);
74
+ return frToBigInt(fe) % exports.BN254_FR_MODULUS;
75
+ }
76
+ /** Poseidon hash with 3 inputs - used for signature: Poseidon(privateKey, commitment, pathIndex) */
77
+ function poseidon3(a, b, c) {
78
+ const poseidon = getPoseidon();
79
+ const fe = poseidon([
80
+ a % exports.BN254_FR_MODULUS,
81
+ b % exports.BN254_FR_MODULUS,
82
+ c % exports.BN254_FR_MODULUS,
83
+ ]);
84
+ return frToBigInt(fe) % exports.BN254_FR_MODULUS;
85
+ }
86
+ /** Poseidon hash with 4 inputs - used for UTXO commitment: Poseidon(amount, pubkey, blinding, mintAddress) */
87
+ function poseidon4(a, b, c, d) {
88
+ const poseidon = getPoseidon();
89
+ const fe = poseidon([
90
+ a % exports.BN254_FR_MODULUS,
91
+ b % exports.BN254_FR_MODULUS,
92
+ c % exports.BN254_FR_MODULUS,
93
+ d % exports.BN254_FR_MODULUS,
94
+ ]);
95
+ return frToBigInt(fe) % exports.BN254_FR_MODULUS;
96
+ }
97
+ /** Convert a Solana PublicKey to a BN254 field element */
98
+ function pubkeyToField(pubkey) {
99
+ return bytesToBigIntBE(pubkey.toBytes()) % exports.BN254_FR_MODULUS;
100
+ }
@@ -0,0 +1,37 @@
1
+ import { Program, Idl, Wallet } from "@coral-xyz/anchor";
2
+ import { Connection, PublicKey } from "@solana/web3.js";
3
+ export declare const PRIVACY_POOL_IDL: Idl;
4
+ /** Deployed program ID extracted from the bundled IDL. */
5
+ export declare const PRIVACY_POOL_PROGRAM_ID: PublicKey;
6
+ /**
7
+ * Create an Anchor `Program` instance for the Veilo Privacy Pool.
8
+ *
9
+ * @param connection Solana RPC connection
10
+ * @param wallet Anchor-compatible wallet (must implement `publicKey` and `signTransaction`)
11
+ * @param opts Optional commitment level (default: "confirmed")
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import { createVeiloProgram } from "@veilo/sdk-core";
16
+ * import { Connection } from "@solana/web3.js";
17
+ *
18
+ * const program = createVeiloProgram(
19
+ * new Connection("https://api.devnet.solana.com"),
20
+ * wallet,
21
+ * );
22
+ * ```
23
+ */
24
+ export declare function createVeiloProgram(connection: Connection, wallet: Wallet, opts?: {
25
+ commitment?: "processed" | "confirmed" | "finalized";
26
+ }): Program;
27
+ /**
28
+ * Create a `Program` for reading on-chain accounts, with no wallet.
29
+ *
30
+ * The shield path never signs, so requiring a `Wallet` just to decode a
31
+ * `MerkleTreeAccount` would force integrators to invent a dummy one. This is
32
+ * safe for `program.account.*.fetch` and the coders; anything that would submit
33
+ * a transaction will fail, which is the intent.
34
+ */
35
+ export declare function createReadonlyVeiloProgram(connection: Connection, opts?: {
36
+ commitment?: "processed" | "confirmed" | "finalized";
37
+ }): Program;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PRIVACY_POOL_PROGRAM_ID = exports.PRIVACY_POOL_IDL = void 0;
7
+ exports.createVeiloProgram = createVeiloProgram;
8
+ exports.createReadonlyVeiloProgram = createReadonlyVeiloProgram;
9
+ const anchor_1 = require("@coral-xyz/anchor");
10
+ const web3_js_1 = require("@solana/web3.js");
11
+ const privacy_pool_js_1 = __importDefault(require("./idl/privacy_pool.js"));
12
+ // Re-export so consumers can access the raw IDL if needed
13
+ exports.PRIVACY_POOL_IDL = privacy_pool_js_1.default;
14
+ /** Deployed program ID extracted from the bundled IDL. */
15
+ exports.PRIVACY_POOL_PROGRAM_ID = new web3_js_1.PublicKey(privacy_pool_js_1.default.address);
16
+ /**
17
+ * Create an Anchor `Program` instance for the Veilo Privacy Pool.
18
+ *
19
+ * @param connection Solana RPC connection
20
+ * @param wallet Anchor-compatible wallet (must implement `publicKey` and `signTransaction`)
21
+ * @param opts Optional commitment level (default: "confirmed")
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { createVeiloProgram } from "@veilo/sdk-core";
26
+ * import { Connection } from "@solana/web3.js";
27
+ *
28
+ * const program = createVeiloProgram(
29
+ * new Connection("https://api.devnet.solana.com"),
30
+ * wallet,
31
+ * );
32
+ * ```
33
+ */
34
+ function createVeiloProgram(connection, wallet, opts) {
35
+ const provider = new anchor_1.AnchorProvider(connection, wallet, {
36
+ commitment: opts?.commitment ?? "confirmed",
37
+ });
38
+ return new anchor_1.Program(exports.PRIVACY_POOL_IDL, provider);
39
+ }
40
+ /**
41
+ * Create a `Program` for reading on-chain accounts, with no wallet.
42
+ *
43
+ * The shield path never signs, so requiring a `Wallet` just to decode a
44
+ * `MerkleTreeAccount` would force integrators to invent a dummy one. This is
45
+ * safe for `program.account.*.fetch` and the coders; anything that would submit
46
+ * a transaction will fail, which is the intent.
47
+ */
48
+ function createReadonlyVeiloProgram(connection, opts) {
49
+ const provider = new anchor_1.AnchorProvider(connection,
50
+ // No signing surface: reads only.
51
+ {
52
+ publicKey: web3_js_1.PublicKey.default,
53
+ signTransaction: () => {
54
+ throw new Error("createReadonlyVeiloProgram: this program cannot sign");
55
+ },
56
+ signAllTransactions: () => {
57
+ throw new Error("createReadonlyVeiloProgram: this program cannot sign");
58
+ },
59
+ }, { commitment: opts?.commitment ?? "confirmed" });
60
+ return new anchor_1.Program(exports.PRIVACY_POOL_IDL, provider);
61
+ }