@veilo/sdk-core 0.1.17 → 0.3.3

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 (52) hide show
  1. package/README.md +1257 -272
  2. package/dist/cjs/client.d.ts +407 -0
  3. package/dist/cjs/client.js +914 -0
  4. package/dist/cjs/config.d.ts +82 -0
  5. package/dist/cjs/config.js +57 -0
  6. package/dist/cjs/events.d.ts +77 -0
  7. package/dist/cjs/events.js +167 -0
  8. package/dist/cjs/idl/privacy_pool.json +10313 -0
  9. package/dist/cjs/index.d.ts +13 -0
  10. package/dist/cjs/index.js +57 -0
  11. package/dist/cjs/merkle.d.ts +64 -0
  12. package/dist/cjs/merkle.js +133 -0
  13. package/dist/cjs/poseidon.d.ts +29 -0
  14. package/dist/cjs/poseidon.js +100 -0
  15. package/dist/cjs/program.d.ts +26 -0
  16. package/dist/cjs/program.js +38 -0
  17. package/dist/cjs/proof.d.ts +183 -0
  18. package/dist/cjs/proof.js +292 -0
  19. package/dist/cjs/prover.d.ts +54 -0
  20. package/dist/cjs/prover.js +112 -0
  21. package/dist/cjs/relayer.d.ts +295 -0
  22. package/dist/cjs/relayer.js +246 -0
  23. package/dist/cjs/retry.d.ts +32 -0
  24. package/dist/cjs/retry.js +75 -0
  25. package/dist/cjs/utxo.d.ts +215 -0
  26. package/dist/cjs/utxo.js +394 -0
  27. package/dist/esm/client.js +887 -0
  28. package/dist/esm/config.js +51 -0
  29. package/dist/esm/events.js +129 -0
  30. package/dist/esm/idl/privacy_pool.json +10313 -0
  31. package/dist/esm/index.js +22 -0
  32. package/dist/esm/merkle.js +129 -0
  33. package/dist/esm/poseidon.js +87 -0
  34. package/dist/esm/program.js +31 -0
  35. package/dist/esm/proof.js +281 -0
  36. package/dist/esm/prover.js +75 -0
  37. package/dist/esm/relayer.js +238 -0
  38. package/dist/esm/retry.js +71 -0
  39. package/dist/esm/utxo.js +372 -0
  40. package/package.json +47 -11
  41. package/src/client.ts +0 -352
  42. package/src/config.ts +0 -13
  43. package/src/index.ts +0 -6
  44. package/src/merkle.ts +0 -178
  45. package/src/note.ts +0 -193
  46. package/src/poseidon.ts +0 -62
  47. package/src/proof.ts +0 -170
  48. package/test/script.js +0 -0
  49. package/test-tsconfig.json +0 -19
  50. package/tests/note.test.ts +0 -50
  51. package/tests/sdk.integration.test.ts +0 -210
  52. package/tsconfig.json +0 -18
