@cloak.ag/sdk 1.0.2 → 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.
- package/dist/chunk-S76QK36U.js +303 -0
- package/dist/crypto-3TOLQOOK.js +54 -0
- package/dist/index.cjs +140 -606
- package/dist/index.d.cts +14 -209
- package/dist/index.d.ts +14 -209
- package/dist/index.js +129 -593
- package/package.json +9 -5
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
8
8
|
// src/core/CloakSDK.ts
|
|
9
9
|
import {
|
|
10
10
|
Keypair,
|
|
11
|
-
PublicKey as
|
|
11
|
+
PublicKey as PublicKey4,
|
|
12
12
|
Transaction
|
|
13
13
|
} from "@solana/web3.js";
|
|
14
14
|
|
|
@@ -28,7 +28,6 @@ import { blake3 } from "@noble/hashes/blake3.js";
|
|
|
28
28
|
import nacl from "tweetnacl";
|
|
29
29
|
|
|
30
30
|
// src/utils/crypto.ts
|
|
31
|
-
import { PublicKey } from "@solana/web3.js";
|
|
32
31
|
import { buildPoseidon } from "circomlibjs";
|
|
33
32
|
var poseidon = null;
|
|
34
33
|
async function getPoseidon() {
|
|
@@ -49,7 +48,7 @@ function splitTo2Limbs(value) {
|
|
|
49
48
|
return [lo, hi];
|
|
50
49
|
}
|
|
51
50
|
function pubkeyToLimbs(pubkey) {
|
|
52
|
-
const bytes = pubkey
|
|
51
|
+
const bytes = typeof pubkey.toBytes === "function" ? pubkey.toBytes() : pubkey;
|
|
53
52
|
const value = BigInt("0x" + Buffer.from(bytes).toString("hex"));
|
|
54
53
|
return splitTo2Limbs(value);
|
|
55
54
|
}
|
|
@@ -677,10 +676,10 @@ var LocalStorageAdapter = class {
|
|
|
677
676
|
};
|
|
678
677
|
|
|
679
678
|
// src/utils/validation.ts
|
|
680
|
-
import { PublicKey
|
|
679
|
+
import { PublicKey } from "@solana/web3.js";
|
|
681
680
|
function isValidSolanaAddress(address) {
|
|
682
681
|
try {
|
|
683
|
-
new
|
|
682
|
+
new PublicKey(address);
|
|
684
683
|
return true;
|
|
685
684
|
} catch {
|
|
686
685
|
return false;
|
|
@@ -779,8 +778,9 @@ function validateTransfers(recipients, totalAmount) {
|
|
|
779
778
|
}
|
|
780
779
|
for (let i = 0; i < recipients.length; i++) {
|
|
781
780
|
const transfer = recipients[i];
|
|
782
|
-
|
|
783
|
-
|
|
781
|
+
const isPublicKeyLike = transfer.recipient && typeof transfer.recipient.toBase58 === "function" && typeof transfer.recipient.toBuffer === "function";
|
|
782
|
+
if (!isPublicKeyLike) {
|
|
783
|
+
throw new Error(`Recipient ${i} must be a PublicKey (got ${typeof transfer.recipient})`);
|
|
784
784
|
}
|
|
785
785
|
if (typeof transfer.amount !== "number" || transfer.amount <= 0) {
|
|
786
786
|
throw new Error(`Recipient ${i} amount must be a positive number`);
|
|
@@ -1025,254 +1025,6 @@ var IndexerService = class {
|
|
|
1025
1025
|
}
|
|
1026
1026
|
};
|
|
1027
1027
|
|
|
1028
|
-
// src/services/ArtifactProverService.ts
|
|
1029
|
-
var ArtifactProverService = class {
|
|
1030
|
-
/**
|
|
1031
|
-
* Create a new Artifact Prover Service client
|
|
1032
|
-
*
|
|
1033
|
-
* @param indexerUrl - Indexer service base URL
|
|
1034
|
-
* @param timeout - Proof generation timeout in ms (default: 5 minutes)
|
|
1035
|
-
* @param pollInterval - Polling interval for status checks (default: 2 seconds)
|
|
1036
|
-
*/
|
|
1037
|
-
constructor(indexerUrl, timeout = 5 * 60 * 1e3, pollInterval = 2e3) {
|
|
1038
|
-
this.indexerUrl = indexerUrl.replace(/\/$/, "");
|
|
1039
|
-
this.timeout = timeout;
|
|
1040
|
-
this.pollInterval = pollInterval;
|
|
1041
|
-
}
|
|
1042
|
-
/**
|
|
1043
|
-
* Generate a zero-knowledge proof using artifact-based flow
|
|
1044
|
-
*
|
|
1045
|
-
* This process typically takes 30-180 seconds depending on the TEE.
|
|
1046
|
-
* Private inputs are uploaded directly to TEE, never passing through backend.
|
|
1047
|
-
*
|
|
1048
|
-
* @param inputs - Circuit inputs (private + public + outputs)
|
|
1049
|
-
* @param options - Optional progress tracking and callbacks
|
|
1050
|
-
* @returns Proof result with hex-encoded proof and public inputs
|
|
1051
|
-
*
|
|
1052
|
-
* @example
|
|
1053
|
-
* ```typescript
|
|
1054
|
-
* const result = await prover.generateProof(inputs);
|
|
1055
|
-
* if (result.success) {
|
|
1056
|
-
* console.log(`Proof: ${result.proof}`);
|
|
1057
|
-
* }
|
|
1058
|
-
* ```
|
|
1059
|
-
*/
|
|
1060
|
-
async generateProof(inputs, options) {
|
|
1061
|
-
const startTime = Date.now();
|
|
1062
|
-
const actualTimeout = options?.timeout || this.timeout;
|
|
1063
|
-
const pollInterval = options?.pollInterval || this.pollInterval;
|
|
1064
|
-
options?.onStart?.();
|
|
1065
|
-
options?.onProgress?.(5);
|
|
1066
|
-
try {
|
|
1067
|
-
options?.onProgress?.(10);
|
|
1068
|
-
const artifactResponse = await fetch(`${this.indexerUrl}/api/v1/tee/artifact`, {
|
|
1069
|
-
method: "POST",
|
|
1070
|
-
headers: {
|
|
1071
|
-
"Content-Type": "application/json"
|
|
1072
|
-
},
|
|
1073
|
-
body: JSON.stringify({
|
|
1074
|
-
program_id: null
|
|
1075
|
-
// Optional, can be null
|
|
1076
|
-
})
|
|
1077
|
-
});
|
|
1078
|
-
if (!artifactResponse.ok) {
|
|
1079
|
-
const errorText = await artifactResponse.text();
|
|
1080
|
-
const errorMessage2 = `Failed to create artifact: ${errorText}`;
|
|
1081
|
-
options?.onError?.(errorMessage2);
|
|
1082
|
-
return {
|
|
1083
|
-
success: false,
|
|
1084
|
-
generationTimeMs: Date.now() - startTime,
|
|
1085
|
-
error: errorMessage2
|
|
1086
|
-
};
|
|
1087
|
-
}
|
|
1088
|
-
const artifactData = await artifactResponse.json();
|
|
1089
|
-
const { artifact_id, upload_url } = artifactData;
|
|
1090
|
-
if (!artifact_id || !upload_url) {
|
|
1091
|
-
const errorMessage2 = "Invalid artifact response: missing artifact_id or upload_url";
|
|
1092
|
-
options?.onError?.(errorMessage2);
|
|
1093
|
-
return {
|
|
1094
|
-
success: false,
|
|
1095
|
-
generationTimeMs: Date.now() - startTime,
|
|
1096
|
-
error: errorMessage2
|
|
1097
|
-
};
|
|
1098
|
-
}
|
|
1099
|
-
const fullUploadUrl = upload_url.startsWith("http") ? upload_url : `${this.indexerUrl}${upload_url}`;
|
|
1100
|
-
options?.onProgress?.(20);
|
|
1101
|
-
const stdinPayload = JSON.stringify({
|
|
1102
|
-
private: inputs.privateInputs,
|
|
1103
|
-
public: inputs.publicInputs,
|
|
1104
|
-
outputs: inputs.outputs,
|
|
1105
|
-
// Include swap_params if present (for swap transactions)
|
|
1106
|
-
...inputs.swapParams && { swap_params: inputs.swapParams }
|
|
1107
|
-
});
|
|
1108
|
-
const uploadResponse = await fetch(fullUploadUrl, {
|
|
1109
|
-
method: "POST",
|
|
1110
|
-
headers: {
|
|
1111
|
-
"Content-Type": "application/json"
|
|
1112
|
-
},
|
|
1113
|
-
body: stdinPayload
|
|
1114
|
-
});
|
|
1115
|
-
if (!uploadResponse.ok) {
|
|
1116
|
-
const errorText = await uploadResponse.text();
|
|
1117
|
-
const errorMessage2 = `Failed to upload stdin to TEE: ${errorText}`;
|
|
1118
|
-
options?.onError?.(errorMessage2);
|
|
1119
|
-
return {
|
|
1120
|
-
success: false,
|
|
1121
|
-
generationTimeMs: Date.now() - startTime,
|
|
1122
|
-
error: errorMessage2
|
|
1123
|
-
};
|
|
1124
|
-
}
|
|
1125
|
-
options?.onProgress?.(30);
|
|
1126
|
-
const requestProofBody = {
|
|
1127
|
-
artifact_id,
|
|
1128
|
-
program_id: null,
|
|
1129
|
-
public_inputs: JSON.stringify(inputs.publicInputs)
|
|
1130
|
-
};
|
|
1131
|
-
const requestProofResponse = await fetch(
|
|
1132
|
-
`${this.indexerUrl}/api/v1/tee/request-proof`,
|
|
1133
|
-
{
|
|
1134
|
-
method: "POST",
|
|
1135
|
-
headers: {
|
|
1136
|
-
"Content-Type": "application/json"
|
|
1137
|
-
},
|
|
1138
|
-
body: JSON.stringify(requestProofBody)
|
|
1139
|
-
}
|
|
1140
|
-
);
|
|
1141
|
-
if (!requestProofResponse.ok) {
|
|
1142
|
-
const errorText = await requestProofResponse.text();
|
|
1143
|
-
const errorMessage2 = `Failed to request proof: ${errorText}`;
|
|
1144
|
-
options?.onError?.(errorMessage2);
|
|
1145
|
-
return {
|
|
1146
|
-
success: false,
|
|
1147
|
-
generationTimeMs: Date.now() - startTime,
|
|
1148
|
-
error: errorMessage2
|
|
1149
|
-
};
|
|
1150
|
-
}
|
|
1151
|
-
const requestProofData = await requestProofResponse.json();
|
|
1152
|
-
const { request_id } = requestProofData;
|
|
1153
|
-
if (!request_id) {
|
|
1154
|
-
const errorMessage2 = "Invalid proof request response: missing request_id";
|
|
1155
|
-
options?.onError?.(errorMessage2);
|
|
1156
|
-
return {
|
|
1157
|
-
success: false,
|
|
1158
|
-
generationTimeMs: Date.now() - startTime,
|
|
1159
|
-
error: errorMessage2
|
|
1160
|
-
};
|
|
1161
|
-
}
|
|
1162
|
-
options?.onProgress?.(40);
|
|
1163
|
-
const pollStartTime = Date.now();
|
|
1164
|
-
let lastProgress = 40;
|
|
1165
|
-
while (Date.now() - pollStartTime < actualTimeout) {
|
|
1166
|
-
const statusResponse = await fetch(
|
|
1167
|
-
`${this.indexerUrl}/api/v1/tee/proof-status?request_id=${request_id}`,
|
|
1168
|
-
{
|
|
1169
|
-
method: "GET"
|
|
1170
|
-
}
|
|
1171
|
-
);
|
|
1172
|
-
if (!statusResponse.ok) {
|
|
1173
|
-
const errorText = await statusResponse.text();
|
|
1174
|
-
const errorMessage2 = `Failed to check proof status: ${errorText}`;
|
|
1175
|
-
options?.onError?.(errorMessage2);
|
|
1176
|
-
return {
|
|
1177
|
-
success: false,
|
|
1178
|
-
generationTimeMs: Date.now() - startTime,
|
|
1179
|
-
error: errorMessage2
|
|
1180
|
-
};
|
|
1181
|
-
}
|
|
1182
|
-
const statusData = await statusResponse.json();
|
|
1183
|
-
const { status, proof, public_inputs, generation_time_ms, error } = statusData;
|
|
1184
|
-
if (status === "ready") {
|
|
1185
|
-
options?.onProgress?.(100);
|
|
1186
|
-
if (!proof || !public_inputs) {
|
|
1187
|
-
const errorMessage2 = "Proof status is 'ready' but proof or public_inputs is missing";
|
|
1188
|
-
options?.onError?.(errorMessage2);
|
|
1189
|
-
return {
|
|
1190
|
-
success: false,
|
|
1191
|
-
generationTimeMs: Date.now() - startTime,
|
|
1192
|
-
error: errorMessage2
|
|
1193
|
-
};
|
|
1194
|
-
}
|
|
1195
|
-
const result = {
|
|
1196
|
-
success: true,
|
|
1197
|
-
proof,
|
|
1198
|
-
publicInputs: public_inputs,
|
|
1199
|
-
generationTimeMs: generation_time_ms || Date.now() - startTime
|
|
1200
|
-
};
|
|
1201
|
-
options?.onSuccess?.(result);
|
|
1202
|
-
return result;
|
|
1203
|
-
}
|
|
1204
|
-
if (status === "failed") {
|
|
1205
|
-
const errorMessage2 = error || "Proof generation failed";
|
|
1206
|
-
options?.onError?.(errorMessage2);
|
|
1207
|
-
return {
|
|
1208
|
-
success: false,
|
|
1209
|
-
generationTimeMs: Date.now() - startTime,
|
|
1210
|
-
error: errorMessage2
|
|
1211
|
-
};
|
|
1212
|
-
}
|
|
1213
|
-
const elapsed = Date.now() - pollStartTime;
|
|
1214
|
-
const progress = Math.min(90, 40 + Math.floor(elapsed / actualTimeout * 50));
|
|
1215
|
-
if (progress > lastProgress) {
|
|
1216
|
-
lastProgress = progress;
|
|
1217
|
-
options?.onProgress?.(progress);
|
|
1218
|
-
}
|
|
1219
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
1220
|
-
}
|
|
1221
|
-
const errorMessage = `Proof generation timed out after ${actualTimeout}ms`;
|
|
1222
|
-
options?.onError?.(errorMessage);
|
|
1223
|
-
return {
|
|
1224
|
-
success: false,
|
|
1225
|
-
generationTimeMs: Date.now() - startTime,
|
|
1226
|
-
error: errorMessage
|
|
1227
|
-
};
|
|
1228
|
-
} catch (error) {
|
|
1229
|
-
const totalTime = Date.now() - startTime;
|
|
1230
|
-
let errorMessage;
|
|
1231
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
1232
|
-
errorMessage = `Proof generation timed out after ${actualTimeout}ms`;
|
|
1233
|
-
} else {
|
|
1234
|
-
errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1235
|
-
}
|
|
1236
|
-
options?.onError?.(errorMessage);
|
|
1237
|
-
return {
|
|
1238
|
-
success: false,
|
|
1239
|
-
generationTimeMs: totalTime,
|
|
1240
|
-
error: errorMessage
|
|
1241
|
-
};
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
/**
|
|
1245
|
-
* Check if the artifact prover service is available
|
|
1246
|
-
*
|
|
1247
|
-
* @returns True if service is healthy
|
|
1248
|
-
*/
|
|
1249
|
-
async healthCheck() {
|
|
1250
|
-
try {
|
|
1251
|
-
const response = await fetch(`${this.indexerUrl}/health`, {
|
|
1252
|
-
method: "GET"
|
|
1253
|
-
});
|
|
1254
|
-
return response.ok;
|
|
1255
|
-
} catch {
|
|
1256
|
-
return false;
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
/**
|
|
1260
|
-
* Get the configured timeout
|
|
1261
|
-
*/
|
|
1262
|
-
getTimeout() {
|
|
1263
|
-
return this.timeout;
|
|
1264
|
-
}
|
|
1265
|
-
/**
|
|
1266
|
-
* Set a new timeout
|
|
1267
|
-
*/
|
|
1268
|
-
setTimeout(timeout) {
|
|
1269
|
-
if (timeout <= 0) {
|
|
1270
|
-
throw new Error("Timeout must be positive");
|
|
1271
|
-
}
|
|
1272
|
-
this.timeout = timeout;
|
|
1273
|
-
}
|
|
1274
|
-
};
|
|
1275
|
-
|
|
1276
1028
|
// src/services/RelayService.ts
|
|
1277
1029
|
var RelayService = class {
|
|
1278
1030
|
/**
|
|
@@ -1769,7 +1521,7 @@ var DepositRecoveryService = class {
|
|
|
1769
1521
|
|
|
1770
1522
|
// src/solana/instructions.ts
|
|
1771
1523
|
import {
|
|
1772
|
-
PublicKey as
|
|
1524
|
+
PublicKey as PublicKey2,
|
|
1773
1525
|
SystemProgram,
|
|
1774
1526
|
TransactionInstruction
|
|
1775
1527
|
} from "@solana/web3.js";
|
|
@@ -1810,16 +1562,16 @@ function createDepositInstruction(params) {
|
|
|
1810
1562
|
});
|
|
1811
1563
|
}
|
|
1812
1564
|
function validateDepositParams(params) {
|
|
1813
|
-
if (!(params.programId instanceof
|
|
1565
|
+
if (!(params.programId instanceof PublicKey2)) {
|
|
1814
1566
|
throw new Error("programId must be a PublicKey");
|
|
1815
1567
|
}
|
|
1816
|
-
if (!(params.payer instanceof
|
|
1568
|
+
if (!(params.payer instanceof PublicKey2)) {
|
|
1817
1569
|
throw new Error("payer must be a PublicKey");
|
|
1818
1570
|
}
|
|
1819
|
-
if (!(params.pool instanceof
|
|
1571
|
+
if (!(params.pool instanceof PublicKey2)) {
|
|
1820
1572
|
throw new Error("pool must be a PublicKey");
|
|
1821
1573
|
}
|
|
1822
|
-
if (!(params.merkleTree instanceof
|
|
1574
|
+
if (!(params.merkleTree instanceof PublicKey2)) {
|
|
1823
1575
|
throw new Error("merkleTree must be a PublicKey");
|
|
1824
1576
|
}
|
|
1825
1577
|
if (typeof params.amount !== "number" || params.amount <= 0) {
|
|
@@ -1836,34 +1588,34 @@ function validateDepositParams(params) {
|
|
|
1836
1588
|
}
|
|
1837
1589
|
|
|
1838
1590
|
// src/utils/pda.ts
|
|
1839
|
-
import { PublicKey as
|
|
1591
|
+
import { PublicKey as PublicKey3 } from "@solana/web3.js";
|
|
1840
1592
|
function getShieldPoolPDAs(programId, mint) {
|
|
1841
1593
|
const pid = programId || CLOAK_PROGRAM_ID;
|
|
1842
|
-
const mintKey = mint ?? new
|
|
1594
|
+
const mintKey = mint ?? new PublicKey3(
|
|
1843
1595
|
// 32 zero bytes, matching Rust `Pubkey::default()`
|
|
1844
1596
|
new Uint8Array(32)
|
|
1845
1597
|
);
|
|
1846
|
-
const [pool] =
|
|
1598
|
+
const [pool] = PublicKey3.findProgramAddressSync(
|
|
1847
1599
|
[Buffer.from("pool"), mintKey.toBytes()],
|
|
1848
1600
|
pid
|
|
1849
1601
|
);
|
|
1850
|
-
const [merkleTree] =
|
|
1602
|
+
const [merkleTree] = PublicKey3.findProgramAddressSync(
|
|
1851
1603
|
[Buffer.from("merkle_tree"), mintKey.toBytes()],
|
|
1852
1604
|
pid
|
|
1853
1605
|
);
|
|
1854
|
-
const [commitments] =
|
|
1606
|
+
const [commitments] = PublicKey3.findProgramAddressSync(
|
|
1855
1607
|
[Buffer.from("commitments"), mintKey.toBytes()],
|
|
1856
1608
|
pid
|
|
1857
1609
|
);
|
|
1858
|
-
const [rootsRing] =
|
|
1610
|
+
const [rootsRing] = PublicKey3.findProgramAddressSync(
|
|
1859
1611
|
[Buffer.from("roots_ring"), mintKey.toBytes()],
|
|
1860
1612
|
pid
|
|
1861
1613
|
);
|
|
1862
|
-
const [nullifierShard] =
|
|
1614
|
+
const [nullifierShard] = PublicKey3.findProgramAddressSync(
|
|
1863
1615
|
[Buffer.from("nullifier_shard"), mintKey.toBytes()],
|
|
1864
1616
|
pid
|
|
1865
1617
|
);
|
|
1866
|
-
const [treasury] =
|
|
1618
|
+
const [treasury] = PublicKey3.findProgramAddressSync(
|
|
1867
1619
|
[Buffer.from("treasury"), mintKey.toBytes()],
|
|
1868
1620
|
pid
|
|
1869
1621
|
);
|
|
@@ -1910,6 +1662,15 @@ async function fileExists(filePath) {
|
|
|
1910
1662
|
return false;
|
|
1911
1663
|
}
|
|
1912
1664
|
}
|
|
1665
|
+
const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
|
|
1666
|
+
if (isBrowser) {
|
|
1667
|
+
try {
|
|
1668
|
+
const response = await fetch(filePath, { method: "HEAD" });
|
|
1669
|
+
return response.ok;
|
|
1670
|
+
} catch {
|
|
1671
|
+
return false;
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1913
1674
|
return false;
|
|
1914
1675
|
}
|
|
1915
1676
|
async function generateWithdrawRegularProof(inputs, circuitsPath) {
|
|
@@ -1953,11 +1714,7 @@ async function generateWithdrawRegularProof(inputs, circuitsPath) {
|
|
|
1953
1714
|
var_fee: inputs.var_fee.toString(),
|
|
1954
1715
|
rem: inputs.rem.toString()
|
|
1955
1716
|
};
|
|
1956
|
-
const { proof, publicSignals } = await snarkjs.groth16.fullProve(
|
|
1957
|
-
circuitInputs,
|
|
1958
|
-
wasmPath,
|
|
1959
|
-
zkeyPath
|
|
1960
|
-
);
|
|
1717
|
+
const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, wasmPath, zkeyPath);
|
|
1961
1718
|
const proofBytes = proofToBytes(proof);
|
|
1962
1719
|
return {
|
|
1963
1720
|
proof,
|
|
@@ -2026,6 +1783,10 @@ async function generateWithdrawSwapProof(inputs, circuitsPath) {
|
|
|
2026
1783
|
};
|
|
2027
1784
|
}
|
|
2028
1785
|
async function areCircuitsAvailable(circuitsPath) {
|
|
1786
|
+
const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
|
|
1787
|
+
if (isBrowser) {
|
|
1788
|
+
return Boolean(circuitsPath && circuitsPath !== "");
|
|
1789
|
+
}
|
|
2029
1790
|
const wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
|
|
2030
1791
|
const zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
|
|
2031
1792
|
const wasmExists = await fileExists(wasmPath);
|
|
@@ -2057,11 +1818,11 @@ async function getDefaultCircuitsPath() {
|
|
|
2057
1818
|
}
|
|
2058
1819
|
|
|
2059
1820
|
// src/core/CloakSDK.ts
|
|
2060
|
-
var CLOAK_PROGRAM_ID = new
|
|
1821
|
+
var CLOAK_PROGRAM_ID = new PublicKey4("c1oak6tetxYnNfvXKFkpn1d98FxtK7B68vBQLYQpWKp");
|
|
2061
1822
|
var CLOAK_API_URL = "https://api.cloak.ag";
|
|
2062
1823
|
var CloakSDK = class {
|
|
2063
1824
|
/**
|
|
2064
|
-
|
|
1825
|
+
* Create a new Cloak SDK client
|
|
2065
1826
|
*
|
|
2066
1827
|
* @param config - Client configuration
|
|
2067
1828
|
*
|
|
@@ -2094,7 +1855,6 @@ var CloakSDK = class {
|
|
|
2094
1855
|
const indexerUrl = config.indexerUrl || typeof process !== "undefined" && process.env?.CLOAK_INDEXER_URL || CLOAK_API_URL;
|
|
2095
1856
|
const relayUrl = config.relayUrl || typeof process !== "undefined" && process.env?.CLOAK_RELAY_URL || CLOAK_API_URL;
|
|
2096
1857
|
this.indexer = new IndexerService(indexerUrl);
|
|
2097
|
-
this.artifactProver = new ArtifactProverService(indexerUrl, 5 * 60 * 1e3, 2e3);
|
|
2098
1858
|
this.relay = new RelayService(relayUrl);
|
|
2099
1859
|
this.depositRecovery = new DepositRecoveryService(this.indexer, indexerUrl);
|
|
2100
1860
|
if (!this.cloakKeys) {
|
|
@@ -2199,27 +1959,48 @@ var CloakSDK = class {
|
|
|
2199
1959
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
|
|
2200
1960
|
const transaction = new Transaction({
|
|
2201
1961
|
feePayer: payerPubkey,
|
|
2202
|
-
blockhash
|
|
2203
|
-
lastValidBlockHeight
|
|
1962
|
+
recentBlockhash: blockhash
|
|
2204
1963
|
}).add(depositIx);
|
|
2205
|
-
if (!
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
`Transaction simulation failed: ${JSON.stringify(simulation.value.err)}
|
|
2211
|
-
Logs:
|
|
2212
|
-
${logs}`
|
|
2213
|
-
);
|
|
2214
|
-
}
|
|
1964
|
+
if (!transaction.feePayer) {
|
|
1965
|
+
throw new Error("Transaction feePayer is not set");
|
|
1966
|
+
}
|
|
1967
|
+
if (!transaction.recentBlockhash) {
|
|
1968
|
+
throw new Error("Transaction recentBlockhash is not set");
|
|
2215
1969
|
}
|
|
2216
1970
|
let signature;
|
|
2217
|
-
if (this.wallet
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
1971
|
+
if (this.wallet) {
|
|
1972
|
+
if (!this.wallet.publicKey) {
|
|
1973
|
+
throw new Error("Wallet not connected - publicKey is null");
|
|
1974
|
+
}
|
|
1975
|
+
if (this.wallet.signTransaction) {
|
|
1976
|
+
try {
|
|
1977
|
+
const signedTransaction = await this.wallet.signTransaction(transaction);
|
|
1978
|
+
const rawTransaction = signedTransaction.serialize();
|
|
1979
|
+
signature = await connection.sendRawTransaction(rawTransaction, {
|
|
1980
|
+
skipPreflight: options?.skipPreflight || false,
|
|
1981
|
+
preflightCommitment: "confirmed",
|
|
1982
|
+
maxRetries: 3
|
|
1983
|
+
});
|
|
1984
|
+
} catch (signError) {
|
|
1985
|
+
if (this.wallet.sendTransaction) {
|
|
1986
|
+
signature = await this.wallet.sendTransaction(transaction, connection, {
|
|
1987
|
+
skipPreflight: options?.skipPreflight || false,
|
|
1988
|
+
preflightCommitment: "confirmed",
|
|
1989
|
+
maxRetries: 3
|
|
1990
|
+
});
|
|
1991
|
+
} else {
|
|
1992
|
+
throw signError;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
} else if (this.wallet.sendTransaction) {
|
|
1996
|
+
signature = await this.wallet.sendTransaction(transaction, connection, {
|
|
1997
|
+
skipPreflight: options?.skipPreflight || false,
|
|
1998
|
+
preflightCommitment: "confirmed",
|
|
1999
|
+
maxRetries: 3
|
|
2000
|
+
});
|
|
2001
|
+
} else {
|
|
2002
|
+
throw new Error("Wallet adapter must provide either sendTransaction or signTransaction");
|
|
2003
|
+
}
|
|
2223
2004
|
} else if (this.keypair) {
|
|
2224
2005
|
signature = await connection.sendTransaction(transaction, [this.keypair], {
|
|
2225
2006
|
skipPreflight: options?.skipPreflight || false,
|
|
@@ -2304,7 +2085,7 @@ ${logs}`
|
|
|
2304
2085
|
}
|
|
2305
2086
|
if (leafIndex === null) {
|
|
2306
2087
|
const programId2 = this.config.programId || CLOAK_PROGRAM_ID;
|
|
2307
|
-
const mintForSOL = new
|
|
2088
|
+
const mintForSOL = new PublicKey4(new Uint8Array(32));
|
|
2308
2089
|
const { merkleTree } = getShieldPoolPDAs(programId2, mintForSOL);
|
|
2309
2090
|
const merkleTreeAccount = await connection.getAccountInfo(merkleTree);
|
|
2310
2091
|
if (!merkleTreeAccount) {
|
|
@@ -2409,17 +2190,10 @@ ${logs}`
|
|
|
2409
2190
|
const feeBps = Math.ceil(protocolFee * 1e4 / note.amount);
|
|
2410
2191
|
const distributableAmount = getDistributableAmount2(note.amount);
|
|
2411
2192
|
validateTransfers(recipients, distributableAmount);
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
if (
|
|
2415
|
-
|
|
2416
|
-
pathElements: note.merkleProof.pathElements,
|
|
2417
|
-
pathIndices: note.merkleProof.pathIndices
|
|
2418
|
-
};
|
|
2419
|
-
merkleRoot = note.root;
|
|
2420
|
-
} else {
|
|
2421
|
-
merkleProof = await this.indexer.getMerkleProof(note.leafIndex);
|
|
2422
|
-
merkleRoot = merkleProof.root || (await this.indexer.getMerkleRoot()).root;
|
|
2193
|
+
const merkleProof = await this.indexer.getMerkleProof(note.leafIndex);
|
|
2194
|
+
const merkleRoot = merkleProof.root || (await this.indexer.getMerkleRoot()).root;
|
|
2195
|
+
if (!merkleRoot) {
|
|
2196
|
+
throw new Error("Failed to get Merkle root from indexer");
|
|
2423
2197
|
}
|
|
2424
2198
|
const nullifier = await computeNullifierAsync(note.sk_spend, note.leafIndex);
|
|
2425
2199
|
const nullifierHex = nullifier.toString(16).padStart(64, "0");
|
|
@@ -2455,7 +2229,8 @@ ${logs}`
|
|
|
2455
2229
|
throw new Error(`Merkle proof path element at position ${i} must be 64 hex characters (32 bytes)`);
|
|
2456
2230
|
}
|
|
2457
2231
|
}
|
|
2458
|
-
const
|
|
2232
|
+
const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
|
|
2233
|
+
const circuitsPath = isBrowser ? "/circuits" : typeof process !== "undefined" && process.env?.CIRCUITS_PATH || await getDefaultCircuitsPath();
|
|
2459
2234
|
const useDirectProof = await areCircuitsAvailable(circuitsPath);
|
|
2460
2235
|
let proofHex;
|
|
2461
2236
|
let finalPublicInputs;
|
|
@@ -2492,6 +2267,13 @@ ${logs}`
|
|
|
2492
2267
|
}
|
|
2493
2268
|
const sk = splitTo2Limbs(sk_spend_bigint);
|
|
2494
2269
|
const r = splitTo2Limbs(r_bigint);
|
|
2270
|
+
const computedCommitment = await computeCommitment(amount_bigint, r_bigint, sk_spend_bigint);
|
|
2271
|
+
const noteCommitment = BigInt("0x" + note.commitment);
|
|
2272
|
+
if (computedCommitment !== noteCommitment) {
|
|
2273
|
+
throw new Error(
|
|
2274
|
+
`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.`
|
|
2275
|
+
);
|
|
2276
|
+
}
|
|
2495
2277
|
const proofInputs = {
|
|
2496
2278
|
root: root_bigint,
|
|
2497
2279
|
nullifier: nullifier_bigint,
|
|
@@ -2510,7 +2292,9 @@ ${logs}`
|
|
|
2510
2292
|
var_fee: varFee,
|
|
2511
2293
|
rem
|
|
2512
2294
|
};
|
|
2295
|
+
options?.onProgress?.("proof_generating");
|
|
2513
2296
|
const proofResult = await generateWithdrawRegularProof(proofInputs, circuitsPath);
|
|
2297
|
+
options?.onProgress?.("proof_complete");
|
|
2514
2298
|
proofHex = Buffer.from(proofResult.proofBytes).toString("hex");
|
|
2515
2299
|
finalPublicInputs = {
|
|
2516
2300
|
root: merkleRoot,
|
|
@@ -2519,43 +2303,9 @@ ${logs}`
|
|
|
2519
2303
|
amount: note.amount
|
|
2520
2304
|
};
|
|
2521
2305
|
} else {
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
r: note.r,
|
|
2526
|
-
sk_spend: note.sk_spend,
|
|
2527
|
-
leaf_index: note.leafIndex,
|
|
2528
|
-
merkle_path: {
|
|
2529
|
-
path_elements: merkleProof.pathElements,
|
|
2530
|
-
path_indices: merkleProof.pathIndices
|
|
2531
|
-
}
|
|
2532
|
-
},
|
|
2533
|
-
publicInputs: {
|
|
2534
|
-
root: merkleRoot,
|
|
2535
|
-
nf: nullifierHex,
|
|
2536
|
-
outputs_hash: outputsHashHex,
|
|
2537
|
-
amount: note.amount
|
|
2538
|
-
},
|
|
2539
|
-
outputs: recipients.map((r) => ({
|
|
2540
|
-
address: r.recipient.toBase58(),
|
|
2541
|
-
amount: r.amount
|
|
2542
|
-
}))
|
|
2543
|
-
};
|
|
2544
|
-
const proofResult = await this.artifactProver.generateProof(proofInputs, {
|
|
2545
|
-
onProgress: options?.onProofProgress,
|
|
2546
|
-
onError: options?.onProgress ? (error) => options.onProgress?.(`Proof generation error: ${error}`) : void 0
|
|
2547
|
-
});
|
|
2548
|
-
if (!proofResult.success || !proofResult.proof) {
|
|
2549
|
-
let errorMessage = proofResult.error || "Proof generation failed";
|
|
2550
|
-
if (errorMessage.startsWith("Proof generation failed: ")) {
|
|
2551
|
-
errorMessage = errorMessage.substring("Proof generation failed: ".length);
|
|
2552
|
-
}
|
|
2553
|
-
errorMessage += `
|
|
2554
|
-
Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., nullifier=${nullifierHex.slice(0, 16)}...`;
|
|
2555
|
-
throw new Error(errorMessage);
|
|
2556
|
-
}
|
|
2557
|
-
proofHex = proofResult.proof;
|
|
2558
|
-
finalPublicInputs = proofInputs.publicInputs;
|
|
2306
|
+
throw new Error(
|
|
2307
|
+
`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.`
|
|
2308
|
+
);
|
|
2559
2309
|
}
|
|
2560
2310
|
const signature = await this.relay.submitWithdraw(
|
|
2561
2311
|
{
|
|
@@ -2710,35 +2460,32 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
|
|
|
2710
2460
|
);
|
|
2711
2461
|
}
|
|
2712
2462
|
let recipientAta;
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2463
|
+
if (options.recipientAta) {
|
|
2464
|
+
recipientAta = new PublicKey4(options.recipientAta);
|
|
2465
|
+
} else {
|
|
2466
|
+
try {
|
|
2467
|
+
const splTokenModule = await import("@solana/spl-token");
|
|
2468
|
+
const getAssociatedTokenAddress = splTokenModule.getAssociatedTokenAddress;
|
|
2469
|
+
if (!getAssociatedTokenAddress) {
|
|
2470
|
+
throw new Error("getAssociatedTokenAddress not found");
|
|
2471
|
+
}
|
|
2472
|
+
const outputMint2 = new PublicKey4(options.outputMint);
|
|
2473
|
+
recipientAta = await getAssociatedTokenAddress(outputMint2, recipient);
|
|
2474
|
+
} catch (error) {
|
|
2475
|
+
throw new Error(
|
|
2476
|
+
`Failed to get associated token account: ${error instanceof Error ? error.message : String(error)}. Please install @solana/spl-token or provide recipientAta in options.`
|
|
2477
|
+
);
|
|
2718
2478
|
}
|
|
2719
|
-
const outputMint2 = new PublicKey5(options.outputMint);
|
|
2720
|
-
recipientAta = await getAssociatedTokenAddress(outputMint2, recipient);
|
|
2721
|
-
} catch (error) {
|
|
2722
|
-
throw new Error(
|
|
2723
|
-
`Failed to get associated token account: ${error instanceof Error ? error.message : String(error)}. Please install @solana/spl-token or provide recipientAta in options.`
|
|
2724
|
-
);
|
|
2725
2479
|
}
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
if (
|
|
2729
|
-
|
|
2730
|
-
pathElements: note.merkleProof.pathElements,
|
|
2731
|
-
pathIndices: note.merkleProof.pathIndices
|
|
2732
|
-
};
|
|
2733
|
-
merkleRoot = note.root;
|
|
2734
|
-
} else {
|
|
2735
|
-
merkleProof = await this.indexer.getMerkleProof(note.leafIndex);
|
|
2736
|
-
merkleRoot = merkleProof.root || (await this.indexer.getMerkleRoot()).root;
|
|
2480
|
+
const merkleProof = await this.indexer.getMerkleProof(note.leafIndex);
|
|
2481
|
+
const merkleRoot = merkleProof.root || (await this.indexer.getMerkleRoot()).root;
|
|
2482
|
+
if (!merkleRoot) {
|
|
2483
|
+
throw new Error("Failed to get Merkle root from indexer");
|
|
2737
2484
|
}
|
|
2738
2485
|
const nullifier = await computeNullifierAsync(note.sk_spend, note.leafIndex);
|
|
2739
2486
|
const nullifierHex = nullifier.toString(16).padStart(64, "0");
|
|
2740
|
-
const inputMint = new
|
|
2741
|
-
const outputMint = new
|
|
2487
|
+
const inputMint = new PublicKey4("11111111111111111111111111111111");
|
|
2488
|
+
const outputMint = new PublicKey4(options.outputMint);
|
|
2742
2489
|
const outputsHash = await computeSwapOutputsHashAsync(
|
|
2743
2490
|
inputMint,
|
|
2744
2491
|
outputMint,
|
|
@@ -2753,7 +2500,8 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
|
|
|
2753
2500
|
if (!merkleProof.pathElements || merkleProof.pathElements.length === 0) {
|
|
2754
2501
|
throw new Error("Merkle proof is invalid: missing path elements");
|
|
2755
2502
|
}
|
|
2756
|
-
const
|
|
2503
|
+
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;
|
|
2504
|
+
const circuitsPath = envCircuitsPath || await getDefaultCircuitsPath();
|
|
2757
2505
|
const useDirectProof = await areCircuitsAvailable(circuitsPath);
|
|
2758
2506
|
let proofHex;
|
|
2759
2507
|
let finalPublicInputs;
|
|
@@ -2768,6 +2516,13 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
|
|
|
2768
2516
|
const inputMintLimbs = pubkeyToLimbs(inputMint.toBytes());
|
|
2769
2517
|
const outputMintLimbs = pubkeyToLimbs(outputMint.toBytes());
|
|
2770
2518
|
const recipientAtaLimbs = pubkeyToLimbs(recipientAta.toBytes());
|
|
2519
|
+
const computedCommitment = await computeCommitment(amount_bigint, r_bigint, sk_spend_bigint);
|
|
2520
|
+
const noteCommitment = BigInt("0x" + note.commitment);
|
|
2521
|
+
if (computedCommitment !== noteCommitment) {
|
|
2522
|
+
throw new Error(
|
|
2523
|
+
`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.`
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2771
2526
|
const t = amount_bigint * 5n;
|
|
2772
2527
|
const varFee = t / 1000n;
|
|
2773
2528
|
const rem = t % 1000n;
|
|
@@ -2789,7 +2544,9 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
|
|
|
2789
2544
|
var_fee: varFee,
|
|
2790
2545
|
rem
|
|
2791
2546
|
};
|
|
2547
|
+
options?.onProgress?.("proof_generating");
|
|
2792
2548
|
const proofResult = await generateWithdrawSwapProof(proofInputs, circuitsPath);
|
|
2549
|
+
options?.onProgress?.("proof_complete");
|
|
2793
2550
|
proofHex = Buffer.from(proofResult.proofBytes).toString("hex");
|
|
2794
2551
|
finalPublicInputs = {
|
|
2795
2552
|
root: merkleRoot,
|
|
@@ -2798,46 +2555,9 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
|
|
|
2798
2555
|
amount: note.amount
|
|
2799
2556
|
};
|
|
2800
2557
|
} else {
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
r: note.r,
|
|
2805
|
-
sk_spend: note.sk_spend,
|
|
2806
|
-
leaf_index: note.leafIndex,
|
|
2807
|
-
merkle_path: {
|
|
2808
|
-
path_elements: merkleProof.pathElements,
|
|
2809
|
-
path_indices: merkleProof.pathIndices
|
|
2810
|
-
}
|
|
2811
|
-
},
|
|
2812
|
-
publicInputs: {
|
|
2813
|
-
root: merkleRoot,
|
|
2814
|
-
nf: nullifierHex,
|
|
2815
|
-
outputs_hash: outputsHashHex,
|
|
2816
|
-
amount: note.amount
|
|
2817
|
-
},
|
|
2818
|
-
outputs: [],
|
|
2819
|
-
// Empty for swaps
|
|
2820
|
-
swapParams: {
|
|
2821
|
-
output_mint: options.outputMint,
|
|
2822
|
-
recipient_ata: recipientAta.toBase58(),
|
|
2823
|
-
min_output_amount: minOutputAmount
|
|
2824
|
-
}
|
|
2825
|
-
};
|
|
2826
|
-
const proofResult = await this.artifactProver.generateProof(proofInputs, {
|
|
2827
|
-
onProgress: options.onProofProgress,
|
|
2828
|
-
onError: options.onProgress ? (error) => options.onProgress?.(`Proof generation error: ${error}`) : void 0
|
|
2829
|
-
});
|
|
2830
|
-
if (!proofResult.success || !proofResult.proof) {
|
|
2831
|
-
let errorMessage = proofResult.error || "Proof generation failed";
|
|
2832
|
-
if (errorMessage.startsWith("Proof generation failed: ")) {
|
|
2833
|
-
errorMessage = errorMessage.substring("Proof generation failed: ".length);
|
|
2834
|
-
}
|
|
2835
|
-
errorMessage += `
|
|
2836
|
-
Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., nullifier=${nullifierHex.slice(0, 16)}...`;
|
|
2837
|
-
throw new Error(errorMessage);
|
|
2838
|
-
}
|
|
2839
|
-
proofHex = proofResult.proof;
|
|
2840
|
-
finalPublicInputs = proofInputs.publicInputs;
|
|
2558
|
+
throw new Error(
|
|
2559
|
+
`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.`
|
|
2560
|
+
);
|
|
2841
2561
|
}
|
|
2842
2562
|
const signature = await this.relay.submitSwap(
|
|
2843
2563
|
{
|
|
@@ -3346,188 +3066,6 @@ function formatErrorForLogging(error) {
|
|
|
3346
3066
|
return String(error);
|
|
3347
3067
|
}
|
|
3348
3068
|
|
|
3349
|
-
// src/services/ProverService.ts
|
|
3350
|
-
var ProverService = class {
|
|
3351
|
-
/**
|
|
3352
|
-
* Create a new Prover Service client
|
|
3353
|
-
*
|
|
3354
|
-
* @param indexerUrl - Indexer/Prover service base URL
|
|
3355
|
-
* @param timeout - Proof generation timeout in ms (default: 5 minutes)
|
|
3356
|
-
*/
|
|
3357
|
-
constructor(indexerUrl, timeout = 5 * 60 * 1e3) {
|
|
3358
|
-
this.indexerUrl = indexerUrl.replace(/\/$/, "");
|
|
3359
|
-
this.timeout = timeout;
|
|
3360
|
-
}
|
|
3361
|
-
/**
|
|
3362
|
-
* Generate a zero-knowledge proof for withdrawal
|
|
3363
|
-
*
|
|
3364
|
-
* This process typically takes 30-180 seconds depending on the backend.
|
|
3365
|
-
*
|
|
3366
|
-
* @param inputs - Circuit inputs (private + public + outputs)
|
|
3367
|
-
* @param options - Optional progress tracking and callbacks
|
|
3368
|
-
* @returns Proof result with hex-encoded proof and public inputs
|
|
3369
|
-
*
|
|
3370
|
-
* @example
|
|
3371
|
-
* ```typescript
|
|
3372
|
-
* const result = await prover.generateProof(inputs);
|
|
3373
|
-
* if (result.success) {
|
|
3374
|
-
* console.log(`Proof: ${result.proof}`);
|
|
3375
|
-
* }
|
|
3376
|
-
* ```
|
|
3377
|
-
*
|
|
3378
|
-
* @example
|
|
3379
|
-
* ```typescript
|
|
3380
|
-
* // With progress tracking
|
|
3381
|
-
* const result = await prover.generateProof(inputs, {
|
|
3382
|
-
* onProgress: (progress) => console.log(`Progress: ${progress}%`),
|
|
3383
|
-
* onStart: () => console.log("Starting proof generation..."),
|
|
3384
|
-
* onSuccess: (result) => console.log("Proof generated!"),
|
|
3385
|
-
* onError: (error) => console.error("Failed:", error)
|
|
3386
|
-
* });
|
|
3387
|
-
* ```
|
|
3388
|
-
*/
|
|
3389
|
-
async generateProof(inputs, options) {
|
|
3390
|
-
const startTime = Date.now();
|
|
3391
|
-
const actualTimeout = options?.timeout || this.timeout;
|
|
3392
|
-
options?.onStart?.();
|
|
3393
|
-
let progressInterval;
|
|
3394
|
-
try {
|
|
3395
|
-
const requestBody = {
|
|
3396
|
-
private_inputs: JSON.stringify(inputs.privateInputs),
|
|
3397
|
-
public_inputs: JSON.stringify(inputs.publicInputs),
|
|
3398
|
-
outputs: JSON.stringify(inputs.outputs)
|
|
3399
|
-
};
|
|
3400
|
-
if (inputs.swapParams) {
|
|
3401
|
-
requestBody.swap_params = inputs.swapParams;
|
|
3402
|
-
}
|
|
3403
|
-
const controller = new AbortController();
|
|
3404
|
-
const timeoutId = setTimeout(() => controller.abort(), actualTimeout);
|
|
3405
|
-
if (options?.onProgress) {
|
|
3406
|
-
let progress = 0;
|
|
3407
|
-
progressInterval = setInterval(() => {
|
|
3408
|
-
progress = Math.min(90, progress + Math.random() * 10);
|
|
3409
|
-
options.onProgress(Math.floor(progress));
|
|
3410
|
-
}, 2e3);
|
|
3411
|
-
}
|
|
3412
|
-
const response = await fetch(`${this.indexerUrl}/api/v1/prove`, {
|
|
3413
|
-
method: "POST",
|
|
3414
|
-
headers: {
|
|
3415
|
-
"Content-Type": "application/json"
|
|
3416
|
-
},
|
|
3417
|
-
body: JSON.stringify(requestBody),
|
|
3418
|
-
signal: controller.signal
|
|
3419
|
-
});
|
|
3420
|
-
clearTimeout(timeoutId);
|
|
3421
|
-
if (progressInterval) clearInterval(progressInterval);
|
|
3422
|
-
if (!response.ok) {
|
|
3423
|
-
let errorMessage = `${response.status} ${response.statusText}`;
|
|
3424
|
-
try {
|
|
3425
|
-
const errorText = await response.text();
|
|
3426
|
-
try {
|
|
3427
|
-
const errorJson = JSON.parse(errorText);
|
|
3428
|
-
errorMessage = errorJson.error || errorJson.message || errorText;
|
|
3429
|
-
} catch {
|
|
3430
|
-
errorMessage = errorText || errorMessage;
|
|
3431
|
-
}
|
|
3432
|
-
} catch {
|
|
3433
|
-
}
|
|
3434
|
-
options?.onError?.(errorMessage);
|
|
3435
|
-
return {
|
|
3436
|
-
success: false,
|
|
3437
|
-
generationTimeMs: Date.now() - startTime,
|
|
3438
|
-
error: errorMessage
|
|
3439
|
-
};
|
|
3440
|
-
}
|
|
3441
|
-
options?.onProgress?.(100);
|
|
3442
|
-
const rawData = await response.json();
|
|
3443
|
-
const result = {
|
|
3444
|
-
success: rawData.success,
|
|
3445
|
-
proof: rawData.proof,
|
|
3446
|
-
publicInputs: rawData.public_inputs,
|
|
3447
|
-
// Map snake_case
|
|
3448
|
-
generationTimeMs: rawData.generation_time_ms || Date.now() - startTime,
|
|
3449
|
-
error: rawData.error
|
|
3450
|
-
};
|
|
3451
|
-
if (!result.success && rawData.execution_report) {
|
|
3452
|
-
}
|
|
3453
|
-
if (!result.success && result.error) {
|
|
3454
|
-
try {
|
|
3455
|
-
const errorObj = typeof result.error === "string" ? JSON.parse(result.error) : result.error;
|
|
3456
|
-
if (errorObj?.error && typeof errorObj.error === "string") {
|
|
3457
|
-
result.error = errorObj.error;
|
|
3458
|
-
} else if (typeof errorObj === "string") {
|
|
3459
|
-
result.error = errorObj;
|
|
3460
|
-
}
|
|
3461
|
-
if (errorObj?.execution_report && typeof errorObj.execution_report === "string") {
|
|
3462
|
-
result.error += `
|
|
3463
|
-
Execution report: ${errorObj.execution_report}`;
|
|
3464
|
-
}
|
|
3465
|
-
if (errorObj?.total_cycles !== void 0) {
|
|
3466
|
-
result.error += `
|
|
3467
|
-
Total cycles: ${errorObj.total_cycles}`;
|
|
3468
|
-
}
|
|
3469
|
-
if (errorObj?.total_syscalls !== void 0) {
|
|
3470
|
-
result.error += `
|
|
3471
|
-
Total syscalls: ${errorObj.total_syscalls}`;
|
|
3472
|
-
}
|
|
3473
|
-
} catch {
|
|
3474
|
-
}
|
|
3475
|
-
}
|
|
3476
|
-
if (result.success) {
|
|
3477
|
-
options?.onSuccess?.(result);
|
|
3478
|
-
} else if (result.error) {
|
|
3479
|
-
options?.onError?.(result.error);
|
|
3480
|
-
}
|
|
3481
|
-
return result;
|
|
3482
|
-
} catch (error) {
|
|
3483
|
-
const totalTime = Date.now() - startTime;
|
|
3484
|
-
if (progressInterval) clearInterval(progressInterval);
|
|
3485
|
-
let errorMessage;
|
|
3486
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
3487
|
-
errorMessage = `Proof generation timed out after ${actualTimeout}ms`;
|
|
3488
|
-
} else {
|
|
3489
|
-
errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
3490
|
-
}
|
|
3491
|
-
options?.onError?.(errorMessage);
|
|
3492
|
-
return {
|
|
3493
|
-
success: false,
|
|
3494
|
-
generationTimeMs: totalTime,
|
|
3495
|
-
error: errorMessage
|
|
3496
|
-
};
|
|
3497
|
-
}
|
|
3498
|
-
}
|
|
3499
|
-
/**
|
|
3500
|
-
* Check if the prover service is available
|
|
3501
|
-
*
|
|
3502
|
-
* @returns True if service is healthy
|
|
3503
|
-
*/
|
|
3504
|
-
async healthCheck() {
|
|
3505
|
-
try {
|
|
3506
|
-
const response = await fetch(`${this.indexerUrl}/health`, {
|
|
3507
|
-
method: "GET"
|
|
3508
|
-
});
|
|
3509
|
-
return response.ok;
|
|
3510
|
-
} catch {
|
|
3511
|
-
return false;
|
|
3512
|
-
}
|
|
3513
|
-
}
|
|
3514
|
-
/**
|
|
3515
|
-
* Get the configured timeout
|
|
3516
|
-
*/
|
|
3517
|
-
getTimeout() {
|
|
3518
|
-
return this.timeout;
|
|
3519
|
-
}
|
|
3520
|
-
/**
|
|
3521
|
-
* Set a new timeout
|
|
3522
|
-
*/
|
|
3523
|
-
setTimeout(timeout) {
|
|
3524
|
-
if (timeout <= 0) {
|
|
3525
|
-
throw new Error("Timeout must be positive");
|
|
3526
|
-
}
|
|
3527
|
-
this.timeout = timeout;
|
|
3528
|
-
}
|
|
3529
|
-
};
|
|
3530
|
-
|
|
3531
3069
|
// src/helpers/wallet-integration.ts
|
|
3532
3070
|
import {
|
|
3533
3071
|
Keypair as Keypair2
|
|
@@ -3605,7 +3143,6 @@ function keypairToAdapter(keypair) {
|
|
|
3605
3143
|
// src/index.ts
|
|
3606
3144
|
var VERSION = "1.0.0";
|
|
3607
3145
|
export {
|
|
3608
|
-
ArtifactProverService,
|
|
3609
3146
|
CLOAK_PROGRAM_ID,
|
|
3610
3147
|
CloakError,
|
|
3611
3148
|
CloakSDK,
|
|
@@ -3615,7 +3152,6 @@ export {
|
|
|
3615
3152
|
LAMPORTS_PER_SOL,
|
|
3616
3153
|
LocalStorageAdapter,
|
|
3617
3154
|
MemoryStorageAdapter,
|
|
3618
|
-
ProverService,
|
|
3619
3155
|
RelayService,
|
|
3620
3156
|
VARIABLE_FEE_RATE,
|
|
3621
3157
|
VERSION,
|