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