@cloak.ag/sdk 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +99 -385
- package/dist/index.d.cts +6 -82
- package/dist/index.d.ts +6 -82
- package/dist/index.js +88 -373
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,7 +30,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
ArtifactProverService: () => ArtifactProverService,
|
|
34
33
|
CLOAK_PROGRAM_ID: () => CLOAK_PROGRAM_ID,
|
|
35
34
|
CloakError: () => CloakError,
|
|
36
35
|
CloakSDK: () => CloakSDK,
|
|
@@ -129,7 +128,7 @@ __export(index_exports, {
|
|
|
129
128
|
module.exports = __toCommonJS(index_exports);
|
|
130
129
|
|
|
131
130
|
// src/core/CloakSDK.ts
|
|
132
|
-
var
|
|
131
|
+
var import_web35 = require("@solana/web3.js");
|
|
133
132
|
|
|
134
133
|
// src/core/types.ts
|
|
135
134
|
var CloakError = class extends Error {
|
|
@@ -147,7 +146,6 @@ var import_blake3 = require("@noble/hashes/blake3.js");
|
|
|
147
146
|
var import_tweetnacl = __toESM(require("tweetnacl"), 1);
|
|
148
147
|
|
|
149
148
|
// src/utils/crypto.ts
|
|
150
|
-
var import_web3 = require("@solana/web3.js");
|
|
151
149
|
var import_circomlibjs = require("circomlibjs");
|
|
152
150
|
var poseidon = null;
|
|
153
151
|
async function getPoseidon() {
|
|
@@ -168,7 +166,7 @@ function splitTo2Limbs(value) {
|
|
|
168
166
|
return [lo, hi];
|
|
169
167
|
}
|
|
170
168
|
function pubkeyToLimbs(pubkey) {
|
|
171
|
-
const bytes = pubkey
|
|
169
|
+
const bytes = typeof pubkey.toBytes === "function" ? pubkey.toBytes() : pubkey;
|
|
172
170
|
const value = BigInt("0x" + Buffer.from(bytes).toString("hex"));
|
|
173
171
|
return splitTo2Limbs(value);
|
|
174
172
|
}
|
|
@@ -796,10 +794,10 @@ var LocalStorageAdapter = class {
|
|
|
796
794
|
};
|
|
797
795
|
|
|
798
796
|
// src/utils/validation.ts
|
|
799
|
-
var
|
|
797
|
+
var import_web3 = require("@solana/web3.js");
|
|
800
798
|
function isValidSolanaAddress(address) {
|
|
801
799
|
try {
|
|
802
|
-
new
|
|
800
|
+
new import_web3.PublicKey(address);
|
|
803
801
|
return true;
|
|
804
802
|
} catch {
|
|
805
803
|
return false;
|
|
@@ -898,8 +896,9 @@ function validateTransfers(recipients, totalAmount) {
|
|
|
898
896
|
}
|
|
899
897
|
for (let i = 0; i < recipients.length; i++) {
|
|
900
898
|
const transfer = recipients[i];
|
|
901
|
-
|
|
902
|
-
|
|
899
|
+
const isPublicKeyLike = transfer.recipient && typeof transfer.recipient.toBase58 === "function" && typeof transfer.recipient.toBuffer === "function";
|
|
900
|
+
if (!isPublicKeyLike) {
|
|
901
|
+
throw new Error(`Recipient ${i} must be a PublicKey (got ${typeof transfer.recipient})`);
|
|
903
902
|
}
|
|
904
903
|
if (typeof transfer.amount !== "number" || transfer.amount <= 0) {
|
|
905
904
|
throw new Error(`Recipient ${i} amount must be a positive number`);
|
|
@@ -1144,254 +1143,6 @@ var IndexerService = class {
|
|
|
1144
1143
|
}
|
|
1145
1144
|
};
|
|
1146
1145
|
|
|
1147
|
-
// src/services/ArtifactProverService.ts
|
|
1148
|
-
var ArtifactProverService = class {
|
|
1149
|
-
/**
|
|
1150
|
-
* Create a new Artifact Prover Service client
|
|
1151
|
-
*
|
|
1152
|
-
* @param indexerUrl - Indexer service base URL
|
|
1153
|
-
* @param timeout - Proof generation timeout in ms (default: 5 minutes)
|
|
1154
|
-
* @param pollInterval - Polling interval for status checks (default: 2 seconds)
|
|
1155
|
-
*/
|
|
1156
|
-
constructor(indexerUrl, timeout = 5 * 60 * 1e3, pollInterval = 2e3) {
|
|
1157
|
-
this.indexerUrl = indexerUrl.replace(/\/$/, "");
|
|
1158
|
-
this.timeout = timeout;
|
|
1159
|
-
this.pollInterval = pollInterval;
|
|
1160
|
-
}
|
|
1161
|
-
/**
|
|
1162
|
-
* Generate a zero-knowledge proof using artifact-based flow
|
|
1163
|
-
*
|
|
1164
|
-
* This process typically takes 30-180 seconds depending on the TEE.
|
|
1165
|
-
* Private inputs are uploaded directly to TEE, never passing through backend.
|
|
1166
|
-
*
|
|
1167
|
-
* @param inputs - Circuit inputs (private + public + outputs)
|
|
1168
|
-
* @param options - Optional progress tracking and callbacks
|
|
1169
|
-
* @returns Proof result with hex-encoded proof and public inputs
|
|
1170
|
-
*
|
|
1171
|
-
* @example
|
|
1172
|
-
* ```typescript
|
|
1173
|
-
* const result = await prover.generateProof(inputs);
|
|
1174
|
-
* if (result.success) {
|
|
1175
|
-
* console.log(`Proof: ${result.proof}`);
|
|
1176
|
-
* }
|
|
1177
|
-
* ```
|
|
1178
|
-
*/
|
|
1179
|
-
async generateProof(inputs, options) {
|
|
1180
|
-
const startTime = Date.now();
|
|
1181
|
-
const actualTimeout = options?.timeout || this.timeout;
|
|
1182
|
-
const pollInterval = options?.pollInterval || this.pollInterval;
|
|
1183
|
-
options?.onStart?.();
|
|
1184
|
-
options?.onProgress?.(5);
|
|
1185
|
-
try {
|
|
1186
|
-
options?.onProgress?.(10);
|
|
1187
|
-
const artifactResponse = await fetch(`${this.indexerUrl}/api/v1/tee/artifact`, {
|
|
1188
|
-
method: "POST",
|
|
1189
|
-
headers: {
|
|
1190
|
-
"Content-Type": "application/json"
|
|
1191
|
-
},
|
|
1192
|
-
body: JSON.stringify({
|
|
1193
|
-
program_id: null
|
|
1194
|
-
// Optional, can be null
|
|
1195
|
-
})
|
|
1196
|
-
});
|
|
1197
|
-
if (!artifactResponse.ok) {
|
|
1198
|
-
const errorText = await artifactResponse.text();
|
|
1199
|
-
const errorMessage2 = `Failed to create artifact: ${errorText}`;
|
|
1200
|
-
options?.onError?.(errorMessage2);
|
|
1201
|
-
return {
|
|
1202
|
-
success: false,
|
|
1203
|
-
generationTimeMs: Date.now() - startTime,
|
|
1204
|
-
error: errorMessage2
|
|
1205
|
-
};
|
|
1206
|
-
}
|
|
1207
|
-
const artifactData = await artifactResponse.json();
|
|
1208
|
-
const { artifact_id, upload_url } = artifactData;
|
|
1209
|
-
if (!artifact_id || !upload_url) {
|
|
1210
|
-
const errorMessage2 = "Invalid artifact response: missing artifact_id or upload_url";
|
|
1211
|
-
options?.onError?.(errorMessage2);
|
|
1212
|
-
return {
|
|
1213
|
-
success: false,
|
|
1214
|
-
generationTimeMs: Date.now() - startTime,
|
|
1215
|
-
error: errorMessage2
|
|
1216
|
-
};
|
|
1217
|
-
}
|
|
1218
|
-
const fullUploadUrl = upload_url.startsWith("http") ? upload_url : `${this.indexerUrl}${upload_url}`;
|
|
1219
|
-
options?.onProgress?.(20);
|
|
1220
|
-
const stdinPayload = JSON.stringify({
|
|
1221
|
-
private: inputs.privateInputs,
|
|
1222
|
-
public: inputs.publicInputs,
|
|
1223
|
-
outputs: inputs.outputs,
|
|
1224
|
-
// Include swap_params if present (for swap transactions)
|
|
1225
|
-
...inputs.swapParams && { swap_params: inputs.swapParams }
|
|
1226
|
-
});
|
|
1227
|
-
const uploadResponse = await fetch(fullUploadUrl, {
|
|
1228
|
-
method: "POST",
|
|
1229
|
-
headers: {
|
|
1230
|
-
"Content-Type": "application/json"
|
|
1231
|
-
},
|
|
1232
|
-
body: stdinPayload
|
|
1233
|
-
});
|
|
1234
|
-
if (!uploadResponse.ok) {
|
|
1235
|
-
const errorText = await uploadResponse.text();
|
|
1236
|
-
const errorMessage2 = `Failed to upload stdin to TEE: ${errorText}`;
|
|
1237
|
-
options?.onError?.(errorMessage2);
|
|
1238
|
-
return {
|
|
1239
|
-
success: false,
|
|
1240
|
-
generationTimeMs: Date.now() - startTime,
|
|
1241
|
-
error: errorMessage2
|
|
1242
|
-
};
|
|
1243
|
-
}
|
|
1244
|
-
options?.onProgress?.(30);
|
|
1245
|
-
const requestProofBody = {
|
|
1246
|
-
artifact_id,
|
|
1247
|
-
program_id: null,
|
|
1248
|
-
public_inputs: JSON.stringify(inputs.publicInputs)
|
|
1249
|
-
};
|
|
1250
|
-
const requestProofResponse = await fetch(
|
|
1251
|
-
`${this.indexerUrl}/api/v1/tee/request-proof`,
|
|
1252
|
-
{
|
|
1253
|
-
method: "POST",
|
|
1254
|
-
headers: {
|
|
1255
|
-
"Content-Type": "application/json"
|
|
1256
|
-
},
|
|
1257
|
-
body: JSON.stringify(requestProofBody)
|
|
1258
|
-
}
|
|
1259
|
-
);
|
|
1260
|
-
if (!requestProofResponse.ok) {
|
|
1261
|
-
const errorText = await requestProofResponse.text();
|
|
1262
|
-
const errorMessage2 = `Failed to request proof: ${errorText}`;
|
|
1263
|
-
options?.onError?.(errorMessage2);
|
|
1264
|
-
return {
|
|
1265
|
-
success: false,
|
|
1266
|
-
generationTimeMs: Date.now() - startTime,
|
|
1267
|
-
error: errorMessage2
|
|
1268
|
-
};
|
|
1269
|
-
}
|
|
1270
|
-
const requestProofData = await requestProofResponse.json();
|
|
1271
|
-
const { request_id } = requestProofData;
|
|
1272
|
-
if (!request_id) {
|
|
1273
|
-
const errorMessage2 = "Invalid proof request response: missing request_id";
|
|
1274
|
-
options?.onError?.(errorMessage2);
|
|
1275
|
-
return {
|
|
1276
|
-
success: false,
|
|
1277
|
-
generationTimeMs: Date.now() - startTime,
|
|
1278
|
-
error: errorMessage2
|
|
1279
|
-
};
|
|
1280
|
-
}
|
|
1281
|
-
options?.onProgress?.(40);
|
|
1282
|
-
const pollStartTime = Date.now();
|
|
1283
|
-
let lastProgress = 40;
|
|
1284
|
-
while (Date.now() - pollStartTime < actualTimeout) {
|
|
1285
|
-
const statusResponse = await fetch(
|
|
1286
|
-
`${this.indexerUrl}/api/v1/tee/proof-status?request_id=${request_id}`,
|
|
1287
|
-
{
|
|
1288
|
-
method: "GET"
|
|
1289
|
-
}
|
|
1290
|
-
);
|
|
1291
|
-
if (!statusResponse.ok) {
|
|
1292
|
-
const errorText = await statusResponse.text();
|
|
1293
|
-
const errorMessage2 = `Failed to check proof status: ${errorText}`;
|
|
1294
|
-
options?.onError?.(errorMessage2);
|
|
1295
|
-
return {
|
|
1296
|
-
success: false,
|
|
1297
|
-
generationTimeMs: Date.now() - startTime,
|
|
1298
|
-
error: errorMessage2
|
|
1299
|
-
};
|
|
1300
|
-
}
|
|
1301
|
-
const statusData = await statusResponse.json();
|
|
1302
|
-
const { status, proof, public_inputs, generation_time_ms, error } = statusData;
|
|
1303
|
-
if (status === "ready") {
|
|
1304
|
-
options?.onProgress?.(100);
|
|
1305
|
-
if (!proof || !public_inputs) {
|
|
1306
|
-
const errorMessage2 = "Proof status is 'ready' but proof or public_inputs is missing";
|
|
1307
|
-
options?.onError?.(errorMessage2);
|
|
1308
|
-
return {
|
|
1309
|
-
success: false,
|
|
1310
|
-
generationTimeMs: Date.now() - startTime,
|
|
1311
|
-
error: errorMessage2
|
|
1312
|
-
};
|
|
1313
|
-
}
|
|
1314
|
-
const result = {
|
|
1315
|
-
success: true,
|
|
1316
|
-
proof,
|
|
1317
|
-
publicInputs: public_inputs,
|
|
1318
|
-
generationTimeMs: generation_time_ms || Date.now() - startTime
|
|
1319
|
-
};
|
|
1320
|
-
options?.onSuccess?.(result);
|
|
1321
|
-
return result;
|
|
1322
|
-
}
|
|
1323
|
-
if (status === "failed") {
|
|
1324
|
-
const errorMessage2 = error || "Proof generation failed";
|
|
1325
|
-
options?.onError?.(errorMessage2);
|
|
1326
|
-
return {
|
|
1327
|
-
success: false,
|
|
1328
|
-
generationTimeMs: Date.now() - startTime,
|
|
1329
|
-
error: errorMessage2
|
|
1330
|
-
};
|
|
1331
|
-
}
|
|
1332
|
-
const elapsed = Date.now() - pollStartTime;
|
|
1333
|
-
const progress = Math.min(90, 40 + Math.floor(elapsed / actualTimeout * 50));
|
|
1334
|
-
if (progress > lastProgress) {
|
|
1335
|
-
lastProgress = progress;
|
|
1336
|
-
options?.onProgress?.(progress);
|
|
1337
|
-
}
|
|
1338
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
1339
|
-
}
|
|
1340
|
-
const errorMessage = `Proof generation timed out after ${actualTimeout}ms`;
|
|
1341
|
-
options?.onError?.(errorMessage);
|
|
1342
|
-
return {
|
|
1343
|
-
success: false,
|
|
1344
|
-
generationTimeMs: Date.now() - startTime,
|
|
1345
|
-
error: errorMessage
|
|
1346
|
-
};
|
|
1347
|
-
} catch (error) {
|
|
1348
|
-
const totalTime = Date.now() - startTime;
|
|
1349
|
-
let errorMessage;
|
|
1350
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
1351
|
-
errorMessage = `Proof generation timed out after ${actualTimeout}ms`;
|
|
1352
|
-
} else {
|
|
1353
|
-
errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1354
|
-
}
|
|
1355
|
-
options?.onError?.(errorMessage);
|
|
1356
|
-
return {
|
|
1357
|
-
success: false,
|
|
1358
|
-
generationTimeMs: totalTime,
|
|
1359
|
-
error: errorMessage
|
|
1360
|
-
};
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
/**
|
|
1364
|
-
* Check if the artifact prover service is available
|
|
1365
|
-
*
|
|
1366
|
-
* @returns True if service is healthy
|
|
1367
|
-
*/
|
|
1368
|
-
async healthCheck() {
|
|
1369
|
-
try {
|
|
1370
|
-
const response = await fetch(`${this.indexerUrl}/health`, {
|
|
1371
|
-
method: "GET"
|
|
1372
|
-
});
|
|
1373
|
-
return response.ok;
|
|
1374
|
-
} catch {
|
|
1375
|
-
return false;
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
/**
|
|
1379
|
-
* Get the configured timeout
|
|
1380
|
-
*/
|
|
1381
|
-
getTimeout() {
|
|
1382
|
-
return this.timeout;
|
|
1383
|
-
}
|
|
1384
|
-
/**
|
|
1385
|
-
* Set a new timeout
|
|
1386
|
-
*/
|
|
1387
|
-
setTimeout(timeout) {
|
|
1388
|
-
if (timeout <= 0) {
|
|
1389
|
-
throw new Error("Timeout must be positive");
|
|
1390
|
-
}
|
|
1391
|
-
this.timeout = timeout;
|
|
1392
|
-
}
|
|
1393
|
-
};
|
|
1394
|
-
|
|
1395
1146
|
// src/services/RelayService.ts
|
|
1396
1147
|
var RelayService = class {
|
|
1397
1148
|
/**
|
|
@@ -1634,7 +1385,7 @@ var RelayService = class {
|
|
|
1634
1385
|
};
|
|
1635
1386
|
|
|
1636
1387
|
// src/services/DepositRecoveryService.ts
|
|
1637
|
-
var
|
|
1388
|
+
var import_web32 = require("@solana/web3.js");
|
|
1638
1389
|
|
|
1639
1390
|
// src/helpers/encrypted-output.ts
|
|
1640
1391
|
function prepareEncryptedOutput(note, cloakKeys) {
|
|
@@ -1725,7 +1476,7 @@ var DepositRecoveryService = class {
|
|
|
1725
1476
|
} catch (e) {
|
|
1726
1477
|
}
|
|
1727
1478
|
onProgress?.("Fetching transaction details...");
|
|
1728
|
-
const connection = new
|
|
1479
|
+
const connection = new import_web32.Connection(
|
|
1729
1480
|
process.env.NEXT_PUBLIC_SOLANA_RPC_URL || "https://api.devnet.solana.com"
|
|
1730
1481
|
);
|
|
1731
1482
|
const txDetails = await connection.getTransaction(signature, {
|
|
@@ -1887,7 +1638,7 @@ var DepositRecoveryService = class {
|
|
|
1887
1638
|
};
|
|
1888
1639
|
|
|
1889
1640
|
// src/solana/instructions.ts
|
|
1890
|
-
var
|
|
1641
|
+
var import_web33 = require("@solana/web3.js");
|
|
1891
1642
|
function createDepositInstruction(params) {
|
|
1892
1643
|
if (params.commitment.length !== 32) {
|
|
1893
1644
|
throw new Error(
|
|
@@ -1909,7 +1660,7 @@ function createDepositInstruction(params) {
|
|
|
1909
1660
|
data.set(discriminant, 0);
|
|
1910
1661
|
data.set(amountBytes, 1);
|
|
1911
1662
|
data.set(params.commitment, 9);
|
|
1912
|
-
return new
|
|
1663
|
+
return new import_web33.TransactionInstruction({
|
|
1913
1664
|
programId: params.programId,
|
|
1914
1665
|
keys: [
|
|
1915
1666
|
// Account 0: Payer (signer, writable) - pays for transaction
|
|
@@ -1917,7 +1668,7 @@ function createDepositInstruction(params) {
|
|
|
1917
1668
|
// Account 1: Pool (writable) - receives SOL
|
|
1918
1669
|
{ pubkey: params.pool, isSigner: false, isWritable: true },
|
|
1919
1670
|
// Account 2: System Program (readonly) - for transfers
|
|
1920
|
-
{ pubkey:
|
|
1671
|
+
{ pubkey: import_web33.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
1921
1672
|
// Account 3: Merkle Tree (writable) - stores on-chain Merkle tree
|
|
1922
1673
|
{ pubkey: params.merkleTree, isSigner: false, isWritable: true }
|
|
1923
1674
|
],
|
|
@@ -1925,16 +1676,16 @@ function createDepositInstruction(params) {
|
|
|
1925
1676
|
});
|
|
1926
1677
|
}
|
|
1927
1678
|
function validateDepositParams(params) {
|
|
1928
|
-
if (!(params.programId instanceof
|
|
1679
|
+
if (!(params.programId instanceof import_web33.PublicKey)) {
|
|
1929
1680
|
throw new Error("programId must be a PublicKey");
|
|
1930
1681
|
}
|
|
1931
|
-
if (!(params.payer instanceof
|
|
1682
|
+
if (!(params.payer instanceof import_web33.PublicKey)) {
|
|
1932
1683
|
throw new Error("payer must be a PublicKey");
|
|
1933
1684
|
}
|
|
1934
|
-
if (!(params.pool instanceof
|
|
1685
|
+
if (!(params.pool instanceof import_web33.PublicKey)) {
|
|
1935
1686
|
throw new Error("pool must be a PublicKey");
|
|
1936
1687
|
}
|
|
1937
|
-
if (!(params.merkleTree instanceof
|
|
1688
|
+
if (!(params.merkleTree instanceof import_web33.PublicKey)) {
|
|
1938
1689
|
throw new Error("merkleTree must be a PublicKey");
|
|
1939
1690
|
}
|
|
1940
1691
|
if (typeof params.amount !== "number" || params.amount <= 0) {
|
|
@@ -1951,34 +1702,34 @@ function validateDepositParams(params) {
|
|
|
1951
1702
|
}
|
|
1952
1703
|
|
|
1953
1704
|
// src/utils/pda.ts
|
|
1954
|
-
var
|
|
1705
|
+
var import_web34 = require("@solana/web3.js");
|
|
1955
1706
|
function getShieldPoolPDAs(programId, mint) {
|
|
1956
1707
|
const pid = programId || CLOAK_PROGRAM_ID;
|
|
1957
|
-
const mintKey = mint ?? new
|
|
1708
|
+
const mintKey = mint ?? new import_web34.PublicKey(
|
|
1958
1709
|
// 32 zero bytes, matching Rust `Pubkey::default()`
|
|
1959
1710
|
new Uint8Array(32)
|
|
1960
1711
|
);
|
|
1961
|
-
const [pool] =
|
|
1712
|
+
const [pool] = import_web34.PublicKey.findProgramAddressSync(
|
|
1962
1713
|
[Buffer.from("pool"), mintKey.toBytes()],
|
|
1963
1714
|
pid
|
|
1964
1715
|
);
|
|
1965
|
-
const [merkleTree] =
|
|
1716
|
+
const [merkleTree] = import_web34.PublicKey.findProgramAddressSync(
|
|
1966
1717
|
[Buffer.from("merkle_tree"), mintKey.toBytes()],
|
|
1967
1718
|
pid
|
|
1968
1719
|
);
|
|
1969
|
-
const [commitments] =
|
|
1720
|
+
const [commitments] = import_web34.PublicKey.findProgramAddressSync(
|
|
1970
1721
|
[Buffer.from("commitments"), mintKey.toBytes()],
|
|
1971
1722
|
pid
|
|
1972
1723
|
);
|
|
1973
|
-
const [rootsRing] =
|
|
1724
|
+
const [rootsRing] = import_web34.PublicKey.findProgramAddressSync(
|
|
1974
1725
|
[Buffer.from("roots_ring"), mintKey.toBytes()],
|
|
1975
1726
|
pid
|
|
1976
1727
|
);
|
|
1977
|
-
const [nullifierShard] =
|
|
1728
|
+
const [nullifierShard] = import_web34.PublicKey.findProgramAddressSync(
|
|
1978
1729
|
[Buffer.from("nullifier_shard"), mintKey.toBytes()],
|
|
1979
1730
|
pid
|
|
1980
1731
|
);
|
|
1981
|
-
const [treasury] =
|
|
1732
|
+
const [treasury] = import_web34.PublicKey.findProgramAddressSync(
|
|
1982
1733
|
[Buffer.from("treasury"), mintKey.toBytes()],
|
|
1983
1734
|
pid
|
|
1984
1735
|
);
|
|
@@ -2025,6 +1776,15 @@ async function fileExists(filePath) {
|
|
|
2025
1776
|
return false;
|
|
2026
1777
|
}
|
|
2027
1778
|
}
|
|
1779
|
+
const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
|
|
1780
|
+
if (isBrowser) {
|
|
1781
|
+
try {
|
|
1782
|
+
const response = await fetch(filePath, { method: "HEAD" });
|
|
1783
|
+
return response.ok;
|
|
1784
|
+
} catch {
|
|
1785
|
+
return false;
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
2028
1788
|
return false;
|
|
2029
1789
|
}
|
|
2030
1790
|
async function generateWithdrawRegularProof(inputs, circuitsPath) {
|
|
@@ -2141,6 +1901,10 @@ async function generateWithdrawSwapProof(inputs, circuitsPath) {
|
|
|
2141
1901
|
};
|
|
2142
1902
|
}
|
|
2143
1903
|
async function areCircuitsAvailable(circuitsPath) {
|
|
1904
|
+
const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
|
|
1905
|
+
if (isBrowser) {
|
|
1906
|
+
return Boolean(circuitsPath && circuitsPath !== "");
|
|
1907
|
+
}
|
|
2144
1908
|
const wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
|
|
2145
1909
|
const zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
|
|
2146
1910
|
const wasmExists = await fileExists(wasmPath);
|
|
@@ -2172,11 +1936,11 @@ async function getDefaultCircuitsPath() {
|
|
|
2172
1936
|
}
|
|
2173
1937
|
|
|
2174
1938
|
// src/core/CloakSDK.ts
|
|
2175
|
-
var CLOAK_PROGRAM_ID = new
|
|
1939
|
+
var CLOAK_PROGRAM_ID = new import_web35.PublicKey("c1oak6tetxYnNfvXKFkpn1d98FxtK7B68vBQLYQpWKp");
|
|
2176
1940
|
var CLOAK_API_URL = "https://api.cloak.ag";
|
|
2177
1941
|
var CloakSDK = class {
|
|
2178
1942
|
/**
|
|
2179
|
-
|
|
1943
|
+
* Create a new Cloak SDK client
|
|
2180
1944
|
*
|
|
2181
1945
|
* @param config - Client configuration
|
|
2182
1946
|
*
|
|
@@ -2201,7 +1965,7 @@ var CloakSDK = class {
|
|
|
2201
1965
|
throw new Error("Must provide either keypairBytes (Node.js) or wallet (Browser)");
|
|
2202
1966
|
}
|
|
2203
1967
|
if (config.keypairBytes) {
|
|
2204
|
-
this.keypair =
|
|
1968
|
+
this.keypair = import_web35.Keypair.fromSecretKey(config.keypairBytes);
|
|
2205
1969
|
}
|
|
2206
1970
|
this.wallet = config.wallet;
|
|
2207
1971
|
this.cloakKeys = config.cloakKeys;
|
|
@@ -2209,7 +1973,6 @@ var CloakSDK = class {
|
|
|
2209
1973
|
const indexerUrl = config.indexerUrl || typeof process !== "undefined" && process.env?.CLOAK_INDEXER_URL || CLOAK_API_URL;
|
|
2210
1974
|
const relayUrl = config.relayUrl || typeof process !== "undefined" && process.env?.CLOAK_RELAY_URL || CLOAK_API_URL;
|
|
2211
1975
|
this.indexer = new IndexerService(indexerUrl);
|
|
2212
|
-
this.artifactProver = new ArtifactProverService(indexerUrl, 5 * 60 * 1e3, 2e3);
|
|
2213
1976
|
this.relay = new RelayService(relayUrl);
|
|
2214
1977
|
this.depositRecovery = new DepositRecoveryService(this.indexer, indexerUrl);
|
|
2215
1978
|
if (!this.cloakKeys) {
|
|
@@ -2312,29 +2075,50 @@ var CloakSDK = class {
|
|
|
2312
2075
|
commitment: commitmentBytes
|
|
2313
2076
|
});
|
|
2314
2077
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
|
|
2315
|
-
const transaction = new
|
|
2078
|
+
const transaction = new import_web35.Transaction({
|
|
2316
2079
|
feePayer: payerPubkey,
|
|
2317
|
-
blockhash
|
|
2318
|
-
lastValidBlockHeight
|
|
2080
|
+
recentBlockhash: blockhash
|
|
2319
2081
|
}).add(depositIx);
|
|
2320
|
-
if (!
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
`Transaction simulation failed: ${JSON.stringify(simulation.value.err)}
|
|
2326
|
-
Logs:
|
|
2327
|
-
${logs}`
|
|
2328
|
-
);
|
|
2329
|
-
}
|
|
2082
|
+
if (!transaction.feePayer) {
|
|
2083
|
+
throw new Error("Transaction feePayer is not set");
|
|
2084
|
+
}
|
|
2085
|
+
if (!transaction.recentBlockhash) {
|
|
2086
|
+
throw new Error("Transaction recentBlockhash is not set");
|
|
2330
2087
|
}
|
|
2331
2088
|
let signature;
|
|
2332
|
-
if (this.wallet
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2089
|
+
if (this.wallet) {
|
|
2090
|
+
if (!this.wallet.publicKey) {
|
|
2091
|
+
throw new Error("Wallet not connected - publicKey is null");
|
|
2092
|
+
}
|
|
2093
|
+
if (this.wallet.signTransaction) {
|
|
2094
|
+
try {
|
|
2095
|
+
const signedTransaction = await this.wallet.signTransaction(transaction);
|
|
2096
|
+
const rawTransaction = signedTransaction.serialize();
|
|
2097
|
+
signature = await connection.sendRawTransaction(rawTransaction, {
|
|
2098
|
+
skipPreflight: options?.skipPreflight || false,
|
|
2099
|
+
preflightCommitment: "confirmed",
|
|
2100
|
+
maxRetries: 3
|
|
2101
|
+
});
|
|
2102
|
+
} catch (signError) {
|
|
2103
|
+
if (this.wallet.sendTransaction) {
|
|
2104
|
+
signature = await this.wallet.sendTransaction(transaction, connection, {
|
|
2105
|
+
skipPreflight: options?.skipPreflight || false,
|
|
2106
|
+
preflightCommitment: "confirmed",
|
|
2107
|
+
maxRetries: 3
|
|
2108
|
+
});
|
|
2109
|
+
} else {
|
|
2110
|
+
throw signError;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
} else if (this.wallet.sendTransaction) {
|
|
2114
|
+
signature = await this.wallet.sendTransaction(transaction, connection, {
|
|
2115
|
+
skipPreflight: options?.skipPreflight || false,
|
|
2116
|
+
preflightCommitment: "confirmed",
|
|
2117
|
+
maxRetries: 3
|
|
2118
|
+
});
|
|
2119
|
+
} else {
|
|
2120
|
+
throw new Error("Wallet adapter must provide either sendTransaction or signTransaction");
|
|
2121
|
+
}
|
|
2338
2122
|
} else if (this.keypair) {
|
|
2339
2123
|
signature = await connection.sendTransaction(transaction, [this.keypair], {
|
|
2340
2124
|
skipPreflight: options?.skipPreflight || false,
|
|
@@ -2419,7 +2203,7 @@ ${logs}`
|
|
|
2419
2203
|
}
|
|
2420
2204
|
if (leafIndex === null) {
|
|
2421
2205
|
const programId2 = this.config.programId || CLOAK_PROGRAM_ID;
|
|
2422
|
-
const mintForSOL = new
|
|
2206
|
+
const mintForSOL = new import_web35.PublicKey(new Uint8Array(32));
|
|
2423
2207
|
const { merkleTree } = getShieldPoolPDAs(programId2, mintForSOL);
|
|
2424
2208
|
const merkleTreeAccount = await connection.getAccountInfo(merkleTree);
|
|
2425
2209
|
if (!merkleTreeAccount) {
|
|
@@ -2570,7 +2354,8 @@ ${logs}`
|
|
|
2570
2354
|
throw new Error(`Merkle proof path element at position ${i} must be 64 hex characters (32 bytes)`);
|
|
2571
2355
|
}
|
|
2572
2356
|
}
|
|
2573
|
-
const
|
|
2357
|
+
const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
|
|
2358
|
+
const circuitsPath = isBrowser ? "/circuits" : typeof process !== "undefined" && process.env?.CIRCUITS_PATH || await getDefaultCircuitsPath();
|
|
2574
2359
|
const useDirectProof = await areCircuitsAvailable(circuitsPath);
|
|
2575
2360
|
let proofHex;
|
|
2576
2361
|
let finalPublicInputs;
|
|
@@ -2634,43 +2419,9 @@ ${logs}`
|
|
|
2634
2419
|
amount: note.amount
|
|
2635
2420
|
};
|
|
2636
2421
|
} else {
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
r: note.r,
|
|
2641
|
-
sk_spend: note.sk_spend,
|
|
2642
|
-
leaf_index: note.leafIndex,
|
|
2643
|
-
merkle_path: {
|
|
2644
|
-
path_elements: merkleProof.pathElements,
|
|
2645
|
-
path_indices: merkleProof.pathIndices
|
|
2646
|
-
}
|
|
2647
|
-
},
|
|
2648
|
-
publicInputs: {
|
|
2649
|
-
root: merkleRoot,
|
|
2650
|
-
nf: nullifierHex,
|
|
2651
|
-
outputs_hash: outputsHashHex,
|
|
2652
|
-
amount: note.amount
|
|
2653
|
-
},
|
|
2654
|
-
outputs: recipients.map((r) => ({
|
|
2655
|
-
address: r.recipient.toBase58(),
|
|
2656
|
-
amount: r.amount
|
|
2657
|
-
}))
|
|
2658
|
-
};
|
|
2659
|
-
const proofResult = await this.artifactProver.generateProof(proofInputs, {
|
|
2660
|
-
onProgress: options?.onProofProgress,
|
|
2661
|
-
onError: options?.onProgress ? (error) => options.onProgress?.(`Proof generation error: ${error}`) : void 0
|
|
2662
|
-
});
|
|
2663
|
-
if (!proofResult.success || !proofResult.proof) {
|
|
2664
|
-
let errorMessage = proofResult.error || "Proof generation failed";
|
|
2665
|
-
if (errorMessage.startsWith("Proof generation failed: ")) {
|
|
2666
|
-
errorMessage = errorMessage.substring("Proof generation failed: ".length);
|
|
2667
|
-
}
|
|
2668
|
-
errorMessage += `
|
|
2669
|
-
Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., nullifier=${nullifierHex.slice(0, 16)}...`;
|
|
2670
|
-
throw new Error(errorMessage);
|
|
2671
|
-
}
|
|
2672
|
-
proofHex = proofResult.proof;
|
|
2673
|
-
finalPublicInputs = proofInputs.publicInputs;
|
|
2422
|
+
throw new Error(
|
|
2423
|
+
`Circuits not available at ${circuitsPath}. Make sure circuits are built and accessible. In browser, circuits should be served from /circuits. In Node.js, set CIRCUITS_PATH environment variable or ensure circuits are in the expected location.`
|
|
2424
|
+
);
|
|
2674
2425
|
}
|
|
2675
2426
|
const signature = await this.relay.submitWithdraw(
|
|
2676
2427
|
{
|
|
@@ -2831,7 +2582,7 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
|
|
|
2831
2582
|
if (!getAssociatedTokenAddress) {
|
|
2832
2583
|
throw new Error("getAssociatedTokenAddress not found");
|
|
2833
2584
|
}
|
|
2834
|
-
const outputMint2 = new
|
|
2585
|
+
const outputMint2 = new import_web35.PublicKey(options.outputMint);
|
|
2835
2586
|
recipientAta = await getAssociatedTokenAddress(outputMint2, recipient);
|
|
2836
2587
|
} catch (error) {
|
|
2837
2588
|
throw new Error(
|
|
@@ -2852,8 +2603,8 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
|
|
|
2852
2603
|
}
|
|
2853
2604
|
const nullifier = await computeNullifierAsync(note.sk_spend, note.leafIndex);
|
|
2854
2605
|
const nullifierHex = nullifier.toString(16).padStart(64, "0");
|
|
2855
|
-
const inputMint = new
|
|
2856
|
-
const outputMint = new
|
|
2606
|
+
const inputMint = new import_web35.PublicKey("11111111111111111111111111111111");
|
|
2607
|
+
const outputMint = new import_web35.PublicKey(options.outputMint);
|
|
2857
2608
|
const outputsHash = await computeSwapOutputsHashAsync(
|
|
2858
2609
|
inputMint,
|
|
2859
2610
|
outputMint,
|
|
@@ -2868,7 +2619,8 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
|
|
|
2868
2619
|
if (!merkleProof.pathElements || merkleProof.pathElements.length === 0) {
|
|
2869
2620
|
throw new Error("Merkle proof is invalid: missing path elements");
|
|
2870
2621
|
}
|
|
2871
|
-
const
|
|
2622
|
+
const envCircuitsPath = typeof window !== "undefined" ? typeof process !== "undefined" && process.env?.NEXT_PUBLIC_CIRCUITS_PATH || void 0 : typeof process !== "undefined" && process.env?.CIRCUITS_PATH || void 0;
|
|
2623
|
+
const circuitsPath = envCircuitsPath || await getDefaultCircuitsPath();
|
|
2872
2624
|
const useDirectProof = await areCircuitsAvailable(circuitsPath);
|
|
2873
2625
|
let proofHex;
|
|
2874
2626
|
let finalPublicInputs;
|
|
@@ -2913,46 +2665,9 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
|
|
|
2913
2665
|
amount: note.amount
|
|
2914
2666
|
};
|
|
2915
2667
|
} else {
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
r: note.r,
|
|
2920
|
-
sk_spend: note.sk_spend,
|
|
2921
|
-
leaf_index: note.leafIndex,
|
|
2922
|
-
merkle_path: {
|
|
2923
|
-
path_elements: merkleProof.pathElements,
|
|
2924
|
-
path_indices: merkleProof.pathIndices
|
|
2925
|
-
}
|
|
2926
|
-
},
|
|
2927
|
-
publicInputs: {
|
|
2928
|
-
root: merkleRoot,
|
|
2929
|
-
nf: nullifierHex,
|
|
2930
|
-
outputs_hash: outputsHashHex,
|
|
2931
|
-
amount: note.amount
|
|
2932
|
-
},
|
|
2933
|
-
outputs: [],
|
|
2934
|
-
// Empty for swaps
|
|
2935
|
-
swapParams: {
|
|
2936
|
-
output_mint: options.outputMint,
|
|
2937
|
-
recipient_ata: recipientAta.toBase58(),
|
|
2938
|
-
min_output_amount: minOutputAmount
|
|
2939
|
-
}
|
|
2940
|
-
};
|
|
2941
|
-
const proofResult = await this.artifactProver.generateProof(proofInputs, {
|
|
2942
|
-
onProgress: options.onProofProgress,
|
|
2943
|
-
onError: options.onProgress ? (error) => options.onProgress?.(`Proof generation error: ${error}`) : void 0
|
|
2944
|
-
});
|
|
2945
|
-
if (!proofResult.success || !proofResult.proof) {
|
|
2946
|
-
let errorMessage = proofResult.error || "Proof generation failed";
|
|
2947
|
-
if (errorMessage.startsWith("Proof generation failed: ")) {
|
|
2948
|
-
errorMessage = errorMessage.substring("Proof generation failed: ".length);
|
|
2949
|
-
}
|
|
2950
|
-
errorMessage += `
|
|
2951
|
-
Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., nullifier=${nullifierHex.slice(0, 16)}...`;
|
|
2952
|
-
throw new Error(errorMessage);
|
|
2953
|
-
}
|
|
2954
|
-
proofHex = proofResult.proof;
|
|
2955
|
-
finalPublicInputs = proofInputs.publicInputs;
|
|
2668
|
+
throw new Error(
|
|
2669
|
+
`Circuits not available at ${circuitsPath}. Make sure circuits are built and accessible. In browser, circuits should be served from /circuits. In Node.js, set CIRCUITS_PATH environment variable or ensure circuits are in the expected location.`
|
|
2670
|
+
);
|
|
2956
2671
|
}
|
|
2957
2672
|
const signature = await this.relay.submitSwap(
|
|
2958
2673
|
{
|
|
@@ -3644,9 +3359,9 @@ Total syscalls: ${errorObj.total_syscalls}`;
|
|
|
3644
3359
|
};
|
|
3645
3360
|
|
|
3646
3361
|
// src/helpers/wallet-integration.ts
|
|
3647
|
-
var
|
|
3362
|
+
var import_web36 = require("@solana/web3.js");
|
|
3648
3363
|
function validateWalletConnected(wallet) {
|
|
3649
|
-
if (wallet instanceof
|
|
3364
|
+
if (wallet instanceof import_web36.Keypair) {
|
|
3650
3365
|
return;
|
|
3651
3366
|
}
|
|
3652
3367
|
if (!wallet.publicKey) {
|
|
@@ -3658,7 +3373,7 @@ function validateWalletConnected(wallet) {
|
|
|
3658
3373
|
}
|
|
3659
3374
|
}
|
|
3660
3375
|
function getPublicKey(wallet) {
|
|
3661
|
-
if (wallet instanceof
|
|
3376
|
+
if (wallet instanceof import_web36.Keypair) {
|
|
3662
3377
|
return wallet.publicKey;
|
|
3663
3378
|
}
|
|
3664
3379
|
if (!wallet.publicKey) {
|
|
@@ -3671,7 +3386,7 @@ function getPublicKey(wallet) {
|
|
|
3671
3386
|
return wallet.publicKey;
|
|
3672
3387
|
}
|
|
3673
3388
|
async function sendTransaction(transaction, wallet, connection, options) {
|
|
3674
|
-
if (wallet instanceof
|
|
3389
|
+
if (wallet instanceof import_web36.Keypair) {
|
|
3675
3390
|
return await connection.sendTransaction(transaction, [wallet], options);
|
|
3676
3391
|
}
|
|
3677
3392
|
if (wallet.sendTransaction) {
|
|
@@ -3688,7 +3403,7 @@ async function sendTransaction(transaction, wallet, connection, options) {
|
|
|
3688
3403
|
}
|
|
3689
3404
|
}
|
|
3690
3405
|
async function signTransaction(transaction, wallet) {
|
|
3691
|
-
if (wallet instanceof
|
|
3406
|
+
if (wallet instanceof import_web36.Keypair) {
|
|
3692
3407
|
transaction.sign(wallet);
|
|
3693
3408
|
return transaction;
|
|
3694
3409
|
}
|
|
@@ -3719,7 +3434,6 @@ function keypairToAdapter(keypair) {
|
|
|
3719
3434
|
var VERSION = "1.0.0";
|
|
3720
3435
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3721
3436
|
0 && (module.exports = {
|
|
3722
|
-
ArtifactProverService,
|
|
3723
3437
|
CLOAK_PROGRAM_ID,
|
|
3724
3438
|
CloakError,
|
|
3725
3439
|
CloakSDK,
|