@cloak.ag/sdk 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,303 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/utils/crypto.ts
9
+ import { buildPoseidon } from "circomlibjs";
10
+ var poseidon = null;
11
+ async function getPoseidon() {
12
+ if (!poseidon) {
13
+ poseidon = await buildPoseidon();
14
+ }
15
+ return poseidon;
16
+ }
17
+ async function poseidonHash(inputs) {
18
+ const p = await getPoseidon();
19
+ const hash = p(inputs.map((x) => p.F.e(x)));
20
+ return p.F.toObject(hash);
21
+ }
22
+ function splitTo2Limbs(value) {
23
+ const mask = (1n << 128n) - 1n;
24
+ const lo = value & mask;
25
+ const hi = value >> 128n;
26
+ return [lo, hi];
27
+ }
28
+ function pubkeyToLimbs(pubkey) {
29
+ const bytes = typeof pubkey.toBytes === "function" ? pubkey.toBytes() : pubkey;
30
+ const value = BigInt("0x" + Buffer.from(bytes).toString("hex"));
31
+ return splitTo2Limbs(value);
32
+ }
33
+ async function computeMerkleRoot(leaf, pathElements, pathIndices) {
34
+ let current = leaf;
35
+ for (let i = 0; i < pathElements.length; i++) {
36
+ if (pathIndices[i] === 0) {
37
+ current = await poseidonHash([current, pathElements[i]]);
38
+ } else {
39
+ current = await poseidonHash([pathElements[i], current]);
40
+ }
41
+ }
42
+ return current;
43
+ }
44
+ function hexToBigint(hex) {
45
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
46
+ return BigInt("0x" + cleanHex);
47
+ }
48
+ async function computeCommitment(amount, r, sk_spend) {
49
+ const [sk0, sk1] = splitTo2Limbs(sk_spend);
50
+ const [r0, r1] = splitTo2Limbs(r);
51
+ const pk_spend = await poseidonHash([sk0, sk1]);
52
+ return await poseidonHash([amount, r0, r1, pk_spend]);
53
+ }
54
+ async function generateCommitmentAsync(amountLamports, r, skSpend) {
55
+ const amount = BigInt(amountLamports);
56
+ const rValue = hexToBigint(bytesToHex(r));
57
+ const skValue = hexToBigint(bytesToHex(skSpend));
58
+ return await computeCommitment(amount, rValue, skValue);
59
+ }
60
+ function generateCommitment(_amountLamports, _r, _skSpend) {
61
+ throw new Error("generateCommitment is deprecated. Use generateCommitmentAsync instead.");
62
+ }
63
+ async function computeNullifier(sk_spend, leafIndex) {
64
+ const [sk0, sk1] = splitTo2Limbs(sk_spend);
65
+ return await poseidonHash([sk0, sk1, leafIndex]);
66
+ }
67
+ async function computeNullifierAsync(skSpend, leafIndex) {
68
+ const skValue = typeof skSpend === "string" ? hexToBigint(skSpend) : hexToBigint(bytesToHex(skSpend));
69
+ return await computeNullifier(skValue, BigInt(leafIndex));
70
+ }
71
+ function computeNullifierSync(_skSpend, _leafIndex) {
72
+ throw new Error("computeNullifierSync is deprecated. Use computeNullifierAsync instead.");
73
+ }
74
+ async function computeOutputsHashAsync(outputs) {
75
+ let hash = 0n;
76
+ for (const output of outputs) {
77
+ const [lo, hi] = pubkeyToLimbs(output.recipient);
78
+ hash = await poseidonHash([hash, lo, hi, BigInt(output.amount)]);
79
+ }
80
+ return hash;
81
+ }
82
+ async function computeOutputsHash(outAddr, outAmount, outFlags) {
83
+ let hash = 0n;
84
+ for (let i = 0; i < 5; i++) {
85
+ if (outFlags[i] === 1) {
86
+ hash = await poseidonHash([hash, outAddr[i][0], outAddr[i][1], outAmount[i]]);
87
+ }
88
+ }
89
+ return hash;
90
+ }
91
+ async function computeOutputsHashFromLimbs(outAddr, outAmount, outFlags) {
92
+ return await computeOutputsHash(outAddr, outAmount, outFlags);
93
+ }
94
+ function computeOutputsHashSync(_outputs) {
95
+ throw new Error("computeOutputsHashSync is deprecated. Use computeOutputsHashAsync instead.");
96
+ }
97
+ async function computeSwapOutputsHash(inputMintLimbs, outputMintLimbs, recipientAtaLimbs, minOutputAmount, publicAmount) {
98
+ return await poseidonHash([
99
+ inputMintLimbs[0],
100
+ inputMintLimbs[1],
101
+ outputMintLimbs[0],
102
+ outputMintLimbs[1],
103
+ recipientAtaLimbs[0],
104
+ recipientAtaLimbs[1],
105
+ minOutputAmount,
106
+ publicAmount
107
+ ]);
108
+ }
109
+ async function computeSwapOutputsHashAsync(inputMint, outputMint, recipientAta, minOutputAmount, amount) {
110
+ const inputMintLimbs = pubkeyToLimbs(inputMint);
111
+ const outputMintLimbs = pubkeyToLimbs(outputMint);
112
+ const recipientAtaLimbs = pubkeyToLimbs(recipientAta);
113
+ return await computeSwapOutputsHash(
114
+ inputMintLimbs,
115
+ outputMintLimbs,
116
+ recipientAtaLimbs,
117
+ BigInt(minOutputAmount),
118
+ BigInt(amount)
119
+ );
120
+ }
121
+ function computeSwapOutputsHashSync(_outputMint, _recipientAta, _minOutputAmount, _amount) {
122
+ throw new Error("computeSwapOutputsHashSync is deprecated. Use computeSwapOutputsHashAsync instead.");
123
+ }
124
+ function bigintToBytes32(n) {
125
+ const hex = n.toString(16).padStart(64, "0");
126
+ const bytes = new Uint8Array(32);
127
+ for (let i = 0; i < 32; i++) {
128
+ bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
129
+ }
130
+ return bytes;
131
+ }
132
+ function hexToBytes(hex) {
133
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
134
+ const bytes = new Uint8Array(cleanHex.length / 2);
135
+ for (let i = 0; i < cleanHex.length; i += 2) {
136
+ bytes[i / 2] = parseInt(cleanHex.substr(i, 2), 16);
137
+ }
138
+ return bytes;
139
+ }
140
+ function bytesToHex(bytes, prefix = false) {
141
+ const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
142
+ return prefix ? `0x${hex}` : hex;
143
+ }
144
+ function randomBytes(length) {
145
+ const bytes = new Uint8Array(length);
146
+ const g = globalThis;
147
+ try {
148
+ const cryptoObj = g?.crypto || g?.window?.crypto || g?.self?.crypto;
149
+ if (cryptoObj && typeof cryptoObj.getRandomValues === "function") {
150
+ cryptoObj.getRandomValues(bytes);
151
+ return bytes;
152
+ }
153
+ } catch {
154
+ }
155
+ try {
156
+ const nodeCrypto = __require("crypto");
157
+ if (nodeCrypto?.randomBytes) {
158
+ const buffer = nodeCrypto.randomBytes(length);
159
+ bytes.set(buffer);
160
+ return bytes;
161
+ }
162
+ if (nodeCrypto?.webcrypto?.getRandomValues) {
163
+ nodeCrypto.webcrypto.getRandomValues(bytes);
164
+ return bytes;
165
+ }
166
+ } catch {
167
+ }
168
+ for (let i = 0; i < length; i++) bytes[i] = Math.floor(Math.random() * 256);
169
+ return bytes;
170
+ }
171
+ function isValidHex(hex, expectedLength) {
172
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
173
+ if (!/^[0-9a-f]*$/i.test(cleanHex)) {
174
+ return false;
175
+ }
176
+ if (cleanHex.length % 2 !== 0) {
177
+ return false;
178
+ }
179
+ if (expectedLength !== void 0) {
180
+ return cleanHex.length === expectedLength * 2;
181
+ }
182
+ return true;
183
+ }
184
+ var BN254_MODULUS = BigInt("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47");
185
+ function proofToBytes(proof) {
186
+ const pi_a_x = BigInt(proof.pi_a[0]);
187
+ const pi_a_y = BigInt(proof.pi_a[1]);
188
+ const pi_a_y_neg = (BN254_MODULUS - pi_a_y) % BN254_MODULUS;
189
+ const pi_a_x_le = bigintToBytes32LE(pi_a_x);
190
+ const pi_a_y_neg_le = bigintToBytes32LE(pi_a_y_neg);
191
+ const pi_a_le = new Uint8Array(64);
192
+ pi_a_le.set(pi_a_x_le, 0);
193
+ pi_a_le.set(pi_a_y_neg_le, 32);
194
+ const pi_a_be = convertEndianness32(pi_a_le);
195
+ const pi_b_x1 = BigInt(proof.pi_b[0][0]);
196
+ const pi_b_x2 = BigInt(proof.pi_b[0][1]);
197
+ const pi_b_y1 = BigInt(proof.pi_b[1][0]);
198
+ const pi_b_y2 = BigInt(proof.pi_b[1][1]);
199
+ const pi_b_x1_le = bigintToBytes32LE(pi_b_x1);
200
+ const pi_b_x2_le = bigintToBytes32LE(pi_b_x2);
201
+ const pi_b_y1_le = bigintToBytes32LE(pi_b_y1);
202
+ const pi_b_y2_le = bigintToBytes32LE(pi_b_y2);
203
+ const pi_b_le = new Uint8Array(128);
204
+ pi_b_le.set(pi_b_x1_le, 0);
205
+ pi_b_le.set(pi_b_x2_le, 32);
206
+ pi_b_le.set(pi_b_y1_le, 64);
207
+ pi_b_le.set(pi_b_y2_le, 96);
208
+ const pi_b_be = convertEndianness64(pi_b_le);
209
+ const pi_c_x = BigInt(proof.pi_c[0]);
210
+ const pi_c_y = BigInt(proof.pi_c[1]);
211
+ const pi_c_x_le = bigintToBytes32LE(pi_c_x);
212
+ const pi_c_y_le = bigintToBytes32LE(pi_c_y);
213
+ const pi_c_le = new Uint8Array(64);
214
+ pi_c_le.set(pi_c_x_le, 0);
215
+ pi_c_le.set(pi_c_y_le, 32);
216
+ const pi_c_be = convertEndianness32(pi_c_le);
217
+ const result = new Uint8Array(256);
218
+ result.set(pi_a_be, 0);
219
+ result.set(pi_b_be, 64);
220
+ result.set(pi_c_be, 192);
221
+ return result;
222
+ }
223
+ function bigintToBytes32LE(n) {
224
+ const bytes = new Uint8Array(32);
225
+ let value = n % BN254_MODULUS;
226
+ if (value < 0) {
227
+ value = (value + BN254_MODULUS) % BN254_MODULUS;
228
+ }
229
+ for (let i = 0; i < 32; i++) {
230
+ bytes[i] = Number(value & BigInt(255));
231
+ value = value >> BigInt(8);
232
+ }
233
+ return bytes;
234
+ }
235
+ function convertEndianness32(bytes) {
236
+ if (bytes.length !== 64) {
237
+ throw new Error("convertEndianness32 expects 64 bytes");
238
+ }
239
+ const result = new Uint8Array(64);
240
+ for (let i = 0; i < 32; i++) {
241
+ result[i] = bytes[31 - i];
242
+ }
243
+ for (let i = 0; i < 32; i++) {
244
+ result[32 + i] = bytes[63 - i];
245
+ }
246
+ return result;
247
+ }
248
+ function convertEndianness64(bytes) {
249
+ if (bytes.length !== 128) {
250
+ throw new Error("convertEndianness64 expects 128 bytes");
251
+ }
252
+ const result = new Uint8Array(128);
253
+ for (let i = 0; i < 64; i++) {
254
+ result[i] = bytes[63 - i];
255
+ }
256
+ for (let i = 0; i < 64; i++) {
257
+ result[64 + i] = bytes[127 - i];
258
+ }
259
+ return result;
260
+ }
261
+ function buildPublicInputsBytes(root, nullifier, outputsHash, publicAmount) {
262
+ const result = new Uint8Array(104);
263
+ result.set(bigintToBytes32(root), 0);
264
+ result.set(bigintToBytes32(nullifier), 32);
265
+ result.set(bigintToBytes32(outputsHash), 64);
266
+ const amountBytes = new Uint8Array(8);
267
+ let amt = publicAmount;
268
+ for (let i = 7; i >= 0; i--) {
269
+ amountBytes[i] = Number(amt & 0xffn);
270
+ amt = amt >> 8n;
271
+ }
272
+ result.set(amountBytes, 96);
273
+ return result;
274
+ }
275
+
276
+ export {
277
+ __require,
278
+ poseidonHash,
279
+ splitTo2Limbs,
280
+ pubkeyToLimbs,
281
+ computeMerkleRoot,
282
+ hexToBigint,
283
+ computeCommitment,
284
+ generateCommitmentAsync,
285
+ generateCommitment,
286
+ computeNullifier,
287
+ computeNullifierAsync,
288
+ computeNullifierSync,
289
+ computeOutputsHashAsync,
290
+ computeOutputsHash,
291
+ computeOutputsHashFromLimbs,
292
+ computeOutputsHashSync,
293
+ computeSwapOutputsHash,
294
+ computeSwapOutputsHashAsync,
295
+ computeSwapOutputsHashSync,
296
+ bigintToBytes32,
297
+ hexToBytes,
298
+ bytesToHex,
299
+ randomBytes,
300
+ isValidHex,
301
+ proofToBytes,
302
+ buildPublicInputsBytes
303
+ };
@@ -0,0 +1,54 @@
1
+ import {
2
+ bigintToBytes32,
3
+ buildPublicInputsBytes,
4
+ bytesToHex,
5
+ computeCommitment,
6
+ computeMerkleRoot,
7
+ computeNullifier,
8
+ computeNullifierAsync,
9
+ computeNullifierSync,
10
+ computeOutputsHash,
11
+ computeOutputsHashAsync,
12
+ computeOutputsHashFromLimbs,
13
+ computeOutputsHashSync,
14
+ computeSwapOutputsHash,
15
+ computeSwapOutputsHashAsync,
16
+ computeSwapOutputsHashSync,
17
+ generateCommitment,
18
+ generateCommitmentAsync,
19
+ hexToBigint,
20
+ hexToBytes,
21
+ isValidHex,
22
+ poseidonHash,
23
+ proofToBytes,
24
+ pubkeyToLimbs,
25
+ randomBytes,
26
+ splitTo2Limbs
27
+ } from "./chunk-S76QK36U.js";
28
+ export {
29
+ bigintToBytes32,
30
+ buildPublicInputsBytes,
31
+ bytesToHex,
32
+ computeCommitment,
33
+ computeMerkleRoot,
34
+ computeNullifier,
35
+ computeNullifierAsync,
36
+ computeNullifierSync,
37
+ computeOutputsHash,
38
+ computeOutputsHashAsync,
39
+ computeOutputsHashFromLimbs,
40
+ computeOutputsHashSync,
41
+ computeSwapOutputsHash,
42
+ computeSwapOutputsHashAsync,
43
+ computeSwapOutputsHashSync,
44
+ generateCommitment,
45
+ generateCommitmentAsync,
46
+ hexToBigint,
47
+ hexToBytes,
48
+ isValidHex,
49
+ poseidonHash,
50
+ proofToBytes,
51
+ pubkeyToLimbs,
52
+ randomBytes,
53
+ splitTo2Limbs
54
+ };
package/dist/index.cjs CHANGED
@@ -39,7 +39,6 @@ __export(index_exports, {
39
39
  LAMPORTS_PER_SOL: () => LAMPORTS_PER_SOL,
40
40
  LocalStorageAdapter: () => LocalStorageAdapter,
41
41
  MemoryStorageAdapter: () => MemoryStorageAdapter,
42
- ProverService: () => ProverService,
43
42
  RelayService: () => RelayService,
44
43
  VARIABLE_FEE_RATE: () => VARIABLE_FEE_RATE,
45
44
  VERSION: () => VERSION,
@@ -1828,11 +1827,7 @@ async function generateWithdrawRegularProof(inputs, circuitsPath) {
1828
1827
  var_fee: inputs.var_fee.toString(),
1829
1828
  rem: inputs.rem.toString()
1830
1829
  };
1831
- const { proof, publicSignals } = await snarkjs.groth16.fullProve(
1832
- circuitInputs,
1833
- wasmPath,
1834
- zkeyPath
1835
- );
1830
+ const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, wasmPath, zkeyPath);
1836
1831
  const proofBytes = proofToBytes(proof);
1837
1832
  return {
1838
1833
  proof,
@@ -2308,17 +2303,10 @@ var CloakSDK = class {
2308
2303
  const feeBps = Math.ceil(protocolFee * 1e4 / note.amount);
2309
2304
  const distributableAmount = getDistributableAmount2(note.amount);
2310
2305
  validateTransfers(recipients, distributableAmount);
2311
- let merkleProof;
2312
- let merkleRoot;
2313
- if (note.merkleProof && note.root) {
2314
- merkleProof = {
2315
- pathElements: note.merkleProof.pathElements,
2316
- pathIndices: note.merkleProof.pathIndices
2317
- };
2318
- merkleRoot = note.root;
2319
- } else {
2320
- merkleProof = await this.indexer.getMerkleProof(note.leafIndex);
2321
- merkleRoot = merkleProof.root || (await this.indexer.getMerkleRoot()).root;
2306
+ const merkleProof = await this.indexer.getMerkleProof(note.leafIndex);
2307
+ const merkleRoot = merkleProof.root || (await this.indexer.getMerkleRoot()).root;
2308
+ if (!merkleRoot) {
2309
+ throw new Error("Failed to get Merkle root from indexer");
2322
2310
  }
2323
2311
  const nullifier = await computeNullifierAsync(note.sk_spend, note.leafIndex);
2324
2312
  const nullifierHex = nullifier.toString(16).padStart(64, "0");
@@ -2392,6 +2380,13 @@ var CloakSDK = class {
2392
2380
  }
2393
2381
  const sk = splitTo2Limbs(sk_spend_bigint);
2394
2382
  const r = splitTo2Limbs(r_bigint);
2383
+ const computedCommitment = await computeCommitment(amount_bigint, r_bigint, sk_spend_bigint);
2384
+ const noteCommitment = BigInt("0x" + note.commitment);
2385
+ if (computedCommitment !== noteCommitment) {
2386
+ throw new Error(
2387
+ `Commitment mismatch! Computed: ${computedCommitment.toString(16)}, Note: ${note.commitment}. This means the note's sk_spend, r, or amount doesn't match what was deposited.`
2388
+ );
2389
+ }
2395
2390
  const proofInputs = {
2396
2391
  root: root_bigint,
2397
2392
  nullifier: nullifier_bigint,
@@ -2410,7 +2405,9 @@ var CloakSDK = class {
2410
2405
  var_fee: varFee,
2411
2406
  rem
2412
2407
  };
2408
+ options?.onProgress?.("proof_generating");
2413
2409
  const proofResult = await generateWithdrawRegularProof(proofInputs, circuitsPath);
2410
+ options?.onProgress?.("proof_complete");
2414
2411
  proofHex = Buffer.from(proofResult.proofBytes).toString("hex");
2415
2412
  finalPublicInputs = {
2416
2413
  root: merkleRoot,
@@ -2576,30 +2573,27 @@ var CloakSDK = class {
2576
2573
  );
2577
2574
  }
2578
2575
  let recipientAta;
2579
- try {
2580
- const splTokenModule = await import("@solana/spl-token");
2581
- const getAssociatedTokenAddress = splTokenModule.getAssociatedTokenAddress;
2582
- if (!getAssociatedTokenAddress) {
2583
- throw new Error("getAssociatedTokenAddress not found");
2576
+ if (options.recipientAta) {
2577
+ recipientAta = new import_web35.PublicKey(options.recipientAta);
2578
+ } else {
2579
+ try {
2580
+ const splTokenModule = await import("@solana/spl-token");
2581
+ const getAssociatedTokenAddress = splTokenModule.getAssociatedTokenAddress;
2582
+ if (!getAssociatedTokenAddress) {
2583
+ throw new Error("getAssociatedTokenAddress not found");
2584
+ }
2585
+ const outputMint2 = new import_web35.PublicKey(options.outputMint);
2586
+ recipientAta = await getAssociatedTokenAddress(outputMint2, recipient);
2587
+ } catch (error) {
2588
+ throw new Error(
2589
+ `Failed to get associated token account: ${error instanceof Error ? error.message : String(error)}. Please install @solana/spl-token or provide recipientAta in options.`
2590
+ );
2584
2591
  }
2585
- const outputMint2 = new import_web35.PublicKey(options.outputMint);
2586
- recipientAta = await getAssociatedTokenAddress(outputMint2, recipient);
2587
- } catch (error) {
2588
- throw new Error(
2589
- `Failed to get associated token account: ${error instanceof Error ? error.message : String(error)}. Please install @solana/spl-token or provide recipientAta in options.`
2590
- );
2591
2592
  }
2592
- let merkleProof;
2593
- let merkleRoot;
2594
- if (note.merkleProof && note.root) {
2595
- merkleProof = {
2596
- pathElements: note.merkleProof.pathElements,
2597
- pathIndices: note.merkleProof.pathIndices
2598
- };
2599
- merkleRoot = note.root;
2600
- } else {
2601
- merkleProof = await this.indexer.getMerkleProof(note.leafIndex);
2602
- merkleRoot = merkleProof.root || (await this.indexer.getMerkleRoot()).root;
2593
+ const merkleProof = await this.indexer.getMerkleProof(note.leafIndex);
2594
+ const merkleRoot = merkleProof.root || (await this.indexer.getMerkleRoot()).root;
2595
+ if (!merkleRoot) {
2596
+ throw new Error("Failed to get Merkle root from indexer");
2603
2597
  }
2604
2598
  const nullifier = await computeNullifierAsync(note.sk_spend, note.leafIndex);
2605
2599
  const nullifierHex = nullifier.toString(16).padStart(64, "0");
@@ -2635,6 +2629,13 @@ var CloakSDK = class {
2635
2629
  const inputMintLimbs = pubkeyToLimbs(inputMint.toBytes());
2636
2630
  const outputMintLimbs = pubkeyToLimbs(outputMint.toBytes());
2637
2631
  const recipientAtaLimbs = pubkeyToLimbs(recipientAta.toBytes());
2632
+ const computedCommitment = await computeCommitment(amount_bigint, r_bigint, sk_spend_bigint);
2633
+ const noteCommitment = BigInt("0x" + note.commitment);
2634
+ if (computedCommitment !== noteCommitment) {
2635
+ throw new Error(
2636
+ `Commitment mismatch! Computed: ${computedCommitment.toString(16)}, Note: ${note.commitment}. This means the note's sk_spend, r, or amount doesn't match what was deposited.`
2637
+ );
2638
+ }
2638
2639
  const t = amount_bigint * 5n;
2639
2640
  const varFee = t / 1000n;
2640
2641
  const rem = t % 1000n;
@@ -2656,7 +2657,9 @@ var CloakSDK = class {
2656
2657
  var_fee: varFee,
2657
2658
  rem
2658
2659
  };
2660
+ options?.onProgress?.("proof_generating");
2659
2661
  const proofResult = await generateWithdrawSwapProof(proofInputs, circuitsPath);
2662
+ options?.onProgress?.("proof_complete");
2660
2663
  proofHex = Buffer.from(proofResult.proofBytes).toString("hex");
2661
2664
  finalPublicInputs = {
2662
2665
  root: merkleRoot,
@@ -3176,188 +3179,6 @@ function formatErrorForLogging(error) {
3176
3179
  return String(error);
3177
3180
  }
3178
3181
 
3179
- // src/services/ProverService.ts
3180
- var ProverService = class {
3181
- /**
3182
- * Create a new Prover Service client
3183
- *
3184
- * @param indexerUrl - Indexer/Prover service base URL
3185
- * @param timeout - Proof generation timeout in ms (default: 5 minutes)
3186
- */
3187
- constructor(indexerUrl, timeout = 5 * 60 * 1e3) {
3188
- this.indexerUrl = indexerUrl.replace(/\/$/, "");
3189
- this.timeout = timeout;
3190
- }
3191
- /**
3192
- * Generate a zero-knowledge proof for withdrawal
3193
- *
3194
- * This process typically takes 30-180 seconds depending on the backend.
3195
- *
3196
- * @param inputs - Circuit inputs (private + public + outputs)
3197
- * @param options - Optional progress tracking and callbacks
3198
- * @returns Proof result with hex-encoded proof and public inputs
3199
- *
3200
- * @example
3201
- * ```typescript
3202
- * const result = await prover.generateProof(inputs);
3203
- * if (result.success) {
3204
- * console.log(`Proof: ${result.proof}`);
3205
- * }
3206
- * ```
3207
- *
3208
- * @example
3209
- * ```typescript
3210
- * // With progress tracking
3211
- * const result = await prover.generateProof(inputs, {
3212
- * onProgress: (progress) => console.log(`Progress: ${progress}%`),
3213
- * onStart: () => console.log("Starting proof generation..."),
3214
- * onSuccess: (result) => console.log("Proof generated!"),
3215
- * onError: (error) => console.error("Failed:", error)
3216
- * });
3217
- * ```
3218
- */
3219
- async generateProof(inputs, options) {
3220
- const startTime = Date.now();
3221
- const actualTimeout = options?.timeout || this.timeout;
3222
- options?.onStart?.();
3223
- let progressInterval;
3224
- try {
3225
- const requestBody = {
3226
- private_inputs: JSON.stringify(inputs.privateInputs),
3227
- public_inputs: JSON.stringify(inputs.publicInputs),
3228
- outputs: JSON.stringify(inputs.outputs)
3229
- };
3230
- if (inputs.swapParams) {
3231
- requestBody.swap_params = inputs.swapParams;
3232
- }
3233
- const controller = new AbortController();
3234
- const timeoutId = setTimeout(() => controller.abort(), actualTimeout);
3235
- if (options?.onProgress) {
3236
- let progress = 0;
3237
- progressInterval = setInterval(() => {
3238
- progress = Math.min(90, progress + Math.random() * 10);
3239
- options.onProgress(Math.floor(progress));
3240
- }, 2e3);
3241
- }
3242
- const response = await fetch(`${this.indexerUrl}/api/v1/prove`, {
3243
- method: "POST",
3244
- headers: {
3245
- "Content-Type": "application/json"
3246
- },
3247
- body: JSON.stringify(requestBody),
3248
- signal: controller.signal
3249
- });
3250
- clearTimeout(timeoutId);
3251
- if (progressInterval) clearInterval(progressInterval);
3252
- if (!response.ok) {
3253
- let errorMessage = `${response.status} ${response.statusText}`;
3254
- try {
3255
- const errorText = await response.text();
3256
- try {
3257
- const errorJson = JSON.parse(errorText);
3258
- errorMessage = errorJson.error || errorJson.message || errorText;
3259
- } catch {
3260
- errorMessage = errorText || errorMessage;
3261
- }
3262
- } catch {
3263
- }
3264
- options?.onError?.(errorMessage);
3265
- return {
3266
- success: false,
3267
- generationTimeMs: Date.now() - startTime,
3268
- error: errorMessage
3269
- };
3270
- }
3271
- options?.onProgress?.(100);
3272
- const rawData = await response.json();
3273
- const result = {
3274
- success: rawData.success,
3275
- proof: rawData.proof,
3276
- publicInputs: rawData.public_inputs,
3277
- // Map snake_case
3278
- generationTimeMs: rawData.generation_time_ms || Date.now() - startTime,
3279
- error: rawData.error
3280
- };
3281
- if (!result.success && rawData.execution_report) {
3282
- }
3283
- if (!result.success && result.error) {
3284
- try {
3285
- const errorObj = typeof result.error === "string" ? JSON.parse(result.error) : result.error;
3286
- if (errorObj?.error && typeof errorObj.error === "string") {
3287
- result.error = errorObj.error;
3288
- } else if (typeof errorObj === "string") {
3289
- result.error = errorObj;
3290
- }
3291
- if (errorObj?.execution_report && typeof errorObj.execution_report === "string") {
3292
- result.error += `
3293
- Execution report: ${errorObj.execution_report}`;
3294
- }
3295
- if (errorObj?.total_cycles !== void 0) {
3296
- result.error += `
3297
- Total cycles: ${errorObj.total_cycles}`;
3298
- }
3299
- if (errorObj?.total_syscalls !== void 0) {
3300
- result.error += `
3301
- Total syscalls: ${errorObj.total_syscalls}`;
3302
- }
3303
- } catch {
3304
- }
3305
- }
3306
- if (result.success) {
3307
- options?.onSuccess?.(result);
3308
- } else if (result.error) {
3309
- options?.onError?.(result.error);
3310
- }
3311
- return result;
3312
- } catch (error) {
3313
- const totalTime = Date.now() - startTime;
3314
- if (progressInterval) clearInterval(progressInterval);
3315
- let errorMessage;
3316
- if (error instanceof Error && error.name === "AbortError") {
3317
- errorMessage = `Proof generation timed out after ${actualTimeout}ms`;
3318
- } else {
3319
- errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
3320
- }
3321
- options?.onError?.(errorMessage);
3322
- return {
3323
- success: false,
3324
- generationTimeMs: totalTime,
3325
- error: errorMessage
3326
- };
3327
- }
3328
- }
3329
- /**
3330
- * Check if the prover service is available
3331
- *
3332
- * @returns True if service is healthy
3333
- */
3334
- async healthCheck() {
3335
- try {
3336
- const response = await fetch(`${this.indexerUrl}/health`, {
3337
- method: "GET"
3338
- });
3339
- return response.ok;
3340
- } catch {
3341
- return false;
3342
- }
3343
- }
3344
- /**
3345
- * Get the configured timeout
3346
- */
3347
- getTimeout() {
3348
- return this.timeout;
3349
- }
3350
- /**
3351
- * Set a new timeout
3352
- */
3353
- setTimeout(timeout) {
3354
- if (timeout <= 0) {
3355
- throw new Error("Timeout must be positive");
3356
- }
3357
- this.timeout = timeout;
3358
- }
3359
- };
3360
-
3361
3182
  // src/helpers/wallet-integration.ts
3362
3183
  var import_web36 = require("@solana/web3.js");
3363
3184
  function validateWalletConnected(wallet) {
@@ -3443,7 +3264,6 @@ var VERSION = "1.0.0";
3443
3264
  LAMPORTS_PER_SOL,
3444
3265
  LocalStorageAdapter,
3445
3266
  MemoryStorageAdapter,
3446
- ProverService,
3447
3267
  RelayService,
3448
3268
  VARIABLE_FEE_RATE,
3449
3269
  VERSION,