@cloak.ag/sdk 1.0.7 → 1.0.8
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/dist/index.cjs +129 -31
- package/dist/index.d.cts +48 -1
- package/dist/index.d.ts +48 -1
- package/dist/index.js +124 -31
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -407,6 +407,7 @@ __export(index_exports, {
|
|
|
407
407
|
CLOAK_PROGRAM_ID: () => CLOAK_PROGRAM_ID,
|
|
408
408
|
CloakError: () => CloakError,
|
|
409
409
|
CloakSDK: () => CloakSDK,
|
|
410
|
+
DEFAULT_CIRCUITS_URL: () => DEFAULT_CIRCUITS_URL,
|
|
410
411
|
EXPECTED_CIRCUIT_HASHES: () => EXPECTED_CIRCUIT_HASHES,
|
|
411
412
|
FIXED_FEE_LAMPORTS: () => FIXED_FEE_LAMPORTS,
|
|
412
413
|
LAMPORTS_PER_SOL: () => LAMPORTS_PER_SOL,
|
|
@@ -417,6 +418,7 @@ __export(index_exports, {
|
|
|
417
418
|
ShieldPoolErrors: () => ShieldPoolErrors,
|
|
418
419
|
VARIABLE_FEE_RATE: () => VARIABLE_FEE_RATE,
|
|
419
420
|
VERSION: () => VERSION,
|
|
421
|
+
areCircuitsAvailable: () => areCircuitsAvailable,
|
|
420
422
|
bigintToBytes32: () => bigintToBytes32,
|
|
421
423
|
buildPublicInputsBytes: () => buildPublicInputsBytes,
|
|
422
424
|
bytesToHex: () => bytesToHex,
|
|
@@ -466,14 +468,17 @@ __export(index_exports, {
|
|
|
466
468
|
generateWithdrawRegularProof: () => generateWithdrawRegularProof,
|
|
467
469
|
generateWithdrawSwapProof: () => generateWithdrawSwapProof,
|
|
468
470
|
getAddressExplorerUrl: () => getAddressExplorerUrl,
|
|
471
|
+
getDefaultCircuitsPath: () => getDefaultCircuitsPath,
|
|
469
472
|
getDistributableAmount: () => getDistributableAmount2,
|
|
470
473
|
getExplorerUrl: () => getExplorerUrl,
|
|
474
|
+
getNullifierPDA: () => getNullifierPDA,
|
|
471
475
|
getPendingOperationsSummary: () => getPendingOperationsSummary,
|
|
472
476
|
getPublicKey: () => getPublicKey,
|
|
473
477
|
getPublicViewKey: () => getPublicViewKey,
|
|
474
478
|
getRecipientAmount: () => getRecipientAmount,
|
|
475
479
|
getRpcUrlForNetwork: () => getRpcUrlForNetwork,
|
|
476
480
|
getShieldPoolPDAs: () => getShieldPoolPDAs,
|
|
481
|
+
getSwapStatePDA: () => getSwapStatePDA,
|
|
477
482
|
getViewKey: () => getViewKey,
|
|
478
483
|
hasPendingOperations: () => hasPendingOperations,
|
|
479
484
|
hexToBigint: () => hexToBigint,
|
|
@@ -2129,30 +2134,85 @@ function getShieldPoolPDAs(programId, mint) {
|
|
|
2129
2134
|
treasury
|
|
2130
2135
|
};
|
|
2131
2136
|
}
|
|
2137
|
+
function getNullifierPDA(nullifier, programId) {
|
|
2138
|
+
const pid = programId || CLOAK_PROGRAM_ID;
|
|
2139
|
+
if (nullifier.length !== 32) {
|
|
2140
|
+
throw new Error(`Nullifier must be 32 bytes, got ${nullifier.length}`);
|
|
2141
|
+
}
|
|
2142
|
+
return import_web33.PublicKey.findProgramAddressSync(
|
|
2143
|
+
[Buffer.from("nullifier"), Buffer.from(nullifier)],
|
|
2144
|
+
pid
|
|
2145
|
+
);
|
|
2146
|
+
}
|
|
2147
|
+
function getSwapStatePDA(nullifier, programId) {
|
|
2148
|
+
const pid = programId || CLOAK_PROGRAM_ID;
|
|
2149
|
+
if (nullifier.length !== 32) {
|
|
2150
|
+
throw new Error(`Nullifier must be 32 bytes, got ${nullifier.length}`);
|
|
2151
|
+
}
|
|
2152
|
+
return import_web33.PublicKey.findProgramAddressSync(
|
|
2153
|
+
[Buffer.from("swap_state"), Buffer.from(nullifier)],
|
|
2154
|
+
pid
|
|
2155
|
+
);
|
|
2156
|
+
}
|
|
2132
2157
|
|
|
2133
2158
|
// src/utils/proof-generation.ts
|
|
2134
2159
|
var snarkjs = __toESM(require("snarkjs"), 1);
|
|
2135
2160
|
init_crypto();
|
|
2136
2161
|
var IS_REACT_NATIVE = typeof navigator !== "undefined" && navigator.product === "ReactNative";
|
|
2137
2162
|
var IS_BROWSER = IS_REACT_NATIVE || typeof window !== "undefined" || typeof globalThis !== "undefined" && typeof globalThis.document !== "undefined";
|
|
2163
|
+
var DEFAULT_CIRCUITS_URL = "https://www.cloak.ag/circuits";
|
|
2164
|
+
function isUrl(path) {
|
|
2165
|
+
return path.startsWith("http://") || path.startsWith("https://");
|
|
2166
|
+
}
|
|
2167
|
+
async function fetchFileAsBuffer(url) {
|
|
2168
|
+
const response = await fetch(url);
|
|
2169
|
+
if (!response.ok) {
|
|
2170
|
+
throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);
|
|
2171
|
+
}
|
|
2172
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
2173
|
+
return new Uint8Array(arrayBuffer);
|
|
2174
|
+
}
|
|
2138
2175
|
var _nodePath = null;
|
|
2139
2176
|
var _nodeFs = null;
|
|
2140
2177
|
var _nodeCrypto = null;
|
|
2178
|
+
var _fs = null;
|
|
2179
|
+
var _path = null;
|
|
2180
|
+
async function loadNodeModules() {
|
|
2181
|
+
if (_fs && _path) {
|
|
2182
|
+
return { fs: _fs, path: _path };
|
|
2183
|
+
}
|
|
2184
|
+
if (IS_BROWSER) {
|
|
2185
|
+
throw new Error("Node.js modules not available in browser/React Native");
|
|
2186
|
+
}
|
|
2187
|
+
const [fsModule, pathModule] = await Promise.all([
|
|
2188
|
+
import("fs"),
|
|
2189
|
+
import("path")
|
|
2190
|
+
]);
|
|
2191
|
+
_fs = fsModule;
|
|
2192
|
+
_path = pathModule;
|
|
2193
|
+
return { fs: _fs, path: _path };
|
|
2194
|
+
}
|
|
2141
2195
|
function nodeRequire(moduleName) {
|
|
2142
2196
|
if (IS_BROWSER) {
|
|
2143
2197
|
throw new Error(`Node.js ${moduleName} module not available in browser/React Native`);
|
|
2144
2198
|
}
|
|
2145
|
-
|
|
2146
|
-
|
|
2199
|
+
try {
|
|
2200
|
+
const requireFunc = new Function("moduleName", "return require(moduleName)");
|
|
2201
|
+
return requireFunc(moduleName);
|
|
2202
|
+
} catch {
|
|
2203
|
+
throw new Error(`Cannot load Node.js module ${moduleName} synchronously in ESM. Use async loadNodeModules() instead.`);
|
|
2204
|
+
}
|
|
2147
2205
|
}
|
|
2148
2206
|
async function getNodePath() {
|
|
2149
2207
|
if (_nodePath) return _nodePath;
|
|
2150
|
-
|
|
2208
|
+
const { path } = await loadNodeModules();
|
|
2209
|
+
_nodePath = path;
|
|
2151
2210
|
return _nodePath;
|
|
2152
2211
|
}
|
|
2153
2212
|
async function getNodeFs() {
|
|
2154
2213
|
if (_nodeFs) return _nodeFs;
|
|
2155
|
-
|
|
2214
|
+
const { fs } = await loadNodeModules();
|
|
2215
|
+
_nodeFs = fs;
|
|
2156
2216
|
return _nodeFs;
|
|
2157
2217
|
}
|
|
2158
2218
|
async function getNodeCrypto() {
|
|
@@ -2173,29 +2233,41 @@ async function fileExists(filePath) {
|
|
|
2173
2233
|
}
|
|
2174
2234
|
}
|
|
2175
2235
|
try {
|
|
2176
|
-
const
|
|
2177
|
-
return
|
|
2236
|
+
const { fs } = await loadNodeModules();
|
|
2237
|
+
return fs.existsSync(filePath);
|
|
2178
2238
|
} catch {
|
|
2179
2239
|
return false;
|
|
2180
2240
|
}
|
|
2181
2241
|
}
|
|
2182
2242
|
async function generateWithdrawRegularProof(inputs, circuitsPath) {
|
|
2183
|
-
let
|
|
2184
|
-
let
|
|
2243
|
+
let wasmInput;
|
|
2244
|
+
let zkeyInput;
|
|
2245
|
+
const useUrl = isUrl(circuitsPath);
|
|
2185
2246
|
if (IS_BROWSER) {
|
|
2186
|
-
|
|
2187
|
-
|
|
2247
|
+
wasmInput = `${circuitsPath}/withdraw_regular_js/withdraw_regular.wasm`;
|
|
2248
|
+
zkeyInput = `${circuitsPath}/withdraw_regular_final.zkey`;
|
|
2249
|
+
} else if (useUrl) {
|
|
2250
|
+
const wasmUrl = `${circuitsPath}/withdraw_regular_js/withdraw_regular.wasm`;
|
|
2251
|
+
const zkeyUrl = `${circuitsPath}/withdraw_regular_final.zkey`;
|
|
2252
|
+
const [wasmData, zkeyData] = await Promise.all([
|
|
2253
|
+
fetchFileAsBuffer(wasmUrl),
|
|
2254
|
+
fetchFileAsBuffer(zkeyUrl)
|
|
2255
|
+
]);
|
|
2256
|
+
wasmInput = wasmData;
|
|
2257
|
+
zkeyInput = zkeyData;
|
|
2188
2258
|
} else {
|
|
2189
|
-
wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
|
|
2190
|
-
zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
|
|
2259
|
+
const wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
|
|
2260
|
+
const zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
|
|
2191
2261
|
const wasmExists = await fileExists(wasmPath);
|
|
2192
2262
|
const zkeyExists = await fileExists(zkeyPath);
|
|
2193
2263
|
if (!wasmExists) {
|
|
2194
|
-
throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages
|
|
2264
|
+
throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages/ first.`);
|
|
2195
2265
|
}
|
|
2196
2266
|
if (!zkeyExists) {
|
|
2197
2267
|
throw new Error(`Circuit zkey not found at ${zkeyPath}. Run circuit setup first.`);
|
|
2198
2268
|
}
|
|
2269
|
+
wasmInput = wasmPath;
|
|
2270
|
+
zkeyInput = zkeyPath;
|
|
2199
2271
|
}
|
|
2200
2272
|
const circuitInputs = {
|
|
2201
2273
|
// Public signals
|
|
@@ -2219,7 +2291,7 @@ async function generateWithdrawRegularProof(inputs, circuitsPath) {
|
|
|
2219
2291
|
var_fee: inputs.var_fee.toString(),
|
|
2220
2292
|
rem: inputs.rem.toString()
|
|
2221
2293
|
};
|
|
2222
|
-
const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs,
|
|
2294
|
+
const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, wasmInput, zkeyInput);
|
|
2223
2295
|
const proofBytes = proofToBytes(proof);
|
|
2224
2296
|
return {
|
|
2225
2297
|
proof,
|
|
@@ -2230,22 +2302,34 @@ async function generateWithdrawRegularProof(inputs, circuitsPath) {
|
|
|
2230
2302
|
};
|
|
2231
2303
|
}
|
|
2232
2304
|
async function generateWithdrawSwapProof(inputs, circuitsPath) {
|
|
2233
|
-
let
|
|
2234
|
-
let
|
|
2305
|
+
let wasmInput;
|
|
2306
|
+
let zkeyInput;
|
|
2307
|
+
const useUrl = isUrl(circuitsPath);
|
|
2235
2308
|
if (IS_BROWSER) {
|
|
2236
|
-
|
|
2237
|
-
|
|
2309
|
+
wasmInput = `${circuitsPath}/withdraw_swap_js/withdraw_swap.wasm`;
|
|
2310
|
+
zkeyInput = `${circuitsPath}/withdraw_swap_final.zkey`;
|
|
2311
|
+
} else if (useUrl) {
|
|
2312
|
+
const wasmUrl = `${circuitsPath}/withdraw_swap_js/withdraw_swap.wasm`;
|
|
2313
|
+
const zkeyUrl = `${circuitsPath}/withdraw_swap_final.zkey`;
|
|
2314
|
+
const [wasmData, zkeyData] = await Promise.all([
|
|
2315
|
+
fetchFileAsBuffer(wasmUrl),
|
|
2316
|
+
fetchFileAsBuffer(zkeyUrl)
|
|
2317
|
+
]);
|
|
2318
|
+
wasmInput = wasmData;
|
|
2319
|
+
zkeyInput = zkeyData;
|
|
2238
2320
|
} else {
|
|
2239
|
-
wasmPath = joinPath(circuitsPath, "build", "withdraw_swap_js", "withdraw_swap.wasm");
|
|
2240
|
-
zkeyPath = joinPath(circuitsPath, "build", "withdraw_swap_final.zkey");
|
|
2321
|
+
const wasmPath = joinPath(circuitsPath, "build", "withdraw_swap_js", "withdraw_swap.wasm");
|
|
2322
|
+
const zkeyPath = joinPath(circuitsPath, "build", "withdraw_swap_final.zkey");
|
|
2241
2323
|
const wasmExists = await fileExists(wasmPath);
|
|
2242
2324
|
const zkeyExists = await fileExists(zkeyPath);
|
|
2243
2325
|
if (!wasmExists) {
|
|
2244
|
-
throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages
|
|
2326
|
+
throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages/ first.`);
|
|
2245
2327
|
}
|
|
2246
2328
|
if (!zkeyExists) {
|
|
2247
2329
|
throw new Error(`Circuit zkey not found at ${zkeyPath}. Run circuit setup first.`);
|
|
2248
2330
|
}
|
|
2331
|
+
wasmInput = wasmPath;
|
|
2332
|
+
zkeyInput = zkeyPath;
|
|
2249
2333
|
}
|
|
2250
2334
|
const sk = splitTo2Limbs(inputs.sk_spend);
|
|
2251
2335
|
const r = splitTo2Limbs(inputs.r);
|
|
@@ -2274,8 +2358,8 @@ async function generateWithdrawSwapProof(inputs, circuitsPath) {
|
|
|
2274
2358
|
};
|
|
2275
2359
|
const { proof, publicSignals } = await snarkjs.groth16.fullProve(
|
|
2276
2360
|
circuitInputs,
|
|
2277
|
-
|
|
2278
|
-
|
|
2361
|
+
wasmInput,
|
|
2362
|
+
zkeyInput
|
|
2279
2363
|
);
|
|
2280
2364
|
const proofBytes = proofToBytes(proof);
|
|
2281
2365
|
return {
|
|
@@ -2287,8 +2371,14 @@ async function generateWithdrawSwapProof(inputs, circuitsPath) {
|
|
|
2287
2371
|
};
|
|
2288
2372
|
}
|
|
2289
2373
|
async function areCircuitsAvailable(circuitsPath) {
|
|
2374
|
+
if (!circuitsPath || circuitsPath === "") {
|
|
2375
|
+
return false;
|
|
2376
|
+
}
|
|
2377
|
+
if (isUrl(circuitsPath)) {
|
|
2378
|
+
return true;
|
|
2379
|
+
}
|
|
2290
2380
|
if (IS_BROWSER) {
|
|
2291
|
-
return
|
|
2381
|
+
return true;
|
|
2292
2382
|
}
|
|
2293
2383
|
const wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
|
|
2294
2384
|
const zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
|
|
@@ -2297,22 +2387,25 @@ async function areCircuitsAvailable(circuitsPath) {
|
|
|
2297
2387
|
return wasmExists && zkeyExists;
|
|
2298
2388
|
}
|
|
2299
2389
|
async function getDefaultCircuitsPath() {
|
|
2390
|
+
if (typeof process !== "undefined" && process.env?.CIRCUITS_PATH) {
|
|
2391
|
+
return process.env.CIRCUITS_PATH;
|
|
2392
|
+
}
|
|
2300
2393
|
if (IS_BROWSER) {
|
|
2301
2394
|
return "/circuits";
|
|
2302
2395
|
}
|
|
2303
2396
|
if (typeof process === "undefined" || !process.cwd) {
|
|
2304
|
-
return
|
|
2397
|
+
return DEFAULT_CIRCUITS_URL;
|
|
2305
2398
|
}
|
|
2306
2399
|
let nodePath;
|
|
2307
2400
|
try {
|
|
2308
2401
|
nodePath = await getNodePath();
|
|
2309
|
-
} catch {
|
|
2310
|
-
return
|
|
2402
|
+
} catch (e) {
|
|
2403
|
+
return DEFAULT_CIRCUITS_URL;
|
|
2311
2404
|
}
|
|
2312
2405
|
const possiblePaths = [
|
|
2313
|
-
nodePath.resolve(process.cwd(), "../../packages
|
|
2314
|
-
nodePath.resolve(process.cwd(), "../packages
|
|
2315
|
-
nodePath.resolve(process.cwd(), "packages
|
|
2406
|
+
nodePath.resolve(process.cwd(), "../../packages/circuits"),
|
|
2407
|
+
nodePath.resolve(process.cwd(), "../packages/circuits"),
|
|
2408
|
+
nodePath.resolve(process.cwd(), "packages/circuits"),
|
|
2316
2409
|
nodePath.resolve(process.cwd(), "../../circuits"),
|
|
2317
2410
|
nodePath.resolve(process.cwd(), "../circuits")
|
|
2318
2411
|
];
|
|
@@ -2321,7 +2414,7 @@ async function getDefaultCircuitsPath() {
|
|
|
2321
2414
|
return p;
|
|
2322
2415
|
}
|
|
2323
2416
|
}
|
|
2324
|
-
return
|
|
2417
|
+
return DEFAULT_CIRCUITS_URL;
|
|
2325
2418
|
}
|
|
2326
2419
|
var EXPECTED_CIRCUIT_HASHES = {
|
|
2327
2420
|
// SHA-256 of the verification key JSON from withdraw_regular circuit
|
|
@@ -3949,6 +4042,7 @@ var VERSION = "1.0.0";
|
|
|
3949
4042
|
CLOAK_PROGRAM_ID,
|
|
3950
4043
|
CloakError,
|
|
3951
4044
|
CloakSDK,
|
|
4045
|
+
DEFAULT_CIRCUITS_URL,
|
|
3952
4046
|
EXPECTED_CIRCUIT_HASHES,
|
|
3953
4047
|
FIXED_FEE_LAMPORTS,
|
|
3954
4048
|
LAMPORTS_PER_SOL,
|
|
@@ -3959,6 +4053,7 @@ var VERSION = "1.0.0";
|
|
|
3959
4053
|
ShieldPoolErrors,
|
|
3960
4054
|
VARIABLE_FEE_RATE,
|
|
3961
4055
|
VERSION,
|
|
4056
|
+
areCircuitsAvailable,
|
|
3962
4057
|
bigintToBytes32,
|
|
3963
4058
|
buildPublicInputsBytes,
|
|
3964
4059
|
bytesToHex,
|
|
@@ -4008,14 +4103,17 @@ var VERSION = "1.0.0";
|
|
|
4008
4103
|
generateWithdrawRegularProof,
|
|
4009
4104
|
generateWithdrawSwapProof,
|
|
4010
4105
|
getAddressExplorerUrl,
|
|
4106
|
+
getDefaultCircuitsPath,
|
|
4011
4107
|
getDistributableAmount,
|
|
4012
4108
|
getExplorerUrl,
|
|
4109
|
+
getNullifierPDA,
|
|
4013
4110
|
getPendingOperationsSummary,
|
|
4014
4111
|
getPublicKey,
|
|
4015
4112
|
getPublicViewKey,
|
|
4016
4113
|
getRecipientAmount,
|
|
4017
4114
|
getRpcUrlForNetwork,
|
|
4018
4115
|
getShieldPoolPDAs,
|
|
4116
|
+
getSwapStatePDA,
|
|
4019
4117
|
getViewKey,
|
|
4020
4118
|
hasPendingOperations,
|
|
4021
4119
|
hexToBigint,
|
package/dist/index.d.cts
CHANGED
|
@@ -1753,6 +1753,7 @@ interface ShieldPoolPDAs {
|
|
|
1753
1753
|
merkleTree: PublicKey;
|
|
1754
1754
|
commitments: PublicKey;
|
|
1755
1755
|
rootsRing: PublicKey;
|
|
1756
|
+
/** @deprecated Use getNullifierPDA() for the new per-nullifier PDA design */
|
|
1756
1757
|
nullifierShard: PublicKey;
|
|
1757
1758
|
treasury: PublicKey;
|
|
1758
1759
|
}
|
|
@@ -1774,6 +1775,30 @@ interface ShieldPoolPDAs {
|
|
|
1774
1775
|
* @param mint - Optional mint address (defaults to 32 zero bytes for native SOL)
|
|
1775
1776
|
*/
|
|
1776
1777
|
declare function getShieldPoolPDAs(programId?: PublicKey, mint?: PublicKey): ShieldPoolPDAs;
|
|
1778
|
+
/**
|
|
1779
|
+
* Derive the nullifier PDA for a specific nullifier hash.
|
|
1780
|
+
*
|
|
1781
|
+
* With the new PDA-per-nullifier design, each nullifier has its own PDA
|
|
1782
|
+
* instead of being stored in a shared shard. The PDA is created when
|
|
1783
|
+
* the nullifier is used during withdrawal.
|
|
1784
|
+
*
|
|
1785
|
+
* Seeds: ["nullifier", nullifier_hash]
|
|
1786
|
+
*
|
|
1787
|
+
* @param nullifier - 32-byte nullifier hash
|
|
1788
|
+
* @param programId - Optional program ID (defaults to CLOAK_PROGRAM_ID)
|
|
1789
|
+
* @returns [PublicKey, bump] - The nullifier PDA and its bump seed
|
|
1790
|
+
*/
|
|
1791
|
+
declare function getNullifierPDA(nullifier: Uint8Array | Buffer, programId?: PublicKey): [PublicKey, number];
|
|
1792
|
+
/**
|
|
1793
|
+
* Derive the swap state PDA for a given nullifier.
|
|
1794
|
+
*
|
|
1795
|
+
* Seeds: ["swap_state", nullifier_hash]
|
|
1796
|
+
*
|
|
1797
|
+
* @param nullifier - 32-byte nullifier hash
|
|
1798
|
+
* @param programId - Optional program ID (defaults to CLOAK_PROGRAM_ID)
|
|
1799
|
+
* @returns [PublicKey, bump] - The swap state PDA and its bump seed
|
|
1800
|
+
*/
|
|
1801
|
+
declare function getSwapStatePDA(nullifier: Uint8Array | Buffer, programId?: PublicKey): [PublicKey, number];
|
|
1777
1802
|
|
|
1778
1803
|
/**
|
|
1779
1804
|
* On-chain Merkle proof computation
|
|
@@ -1838,6 +1863,11 @@ declare function computeProofForLatestDeposit(connection: Connection, merkleTree
|
|
|
1838
1863
|
* as it doesn't require a backend prover service.
|
|
1839
1864
|
*/
|
|
1840
1865
|
|
|
1866
|
+
/**
|
|
1867
|
+
* Default URL for fetching circuit artifacts
|
|
1868
|
+
* These are served from the Cloak web app at https://cloak.ag
|
|
1869
|
+
*/
|
|
1870
|
+
declare const DEFAULT_CIRCUITS_URL = "https://www.cloak.ag/circuits";
|
|
1841
1871
|
interface WithdrawRegularInputs {
|
|
1842
1872
|
root: bigint;
|
|
1843
1873
|
nullifier: bigint;
|
|
@@ -1898,6 +1928,23 @@ declare function generateWithdrawRegularProof(inputs: WithdrawRegularInputs, cir
|
|
|
1898
1928
|
* @param circuitsPath - Path or URL to circuits directory. In browser, use URL like '/circuits' or full URL.
|
|
1899
1929
|
*/
|
|
1900
1930
|
declare function generateWithdrawSwapProof(inputs: WithdrawSwapInputs, circuitsPath: string): Promise<ProofResult>;
|
|
1931
|
+
/**
|
|
1932
|
+
* Check if circuits are available at the given path or URL
|
|
1933
|
+
* Supports both local file paths and remote URLs
|
|
1934
|
+
*
|
|
1935
|
+
* Note: For remote URLs, this returns true without checking (snarkjs will handle loading).
|
|
1936
|
+
* For local paths, it checks if the files exist on disk.
|
|
1937
|
+
*/
|
|
1938
|
+
declare function areCircuitsAvailable(circuitsPath: string): Promise<boolean>;
|
|
1939
|
+
/**
|
|
1940
|
+
* Get default circuits path or URL
|
|
1941
|
+
*
|
|
1942
|
+
* Priority:
|
|
1943
|
+
* 1. CIRCUITS_PATH environment variable (if set)
|
|
1944
|
+
* 2. Local file paths (if available)
|
|
1945
|
+
* 3. Default remote URL (https://cloak.ag/circuits)
|
|
1946
|
+
*/
|
|
1947
|
+
declare function getDefaultCircuitsPath(): Promise<string>;
|
|
1901
1948
|
/**
|
|
1902
1949
|
* Expected circuit hashes for verification
|
|
1903
1950
|
* These are computed from the verification key files to ensure circuits match on-chain vkeys
|
|
@@ -2076,4 +2123,4 @@ declare function cleanupStalePendingOperations(maxAgeMs?: number): {
|
|
|
2076
2123
|
|
|
2077
2124
|
declare const VERSION = "1.0.0";
|
|
2078
2125
|
|
|
2079
|
-
export { CLOAK_PROGRAM_ID, type CircuitVerificationResult, type CloakConfig, CloakError, type CloakKeyPair, type CloakNote, CloakSDK, type DepositInstructionParams, type DepositOptions, type DepositResult, type DepositStatus, EXPECTED_CIRCUIT_HASHES, type EncryptedNote, type ErrorCategory, FIXED_FEE_LAMPORTS, type Groth16Proof, LAMPORTS_PER_SOL, LocalStorageAdapter, type LogLevel, type Logger, type MasterKey, type MaxLengthArray, MemoryStorageAdapter, type MerkleProof, type MerkleRootResponse, type Network, type NoteData, type OnchainMerkleProof, type PendingDeposit, type PendingWithdrawal, type ProofResult, RelayService, RootNotFoundError, ShieldPoolErrors, type ShieldPoolPDAs, type SpendKey, type StorageAdapter, type SwapOptions, type SwapParams, type SwapResult, type Transfer, type TransferOptions, type TransferResult, type TxStatus, type UserFriendlyError, VARIABLE_FEE_RATE, VERSION, type ViewKey, type WalletAdapter, type WithdrawOptions, type WithdrawRegularInputs, type WithdrawSubmissionResult, type WithdrawSwapInputs, bigintToBytes32, buildPublicInputsBytes, bytesToHex, calculateFee, calculateRelayFee, cleanupStalePendingOperations, clearPendingDeposits, clearPendingWithdrawals, computeCommitment, computeMerkleRoot, computeNullifier, computeNullifierAsync, computeNullifierSync, computeOutputsHash, computeOutputsHashAsync, computeOutputsHashSync, computeProofForLatestDeposit, computeProofFromChain, computeSwapOutputsHash, computeSwapOutputsHashAsync, computeSwapOutputsHashSync, copyNoteToClipboard, createCloakError, createDepositInstruction, createLogger, deriveSpendKey, deriveViewKey, detectNetworkFromRpcUrl, downloadNote, encodeNoteSimple, encryptNoteForRecipient, exportKeys, exportNote, exportWalletKeys, filterNotesByNetwork, filterWithdrawableNotes, findNoteByCommitment, formatAmount, formatErrorForLogging, formatSol, generateCloakKeys, generateCommitment, generateCommitmentAsync, generateMasterSeed, generateNote, generateNoteFromWallet, generateWithdrawRegularProof, generateWithdrawSwapProof, getAddressExplorerUrl, getDistributableAmount, getExplorerUrl, getPendingOperationsSummary, getPublicKey, getPublicViewKey, getRecipientAmount, getRpcUrlForNetwork, getShieldPoolPDAs, getViewKey, hasPendingOperations, hexToBigint, hexToBytes, importKeys, importWalletKeys, isDebugEnabled, isRootNotFoundError, isValidHex, isValidRpcUrl, isValidSolanaAddress, isWithdrawable, keypairToAdapter, loadPendingDeposits, loadPendingWithdrawals, parseAmount, parseError, parseNote, parseTransactionError, poseidonHash, prepareEncryptedOutput, prepareEncryptedOutputForRecipient, proofToBytes, pubkeyToLimbs, randomBytes, readMerkleTreeState, removePendingDeposit, removePendingWithdrawal, savePendingDeposit, savePendingWithdrawal, scanNotesForWallet, sdkLogger, sendTransaction, serializeNote, setDebugMode, signTransaction, splitTo2Limbs, truncate, tryDecryptNote, updateNoteWithDeposit, updatePendingDeposit, updatePendingWithdrawal, validateDepositParams, validateNote, validateOutputsSum, validateTransfers, validateWalletConnected, validateWithdrawableNote, verifyAllCircuits, verifyCircuitIntegrity, withTiming };
|
|
2126
|
+
export { CLOAK_PROGRAM_ID, type CircuitVerificationResult, type CloakConfig, CloakError, type CloakKeyPair, type CloakNote, CloakSDK, DEFAULT_CIRCUITS_URL, type DepositInstructionParams, type DepositOptions, type DepositResult, type DepositStatus, EXPECTED_CIRCUIT_HASHES, type EncryptedNote, type ErrorCategory, FIXED_FEE_LAMPORTS, type Groth16Proof, LAMPORTS_PER_SOL, LocalStorageAdapter, type LogLevel, type Logger, type MasterKey, type MaxLengthArray, MemoryStorageAdapter, type MerkleProof, type MerkleRootResponse, type Network, type NoteData, type OnchainMerkleProof, type PendingDeposit, type PendingWithdrawal, type ProofResult, RelayService, RootNotFoundError, ShieldPoolErrors, type ShieldPoolPDAs, type SpendKey, type StorageAdapter, type SwapOptions, type SwapParams, type SwapResult, type Transfer, type TransferOptions, type TransferResult, type TxStatus, type UserFriendlyError, VARIABLE_FEE_RATE, VERSION, type ViewKey, type WalletAdapter, type WithdrawOptions, type WithdrawRegularInputs, type WithdrawSubmissionResult, type WithdrawSwapInputs, areCircuitsAvailable, bigintToBytes32, buildPublicInputsBytes, bytesToHex, calculateFee, calculateRelayFee, cleanupStalePendingOperations, clearPendingDeposits, clearPendingWithdrawals, computeCommitment, computeMerkleRoot, computeNullifier, computeNullifierAsync, computeNullifierSync, computeOutputsHash, computeOutputsHashAsync, computeOutputsHashSync, computeProofForLatestDeposit, computeProofFromChain, computeSwapOutputsHash, computeSwapOutputsHashAsync, computeSwapOutputsHashSync, copyNoteToClipboard, createCloakError, createDepositInstruction, createLogger, deriveSpendKey, deriveViewKey, detectNetworkFromRpcUrl, downloadNote, encodeNoteSimple, encryptNoteForRecipient, exportKeys, exportNote, exportWalletKeys, filterNotesByNetwork, filterWithdrawableNotes, findNoteByCommitment, formatAmount, formatErrorForLogging, formatSol, generateCloakKeys, generateCommitment, generateCommitmentAsync, generateMasterSeed, generateNote, generateNoteFromWallet, generateWithdrawRegularProof, generateWithdrawSwapProof, getAddressExplorerUrl, getDefaultCircuitsPath, getDistributableAmount, getExplorerUrl, getNullifierPDA, getPendingOperationsSummary, getPublicKey, getPublicViewKey, getRecipientAmount, getRpcUrlForNetwork, getShieldPoolPDAs, getSwapStatePDA, getViewKey, hasPendingOperations, hexToBigint, hexToBytes, importKeys, importWalletKeys, isDebugEnabled, isRootNotFoundError, isValidHex, isValidRpcUrl, isValidSolanaAddress, isWithdrawable, keypairToAdapter, loadPendingDeposits, loadPendingWithdrawals, parseAmount, parseError, parseNote, parseTransactionError, poseidonHash, prepareEncryptedOutput, prepareEncryptedOutputForRecipient, proofToBytes, pubkeyToLimbs, randomBytes, readMerkleTreeState, removePendingDeposit, removePendingWithdrawal, savePendingDeposit, savePendingWithdrawal, scanNotesForWallet, sdkLogger, sendTransaction, serializeNote, setDebugMode, signTransaction, splitTo2Limbs, truncate, tryDecryptNote, updateNoteWithDeposit, updatePendingDeposit, updatePendingWithdrawal, validateDepositParams, validateNote, validateOutputsSum, validateTransfers, validateWalletConnected, validateWithdrawableNote, verifyAllCircuits, verifyCircuitIntegrity, withTiming };
|
package/dist/index.d.ts
CHANGED
|
@@ -1753,6 +1753,7 @@ interface ShieldPoolPDAs {
|
|
|
1753
1753
|
merkleTree: PublicKey;
|
|
1754
1754
|
commitments: PublicKey;
|
|
1755
1755
|
rootsRing: PublicKey;
|
|
1756
|
+
/** @deprecated Use getNullifierPDA() for the new per-nullifier PDA design */
|
|
1756
1757
|
nullifierShard: PublicKey;
|
|
1757
1758
|
treasury: PublicKey;
|
|
1758
1759
|
}
|
|
@@ -1774,6 +1775,30 @@ interface ShieldPoolPDAs {
|
|
|
1774
1775
|
* @param mint - Optional mint address (defaults to 32 zero bytes for native SOL)
|
|
1775
1776
|
*/
|
|
1776
1777
|
declare function getShieldPoolPDAs(programId?: PublicKey, mint?: PublicKey): ShieldPoolPDAs;
|
|
1778
|
+
/**
|
|
1779
|
+
* Derive the nullifier PDA for a specific nullifier hash.
|
|
1780
|
+
*
|
|
1781
|
+
* With the new PDA-per-nullifier design, each nullifier has its own PDA
|
|
1782
|
+
* instead of being stored in a shared shard. The PDA is created when
|
|
1783
|
+
* the nullifier is used during withdrawal.
|
|
1784
|
+
*
|
|
1785
|
+
* Seeds: ["nullifier", nullifier_hash]
|
|
1786
|
+
*
|
|
1787
|
+
* @param nullifier - 32-byte nullifier hash
|
|
1788
|
+
* @param programId - Optional program ID (defaults to CLOAK_PROGRAM_ID)
|
|
1789
|
+
* @returns [PublicKey, bump] - The nullifier PDA and its bump seed
|
|
1790
|
+
*/
|
|
1791
|
+
declare function getNullifierPDA(nullifier: Uint8Array | Buffer, programId?: PublicKey): [PublicKey, number];
|
|
1792
|
+
/**
|
|
1793
|
+
* Derive the swap state PDA for a given nullifier.
|
|
1794
|
+
*
|
|
1795
|
+
* Seeds: ["swap_state", nullifier_hash]
|
|
1796
|
+
*
|
|
1797
|
+
* @param nullifier - 32-byte nullifier hash
|
|
1798
|
+
* @param programId - Optional program ID (defaults to CLOAK_PROGRAM_ID)
|
|
1799
|
+
* @returns [PublicKey, bump] - The swap state PDA and its bump seed
|
|
1800
|
+
*/
|
|
1801
|
+
declare function getSwapStatePDA(nullifier: Uint8Array | Buffer, programId?: PublicKey): [PublicKey, number];
|
|
1777
1802
|
|
|
1778
1803
|
/**
|
|
1779
1804
|
* On-chain Merkle proof computation
|
|
@@ -1838,6 +1863,11 @@ declare function computeProofForLatestDeposit(connection: Connection, merkleTree
|
|
|
1838
1863
|
* as it doesn't require a backend prover service.
|
|
1839
1864
|
*/
|
|
1840
1865
|
|
|
1866
|
+
/**
|
|
1867
|
+
* Default URL for fetching circuit artifacts
|
|
1868
|
+
* These are served from the Cloak web app at https://cloak.ag
|
|
1869
|
+
*/
|
|
1870
|
+
declare const DEFAULT_CIRCUITS_URL = "https://www.cloak.ag/circuits";
|
|
1841
1871
|
interface WithdrawRegularInputs {
|
|
1842
1872
|
root: bigint;
|
|
1843
1873
|
nullifier: bigint;
|
|
@@ -1898,6 +1928,23 @@ declare function generateWithdrawRegularProof(inputs: WithdrawRegularInputs, cir
|
|
|
1898
1928
|
* @param circuitsPath - Path or URL to circuits directory. In browser, use URL like '/circuits' or full URL.
|
|
1899
1929
|
*/
|
|
1900
1930
|
declare function generateWithdrawSwapProof(inputs: WithdrawSwapInputs, circuitsPath: string): Promise<ProofResult>;
|
|
1931
|
+
/**
|
|
1932
|
+
* Check if circuits are available at the given path or URL
|
|
1933
|
+
* Supports both local file paths and remote URLs
|
|
1934
|
+
*
|
|
1935
|
+
* Note: For remote URLs, this returns true without checking (snarkjs will handle loading).
|
|
1936
|
+
* For local paths, it checks if the files exist on disk.
|
|
1937
|
+
*/
|
|
1938
|
+
declare function areCircuitsAvailable(circuitsPath: string): Promise<boolean>;
|
|
1939
|
+
/**
|
|
1940
|
+
* Get default circuits path or URL
|
|
1941
|
+
*
|
|
1942
|
+
* Priority:
|
|
1943
|
+
* 1. CIRCUITS_PATH environment variable (if set)
|
|
1944
|
+
* 2. Local file paths (if available)
|
|
1945
|
+
* 3. Default remote URL (https://cloak.ag/circuits)
|
|
1946
|
+
*/
|
|
1947
|
+
declare function getDefaultCircuitsPath(): Promise<string>;
|
|
1901
1948
|
/**
|
|
1902
1949
|
* Expected circuit hashes for verification
|
|
1903
1950
|
* These are computed from the verification key files to ensure circuits match on-chain vkeys
|
|
@@ -2076,4 +2123,4 @@ declare function cleanupStalePendingOperations(maxAgeMs?: number): {
|
|
|
2076
2123
|
|
|
2077
2124
|
declare const VERSION = "1.0.0";
|
|
2078
2125
|
|
|
2079
|
-
export { CLOAK_PROGRAM_ID, type CircuitVerificationResult, type CloakConfig, CloakError, type CloakKeyPair, type CloakNote, CloakSDK, type DepositInstructionParams, type DepositOptions, type DepositResult, type DepositStatus, EXPECTED_CIRCUIT_HASHES, type EncryptedNote, type ErrorCategory, FIXED_FEE_LAMPORTS, type Groth16Proof, LAMPORTS_PER_SOL, LocalStorageAdapter, type LogLevel, type Logger, type MasterKey, type MaxLengthArray, MemoryStorageAdapter, type MerkleProof, type MerkleRootResponse, type Network, type NoteData, type OnchainMerkleProof, type PendingDeposit, type PendingWithdrawal, type ProofResult, RelayService, RootNotFoundError, ShieldPoolErrors, type ShieldPoolPDAs, type SpendKey, type StorageAdapter, type SwapOptions, type SwapParams, type SwapResult, type Transfer, type TransferOptions, type TransferResult, type TxStatus, type UserFriendlyError, VARIABLE_FEE_RATE, VERSION, type ViewKey, type WalletAdapter, type WithdrawOptions, type WithdrawRegularInputs, type WithdrawSubmissionResult, type WithdrawSwapInputs, bigintToBytes32, buildPublicInputsBytes, bytesToHex, calculateFee, calculateRelayFee, cleanupStalePendingOperations, clearPendingDeposits, clearPendingWithdrawals, computeCommitment, computeMerkleRoot, computeNullifier, computeNullifierAsync, computeNullifierSync, computeOutputsHash, computeOutputsHashAsync, computeOutputsHashSync, computeProofForLatestDeposit, computeProofFromChain, computeSwapOutputsHash, computeSwapOutputsHashAsync, computeSwapOutputsHashSync, copyNoteToClipboard, createCloakError, createDepositInstruction, createLogger, deriveSpendKey, deriveViewKey, detectNetworkFromRpcUrl, downloadNote, encodeNoteSimple, encryptNoteForRecipient, exportKeys, exportNote, exportWalletKeys, filterNotesByNetwork, filterWithdrawableNotes, findNoteByCommitment, formatAmount, formatErrorForLogging, formatSol, generateCloakKeys, generateCommitment, generateCommitmentAsync, generateMasterSeed, generateNote, generateNoteFromWallet, generateWithdrawRegularProof, generateWithdrawSwapProof, getAddressExplorerUrl, getDistributableAmount, getExplorerUrl, getPendingOperationsSummary, getPublicKey, getPublicViewKey, getRecipientAmount, getRpcUrlForNetwork, getShieldPoolPDAs, getViewKey, hasPendingOperations, hexToBigint, hexToBytes, importKeys, importWalletKeys, isDebugEnabled, isRootNotFoundError, isValidHex, isValidRpcUrl, isValidSolanaAddress, isWithdrawable, keypairToAdapter, loadPendingDeposits, loadPendingWithdrawals, parseAmount, parseError, parseNote, parseTransactionError, poseidonHash, prepareEncryptedOutput, prepareEncryptedOutputForRecipient, proofToBytes, pubkeyToLimbs, randomBytes, readMerkleTreeState, removePendingDeposit, removePendingWithdrawal, savePendingDeposit, savePendingWithdrawal, scanNotesForWallet, sdkLogger, sendTransaction, serializeNote, setDebugMode, signTransaction, splitTo2Limbs, truncate, tryDecryptNote, updateNoteWithDeposit, updatePendingDeposit, updatePendingWithdrawal, validateDepositParams, validateNote, validateOutputsSum, validateTransfers, validateWalletConnected, validateWithdrawableNote, verifyAllCircuits, verifyCircuitIntegrity, withTiming };
|
|
2126
|
+
export { CLOAK_PROGRAM_ID, type CircuitVerificationResult, type CloakConfig, CloakError, type CloakKeyPair, type CloakNote, CloakSDK, DEFAULT_CIRCUITS_URL, type DepositInstructionParams, type DepositOptions, type DepositResult, type DepositStatus, EXPECTED_CIRCUIT_HASHES, type EncryptedNote, type ErrorCategory, FIXED_FEE_LAMPORTS, type Groth16Proof, LAMPORTS_PER_SOL, LocalStorageAdapter, type LogLevel, type Logger, type MasterKey, type MaxLengthArray, MemoryStorageAdapter, type MerkleProof, type MerkleRootResponse, type Network, type NoteData, type OnchainMerkleProof, type PendingDeposit, type PendingWithdrawal, type ProofResult, RelayService, RootNotFoundError, ShieldPoolErrors, type ShieldPoolPDAs, type SpendKey, type StorageAdapter, type SwapOptions, type SwapParams, type SwapResult, type Transfer, type TransferOptions, type TransferResult, type TxStatus, type UserFriendlyError, VARIABLE_FEE_RATE, VERSION, type ViewKey, type WalletAdapter, type WithdrawOptions, type WithdrawRegularInputs, type WithdrawSubmissionResult, type WithdrawSwapInputs, areCircuitsAvailable, bigintToBytes32, buildPublicInputsBytes, bytesToHex, calculateFee, calculateRelayFee, cleanupStalePendingOperations, clearPendingDeposits, clearPendingWithdrawals, computeCommitment, computeMerkleRoot, computeNullifier, computeNullifierAsync, computeNullifierSync, computeOutputsHash, computeOutputsHashAsync, computeOutputsHashSync, computeProofForLatestDeposit, computeProofFromChain, computeSwapOutputsHash, computeSwapOutputsHashAsync, computeSwapOutputsHashSync, copyNoteToClipboard, createCloakError, createDepositInstruction, createLogger, deriveSpendKey, deriveViewKey, detectNetworkFromRpcUrl, downloadNote, encodeNoteSimple, encryptNoteForRecipient, exportKeys, exportNote, exportWalletKeys, filterNotesByNetwork, filterWithdrawableNotes, findNoteByCommitment, formatAmount, formatErrorForLogging, formatSol, generateCloakKeys, generateCommitment, generateCommitmentAsync, generateMasterSeed, generateNote, generateNoteFromWallet, generateWithdrawRegularProof, generateWithdrawSwapProof, getAddressExplorerUrl, getDefaultCircuitsPath, getDistributableAmount, getExplorerUrl, getNullifierPDA, getPendingOperationsSummary, getPublicKey, getPublicViewKey, getRecipientAmount, getRpcUrlForNetwork, getShieldPoolPDAs, getSwapStatePDA, getViewKey, hasPendingOperations, hexToBigint, hexToBytes, importKeys, importWalletKeys, isDebugEnabled, isRootNotFoundError, isValidHex, isValidRpcUrl, isValidSolanaAddress, isWithdrawable, keypairToAdapter, loadPendingDeposits, loadPendingWithdrawals, parseAmount, parseError, parseNote, parseTransactionError, poseidonHash, prepareEncryptedOutput, prepareEncryptedOutputForRecipient, proofToBytes, pubkeyToLimbs, randomBytes, readMerkleTreeState, removePendingDeposit, removePendingWithdrawal, savePendingDeposit, savePendingWithdrawal, scanNotesForWallet, sdkLogger, sendTransaction, serializeNote, setDebugMode, signTransaction, splitTo2Limbs, truncate, tryDecryptNote, updateNoteWithDeposit, updatePendingDeposit, updatePendingWithdrawal, validateDepositParams, validateNote, validateOutputsSum, validateTransfers, validateWalletConnected, validateWithdrawableNote, verifyAllCircuits, verifyCircuitIntegrity, withTiming };
|
package/dist/index.js
CHANGED
|
@@ -1633,29 +1633,84 @@ function getShieldPoolPDAs(programId, mint) {
|
|
|
1633
1633
|
treasury
|
|
1634
1634
|
};
|
|
1635
1635
|
}
|
|
1636
|
+
function getNullifierPDA(nullifier, programId) {
|
|
1637
|
+
const pid = programId || CLOAK_PROGRAM_ID;
|
|
1638
|
+
if (nullifier.length !== 32) {
|
|
1639
|
+
throw new Error(`Nullifier must be 32 bytes, got ${nullifier.length}`);
|
|
1640
|
+
}
|
|
1641
|
+
return PublicKey3.findProgramAddressSync(
|
|
1642
|
+
[Buffer.from("nullifier"), Buffer.from(nullifier)],
|
|
1643
|
+
pid
|
|
1644
|
+
);
|
|
1645
|
+
}
|
|
1646
|
+
function getSwapStatePDA(nullifier, programId) {
|
|
1647
|
+
const pid = programId || CLOAK_PROGRAM_ID;
|
|
1648
|
+
if (nullifier.length !== 32) {
|
|
1649
|
+
throw new Error(`Nullifier must be 32 bytes, got ${nullifier.length}`);
|
|
1650
|
+
}
|
|
1651
|
+
return PublicKey3.findProgramAddressSync(
|
|
1652
|
+
[Buffer.from("swap_state"), Buffer.from(nullifier)],
|
|
1653
|
+
pid
|
|
1654
|
+
);
|
|
1655
|
+
}
|
|
1636
1656
|
|
|
1637
1657
|
// src/utils/proof-generation.ts
|
|
1638
1658
|
import * as snarkjs from "snarkjs";
|
|
1639
1659
|
var IS_REACT_NATIVE = typeof navigator !== "undefined" && navigator.product === "ReactNative";
|
|
1640
1660
|
var IS_BROWSER = IS_REACT_NATIVE || typeof window !== "undefined" || typeof globalThis !== "undefined" && typeof globalThis.document !== "undefined";
|
|
1661
|
+
var DEFAULT_CIRCUITS_URL = "https://www.cloak.ag/circuits";
|
|
1662
|
+
function isUrl(path) {
|
|
1663
|
+
return path.startsWith("http://") || path.startsWith("https://");
|
|
1664
|
+
}
|
|
1665
|
+
async function fetchFileAsBuffer(url) {
|
|
1666
|
+
const response = await fetch(url);
|
|
1667
|
+
if (!response.ok) {
|
|
1668
|
+
throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);
|
|
1669
|
+
}
|
|
1670
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
1671
|
+
return new Uint8Array(arrayBuffer);
|
|
1672
|
+
}
|
|
1641
1673
|
var _nodePath = null;
|
|
1642
1674
|
var _nodeFs = null;
|
|
1643
1675
|
var _nodeCrypto = null;
|
|
1676
|
+
var _fs = null;
|
|
1677
|
+
var _path = null;
|
|
1678
|
+
async function loadNodeModules() {
|
|
1679
|
+
if (_fs && _path) {
|
|
1680
|
+
return { fs: _fs, path: _path };
|
|
1681
|
+
}
|
|
1682
|
+
if (IS_BROWSER) {
|
|
1683
|
+
throw new Error("Node.js modules not available in browser/React Native");
|
|
1684
|
+
}
|
|
1685
|
+
const [fsModule, pathModule] = await Promise.all([
|
|
1686
|
+
import("fs"),
|
|
1687
|
+
import("path")
|
|
1688
|
+
]);
|
|
1689
|
+
_fs = fsModule;
|
|
1690
|
+
_path = pathModule;
|
|
1691
|
+
return { fs: _fs, path: _path };
|
|
1692
|
+
}
|
|
1644
1693
|
function nodeRequire(moduleName) {
|
|
1645
1694
|
if (IS_BROWSER) {
|
|
1646
1695
|
throw new Error(`Node.js ${moduleName} module not available in browser/React Native`);
|
|
1647
1696
|
}
|
|
1648
|
-
|
|
1649
|
-
|
|
1697
|
+
try {
|
|
1698
|
+
const requireFunc = new Function("moduleName", "return require(moduleName)");
|
|
1699
|
+
return requireFunc(moduleName);
|
|
1700
|
+
} catch {
|
|
1701
|
+
throw new Error(`Cannot load Node.js module ${moduleName} synchronously in ESM. Use async loadNodeModules() instead.`);
|
|
1702
|
+
}
|
|
1650
1703
|
}
|
|
1651
1704
|
async function getNodePath() {
|
|
1652
1705
|
if (_nodePath) return _nodePath;
|
|
1653
|
-
|
|
1706
|
+
const { path } = await loadNodeModules();
|
|
1707
|
+
_nodePath = path;
|
|
1654
1708
|
return _nodePath;
|
|
1655
1709
|
}
|
|
1656
1710
|
async function getNodeFs() {
|
|
1657
1711
|
if (_nodeFs) return _nodeFs;
|
|
1658
|
-
|
|
1712
|
+
const { fs } = await loadNodeModules();
|
|
1713
|
+
_nodeFs = fs;
|
|
1659
1714
|
return _nodeFs;
|
|
1660
1715
|
}
|
|
1661
1716
|
async function getNodeCrypto() {
|
|
@@ -1676,29 +1731,41 @@ async function fileExists(filePath) {
|
|
|
1676
1731
|
}
|
|
1677
1732
|
}
|
|
1678
1733
|
try {
|
|
1679
|
-
const
|
|
1680
|
-
return
|
|
1734
|
+
const { fs } = await loadNodeModules();
|
|
1735
|
+
return fs.existsSync(filePath);
|
|
1681
1736
|
} catch {
|
|
1682
1737
|
return false;
|
|
1683
1738
|
}
|
|
1684
1739
|
}
|
|
1685
1740
|
async function generateWithdrawRegularProof(inputs, circuitsPath) {
|
|
1686
|
-
let
|
|
1687
|
-
let
|
|
1741
|
+
let wasmInput;
|
|
1742
|
+
let zkeyInput;
|
|
1743
|
+
const useUrl = isUrl(circuitsPath);
|
|
1688
1744
|
if (IS_BROWSER) {
|
|
1689
|
-
|
|
1690
|
-
|
|
1745
|
+
wasmInput = `${circuitsPath}/withdraw_regular_js/withdraw_regular.wasm`;
|
|
1746
|
+
zkeyInput = `${circuitsPath}/withdraw_regular_final.zkey`;
|
|
1747
|
+
} else if (useUrl) {
|
|
1748
|
+
const wasmUrl = `${circuitsPath}/withdraw_regular_js/withdraw_regular.wasm`;
|
|
1749
|
+
const zkeyUrl = `${circuitsPath}/withdraw_regular_final.zkey`;
|
|
1750
|
+
const [wasmData, zkeyData] = await Promise.all([
|
|
1751
|
+
fetchFileAsBuffer(wasmUrl),
|
|
1752
|
+
fetchFileAsBuffer(zkeyUrl)
|
|
1753
|
+
]);
|
|
1754
|
+
wasmInput = wasmData;
|
|
1755
|
+
zkeyInput = zkeyData;
|
|
1691
1756
|
} else {
|
|
1692
|
-
wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
|
|
1693
|
-
zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
|
|
1757
|
+
const wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
|
|
1758
|
+
const zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
|
|
1694
1759
|
const wasmExists = await fileExists(wasmPath);
|
|
1695
1760
|
const zkeyExists = await fileExists(zkeyPath);
|
|
1696
1761
|
if (!wasmExists) {
|
|
1697
|
-
throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages
|
|
1762
|
+
throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages/ first.`);
|
|
1698
1763
|
}
|
|
1699
1764
|
if (!zkeyExists) {
|
|
1700
1765
|
throw new Error(`Circuit zkey not found at ${zkeyPath}. Run circuit setup first.`);
|
|
1701
1766
|
}
|
|
1767
|
+
wasmInput = wasmPath;
|
|
1768
|
+
zkeyInput = zkeyPath;
|
|
1702
1769
|
}
|
|
1703
1770
|
const circuitInputs = {
|
|
1704
1771
|
// Public signals
|
|
@@ -1722,7 +1789,7 @@ async function generateWithdrawRegularProof(inputs, circuitsPath) {
|
|
|
1722
1789
|
var_fee: inputs.var_fee.toString(),
|
|
1723
1790
|
rem: inputs.rem.toString()
|
|
1724
1791
|
};
|
|
1725
|
-
const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs,
|
|
1792
|
+
const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, wasmInput, zkeyInput);
|
|
1726
1793
|
const proofBytes = proofToBytes(proof);
|
|
1727
1794
|
return {
|
|
1728
1795
|
proof,
|
|
@@ -1733,22 +1800,34 @@ async function generateWithdrawRegularProof(inputs, circuitsPath) {
|
|
|
1733
1800
|
};
|
|
1734
1801
|
}
|
|
1735
1802
|
async function generateWithdrawSwapProof(inputs, circuitsPath) {
|
|
1736
|
-
let
|
|
1737
|
-
let
|
|
1803
|
+
let wasmInput;
|
|
1804
|
+
let zkeyInput;
|
|
1805
|
+
const useUrl = isUrl(circuitsPath);
|
|
1738
1806
|
if (IS_BROWSER) {
|
|
1739
|
-
|
|
1740
|
-
|
|
1807
|
+
wasmInput = `${circuitsPath}/withdraw_swap_js/withdraw_swap.wasm`;
|
|
1808
|
+
zkeyInput = `${circuitsPath}/withdraw_swap_final.zkey`;
|
|
1809
|
+
} else if (useUrl) {
|
|
1810
|
+
const wasmUrl = `${circuitsPath}/withdraw_swap_js/withdraw_swap.wasm`;
|
|
1811
|
+
const zkeyUrl = `${circuitsPath}/withdraw_swap_final.zkey`;
|
|
1812
|
+
const [wasmData, zkeyData] = await Promise.all([
|
|
1813
|
+
fetchFileAsBuffer(wasmUrl),
|
|
1814
|
+
fetchFileAsBuffer(zkeyUrl)
|
|
1815
|
+
]);
|
|
1816
|
+
wasmInput = wasmData;
|
|
1817
|
+
zkeyInput = zkeyData;
|
|
1741
1818
|
} else {
|
|
1742
|
-
wasmPath = joinPath(circuitsPath, "build", "withdraw_swap_js", "withdraw_swap.wasm");
|
|
1743
|
-
zkeyPath = joinPath(circuitsPath, "build", "withdraw_swap_final.zkey");
|
|
1819
|
+
const wasmPath = joinPath(circuitsPath, "build", "withdraw_swap_js", "withdraw_swap.wasm");
|
|
1820
|
+
const zkeyPath = joinPath(circuitsPath, "build", "withdraw_swap_final.zkey");
|
|
1744
1821
|
const wasmExists = await fileExists(wasmPath);
|
|
1745
1822
|
const zkeyExists = await fileExists(zkeyPath);
|
|
1746
1823
|
if (!wasmExists) {
|
|
1747
|
-
throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages
|
|
1824
|
+
throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages/ first.`);
|
|
1748
1825
|
}
|
|
1749
1826
|
if (!zkeyExists) {
|
|
1750
1827
|
throw new Error(`Circuit zkey not found at ${zkeyPath}. Run circuit setup first.`);
|
|
1751
1828
|
}
|
|
1829
|
+
wasmInput = wasmPath;
|
|
1830
|
+
zkeyInput = zkeyPath;
|
|
1752
1831
|
}
|
|
1753
1832
|
const sk = splitTo2Limbs(inputs.sk_spend);
|
|
1754
1833
|
const r = splitTo2Limbs(inputs.r);
|
|
@@ -1777,8 +1856,8 @@ async function generateWithdrawSwapProof(inputs, circuitsPath) {
|
|
|
1777
1856
|
};
|
|
1778
1857
|
const { proof, publicSignals } = await snarkjs.groth16.fullProve(
|
|
1779
1858
|
circuitInputs,
|
|
1780
|
-
|
|
1781
|
-
|
|
1859
|
+
wasmInput,
|
|
1860
|
+
zkeyInput
|
|
1782
1861
|
);
|
|
1783
1862
|
const proofBytes = proofToBytes(proof);
|
|
1784
1863
|
return {
|
|
@@ -1790,8 +1869,14 @@ async function generateWithdrawSwapProof(inputs, circuitsPath) {
|
|
|
1790
1869
|
};
|
|
1791
1870
|
}
|
|
1792
1871
|
async function areCircuitsAvailable(circuitsPath) {
|
|
1872
|
+
if (!circuitsPath || circuitsPath === "") {
|
|
1873
|
+
return false;
|
|
1874
|
+
}
|
|
1875
|
+
if (isUrl(circuitsPath)) {
|
|
1876
|
+
return true;
|
|
1877
|
+
}
|
|
1793
1878
|
if (IS_BROWSER) {
|
|
1794
|
-
return
|
|
1879
|
+
return true;
|
|
1795
1880
|
}
|
|
1796
1881
|
const wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
|
|
1797
1882
|
const zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
|
|
@@ -1800,22 +1885,25 @@ async function areCircuitsAvailable(circuitsPath) {
|
|
|
1800
1885
|
return wasmExists && zkeyExists;
|
|
1801
1886
|
}
|
|
1802
1887
|
async function getDefaultCircuitsPath() {
|
|
1888
|
+
if (typeof process !== "undefined" && process.env?.CIRCUITS_PATH) {
|
|
1889
|
+
return process.env.CIRCUITS_PATH;
|
|
1890
|
+
}
|
|
1803
1891
|
if (IS_BROWSER) {
|
|
1804
1892
|
return "/circuits";
|
|
1805
1893
|
}
|
|
1806
1894
|
if (typeof process === "undefined" || !process.cwd) {
|
|
1807
|
-
return
|
|
1895
|
+
return DEFAULT_CIRCUITS_URL;
|
|
1808
1896
|
}
|
|
1809
1897
|
let nodePath;
|
|
1810
1898
|
try {
|
|
1811
1899
|
nodePath = await getNodePath();
|
|
1812
|
-
} catch {
|
|
1813
|
-
return
|
|
1900
|
+
} catch (e) {
|
|
1901
|
+
return DEFAULT_CIRCUITS_URL;
|
|
1814
1902
|
}
|
|
1815
1903
|
const possiblePaths = [
|
|
1816
|
-
nodePath.resolve(process.cwd(), "../../packages
|
|
1817
|
-
nodePath.resolve(process.cwd(), "../packages
|
|
1818
|
-
nodePath.resolve(process.cwd(), "packages
|
|
1904
|
+
nodePath.resolve(process.cwd(), "../../packages/circuits"),
|
|
1905
|
+
nodePath.resolve(process.cwd(), "../packages/circuits"),
|
|
1906
|
+
nodePath.resolve(process.cwd(), "packages/circuits"),
|
|
1819
1907
|
nodePath.resolve(process.cwd(), "../../circuits"),
|
|
1820
1908
|
nodePath.resolve(process.cwd(), "../circuits")
|
|
1821
1909
|
];
|
|
@@ -1824,7 +1912,7 @@ async function getDefaultCircuitsPath() {
|
|
|
1824
1912
|
return p;
|
|
1825
1913
|
}
|
|
1826
1914
|
}
|
|
1827
|
-
return
|
|
1915
|
+
return DEFAULT_CIRCUITS_URL;
|
|
1828
1916
|
}
|
|
1829
1917
|
var EXPECTED_CIRCUIT_HASHES = {
|
|
1830
1918
|
// SHA-256 of the verification key JSON from withdraw_regular circuit
|
|
@@ -3442,6 +3530,7 @@ export {
|
|
|
3442
3530
|
CLOAK_PROGRAM_ID,
|
|
3443
3531
|
CloakError,
|
|
3444
3532
|
CloakSDK,
|
|
3533
|
+
DEFAULT_CIRCUITS_URL,
|
|
3445
3534
|
EXPECTED_CIRCUIT_HASHES,
|
|
3446
3535
|
FIXED_FEE_LAMPORTS,
|
|
3447
3536
|
LAMPORTS_PER_SOL,
|
|
@@ -3452,6 +3541,7 @@ export {
|
|
|
3452
3541
|
ShieldPoolErrors,
|
|
3453
3542
|
VARIABLE_FEE_RATE,
|
|
3454
3543
|
VERSION,
|
|
3544
|
+
areCircuitsAvailable,
|
|
3455
3545
|
bigintToBytes32,
|
|
3456
3546
|
buildPublicInputsBytes,
|
|
3457
3547
|
bytesToHex,
|
|
@@ -3501,14 +3591,17 @@ export {
|
|
|
3501
3591
|
generateWithdrawRegularProof,
|
|
3502
3592
|
generateWithdrawSwapProof,
|
|
3503
3593
|
getAddressExplorerUrl,
|
|
3594
|
+
getDefaultCircuitsPath,
|
|
3504
3595
|
getDistributableAmount2 as getDistributableAmount,
|
|
3505
3596
|
getExplorerUrl,
|
|
3597
|
+
getNullifierPDA,
|
|
3506
3598
|
getPendingOperationsSummary,
|
|
3507
3599
|
getPublicKey,
|
|
3508
3600
|
getPublicViewKey,
|
|
3509
3601
|
getRecipientAmount,
|
|
3510
3602
|
getRpcUrlForNetwork,
|
|
3511
3603
|
getShieldPoolPDAs,
|
|
3604
|
+
getSwapStatePDA,
|
|
3512
3605
|
getViewKey,
|
|
3513
3606
|
hasPendingOperations,
|
|
3514
3607
|
hexToBigint,
|