@cloak.ag/sdk 1.0.1 → 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 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,
@@ -83,6 +82,8 @@ __export(index_exports, {
83
82
  generateMasterSeed: () => generateMasterSeed,
84
83
  generateNote: () => generateNote,
85
84
  generateNoteFromWallet: () => generateNoteFromWallet,
85
+ generateWithdrawRegularProof: () => generateWithdrawRegularProof,
86
+ generateWithdrawSwapProof: () => generateWithdrawSwapProof,
86
87
  getAddressExplorerUrl: () => getAddressExplorerUrl,
87
88
  getDistributableAmount: () => getDistributableAmount2,
88
89
  getExplorerUrl: () => getExplorerUrl,
@@ -127,7 +128,7 @@ __export(index_exports, {
127
128
  module.exports = __toCommonJS(index_exports);
128
129
 
129
130
  // src/core/CloakSDK.ts
130
- var import_web36 = require("@solana/web3.js");
131
+ var import_web35 = require("@solana/web3.js");
131
132
 
132
133
  // src/core/types.ts
133
134
  var CloakError = class extends Error {
@@ -145,7 +146,6 @@ var import_blake3 = require("@noble/hashes/blake3.js");
145
146
  var import_tweetnacl = __toESM(require("tweetnacl"), 1);
146
147
 
147
148
  // src/utils/crypto.ts
148
- var import_web3 = require("@solana/web3.js");
149
149
  var import_circomlibjs = require("circomlibjs");
150
150
  var poseidon = null;
151
151
  async function getPoseidon() {
@@ -166,7 +166,7 @@ function splitTo2Limbs(value) {
166
166
  return [lo, hi];
167
167
  }
168
168
  function pubkeyToLimbs(pubkey) {
169
- const bytes = pubkey instanceof import_web3.PublicKey ? pubkey.toBytes() : pubkey;
169
+ const bytes = typeof pubkey.toBytes === "function" ? pubkey.toBytes() : pubkey;
170
170
  const value = BigInt("0x" + Buffer.from(bytes).toString("hex"));
171
171
  return splitTo2Limbs(value);
172
172
  }
@@ -794,10 +794,10 @@ var LocalStorageAdapter = class {
794
794
  };
795
795
 
796
796
  // src/utils/validation.ts
797
- var import_web32 = require("@solana/web3.js");
797
+ var import_web3 = require("@solana/web3.js");
798
798
  function isValidSolanaAddress(address) {
799
799
  try {
800
- new import_web32.PublicKey(address);
800
+ new import_web3.PublicKey(address);
801
801
  return true;
802
802
  } catch {
803
803
  return false;
@@ -896,8 +896,9 @@ function validateTransfers(recipients, totalAmount) {
896
896
  }
897
897
  for (let i = 0; i < recipients.length; i++) {
898
898
  const transfer = recipients[i];
899
- if (!transfer.recipient || !(transfer.recipient instanceof import_web32.PublicKey)) {
900
- throw new Error(`Recipient ${i} must be a PublicKey`);
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})`);
901
902
  }
902
903
  if (typeof transfer.amount !== "number" || transfer.amount <= 0) {
903
904
  throw new Error(`Recipient ${i} amount must be a positive number`);
@@ -1142,254 +1143,6 @@ var IndexerService = class {
1142
1143
  }
1143
1144
  };
1144
1145
 
1145
- // src/services/ArtifactProverService.ts
1146
- var ArtifactProverService = class {
1147
- /**
1148
- * Create a new Artifact Prover Service client
1149
- *
1150
- * @param indexerUrl - Indexer service base URL
1151
- * @param timeout - Proof generation timeout in ms (default: 5 minutes)
1152
- * @param pollInterval - Polling interval for status checks (default: 2 seconds)
1153
- */
1154
- constructor(indexerUrl, timeout = 5 * 60 * 1e3, pollInterval = 2e3) {
1155
- this.indexerUrl = indexerUrl.replace(/\/$/, "");
1156
- this.timeout = timeout;
1157
- this.pollInterval = pollInterval;
1158
- }
1159
- /**
1160
- * Generate a zero-knowledge proof using artifact-based flow
1161
- *
1162
- * This process typically takes 30-180 seconds depending on the TEE.
1163
- * Private inputs are uploaded directly to TEE, never passing through backend.
1164
- *
1165
- * @param inputs - Circuit inputs (private + public + outputs)
1166
- * @param options - Optional progress tracking and callbacks
1167
- * @returns Proof result with hex-encoded proof and public inputs
1168
- *
1169
- * @example
1170
- * ```typescript
1171
- * const result = await prover.generateProof(inputs);
1172
- * if (result.success) {
1173
- * console.log(`Proof: ${result.proof}`);
1174
- * }
1175
- * ```
1176
- */
1177
- async generateProof(inputs, options) {
1178
- const startTime = Date.now();
1179
- const actualTimeout = options?.timeout || this.timeout;
1180
- const pollInterval = options?.pollInterval || this.pollInterval;
1181
- options?.onStart?.();
1182
- options?.onProgress?.(5);
1183
- try {
1184
- options?.onProgress?.(10);
1185
- const artifactResponse = await fetch(`${this.indexerUrl}/api/v1/tee/artifact`, {
1186
- method: "POST",
1187
- headers: {
1188
- "Content-Type": "application/json"
1189
- },
1190
- body: JSON.stringify({
1191
- program_id: null
1192
- // Optional, can be null
1193
- })
1194
- });
1195
- if (!artifactResponse.ok) {
1196
- const errorText = await artifactResponse.text();
1197
- const errorMessage2 = `Failed to create artifact: ${errorText}`;
1198
- options?.onError?.(errorMessage2);
1199
- return {
1200
- success: false,
1201
- generationTimeMs: Date.now() - startTime,
1202
- error: errorMessage2
1203
- };
1204
- }
1205
- const artifactData = await artifactResponse.json();
1206
- const { artifact_id, upload_url } = artifactData;
1207
- if (!artifact_id || !upload_url) {
1208
- const errorMessage2 = "Invalid artifact response: missing artifact_id or upload_url";
1209
- options?.onError?.(errorMessage2);
1210
- return {
1211
- success: false,
1212
- generationTimeMs: Date.now() - startTime,
1213
- error: errorMessage2
1214
- };
1215
- }
1216
- const fullUploadUrl = upload_url.startsWith("http") ? upload_url : `${this.indexerUrl}${upload_url}`;
1217
- options?.onProgress?.(20);
1218
- const stdinPayload = JSON.stringify({
1219
- private: inputs.privateInputs,
1220
- public: inputs.publicInputs,
1221
- outputs: inputs.outputs,
1222
- // Include swap_params if present (for swap transactions)
1223
- ...inputs.swapParams && { swap_params: inputs.swapParams }
1224
- });
1225
- const uploadResponse = await fetch(fullUploadUrl, {
1226
- method: "POST",
1227
- headers: {
1228
- "Content-Type": "application/json"
1229
- },
1230
- body: stdinPayload
1231
- });
1232
- if (!uploadResponse.ok) {
1233
- const errorText = await uploadResponse.text();
1234
- const errorMessage2 = `Failed to upload stdin to TEE: ${errorText}`;
1235
- options?.onError?.(errorMessage2);
1236
- return {
1237
- success: false,
1238
- generationTimeMs: Date.now() - startTime,
1239
- error: errorMessage2
1240
- };
1241
- }
1242
- options?.onProgress?.(30);
1243
- const requestProofBody = {
1244
- artifact_id,
1245
- program_id: null,
1246
- public_inputs: JSON.stringify(inputs.publicInputs)
1247
- };
1248
- const requestProofResponse = await fetch(
1249
- `${this.indexerUrl}/api/v1/tee/request-proof`,
1250
- {
1251
- method: "POST",
1252
- headers: {
1253
- "Content-Type": "application/json"
1254
- },
1255
- body: JSON.stringify(requestProofBody)
1256
- }
1257
- );
1258
- if (!requestProofResponse.ok) {
1259
- const errorText = await requestProofResponse.text();
1260
- const errorMessage2 = `Failed to request proof: ${errorText}`;
1261
- options?.onError?.(errorMessage2);
1262
- return {
1263
- success: false,
1264
- generationTimeMs: Date.now() - startTime,
1265
- error: errorMessage2
1266
- };
1267
- }
1268
- const requestProofData = await requestProofResponse.json();
1269
- const { request_id } = requestProofData;
1270
- if (!request_id) {
1271
- const errorMessage2 = "Invalid proof request response: missing request_id";
1272
- options?.onError?.(errorMessage2);
1273
- return {
1274
- success: false,
1275
- generationTimeMs: Date.now() - startTime,
1276
- error: errorMessage2
1277
- };
1278
- }
1279
- options?.onProgress?.(40);
1280
- const pollStartTime = Date.now();
1281
- let lastProgress = 40;
1282
- while (Date.now() - pollStartTime < actualTimeout) {
1283
- const statusResponse = await fetch(
1284
- `${this.indexerUrl}/api/v1/tee/proof-status?request_id=${request_id}`,
1285
- {
1286
- method: "GET"
1287
- }
1288
- );
1289
- if (!statusResponse.ok) {
1290
- const errorText = await statusResponse.text();
1291
- const errorMessage2 = `Failed to check proof status: ${errorText}`;
1292
- options?.onError?.(errorMessage2);
1293
- return {
1294
- success: false,
1295
- generationTimeMs: Date.now() - startTime,
1296
- error: errorMessage2
1297
- };
1298
- }
1299
- const statusData = await statusResponse.json();
1300
- const { status, proof, public_inputs, generation_time_ms, error } = statusData;
1301
- if (status === "ready") {
1302
- options?.onProgress?.(100);
1303
- if (!proof || !public_inputs) {
1304
- const errorMessage2 = "Proof status is 'ready' but proof or public_inputs is missing";
1305
- options?.onError?.(errorMessage2);
1306
- return {
1307
- success: false,
1308
- generationTimeMs: Date.now() - startTime,
1309
- error: errorMessage2
1310
- };
1311
- }
1312
- const result = {
1313
- success: true,
1314
- proof,
1315
- publicInputs: public_inputs,
1316
- generationTimeMs: generation_time_ms || Date.now() - startTime
1317
- };
1318
- options?.onSuccess?.(result);
1319
- return result;
1320
- }
1321
- if (status === "failed") {
1322
- const errorMessage2 = error || "Proof generation failed";
1323
- options?.onError?.(errorMessage2);
1324
- return {
1325
- success: false,
1326
- generationTimeMs: Date.now() - startTime,
1327
- error: errorMessage2
1328
- };
1329
- }
1330
- const elapsed = Date.now() - pollStartTime;
1331
- const progress = Math.min(90, 40 + Math.floor(elapsed / actualTimeout * 50));
1332
- if (progress > lastProgress) {
1333
- lastProgress = progress;
1334
- options?.onProgress?.(progress);
1335
- }
1336
- await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
1337
- }
1338
- const errorMessage = `Proof generation timed out after ${actualTimeout}ms`;
1339
- options?.onError?.(errorMessage);
1340
- return {
1341
- success: false,
1342
- generationTimeMs: Date.now() - startTime,
1343
- error: errorMessage
1344
- };
1345
- } catch (error) {
1346
- const totalTime = Date.now() - startTime;
1347
- let errorMessage;
1348
- if (error instanceof Error && error.name === "AbortError") {
1349
- errorMessage = `Proof generation timed out after ${actualTimeout}ms`;
1350
- } else {
1351
- errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
1352
- }
1353
- options?.onError?.(errorMessage);
1354
- return {
1355
- success: false,
1356
- generationTimeMs: totalTime,
1357
- error: errorMessage
1358
- };
1359
- }
1360
- }
1361
- /**
1362
- * Check if the artifact prover service is available
1363
- *
1364
- * @returns True if service is healthy
1365
- */
1366
- async healthCheck() {
1367
- try {
1368
- const response = await fetch(`${this.indexerUrl}/health`, {
1369
- method: "GET"
1370
- });
1371
- return response.ok;
1372
- } catch {
1373
- return false;
1374
- }
1375
- }
1376
- /**
1377
- * Get the configured timeout
1378
- */
1379
- getTimeout() {
1380
- return this.timeout;
1381
- }
1382
- /**
1383
- * Set a new timeout
1384
- */
1385
- setTimeout(timeout) {
1386
- if (timeout <= 0) {
1387
- throw new Error("Timeout must be positive");
1388
- }
1389
- this.timeout = timeout;
1390
- }
1391
- };
1392
-
1393
1146
  // src/services/RelayService.ts
1394
1147
  var RelayService = class {
1395
1148
  /**
@@ -1627,12 +1380,12 @@ var RelayService = class {
1627
1380
  * Sleep utility
1628
1381
  */
1629
1382
  sleep(ms) {
1630
- return new Promise((resolve2) => setTimeout(resolve2, ms));
1383
+ return new Promise((resolve) => setTimeout(resolve, ms));
1631
1384
  }
1632
1385
  };
1633
1386
 
1634
1387
  // src/services/DepositRecoveryService.ts
1635
- var import_web33 = require("@solana/web3.js");
1388
+ var import_web32 = require("@solana/web3.js");
1636
1389
 
1637
1390
  // src/helpers/encrypted-output.ts
1638
1391
  function prepareEncryptedOutput(note, cloakKeys) {
@@ -1723,7 +1476,7 @@ var DepositRecoveryService = class {
1723
1476
  } catch (e) {
1724
1477
  }
1725
1478
  onProgress?.("Fetching transaction details...");
1726
- const connection = new import_web33.Connection(
1479
+ const connection = new import_web32.Connection(
1727
1480
  process.env.NEXT_PUBLIC_SOLANA_RPC_URL || "https://api.devnet.solana.com"
1728
1481
  );
1729
1482
  const txDetails = await connection.getTransaction(signature, {
@@ -1885,7 +1638,7 @@ var DepositRecoveryService = class {
1885
1638
  };
1886
1639
 
1887
1640
  // src/solana/instructions.ts
1888
- var import_web34 = require("@solana/web3.js");
1641
+ var import_web33 = require("@solana/web3.js");
1889
1642
  function createDepositInstruction(params) {
1890
1643
  if (params.commitment.length !== 32) {
1891
1644
  throw new Error(
@@ -1907,7 +1660,7 @@ function createDepositInstruction(params) {
1907
1660
  data.set(discriminant, 0);
1908
1661
  data.set(amountBytes, 1);
1909
1662
  data.set(params.commitment, 9);
1910
- return new import_web34.TransactionInstruction({
1663
+ return new import_web33.TransactionInstruction({
1911
1664
  programId: params.programId,
1912
1665
  keys: [
1913
1666
  // Account 0: Payer (signer, writable) - pays for transaction
@@ -1915,7 +1668,7 @@ function createDepositInstruction(params) {
1915
1668
  // Account 1: Pool (writable) - receives SOL
1916
1669
  { pubkey: params.pool, isSigner: false, isWritable: true },
1917
1670
  // Account 2: System Program (readonly) - for transfers
1918
- { pubkey: import_web34.SystemProgram.programId, isSigner: false, isWritable: false },
1671
+ { pubkey: import_web33.SystemProgram.programId, isSigner: false, isWritable: false },
1919
1672
  // Account 3: Merkle Tree (writable) - stores on-chain Merkle tree
1920
1673
  { pubkey: params.merkleTree, isSigner: false, isWritable: true }
1921
1674
  ],
@@ -1923,16 +1676,16 @@ function createDepositInstruction(params) {
1923
1676
  });
1924
1677
  }
1925
1678
  function validateDepositParams(params) {
1926
- if (!(params.programId instanceof import_web34.PublicKey)) {
1679
+ if (!(params.programId instanceof import_web33.PublicKey)) {
1927
1680
  throw new Error("programId must be a PublicKey");
1928
1681
  }
1929
- if (!(params.payer instanceof import_web34.PublicKey)) {
1682
+ if (!(params.payer instanceof import_web33.PublicKey)) {
1930
1683
  throw new Error("payer must be a PublicKey");
1931
1684
  }
1932
- if (!(params.pool instanceof import_web34.PublicKey)) {
1685
+ if (!(params.pool instanceof import_web33.PublicKey)) {
1933
1686
  throw new Error("pool must be a PublicKey");
1934
1687
  }
1935
- if (!(params.merkleTree instanceof import_web34.PublicKey)) {
1688
+ if (!(params.merkleTree instanceof import_web33.PublicKey)) {
1936
1689
  throw new Error("merkleTree must be a PublicKey");
1937
1690
  }
1938
1691
  if (typeof params.amount !== "number" || params.amount <= 0) {
@@ -1949,34 +1702,34 @@ function validateDepositParams(params) {
1949
1702
  }
1950
1703
 
1951
1704
  // src/utils/pda.ts
1952
- var import_web35 = require("@solana/web3.js");
1705
+ var import_web34 = require("@solana/web3.js");
1953
1706
  function getShieldPoolPDAs(programId, mint) {
1954
1707
  const pid = programId || CLOAK_PROGRAM_ID;
1955
- const mintKey = mint ?? new import_web35.PublicKey(
1708
+ const mintKey = mint ?? new import_web34.PublicKey(
1956
1709
  // 32 zero bytes, matching Rust `Pubkey::default()`
1957
1710
  new Uint8Array(32)
1958
1711
  );
1959
- const [pool] = import_web35.PublicKey.findProgramAddressSync(
1712
+ const [pool] = import_web34.PublicKey.findProgramAddressSync(
1960
1713
  [Buffer.from("pool"), mintKey.toBytes()],
1961
1714
  pid
1962
1715
  );
1963
- const [merkleTree] = import_web35.PublicKey.findProgramAddressSync(
1716
+ const [merkleTree] = import_web34.PublicKey.findProgramAddressSync(
1964
1717
  [Buffer.from("merkle_tree"), mintKey.toBytes()],
1965
1718
  pid
1966
1719
  );
1967
- const [commitments] = import_web35.PublicKey.findProgramAddressSync(
1720
+ const [commitments] = import_web34.PublicKey.findProgramAddressSync(
1968
1721
  [Buffer.from("commitments"), mintKey.toBytes()],
1969
1722
  pid
1970
1723
  );
1971
- const [rootsRing] = import_web35.PublicKey.findProgramAddressSync(
1724
+ const [rootsRing] = import_web34.PublicKey.findProgramAddressSync(
1972
1725
  [Buffer.from("roots_ring"), mintKey.toBytes()],
1973
1726
  pid
1974
1727
  );
1975
- const [nullifierShard] = import_web35.PublicKey.findProgramAddressSync(
1728
+ const [nullifierShard] = import_web34.PublicKey.findProgramAddressSync(
1976
1729
  [Buffer.from("nullifier_shard"), mintKey.toBytes()],
1977
1730
  pid
1978
1731
  );
1979
- const [treasury] = import_web35.PublicKey.findProgramAddressSync(
1732
+ const [treasury] = import_web34.PublicKey.findProgramAddressSync(
1980
1733
  [Buffer.from("treasury"), mintKey.toBytes()],
1981
1734
  pid
1982
1735
  );
@@ -1992,16 +1745,66 @@ function getShieldPoolPDAs(programId, mint) {
1992
1745
 
1993
1746
  // src/utils/proof-generation.ts
1994
1747
  var snarkjs = __toESM(require("snarkjs"), 1);
1995
- var path = __toESM(require("path"), 1);
1996
- var fs = __toESM(require("fs"), 1);
1997
- async function generateWithdrawRegularProof(inputs, circuitsPath) {
1998
- const wasmPath = path.join(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
1999
- const zkeyPath = path.join(circuitsPath, "build", "withdraw_regular_final.zkey");
2000
- if (!fs.existsSync(wasmPath)) {
2001
- throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages-new/circuits first.`);
1748
+ var path = null;
1749
+ var fs = null;
1750
+ async function loadNodeModules() {
1751
+ const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
1752
+ if (!isBrowser && typeof process !== "undefined" && process.versions?.node) {
1753
+ if (!path) {
1754
+ path = await import("path");
1755
+ }
1756
+ if (!fs) {
1757
+ fs = await import("fs");
1758
+ }
1759
+ return { path, fs };
1760
+ }
1761
+ return { path: null, fs: null };
1762
+ }
1763
+ function joinPath(...parts) {
1764
+ const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
1765
+ if (!isBrowser && path) {
1766
+ return path.join(...parts);
1767
+ }
1768
+ return parts.join("/").replace(/\/+/g, "/");
1769
+ }
1770
+ async function fileExists(filePath) {
1771
+ const { fs: fs2 } = await loadNodeModules();
1772
+ if (fs2) {
1773
+ try {
1774
+ return fs2.existsSync(filePath);
1775
+ } catch {
1776
+ return false;
1777
+ }
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
+ }
2002
1787
  }
2003
- if (!fs.existsSync(zkeyPath)) {
2004
- throw new Error(`Circuit zkey not found at ${zkeyPath}. Run circuit setup first.`);
1788
+ return false;
1789
+ }
1790
+ async function generateWithdrawRegularProof(inputs, circuitsPath) {
1791
+ const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
1792
+ let wasmPath;
1793
+ let zkeyPath;
1794
+ if (isBrowser) {
1795
+ wasmPath = `${circuitsPath}/withdraw_regular_js/withdraw_regular.wasm`;
1796
+ zkeyPath = `${circuitsPath}/withdraw_regular_final.zkey`;
1797
+ } else {
1798
+ wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
1799
+ zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
1800
+ const wasmExists = await fileExists(wasmPath);
1801
+ const zkeyExists = await fileExists(zkeyPath);
1802
+ if (!wasmExists) {
1803
+ throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages-new/circuits first.`);
1804
+ }
1805
+ if (!zkeyExists) {
1806
+ throw new Error(`Circuit zkey not found at ${zkeyPath}. Run circuit setup first.`);
1807
+ }
2005
1808
  }
2006
1809
  const circuitInputs = {
2007
1810
  // Public signals
@@ -2040,13 +1843,23 @@ async function generateWithdrawRegularProof(inputs, circuitsPath) {
2040
1843
  };
2041
1844
  }
2042
1845
  async function generateWithdrawSwapProof(inputs, circuitsPath) {
2043
- const wasmPath = path.join(circuitsPath, "build", "withdraw_swap_js", "withdraw_swap.wasm");
2044
- const zkeyPath = path.join(circuitsPath, "build", "withdraw_swap_final.zkey");
2045
- if (!fs.existsSync(wasmPath)) {
2046
- throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages-new/circuits first.`);
2047
- }
2048
- if (!fs.existsSync(zkeyPath)) {
2049
- throw new Error(`Circuit zkey not found at ${zkeyPath}. Run circuit setup first.`);
1846
+ const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
1847
+ let wasmPath;
1848
+ let zkeyPath;
1849
+ if (isBrowser) {
1850
+ wasmPath = `${circuitsPath}/withdraw_swap_js/withdraw_swap.wasm`;
1851
+ zkeyPath = `${circuitsPath}/withdraw_swap_final.zkey`;
1852
+ } else {
1853
+ wasmPath = joinPath(circuitsPath, "build", "withdraw_swap_js", "withdraw_swap.wasm");
1854
+ zkeyPath = joinPath(circuitsPath, "build", "withdraw_swap_final.zkey");
1855
+ const wasmExists = await fileExists(wasmPath);
1856
+ const zkeyExists = await fileExists(zkeyPath);
1857
+ if (!wasmExists) {
1858
+ throw new Error(`Circuit WASM not found at ${wasmPath}. Run 'just circuits-compile' in packages-new/circuits first.`);
1859
+ }
1860
+ if (!zkeyExists) {
1861
+ throw new Error(`Circuit zkey not found at ${zkeyPath}. Run circuit setup first.`);
1862
+ }
2050
1863
  }
2051
1864
  const sk = splitTo2Limbs(inputs.sk_spend);
2052
1865
  const r = splitTo2Limbs(inputs.r);
@@ -2087,21 +1900,35 @@ async function generateWithdrawSwapProof(inputs, circuitsPath) {
2087
1900
  // Not used, kept for compatibility
2088
1901
  };
2089
1902
  }
2090
- function areCircuitsAvailable(circuitsPath) {
2091
- const wasmPath = path.join(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
2092
- const zkeyPath = path.join(circuitsPath, "build", "withdraw_regular_final.zkey");
2093
- return fs.existsSync(wasmPath) && fs.existsSync(zkeyPath);
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
+ }
1908
+ const wasmPath = joinPath(circuitsPath, "build", "withdraw_regular_js", "withdraw_regular.wasm");
1909
+ const zkeyPath = joinPath(circuitsPath, "build", "withdraw_regular_final.zkey");
1910
+ const wasmExists = await fileExists(wasmPath);
1911
+ const zkeyExists = await fileExists(zkeyPath);
1912
+ return wasmExists && zkeyExists;
2094
1913
  }
2095
- function getDefaultCircuitsPath() {
1914
+ async function getDefaultCircuitsPath() {
1915
+ const isBrowser = typeof window !== "undefined" || typeof globalThis !== "undefined" && globalThis.window;
1916
+ if (isBrowser) {
1917
+ return "/circuits";
1918
+ }
1919
+ const { path: path2 } = await loadNodeModules();
1920
+ if (!path2 || typeof process === "undefined" || !process.cwd) {
1921
+ return "/circuits";
1922
+ }
2096
1923
  const possiblePaths = [
2097
- path.resolve(process.cwd(), "../../packages-new/circuits"),
2098
- path.resolve(process.cwd(), "../packages-new/circuits"),
2099
- path.resolve(process.cwd(), "packages-new/circuits"),
2100
- path.resolve(process.cwd(), "../../circuits"),
2101
- path.resolve(process.cwd(), "../circuits")
1924
+ path2.resolve(process.cwd(), "../../packages-new/circuits"),
1925
+ path2.resolve(process.cwd(), "../packages-new/circuits"),
1926
+ path2.resolve(process.cwd(), "packages-new/circuits"),
1927
+ path2.resolve(process.cwd(), "../../circuits"),
1928
+ path2.resolve(process.cwd(), "../circuits")
2102
1929
  ];
2103
1930
  for (const p of possiblePaths) {
2104
- if (areCircuitsAvailable(p)) {
1931
+ if (await areCircuitsAvailable(p)) {
2105
1932
  return p;
2106
1933
  }
2107
1934
  }
@@ -2109,7 +1936,7 @@ function getDefaultCircuitsPath() {
2109
1936
  }
2110
1937
 
2111
1938
  // src/core/CloakSDK.ts
2112
- var CLOAK_PROGRAM_ID = new import_web36.PublicKey("c1oak6tetxYnNfvXKFkpn1d98FxtK7B68vBQLYQpWKp");
1939
+ var CLOAK_PROGRAM_ID = new import_web35.PublicKey("c1oak6tetxYnNfvXKFkpn1d98FxtK7B68vBQLYQpWKp");
2113
1940
  var CLOAK_API_URL = "https://api.cloak.ag";
2114
1941
  var CloakSDK = class {
2115
1942
  /**
@@ -2117,21 +1944,35 @@ var CloakSDK = class {
2117
1944
  *
2118
1945
  * @param config - Client configuration
2119
1946
  *
2120
- * @example
1947
+ * @example Node.js mode (with keypair)
2121
1948
  * ```typescript
2122
1949
  * const sdk = new CloakSDK({
2123
1950
  * keypairBytes: keypair.secretKey,
2124
1951
  * network: "devnet"
2125
- * });
1952
+ * });
1953
+ * ```
1954
+ *
1955
+ * @example Browser mode (with wallet adapter)
1956
+ * ```typescript
1957
+ * const sdk = new CloakSDK({
1958
+ * wallet: walletAdapter,
1959
+ * network: "devnet"
1960
+ * });
1961
+ * ```
2126
1962
  */
2127
1963
  constructor(config) {
2128
- this.keypair = import_web36.Keypair.fromSecretKey(config.keypairBytes);
1964
+ if (!config.keypairBytes && !config.wallet) {
1965
+ throw new Error("Must provide either keypairBytes (Node.js) or wallet (Browser)");
1966
+ }
1967
+ if (config.keypairBytes) {
1968
+ this.keypair = import_web35.Keypair.fromSecretKey(config.keypairBytes);
1969
+ }
1970
+ this.wallet = config.wallet;
2129
1971
  this.cloakKeys = config.cloakKeys;
2130
1972
  this.storage = config.storage || new MemoryStorageAdapter();
2131
- const indexerUrl = config.indexerUrl || process.env.CLOAK_INDEXER_URL || CLOAK_API_URL;
2132
- const relayUrl = config.relayUrl || process.env.CLOAK_RELAY_URL || CLOAK_API_URL;
1973
+ const indexerUrl = config.indexerUrl || typeof process !== "undefined" && process.env?.CLOAK_INDEXER_URL || CLOAK_API_URL;
1974
+ const relayUrl = config.relayUrl || typeof process !== "undefined" && process.env?.CLOAK_RELAY_URL || CLOAK_API_URL;
2133
1975
  this.indexer = new IndexerService(indexerUrl);
2134
- this.artifactProver = new ArtifactProverService(indexerUrl, 5 * 60 * 1e3, 2e3);
2135
1976
  this.relay = new RelayService(relayUrl);
2136
1977
  this.depositRecovery = new DepositRecoveryService(this.indexer, indexerUrl);
2137
1978
  if (!this.cloakKeys) {
@@ -2157,6 +1998,24 @@ var CloakSDK = class {
2157
1998
  treasuryAddress: treasury
2158
1999
  };
2159
2000
  }
2001
+ /**
2002
+ * Get the public key for deposits (from keypair or wallet)
2003
+ */
2004
+ getPublicKey() {
2005
+ if (this.keypair) {
2006
+ return this.keypair.publicKey;
2007
+ }
2008
+ if (this.wallet?.publicKey) {
2009
+ return this.wallet.publicKey;
2010
+ }
2011
+ throw new Error("No public key available - wallet not connected or keypair not provided");
2012
+ }
2013
+ /**
2014
+ * Check if the SDK is using a wallet adapter
2015
+ */
2016
+ isWalletMode() {
2017
+ return !!this.wallet && !this.keypair;
2018
+ }
2160
2019
  /**
2161
2020
  * Deposit SOL into the Cloak protocol
2162
2021
  *
@@ -2197,7 +2056,8 @@ var CloakSDK = class {
2197
2056
  throw new Error("Note has already been deposited");
2198
2057
  }
2199
2058
  }
2200
- const balance = await connection.getBalance(this.keypair.publicKey);
2059
+ const payerPubkey = this.getPublicKey();
2060
+ const balance = await connection.getBalance(payerPubkey);
2201
2061
  const requiredAmount = note.amount + 5e3;
2202
2062
  if (balance < requiredAmount) {
2203
2063
  throw new Error(
@@ -2208,34 +2068,66 @@ var CloakSDK = class {
2208
2068
  const programId = this.config.programId || CLOAK_PROGRAM_ID;
2209
2069
  const depositIx = createDepositInstruction({
2210
2070
  programId,
2211
- payer: this.keypair.publicKey,
2071
+ payer: payerPubkey,
2212
2072
  pool: this.config.poolAddress,
2213
2073
  merkleTree: this.config.merkleTreeAddress,
2214
2074
  amount: note.amount,
2215
2075
  commitment: commitmentBytes
2216
2076
  });
2217
2077
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
2218
- const transaction = new import_web36.Transaction({
2219
- feePayer: this.keypair.publicKey,
2220
- blockhash,
2221
- lastValidBlockHeight
2078
+ const transaction = new import_web35.Transaction({
2079
+ feePayer: payerPubkey,
2080
+ recentBlockhash: blockhash
2222
2081
  }).add(depositIx);
2223
- if (!options?.skipPreflight) {
2224
- const simulation = await connection.simulateTransaction(transaction);
2225
- if (simulation.value.err) {
2226
- const logs = simulation.value.logs?.join("\n") || "No logs";
2227
- throw new Error(
2228
- `Transaction simulation failed: ${JSON.stringify(simulation.value.err)}
2229
- Logs:
2230
- ${logs}`
2231
- );
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");
2087
+ }
2088
+ let signature;
2089
+ if (this.wallet) {
2090
+ if (!this.wallet.publicKey) {
2091
+ throw new Error("Wallet not connected - publicKey is null");
2232
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
+ }
2122
+ } else if (this.keypair) {
2123
+ signature = await connection.sendTransaction(transaction, [this.keypair], {
2124
+ skipPreflight: options?.skipPreflight || false,
2125
+ preflightCommitment: "confirmed",
2126
+ maxRetries: 3
2127
+ });
2128
+ } else {
2129
+ throw new Error("No signing method available - provide keypair or wallet");
2233
2130
  }
2234
- const signature = await connection.sendTransaction(transaction, [this.keypair], {
2235
- skipPreflight: options?.skipPreflight || false,
2236
- preflightCommitment: "confirmed",
2237
- maxRetries: 3
2238
- });
2239
2131
  const confirmation = await connection.confirmTransaction({
2240
2132
  signature,
2241
2133
  blockhash,
@@ -2297,13 +2189,13 @@ ${logs}`
2297
2189
  break;
2298
2190
  } else if (response.status === 404 && attempt < maxRetries2 - 1) {
2299
2191
  const delay = Math.min(initialRetryDelay2 * (attempt + 1), 2e3);
2300
- await new Promise((resolve2) => setTimeout(resolve2, delay));
2192
+ await new Promise((resolve) => setTimeout(resolve, delay));
2301
2193
  continue;
2302
2194
  }
2303
2195
  } catch (e) {
2304
2196
  if (attempt < maxRetries2 - 1) {
2305
2197
  const delay = Math.min(initialRetryDelay2 * (attempt + 1), 2e3);
2306
- await new Promise((resolve2) => setTimeout(resolve2, delay));
2198
+ await new Promise((resolve) => setTimeout(resolve, delay));
2307
2199
  continue;
2308
2200
  }
2309
2201
  }
@@ -2311,7 +2203,7 @@ ${logs}`
2311
2203
  }
2312
2204
  if (leafIndex === null) {
2313
2205
  const programId2 = this.config.programId || CLOAK_PROGRAM_ID;
2314
- const mintForSOL = new import_web36.PublicKey(new Uint8Array(32));
2206
+ const mintForSOL = new import_web35.PublicKey(new Uint8Array(32));
2315
2207
  const { merkleTree } = getShieldPoolPDAs(programId2, mintForSOL);
2316
2208
  const merkleTreeAccount = await connection.getAccountInfo(merkleTree);
2317
2209
  if (!merkleTreeAccount) {
@@ -2336,7 +2228,7 @@ ${logs}`
2336
2228
  const errorMessage = error instanceof Error ? error.message : String(error);
2337
2229
  if (errorMessage.includes("404") && attempt < maxRetries - 1) {
2338
2230
  const delay = Math.min(initialRetryDelay * (attempt + 1), 2e3);
2339
- await new Promise((resolve2) => setTimeout(resolve2, delay));
2231
+ await new Promise((resolve) => setTimeout(resolve, delay));
2340
2232
  continue;
2341
2233
  }
2342
2234
  throw error;
@@ -2462,8 +2354,9 @@ ${logs}`
2462
2354
  throw new Error(`Merkle proof path element at position ${i} must be 64 hex characters (32 bytes)`);
2463
2355
  }
2464
2356
  }
2465
- const circuitsPath = process.env.CIRCUITS_PATH || getDefaultCircuitsPath();
2466
- const useDirectProof = areCircuitsAvailable(circuitsPath);
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();
2359
+ const useDirectProof = await areCircuitsAvailable(circuitsPath);
2467
2360
  let proofHex;
2468
2361
  let finalPublicInputs;
2469
2362
  if (useDirectProof) {
@@ -2526,43 +2419,9 @@ ${logs}`
2526
2419
  amount: note.amount
2527
2420
  };
2528
2421
  } else {
2529
- const proofInputs = {
2530
- privateInputs: {
2531
- amount: note.amount,
2532
- r: note.r,
2533
- sk_spend: note.sk_spend,
2534
- leaf_index: note.leafIndex,
2535
- merkle_path: {
2536
- path_elements: merkleProof.pathElements,
2537
- path_indices: merkleProof.pathIndices
2538
- }
2539
- },
2540
- publicInputs: {
2541
- root: merkleRoot,
2542
- nf: nullifierHex,
2543
- outputs_hash: outputsHashHex,
2544
- amount: note.amount
2545
- },
2546
- outputs: recipients.map((r) => ({
2547
- address: r.recipient.toBase58(),
2548
- amount: r.amount
2549
- }))
2550
- };
2551
- const proofResult = await this.artifactProver.generateProof(proofInputs, {
2552
- onProgress: options?.onProofProgress,
2553
- onError: options?.onProgress ? (error) => options.onProgress?.(`Proof generation error: ${error}`) : void 0
2554
- });
2555
- if (!proofResult.success || !proofResult.proof) {
2556
- let errorMessage = proofResult.error || "Proof generation failed";
2557
- if (errorMessage.startsWith("Proof generation failed: ")) {
2558
- errorMessage = errorMessage.substring("Proof generation failed: ".length);
2559
- }
2560
- errorMessage += `
2561
- Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., nullifier=${nullifierHex.slice(0, 16)}...`;
2562
- throw new Error(errorMessage);
2563
- }
2564
- proofHex = proofResult.proof;
2565
- 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
+ );
2566
2425
  }
2567
2426
  const signature = await this.relay.submitWithdraw(
2568
2427
  {
@@ -2723,7 +2582,7 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
2723
2582
  if (!getAssociatedTokenAddress) {
2724
2583
  throw new Error("getAssociatedTokenAddress not found");
2725
2584
  }
2726
- const outputMint2 = new import_web36.PublicKey(options.outputMint);
2585
+ const outputMint2 = new import_web35.PublicKey(options.outputMint);
2727
2586
  recipientAta = await getAssociatedTokenAddress(outputMint2, recipient);
2728
2587
  } catch (error) {
2729
2588
  throw new Error(
@@ -2744,8 +2603,8 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
2744
2603
  }
2745
2604
  const nullifier = await computeNullifierAsync(note.sk_spend, note.leafIndex);
2746
2605
  const nullifierHex = nullifier.toString(16).padStart(64, "0");
2747
- const inputMint = new import_web36.PublicKey("11111111111111111111111111111111");
2748
- const outputMint = new import_web36.PublicKey(options.outputMint);
2606
+ const inputMint = new import_web35.PublicKey("11111111111111111111111111111111");
2607
+ const outputMint = new import_web35.PublicKey(options.outputMint);
2749
2608
  const outputsHash = await computeSwapOutputsHashAsync(
2750
2609
  inputMint,
2751
2610
  outputMint,
@@ -2760,8 +2619,9 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
2760
2619
  if (!merkleProof.pathElements || merkleProof.pathElements.length === 0) {
2761
2620
  throw new Error("Merkle proof is invalid: missing path elements");
2762
2621
  }
2763
- const circuitsPath = process.env.CIRCUITS_PATH || getDefaultCircuitsPath();
2764
- const useDirectProof = areCircuitsAvailable(circuitsPath);
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();
2624
+ const useDirectProof = await areCircuitsAvailable(circuitsPath);
2765
2625
  let proofHex;
2766
2626
  let finalPublicInputs;
2767
2627
  if (useDirectProof) {
@@ -2805,46 +2665,9 @@ Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., n
2805
2665
  amount: note.amount
2806
2666
  };
2807
2667
  } else {
2808
- const proofInputs = {
2809
- privateInputs: {
2810
- amount: note.amount,
2811
- r: note.r,
2812
- sk_spend: note.sk_spend,
2813
- leaf_index: note.leafIndex,
2814
- merkle_path: {
2815
- path_elements: merkleProof.pathElements,
2816
- path_indices: merkleProof.pathIndices
2817
- }
2818
- },
2819
- publicInputs: {
2820
- root: merkleRoot,
2821
- nf: nullifierHex,
2822
- outputs_hash: outputsHashHex,
2823
- amount: note.amount
2824
- },
2825
- outputs: [],
2826
- // Empty for swaps
2827
- swapParams: {
2828
- output_mint: options.outputMint,
2829
- recipient_ata: recipientAta.toBase58(),
2830
- min_output_amount: minOutputAmount
2831
- }
2832
- };
2833
- const proofResult = await this.artifactProver.generateProof(proofInputs, {
2834
- onProgress: options.onProofProgress,
2835
- onError: options.onProgress ? (error) => options.onProgress?.(`Proof generation error: ${error}`) : void 0
2836
- });
2837
- if (!proofResult.success || !proofResult.proof) {
2838
- let errorMessage = proofResult.error || "Proof generation failed";
2839
- if (errorMessage.startsWith("Proof generation failed: ")) {
2840
- errorMessage = errorMessage.substring("Proof generation failed: ".length);
2841
- }
2842
- errorMessage += `
2843
- Note details: leafIndex=${note.leafIndex}, root=${merkleRoot.slice(0, 16)}..., nullifier=${nullifierHex.slice(0, 16)}...`;
2844
- throw new Error(errorMessage);
2845
- }
2846
- proofHex = proofResult.proof;
2847
- 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
+ );
2848
2671
  }
2849
2672
  const signature = await this.relay.submitSwap(
2850
2673
  {
@@ -3536,9 +3359,9 @@ Total syscalls: ${errorObj.total_syscalls}`;
3536
3359
  };
3537
3360
 
3538
3361
  // src/helpers/wallet-integration.ts
3539
- var import_web37 = require("@solana/web3.js");
3362
+ var import_web36 = require("@solana/web3.js");
3540
3363
  function validateWalletConnected(wallet) {
3541
- if (wallet instanceof import_web37.Keypair) {
3364
+ if (wallet instanceof import_web36.Keypair) {
3542
3365
  return;
3543
3366
  }
3544
3367
  if (!wallet.publicKey) {
@@ -3550,7 +3373,7 @@ function validateWalletConnected(wallet) {
3550
3373
  }
3551
3374
  }
3552
3375
  function getPublicKey(wallet) {
3553
- if (wallet instanceof import_web37.Keypair) {
3376
+ if (wallet instanceof import_web36.Keypair) {
3554
3377
  return wallet.publicKey;
3555
3378
  }
3556
3379
  if (!wallet.publicKey) {
@@ -3563,7 +3386,7 @@ function getPublicKey(wallet) {
3563
3386
  return wallet.publicKey;
3564
3387
  }
3565
3388
  async function sendTransaction(transaction, wallet, connection, options) {
3566
- if (wallet instanceof import_web37.Keypair) {
3389
+ if (wallet instanceof import_web36.Keypair) {
3567
3390
  return await connection.sendTransaction(transaction, [wallet], options);
3568
3391
  }
3569
3392
  if (wallet.sendTransaction) {
@@ -3580,7 +3403,7 @@ async function sendTransaction(transaction, wallet, connection, options) {
3580
3403
  }
3581
3404
  }
3582
3405
  async function signTransaction(transaction, wallet) {
3583
- if (wallet instanceof import_web37.Keypair) {
3406
+ if (wallet instanceof import_web36.Keypair) {
3584
3407
  transaction.sign(wallet);
3585
3408
  return transaction;
3586
3409
  }
@@ -3611,7 +3434,6 @@ function keypairToAdapter(keypair) {
3611
3434
  var VERSION = "1.0.0";
3612
3435
  // Annotate the CommonJS export names for ESM import in node:
3613
3436
  0 && (module.exports = {
3614
- ArtifactProverService,
3615
3437
  CLOAK_PROGRAM_ID,
3616
3438
  CloakError,
3617
3439
  CloakSDK,
@@ -3664,6 +3486,8 @@ var VERSION = "1.0.0";
3664
3486
  generateMasterSeed,
3665
3487
  generateNote,
3666
3488
  generateNoteFromWallet,
3489
+ generateWithdrawRegularProof,
3490
+ generateWithdrawSwapProof,
3667
3491
  getAddressExplorerUrl,
3668
3492
  getDistributableAmount,
3669
3493
  getExplorerUrl,