@@ -0,0 +1,13 @@
1
+ export * from "./client";
2
+ export * from "./utxo";
3
+ export * from "./config";
4
+ export * from "./merkle";
5
+ export * from "./proof";
6
+ export * from "./events";
7
+ export { createVeiloProgram, PRIVACY_POOL_IDL, PRIVACY_POOL_PROGRAM_ID, } from "./program";
8
+ export { createTransactionProver, verifyProof } from "./prover";
9
+ export type { CircuitArtifacts } from "./prover";
10
+ export * from "./relayer";
11
+ export { withRpcRetry, DEFAULT_RPC_RETRY } from "./retry";
12
+ export type { RpcRetryPolicy } from "./retry";
13
+ export { initPoseidon, getPoseidon, BN254_FR_MODULUS, bytesToBigIntBE, bigIntToBytesBE, frToBigInt, poseidon1, poseidon2, poseidon3, poseidon4, pubkeyToField, } from "./poseidon";
@@ -0,0 +1,57 @@
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.verifyProof = exports.createTransactionProver = exports.PRIVACY_POOL_PROGRAM_ID = exports.PRIVACY_POOL_IDL = exports.createVeiloProgram = void 0;
18
+ // Core client functions
19
+ __exportStar(require("./client"), exports);
20
+ // UTXO types and functions (replaces note.ts)
21
+ __exportStar(require("./utxo"), exports);
22
+ // Configuration constants and types
23
+ __exportStar(require("./config"), exports);
24
+ // Merkle tree implementation
25
+ __exportStar(require("./merkle"), exports);
26
+ // Proof types and helpers
27
+ __exportStar(require("./proof"), exports);
28
+ // On-chain event scanning and tree reconstruction
29
+ __exportStar(require("./events"), exports);
30
+ // Program factory and IDL
31
+ var program_1 = require("./program");
32
+ Object.defineProperty(exports, "createVeiloProgram", { enumerable: true, get: function () { return program_1.createVeiloProgram; } });
33
+ Object.defineProperty(exports, "PRIVACY_POOL_IDL", { enumerable: true, get: function () { return program_1.PRIVACY_POOL_IDL; } });
34
+ Object.defineProperty(exports, "PRIVACY_POOL_PROGRAM_ID", { enumerable: true, get: function () { return program_1.PRIVACY_POOL_PROGRAM_ID; } });
35
+ // Proof generation (requires snarkjs peer dependency)
36
+ var prover_1 = require("./prover");
37
+ Object.defineProperty(exports, "createTransactionProver", { enumerable: true, get: function () { return prover_1.createTransactionProver; } });
38
+ Object.defineProperty(exports, "verifyProof", { enumerable: true, get: function () { return prover_1.verifyProof; } });
39
+ // Relayer API client
40
+ __exportStar(require("./relayer"), exports);
41
+ // RPC retry / resilience
42
+ var retry_1 = require("./retry");
43
+ Object.defineProperty(exports, "withRpcRetry", { enumerable: true, get: function () { return retry_1.withRpcRetry; } });
44
+ Object.defineProperty(exports, "DEFAULT_RPC_RETRY", { enumerable: true, get: function () { return retry_1.DEFAULT_RPC_RETRY; } });
45
+ // Poseidon hash functions
46
+ var poseidon_1 = require("./poseidon");
47
+ Object.defineProperty(exports, "initPoseidon", { enumerable: true, get: function () { return poseidon_1.initPoseidon; } });
48
+ Object.defineProperty(exports, "getPoseidon", { enumerable: true, get: function () { return poseidon_1.getPoseidon; } });
49
+ Object.defineProperty(exports, "BN254_FR_MODULUS", { enumerable: true, get: function () { return poseidon_1.BN254_FR_MODULUS; } });
50
+ Object.defineProperty(exports, "bytesToBigIntBE", { enumerable: true, get: function () { return poseidon_1.bytesToBigIntBE; } });
51
+ Object.defineProperty(exports, "bigIntToBytesBE", { enumerable: true, get: function () { return poseidon_1.bigIntToBytesBE; } });
52
+ Object.defineProperty(exports, "frToBigInt", { enumerable: true, get: function () { return poseidon_1.frToBigInt; } });
53
+ Object.defineProperty(exports, "poseidon1", { enumerable: true, get: function () { return poseidon_1.poseidon1; } });
54
+ Object.defineProperty(exports, "poseidon2", { enumerable: true, get: function () { return poseidon_1.poseidon2; } });
55
+ Object.defineProperty(exports, "poseidon3", { enumerable: true, get: function () { return poseidon_1.poseidon3; } });
56
+ Object.defineProperty(exports, "poseidon4", { enumerable: true, get: function () { return poseidon_1.poseidon4; } });
57
+ Object.defineProperty(exports, "pubkeyToField", { enumerable: true, get: function () { return poseidon_1.pubkeyToField; } });
@@ -0,0 +1,64 @@
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
+ }
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MerkleTree = void 0;
4
+ const poseidon_1 = require("./poseidon");
5
+ // Poseidon-based hash of two 32-byte field elements.
6
+ function hashPair(left, right) {
7
+ if (left.length !== 32 || right.length !== 32) {
8
+ throw new Error("hashPair expects 32-byte inputs");
9
+ }
10
+ const poseidon = (0, poseidon_1.getPoseidon)();
11
+ const lf = (0, poseidon_1.bytesToBigIntBE)(left) % poseidon_1.BN254_FR_MODULUS;
12
+ const rf = (0, poseidon_1.bytesToBigIntBE)(right) % poseidon_1.BN254_FR_MODULUS;
13
+ const fe = poseidon([lf, rf]);
14
+ const outBig = (0, poseidon_1.frToBigInt)(fe) % poseidon_1.BN254_FR_MODULUS;
15
+ return (0, poseidon_1.bigIntToBytesBE)(outBig);
16
+ }
17
+ /**
18
+ * Fixed-depth binary Merkle tree over BN254 Fr:
19
+ * - Leaves and internal nodes are 32-byte big-endian Fr elements.
20
+ * - Hash is Poseidon(2)(left, right).
21
+ * - Unfilled leaves use the Poseidon zero chain:
22
+ * zero[0] = 0
23
+ * zero[i+1] = Poseidon(zero[i], zero[i])
24
+ *
25
+ * Depth must match:
26
+ * - Circom WithdrawCircuit(depth)
27
+ * - Rust MERKLE_TREE_HEIGHT
28
+ */
29
+ class MerkleTree {
30
+ constructor(depth = 22) {
31
+ this.depth = depth;
32
+ this.zeroes = [];
33
+ this.layers = [];
34
+ // zero[0] = 0 (Fr), then zero[i+1] = Poseidon(zero[i], zero[i])
35
+ let zero = (0, poseidon_1.bigIntToBytesBE)(0n);
36
+ this.zeroes.push(zero);
37
+ for (let level = 1; level <= depth; level++) {
38
+ zero = hashPair(zero, zero);
39
+ this.zeroes.push(zero);
40
+ }
41
+ // Allocate layers:
42
+ // level 0: 2^depth leaves
43
+ // level 1: 2^(depth-1) parents
44
+ // ...
45
+ // level depth: 1 root
46
+ for (let level = 0; level <= depth; level++) {
47
+ const size = 1 << (depth - level);
48
+ if (!Number.isSafeInteger(size) || size <= 0) {
49
+ throw new Error(`Invalid MerkleTree depth=${depth}, level=${level}, size=${size}`);
50
+ }
51
+ const arr = new Array(size);
52
+ for (let i = 0; i < size; i++) {
53
+ arr[i] = this.zeroes[level];
54
+ }
55
+ this.layers.push(arr);
56
+ }
57
+ this.nextIndex = 0;
58
+ }
59
+ get capacity() {
60
+ return 1 << this.depth;
61
+ }
62
+ get root() {
63
+ return this.layers[this.depth][0];
64
+ }
65
+ /**
66
+ * Insert a leaf and recompute the path up to the root.
67
+ * Returns the leaf index and the new root.
68
+ */
69
+ insert(leaf) {
70
+ if (leaf.length !== 32) {
71
+ throw new Error("leaf must be 32 bytes");
72
+ }
73
+ const index = this.nextIndex;
74
+ if (index >= this.capacity) {
75
+ throw new Error("Merkle tree is full");
76
+ }
77
+ // Set leaf
78
+ this.layers[0][index] = leaf;
79
+ // Bubble up
80
+ let idx = index;
81
+ for (let level = 1; level <= this.depth; level++) {
82
+ const parentIndex = Math.floor(idx / 2);
83
+ const leftIndex = parentIndex * 2;
84
+ const rightIndex = leftIndex + 1;
85
+ const left = this.layers[level - 1][leftIndex];
86
+ const right = rightIndex < this.layers[level - 1].length
87
+ ? this.layers[level - 1][rightIndex]
88
+ : this.zeroes[level - 1];
89
+ this.layers[level][parentIndex] = hashPair(left, right);
90
+ idx = parentIndex;
91
+ }
92
+ this.nextIndex++;
93
+ return { index, root: this.root };
94
+ }
95
+ /**
96
+ * Return Merkle proof (path + indices) for a given leaf index.
97
+ * This feeds directly into the Circom `MerklePathVerifier(depth)`:
98
+ * - `pathElements[i]` = sibling
99
+ * - `pathIndices[i]` = 0/1 as defined above
100
+ */
101
+ getPath(index) {
102
+ if (index < 0 || index >= this.capacity) {
103
+ throw new Error("index out of range");
104
+ }
105
+ const path = [];
106
+ const indices = [];
107
+ let idx = index;
108
+ for (let level = 0; level < this.depth; level++) {
109
+ const isRight = idx % 2 === 1;
110
+ const siblingIndex = isRight ? idx - 1 : idx + 1;
111
+ const sibling = siblingIndex < this.layers[level].length
112
+ ? this.layers[level][siblingIndex]
113
+ : this.zeroes[level];
114
+ path.push(sibling);
115
+ // 0 = current is left, 1 = current is right
116
+ indices.push(isRight ? 1 : 0);
117
+ idx = Math.floor(idx / 2);
118
+ }
119
+ return { leafIndex: index, path, indices };
120
+ }
121
+ /**
122
+ * Return Merkle proof in circuit-compatible format.
123
+ * The circuit uses pathIndex directly and converts to bits via Num2Bits(levels).
124
+ */
125
+ getCircuitPath(index) {
126
+ const merklePath = this.getPath(index);
127
+ return {
128
+ pathIndex: index,
129
+ pathElements: merklePath.path.map((p) => (0, poseidon_1.bytesToBigIntBE)(p) % poseidon_1.BN254_FR_MODULUS),
130
+ };
131
+ }
132
+ }
133
+ exports.MerkleTree = MerkleTree;
@@ -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,26 @@
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;
@@ -0,0 +1,38 @@
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
+ const anchor_1 = require("@coral-xyz/anchor");
9
+ const web3_js_1 = require("@solana/web3.js");
10
+ const privacy_pool_json_1 = __importDefault(require("./idl/privacy_pool.json"));
11
+ // Re-export so consumers can access the raw IDL if needed
12
+ exports.PRIVACY_POOL_IDL = privacy_pool_json_1.default;
13
+ /** Deployed program ID extracted from the bundled IDL. */
14
+ exports.PRIVACY_POOL_PROGRAM_ID = new web3_js_1.PublicKey(privacy_pool_json_1.default.address);
15
+ /**
16
+ * Create an Anchor `Program` instance for the Veilo Privacy Pool.
17
+ *
18
+ * @param connection Solana RPC connection
19
+ * @param wallet Anchor-compatible wallet (must implement `publicKey` and `signTransaction`)
20
+ * @param opts Optional commitment level (default: "confirmed")
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { createVeiloProgram } from "@veilo/sdk-core";
25
+ * import { Connection } from "@solana/web3.js";
26
+ *
27
+ * const program = createVeiloProgram(
28
+ * new Connection("https://api.devnet.solana.com"),
29
+ * wallet,
30
+ * );
31
+ * ```
32
+ */
33
+ function createVeiloProgram(connection, wallet, opts) {
34
+ const provider = new anchor_1.AnchorProvider(connection, wallet, {
35
+ commitment: opts?.commitment ?? "confirmed",
36
+ });
37
+ return new anchor_1.Program(exports.PRIVACY_POOL_IDL, provider);
38
+ }
@@ -0,0 +1,183 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import { SerializedUTXO, InputUTXO } from "./utxo";
3
+ /**
4
+ * External data that gets hashed into ext_data_hash.
5
+ * These are public parameters that affect financial flows.
6
+ */
7
+ export type ExtData = {
8
+ /** Who receives withdrawal (for withdrawals) */
9
+ recipient: PublicKey;
10
+ /** Who submits tx and gets fee */
11
+ relayer: PublicKey;
12
+ /** Fee to relayer in lamports/token units */
13
+ fee: bigint;
14
+ /** Refund to user in lamports/token units (for gas compensation) */
15
+ refund: bigint;
16
+ /** Claimant key committed into the proof */
17
+ claimant: PublicKey;
18
+ };
19
+ /**
20
+ * Transaction circuit inputs (8 public inputs, many private inputs).
21
+ * This structure is used to prepare inputs for the snarkjs prover.
22
+ */
23
+ export type TransactionCircuitInputs = {
24
+ /** Merkle root of UTXO tree */
25
+ root: Uint8Array;
26
+ /** Net deposit/withdrawal amount (positive = deposit, negative = withdrawal) */
27
+ publicAmount: bigint;
28
+ /** Hash of external data (recipient, relayer, fee, refund) */
29
+ extDataHash: Uint8Array;
30
+ /** Token mint address */
31
+ mintAddress: PublicKey;
32
+ /** Nullifiers for the two input UTXOs */
33
+ inputNullifiers: [Uint8Array, Uint8Array];
34
+ /** Commitments for the two output UTXOs */
35
+ outputCommitments: [Uint8Array, Uint8Array];
36
+ inAmount: [bigint, bigint];
37
+ inPubkey: [bigint, bigint];
38
+ inBlinding: [bigint, bigint];
39
+ inPathIndex: [number, number];
40
+ inPathElements: [bigint[], bigint[]];
41
+ inPrivateKey: [bigint, bigint];
42
+ outAmount: [bigint, bigint];
43
+ outPubkey: [bigint, bigint];
44
+ outBlinding: [bigint, bigint];
45
+ };
46
+ /**
47
+ * Proof structure matching the on-chain TransactionProof struct.
48
+ * Total size: 256 bytes (64 + 128 + 64)
49
+ */
50
+ export type TransactionProofStruct = {
51
+ /** G1 point A (64 bytes) */
52
+ proofA: number[];
53
+ /** G2 point B (128 bytes) */
54
+ proofB: number[];
55
+ /** G1 point C (64 bytes) */
56
+ proofC: number[];
57
+ };
58
+ /**
59
+ * Shape of a Groth16 proof produced by snarkjs.
60
+ */
61
+ export type RawProof = {
62
+ pi_a: [string, string, string];
63
+ pi_b: [[string, string], [string, string], [string, string]];
64
+ pi_c: [string, string, string];
65
+ protocol: string;
66
+ curve: string;
67
+ };
68
+ /**
69
+ * Proof builder function type - takes circuit inputs and returns a raw snarkjs proof.
70
+ */
71
+ export type TransactionProofBuilder = (inputs: TransactionCircuitInputs) => Promise<RawProof>;
72
+ /**
73
+ * Compute the external data hash.
74
+ * Matches on-chain computation:
75
+ * hash1 = Poseidon(recipient, relayer)
76
+ * hash2 = Poseidon(fee, refund)
77
+ * extDataHash = Poseidon(hash1, hash2, claimant)
78
+ */
79
+ export declare function computeExtDataHash(extData: ExtData): Uint8Array;
80
+ /**
81
+ * Convert i64 to field element (handles negative via modular arithmetic).
82
+ * For negative values, we add the field modulus to get the equivalent positive representation.
83
+ */
84
+ export declare function i64ToField(value: bigint): bigint;
85
+ /**
86
+ * Prepare transaction circuit inputs from high-level parameters.
87
+ * This converts the SDK types into the format expected by the circuit.
88
+ */
89
+ export declare function prepareTransactionInputs(params: {
90
+ inputUTXOs: [InputUTXO, InputUTXO];
91
+ outputUTXOs: [SerializedUTXO, SerializedUTXO];
92
+ root: Uint8Array;
93
+ publicAmount: bigint;
94
+ extData: ExtData;
95
+ mintAddress: PublicKey;
96
+ }): TransactionCircuitInputs;
97
+ /**
98
+ * Turn a snarkjs Groth16 proof into 256 bytes:
99
+ * A(G1) | B(G2) | C(G1)
100
+ * where:
101
+ * A = (ax, ay) -> 64 bytes
102
+ * B = (bx1, bx0, by1, by0) -> 128 bytes (swapped pairs for alt_bn128)
103
+ * C = (cx, cy) -> 64 bytes
104
+ *
105
+ * Each field element is encoded as 32-byte BE to match the on-chain verifier.
106
+ * We ignore the extra projective/z components snarkjs keeps.
107
+ */
108
+ export declare function packProofToBytes(proof: RawProof): Uint8Array;
109
+ /**
110
+ * Encode a snarkjs proof into the TransactionProofStruct format expected by the on-chain program.
111
+ */
112
+ export declare function encodeSnarkjsProofToTransactionProof(proof: RawProof): TransactionProofStruct;
113
+ /**
114
+ * Convert TransactionCircuitInputs to the format expected by snarkjs.groth16.fullProve().
115
+ * All values are converted to strings (snarkjs expects string inputs for field elements).
116
+ */
117
+ export declare function formatInputsForSnarkjs(inputs: TransactionCircuitInputs): Record<string, any>;
118
+ /**
119
+ * Swap circuit inputs. Matches the signal shape declared by swap.circom's
120
+ * main component (see zk-circuits/swap.circom lines 208-238). Unlike the
121
+ * transaction circuit, the swap circuit distinguishes a "change" output
122
+ * (same mint as source) from a "dest" output (dest mint) and takes a
123
+ * swap-specific params hash and swapAmount alongside the usual inputs.
124
+ */
125
+ export type SwapCircuitInputs = {
126
+ sourceRoot: Uint8Array;
127
+ swapParamsHash: Uint8Array;
128
+ extDataHash: Uint8Array;
129
+ sourceMint: PublicKey;
130
+ destMint: PublicKey;
131
+ inputNullifiers: [Uint8Array, Uint8Array];
132
+ changeCommitment: Uint8Array;
133
+ destCommitment: Uint8Array;
134
+ swapAmount: bigint;
135
+ inAmount: [bigint, bigint];
136
+ inPubkey: [bigint, bigint];
137
+ inBlinding: [bigint, bigint];
138
+ inPathIndex: [number, number];
139
+ inPathElements: [bigint[], bigint[]];
140
+ inPrivateKey: [bigint, bigint];
141
+ changeAmount: bigint;
142
+ changePubkey: bigint;
143
+ changeBlinding: bigint;
144
+ destAmount: bigint;
145
+ destPubkey: bigint;
146
+ destBlinding: bigint;
147
+ minAmountOut: bigint;
148
+ deadline: bigint;
149
+ };
150
+ /**
151
+ * Convert SwapCircuitInputs into the shape expected by
152
+ * snarkjs.groth16.fullProve() for swap.circom. Every value is emitted as a
153
+ * decimal string (or string array) because snarkjs only accepts field
154
+ * elements as strings.
155
+ *
156
+ * Mirrors `generateSwapProof` in
157
+ * relayer-server/src/controllers/swap.helpers.ts so SDK-side swap proofs
158
+ * verify against the same circuit the relayer uses.
159
+ */
160
+ export declare function formatSwapInputsForSnarkjs(inputs: SwapCircuitInputs): Record<string, any>;
161
+ /**
162
+ * Compute the swap params hash that the swap circuit and on-chain program verify.
163
+ * Mirrors relayer-server/src/controllers/swap.helpers.ts `computeSwapParamsHash`.
164
+ *
165
+ * Circuit formula (swap.circom lines 293-307):
166
+ * mintPairHash = Poseidon(sourceMint, destMint)
167
+ * swapTermsHash = Poseidon(minAmountOut, deadline, destAmount)
168
+ * swapParamsHash = Poseidon(mintPairHash, swapTermsHash)
169
+ *
170
+ * @param sourceMint Source pool mint
171
+ * @param destMint Destination pool mint
172
+ * @param minAmountOut Minimum accepted output amount (slippage protected)
173
+ * @param deadline Unix timestamp deadline (i64, 0 = no deadline)
174
+ * @param destAmount Actual amount committed to destination UTXO (≥ minAmountOut -
175
+ * relayerFee). If omitted, defaults to minAmountOut.
176
+ */
177
+ export declare function computeSwapParamsHash(sourceMint: PublicKey, destMint: PublicKey, minAmountOut: bigint, deadline: bigint, destAmount?: bigint): Uint8Array;
178
+ /**
179
+ * Compute the swap data hash committed on-chain for Jupiter instruction integrity.
180
+ * SHA-256 of the raw Jupiter swap instruction data bytes.
181
+ * Mirrors relayer-server/src/controllers/swap.helpers.ts `computeSwapDataHash`.
182
+ */
183
+ export declare function computeSwapDataHash(swapData: Uint8Array | Buffer): Uint8Array;