@cloak.ag/sdk 1.0.8 → 1.0.9

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.
Files changed (3) hide show
  1. package/dist/index.cjs +245 -289
  2. package/dist/index.js +365 -40
  3. package/package.json +3 -4
package/dist/index.cjs CHANGED
@@ -5,9 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __esm = (fn, res) => function __init() {
9
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
- };
11
8
  var __export = (target, all) => {
12
9
  for (var name in all)
13
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -30,7 +27,159 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
27
  ));
31
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
29
 
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ CLOAK_PROGRAM_ID: () => CLOAK_PROGRAM_ID,
34
+ CloakError: () => CloakError,
35
+ CloakSDK: () => CloakSDK,
36
+ DEFAULT_CIRCUITS_URL: () => DEFAULT_CIRCUITS_URL,
37
+ EXPECTED_CIRCUIT_HASHES: () => EXPECTED_CIRCUIT_HASHES,
38
+ FIXED_FEE_LAMPORTS: () => FIXED_FEE_LAMPORTS,
39
+ LAMPORTS_PER_SOL: () => LAMPORTS_PER_SOL,
40
+ LocalStorageAdapter: () => LocalStorageAdapter,
41
+ MemoryStorageAdapter: () => MemoryStorageAdapter,
42
+ RelayService: () => RelayService,
43
+ RootNotFoundError: () => RootNotFoundError,
44
+ ShieldPoolErrors: () => ShieldPoolErrors,
45
+ VARIABLE_FEE_RATE: () => VARIABLE_FEE_RATE,
46
+ VERSION: () => VERSION,
47
+ areCircuitsAvailable: () => areCircuitsAvailable,
48
+ bigintToBytes32: () => bigintToBytes32,
49
+ buildPublicInputsBytes: () => buildPublicInputsBytes,
50
+ bytesToHex: () => bytesToHex,
51
+ calculateFee: () => calculateFee2,
52
+ calculateRelayFee: () => calculateRelayFee,
53
+ cleanupStalePendingOperations: () => cleanupStalePendingOperations,
54
+ clearPendingDeposits: () => clearPendingDeposits,
55
+ clearPendingWithdrawals: () => clearPendingWithdrawals,
56
+ computeCommitment: () => computeCommitment,
57
+ computeMerkleRoot: () => computeMerkleRoot,
58
+ computeNullifier: () => computeNullifier,
59
+ computeNullifierAsync: () => computeNullifierAsync,
60
+ computeNullifierSync: () => computeNullifierSync,
61
+ computeOutputsHash: () => computeOutputsHash,
62
+ computeOutputsHashAsync: () => computeOutputsHashAsync,
63
+ computeOutputsHashSync: () => computeOutputsHashSync,
64
+ computeProofForLatestDeposit: () => computeProofForLatestDeposit,
65
+ computeProofFromChain: () => computeProofFromChain,
66
+ computeSwapOutputsHash: () => computeSwapOutputsHash,
67
+ computeSwapOutputsHashAsync: () => computeSwapOutputsHashAsync,
68
+ computeSwapOutputsHashSync: () => computeSwapOutputsHashSync,
69
+ copyNoteToClipboard: () => copyNoteToClipboard,
70
+ createCloakError: () => createCloakError,
71
+ createDepositInstruction: () => createDepositInstruction,
72
+ createLogger: () => createLogger,
73
+ deriveSpendKey: () => deriveSpendKey,
74
+ deriveViewKey: () => deriveViewKey,
75
+ detectNetworkFromRpcUrl: () => detectNetworkFromRpcUrl,
76
+ downloadNote: () => downloadNote,
77
+ encodeNoteSimple: () => encodeNoteSimple,
78
+ encryptNoteForRecipient: () => encryptNoteForRecipient,
79
+ exportKeys: () => exportKeys,
80
+ exportNote: () => exportNote,
81
+ exportWalletKeys: () => exportWalletKeys,
82
+ filterNotesByNetwork: () => filterNotesByNetwork,
83
+ filterWithdrawableNotes: () => filterWithdrawableNotes,
84
+ findNoteByCommitment: () => findNoteByCommitment,
85
+ formatAmount: () => formatAmount,
86
+ formatErrorForLogging: () => formatErrorForLogging,
87
+ formatSol: () => formatSol,
88
+ generateCloakKeys: () => generateCloakKeys,
89
+ generateCommitment: () => generateCommitment,
90
+ generateCommitmentAsync: () => generateCommitmentAsync,
91
+ generateMasterSeed: () => generateMasterSeed,
92
+ generateNote: () => generateNote,
93
+ generateNoteFromWallet: () => generateNoteFromWallet,
94
+ generateWithdrawRegularProof: () => generateWithdrawRegularProof,
95
+ generateWithdrawSwapProof: () => generateWithdrawSwapProof,
96
+ getAddressExplorerUrl: () => getAddressExplorerUrl,
97
+ getDefaultCircuitsPath: () => getDefaultCircuitsPath,
98
+ getDistributableAmount: () => getDistributableAmount2,
99
+ getExplorerUrl: () => getExplorerUrl,
100
+ getNullifierPDA: () => getNullifierPDA,
101
+ getPendingOperationsSummary: () => getPendingOperationsSummary,
102
+ getPublicKey: () => getPublicKey,
103
+ getPublicViewKey: () => getPublicViewKey,
104
+ getRecipientAmount: () => getRecipientAmount,
105
+ getRpcUrlForNetwork: () => getRpcUrlForNetwork,
106
+ getShieldPoolPDAs: () => getShieldPoolPDAs,
107
+ getSwapStatePDA: () => getSwapStatePDA,
108
+ getViewKey: () => getViewKey,
109
+ hasPendingOperations: () => hasPendingOperations,
110
+ hexToBigint: () => hexToBigint,
111
+ hexToBytes: () => hexToBytes,
112
+ importKeys: () => importKeys,
113
+ importWalletKeys: () => importWalletKeys,
114
+ isDebugEnabled: () => isDebugEnabled,
115
+ isRootNotFoundError: () => isRootNotFoundError,
116
+ isValidHex: () => isValidHex,
117
+ isValidRpcUrl: () => isValidRpcUrl,
118
+ isValidSolanaAddress: () => isValidSolanaAddress,
119
+ isWithdrawable: () => isWithdrawable,
120
+ keypairToAdapter: () => keypairToAdapter,
121
+ loadPendingDeposits: () => loadPendingDeposits,
122
+ loadPendingWithdrawals: () => loadPendingWithdrawals,
123
+ parseAmount: () => parseAmount,
124
+ parseError: () => parseError,
125
+ parseNote: () => parseNote,
126
+ parseTransactionError: () => parseTransactionError,
127
+ poseidonHash: () => poseidonHash,
128
+ prepareEncryptedOutput: () => prepareEncryptedOutput,
129
+ prepareEncryptedOutputForRecipient: () => prepareEncryptedOutputForRecipient,
130
+ proofToBytes: () => proofToBytes,
131
+ pubkeyToLimbs: () => pubkeyToLimbs,
132
+ randomBytes: () => randomBytes,
133
+ readMerkleTreeState: () => readMerkleTreeState,
134
+ removePendingDeposit: () => removePendingDeposit,
135
+ removePendingWithdrawal: () => removePendingWithdrawal,
136
+ savePendingDeposit: () => savePendingDeposit,
137
+ savePendingWithdrawal: () => savePendingWithdrawal,
138
+ scanNotesForWallet: () => scanNotesForWallet,
139
+ sdkLogger: () => sdkLogger,
140
+ sendTransaction: () => sendTransaction,
141
+ serializeNote: () => serializeNote,
142
+ setDebugMode: () => setDebugMode,
143
+ signTransaction: () => signTransaction,
144
+ splitTo2Limbs: () => splitTo2Limbs,
145
+ truncate: () => truncate,
146
+ tryDecryptNote: () => tryDecryptNote,
147
+ updateNoteWithDeposit: () => updateNoteWithDeposit,
148
+ updatePendingDeposit: () => updatePendingDeposit,
149
+ updatePendingWithdrawal: () => updatePendingWithdrawal,
150
+ validateDepositParams: () => validateDepositParams,
151
+ validateNote: () => validateNote,
152
+ validateOutputsSum: () => validateOutputsSum,
153
+ validateTransfers: () => validateTransfers,
154
+ validateWalletConnected: () => validateWalletConnected,
155
+ validateWithdrawableNote: () => validateWithdrawableNote,
156
+ verifyAllCircuits: () => verifyAllCircuits,
157
+ verifyCircuitIntegrity: () => verifyCircuitIntegrity,
158
+ withTiming: () => withTiming
159
+ });
160
+ module.exports = __toCommonJS(index_exports);
161
+
162
+ // src/core/CloakSDK.ts
163
+ var import_web34 = require("@solana/web3.js");
164
+
165
+ // src/core/types.ts
166
+ var CloakError = class extends Error {
167
+ constructor(message, category, retryable = false, originalError) {
168
+ super(message);
169
+ this.category = category;
170
+ this.retryable = retryable;
171
+ this.originalError = originalError;
172
+ this.name = "CloakError";
173
+ }
174
+ };
175
+
176
+ // src/core/keys.ts
177
+ var import_blake3 = require("@noble/hashes/blake3");
178
+ var import_tweetnacl = __toESM(require("tweetnacl"), 1);
179
+
33
180
  // src/utils/crypto.ts
181
+ var import_circomlibjs = require("circomlibjs");
182
+ var poseidon = null;
34
183
  async function getPoseidon() {
35
184
  if (!poseidon) {
36
185
  poseidon = await (0, import_circomlibjs.buildPoseidon)();
@@ -201,6 +350,7 @@ function isValidHex(hex, expectedLength) {
201
350
  }
202
351
  return true;
203
352
  }
353
+ var BN254_MODULUS = BigInt("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47");
204
354
  function proofToBytes(proof) {
205
355
  const pi_a_x = BigInt(proof.pi_a[0]);
206
356
  const pi_a_y = BigInt(proof.pi_a[1]);
@@ -291,266 +441,8 @@ function buildPublicInputsBytes(root, nullifier, outputsHash, publicAmount) {
291
441
  result.set(amountBytes, 96);
292
442
  return result;
293
443
  }
294
- var import_circomlibjs, poseidon, BN254_MODULUS;
295
- var init_crypto = __esm({
296
- "src/utils/crypto.ts"() {
297
- "use strict";
298
- import_circomlibjs = require("circomlibjs");
299
- poseidon = null;
300
- BN254_MODULUS = BigInt("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47");
301
- }
302
- });
303
-
304
- // src/utils/onchain-proof.ts
305
- var onchain_proof_exports = {};
306
- __export(onchain_proof_exports, {
307
- computeProofForLatestDeposit: () => computeProofForLatestDeposit,
308
- computeProofFromChain: () => computeProofFromChain,
309
- readMerkleTreeState: () => readMerkleTreeState
310
- });
311
- async function ensureZeroValues() {
312
- if (zeroValuesComputed) return;
313
- for (let i = 1; i <= MERKLE_TREE_HEIGHT; i++) {
314
- const prevZeroHex = POSEIDON_ZERO_VALUES[i - 1];
315
- const prevZeroBigInt = BigInt("0x" + prevZeroHex);
316
- const hash = await poseidonHash([prevZeroBigInt, prevZeroBigInt]);
317
- POSEIDON_ZERO_VALUES[i] = hash.toString(16).padStart(64, "0");
318
- }
319
- zeroValuesComputed = true;
320
- }
321
- async function readMerkleTreeState(connection, merkleTreePDA) {
322
- const accountInfo = await connection.getAccountInfo(merkleTreePDA);
323
- if (!accountInfo) {
324
- throw new Error("Merkle tree account not found");
325
- }
326
- const data = accountInfo.data;
327
- const nextIndex = Number(data.readBigUInt64LE(32));
328
- const subtrees = [];
329
- for (let i = 0; i < MERKLE_TREE_HEIGHT; i++) {
330
- const offset = SUBTREES_OFFSET + i * 32;
331
- const subtree = data.slice(offset, offset + 32);
332
- subtrees.push(Buffer.from(subtree).toString("hex"));
333
- }
334
- const root = Buffer.from(data.slice(ROOT_OFFSET, ROOT_OFFSET + 32)).toString("hex");
335
- return { nextIndex, root, subtrees };
336
- }
337
- async function computeProofFromChain(connection, merkleTreePDA, leafIndex) {
338
- await ensureZeroValues();
339
- const { nextIndex, root, subtrees } = await readMerkleTreeState(connection, merkleTreePDA);
340
- if (leafIndex >= nextIndex) {
341
- throw new Error(`Leaf index ${leafIndex} is beyond next_index ${nextIndex}`);
342
- }
343
- const pathElements = [];
344
- const pathIndices = [];
345
- let index = leafIndex;
346
- for (let level = 0; level < MERKLE_TREE_HEIGHT; level++) {
347
- pathIndices.push(index % 2);
348
- if (index % 2 === 0) {
349
- const siblingIndex = index + 1;
350
- const levelNextIndex = Math.ceil(nextIndex / (1 << level));
351
- if (siblingIndex >= levelNextIndex) {
352
- pathElements.push(POSEIDON_ZERO_VALUES[level]);
353
- } else {
354
- pathElements.push(POSEIDON_ZERO_VALUES[level]);
355
- }
356
- } else {
357
- pathElements.push(subtrees[level]);
358
- }
359
- index = Math.floor(index / 2);
360
- }
361
- return { pathElements, pathIndices, root };
362
- }
363
- async function computeProofForLatestDeposit(connection, merkleTreePDA) {
364
- await ensureZeroValues();
365
- const { nextIndex, root, subtrees } = await readMerkleTreeState(connection, merkleTreePDA);
366
- if (nextIndex === 0) {
367
- throw new Error("No leaves in tree");
368
- }
369
- const leafIndex = nextIndex - 1;
370
- const proof = await computeProofInternal(leafIndex, nextIndex, subtrees);
371
- return { ...proof, root, leafIndex };
372
- }
373
- async function computeProofInternal(leafIndex, _nextIndex, subtrees) {
374
- const pathElements = [];
375
- const pathIndices = [];
376
- let index = leafIndex;
377
- for (let level = 0; level < MERKLE_TREE_HEIGHT; level++) {
378
- pathIndices.push(index % 2);
379
- if (index % 2 === 0) {
380
- pathElements.push(POSEIDON_ZERO_VALUES[level]);
381
- } else {
382
- pathElements.push(subtrees[level]);
383
- }
384
- index = Math.floor(index / 2);
385
- }
386
- return { pathElements, pathIndices };
387
- }
388
- var MERKLE_TREE_HEIGHT, SUBTREES_OFFSET, ROOT_OFFSET, POSEIDON_ZERO_VALUES, zeroValuesComputed;
389
- var init_onchain_proof = __esm({
390
- "src/utils/onchain-proof.ts"() {
391
- "use strict";
392
- init_crypto();
393
- MERKLE_TREE_HEIGHT = 32;
394
- SUBTREES_OFFSET = 40;
395
- ROOT_OFFSET = 40 + MERKLE_TREE_HEIGHT * 32;
396
- POSEIDON_ZERO_VALUES = [
397
- "0000000000000000000000000000000000000000000000000000000000000000"
398
- // level 0
399
- ];
400
- zeroValuesComputed = false;
401
- }
402
- });
403
-
404
- // src/index.ts
405
- var index_exports = {};
406
- __export(index_exports, {
407
- CLOAK_PROGRAM_ID: () => CLOAK_PROGRAM_ID,
408
- CloakError: () => CloakError,
409
- CloakSDK: () => CloakSDK,
410
- DEFAULT_CIRCUITS_URL: () => DEFAULT_CIRCUITS_URL,
411
- EXPECTED_CIRCUIT_HASHES: () => EXPECTED_CIRCUIT_HASHES,
412
- FIXED_FEE_LAMPORTS: () => FIXED_FEE_LAMPORTS,
413
- LAMPORTS_PER_SOL: () => LAMPORTS_PER_SOL,
414
- LocalStorageAdapter: () => LocalStorageAdapter,
415
- MemoryStorageAdapter: () => MemoryStorageAdapter,
416
- RelayService: () => RelayService,
417
- RootNotFoundError: () => RootNotFoundError,
418
- ShieldPoolErrors: () => ShieldPoolErrors,
419
- VARIABLE_FEE_RATE: () => VARIABLE_FEE_RATE,
420
- VERSION: () => VERSION,
421
- areCircuitsAvailable: () => areCircuitsAvailable,
422
- bigintToBytes32: () => bigintToBytes32,
423
- buildPublicInputsBytes: () => buildPublicInputsBytes,
424
- bytesToHex: () => bytesToHex,
425
- calculateFee: () => calculateFee2,
426
- calculateRelayFee: () => calculateRelayFee,
427
- cleanupStalePendingOperations: () => cleanupStalePendingOperations,
428
- clearPendingDeposits: () => clearPendingDeposits,
429
- clearPendingWithdrawals: () => clearPendingWithdrawals,
430
- computeCommitment: () => computeCommitment,
431
- computeMerkleRoot: () => computeMerkleRoot,
432
- computeNullifier: () => computeNullifier,
433
- computeNullifierAsync: () => computeNullifierAsync,
434
- computeNullifierSync: () => computeNullifierSync,
435
- computeOutputsHash: () => computeOutputsHash,
436
- computeOutputsHashAsync: () => computeOutputsHashAsync,
437
- computeOutputsHashSync: () => computeOutputsHashSync,
438
- computeProofForLatestDeposit: () => computeProofForLatestDeposit,
439
- computeProofFromChain: () => computeProofFromChain,
440
- computeSwapOutputsHash: () => computeSwapOutputsHash,
441
- computeSwapOutputsHashAsync: () => computeSwapOutputsHashAsync,
442
- computeSwapOutputsHashSync: () => computeSwapOutputsHashSync,
443
- copyNoteToClipboard: () => copyNoteToClipboard,
444
- createCloakError: () => createCloakError,
445
- createDepositInstruction: () => createDepositInstruction,
446
- createLogger: () => createLogger,
447
- deriveSpendKey: () => deriveSpendKey,
448
- deriveViewKey: () => deriveViewKey,
449
- detectNetworkFromRpcUrl: () => detectNetworkFromRpcUrl,
450
- downloadNote: () => downloadNote,
451
- encodeNoteSimple: () => encodeNoteSimple,
452
- encryptNoteForRecipient: () => encryptNoteForRecipient,
453
- exportKeys: () => exportKeys,
454
- exportNote: () => exportNote,
455
- exportWalletKeys: () => exportWalletKeys,
456
- filterNotesByNetwork: () => filterNotesByNetwork,
457
- filterWithdrawableNotes: () => filterWithdrawableNotes,
458
- findNoteByCommitment: () => findNoteByCommitment,
459
- formatAmount: () => formatAmount,
460
- formatErrorForLogging: () => formatErrorForLogging,
461
- formatSol: () => formatSol,
462
- generateCloakKeys: () => generateCloakKeys,
463
- generateCommitment: () => generateCommitment,
464
- generateCommitmentAsync: () => generateCommitmentAsync,
465
- generateMasterSeed: () => generateMasterSeed,
466
- generateNote: () => generateNote,
467
- generateNoteFromWallet: () => generateNoteFromWallet,
468
- generateWithdrawRegularProof: () => generateWithdrawRegularProof,
469
- generateWithdrawSwapProof: () => generateWithdrawSwapProof,
470
- getAddressExplorerUrl: () => getAddressExplorerUrl,
471
- getDefaultCircuitsPath: () => getDefaultCircuitsPath,
472
- getDistributableAmount: () => getDistributableAmount2,
473
- getExplorerUrl: () => getExplorerUrl,
474
- getNullifierPDA: () => getNullifierPDA,
475
- getPendingOperationsSummary: () => getPendingOperationsSummary,
476
- getPublicKey: () => getPublicKey,
477
- getPublicViewKey: () => getPublicViewKey,
478
- getRecipientAmount: () => getRecipientAmount,
479
- getRpcUrlForNetwork: () => getRpcUrlForNetwork,
480
- getShieldPoolPDAs: () => getShieldPoolPDAs,
481
- getSwapStatePDA: () => getSwapStatePDA,
482
- getViewKey: () => getViewKey,
483
- hasPendingOperations: () => hasPendingOperations,
484
- hexToBigint: () => hexToBigint,
485
- hexToBytes: () => hexToBytes,
486
- importKeys: () => importKeys,
487
- importWalletKeys: () => importWalletKeys,
488
- isDebugEnabled: () => isDebugEnabled,
489
- isRootNotFoundError: () => isRootNotFoundError,
490
- isValidHex: () => isValidHex,
491
- isValidRpcUrl: () => isValidRpcUrl,
492
- isValidSolanaAddress: () => isValidSolanaAddress,
493
- isWithdrawable: () => isWithdrawable,
494
- keypairToAdapter: () => keypairToAdapter,
495
- loadPendingDeposits: () => loadPendingDeposits,
496
- loadPendingWithdrawals: () => loadPendingWithdrawals,
497
- parseAmount: () => parseAmount,
498
- parseError: () => parseError,
499
- parseNote: () => parseNote,
500
- parseTransactionError: () => parseTransactionError,
501
- poseidonHash: () => poseidonHash,
502
- prepareEncryptedOutput: () => prepareEncryptedOutput,
503
- prepareEncryptedOutputForRecipient: () => prepareEncryptedOutputForRecipient,
504
- proofToBytes: () => proofToBytes,
505
- pubkeyToLimbs: () => pubkeyToLimbs,
506
- randomBytes: () => randomBytes,
507
- readMerkleTreeState: () => readMerkleTreeState,
508
- removePendingDeposit: () => removePendingDeposit,
509
- removePendingWithdrawal: () => removePendingWithdrawal,
510
- savePendingDeposit: () => savePendingDeposit,
511
- savePendingWithdrawal: () => savePendingWithdrawal,
512
- scanNotesForWallet: () => scanNotesForWallet,
513
- sdkLogger: () => sdkLogger,
514
- sendTransaction: () => sendTransaction,
515
- serializeNote: () => serializeNote,
516
- setDebugMode: () => setDebugMode,
517
- signTransaction: () => signTransaction,
518
- splitTo2Limbs: () => splitTo2Limbs,
519
- truncate: () => truncate,
520
- tryDecryptNote: () => tryDecryptNote,
521
- updateNoteWithDeposit: () => updateNoteWithDeposit,
522
- updatePendingDeposit: () => updatePendingDeposit,
523
- updatePendingWithdrawal: () => updatePendingWithdrawal,
524
- validateDepositParams: () => validateDepositParams,
525
- validateNote: () => validateNote,
526
- validateOutputsSum: () => validateOutputsSum,
527
- validateTransfers: () => validateTransfers,
528
- validateWalletConnected: () => validateWalletConnected,
529
- validateWithdrawableNote: () => validateWithdrawableNote,
530
- verifyAllCircuits: () => verifyAllCircuits,
531
- verifyCircuitIntegrity: () => verifyCircuitIntegrity,
532
- withTiming: () => withTiming
533
- });
534
- module.exports = __toCommonJS(index_exports);
535
-
536
- // src/core/CloakSDK.ts
537
- var import_web34 = require("@solana/web3.js");
538
-
539
- // src/core/types.ts
540
- var CloakError = class extends Error {
541
- constructor(message, category, retryable = false, originalError) {
542
- super(message);
543
- this.category = category;
544
- this.retryable = retryable;
545
- this.originalError = originalError;
546
- this.name = "CloakError";
547
- }
548
- };
549
444
 
550
445
  // src/core/keys.ts
551
- var import_blake3 = require("@noble/hashes/blake3");
552
- var import_tweetnacl = __toESM(require("tweetnacl"), 1);
553
- init_crypto();
554
446
  function generateMasterSeed() {
555
447
  const seed = new Uint8Array(32);
556
448
  const g = globalThis;
@@ -720,7 +612,6 @@ function getAddressExplorerUrl(address, network = "devnet") {
720
612
  }
721
613
 
722
614
  // src/core/note-manager.ts
723
- init_crypto();
724
615
  async function generateNote(amountLamports, network) {
725
616
  const actualNetwork = network || detectNetworkFromRpcUrl();
726
617
  const skSpend = randomBytes(32);
@@ -939,7 +830,6 @@ var LocalStorageAdapter = class {
939
830
 
940
831
  // src/utils/validation.ts
941
832
  var import_web3 = require("@solana/web3.js");
942
- init_crypto();
943
833
  function isValidSolanaAddress(address) {
944
834
  try {
945
835
  new import_web3.PublicKey(address);
@@ -1057,9 +947,6 @@ function validateTransfers(recipients, totalAmount) {
1057
947
  }
1058
948
  }
1059
949
 
1060
- // src/core/CloakSDK.ts
1061
- init_crypto();
1062
-
1063
950
  // src/utils/errors.ts
1064
951
  var RootNotFoundError = class extends Error {
1065
952
  constructor(message = "Merkle root not found in history") {
@@ -1729,7 +1616,6 @@ function calculateRelayFee(amountLamports, feeBps) {
1729
1616
  }
1730
1617
 
1731
1618
  // src/services/RelayService.ts
1732
- init_crypto();
1733
1619
  var RelayService = class {
1734
1620
  /**
1735
1621
  * Create a new Relay Service client
@@ -2157,7 +2043,6 @@ function getSwapStatePDA(nullifier, programId) {
2157
2043
 
2158
2044
  // src/utils/proof-generation.ts
2159
2045
  var snarkjs = __toESM(require("snarkjs"), 1);
2160
- init_crypto();
2161
2046
  var IS_REACT_NATIVE = typeof navigator !== "undefined" && navigator.product === "ReactNative";
2162
2047
  var IS_BROWSER = IS_REACT_NATIVE || typeof window !== "undefined" || typeof globalThis !== "undefined" && typeof globalThis.document !== "undefined";
2163
2048
  var DEFAULT_CIRCUITS_URL = "https://www.cloak.ag/circuits";
@@ -2501,9 +2386,6 @@ async function verifyAllCircuits(circuitsPath) {
2501
2386
  return results;
2502
2387
  }
2503
2388
 
2504
- // src/core/CloakSDK.ts
2505
- init_crypto();
2506
-
2507
2389
  // src/utils/logger.ts
2508
2390
  var globalDebugEnabled = false;
2509
2391
  function checkEnvDebug() {
@@ -2591,6 +2473,93 @@ function truncate(str, len = 20) {
2591
2473
  }
2592
2474
  var sdkLogger = createLogger("cloak::sdk");
2593
2475
 
2476
+ // src/utils/onchain-proof.ts
2477
+ var MERKLE_TREE_HEIGHT = 32;
2478
+ var SUBTREES_OFFSET = 40;
2479
+ var ROOT_OFFSET = 40 + MERKLE_TREE_HEIGHT * 32;
2480
+ var POSEIDON_ZERO_VALUES = [
2481
+ "0000000000000000000000000000000000000000000000000000000000000000"
2482
+ // level 0
2483
+ ];
2484
+ var zeroValuesComputed = false;
2485
+ async function ensureZeroValues() {
2486
+ if (zeroValuesComputed) return;
2487
+ for (let i = 1; i <= MERKLE_TREE_HEIGHT; i++) {
2488
+ const prevZeroHex = POSEIDON_ZERO_VALUES[i - 1];
2489
+ const prevZeroBigInt = BigInt("0x" + prevZeroHex);
2490
+ const hash = await poseidonHash([prevZeroBigInt, prevZeroBigInt]);
2491
+ POSEIDON_ZERO_VALUES[i] = hash.toString(16).padStart(64, "0");
2492
+ }
2493
+ zeroValuesComputed = true;
2494
+ }
2495
+ async function readMerkleTreeState(connection, merkleTreePDA) {
2496
+ const accountInfo = await connection.getAccountInfo(merkleTreePDA);
2497
+ if (!accountInfo) {
2498
+ throw new Error("Merkle tree account not found");
2499
+ }
2500
+ const data = accountInfo.data;
2501
+ const nextIndex = Number(data.readBigUInt64LE(32));
2502
+ const subtrees = [];
2503
+ for (let i = 0; i < MERKLE_TREE_HEIGHT; i++) {
2504
+ const offset = SUBTREES_OFFSET + i * 32;
2505
+ const subtree = data.slice(offset, offset + 32);
2506
+ subtrees.push(Buffer.from(subtree).toString("hex"));
2507
+ }
2508
+ const root = Buffer.from(data.slice(ROOT_OFFSET, ROOT_OFFSET + 32)).toString("hex");
2509
+ return { nextIndex, root, subtrees };
2510
+ }
2511
+ async function computeProofFromChain(connection, merkleTreePDA, leafIndex) {
2512
+ await ensureZeroValues();
2513
+ const { nextIndex, root, subtrees } = await readMerkleTreeState(connection, merkleTreePDA);
2514
+ if (leafIndex >= nextIndex) {
2515
+ throw new Error(`Leaf index ${leafIndex} is beyond next_index ${nextIndex}`);
2516
+ }
2517
+ const pathElements = [];
2518
+ const pathIndices = [];
2519
+ let index = leafIndex;
2520
+ for (let level = 0; level < MERKLE_TREE_HEIGHT; level++) {
2521
+ pathIndices.push(index % 2);
2522
+ if (index % 2 === 0) {
2523
+ const siblingIndex = index + 1;
2524
+ const levelNextIndex = Math.ceil(nextIndex / (1 << level));
2525
+ if (siblingIndex >= levelNextIndex) {
2526
+ pathElements.push(POSEIDON_ZERO_VALUES[level]);
2527
+ } else {
2528
+ pathElements.push(POSEIDON_ZERO_VALUES[level]);
2529
+ }
2530
+ } else {
2531
+ pathElements.push(subtrees[level]);
2532
+ }
2533
+ index = Math.floor(index / 2);
2534
+ }
2535
+ return { pathElements, pathIndices, root };
2536
+ }
2537
+ async function computeProofForLatestDeposit(connection, merkleTreePDA) {
2538
+ await ensureZeroValues();
2539
+ const { nextIndex, root, subtrees } = await readMerkleTreeState(connection, merkleTreePDA);
2540
+ if (nextIndex === 0) {
2541
+ throw new Error("No leaves in tree");
2542
+ }
2543
+ const leafIndex = nextIndex - 1;
2544
+ const proof = await computeProofInternal(leafIndex, nextIndex, subtrees);
2545
+ return { ...proof, root, leafIndex };
2546
+ }
2547
+ async function computeProofInternal(leafIndex, _nextIndex, subtrees) {
2548
+ const pathElements = [];
2549
+ const pathIndices = [];
2550
+ let index = leafIndex;
2551
+ for (let level = 0; level < MERKLE_TREE_HEIGHT; level++) {
2552
+ pathIndices.push(index % 2);
2553
+ if (index % 2 === 0) {
2554
+ pathElements.push(POSEIDON_ZERO_VALUES[level]);
2555
+ } else {
2556
+ pathElements.push(subtrees[level]);
2557
+ }
2558
+ index = Math.floor(index / 2);
2559
+ }
2560
+ return { pathElements, pathIndices };
2561
+ }
2562
+
2594
2563
  // src/core/CloakSDK.ts
2595
2564
  var COMPUTE_BUDGET_PROGRAM_ID = new import_web34.PublicKey("ComputeBudget111111111111111111111111111111");
2596
2565
  function createSetLoadedAccountsDataSizeLimitInstruction(bytes) {
@@ -2919,11 +2888,10 @@ var CloakSDK = class {
2919
2888
  }
2920
2889
  let merkleProof;
2921
2890
  try {
2922
- const { computeProofFromChain: computeProofFromChain2 } = await Promise.resolve().then(() => (init_onchain_proof(), onchain_proof_exports));
2923
2891
  const programId2 = this.config.programId || CLOAK_PROGRAM_ID;
2924
2892
  const mintForSOL = new import_web34.PublicKey(new Uint8Array(32));
2925
2893
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId2, mintForSOL);
2926
- const chainProof = await computeProofFromChain2(connection, merkleTreePDA, leafIndex);
2894
+ const chainProof = await computeProofFromChain(connection, merkleTreePDA, leafIndex);
2927
2895
  merkleProof = {
2928
2896
  pathElements: chainProof.pathElements,
2929
2897
  pathIndices: chainProof.pathIndices
@@ -3043,11 +3011,10 @@ var CloakSDK = class {
3043
3011
  merkleProof = note.merkleProof;
3044
3012
  merkleRoot = note.root;
3045
3013
  } else {
3046
- const { computeProofFromChain: computeProofFromChain2 } = await Promise.resolve().then(() => (init_onchain_proof(), onchain_proof_exports));
3047
3014
  const programId = this.config.programId || CLOAK_PROGRAM_ID;
3048
3015
  const mintForSOL = new import_web34.PublicKey(new Uint8Array(32));
3049
3016
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId, mintForSOL);
3050
- const chainProof = await computeProofFromChain2(
3017
+ const chainProof = await computeProofFromChain(
3051
3018
  connection,
3052
3019
  merkleTreePDA,
3053
3020
  note.leafIndex
@@ -3369,11 +3336,10 @@ var CloakSDK = class {
3369
3336
  options?.onProgress?.(`proof_refresh_${attempt + 1}`);
3370
3337
  await new Promise((resolve) => setTimeout(resolve, 1e3));
3371
3338
  }
3372
- const { computeProofFromChain: computeProofFromChain2 } = await Promise.resolve().then(() => (init_onchain_proof(), onchain_proof_exports));
3373
3339
  const programId = this.config.programId || CLOAK_PROGRAM_ID;
3374
3340
  const mintForSOL = new import_web34.PublicKey(new Uint8Array(32));
3375
3341
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId, mintForSOL);
3376
- const chainProof = await computeProofFromChain2(connection, merkleTreePDA, note.leafIndex);
3342
+ const chainProof = await computeProofFromChain(connection, merkleTreePDA, note.leafIndex);
3377
3343
  const merkleProof = {
3378
3344
  pathElements: chainProof.pathElements,
3379
3345
  pathIndices: chainProof.pathIndices
@@ -3543,11 +3509,10 @@ var CloakSDK = class {
3543
3509
  * @returns Merkle proof computed from on-chain data
3544
3510
  */
3545
3511
  async getMerkleProof(connection, leafIndex) {
3546
- const { computeProofFromChain: computeProofFromChain2 } = await Promise.resolve().then(() => (init_onchain_proof(), onchain_proof_exports));
3547
3512
  const programId = this.config.programId || CLOAK_PROGRAM_ID;
3548
3513
  const mintForSOL = new import_web34.PublicKey(new Uint8Array(32));
3549
3514
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId, mintForSOL);
3550
- const chainProof = await computeProofFromChain2(connection, merkleTreePDA, leafIndex);
3515
+ const chainProof = await computeProofFromChain(connection, merkleTreePDA, leafIndex);
3551
3516
  return {
3552
3517
  pathElements: chainProof.pathElements,
3553
3518
  pathIndices: chainProof.pathIndices,
@@ -3561,11 +3526,10 @@ var CloakSDK = class {
3561
3526
  * @returns Current root hash from on-chain tree
3562
3527
  */
3563
3528
  async getCurrentRoot(connection) {
3564
- const { readMerkleTreeState: readMerkleTreeState2 } = await Promise.resolve().then(() => (init_onchain_proof(), onchain_proof_exports));
3565
3529
  const programId = this.config.programId || CLOAK_PROGRAM_ID;
3566
3530
  const mintForSOL = new import_web34.PublicKey(new Uint8Array(32));
3567
3531
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId, mintForSOL);
3568
- const state = await readMerkleTreeState2(connection, merkleTreePDA);
3532
+ const state = await readMerkleTreeState(connection, merkleTreePDA);
3569
3533
  return state.root;
3570
3534
  }
3571
3535
  /**
@@ -3717,7 +3681,6 @@ var CloakSDK = class {
3717
3681
  };
3718
3682
 
3719
3683
  // src/core/note.ts
3720
- init_crypto();
3721
3684
  function serializeNote(note, pretty = false) {
3722
3685
  validateNote(note);
3723
3686
  return pretty ? JSON.stringify(note, null, 2) : JSON.stringify(note);
@@ -3750,11 +3713,7 @@ async function copyNoteToClipboard(note) {
3750
3713
  await nav.clipboard.writeText(json);
3751
3714
  }
3752
3715
 
3753
- // src/index.ts
3754
- init_crypto();
3755
-
3756
3716
  // src/helpers/encrypted-output.ts
3757
- init_crypto();
3758
3717
  function prepareEncryptedOutput(note, cloakKeys) {
3759
3718
  const noteData = {
3760
3719
  amount: note.amount,
@@ -3865,9 +3824,6 @@ function keypairToAdapter(keypair) {
3865
3824
  };
3866
3825
  }
3867
3826
 
3868
- // src/index.ts
3869
- init_onchain_proof();
3870
-
3871
3827
  // src/utils/pending-operations.ts
3872
3828
  var PENDING_DEPOSITS_KEY = "cloak_pending_deposits";
3873
3829
  var PENDING_WITHDRAWALS_KEY = "cloak_pending_withdrawals";
package/dist/index.js CHANGED
@@ -1,33 +1,9 @@
1
- import {
2
- __require,
3
- bigintToBytes32,
4
- buildPublicInputsBytes,
5
- bytesToHex,
6
- computeCommitment,
7
- computeMerkleRoot,
8
- computeNullifier,
9
- computeNullifierAsync,
10
- computeNullifierSync,
11
- computeOutputsHash,
12
- computeOutputsHashAsync,
13
- computeOutputsHashSync,
14
- computeProofForLatestDeposit,
15
- computeProofFromChain,
16
- computeSwapOutputsHash,
17
- computeSwapOutputsHashAsync,
18
- computeSwapOutputsHashSync,
19
- generateCommitment,
20
- generateCommitmentAsync,
21
- hexToBigint,
22
- hexToBytes,
23
- isValidHex,
24
- poseidonHash,
25
- proofToBytes,
26
- pubkeyToLimbs,
27
- randomBytes,
28
- readMerkleTreeState,
29
- splitTo2Limbs
30
- } from "./chunk-QDMAIFO4.js";
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
31
7
 
32
8
  // src/core/CloakSDK.ts
33
9
  import {
@@ -52,6 +28,273 @@ var CloakError = class extends Error {
52
28
  // src/core/keys.ts
53
29
  import { blake3 } from "@noble/hashes/blake3";
54
30
  import nacl from "tweetnacl";
31
+
32
+ // src/utils/crypto.ts
33
+ import { buildPoseidon } from "circomlibjs";
34
+ var poseidon = null;
35
+ async function getPoseidon() {
36
+ if (!poseidon) {
37
+ poseidon = await buildPoseidon();
38
+ }
39
+ return poseidon;
40
+ }
41
+ async function poseidonHash(inputs) {
42
+ const p = await getPoseidon();
43
+ const hash = p(inputs.map((x) => p.F.e(x)));
44
+ return p.F.toObject(hash);
45
+ }
46
+ function splitTo2Limbs(value) {
47
+ const mask = (1n << 128n) - 1n;
48
+ const lo = value & mask;
49
+ const hi = value >> 128n;
50
+ return [lo, hi];
51
+ }
52
+ function pubkeyToLimbs(pubkey) {
53
+ const bytes = typeof pubkey.toBytes === "function" ? pubkey.toBytes() : pubkey;
54
+ const value = BigInt("0x" + Buffer.from(bytes).toString("hex"));
55
+ return splitTo2Limbs(value);
56
+ }
57
+ async function computeMerkleRoot(leaf, pathElements, pathIndices) {
58
+ let current = leaf;
59
+ for (let i = 0; i < pathElements.length; i++) {
60
+ if (pathIndices[i] === 0) {
61
+ current = await poseidonHash([current, pathElements[i]]);
62
+ } else {
63
+ current = await poseidonHash([pathElements[i], current]);
64
+ }
65
+ }
66
+ return current;
67
+ }
68
+ function hexToBigint(hex) {
69
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
70
+ return BigInt("0x" + cleanHex);
71
+ }
72
+ async function computeCommitment(amount, r, sk_spend) {
73
+ const [sk0, sk1] = splitTo2Limbs(sk_spend);
74
+ const [r0, r1] = splitTo2Limbs(r);
75
+ const pk_spend = await poseidonHash([sk0, sk1]);
76
+ return await poseidonHash([amount, r0, r1, pk_spend]);
77
+ }
78
+ async function generateCommitmentAsync(amountLamports, r, skSpend) {
79
+ const amount = BigInt(amountLamports);
80
+ const rValue = hexToBigint(bytesToHex(r));
81
+ const skValue = hexToBigint(bytesToHex(skSpend));
82
+ return await computeCommitment(amount, rValue, skValue);
83
+ }
84
+ function generateCommitment(_amountLamports, _r, _skSpend) {
85
+ throw new Error("generateCommitment is deprecated. Use generateCommitmentAsync instead.");
86
+ }
87
+ async function computeNullifier(sk_spend, leafIndex) {
88
+ const [sk0, sk1] = splitTo2Limbs(sk_spend);
89
+ return await poseidonHash([sk0, sk1, leafIndex]);
90
+ }
91
+ async function computeNullifierAsync(skSpend, leafIndex) {
92
+ const skValue = typeof skSpend === "string" ? hexToBigint(skSpend) : hexToBigint(bytesToHex(skSpend));
93
+ return await computeNullifier(skValue, BigInt(leafIndex));
94
+ }
95
+ function computeNullifierSync(_skSpend, _leafIndex) {
96
+ throw new Error("computeNullifierSync is deprecated. Use computeNullifierAsync instead.");
97
+ }
98
+ async function computeOutputsHashAsync(outputs) {
99
+ let hash = 0n;
100
+ for (const output of outputs) {
101
+ const [lo, hi] = pubkeyToLimbs(output.recipient);
102
+ hash = await poseidonHash([hash, lo, hi, BigInt(output.amount)]);
103
+ }
104
+ return hash;
105
+ }
106
+ async function computeOutputsHash(outAddr, outAmount, outFlags) {
107
+ let hash = 0n;
108
+ for (let i = 0; i < 5; i++) {
109
+ if (outFlags[i] === 1) {
110
+ hash = await poseidonHash([hash, outAddr[i][0], outAddr[i][1], outAmount[i]]);
111
+ }
112
+ }
113
+ return hash;
114
+ }
115
+ function computeOutputsHashSync(_outputs) {
116
+ throw new Error("computeOutputsHashSync is deprecated. Use computeOutputsHashAsync instead.");
117
+ }
118
+ async function computeSwapOutputsHash(inputMintLimbs, outputMintLimbs, recipientAtaLimbs, minOutputAmount, publicAmount) {
119
+ return await poseidonHash([
120
+ inputMintLimbs[0],
121
+ inputMintLimbs[1],
122
+ outputMintLimbs[0],
123
+ outputMintLimbs[1],
124
+ recipientAtaLimbs[0],
125
+ recipientAtaLimbs[1],
126
+ minOutputAmount,
127
+ publicAmount
128
+ ]);
129
+ }
130
+ async function computeSwapOutputsHashAsync(inputMint, outputMint, recipientAta, minOutputAmount, amount) {
131
+ const inputMintLimbs = pubkeyToLimbs(inputMint);
132
+ const outputMintLimbs = pubkeyToLimbs(outputMint);
133
+ const recipientAtaLimbs = pubkeyToLimbs(recipientAta);
134
+ return await computeSwapOutputsHash(
135
+ inputMintLimbs,
136
+ outputMintLimbs,
137
+ recipientAtaLimbs,
138
+ BigInt(minOutputAmount),
139
+ BigInt(amount)
140
+ );
141
+ }
142
+ function computeSwapOutputsHashSync(_outputMint, _recipientAta, _minOutputAmount, _amount) {
143
+ throw new Error("computeSwapOutputsHashSync is deprecated. Use computeSwapOutputsHashAsync instead.");
144
+ }
145
+ function bigintToBytes32(n) {
146
+ const hex = n.toString(16).padStart(64, "0");
147
+ const bytes = new Uint8Array(32);
148
+ for (let i = 0; i < 32; i++) {
149
+ bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
150
+ }
151
+ return bytes;
152
+ }
153
+ function hexToBytes(hex) {
154
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
155
+ const bytes = new Uint8Array(cleanHex.length / 2);
156
+ for (let i = 0; i < cleanHex.length; i += 2) {
157
+ bytes[i / 2] = parseInt(cleanHex.substr(i, 2), 16);
158
+ }
159
+ return bytes;
160
+ }
161
+ function bytesToHex(bytes, prefix = false) {
162
+ const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
163
+ return prefix ? `0x${hex}` : hex;
164
+ }
165
+ function randomBytes(length) {
166
+ const bytes = new Uint8Array(length);
167
+ const g = globalThis;
168
+ try {
169
+ const cryptoObj = g?.crypto || g?.window?.crypto || g?.self?.crypto;
170
+ if (cryptoObj && typeof cryptoObj.getRandomValues === "function") {
171
+ cryptoObj.getRandomValues(bytes);
172
+ return bytes;
173
+ }
174
+ } catch {
175
+ }
176
+ try {
177
+ const nodeCrypto = __require("crypto");
178
+ if (nodeCrypto?.randomBytes) {
179
+ const buffer = nodeCrypto.randomBytes(length);
180
+ bytes.set(buffer);
181
+ return bytes;
182
+ }
183
+ if (nodeCrypto?.webcrypto?.getRandomValues) {
184
+ nodeCrypto.webcrypto.getRandomValues(bytes);
185
+ return bytes;
186
+ }
187
+ } catch {
188
+ }
189
+ for (let i = 0; i < length; i++) bytes[i] = Math.floor(Math.random() * 256);
190
+ return bytes;
191
+ }
192
+ function isValidHex(hex, expectedLength) {
193
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
194
+ if (!/^[0-9a-f]*$/i.test(cleanHex)) {
195
+ return false;
196
+ }
197
+ if (cleanHex.length % 2 !== 0) {
198
+ return false;
199
+ }
200
+ if (expectedLength !== void 0) {
201
+ return cleanHex.length === expectedLength * 2;
202
+ }
203
+ return true;
204
+ }
205
+ var BN254_MODULUS = BigInt("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47");
206
+ function proofToBytes(proof) {
207
+ const pi_a_x = BigInt(proof.pi_a[0]);
208
+ const pi_a_y = BigInt(proof.pi_a[1]);
209
+ const pi_a_y_neg = (BN254_MODULUS - pi_a_y) % BN254_MODULUS;
210
+ const pi_a_x_le = bigintToBytes32LE(pi_a_x);
211
+ const pi_a_y_neg_le = bigintToBytes32LE(pi_a_y_neg);
212
+ const pi_a_le = new Uint8Array(64);
213
+ pi_a_le.set(pi_a_x_le, 0);
214
+ pi_a_le.set(pi_a_y_neg_le, 32);
215
+ const pi_a_be = convertEndianness32(pi_a_le);
216
+ const pi_b_x1 = BigInt(proof.pi_b[0][0]);
217
+ const pi_b_x2 = BigInt(proof.pi_b[0][1]);
218
+ const pi_b_y1 = BigInt(proof.pi_b[1][0]);
219
+ const pi_b_y2 = BigInt(proof.pi_b[1][1]);
220
+ const pi_b_x1_le = bigintToBytes32LE(pi_b_x1);
221
+ const pi_b_x2_le = bigintToBytes32LE(pi_b_x2);
222
+ const pi_b_y1_le = bigintToBytes32LE(pi_b_y1);
223
+ const pi_b_y2_le = bigintToBytes32LE(pi_b_y2);
224
+ const pi_b_le = new Uint8Array(128);
225
+ pi_b_le.set(pi_b_x1_le, 0);
226
+ pi_b_le.set(pi_b_x2_le, 32);
227
+ pi_b_le.set(pi_b_y1_le, 64);
228
+ pi_b_le.set(pi_b_y2_le, 96);
229
+ const pi_b_be = convertEndianness64(pi_b_le);
230
+ const pi_c_x = BigInt(proof.pi_c[0]);
231
+ const pi_c_y = BigInt(proof.pi_c[1]);
232
+ const pi_c_x_le = bigintToBytes32LE(pi_c_x);
233
+ const pi_c_y_le = bigintToBytes32LE(pi_c_y);
234
+ const pi_c_le = new Uint8Array(64);
235
+ pi_c_le.set(pi_c_x_le, 0);
236
+ pi_c_le.set(pi_c_y_le, 32);
237
+ const pi_c_be = convertEndianness32(pi_c_le);
238
+ const result = new Uint8Array(256);
239
+ result.set(pi_a_be, 0);
240
+ result.set(pi_b_be, 64);
241
+ result.set(pi_c_be, 192);
242
+ return result;
243
+ }
244
+ function bigintToBytes32LE(n) {
245
+ const bytes = new Uint8Array(32);
246
+ let value = n % BN254_MODULUS;
247
+ if (value < 0) {
248
+ value = (value + BN254_MODULUS) % BN254_MODULUS;
249
+ }
250
+ for (let i = 0; i < 32; i++) {
251
+ bytes[i] = Number(value & BigInt(255));
252
+ value = value >> BigInt(8);
253
+ }
254
+ return bytes;
255
+ }
256
+ function convertEndianness32(bytes) {
257
+ if (bytes.length !== 64) {
258
+ throw new Error("convertEndianness32 expects 64 bytes");
259
+ }
260
+ const result = new Uint8Array(64);
261
+ for (let i = 0; i < 32; i++) {
262
+ result[i] = bytes[31 - i];
263
+ }
264
+ for (let i = 0; i < 32; i++) {
265
+ result[32 + i] = bytes[63 - i];
266
+ }
267
+ return result;
268
+ }
269
+ function convertEndianness64(bytes) {
270
+ if (bytes.length !== 128) {
271
+ throw new Error("convertEndianness64 expects 128 bytes");
272
+ }
273
+ const result = new Uint8Array(128);
274
+ for (let i = 0; i < 64; i++) {
275
+ result[i] = bytes[63 - i];
276
+ }
277
+ for (let i = 0; i < 64; i++) {
278
+ result[64 + i] = bytes[127 - i];
279
+ }
280
+ return result;
281
+ }
282
+ function buildPublicInputsBytes(root, nullifier, outputsHash, publicAmount) {
283
+ const result = new Uint8Array(104);
284
+ result.set(bigintToBytes32(root), 0);
285
+ result.set(bigintToBytes32(nullifier), 32);
286
+ result.set(bigintToBytes32(outputsHash), 64);
287
+ const amountBytes = new Uint8Array(8);
288
+ let amt = publicAmount;
289
+ for (let i = 7; i >= 0; i--) {
290
+ amountBytes[i] = Number(amt & 0xffn);
291
+ amt = amt >> 8n;
292
+ }
293
+ result.set(amountBytes, 96);
294
+ return result;
295
+ }
296
+
297
+ // src/core/keys.ts
55
298
  function generateMasterSeed() {
56
299
  const seed = new Uint8Array(32);
57
300
  const g = globalThis;
@@ -2086,6 +2329,93 @@ function truncate(str, len = 20) {
2086
2329
  }
2087
2330
  var sdkLogger = createLogger("cloak::sdk");
2088
2331
 
2332
+ // src/utils/onchain-proof.ts
2333
+ var MERKLE_TREE_HEIGHT = 32;
2334
+ var SUBTREES_OFFSET = 40;
2335
+ var ROOT_OFFSET = 40 + MERKLE_TREE_HEIGHT * 32;
2336
+ var POSEIDON_ZERO_VALUES = [
2337
+ "0000000000000000000000000000000000000000000000000000000000000000"
2338
+ // level 0
2339
+ ];
2340
+ var zeroValuesComputed = false;
2341
+ async function ensureZeroValues() {
2342
+ if (zeroValuesComputed) return;
2343
+ for (let i = 1; i <= MERKLE_TREE_HEIGHT; i++) {
2344
+ const prevZeroHex = POSEIDON_ZERO_VALUES[i - 1];
2345
+ const prevZeroBigInt = BigInt("0x" + prevZeroHex);
2346
+ const hash = await poseidonHash([prevZeroBigInt, prevZeroBigInt]);
2347
+ POSEIDON_ZERO_VALUES[i] = hash.toString(16).padStart(64, "0");
2348
+ }
2349
+ zeroValuesComputed = true;
2350
+ }
2351
+ async function readMerkleTreeState(connection, merkleTreePDA) {
2352
+ const accountInfo = await connection.getAccountInfo(merkleTreePDA);
2353
+ if (!accountInfo) {
2354
+ throw new Error("Merkle tree account not found");
2355
+ }
2356
+ const data = accountInfo.data;
2357
+ const nextIndex = Number(data.readBigUInt64LE(32));
2358
+ const subtrees = [];
2359
+ for (let i = 0; i < MERKLE_TREE_HEIGHT; i++) {
2360
+ const offset = SUBTREES_OFFSET + i * 32;
2361
+ const subtree = data.slice(offset, offset + 32);
2362
+ subtrees.push(Buffer.from(subtree).toString("hex"));
2363
+ }
2364
+ const root = Buffer.from(data.slice(ROOT_OFFSET, ROOT_OFFSET + 32)).toString("hex");
2365
+ return { nextIndex, root, subtrees };
2366
+ }
2367
+ async function computeProofFromChain(connection, merkleTreePDA, leafIndex) {
2368
+ await ensureZeroValues();
2369
+ const { nextIndex, root, subtrees } = await readMerkleTreeState(connection, merkleTreePDA);
2370
+ if (leafIndex >= nextIndex) {
2371
+ throw new Error(`Leaf index ${leafIndex} is beyond next_index ${nextIndex}`);
2372
+ }
2373
+ const pathElements = [];
2374
+ const pathIndices = [];
2375
+ let index = leafIndex;
2376
+ for (let level = 0; level < MERKLE_TREE_HEIGHT; level++) {
2377
+ pathIndices.push(index % 2);
2378
+ if (index % 2 === 0) {
2379
+ const siblingIndex = index + 1;
2380
+ const levelNextIndex = Math.ceil(nextIndex / (1 << level));
2381
+ if (siblingIndex >= levelNextIndex) {
2382
+ pathElements.push(POSEIDON_ZERO_VALUES[level]);
2383
+ } else {
2384
+ pathElements.push(POSEIDON_ZERO_VALUES[level]);
2385
+ }
2386
+ } else {
2387
+ pathElements.push(subtrees[level]);
2388
+ }
2389
+ index = Math.floor(index / 2);
2390
+ }
2391
+ return { pathElements, pathIndices, root };
2392
+ }
2393
+ async function computeProofForLatestDeposit(connection, merkleTreePDA) {
2394
+ await ensureZeroValues();
2395
+ const { nextIndex, root, subtrees } = await readMerkleTreeState(connection, merkleTreePDA);
2396
+ if (nextIndex === 0) {
2397
+ throw new Error("No leaves in tree");
2398
+ }
2399
+ const leafIndex = nextIndex - 1;
2400
+ const proof = await computeProofInternal(leafIndex, nextIndex, subtrees);
2401
+ return { ...proof, root, leafIndex };
2402
+ }
2403
+ async function computeProofInternal(leafIndex, _nextIndex, subtrees) {
2404
+ const pathElements = [];
2405
+ const pathIndices = [];
2406
+ let index = leafIndex;
2407
+ for (let level = 0; level < MERKLE_TREE_HEIGHT; level++) {
2408
+ pathIndices.push(index % 2);
2409
+ if (index % 2 === 0) {
2410
+ pathElements.push(POSEIDON_ZERO_VALUES[level]);
2411
+ } else {
2412
+ pathElements.push(subtrees[level]);
2413
+ }
2414
+ index = Math.floor(index / 2);
2415
+ }
2416
+ return { pathElements, pathIndices };
2417
+ }
2418
+
2089
2419
  // src/core/CloakSDK.ts
2090
2420
  var COMPUTE_BUDGET_PROGRAM_ID = new PublicKey4("ComputeBudget111111111111111111111111111111");
2091
2421
  function createSetLoadedAccountsDataSizeLimitInstruction(bytes) {
@@ -2414,11 +2744,10 @@ var CloakSDK = class {
2414
2744
  }
2415
2745
  let merkleProof;
2416
2746
  try {
2417
- const { computeProofFromChain: computeProofFromChain2 } = await import("./onchain-proof-CY7AWF43.js");
2418
2747
  const programId2 = this.config.programId || CLOAK_PROGRAM_ID;
2419
2748
  const mintForSOL = new PublicKey4(new Uint8Array(32));
2420
2749
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId2, mintForSOL);
2421
- const chainProof = await computeProofFromChain2(connection, merkleTreePDA, leafIndex);
2750
+ const chainProof = await computeProofFromChain(connection, merkleTreePDA, leafIndex);
2422
2751
  merkleProof = {
2423
2752
  pathElements: chainProof.pathElements,
2424
2753
  pathIndices: chainProof.pathIndices
@@ -2538,11 +2867,10 @@ var CloakSDK = class {
2538
2867
  merkleProof = note.merkleProof;
2539
2868
  merkleRoot = note.root;
2540
2869
  } else {
2541
- const { computeProofFromChain: computeProofFromChain2 } = await import("./onchain-proof-CY7AWF43.js");
2542
2870
  const programId = this.config.programId || CLOAK_PROGRAM_ID;
2543
2871
  const mintForSOL = new PublicKey4(new Uint8Array(32));
2544
2872
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId, mintForSOL);
2545
- const chainProof = await computeProofFromChain2(
2873
+ const chainProof = await computeProofFromChain(
2546
2874
  connection,
2547
2875
  merkleTreePDA,
2548
2876
  note.leafIndex
@@ -2864,11 +3192,10 @@ var CloakSDK = class {
2864
3192
  options?.onProgress?.(`proof_refresh_${attempt + 1}`);
2865
3193
  await new Promise((resolve) => setTimeout(resolve, 1e3));
2866
3194
  }
2867
- const { computeProofFromChain: computeProofFromChain2 } = await import("./onchain-proof-CY7AWF43.js");
2868
3195
  const programId = this.config.programId || CLOAK_PROGRAM_ID;
2869
3196
  const mintForSOL = new PublicKey4(new Uint8Array(32));
2870
3197
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId, mintForSOL);
2871
- const chainProof = await computeProofFromChain2(connection, merkleTreePDA, note.leafIndex);
3198
+ const chainProof = await computeProofFromChain(connection, merkleTreePDA, note.leafIndex);
2872
3199
  const merkleProof = {
2873
3200
  pathElements: chainProof.pathElements,
2874
3201
  pathIndices: chainProof.pathIndices
@@ -3038,11 +3365,10 @@ var CloakSDK = class {
3038
3365
  * @returns Merkle proof computed from on-chain data
3039
3366
  */
3040
3367
  async getMerkleProof(connection, leafIndex) {
3041
- const { computeProofFromChain: computeProofFromChain2 } = await import("./onchain-proof-CY7AWF43.js");
3042
3368
  const programId = this.config.programId || CLOAK_PROGRAM_ID;
3043
3369
  const mintForSOL = new PublicKey4(new Uint8Array(32));
3044
3370
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId, mintForSOL);
3045
- const chainProof = await computeProofFromChain2(connection, merkleTreePDA, leafIndex);
3371
+ const chainProof = await computeProofFromChain(connection, merkleTreePDA, leafIndex);
3046
3372
  return {
3047
3373
  pathElements: chainProof.pathElements,
3048
3374
  pathIndices: chainProof.pathIndices,
@@ -3056,11 +3382,10 @@ var CloakSDK = class {
3056
3382
  * @returns Current root hash from on-chain tree
3057
3383
  */
3058
3384
  async getCurrentRoot(connection) {
3059
- const { readMerkleTreeState: readMerkleTreeState2 } = await import("./onchain-proof-CY7AWF43.js");
3060
3385
  const programId = this.config.programId || CLOAK_PROGRAM_ID;
3061
3386
  const mintForSOL = new PublicKey4(new Uint8Array(32));
3062
3387
  const { merkleTree: merkleTreePDA } = getShieldPoolPDAs(programId, mintForSOL);
3063
- const state = await readMerkleTreeState2(connection, merkleTreePDA);
3388
+ const state = await readMerkleTreeState(connection, merkleTreePDA);
3064
3389
  return state.root;
3065
3390
  }
3066
3391
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloak.ag/sdk",
3
3
  "description": "TypeScript SDK for Cloak",
4
- "version": "1.0.8",
4
+ "version": "1.0.9",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.js",
@@ -25,8 +25,7 @@
25
25
  "example:multiple": "tsx examples/multiple-withdraw.ts",
26
26
  "example:swap": "tsx examples/swap.ts",
27
27
  "example:usdc-send": "tsx examples/usdc-send.ts",
28
- "example:usdc-receive": "tsx examples/usdc-receive.ts",
29
- "example:stress": "tsx examples/concurrent-stress.ts"
28
+ "example:usdc-receive": "tsx examples/usdc-receive.ts"
30
29
  },
31
30
  "keywords": [
32
31
  "solana",
@@ -101,4 +100,4 @@
101
100
  "bigint-buffer": "npm:bigint-buffer-fixed@^1.1.6",
102
101
  "tar": "^7.5.4"
103
102
  }
104
- }
103
+ }