@cloak.dev/sdk 0.1.0
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/README.md +268 -0
- package/dist/chunk-2SOX3JNO.js +255 -0
- package/dist/index.cjs +9785 -0
- package/dist/index.d.cts +3430 -0
- package/dist/index.d.ts +3430 -0
- package/dist/index.js +9338 -0
- package/dist/utxo-LSTVI4HH.js +42 -0
- package/package.json +120 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3430 @@
|
|
|
1
|
+
import { PublicKey, Transaction, Connection, TransactionInstruction, Keypair, SendOptions, AddressLookupTableAccount, VersionedTransaction } from '@solana/web3.js';
|
|
2
|
+
|
|
3
|
+
type ComplianceTxType = "deposit" | "withdraw" | "send" | "swap";
|
|
4
|
+
interface TransactionMetadata {
|
|
5
|
+
amount: number;
|
|
6
|
+
recipient: string;
|
|
7
|
+
timestamp: number;
|
|
8
|
+
txType: ComplianceTxType;
|
|
9
|
+
commitment: string;
|
|
10
|
+
signature?: string;
|
|
11
|
+
outputMint?: string;
|
|
12
|
+
}
|
|
13
|
+
interface EncryptedMetadataBundle {
|
|
14
|
+
encrypted_user: string;
|
|
15
|
+
encrypted_compliance: string;
|
|
16
|
+
user_pubkey: string;
|
|
17
|
+
commitment: string;
|
|
18
|
+
timestamp: number;
|
|
19
|
+
tx_type?: ComplianceTxType;
|
|
20
|
+
wallet_signature?: string;
|
|
21
|
+
viewing_key?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Supported Solana networks
|
|
26
|
+
*/
|
|
27
|
+
type Network = "localnet" | "devnet" | "mainnet" | "testnet";
|
|
28
|
+
/**
|
|
29
|
+
* Minimal wallet adapter interface
|
|
30
|
+
* Compatible with @solana/wallet-adapter-base
|
|
31
|
+
*/
|
|
32
|
+
interface WalletAdapter {
|
|
33
|
+
publicKey: PublicKey | null;
|
|
34
|
+
signTransaction?<T extends Transaction>(transaction: T): Promise<T>;
|
|
35
|
+
signAllTransactions?<T extends Transaction>(transactions: T[]): Promise<T[]>;
|
|
36
|
+
sendTransaction?(transaction: Transaction, connection: any, options?: any): Promise<string>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Cloak-specific error with categorization
|
|
40
|
+
*/
|
|
41
|
+
declare class CloakError extends Error {
|
|
42
|
+
category: "network" | "indexer" | "prover" | "relay" | "validation" | "wallet" | "environment" | "service";
|
|
43
|
+
retryable: boolean;
|
|
44
|
+
originalError?: Error | undefined;
|
|
45
|
+
constructor(message: string, category: "network" | "indexer" | "prover" | "relay" | "validation" | "wallet" | "environment" | "service", retryable?: boolean, originalError?: Error | undefined);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Cloak Note - Represents a private transaction commitment
|
|
49
|
+
*
|
|
50
|
+
* A note contains all the information needed to withdraw funds from the Cloak protocol.
|
|
51
|
+
* Keep this safe and secret - anyone with access to this note can withdraw the funds!
|
|
52
|
+
*/
|
|
53
|
+
interface CloakNote {
|
|
54
|
+
/** Protocol version */
|
|
55
|
+
version: string;
|
|
56
|
+
/** Amount in lamports */
|
|
57
|
+
amount: number;
|
|
58
|
+
/** Commitment hash (hex) */
|
|
59
|
+
commitment: string;
|
|
60
|
+
/** Spending secret key (hex, 64 chars) */
|
|
61
|
+
sk_spend: string;
|
|
62
|
+
/** Randomness value (hex, 64 chars) */
|
|
63
|
+
r: string;
|
|
64
|
+
/** Transaction signature from deposit (optional until deposited) */
|
|
65
|
+
depositSignature?: string;
|
|
66
|
+
/** Solana slot when deposited (optional until deposited) */
|
|
67
|
+
depositSlot?: number;
|
|
68
|
+
/** Index in the Merkle tree (optional until deposited) */
|
|
69
|
+
leafIndex?: number;
|
|
70
|
+
/** Historical Merkle root at time of deposit (optional until deposited) */
|
|
71
|
+
root?: string;
|
|
72
|
+
/** Merkle proof at time of deposit (optional until deposited) */
|
|
73
|
+
merkleProof?: MerkleProof;
|
|
74
|
+
/** Creation timestamp */
|
|
75
|
+
timestamp: number;
|
|
76
|
+
/** Network where this note was created */
|
|
77
|
+
network: Network;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Merkle proof for a leaf in the commitment tree
|
|
81
|
+
*/
|
|
82
|
+
interface MerkleProof {
|
|
83
|
+
/** Sibling hashes along the path (hex strings) */
|
|
84
|
+
pathElements: string[];
|
|
85
|
+
/** Path directions (0 = left, 1 = right) */
|
|
86
|
+
pathIndices: number[];
|
|
87
|
+
/** Optional root for backward compatibility */
|
|
88
|
+
root?: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Transfer recipient - used in privateTransfer
|
|
92
|
+
*/
|
|
93
|
+
interface Transfer {
|
|
94
|
+
/** Recipient's Solana public key */
|
|
95
|
+
recipient: PublicKey;
|
|
96
|
+
/** Amount to send in lamports */
|
|
97
|
+
amount: number;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Type-safe array with maximum length constraint
|
|
101
|
+
* Used to enforce 1-5 recipients in privateTransfer
|
|
102
|
+
*/
|
|
103
|
+
type MaxLengthArray<T, Max extends number, A extends T[] = []> = A['length'] extends Max ? A : A | MaxLengthArray<T, Max, [T, ...A]>;
|
|
104
|
+
/**
|
|
105
|
+
* Result from a private transfer
|
|
106
|
+
*/
|
|
107
|
+
interface TransferResult {
|
|
108
|
+
/** Solana transaction signature */
|
|
109
|
+
signature: string;
|
|
110
|
+
/** Recipients and amounts that were sent */
|
|
111
|
+
outputs: Array<{
|
|
112
|
+
recipient: string;
|
|
113
|
+
amount: number;
|
|
114
|
+
}>;
|
|
115
|
+
/** Nullifier used (prevents double-spending) */
|
|
116
|
+
nullifier: string;
|
|
117
|
+
/** Merkle root that was proven against */
|
|
118
|
+
root: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Result from a deposit operation
|
|
122
|
+
*/
|
|
123
|
+
interface DepositResult {
|
|
124
|
+
/** The created note (save this securely!) */
|
|
125
|
+
note: CloakNote;
|
|
126
|
+
/** Solana transaction signature */
|
|
127
|
+
signature: string;
|
|
128
|
+
/** Leaf index in the Merkle tree */
|
|
129
|
+
leafIndex: number;
|
|
130
|
+
/** Current Merkle root */
|
|
131
|
+
root: string;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Configuration for the Cloak SDK
|
|
135
|
+
*/
|
|
136
|
+
interface CloakConfig {
|
|
137
|
+
/** Solana network */
|
|
138
|
+
network?: Network;
|
|
139
|
+
/**
|
|
140
|
+
* Keypair bytes for signing (deprecated - use wallet instead)
|
|
141
|
+
* @deprecated Use wallet parameter for better integration
|
|
142
|
+
*/
|
|
143
|
+
keypairBytes?: Uint8Array;
|
|
144
|
+
/**
|
|
145
|
+
* Wallet adapter for signing transactions
|
|
146
|
+
* Required unless using keypairBytes
|
|
147
|
+
*/
|
|
148
|
+
wallet?: WalletAdapter;
|
|
149
|
+
/**
|
|
150
|
+
* Cloak key pair for v2.0 features (note scanning, encryption)
|
|
151
|
+
* Optional but recommended for full functionality
|
|
152
|
+
*/
|
|
153
|
+
cloakKeys?: any;
|
|
154
|
+
/** Optional: Proof generation timeout in milliseconds (default: 5 minutes) */
|
|
155
|
+
proofTimeout?: number;
|
|
156
|
+
/** Optional: Program ID (defaults to Cloak mainnet program) */
|
|
157
|
+
programId?: PublicKey;
|
|
158
|
+
/** Optional: Pool account address (auto-derived from program ID if not provided) */
|
|
159
|
+
poolAddress?: PublicKey;
|
|
160
|
+
/** Optional: Merkle tree account address (auto-derived if not provided) */
|
|
161
|
+
merkleTreeAddress?: PublicKey;
|
|
162
|
+
/** Optional: Treasury account address (auto-derived if not provided) */
|
|
163
|
+
treasuryAddress?: PublicKey;
|
|
164
|
+
/**
|
|
165
|
+
* Enable debug logging with structured output similar to Rust tracing.
|
|
166
|
+
*
|
|
167
|
+
* When enabled, logs SDK operations with timestamps, module paths,
|
|
168
|
+
* and key-value pairs for context:
|
|
169
|
+
*
|
|
170
|
+
* ```
|
|
171
|
+
* 2026-01-23T00:51:46.489000Z INFO cloak::sdk: 📥 Deposit completed signature=42XB... leaf_index=757
|
|
172
|
+
* ```
|
|
173
|
+
*
|
|
174
|
+
* Can also be enabled via environment variable:
|
|
175
|
+
* - `CLOAK_DEBUG=1`
|
|
176
|
+
* - `DEBUG=cloak:*`
|
|
177
|
+
*
|
|
178
|
+
* Default: false
|
|
179
|
+
*/
|
|
180
|
+
debug?: boolean;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Deposit progress status
|
|
184
|
+
*/
|
|
185
|
+
type DepositStatus = "generating_note" | "awaiting_note_acknowledgment" | "note_saved" | "creating_transaction" | "simulating" | "sending" | "confirming" | "submitting_to_indexer" | "fetching_proof" | "complete";
|
|
186
|
+
/**
|
|
187
|
+
* Options for deposit operation
|
|
188
|
+
*/
|
|
189
|
+
interface DepositOptions {
|
|
190
|
+
/** Optional callback for progress updates with detailed status */
|
|
191
|
+
onProgress?: (status: DepositStatus | string, details?: {
|
|
192
|
+
message?: string;
|
|
193
|
+
step?: number;
|
|
194
|
+
totalSteps?: number;
|
|
195
|
+
retryAttempt?: number;
|
|
196
|
+
}) => void;
|
|
197
|
+
/** Callback when transaction is sent (before confirmation) */
|
|
198
|
+
onTransactionSent?: (signature: string) => void;
|
|
199
|
+
/** Callback when transaction is confirmed */
|
|
200
|
+
onConfirmed?: (signature: string, slot: number) => void;
|
|
201
|
+
/**
|
|
202
|
+
* CRITICAL: Callback when note is generated, BEFORE any on-chain transaction.
|
|
203
|
+
*
|
|
204
|
+
* This is your chance to safely persist the note. If you don't save the note
|
|
205
|
+
* and the deposit succeeds but the browser crashes, your funds could be lost!
|
|
206
|
+
*
|
|
207
|
+
* The callback receives the note with all secrets needed for withdrawal.
|
|
208
|
+
* The deposit will NOT proceed until this callback completes.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* onNoteGenerated: async (note) => {
|
|
213
|
+
* // Save to secure storage BEFORE deposit proceeds
|
|
214
|
+
* await localStorage.setItem(`pending_note_${note.commitment}`, JSON.stringify(note));
|
|
215
|
+
* // Or show user a modal to copy/download the note
|
|
216
|
+
* }
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
onNoteGenerated?: (note: CloakNote) => Promise<void> | void;
|
|
220
|
+
/**
|
|
221
|
+
* If true, require user to acknowledge the note before proceeding with deposit.
|
|
222
|
+
* When enabled with onNoteGenerated, the deposit will wait for the callback to complete.
|
|
223
|
+
* Default: true when onNoteGenerated is provided
|
|
224
|
+
*/
|
|
225
|
+
requireNoteAcknowledgment?: boolean;
|
|
226
|
+
/** Skip simulation (default: false) */
|
|
227
|
+
skipPreflight?: boolean;
|
|
228
|
+
/**
|
|
229
|
+
* Compute units to request.
|
|
230
|
+
* - If `optimizeCU` is true, this is ignored and CU is determined via simulation
|
|
231
|
+
* - Otherwise defaults to 40,000 (suitable for typical deposits)
|
|
232
|
+
*/
|
|
233
|
+
computeUnits?: number;
|
|
234
|
+
/**
|
|
235
|
+
* Enable simulation-based CU optimization.
|
|
236
|
+
* When true, simulates the transaction first to determine actual CU usage,
|
|
237
|
+
* then sets an optimal limit (simulated + 20% buffer).
|
|
238
|
+
*
|
|
239
|
+
* **Note: Only works in keypair mode (Node.js/scripts).**
|
|
240
|
+
* In wallet/browser mode, this is ignored because simulation would require
|
|
241
|
+
* the user to sign twice (simulation + actual tx) which is bad UX.
|
|
242
|
+
*
|
|
243
|
+
* Trade-offs:
|
|
244
|
+
* - ✅ Optimal block scheduling priority
|
|
245
|
+
* - ❌ Adds ~200-500ms latency (extra RPC call)
|
|
246
|
+
* - ❌ Only available in keypair mode
|
|
247
|
+
*
|
|
248
|
+
* Default: false (uses fixed 40K CU which is ~75% efficient for typical deposits)
|
|
249
|
+
*/
|
|
250
|
+
optimizeCU?: boolean;
|
|
251
|
+
/** Priority fee in micro-lamports (default: 10,000) */
|
|
252
|
+
priorityFee?: number;
|
|
253
|
+
/**
|
|
254
|
+
* Loaded accounts data size limit in bytes.
|
|
255
|
+
*
|
|
256
|
+
* Without this, Solana defaults to 64MB which incurs CU overhead
|
|
257
|
+
* (charged at 8 CU per 32KB). Setting a lower limit improves priority.
|
|
258
|
+
*
|
|
259
|
+
* **Note for Cloak deposits:**
|
|
260
|
+
* The Shield Pool program is ~104KB, so the minimum practical limit is ~128KB.
|
|
261
|
+
*
|
|
262
|
+
* Default: 256 * 1024 (256KB) - provides safety margin above program size.
|
|
263
|
+
* Set to 0 to disable (use Solana 64MB default).
|
|
264
|
+
*
|
|
265
|
+
* @see https://www.anza.xyz/blog/cu-optimization-with-setloadedaccountsdatasizelimit
|
|
266
|
+
*/
|
|
267
|
+
loadedAccountsDataSizeLimit?: number;
|
|
268
|
+
/**
|
|
269
|
+
* Optional: Encrypt output for specific recipient's view key
|
|
270
|
+
* If not provided, encrypts for the wallet's own view key (for self-scanning)
|
|
271
|
+
*/
|
|
272
|
+
recipientViewKey?: string;
|
|
273
|
+
/**
|
|
274
|
+
* Skip privacy warning on testnet (default: false)
|
|
275
|
+
* Warning: Only skip if you understand the privacy limitations
|
|
276
|
+
*/
|
|
277
|
+
skipPrivacyWarning?: boolean;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Options for private transfer/withdraw operation
|
|
281
|
+
*/
|
|
282
|
+
interface TransferOptions {
|
|
283
|
+
/**
|
|
284
|
+
* Optional callback for progress updates
|
|
285
|
+
* Note: relayFeeBps is automatically calculated from protocol fees
|
|
286
|
+
*/
|
|
287
|
+
onProgress?: (status: string) => void;
|
|
288
|
+
/** Optional callback for proof generation progress (0-100) */
|
|
289
|
+
onProofProgress?: (percent: number) => void;
|
|
290
|
+
/**
|
|
291
|
+
* Metadata bundle for compliance tracking.
|
|
292
|
+
* On first transaction, should include viewing_key for compliance registration.
|
|
293
|
+
*/
|
|
294
|
+
metadataBundle?: {
|
|
295
|
+
encrypted_user: string;
|
|
296
|
+
encrypted_compliance: string;
|
|
297
|
+
user_pubkey: string;
|
|
298
|
+
commitment: string;
|
|
299
|
+
timestamp: number;
|
|
300
|
+
tx_type?: ComplianceTxType;
|
|
301
|
+
viewing_key?: string;
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Options for withdrawal (convenience method with single recipient)
|
|
306
|
+
*/
|
|
307
|
+
interface WithdrawOptions extends TransferOptions {
|
|
308
|
+
/** Whether to withdraw full amount minus fees (default: true) */
|
|
309
|
+
withdrawAll?: boolean;
|
|
310
|
+
/** Specific amount to withdraw in lamports (if not withdrawing all) */
|
|
311
|
+
amount?: number;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Merkle root response from indexer
|
|
315
|
+
*/
|
|
316
|
+
interface MerkleRootResponse {
|
|
317
|
+
root: string;
|
|
318
|
+
next_index: number;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Transaction status from relay service
|
|
322
|
+
*/
|
|
323
|
+
interface TxStatus {
|
|
324
|
+
status: "pending" | "processing" | "completed" | "failed";
|
|
325
|
+
txId?: string;
|
|
326
|
+
error?: string;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Swap parameters for token swaps
|
|
330
|
+
*/
|
|
331
|
+
interface SwapParams {
|
|
332
|
+
/** Output token mint address */
|
|
333
|
+
output_mint: string;
|
|
334
|
+
/** Slippage tolerance in basis points (e.g., 100 = 1%) */
|
|
335
|
+
slippage_bps: number;
|
|
336
|
+
/** Minimum output amount in token's smallest unit */
|
|
337
|
+
min_output_amount: number;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Options for swap operation
|
|
341
|
+
*/
|
|
342
|
+
interface SwapOptions extends TransferOptions {
|
|
343
|
+
/** Output token mint address */
|
|
344
|
+
outputMint: string;
|
|
345
|
+
/** Slippage tolerance in basis points (default: 100 = 1%) */
|
|
346
|
+
slippageBps?: number;
|
|
347
|
+
/** Minimum output amount (will be calculated from quote if not provided) */
|
|
348
|
+
minOutputAmount?: number;
|
|
349
|
+
/** Optional callback to get swap quote */
|
|
350
|
+
getQuote?: (amountLamports: number, outputMint: string, slippageBps: number) => Promise<{
|
|
351
|
+
outAmount: number;
|
|
352
|
+
minOutputAmount: number;
|
|
353
|
+
}>;
|
|
354
|
+
/**
|
|
355
|
+
* Recipient's associated token account for the output token.
|
|
356
|
+
* If not provided, will be computed automatically (requires @solana/spl-token).
|
|
357
|
+
* For browser environments, it's recommended to compute this in the frontend
|
|
358
|
+
* where @solana/spl-token is properly bundled.
|
|
359
|
+
*/
|
|
360
|
+
recipientAta?: string;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Result from a swap operation
|
|
364
|
+
*/
|
|
365
|
+
interface SwapResult extends TransferResult {
|
|
366
|
+
/** Output token mint address */
|
|
367
|
+
outputMint: string;
|
|
368
|
+
/** Minimum output amount that was guaranteed */
|
|
369
|
+
minOutputAmount: number;
|
|
370
|
+
/** Actual output amount received (may be higher than min) */
|
|
371
|
+
actualOutputAmount?: number;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Cloak Key Hierarchy (v2.0)
|
|
376
|
+
*
|
|
377
|
+
* Implements view/spend key separation for privacy-preserving note scanning:
|
|
378
|
+
* - Master Seed → Spend Key → View Key → Public View Key
|
|
379
|
+
* - Enables note discovery without exposing spending authority
|
|
380
|
+
* - Compatible with v1.0 notes (backward compatible)
|
|
381
|
+
*/
|
|
382
|
+
interface MasterKey {
|
|
383
|
+
seed: Uint8Array;
|
|
384
|
+
seedHex: string;
|
|
385
|
+
}
|
|
386
|
+
interface SpendKey {
|
|
387
|
+
sk_spend: Uint8Array;
|
|
388
|
+
pk_spend: Uint8Array;
|
|
389
|
+
sk_spend_hex: string;
|
|
390
|
+
pk_spend_hex: string;
|
|
391
|
+
}
|
|
392
|
+
interface ViewKey {
|
|
393
|
+
vk_secret: Uint8Array;
|
|
394
|
+
pvk: Uint8Array;
|
|
395
|
+
vk_secret_hex: string;
|
|
396
|
+
pvk_hex: string;
|
|
397
|
+
}
|
|
398
|
+
interface CloakKeyPair {
|
|
399
|
+
master: MasterKey;
|
|
400
|
+
spend: SpendKey;
|
|
401
|
+
view: ViewKey;
|
|
402
|
+
}
|
|
403
|
+
interface EncryptedNote$1 {
|
|
404
|
+
ephemeral_pk: string;
|
|
405
|
+
ciphertext: string;
|
|
406
|
+
nonce: string;
|
|
407
|
+
}
|
|
408
|
+
interface NoteData {
|
|
409
|
+
amount: number;
|
|
410
|
+
r: string;
|
|
411
|
+
sk_spend: string;
|
|
412
|
+
commitment: string;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Generate a new master seed from secure randomness
|
|
416
|
+
*/
|
|
417
|
+
declare function generateMasterSeed(): MasterKey;
|
|
418
|
+
/**
|
|
419
|
+
* Derive spend key from master seed
|
|
420
|
+
*/
|
|
421
|
+
declare function deriveSpendKey(masterSeed: Uint8Array): SpendKey;
|
|
422
|
+
/**
|
|
423
|
+
* Derive view key from spend key
|
|
424
|
+
*/
|
|
425
|
+
declare function deriveViewKey(sk_spend: Uint8Array): ViewKey;
|
|
426
|
+
/**
|
|
427
|
+
* Generate complete key hierarchy from master seed
|
|
428
|
+
*/
|
|
429
|
+
declare function generateCloakKeys(masterSeed?: Uint8Array): CloakKeyPair;
|
|
430
|
+
/**
|
|
431
|
+
* Encrypt note data for a recipient using their public view key
|
|
432
|
+
*
|
|
433
|
+
* Uses X25519 ECDH + XSalsa20-Poly1305 authenticated encryption
|
|
434
|
+
*/
|
|
435
|
+
declare function encryptNoteForRecipient(noteData: NoteData, recipientPvk: Uint8Array): EncryptedNote$1;
|
|
436
|
+
/**
|
|
437
|
+
* Attempt to decrypt an encrypted note using view key
|
|
438
|
+
*
|
|
439
|
+
* Returns null if decryption fails (note doesn't belong to this wallet)
|
|
440
|
+
* Returns NoteData if successful
|
|
441
|
+
*/
|
|
442
|
+
declare function tryDecryptNote(encryptedNote: EncryptedNote$1, viewKey: ViewKey): NoteData | null;
|
|
443
|
+
/**
|
|
444
|
+
* Scan a batch of encrypted outputs and return notes belonging to this wallet
|
|
445
|
+
*/
|
|
446
|
+
declare function scanNotesForWallet(encryptedOutputs: string[], // Base64 encoded encrypted note JSON
|
|
447
|
+
viewKey: ViewKey): NoteData[];
|
|
448
|
+
/**
|
|
449
|
+
* Export keys for backup (WARNING: contains secrets!)
|
|
450
|
+
*/
|
|
451
|
+
declare function exportKeys(keys: CloakKeyPair): string;
|
|
452
|
+
/**
|
|
453
|
+
* Import keys from backup
|
|
454
|
+
*/
|
|
455
|
+
declare function importKeys(exported: string): CloakKeyPair;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Storage Interface
|
|
459
|
+
*
|
|
460
|
+
* Defines a pluggable storage interface for notes and keys.
|
|
461
|
+
* Applications can implement their own storage (localStorage, IndexedDB, file system, etc.)
|
|
462
|
+
*/
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Storage adapter interface
|
|
466
|
+
*
|
|
467
|
+
* Implement this interface to provide custom storage for notes and keys.
|
|
468
|
+
* The SDK will use this adapter for all persistence operations.
|
|
469
|
+
*/
|
|
470
|
+
interface StorageAdapter {
|
|
471
|
+
/**
|
|
472
|
+
* Save a note
|
|
473
|
+
*/
|
|
474
|
+
saveNote(note: CloakNote): Promise<void> | void;
|
|
475
|
+
/**
|
|
476
|
+
* Load all notes
|
|
477
|
+
*/
|
|
478
|
+
loadAllNotes(): Promise<CloakNote[]> | CloakNote[];
|
|
479
|
+
/**
|
|
480
|
+
* Update a note
|
|
481
|
+
*/
|
|
482
|
+
updateNote(commitment: string, updates: Partial<CloakNote>): Promise<void> | void;
|
|
483
|
+
/**
|
|
484
|
+
* Delete a note
|
|
485
|
+
*/
|
|
486
|
+
deleteNote(commitment: string): Promise<void> | void;
|
|
487
|
+
/**
|
|
488
|
+
* Clear all notes
|
|
489
|
+
*/
|
|
490
|
+
clearAllNotes(): Promise<void> | void;
|
|
491
|
+
/**
|
|
492
|
+
* Save wallet keys
|
|
493
|
+
*/
|
|
494
|
+
saveKeys(keys: CloakKeyPair): Promise<void> | void;
|
|
495
|
+
/**
|
|
496
|
+
* Load wallet keys
|
|
497
|
+
*/
|
|
498
|
+
loadKeys(): Promise<CloakKeyPair | null> | CloakKeyPair | null;
|
|
499
|
+
/**
|
|
500
|
+
* Delete wallet keys
|
|
501
|
+
*/
|
|
502
|
+
deleteKeys(): Promise<void> | void;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* In-memory storage adapter (default, no persistence)
|
|
506
|
+
*
|
|
507
|
+
* Useful for testing or when storage is handled externally
|
|
508
|
+
*/
|
|
509
|
+
declare class MemoryStorageAdapter implements StorageAdapter {
|
|
510
|
+
private notes;
|
|
511
|
+
private keys;
|
|
512
|
+
saveNote(note: CloakNote): void;
|
|
513
|
+
loadAllNotes(): CloakNote[];
|
|
514
|
+
updateNote(commitment: string, updates: Partial<CloakNote>): void;
|
|
515
|
+
deleteNote(commitment: string): void;
|
|
516
|
+
clearAllNotes(): void;
|
|
517
|
+
saveKeys(keys: CloakKeyPair): void;
|
|
518
|
+
loadKeys(): CloakKeyPair | null;
|
|
519
|
+
deleteKeys(): void;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Browser localStorage adapter (optional, for browser environments)
|
|
523
|
+
*
|
|
524
|
+
* Only use this if you're in a browser environment and want localStorage persistence.
|
|
525
|
+
* Import from a separate browser-specific module.
|
|
526
|
+
*/
|
|
527
|
+
declare class LocalStorageAdapter implements StorageAdapter {
|
|
528
|
+
private notesKey;
|
|
529
|
+
private keysKey;
|
|
530
|
+
constructor(notesKey?: string, keysKey?: string);
|
|
531
|
+
private getStorage;
|
|
532
|
+
saveNote(note: CloakNote): void;
|
|
533
|
+
loadAllNotes(): CloakNote[];
|
|
534
|
+
updateNote(commitment: string, updates: Partial<CloakNote>): void;
|
|
535
|
+
deleteNote(commitment: string): void;
|
|
536
|
+
clearAllNotes(): void;
|
|
537
|
+
saveKeys(keys: CloakKeyPair): void;
|
|
538
|
+
loadKeys(): CloakKeyPair | null;
|
|
539
|
+
deleteKeys(): void;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/** Default Cloak Program ID on Solana */
|
|
543
|
+
declare const CLOAK_PROGRAM_ID: PublicKey;
|
|
544
|
+
/**
|
|
545
|
+
* Main Cloak SDK
|
|
546
|
+
*
|
|
547
|
+
* Provides high-level API for interacting with the Cloak protocol,
|
|
548
|
+
* including deposits, withdrawals, and private transfers.
|
|
549
|
+
*
|
|
550
|
+
* Supports two modes:
|
|
551
|
+
* 1. Node.js mode with keypairBytes - for scripts and backend services
|
|
552
|
+
* 2. Wallet adapter mode - for browser applications with wallet integration
|
|
553
|
+
*/
|
|
554
|
+
declare class CloakSDK {
|
|
555
|
+
private config;
|
|
556
|
+
private keypair?;
|
|
557
|
+
private wallet?;
|
|
558
|
+
private cloakKeys?;
|
|
559
|
+
private relay;
|
|
560
|
+
private storage;
|
|
561
|
+
/**
|
|
562
|
+
* Create a new Cloak SDK client
|
|
563
|
+
*
|
|
564
|
+
* @param config - Client configuration
|
|
565
|
+
*
|
|
566
|
+
* @example Node.js mode (with keypair)
|
|
567
|
+
* ```typescript
|
|
568
|
+
* const sdk = new CloakSDK({
|
|
569
|
+
* keypairBytes: keypair.secretKey,
|
|
570
|
+
* network: "devnet"
|
|
571
|
+
* });
|
|
572
|
+
* ```
|
|
573
|
+
*
|
|
574
|
+
* @example Browser mode (with wallet adapter)
|
|
575
|
+
* ```typescript
|
|
576
|
+
* const sdk = new CloakSDK({
|
|
577
|
+
* wallet: walletAdapter,
|
|
578
|
+
* network: "devnet"
|
|
579
|
+
* });
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
582
|
+
constructor(config: {
|
|
583
|
+
/** Keypair bytes for signing (Node.js mode) */
|
|
584
|
+
keypairBytes?: Uint8Array;
|
|
585
|
+
/** Wallet adapter for signing (Browser mode) */
|
|
586
|
+
wallet?: WalletAdapter;
|
|
587
|
+
network?: Network;
|
|
588
|
+
cloakKeys?: CloakKeyPair;
|
|
589
|
+
storage?: StorageAdapter;
|
|
590
|
+
programId?: PublicKey;
|
|
591
|
+
relayUrl?: string;
|
|
592
|
+
/** Enable debug logging with structured output */
|
|
593
|
+
debug?: boolean;
|
|
594
|
+
});
|
|
595
|
+
/**
|
|
596
|
+
* Get the public key for deposits (from keypair or wallet)
|
|
597
|
+
*/
|
|
598
|
+
getPublicKey(): PublicKey;
|
|
599
|
+
/**
|
|
600
|
+
* Check if the SDK is using a wallet adapter
|
|
601
|
+
*/
|
|
602
|
+
isWalletMode(): boolean;
|
|
603
|
+
/**
|
|
604
|
+
* Deposit SOL into the Cloak protocol
|
|
605
|
+
*
|
|
606
|
+
* Creates a new note (or uses a provided one), submits a deposit transaction,
|
|
607
|
+
* and registers with the indexer.
|
|
608
|
+
*
|
|
609
|
+
* @param connection - Solana connection
|
|
610
|
+
* @param payer - Payer wallet with sendTransaction method
|
|
611
|
+
* @param amountOrNote - Amount in lamports OR an existing note to deposit
|
|
612
|
+
* @param options - Optional configuration
|
|
613
|
+
* @returns Deposit result with note and transaction info
|
|
614
|
+
*
|
|
615
|
+
* @example
|
|
616
|
+
* ```typescript
|
|
617
|
+
* // Generate and deposit in one step
|
|
618
|
+
* const result = await client.deposit(
|
|
619
|
+
* connection,
|
|
620
|
+
* wallet,
|
|
621
|
+
* 1_000_000_000,
|
|
622
|
+
* {
|
|
623
|
+
* onProgress: (status) => console.log(status)
|
|
624
|
+
* }
|
|
625
|
+
* );
|
|
626
|
+
*
|
|
627
|
+
* // Or deposit a pre-generated note
|
|
628
|
+
* const note = client.generateNote(1_000_000_000);
|
|
629
|
+
* const result = await client.deposit(connection, wallet, note);
|
|
630
|
+
* ```
|
|
631
|
+
*/
|
|
632
|
+
deposit(connection: Connection, amountOrNote: number | CloakNote, options?: DepositOptions): Promise<DepositResult>;
|
|
633
|
+
/**
|
|
634
|
+
* Private transfer with up to 5 recipients
|
|
635
|
+
*
|
|
636
|
+
* Handles the complete private transfer flow:
|
|
637
|
+
* 1. If note is not deposited, deposits it first and waits for confirmation
|
|
638
|
+
* 2. Generates a zero-knowledge proof
|
|
639
|
+
* 3. Submits the withdrawal via relay service to recipients
|
|
640
|
+
*
|
|
641
|
+
* This is the main method for performing private transfers - it handles everything!
|
|
642
|
+
*
|
|
643
|
+
* @param connection - Solana connection (required for deposit if not already deposited)
|
|
644
|
+
* @param payer - Payer wallet (required for deposit if not already deposited)
|
|
645
|
+
* @param note - Note to spend (can be deposited or not)
|
|
646
|
+
* @param recipients - Array of 1-5 recipients with amounts
|
|
647
|
+
* @param options - Optional configuration
|
|
648
|
+
* @returns Transfer result with signature and outputs
|
|
649
|
+
*
|
|
650
|
+
* @example
|
|
651
|
+
* ```typescript
|
|
652
|
+
* // Create a note (not deposited yet)
|
|
653
|
+
* const note = client.generateNote(1_000_000_000);
|
|
654
|
+
*
|
|
655
|
+
* // privateTransfer handles the full flow: deposit + withdraw
|
|
656
|
+
* const result = await client.privateTransfer(
|
|
657
|
+
* connection,
|
|
658
|
+
* wallet,
|
|
659
|
+
* note,
|
|
660
|
+
* [
|
|
661
|
+
* { recipient: new PublicKey("..."), amount: 500_000_000 },
|
|
662
|
+
* { recipient: new PublicKey("..."), amount: 492_500_000 }
|
|
663
|
+
* ],
|
|
664
|
+
* {
|
|
665
|
+
* relayFeeBps: 50, // 0.5%
|
|
666
|
+
* onProgress: (status) => console.log(status),
|
|
667
|
+
* onProofProgress: (pct) => console.log(`Proof: ${pct}%`)
|
|
668
|
+
* }
|
|
669
|
+
* );
|
|
670
|
+
* console.log(`Success! TX: ${result.signature}`);
|
|
671
|
+
* ```
|
|
672
|
+
*/
|
|
673
|
+
privateTransfer(connection: Connection, note: CloakNote, recipients: MaxLengthArray<Transfer, 5>, options?: TransferOptions): Promise<TransferResult>;
|
|
674
|
+
/**
|
|
675
|
+
* Withdraw to a single recipient
|
|
676
|
+
*
|
|
677
|
+
* Convenience method for withdrawing to one address.
|
|
678
|
+
* Handles the complete flow: deposits if needed, then withdraws.
|
|
679
|
+
*
|
|
680
|
+
* @param connection - Solana connection
|
|
681
|
+
* @param payer - Payer wallet
|
|
682
|
+
* @param note - Note to spend
|
|
683
|
+
* @param recipient - Recipient address
|
|
684
|
+
* @param options - Optional configuration
|
|
685
|
+
* @returns Transfer result
|
|
686
|
+
*
|
|
687
|
+
* @example
|
|
688
|
+
* ```typescript
|
|
689
|
+
* const note = client.generateNote(1_000_000_000);
|
|
690
|
+
* const result = await client.withdraw(
|
|
691
|
+
* connection,
|
|
692
|
+
* wallet,
|
|
693
|
+
* note,
|
|
694
|
+
* new PublicKey("..."),
|
|
695
|
+
* { withdrawAll: true }
|
|
696
|
+
* );
|
|
697
|
+
* ```
|
|
698
|
+
*/
|
|
699
|
+
withdraw(connection: Connection, note: CloakNote, recipient: PublicKey, options?: WithdrawOptions): Promise<TransferResult>;
|
|
700
|
+
/**
|
|
701
|
+
* Send SOL privately to multiple recipients
|
|
702
|
+
*
|
|
703
|
+
* Convenience method that wraps privateTransfer with a simpler API.
|
|
704
|
+
* Handles the complete flow: deposits if needed, then sends to recipients.
|
|
705
|
+
*
|
|
706
|
+
* @param connection - Solana connection
|
|
707
|
+
* @param note - Note to spend
|
|
708
|
+
* @param recipients - Array of 1-5 recipients with amounts
|
|
709
|
+
* @param options - Optional configuration
|
|
710
|
+
* @returns Transfer result
|
|
711
|
+
*
|
|
712
|
+
* @example
|
|
713
|
+
* ```typescript
|
|
714
|
+
* const note = client.generateNote(1_000_000_000);
|
|
715
|
+
* const result = await client.send(
|
|
716
|
+
* connection,
|
|
717
|
+
* note,
|
|
718
|
+
* [
|
|
719
|
+
* { recipient: new PublicKey("..."), amount: 500_000_000 },
|
|
720
|
+
* { recipient: new PublicKey("..."), amount: 492_500_000 }
|
|
721
|
+
* ]
|
|
722
|
+
* );
|
|
723
|
+
* ```
|
|
724
|
+
*/
|
|
725
|
+
send(connection: Connection, note: CloakNote, recipients: MaxLengthArray<Transfer, 5>, options?: TransferOptions): Promise<TransferResult>;
|
|
726
|
+
/**
|
|
727
|
+
* Swap SOL for tokens privately
|
|
728
|
+
*
|
|
729
|
+
* Withdraws SOL from a note and swaps it for tokens via the relay service.
|
|
730
|
+
* Handles the complete flow: deposits if needed, generates proof, and submits swap.
|
|
731
|
+
*
|
|
732
|
+
* @param connection - Solana connection
|
|
733
|
+
* @param note - Note to spend
|
|
734
|
+
* @param recipient - Recipient address (will receive tokens)
|
|
735
|
+
* @param options - Swap configuration
|
|
736
|
+
* @returns Swap result with transaction signature
|
|
737
|
+
*
|
|
738
|
+
* @example
|
|
739
|
+
* ```typescript
|
|
740
|
+
* const note = client.generateNote(1_000_000_000);
|
|
741
|
+
* const result = await client.swap(
|
|
742
|
+
* connection,
|
|
743
|
+
* note,
|
|
744
|
+
* new PublicKey("..."), // recipient
|
|
745
|
+
* {
|
|
746
|
+
* outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
|
|
747
|
+
* slippageBps: 100, // 1%
|
|
748
|
+
* getQuote: async (amount, mint, slippage) => {
|
|
749
|
+
* // Fetch quote from your swap API
|
|
750
|
+
* const quote = await fetchSwapQuote(amount, mint, slippage);
|
|
751
|
+
* return {
|
|
752
|
+
* outAmount: quote.outAmount,
|
|
753
|
+
* minOutputAmount: quote.minOutputAmount
|
|
754
|
+
* };
|
|
755
|
+
* }
|
|
756
|
+
* }
|
|
757
|
+
* );
|
|
758
|
+
* ```
|
|
759
|
+
*/
|
|
760
|
+
swap(connection: Connection, note: CloakNote, recipient: PublicKey, options: SwapOptions): Promise<SwapResult>;
|
|
761
|
+
/**
|
|
762
|
+
* Generate a new note without depositing
|
|
763
|
+
*
|
|
764
|
+
* @param amountLamports - Amount for the note
|
|
765
|
+
* @param useWalletKeys - Whether to use wallet keys (v2.0 recommended)
|
|
766
|
+
* @returns New note (not yet deposited)
|
|
767
|
+
*/
|
|
768
|
+
generateNote(amountLamports: number, useWalletKeys?: boolean): Promise<CloakNote>;
|
|
769
|
+
/**
|
|
770
|
+
* Parse a note from JSON string
|
|
771
|
+
*
|
|
772
|
+
* @param jsonString - JSON representation
|
|
773
|
+
* @returns Parsed note
|
|
774
|
+
*/
|
|
775
|
+
parseNote(jsonString: string): CloakNote;
|
|
776
|
+
/**
|
|
777
|
+
* Export a note to JSON string
|
|
778
|
+
*
|
|
779
|
+
* @param note - Note to export
|
|
780
|
+
* @param pretty - Format with indentation
|
|
781
|
+
* @returns JSON string
|
|
782
|
+
*/
|
|
783
|
+
exportNote(note: CloakNote, pretty?: boolean): string;
|
|
784
|
+
/**
|
|
785
|
+
* Check if a note is ready for withdrawal
|
|
786
|
+
*
|
|
787
|
+
* @param note - Note to check
|
|
788
|
+
* @returns True if withdrawable
|
|
789
|
+
*/
|
|
790
|
+
isWithdrawable(note: CloakNote): boolean;
|
|
791
|
+
/**
|
|
792
|
+
* Get Merkle proof for a leaf index directly from on-chain state
|
|
793
|
+
*
|
|
794
|
+
* @param connection - Solana connection
|
|
795
|
+
* @param leafIndex - Leaf index in tree
|
|
796
|
+
* @returns Merkle proof computed from on-chain data
|
|
797
|
+
*/
|
|
798
|
+
getMerkleProof(connection: Connection, leafIndex: number): Promise<MerkleProof>;
|
|
799
|
+
/**
|
|
800
|
+
* Get current Merkle root directly from on-chain state
|
|
801
|
+
*
|
|
802
|
+
* @param connection - Solana connection
|
|
803
|
+
* @returns Current root hash from on-chain tree
|
|
804
|
+
*/
|
|
805
|
+
getCurrentRoot(connection: Connection): Promise<string>;
|
|
806
|
+
/**
|
|
807
|
+
* Get transaction status from relay service
|
|
808
|
+
*
|
|
809
|
+
* @param requestId - Request ID from previous submission
|
|
810
|
+
* @returns Current status
|
|
811
|
+
*/
|
|
812
|
+
getTransactionStatus(requestId: string): Promise<TxStatus>;
|
|
813
|
+
/**
|
|
814
|
+
* Fetch and decrypt this user's transaction metadata history.
|
|
815
|
+
* DEPRECATED: This functionality is no longer supported
|
|
816
|
+
*/
|
|
817
|
+
getTransactionMetadata(_options?: {
|
|
818
|
+
_after?: number;
|
|
819
|
+
_before?: number;
|
|
820
|
+
}): Promise<TransactionMetadata[]>;
|
|
821
|
+
/**
|
|
822
|
+
* Load all notes from storage
|
|
823
|
+
*
|
|
824
|
+
* @returns Array of saved notes
|
|
825
|
+
*/
|
|
826
|
+
loadNotes(): Promise<CloakNote[]>;
|
|
827
|
+
/**
|
|
828
|
+
* Save a note to storage
|
|
829
|
+
*
|
|
830
|
+
* @param note - Note to save
|
|
831
|
+
*/
|
|
832
|
+
saveNote(note: CloakNote): Promise<void>;
|
|
833
|
+
/**
|
|
834
|
+
* Find a note by its commitment
|
|
835
|
+
*
|
|
836
|
+
* @param commitment - Commitment hash
|
|
837
|
+
* @returns Note if found
|
|
838
|
+
*/
|
|
839
|
+
findNote(commitment: string): Promise<CloakNote | undefined>;
|
|
840
|
+
/**
|
|
841
|
+
* Import wallet keys from JSON
|
|
842
|
+
*
|
|
843
|
+
* @param keysJson - JSON string containing keys
|
|
844
|
+
*/
|
|
845
|
+
importWalletKeys(keysJson: string): Promise<void>;
|
|
846
|
+
/**
|
|
847
|
+
* Export wallet keys to JSON
|
|
848
|
+
*
|
|
849
|
+
* WARNING: This exports secret keys! Store securely.
|
|
850
|
+
*
|
|
851
|
+
* @returns JSON string with keys
|
|
852
|
+
*/
|
|
853
|
+
exportWalletKeys(): string;
|
|
854
|
+
/**
|
|
855
|
+
* Get the configuration
|
|
856
|
+
*/
|
|
857
|
+
getConfig(): CloakConfig;
|
|
858
|
+
/**
|
|
859
|
+
* Wrap errors with better categorization and user-friendly messages
|
|
860
|
+
*
|
|
861
|
+
* @private
|
|
862
|
+
*/
|
|
863
|
+
private wrapError;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Serialize a note to JSON string
|
|
868
|
+
*
|
|
869
|
+
* @param note - Note to serialize
|
|
870
|
+
* @param pretty - Whether to format with indentation (default: false)
|
|
871
|
+
* @returns JSON string
|
|
872
|
+
*
|
|
873
|
+
* @example
|
|
874
|
+
* ```typescript
|
|
875
|
+
* const json = serializeNote(note, true);
|
|
876
|
+
* console.log(json);
|
|
877
|
+
* // Or save to file, copy to clipboard, etc.
|
|
878
|
+
* ```
|
|
879
|
+
*/
|
|
880
|
+
declare function serializeNote(note: CloakNote, pretty?: boolean): string;
|
|
881
|
+
/**
|
|
882
|
+
* Export note as downloadable JSON (browser only)
|
|
883
|
+
*
|
|
884
|
+
* @param note - Note to export
|
|
885
|
+
* @param filename - Optional custom filename
|
|
886
|
+
*/
|
|
887
|
+
declare function downloadNote(note: CloakNote, filename?: string): void;
|
|
888
|
+
/**
|
|
889
|
+
* Copy note to clipboard as JSON (browser only)
|
|
890
|
+
*
|
|
891
|
+
* @param note - Note to copy
|
|
892
|
+
* @returns Promise that resolves when copied
|
|
893
|
+
*/
|
|
894
|
+
declare function copyNoteToClipboard(note: CloakNote): Promise<void>;
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* Fee calculation utilities for Cloak Protocol
|
|
898
|
+
*
|
|
899
|
+
* The protocol charges a fixed fee plus a variable percentage fee
|
|
900
|
+
* to prevent sybil attacks and cover operational costs.
|
|
901
|
+
*
|
|
902
|
+
* IMPORTANT: These constants are the single source of truth for fee calculations.
|
|
903
|
+
* When updating fees, only change these values - all other code should import from here.
|
|
904
|
+
*/
|
|
905
|
+
/** Lamports per SOL */
|
|
906
|
+
declare const LAMPORTS_PER_SOL = 1000000000;
|
|
907
|
+
/** Fixed fee: 0.005 SOL (5M lamports) */
|
|
908
|
+
declare const FIXED_FEE_LAMPORTS = 5000000;
|
|
909
|
+
/** Variable fee numerator (3 = 0.3%) */
|
|
910
|
+
declare const VARIABLE_FEE_NUMERATOR = 3;
|
|
911
|
+
/** Variable fee denominator (1000 = divide by 1000) */
|
|
912
|
+
declare const VARIABLE_FEE_DENOMINATOR = 1000;
|
|
913
|
+
/** Variable fee rate as decimal: 0.3% = 0.003 */
|
|
914
|
+
declare const VARIABLE_FEE_RATE: number;
|
|
915
|
+
/** Minimum deposit amount to prevent dust/UX footguns (0.01 SOL). */
|
|
916
|
+
declare const MIN_DEPOSIT_LAMPORTS = 10000000;
|
|
917
|
+
/**
|
|
918
|
+
* Calculate the total protocol fee for a given amount
|
|
919
|
+
*
|
|
920
|
+
* Formula: FIXED_FEE + floor((amount * VARIABLE_FEE_NUMERATOR) / VARIABLE_FEE_DENOMINATOR)
|
|
921
|
+
*
|
|
922
|
+
* @param amountLamports - Amount in lamports
|
|
923
|
+
* @returns Total fee in lamports
|
|
924
|
+
*
|
|
925
|
+
* @example
|
|
926
|
+
* ```typescript
|
|
927
|
+
* const fee = calculateFee(1_000_000_000); // 1 SOL
|
|
928
|
+
* // Returns: 5_000_000 (fixed) + 3_000_000 (0.3%) = 8_000_000 lamports
|
|
929
|
+
* ```
|
|
930
|
+
*/
|
|
931
|
+
declare function calculateFee(amountLamports: number): number;
|
|
932
|
+
/**
|
|
933
|
+
* Bigint version of calculateFee (for UTXO flows that use bigint lamports).
|
|
934
|
+
*/
|
|
935
|
+
declare function calculateFeeBigint(amountLamports: bigint): bigint;
|
|
936
|
+
/**
|
|
937
|
+
* Returns true if a withdrawal amount can pay fees and still leave >0 lamports.
|
|
938
|
+
* (On-chain uses the same integer math and enforces this as well.)
|
|
939
|
+
*/
|
|
940
|
+
declare function isWithdrawAmountSufficient(amountLamports: bigint): boolean;
|
|
941
|
+
/**
|
|
942
|
+
* Calculate the distributable amount after protocol fees
|
|
943
|
+
*
|
|
944
|
+
* This is the amount available to send to recipients.
|
|
945
|
+
*
|
|
946
|
+
* @param amountLamports - Total note amount in lamports
|
|
947
|
+
* @returns Amount available for recipients in lamports
|
|
948
|
+
*
|
|
949
|
+
* @example
|
|
950
|
+
* ```typescript
|
|
951
|
+
* const distributable = getDistributableAmount(1_000_000_000);
|
|
952
|
+
* // Returns: 1_000_000_000 - 7_500_000 = 992_500_000 lamports
|
|
953
|
+
* ```
|
|
954
|
+
*/
|
|
955
|
+
declare function getDistributableAmount(amountLamports: number): number;
|
|
956
|
+
/**
|
|
957
|
+
* Format lamports as SOL string
|
|
958
|
+
*
|
|
959
|
+
* @param lamports - Amount in lamports
|
|
960
|
+
* @param decimals - Number of decimal places (default: 9)
|
|
961
|
+
* @returns Formatted string (e.g., "1.000000000")
|
|
962
|
+
*
|
|
963
|
+
* @example
|
|
964
|
+
* ```typescript
|
|
965
|
+
* formatAmount(1_000_000_000); // "1.000000000"
|
|
966
|
+
* formatAmount(1_500_000_000); // "1.500000000"
|
|
967
|
+
* formatAmount(123_456_789, 4); // "0.1235"
|
|
968
|
+
* ```
|
|
969
|
+
*/
|
|
970
|
+
declare function formatAmount(lamports: number, decimals?: number): string;
|
|
971
|
+
/**
|
|
972
|
+
* Parse SOL string to lamports
|
|
973
|
+
*
|
|
974
|
+
* @param sol - SOL amount as string (e.g., "1.5")
|
|
975
|
+
* @returns Amount in lamports
|
|
976
|
+
* @throws Error if invalid format
|
|
977
|
+
*
|
|
978
|
+
* @example
|
|
979
|
+
* ```typescript
|
|
980
|
+
* parseAmount("1.5"); // 1_500_000_000
|
|
981
|
+
* parseAmount("0.001"); // 1_000_000
|
|
982
|
+
* ```
|
|
983
|
+
*/
|
|
984
|
+
declare function parseAmount(sol: string): number;
|
|
985
|
+
/**
|
|
986
|
+
* Validate that outputs sum equals expected amount
|
|
987
|
+
*
|
|
988
|
+
* @param outputs - Array of output amounts
|
|
989
|
+
* @param expectedTotal - Expected total amount
|
|
990
|
+
* @returns True if amounts match
|
|
991
|
+
*/
|
|
992
|
+
declare function validateOutputsSum(outputs: Array<{
|
|
993
|
+
amount: number;
|
|
994
|
+
}>, expectedTotal: number): boolean;
|
|
995
|
+
/**
|
|
996
|
+
* Calculate relay fee from basis points
|
|
997
|
+
*
|
|
998
|
+
* @param amountLamports - Amount in lamports
|
|
999
|
+
* @param feeBps - Fee in basis points (100 bps = 1%)
|
|
1000
|
+
* @returns Relay fee in lamports
|
|
1001
|
+
*
|
|
1002
|
+
* @example
|
|
1003
|
+
* ```typescript
|
|
1004
|
+
* calculateRelayFee(1_000_000_000, 50); // 0.5% = 5_000_000 lamports
|
|
1005
|
+
* ```
|
|
1006
|
+
*/
|
|
1007
|
+
declare function calculateRelayFee(amountLamports: number, feeBps: number): number;
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* Note Manager
|
|
1011
|
+
*
|
|
1012
|
+
* Standalone note management - no browser dependencies.
|
|
1013
|
+
* Storage is handled externally via StorageAdapter.
|
|
1014
|
+
*
|
|
1015
|
+
* Core functionality:
|
|
1016
|
+
* - Generate notes (v1.0 and v2.0)
|
|
1017
|
+
* - Parse and validate notes
|
|
1018
|
+
* - Note utilities (formatting, fees, etc.)
|
|
1019
|
+
* - Key management (without storage)
|
|
1020
|
+
*/
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* Generate a new note without wallet keys (legacy v1.0)
|
|
1024
|
+
* Uses Poseidon hashing to match circuit implementation
|
|
1025
|
+
* @deprecated Use generateNoteFromWallet instead for enhanced security
|
|
1026
|
+
*/
|
|
1027
|
+
declare function generateNote(amountLamports: number, network?: Network): Promise<CloakNote>;
|
|
1028
|
+
/**
|
|
1029
|
+
* Generate a note using wallet's spend key (v2.0 recommended)
|
|
1030
|
+
* Uses Poseidon hashing to match circuit implementation
|
|
1031
|
+
*/
|
|
1032
|
+
declare function generateNoteFromWallet(amountLamports: number, keys: CloakKeyPair, network?: Network): Promise<CloakNote>;
|
|
1033
|
+
/**
|
|
1034
|
+
* Parse and validate a note from JSON string
|
|
1035
|
+
*/
|
|
1036
|
+
declare function parseNote(jsonString: string): CloakNote;
|
|
1037
|
+
/**
|
|
1038
|
+
* Export note to JSON string
|
|
1039
|
+
*/
|
|
1040
|
+
declare function exportNote(note: CloakNote, pretty?: boolean): string;
|
|
1041
|
+
/**
|
|
1042
|
+
* Check if a note is withdrawable (has been deposited)
|
|
1043
|
+
* Note: merkleProof is optional - it may be fetched lazily at withdrawal time
|
|
1044
|
+
*/
|
|
1045
|
+
declare function isWithdrawable(note: CloakNote): boolean;
|
|
1046
|
+
/**
|
|
1047
|
+
* Update note with deposit information
|
|
1048
|
+
* Returns a new note object with deposit info added
|
|
1049
|
+
*/
|
|
1050
|
+
declare function updateNoteWithDeposit(note: CloakNote, depositInfo: {
|
|
1051
|
+
signature: string;
|
|
1052
|
+
slot: number;
|
|
1053
|
+
leafIndex: number;
|
|
1054
|
+
root: string;
|
|
1055
|
+
merkleProof?: {
|
|
1056
|
+
pathElements: string[];
|
|
1057
|
+
pathIndices: number[];
|
|
1058
|
+
};
|
|
1059
|
+
}): CloakNote;
|
|
1060
|
+
/**
|
|
1061
|
+
* Find note by commitment from an array
|
|
1062
|
+
*/
|
|
1063
|
+
declare function findNoteByCommitment(notes: CloakNote[], commitment: string): CloakNote | undefined;
|
|
1064
|
+
/**
|
|
1065
|
+
* Filter notes by network
|
|
1066
|
+
*/
|
|
1067
|
+
declare function filterNotesByNetwork(notes: CloakNote[], network: Network): CloakNote[];
|
|
1068
|
+
/**
|
|
1069
|
+
* Filter notes that can be withdrawn
|
|
1070
|
+
*/
|
|
1071
|
+
declare function filterWithdrawableNotes(notes: CloakNote[]): CloakNote[];
|
|
1072
|
+
/**
|
|
1073
|
+
* Export keys to JSON string
|
|
1074
|
+
* WARNING: This exports secret keys! Store securely.
|
|
1075
|
+
*/
|
|
1076
|
+
declare function exportWalletKeys(keys: CloakKeyPair): string;
|
|
1077
|
+
/**
|
|
1078
|
+
* Import keys from JSON string
|
|
1079
|
+
*/
|
|
1080
|
+
declare function importWalletKeys(keysJson: string): CloakKeyPair;
|
|
1081
|
+
/**
|
|
1082
|
+
* Get public view key from keys
|
|
1083
|
+
*/
|
|
1084
|
+
declare function getPublicViewKey(keys: CloakKeyPair): string;
|
|
1085
|
+
/**
|
|
1086
|
+
* Get view key from keys
|
|
1087
|
+
*/
|
|
1088
|
+
declare function getViewKey(keys: CloakKeyPair): ViewKey;
|
|
1089
|
+
/**
|
|
1090
|
+
* Get recipient amount after fees
|
|
1091
|
+
*/
|
|
1092
|
+
declare function getRecipientAmount(amountLamports: number): number;
|
|
1093
|
+
|
|
1094
|
+
interface ViewingKeyPair {
|
|
1095
|
+
privateKey: Uint8Array;
|
|
1096
|
+
publicKey: Uint8Array;
|
|
1097
|
+
}
|
|
1098
|
+
/** Zcash-style expanded spend key: ask (auth), nsk (nullifier/nk), ovk (outgoing view) */
|
|
1099
|
+
interface ExpandedSpendKey {
|
|
1100
|
+
ask: Uint8Array;
|
|
1101
|
+
nsk: Uint8Array;
|
|
1102
|
+
ovk: Uint8Array;
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Expand spend key into (ask, nsk, ovk) — Zcash-style.
|
|
1106
|
+
* - ask: spend authorization (future)
|
|
1107
|
+
* - nsk: base for incoming viewing (nk) — chain note decryption
|
|
1108
|
+
* - ovk: outgoing viewing (future)
|
|
1109
|
+
*/
|
|
1110
|
+
declare function expandSpendKey(skSpend: Uint8Array): ExpandedSpendKey;
|
|
1111
|
+
/**
|
|
1112
|
+
* Derive chain note viewing key from nk (Zcash-style IVK component).
|
|
1113
|
+
* Used for trial-decrypting incoming chain notes.
|
|
1114
|
+
*
|
|
1115
|
+
* @param nk 32-byte nk (from expandSpendKey(...).nsk — the incoming view base)
|
|
1116
|
+
*/
|
|
1117
|
+
declare function deriveViewingKeyFromNk(nk: Uint8Array): ViewingKeyPair;
|
|
1118
|
+
/**
|
|
1119
|
+
* Derive diversifier for per-output chain note encryption (Phase 3).
|
|
1120
|
+
* d = BLAKE3("cloak_div_v1" || nk || commitmentHex || outputIndex)[0:11]
|
|
1121
|
+
*/
|
|
1122
|
+
declare function deriveDiversifier(nk: Uint8Array, commitmentHex: string, outputIndex: number): Uint8Array;
|
|
1123
|
+
/**
|
|
1124
|
+
* Derive per-output viewing key pair from nk + diversifier (Phase 3).
|
|
1125
|
+
* sk_d = BLAKE3("cloak_sk_d_v1" || nk || d) → clamp → X25519 keypair
|
|
1126
|
+
*/
|
|
1127
|
+
declare function deriveDiversifiedViewingKey(nk: Uint8Array, diversifier: Uint8Array): ViewingKeyPair;
|
|
1128
|
+
/**
|
|
1129
|
+
* Derive chain note viewing key from spend key (Zcash-style).
|
|
1130
|
+
* Expands to (ask, nsk, ovk) and uses nsk (nk) for chain note decryption.
|
|
1131
|
+
*/
|
|
1132
|
+
declare function deriveViewingKeyFromSpendKey(skSpend: Uint8Array): ViewingKeyPair;
|
|
1133
|
+
/**
|
|
1134
|
+
* Derive chain note viewing key from UTXO private key (Zcash-style).
|
|
1135
|
+
* New UTXO (new keypair) => new viewing key.
|
|
1136
|
+
*
|
|
1137
|
+
* @param utxoPrivateKey UTXO keypair.privateKey (Poseidon field bigint)
|
|
1138
|
+
*/
|
|
1139
|
+
declare function deriveViewingKeyFromUtxoPrivateKey(utxoPrivateKey: bigint): ViewingKeyPair;
|
|
1140
|
+
/**
|
|
1141
|
+
* Get nk (incoming viewing base) from UTXO private key for Phase 3 diversified chain notes.
|
|
1142
|
+
*/
|
|
1143
|
+
declare function getNkFromUtxoPrivateKey(utxoPrivateKey: bigint): Uint8Array;
|
|
1144
|
+
/**
|
|
1145
|
+
* Generate a random viewing key pair (for tests/examples that need ephemeral keys).
|
|
1146
|
+
* Uses deriveViewingKeyFromSpendKey with random bytes.
|
|
1147
|
+
*/
|
|
1148
|
+
declare function generateViewingKeyPair(): ViewingKeyPair;
|
|
1149
|
+
/**
|
|
1150
|
+
* Derive the user-specific scalar from the relay-provided compliance master public key.
|
|
1151
|
+
*/
|
|
1152
|
+
declare function deriveUserComplianceScalar(masterCompliancePublicKey: Uint8Array, userPublicKey: PublicKey): Promise<Uint8Array>;
|
|
1153
|
+
/**
|
|
1154
|
+
* Derive a per-user compliance public key from the relay's master compliance public key.
|
|
1155
|
+
*
|
|
1156
|
+
* Formula:
|
|
1157
|
+
* - factor = Poseidon(master_compliance_public_key, user_wallet_pubkey)
|
|
1158
|
+
* - user_compliance_public = X25519(factor, master_compliance_public_key)
|
|
1159
|
+
*/
|
|
1160
|
+
declare function deriveUserCompliancePublicKey(masterCompliancePublicKey: Uint8Array, userPublicKey: PublicKey): Promise<Uint8Array>;
|
|
1161
|
+
/**
|
|
1162
|
+
* Legacy sign-in message retained for wallet-seed derivation compatibility in web/examples.
|
|
1163
|
+
* Viewing-key registration auth now uses one-time relay challenge messages.
|
|
1164
|
+
*/
|
|
1165
|
+
declare const SIGN_IN_MESSAGE = "Cloak: Sign in\n\nSign this message to securely access your Cloak account.\nThis does NOT authorize any transaction or spend any funds.";
|
|
1166
|
+
/**
|
|
1167
|
+
* Register nk (Phase 3) with relay for compliance scanning.
|
|
1168
|
+
* Relay stores nk and derives sk_d per note when exporting.
|
|
1169
|
+
* Registration is authenticated via one-time nonce challenge.
|
|
1170
|
+
*/
|
|
1171
|
+
declare function registerViewingKey(relayUrl: string, userPubkey: PublicKey, nk: Uint8Array, signMessage: (message: Uint8Array) => Promise<Uint8Array>): Promise<void>;
|
|
1172
|
+
|
|
1173
|
+
interface EncryptMetadataContext {
|
|
1174
|
+
userPubkey?: PublicKey | string;
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Encrypt a metadata object under:
|
|
1178
|
+
* 1. User view key public key
|
|
1179
|
+
* 2. User-specific compliance public key
|
|
1180
|
+
*/
|
|
1181
|
+
declare function encryptTransactionMetadata(metadata: TransactionMetadata, userViewKeyPublic: Uint8Array, complianceKeyPublic: Uint8Array, context?: EncryptMetadataContext): Promise<EncryptedMetadataBundle>;
|
|
1182
|
+
/**
|
|
1183
|
+
* Encrypt metadata using viewing key for both user and compliance.
|
|
1184
|
+
* This is used in the new viewing key-based compliance flow.
|
|
1185
|
+
*
|
|
1186
|
+
* @param metadata - Transaction metadata to encrypt
|
|
1187
|
+
* @param viewingKeyPrivate - The user's viewing key private key (32 bytes)
|
|
1188
|
+
* @param userPubkey - The user's wallet public key
|
|
1189
|
+
* @returns Encrypted metadata bundle
|
|
1190
|
+
*/
|
|
1191
|
+
declare function encryptTransactionMetadataBundle(metadata: TransactionMetadata, viewingKeyPrivate: Uint8Array, userPubkey: PublicKey): Promise<{
|
|
1192
|
+
encrypted_user: string;
|
|
1193
|
+
encrypted_compliance: string;
|
|
1194
|
+
user_pubkey: string;
|
|
1195
|
+
commitment: string;
|
|
1196
|
+
timestamp: number;
|
|
1197
|
+
tx_type?: string;
|
|
1198
|
+
}>;
|
|
1199
|
+
/**
|
|
1200
|
+
* Decrypt metadata with the direct recipient secret key.
|
|
1201
|
+
*
|
|
1202
|
+
* - For user blobs: pass `view.vk_secret`
|
|
1203
|
+
* - For compliance blobs: pass the derived per-user compliance private key
|
|
1204
|
+
*/
|
|
1205
|
+
declare function decryptTransactionMetadata(encrypted: string, viewKeySecret: Uint8Array): Promise<TransactionMetadata>;
|
|
1206
|
+
/**
|
|
1207
|
+
* Decrypt compliance metadata using the master compliance private key.
|
|
1208
|
+
*
|
|
1209
|
+
* This mirrors relay-side decryption:
|
|
1210
|
+
* shared = X25519(master_private, X25519(user_factor, ephemeral_pk))
|
|
1211
|
+
*/
|
|
1212
|
+
declare function decryptComplianceMetadataWithMasterKey(encrypted: string, masterCompliancePrivateKey: Uint8Array, masterCompliancePublicKey: Uint8Array, userPublicKey: PublicKey): Promise<TransactionMetadata>;
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Compute Poseidon hash of field elements
|
|
1216
|
+
* Uses circomlibjs Poseidon which matches the circuit implementation
|
|
1217
|
+
*/
|
|
1218
|
+
declare function poseidonHash(inputs: bigint[]): Promise<bigint>;
|
|
1219
|
+
/**
|
|
1220
|
+
* Split a 256-bit value into two 128-bit limbs
|
|
1221
|
+
* Returns [lo, hi] where lo is the lower 128 bits
|
|
1222
|
+
*/
|
|
1223
|
+
declare function splitTo2Limbs(value: bigint): [bigint, bigint];
|
|
1224
|
+
/**
|
|
1225
|
+
* Convert a PublicKey (32 bytes) to two 128-bit limbs
|
|
1226
|
+
* Uses duck typing to handle cross-module PublicKey instances
|
|
1227
|
+
*/
|
|
1228
|
+
declare function pubkeyToLimbs(pubkey: Uint8Array | PublicKey | {
|
|
1229
|
+
toBytes: () => Uint8Array;
|
|
1230
|
+
}): [bigint, bigint];
|
|
1231
|
+
/**
|
|
1232
|
+
* Compute Merkle root from leaf and path
|
|
1233
|
+
*
|
|
1234
|
+
* This matches the test implementation
|
|
1235
|
+
*
|
|
1236
|
+
* @param leaf - Leaf value as bigint
|
|
1237
|
+
* @param pathElements - Sibling hashes along the path
|
|
1238
|
+
* @param pathIndices - Path directions (0 = left, 1 = right)
|
|
1239
|
+
* @returns Merkle root as bigint
|
|
1240
|
+
*/
|
|
1241
|
+
declare function computeMerkleRoot(leaf: bigint, pathElements: bigint[], pathIndices: number[]): Promise<bigint>;
|
|
1242
|
+
/**
|
|
1243
|
+
* Convert hex string to bigint
|
|
1244
|
+
*/
|
|
1245
|
+
declare function hexToBigint$1(hex: string): bigint;
|
|
1246
|
+
/**
|
|
1247
|
+
* Compute commitment = Poseidon(amount, r0, r1, pk_spend)
|
|
1248
|
+
* where pk_spend = Poseidon(sk0, sk1)
|
|
1249
|
+
* (matching withdraw_regular.circom)
|
|
1250
|
+
*
|
|
1251
|
+
* This is the test-style function that takes bigints directly
|
|
1252
|
+
*
|
|
1253
|
+
* @param amount - Amount as bigint
|
|
1254
|
+
* @param r - Randomness as bigint
|
|
1255
|
+
* @param sk_spend - Spending secret key as bigint
|
|
1256
|
+
* @returns Commitment hash as bigint
|
|
1257
|
+
*/
|
|
1258
|
+
declare function computeCommitment$1(amount: bigint, r: bigint, sk_spend: bigint): Promise<bigint>;
|
|
1259
|
+
/**
|
|
1260
|
+
* Generate a Poseidon commitment for a note
|
|
1261
|
+
*
|
|
1262
|
+
* Formula: Poseidon(amount, r0, r1, pk_spend)
|
|
1263
|
+
* where pk_spend = Poseidon(sk0, sk1)
|
|
1264
|
+
*
|
|
1265
|
+
* This matches the withdraw_regular.circom circuit
|
|
1266
|
+
*
|
|
1267
|
+
* @param amountLamports - Amount in lamports
|
|
1268
|
+
* @param r - Randomness bytes (32 bytes)
|
|
1269
|
+
* @param skSpend - Spending secret key bytes (32 bytes)
|
|
1270
|
+
* @returns Commitment hash as bigint
|
|
1271
|
+
*/
|
|
1272
|
+
declare function generateCommitmentAsync(amountLamports: number, r: Uint8Array, skSpend: Uint8Array): Promise<bigint>;
|
|
1273
|
+
/**
|
|
1274
|
+
* Generate a Poseidon commitment for a note (sync wrapper)
|
|
1275
|
+
* Returns bytes instead of bigint for backward compatibility
|
|
1276
|
+
*
|
|
1277
|
+
* @deprecated Use generateCommitmentAsync instead
|
|
1278
|
+
*/
|
|
1279
|
+
declare function generateCommitment(_amountLamports: number, _r: Uint8Array, _skSpend: Uint8Array): Uint8Array;
|
|
1280
|
+
/**
|
|
1281
|
+
* Compute nullifier = Poseidon(sk0, sk1, leaf_index)
|
|
1282
|
+
* (matching withdraw_regular.circom)
|
|
1283
|
+
*
|
|
1284
|
+
* This is the test-style function that takes bigint directly
|
|
1285
|
+
*
|
|
1286
|
+
* @param sk_spend - Spending secret key as bigint
|
|
1287
|
+
* @param leafIndex - Index in the Merkle tree as bigint
|
|
1288
|
+
* @returns Nullifier as bigint
|
|
1289
|
+
*/
|
|
1290
|
+
declare function computeNullifier$1(sk_spend: bigint, leafIndex: bigint): Promise<bigint>;
|
|
1291
|
+
/**
|
|
1292
|
+
* Compute nullifier from spending key and leaf index
|
|
1293
|
+
*
|
|
1294
|
+
* Formula: Poseidon(sk0, sk1, leaf_index)
|
|
1295
|
+
*
|
|
1296
|
+
* This matches the circuit's nullifier computation
|
|
1297
|
+
*
|
|
1298
|
+
* @param skSpend - Spending secret key bytes (32 bytes) or hex string
|
|
1299
|
+
* @param leafIndex - Index in the Merkle tree
|
|
1300
|
+
* @returns Nullifier as bigint
|
|
1301
|
+
*/
|
|
1302
|
+
declare function computeNullifierAsync(skSpend: Uint8Array | string, leafIndex: number): Promise<bigint>;
|
|
1303
|
+
/**
|
|
1304
|
+
* Compute nullifier (sync wrapper for backward compatibility)
|
|
1305
|
+
* @deprecated Use computeNullifierAsync instead
|
|
1306
|
+
*/
|
|
1307
|
+
declare function computeNullifierSync(_skSpend: Uint8Array, _leafIndex: number): Uint8Array;
|
|
1308
|
+
/**
|
|
1309
|
+
* Compute outputs hash from recipients and amounts
|
|
1310
|
+
*
|
|
1311
|
+
* Formula: Chain of Poseidon(prev_hash, addr_lo, addr_hi, amount) for each active output
|
|
1312
|
+
*
|
|
1313
|
+
* This matches the withdraw_regular.circom circuit's outputs hash computation
|
|
1314
|
+
*
|
|
1315
|
+
* @param outputs - Array of {recipient: PublicKey, amount: number}
|
|
1316
|
+
* @returns Outputs hash as bigint
|
|
1317
|
+
*/
|
|
1318
|
+
declare function computeOutputsHashAsync(outputs: Array<{
|
|
1319
|
+
recipient: PublicKey;
|
|
1320
|
+
amount: number;
|
|
1321
|
+
}>): Promise<bigint>;
|
|
1322
|
+
/**
|
|
1323
|
+
* Compute outputs hash for withdraw_regular circuit
|
|
1324
|
+
* outputs_hash = chain of Poseidon(prev_hash, addr_lo, addr_hi, amount) for each active output
|
|
1325
|
+
*
|
|
1326
|
+
* This is the test-style function that takes raw limbs
|
|
1327
|
+
*
|
|
1328
|
+
* @param outAddr - Array of [lo, hi] limb pairs for each address (5x2 array)
|
|
1329
|
+
* @param outAmount - Array of amounts as bigints (5 elements)
|
|
1330
|
+
* @param outFlags - Array of flags (1 = active, 0 = inactive) (5 elements)
|
|
1331
|
+
* @returns Outputs hash as bigint
|
|
1332
|
+
*/
|
|
1333
|
+
declare function computeOutputsHash(outAddr: bigint[][], outAmount: bigint[], outFlags: number[]): Promise<bigint>;
|
|
1334
|
+
/**
|
|
1335
|
+
* Compute outputs hash (sync wrapper for backward compatibility)
|
|
1336
|
+
* @deprecated Use computeOutputsHashAsync instead
|
|
1337
|
+
*/
|
|
1338
|
+
declare function computeOutputsHashSync(_outputs: Array<{
|
|
1339
|
+
recipient: PublicKey;
|
|
1340
|
+
amount: number;
|
|
1341
|
+
}>): Uint8Array;
|
|
1342
|
+
/**
|
|
1343
|
+
* Compute outputs hash for withdraw_swap circuit
|
|
1344
|
+
* outputs_hash = Poseidon(input_mint limbs, output_mint limbs, recipient_ata limbs, min_output_amount, public_amount)
|
|
1345
|
+
*
|
|
1346
|
+
* This is the test-style function that takes raw limbs
|
|
1347
|
+
*
|
|
1348
|
+
* @param inputMintLimbs - Input mint address as [lo, hi] limbs
|
|
1349
|
+
* @param outputMintLimbs - Output mint address as [lo, hi] limbs
|
|
1350
|
+
* @param recipientAtaLimbs - Recipient ATA as [lo, hi] limbs
|
|
1351
|
+
* @param minOutputAmount - Minimum output amount as bigint
|
|
1352
|
+
* @param publicAmount - Public amount as bigint
|
|
1353
|
+
* @returns Outputs hash as bigint
|
|
1354
|
+
*/
|
|
1355
|
+
declare function computeSwapOutputsHash(inputMintLimbs: [bigint, bigint], outputMintLimbs: [bigint, bigint], recipientAtaLimbs: [bigint, bigint], minOutputAmount: bigint, publicAmount: bigint): Promise<bigint>;
|
|
1356
|
+
/**
|
|
1357
|
+
* Compute outputs hash for swap transactions
|
|
1358
|
+
*
|
|
1359
|
+
* Formula: Poseidon(input_mint_lo, input_mint_hi, output_mint_lo, output_mint_hi,
|
|
1360
|
+
* recipient_ata_lo, recipient_ata_hi, min_output_amount, public_amount)
|
|
1361
|
+
*
|
|
1362
|
+
* This matches the withdraw_swap.circom circuit
|
|
1363
|
+
*
|
|
1364
|
+
* @param inputMint - Input token mint address (SOL = SystemProgram)
|
|
1365
|
+
* @param outputMint - Output token mint address
|
|
1366
|
+
* @param recipientAta - Recipient's associated token account
|
|
1367
|
+
* @param minOutputAmount - Minimum output amount in token's smallest unit
|
|
1368
|
+
* @param amount - Note amount in lamports (public_amount)
|
|
1369
|
+
* @returns Outputs hash as bigint
|
|
1370
|
+
*/
|
|
1371
|
+
declare function computeSwapOutputsHashAsync(inputMint: PublicKey, outputMint: PublicKey, recipientAta: PublicKey, minOutputAmount: number, amount: number): Promise<bigint>;
|
|
1372
|
+
/**
|
|
1373
|
+
* Compute swap outputs hash (sync wrapper for backward compatibility)
|
|
1374
|
+
* @deprecated Use computeSwapOutputsHashAsync instead
|
|
1375
|
+
*/
|
|
1376
|
+
declare function computeSwapOutputsHashSync(_outputMint: PublicKey, _recipientAta: PublicKey, _minOutputAmount: number, _amount: number): Uint8Array;
|
|
1377
|
+
/**
|
|
1378
|
+
* Convert bigint to 32-byte big-endian Uint8Array
|
|
1379
|
+
*/
|
|
1380
|
+
declare function bigintToBytes32$1(n: bigint): Uint8Array;
|
|
1381
|
+
/**
|
|
1382
|
+
* Convert hex string to Uint8Array
|
|
1383
|
+
*
|
|
1384
|
+
* @param hex - Hex string (with or without 0x prefix)
|
|
1385
|
+
* @returns Decoded bytes
|
|
1386
|
+
*/
|
|
1387
|
+
declare function hexToBytes(hex: string): Uint8Array;
|
|
1388
|
+
/**
|
|
1389
|
+
* Convert Uint8Array to hex string
|
|
1390
|
+
*
|
|
1391
|
+
* @param bytes - Bytes to encode
|
|
1392
|
+
* @param prefix - Whether to include 0x prefix (default: false)
|
|
1393
|
+
* @returns Hex-encoded string
|
|
1394
|
+
*/
|
|
1395
|
+
declare function bytesToHex(bytes: Uint8Array, prefix?: boolean): string;
|
|
1396
|
+
/**
|
|
1397
|
+
* Generate random bytes using Web Crypto API
|
|
1398
|
+
*
|
|
1399
|
+
* @param length - Number of bytes to generate
|
|
1400
|
+
* @returns Random bytes
|
|
1401
|
+
*/
|
|
1402
|
+
declare function randomBytes(length: number): Uint8Array;
|
|
1403
|
+
/**
|
|
1404
|
+
* Validate a hex string format
|
|
1405
|
+
*
|
|
1406
|
+
* @param hex - Hex string to validate
|
|
1407
|
+
* @param expectedLength - Expected length in bytes (optional)
|
|
1408
|
+
* @returns True if valid hex string
|
|
1409
|
+
*/
|
|
1410
|
+
declare function isValidHex(hex: string, expectedLength?: number): boolean;
|
|
1411
|
+
/**
|
|
1412
|
+
* Groth16 proof structure from snarkjs
|
|
1413
|
+
*/
|
|
1414
|
+
interface Groth16Proof {
|
|
1415
|
+
pi_a: string[];
|
|
1416
|
+
pi_b: string[][];
|
|
1417
|
+
pi_c: string[];
|
|
1418
|
+
protocol: string;
|
|
1419
|
+
curve: string;
|
|
1420
|
+
}
|
|
1421
|
+
/**
|
|
1422
|
+
* Convert snarkjs Groth16 proof to 256-byte format for Solana (pinocchio-groth16 format)
|
|
1423
|
+
*
|
|
1424
|
+
* Based on pinocchio-groth16/src/proof_parser.rs convert_proof function:
|
|
1425
|
+
* - Proof_a: Must be NEGATED (as G1 point) and converted from LE to BE
|
|
1426
|
+
* - Proof_b: Converted from LE to BE (reversing each 64-byte chunk)
|
|
1427
|
+
* - Proof_c: Converted from LE to BE (reversing each 32-byte chunk)
|
|
1428
|
+
*
|
|
1429
|
+
* Format: pi_a (64) + pi_b (128) + pi_c (64) = 256 bytes
|
|
1430
|
+
*/
|
|
1431
|
+
declare function proofToBytes(proof: Groth16Proof): Uint8Array;
|
|
1432
|
+
/**
|
|
1433
|
+
* Build public inputs bytes for on-chain verification
|
|
1434
|
+
* Format: root (32) + nullifier (32) + outputs_hash (32) + public_amount (8) = 104 bytes
|
|
1435
|
+
*/
|
|
1436
|
+
declare function buildPublicInputsBytes(root: bigint, nullifier: bigint, outputsHash: bigint, publicAmount: bigint): Uint8Array;
|
|
1437
|
+
|
|
1438
|
+
/**
|
|
1439
|
+
* Validate a Solana public key
|
|
1440
|
+
*
|
|
1441
|
+
* @param address - Address string to validate
|
|
1442
|
+
* @returns True if valid Solana address
|
|
1443
|
+
*/
|
|
1444
|
+
declare function isValidSolanaAddress(address: string): boolean;
|
|
1445
|
+
/**
|
|
1446
|
+
* Validate a Cloak note structure
|
|
1447
|
+
*
|
|
1448
|
+
* @param note - Note object to validate
|
|
1449
|
+
* @throws Error if invalid
|
|
1450
|
+
*/
|
|
1451
|
+
declare function validateNote(note: any): asserts note is CloakNote;
|
|
1452
|
+
/**
|
|
1453
|
+
* Validate that a note is ready for withdrawal
|
|
1454
|
+
*
|
|
1455
|
+
* @param note - Note to validate
|
|
1456
|
+
* @throws Error if note cannot be used for withdrawal
|
|
1457
|
+
*/
|
|
1458
|
+
declare function validateWithdrawableNote(note: CloakNote): void;
|
|
1459
|
+
/**
|
|
1460
|
+
* Validate transfer recipients
|
|
1461
|
+
*
|
|
1462
|
+
* @param recipients - Array of transfers to validate
|
|
1463
|
+
* @param totalAmount - Total amount available
|
|
1464
|
+
* @throws Error if invalid
|
|
1465
|
+
*/
|
|
1466
|
+
declare function validateTransfers(recipients: Array<{
|
|
1467
|
+
recipient: PublicKey;
|
|
1468
|
+
amount: number;
|
|
1469
|
+
}>, totalAmount: number): void;
|
|
1470
|
+
|
|
1471
|
+
/**
|
|
1472
|
+
* Network Utilities
|
|
1473
|
+
*
|
|
1474
|
+
* Helper functions for network detection and configuration
|
|
1475
|
+
*/
|
|
1476
|
+
|
|
1477
|
+
/**
|
|
1478
|
+
* Detect network from RPC URL
|
|
1479
|
+
*
|
|
1480
|
+
* Attempts to detect the Solana network from common RPC URL patterns.
|
|
1481
|
+
* Falls back to devnet if unable to detect.
|
|
1482
|
+
*/
|
|
1483
|
+
declare function detectNetworkFromRpcUrl(rpcUrl?: string): Network;
|
|
1484
|
+
/**
|
|
1485
|
+
* Get the standard RPC URL for a network
|
|
1486
|
+
*/
|
|
1487
|
+
declare function getRpcUrlForNetwork(network: Network): string;
|
|
1488
|
+
/**
|
|
1489
|
+
* Validate RPC URL format
|
|
1490
|
+
*/
|
|
1491
|
+
declare function isValidRpcUrl(url: string): boolean;
|
|
1492
|
+
/**
|
|
1493
|
+
* Get explorer URL for a transaction
|
|
1494
|
+
*/
|
|
1495
|
+
declare function getExplorerUrl(signature: string, network?: Network): string;
|
|
1496
|
+
/**
|
|
1497
|
+
* Get explorer URL for an address
|
|
1498
|
+
*/
|
|
1499
|
+
declare function getAddressExplorerUrl(address: string, network?: Network): string;
|
|
1500
|
+
|
|
1501
|
+
/**
|
|
1502
|
+
* Error Utilities
|
|
1503
|
+
*
|
|
1504
|
+
* Helper functions for parsing and presenting user-friendly error messages.
|
|
1505
|
+
* This is the single source of truth for error codes and messages.
|
|
1506
|
+
*/
|
|
1507
|
+
|
|
1508
|
+
/**
|
|
1509
|
+
* Error thrown when the Merkle root used in a proof is no longer
|
|
1510
|
+
* in the on-chain root history (stale root).
|
|
1511
|
+
*
|
|
1512
|
+
* This happens when many deposits occur between proof generation and
|
|
1513
|
+
* transaction submission, pushing the proof's root out of history.
|
|
1514
|
+
*
|
|
1515
|
+
* The fix is to regenerate the proof with a fresh Merkle root.
|
|
1516
|
+
*/
|
|
1517
|
+
declare class RootNotFoundError extends Error {
|
|
1518
|
+
constructor(message?: string);
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Check if an error message indicates a RootNotFound (0x1001) error
|
|
1522
|
+
*/
|
|
1523
|
+
declare function isRootNotFoundError(error: unknown): boolean;
|
|
1524
|
+
/**
|
|
1525
|
+
* Parse a relay error response (e.g. 400 RootNotFound) and extract current_root when present.
|
|
1526
|
+
* The relay returns { error: true, message: "...", current_root?: string } for RootNotFound.
|
|
1527
|
+
*/
|
|
1528
|
+
declare function parseRelayErrorResponse(responseText: string): {
|
|
1529
|
+
isRootNotFound: boolean;
|
|
1530
|
+
currentRoot?: string;
|
|
1531
|
+
};
|
|
1532
|
+
/**
|
|
1533
|
+
* Shield Pool Program Error Codes
|
|
1534
|
+
*
|
|
1535
|
+
* Maps on-chain program error codes to user-friendly error messages.
|
|
1536
|
+
* These codes match the program's error enum.
|
|
1537
|
+
*/
|
|
1538
|
+
declare const ShieldPoolErrors: Record<number, string>;
|
|
1539
|
+
/**
|
|
1540
|
+
* Error categories for UI display
|
|
1541
|
+
*/
|
|
1542
|
+
type ErrorCategory = "wallet" | "network" | "validation" | "service" | "transaction" | "unknown";
|
|
1543
|
+
/**
|
|
1544
|
+
* Structured error result for UI
|
|
1545
|
+
*/
|
|
1546
|
+
interface UserFriendlyError {
|
|
1547
|
+
/** User-facing title */
|
|
1548
|
+
title: string;
|
|
1549
|
+
/** User-facing description */
|
|
1550
|
+
message: string;
|
|
1551
|
+
/** Error category for styling */
|
|
1552
|
+
category: ErrorCategory;
|
|
1553
|
+
/** Optional suggestion for the user */
|
|
1554
|
+
suggestion?: string;
|
|
1555
|
+
/** Whether the error is recoverable (user can retry) */
|
|
1556
|
+
recoverable: boolean;
|
|
1557
|
+
/** Original error for debugging (not shown to user) */
|
|
1558
|
+
originalError?: string;
|
|
1559
|
+
}
|
|
1560
|
+
/**
|
|
1561
|
+
* Parse any error and return a user-friendly error object
|
|
1562
|
+
*/
|
|
1563
|
+
declare function parseError(error: unknown): UserFriendlyError;
|
|
1564
|
+
/**
|
|
1565
|
+
* Parse transaction error and return user-friendly message
|
|
1566
|
+
*
|
|
1567
|
+
* Attempts to extract meaningful error information from various
|
|
1568
|
+
* error formats (program errors, RPC errors, custom errors)
|
|
1569
|
+
*/
|
|
1570
|
+
declare function parseTransactionError(error: any): string;
|
|
1571
|
+
/**
|
|
1572
|
+
* Create a CloakError with appropriate categorization
|
|
1573
|
+
*/
|
|
1574
|
+
declare function createCloakError(error: unknown, _context: string): CloakError;
|
|
1575
|
+
/**
|
|
1576
|
+
* Format error for logging
|
|
1577
|
+
*/
|
|
1578
|
+
declare function formatErrorForLogging(error: unknown): string;
|
|
1579
|
+
|
|
1580
|
+
/**
|
|
1581
|
+
* Structured Logger for Cloak SDK
|
|
1582
|
+
*
|
|
1583
|
+
* Provides structured logging similar to Rust tracing format:
|
|
1584
|
+
* 2026-01-23T00:51:46.489317Z INFO cloak::module: 📥 Message key=value
|
|
1585
|
+
*
|
|
1586
|
+
* Enable via:
|
|
1587
|
+
* - SDK config: new CloakSDK({ debug: true })
|
|
1588
|
+
* - Environment: CLOAK_DEBUG=1 or DEBUG=cloak:*
|
|
1589
|
+
*/
|
|
1590
|
+
type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR";
|
|
1591
|
+
/**
|
|
1592
|
+
* Enable or disable debug logging globally
|
|
1593
|
+
*/
|
|
1594
|
+
declare function setDebugMode(enabled: boolean): void;
|
|
1595
|
+
/**
|
|
1596
|
+
* Check if debug mode is enabled
|
|
1597
|
+
*/
|
|
1598
|
+
declare function isDebugEnabled(): boolean;
|
|
1599
|
+
/**
|
|
1600
|
+
* Logger interface
|
|
1601
|
+
*/
|
|
1602
|
+
interface Logger {
|
|
1603
|
+
debug: (message: string, kvPairs?: Record<string, unknown>) => void;
|
|
1604
|
+
info: (message: string, kvPairs?: Record<string, unknown>) => void;
|
|
1605
|
+
warn: (message: string, kvPairs?: Record<string, unknown>) => void;
|
|
1606
|
+
error: (message: string, kvPairs?: Record<string, unknown>) => void;
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* Create a logger for a specific module
|
|
1610
|
+
*
|
|
1611
|
+
* @param module - Module name (e.g., "cloak::sdk", "cloak::indexer")
|
|
1612
|
+
* @returns Logger instance with debug, info, warn, error methods
|
|
1613
|
+
*
|
|
1614
|
+
* @example
|
|
1615
|
+
* ```typescript
|
|
1616
|
+
* const log = createLogger("cloak::deposit");
|
|
1617
|
+
* log.info("Depositing", { amount: 100000000 });
|
|
1618
|
+
* // Output: 2026-01-23T00:51:46.489000Z INFO cloak::deposit: Depositing amount=100000000
|
|
1619
|
+
* ```
|
|
1620
|
+
*/
|
|
1621
|
+
declare function createLogger(module: string): Logger;
|
|
1622
|
+
/**
|
|
1623
|
+
* Measure and return duration of an async operation
|
|
1624
|
+
*
|
|
1625
|
+
* @param _logger - Logger instance (reserved for future debug logging)
|
|
1626
|
+
* @param _operation - Operation name (reserved for future debug logging)
|
|
1627
|
+
* @param fn - Async function to measure
|
|
1628
|
+
* @returns Result and duration in milliseconds
|
|
1629
|
+
*/
|
|
1630
|
+
declare function withTiming<T>(_logger: Logger, _operation: string, fn: () => Promise<T>): Promise<{
|
|
1631
|
+
result: T;
|
|
1632
|
+
durationMs: number;
|
|
1633
|
+
}>;
|
|
1634
|
+
/**
|
|
1635
|
+
* Format lamports as SOL with proper decimals
|
|
1636
|
+
*/
|
|
1637
|
+
declare function formatSol(lamports: number | bigint): string;
|
|
1638
|
+
/**
|
|
1639
|
+
* Truncate a string (useful for signatures, hashes)
|
|
1640
|
+
*/
|
|
1641
|
+
declare function truncate(str: string, len?: number): string;
|
|
1642
|
+
/**
|
|
1643
|
+
* Default SDK logger instance
|
|
1644
|
+
*/
|
|
1645
|
+
declare const sdkLogger: Logger;
|
|
1646
|
+
|
|
1647
|
+
/**
|
|
1648
|
+
* Result from submitting a withdrawal that includes the request ID
|
|
1649
|
+
* for potential recovery/resume scenarios
|
|
1650
|
+
*/
|
|
1651
|
+
interface WithdrawSubmissionResult {
|
|
1652
|
+
/** The relay request ID - persist this for recovery */
|
|
1653
|
+
requestId: string;
|
|
1654
|
+
/** The final transaction signature */
|
|
1655
|
+
signature: string;
|
|
1656
|
+
}
|
|
1657
|
+
/**
|
|
1658
|
+
* Relay Service Client
|
|
1659
|
+
*
|
|
1660
|
+
* Handles submission of withdrawal transactions through a relay service
|
|
1661
|
+
* that pays for transaction fees and submits the transaction on-chain.
|
|
1662
|
+
*/
|
|
1663
|
+
declare class RelayService {
|
|
1664
|
+
private baseUrl;
|
|
1665
|
+
/**
|
|
1666
|
+
* Create a new Relay Service client
|
|
1667
|
+
*
|
|
1668
|
+
* @param baseUrl - Relay service base URL
|
|
1669
|
+
*/
|
|
1670
|
+
constructor(baseUrl: string);
|
|
1671
|
+
/**
|
|
1672
|
+
* Submit a withdrawal transaction via relay
|
|
1673
|
+
*
|
|
1674
|
+
* The relay service will validate the proof, pay for transaction fees,
|
|
1675
|
+
* and submit the transaction on-chain.
|
|
1676
|
+
*
|
|
1677
|
+
* @param params - Withdrawal parameters
|
|
1678
|
+
* @param onStatusUpdate - Optional callback for status updates
|
|
1679
|
+
* @param onRequestId - CRITICAL: Callback when request_id is received.
|
|
1680
|
+
* Persist this ID to recover if browser crashes during polling.
|
|
1681
|
+
* @returns Transaction signature when completed
|
|
1682
|
+
*
|
|
1683
|
+
* @example
|
|
1684
|
+
* ```typescript
|
|
1685
|
+
* const signature = await relay.submitWithdraw({
|
|
1686
|
+
* proof: proofHex,
|
|
1687
|
+
* publicInputs: { root, nf, outputs_hash, amount },
|
|
1688
|
+
* outputs: [{ recipient: addr, amount: lamports }],
|
|
1689
|
+
* feeBps: 50
|
|
1690
|
+
* }, (status) => console.log(`Status: ${status}`),
|
|
1691
|
+
* (requestId) => localStorage.setItem('pending_withdraw', requestId));
|
|
1692
|
+
* console.log(`Transaction: ${signature}`);
|
|
1693
|
+
* ```
|
|
1694
|
+
*/
|
|
1695
|
+
submitWithdraw(params: {
|
|
1696
|
+
proof: string;
|
|
1697
|
+
publicInputs: {
|
|
1698
|
+
root: string;
|
|
1699
|
+
nf: string;
|
|
1700
|
+
outputs_hash: string;
|
|
1701
|
+
amount: number;
|
|
1702
|
+
};
|
|
1703
|
+
outputs: Array<{
|
|
1704
|
+
recipient: string;
|
|
1705
|
+
amount: number;
|
|
1706
|
+
}>;
|
|
1707
|
+
feeBps: number;
|
|
1708
|
+
metadataBundle?: EncryptedMetadataBundle;
|
|
1709
|
+
}, onStatusUpdate?: (status: string) => void, onRequestId?: (requestId: string) => void): Promise<string>;
|
|
1710
|
+
/**
|
|
1711
|
+
* Resume polling for a withdrawal that was previously started
|
|
1712
|
+
*
|
|
1713
|
+
* Use this after page reload to check status of a pending withdrawal.
|
|
1714
|
+
* The requestId should have been persisted via the onRequestId callback.
|
|
1715
|
+
*
|
|
1716
|
+
* @param requestId - Request ID from a previous submitWithdraw call
|
|
1717
|
+
* @param onStatusUpdate - Optional callback for status updates
|
|
1718
|
+
* @returns Transaction signature if completed, null if still pending/failed
|
|
1719
|
+
*
|
|
1720
|
+
* @example
|
|
1721
|
+
* ```typescript
|
|
1722
|
+
* // On page load, check for pending withdrawal
|
|
1723
|
+
* const pendingId = localStorage.getItem('pending_withdraw');
|
|
1724
|
+
* if (pendingId) {
|
|
1725
|
+
* const result = await relay.resumeWithdraw(pendingId);
|
|
1726
|
+
* if (result.status === 'completed') {
|
|
1727
|
+
* console.log('Withdrawal completed:', result.signature);
|
|
1728
|
+
* localStorage.removeItem('pending_withdraw');
|
|
1729
|
+
* }
|
|
1730
|
+
* }
|
|
1731
|
+
* ```
|
|
1732
|
+
*/
|
|
1733
|
+
resumeWithdraw(requestId: string, onStatusUpdate?: (status: string) => void): Promise<{
|
|
1734
|
+
status: 'completed' | 'failed' | 'pending';
|
|
1735
|
+
signature?: string;
|
|
1736
|
+
error?: string;
|
|
1737
|
+
}>;
|
|
1738
|
+
/**
|
|
1739
|
+
* Poll for withdrawal completion
|
|
1740
|
+
*
|
|
1741
|
+
* @param requestId - Request ID from relay service
|
|
1742
|
+
* @param onStatusUpdate - Optional callback for status updates
|
|
1743
|
+
* @returns Transaction signature when completed
|
|
1744
|
+
*/
|
|
1745
|
+
private pollForCompletion;
|
|
1746
|
+
/**
|
|
1747
|
+
* Submit a swap transaction via relay
|
|
1748
|
+
*
|
|
1749
|
+
* Similar to submitWithdraw but includes swap parameters for token swaps.
|
|
1750
|
+
* The relay service will validate the proof, execute the swap, pay for fees,
|
|
1751
|
+
* and submit the transaction on-chain.
|
|
1752
|
+
*
|
|
1753
|
+
* @param params - Swap parameters
|
|
1754
|
+
* @param onStatusUpdate - Optional callback for status updates
|
|
1755
|
+
* @returns Transaction signature when completed
|
|
1756
|
+
*
|
|
1757
|
+
* @example
|
|
1758
|
+
* ```typescript
|
|
1759
|
+
* const signature = await relay.submitSwap({
|
|
1760
|
+
* proof: proofHex,
|
|
1761
|
+
* publicInputs: { root, nf, outputs_hash, amount },
|
|
1762
|
+
* outputs: [{ recipient: addr, amount: lamports }],
|
|
1763
|
+
* feeBps: 50,
|
|
1764
|
+
* swap: {
|
|
1765
|
+
* output_mint: tokenMint.toBase58(),
|
|
1766
|
+
* slippage_bps: 100,
|
|
1767
|
+
* min_output_amount: minAmount
|
|
1768
|
+
* }
|
|
1769
|
+
* }, (status) => console.log(`Status: ${status}`));
|
|
1770
|
+
* console.log(`Transaction: ${signature}`);
|
|
1771
|
+
* ```
|
|
1772
|
+
*/
|
|
1773
|
+
submitSwap(params: {
|
|
1774
|
+
proof: string;
|
|
1775
|
+
publicInputs: {
|
|
1776
|
+
root: string;
|
|
1777
|
+
nf: string;
|
|
1778
|
+
outputs_hash: string;
|
|
1779
|
+
amount: number;
|
|
1780
|
+
};
|
|
1781
|
+
outputs: Array<{
|
|
1782
|
+
recipient: string;
|
|
1783
|
+
amount: number;
|
|
1784
|
+
}>;
|
|
1785
|
+
feeBps: number;
|
|
1786
|
+
swap: {
|
|
1787
|
+
output_mint: string;
|
|
1788
|
+
slippage_bps: number;
|
|
1789
|
+
min_output_amount: number;
|
|
1790
|
+
};
|
|
1791
|
+
metadataBundle?: EncryptedMetadataBundle;
|
|
1792
|
+
}, onStatusUpdate?: (status: string) => void, onRequestId?: (requestId: string) => void): Promise<string>;
|
|
1793
|
+
/**
|
|
1794
|
+
* Get transaction status
|
|
1795
|
+
*
|
|
1796
|
+
* @param requestId - Request ID from previous submission
|
|
1797
|
+
* @returns Current status
|
|
1798
|
+
*
|
|
1799
|
+
* @example
|
|
1800
|
+
* ```typescript
|
|
1801
|
+
* const status = await relay.getStatus(requestId);
|
|
1802
|
+
* console.log(`Status: ${status.status}`);
|
|
1803
|
+
* if (status.status === 'completed') {
|
|
1804
|
+
* console.log(`TX: ${status.txId}`);
|
|
1805
|
+
* }
|
|
1806
|
+
* ```
|
|
1807
|
+
*/
|
|
1808
|
+
getStatus(requestId: string): Promise<TxStatus>;
|
|
1809
|
+
/**
|
|
1810
|
+
* Register viewing key with relay for compliance decryption.
|
|
1811
|
+
* This is a one-time operation - the viewing key is stored by the relay.
|
|
1812
|
+
*
|
|
1813
|
+
* The user must sign a one-time relay challenge proving wallet ownership.
|
|
1814
|
+
*
|
|
1815
|
+
* @param userPubkey - User's wallet public key (base58)
|
|
1816
|
+
* @param viewingKey - Viewing key private key (32 bytes, hex encoded)
|
|
1817
|
+
* @param signMessage - Function to sign challenge message bytes
|
|
1818
|
+
*
|
|
1819
|
+
* @example
|
|
1820
|
+
* ```typescript
|
|
1821
|
+
* await relay.registerViewingKey(
|
|
1822
|
+
* userPublicKey.toBase58(),
|
|
1823
|
+
* viewingKeyHex,
|
|
1824
|
+
* signatureBase64
|
|
1825
|
+
* );
|
|
1826
|
+
* ```
|
|
1827
|
+
*/
|
|
1828
|
+
registerViewingKey(userPubkey: string, viewingKey: string, signMessage: (message: Uint8Array) => Promise<Uint8Array>): Promise<boolean>;
|
|
1829
|
+
/**
|
|
1830
|
+
* Fetch relay compliance master public key.
|
|
1831
|
+
* DEPRECATED: This endpoint is no longer used
|
|
1832
|
+
*/
|
|
1833
|
+
getCompliancePublicKey(): Promise<Uint8Array>;
|
|
1834
|
+
/**
|
|
1835
|
+
* Convert bytes to base64 string
|
|
1836
|
+
*/
|
|
1837
|
+
private bytesToBase64;
|
|
1838
|
+
/**
|
|
1839
|
+
* Sleep utility
|
|
1840
|
+
*/
|
|
1841
|
+
private sleep;
|
|
1842
|
+
private computeViewingKeyIdentifier;
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
/**
|
|
1846
|
+
* Risk Oracle Service
|
|
1847
|
+
*
|
|
1848
|
+
* Self-contained module for fetching Switchboard risk quote instructions
|
|
1849
|
+
* using the Range Risk API. Eliminates the need for an external web endpoint
|
|
1850
|
+
* (e.g. `/api/risk-quote`) by calling Switchboard directly from the SDK.
|
|
1851
|
+
*
|
|
1852
|
+
* Uses dynamic imports for @switchboard-xyz packages so they are only loaded
|
|
1853
|
+
* when fetchRiskQuoteIx is actually called — not at SDK import time. This
|
|
1854
|
+
* prevents the heavy Node.js-only Switchboard code from being bundled into
|
|
1855
|
+
* browser builds (Next.js, etc.).
|
|
1856
|
+
*
|
|
1857
|
+
* Usage:
|
|
1858
|
+
* const { instruction, queue } = await fetchRiskQuoteIx(connection, wallet, rangeApiKey);
|
|
1859
|
+
*/
|
|
1860
|
+
|
|
1861
|
+
/**
|
|
1862
|
+
* Fetch a Switchboard risk quote instruction directly from Range + Switchboard.
|
|
1863
|
+
*
|
|
1864
|
+
* This removes the need for an external `/api/risk-quote` endpoint. The SDK
|
|
1865
|
+
* calls Switchboard's crossbar oracle network directly with the Range API key.
|
|
1866
|
+
*
|
|
1867
|
+
* @param connection - Solana RPC connection
|
|
1868
|
+
* @param wallet - Depositor's public key (the wallet being risk-scored)
|
|
1869
|
+
* @param rangeApiKey - Range.org API key for the risk score lookup
|
|
1870
|
+
* @returns The Ed25519 sig-verify instruction to prepend at index 0, plus the queue pubkey
|
|
1871
|
+
*/
|
|
1872
|
+
declare function fetchRiskQuoteIx(connection: Connection, wallet: PublicKey, rangeApiKey: string): Promise<{
|
|
1873
|
+
instruction: TransactionInstruction;
|
|
1874
|
+
queue: PublicKey;
|
|
1875
|
+
}>;
|
|
1876
|
+
|
|
1877
|
+
/**
|
|
1878
|
+
* Encrypted Output Helpers
|
|
1879
|
+
*
|
|
1880
|
+
* Functions for creating encrypted outputs that enable note scanning
|
|
1881
|
+
*/
|
|
1882
|
+
|
|
1883
|
+
/**
|
|
1884
|
+
* Prepare encrypted output for scanning by wallet owner
|
|
1885
|
+
*
|
|
1886
|
+
* @param note - Note to encrypt
|
|
1887
|
+
* @param cloakKeys - Wallet's Cloak keys (for self-encryption)
|
|
1888
|
+
* @returns Base64-encoded encrypted output
|
|
1889
|
+
*/
|
|
1890
|
+
declare function prepareEncryptedOutput(note: CloakNote, cloakKeys: CloakKeyPair): string;
|
|
1891
|
+
/**
|
|
1892
|
+
* Prepare encrypted output for a specific recipient
|
|
1893
|
+
*
|
|
1894
|
+
* @param note - Note to encrypt
|
|
1895
|
+
* @param recipientPvkHex - Recipient's public view key (hex)
|
|
1896
|
+
* @returns Base64-encoded encrypted output
|
|
1897
|
+
*/
|
|
1898
|
+
declare function prepareEncryptedOutputForRecipient(note: CloakNote, recipientPvkHex: string): string;
|
|
1899
|
+
/**
|
|
1900
|
+
* Simple base64 encoding for v1.0 notes (no encryption)
|
|
1901
|
+
*
|
|
1902
|
+
* @param note - Note to encode
|
|
1903
|
+
* @returns Base64-encoded note data
|
|
1904
|
+
*/
|
|
1905
|
+
declare function encodeNoteSimple(note: CloakNote): string;
|
|
1906
|
+
|
|
1907
|
+
/**
|
|
1908
|
+
* Wallet Integration Helpers
|
|
1909
|
+
*
|
|
1910
|
+
* Helper functions for working with Solana Wallet Adapters
|
|
1911
|
+
*/
|
|
1912
|
+
|
|
1913
|
+
/**
|
|
1914
|
+
* Validate wallet is connected and has public key
|
|
1915
|
+
*/
|
|
1916
|
+
declare function validateWalletConnected(wallet: WalletAdapter | Keypair): void;
|
|
1917
|
+
/**
|
|
1918
|
+
* Get public key from wallet or keypair
|
|
1919
|
+
*/
|
|
1920
|
+
declare function getPublicKey(wallet: WalletAdapter | Keypair): PublicKey;
|
|
1921
|
+
/**
|
|
1922
|
+
* Send transaction using wallet adapter or keypair
|
|
1923
|
+
*/
|
|
1924
|
+
declare function sendTransaction(transaction: Transaction, wallet: WalletAdapter | Keypair, connection: Connection, options?: SendOptions): Promise<string>;
|
|
1925
|
+
/**
|
|
1926
|
+
* Sign transaction using wallet adapter or keypair
|
|
1927
|
+
*/
|
|
1928
|
+
declare function signTransaction<T extends Transaction>(transaction: T, wallet: WalletAdapter | Keypair): Promise<T>;
|
|
1929
|
+
/**
|
|
1930
|
+
* Create a keypair adapter for testing
|
|
1931
|
+
*/
|
|
1932
|
+
declare function keypairToAdapter(keypair: Keypair): WalletAdapter;
|
|
1933
|
+
|
|
1934
|
+
/**
|
|
1935
|
+
* Create a deposit instruction
|
|
1936
|
+
*
|
|
1937
|
+
* Deposits SOL into the Cloak protocol by creating a commitment.
|
|
1938
|
+
*
|
|
1939
|
+
* Instruction format:
|
|
1940
|
+
* - Byte 0: Discriminant (0x01 for Deposit, per ShieldPoolInstruction enum)
|
|
1941
|
+
* - Bytes 1-8: Amount (u64, little-endian)
|
|
1942
|
+
* - Bytes 9-40: Commitment (32 bytes)
|
|
1943
|
+
*
|
|
1944
|
+
* @param params - Deposit parameters
|
|
1945
|
+
* @returns Transaction instruction
|
|
1946
|
+
*
|
|
1947
|
+
* @example
|
|
1948
|
+
* ```typescript
|
|
1949
|
+
* const instruction = createDepositInstruction({
|
|
1950
|
+
* programId: CLOAK_PROGRAM_ID,
|
|
1951
|
+
* payer: wallet.publicKey,
|
|
1952
|
+
* pool: POOL_ADDRESS,
|
|
1953
|
+
* commitments: COMMITMENTS_ADDRESS,
|
|
1954
|
+
* amount: 1_000_000_000, // 1 SOL
|
|
1955
|
+
* commitment: commitmentBytes
|
|
1956
|
+
* });
|
|
1957
|
+
* ```
|
|
1958
|
+
*/
|
|
1959
|
+
declare function createDepositInstruction(params: {
|
|
1960
|
+
programId: PublicKey;
|
|
1961
|
+
payer: PublicKey;
|
|
1962
|
+
pool: PublicKey;
|
|
1963
|
+
merkleTree: PublicKey;
|
|
1964
|
+
amount: number;
|
|
1965
|
+
commitment: Uint8Array;
|
|
1966
|
+
}): TransactionInstruction;
|
|
1967
|
+
/**
|
|
1968
|
+
* Deposit instruction parameters for type safety
|
|
1969
|
+
*/
|
|
1970
|
+
interface DepositInstructionParams {
|
|
1971
|
+
programId: PublicKey;
|
|
1972
|
+
payer: PublicKey;
|
|
1973
|
+
pool: PublicKey;
|
|
1974
|
+
merkleTree: PublicKey;
|
|
1975
|
+
amount: number;
|
|
1976
|
+
commitment: Uint8Array;
|
|
1977
|
+
}
|
|
1978
|
+
/**
|
|
1979
|
+
* Validate deposit instruction parameters
|
|
1980
|
+
*
|
|
1981
|
+
* @param params - Parameters to validate
|
|
1982
|
+
* @throws Error if invalid
|
|
1983
|
+
*/
|
|
1984
|
+
declare function validateDepositParams(params: DepositInstructionParams): void;
|
|
1985
|
+
|
|
1986
|
+
/**
|
|
1987
|
+
* Program Derived Address (PDA) utilities for Shield Pool
|
|
1988
|
+
*
|
|
1989
|
+
* These functions derive deterministic addresses from the program ID and seeds.
|
|
1990
|
+
* This matches the behavior in tooling/test/src/shared.rs::get_pda_addresses()
|
|
1991
|
+
*/
|
|
1992
|
+
|
|
1993
|
+
interface ShieldPoolPDAs {
|
|
1994
|
+
pool: PublicKey;
|
|
1995
|
+
merkleTree: PublicKey;
|
|
1996
|
+
vaultAuthority: PublicKey;
|
|
1997
|
+
treasury: PublicKey;
|
|
1998
|
+
}
|
|
1999
|
+
/**
|
|
2000
|
+
* Derive all Shield Pool PDAs from program ID + pool mint
|
|
2001
|
+
*
|
|
2002
|
+
* Seeds match the on-chain mint-scoped program:
|
|
2003
|
+
* - pool: [b"pool", mint]
|
|
2004
|
+
* - merkle_tree: [b"merkle_tree", mint]
|
|
2005
|
+
* - treasury: [b"treasury", mint]
|
|
2006
|
+
* - vault_authority: [b"vault_authority", mint]
|
|
2007
|
+
*
|
|
2008
|
+
* @param programId - Optional program ID (defaults to CLOAK_PROGRAM_ID)
|
|
2009
|
+
* @param mint - Pool mint (defaults to NATIVE_SOL_MINT / WSOL sentinel)
|
|
2010
|
+
*/
|
|
2011
|
+
declare function getShieldPoolPDAs(programId?: PublicKey, mint?: PublicKey): ShieldPoolPDAs;
|
|
2012
|
+
/**
|
|
2013
|
+
* Derive the nullifier PDA for a specific pool + nullifier hash.
|
|
2014
|
+
*
|
|
2015
|
+
* With the new PDA-per-nullifier design, each nullifier has its own PDA
|
|
2016
|
+
* instead of being stored in a shared shard. The PDA is created when
|
|
2017
|
+
* the nullifier is used during withdrawal.
|
|
2018
|
+
*
|
|
2019
|
+
* Seeds: ["nullifier", pool_pubkey, nullifier_hash]
|
|
2020
|
+
*
|
|
2021
|
+
* @param poolPubkey - Pool PDA that scopes nullifier domain
|
|
2022
|
+
* @param nullifier - 32-byte nullifier hash
|
|
2023
|
+
* @param programId - Optional program ID (defaults to CLOAK_PROGRAM_ID)
|
|
2024
|
+
* @returns [PublicKey, bump] - The nullifier PDA and its bump seed
|
|
2025
|
+
*/
|
|
2026
|
+
declare function getNullifierPDA(poolPubkey: PublicKey, nullifier: Uint8Array | Buffer, programId?: PublicKey): [PublicKey, number];
|
|
2027
|
+
/**
|
|
2028
|
+
* Derive the swap state PDA for a given pool + nullifier.
|
|
2029
|
+
*
|
|
2030
|
+
* Seeds: ["swap_state", pool_pubkey, nullifier_hash]
|
|
2031
|
+
*
|
|
2032
|
+
* @param poolPubkey - Pool PDA used for swap state domain separation
|
|
2033
|
+
* @param nullifier - 32-byte nullifier hash
|
|
2034
|
+
* @param programId - Optional program ID (defaults to CLOAK_PROGRAM_ID)
|
|
2035
|
+
* @returns [PublicKey, bump] - The swap state PDA and its bump seed
|
|
2036
|
+
*/
|
|
2037
|
+
declare function getSwapStatePDA(poolPubkey: PublicKey, nullifier: Uint8Array | Buffer, programId?: PublicKey): [PublicKey, number];
|
|
2038
|
+
|
|
2039
|
+
/**
|
|
2040
|
+
* On-chain Merkle proof computation
|
|
2041
|
+
*
|
|
2042
|
+
* Computes Merkle proofs directly from on-chain tree state,
|
|
2043
|
+
* eliminating the need for an indexer for proof generation.
|
|
2044
|
+
*/
|
|
2045
|
+
|
|
2046
|
+
/**
|
|
2047
|
+
* Merkle proof result
|
|
2048
|
+
*/
|
|
2049
|
+
interface OnchainMerkleProof {
|
|
2050
|
+
pathElements: string[];
|
|
2051
|
+
pathIndices: number[];
|
|
2052
|
+
root: string;
|
|
2053
|
+
}
|
|
2054
|
+
interface MerkleTreeState {
|
|
2055
|
+
nextIndex: number;
|
|
2056
|
+
root: string;
|
|
2057
|
+
subtrees: string[];
|
|
2058
|
+
}
|
|
2059
|
+
/**
|
|
2060
|
+
* Read the Merkle tree state from on-chain account
|
|
2061
|
+
* @param forceConfirmed - If true, forces "confirmed" commitment level for fresh data
|
|
2062
|
+
* @param relayUrl - Optional relay URL to query for current root (bypasses RPC caching)
|
|
2063
|
+
* @param mint - Optional pool mint used when querying relay /merkle-root
|
|
2064
|
+
*/
|
|
2065
|
+
declare function readMerkleTreeState(connection: Connection, merkleTreePDA: PublicKey, forceConfirmed?: boolean, relayUrl?: string,
|
|
2066
|
+
/** When true, skip relay root and use chain directly (avoids stale relay root causing ProofInvalid) */
|
|
2067
|
+
skipRelayRoot?: boolean, mint?: PublicKey): Promise<MerkleTreeState>;
|
|
2068
|
+
/**
|
|
2069
|
+
* Compute Merkle proof for a leaf at a given index using on-chain state
|
|
2070
|
+
*
|
|
2071
|
+
* This works by:
|
|
2072
|
+
* 1. Reading the subtrees (frontier) from the on-chain account
|
|
2073
|
+
* 2. For each level, determining the sibling:
|
|
2074
|
+
* - If index is odd: sibling is the stored subtree (left sibling)
|
|
2075
|
+
* - If index is even: sibling is either a subsequent subtree or zero value
|
|
2076
|
+
*
|
|
2077
|
+
* Note: This works best for recent leaves where siblings are zero values.
|
|
2078
|
+
* For older leaves with non-zero siblings that aren't stored in subtrees,
|
|
2079
|
+
* an indexer may still be needed.
|
|
2080
|
+
*
|
|
2081
|
+
* @param connection - Solana connection
|
|
2082
|
+
* @param merkleTreePDA - PDA of the merkle tree account
|
|
2083
|
+
* @param leafIndex - Index of the leaf to compute proof for
|
|
2084
|
+
* @param forceConfirmed - If true, forces "confirmed" commitment level for fresh data
|
|
2085
|
+
* @returns Merkle proof with path elements and indices
|
|
2086
|
+
*/
|
|
2087
|
+
declare function computeProofFromChain(connection: Connection, merkleTreePDA: PublicKey, leafIndex: number, forceConfirmed?: boolean): Promise<OnchainMerkleProof>;
|
|
2088
|
+
/**
|
|
2089
|
+
* Compute proof for the most recently inserted leaf
|
|
2090
|
+
*
|
|
2091
|
+
* This is the most reliable case - immediately after your deposit,
|
|
2092
|
+
* all siblings to the right are zero values, and siblings to the left
|
|
2093
|
+
* are stored in the subtrees.
|
|
2094
|
+
*/
|
|
2095
|
+
declare function computeProofForLatestDeposit(connection: Connection, merkleTreePDA: PublicKey): Promise<OnchainMerkleProof & {
|
|
2096
|
+
leafIndex: number;
|
|
2097
|
+
}>;
|
|
2098
|
+
|
|
2099
|
+
/**
|
|
2100
|
+
* Merkle Tree implementation for computing proofs
|
|
2101
|
+
*
|
|
2102
|
+
* This tree stores all leaves and can compute the correct Merkle path
|
|
2103
|
+
* for any leaf index.
|
|
2104
|
+
*/
|
|
2105
|
+
declare const MERKLE_TREE_HEIGHT = 32;
|
|
2106
|
+
/**
|
|
2107
|
+
* Merkle Tree class that stores all leaves and computes proofs
|
|
2108
|
+
*/
|
|
2109
|
+
declare class MerkleTree {
|
|
2110
|
+
private levels;
|
|
2111
|
+
private capacity;
|
|
2112
|
+
private layers;
|
|
2113
|
+
private zeros;
|
|
2114
|
+
private poseidon;
|
|
2115
|
+
/**
|
|
2116
|
+
* Create a new Merkle tree
|
|
2117
|
+
* @param levels Number of levels in the tree (height)
|
|
2118
|
+
* @param leaves Initial leaves to insert
|
|
2119
|
+
* @param zeros Precomputed zero values for each level
|
|
2120
|
+
* @param poseidon Pre-initialized Poseidon instance (avoids async in constructor)
|
|
2121
|
+
*/
|
|
2122
|
+
constructor(levels: number, leaves: bigint[], zeros: bigint[], poseidon: any);
|
|
2123
|
+
/**
|
|
2124
|
+
* Create a new MerkleTree with async initialization
|
|
2125
|
+
*/
|
|
2126
|
+
static create(levels?: number, leaves?: bigint[]): Promise<MerkleTree>;
|
|
2127
|
+
/**
|
|
2128
|
+
* Rebuild the tree from the leaves (synchronous — poseidon must be initialized)
|
|
2129
|
+
*/
|
|
2130
|
+
private _rebuildSync;
|
|
2131
|
+
/**
|
|
2132
|
+
* Get the tree root
|
|
2133
|
+
*/
|
|
2134
|
+
root(): bigint;
|
|
2135
|
+
/**
|
|
2136
|
+
* Get the number of leaves in the tree
|
|
2137
|
+
*/
|
|
2138
|
+
get length(): number;
|
|
2139
|
+
/**
|
|
2140
|
+
* Insert a new leaf into the tree
|
|
2141
|
+
*/
|
|
2142
|
+
insert(leaf: bigint): void;
|
|
2143
|
+
/**
|
|
2144
|
+
* Insert multiple leaves
|
|
2145
|
+
*/
|
|
2146
|
+
bulkInsert(leaves: bigint[]): void;
|
|
2147
|
+
/**
|
|
2148
|
+
* Update the path from a leaf to the root
|
|
2149
|
+
*/
|
|
2150
|
+
private _updatePath;
|
|
2151
|
+
/**
|
|
2152
|
+
* Get the Merkle path for a leaf at the given index
|
|
2153
|
+
* @param index Leaf index
|
|
2154
|
+
* @returns pathElements and pathIndices for the proof
|
|
2155
|
+
*/
|
|
2156
|
+
path(index: number): {
|
|
2157
|
+
pathElements: bigint[];
|
|
2158
|
+
pathIndices: number;
|
|
2159
|
+
};
|
|
2160
|
+
/**
|
|
2161
|
+
* Find the index of a leaf in the tree
|
|
2162
|
+
* @param leaf Leaf value to find
|
|
2163
|
+
* @returns Index if found, -1 otherwise
|
|
2164
|
+
*/
|
|
2165
|
+
indexOf(leaf: bigint): number;
|
|
2166
|
+
/**
|
|
2167
|
+
* Get all leaves
|
|
2168
|
+
*/
|
|
2169
|
+
leaves(): bigint[];
|
|
2170
|
+
}
|
|
2171
|
+
/**
|
|
2172
|
+
* Build a MerkleTree from commitment values
|
|
2173
|
+
* @param commitments Array of commitment bigints
|
|
2174
|
+
* @param height Tree height (default: 32)
|
|
2175
|
+
*/
|
|
2176
|
+
declare function buildMerkleTree(commitments: bigint[], height?: number): Promise<MerkleTree>;
|
|
2177
|
+
|
|
2178
|
+
/**
|
|
2179
|
+
* Relay client utilities for fetching data from the relay service
|
|
2180
|
+
*/
|
|
2181
|
+
|
|
2182
|
+
interface CommitmentEntry {
|
|
2183
|
+
index: number;
|
|
2184
|
+
commitment: string;
|
|
2185
|
+
}
|
|
2186
|
+
interface CommitmentsResponse {
|
|
2187
|
+
commitments: CommitmentEntry[];
|
|
2188
|
+
count: number;
|
|
2189
|
+
target_reached?: boolean;
|
|
2190
|
+
canonical?: boolean;
|
|
2191
|
+
canonical_reason?: string | null;
|
|
2192
|
+
}
|
|
2193
|
+
interface FetchCommitmentsOptions {
|
|
2194
|
+
mint?: PublicKey;
|
|
2195
|
+
timeoutMs?: number;
|
|
2196
|
+
maxRetries?: number;
|
|
2197
|
+
sync?: boolean;
|
|
2198
|
+
repair?: boolean;
|
|
2199
|
+
requireTarget?: boolean;
|
|
2200
|
+
requireCanonical?: boolean;
|
|
2201
|
+
fromIndex?: number;
|
|
2202
|
+
limit?: number;
|
|
2203
|
+
waitForIndex?: number;
|
|
2204
|
+
}
|
|
2205
|
+
/**
|
|
2206
|
+
* Fetch all commitments from the relay
|
|
2207
|
+
* @param relayUrl Base URL of the relay service (may include cache-busting query params)
|
|
2208
|
+
* @param options Timeout and retry options
|
|
2209
|
+
* @returns Array of commitment entries
|
|
2210
|
+
*/
|
|
2211
|
+
declare function fetchCommitments(relayUrl: string, options?: FetchCommitmentsOptions): Promise<CommitmentEntry[]>;
|
|
2212
|
+
/**
|
|
2213
|
+
* Build a Merkle tree from relay commitments
|
|
2214
|
+
* @param relayUrl Base URL of the relay service
|
|
2215
|
+
* @param options When sync is true, triggers on-demand sync on relay before fetching (for freshness when relay is behind chain)
|
|
2216
|
+
* @returns MerkleTree instance with all commitments loaded
|
|
2217
|
+
*
|
|
2218
|
+
* Supports sparse indices by zero-filling missing leaves, including missing prefixes.
|
|
2219
|
+
* Non-contiguous gaps (e.g. 0,1,2,3,22,23,30,31,32,33) are reconstructed with
|
|
2220
|
+
* zero leaves to match the on-chain Merkle tree structure.
|
|
2221
|
+
*/
|
|
2222
|
+
declare function buildMerkleTreeFromRelay(relayUrl: string, options?: {
|
|
2223
|
+
mint?: PublicKey;
|
|
2224
|
+
sync?: boolean;
|
|
2225
|
+
repair?: boolean;
|
|
2226
|
+
requireTarget?: boolean;
|
|
2227
|
+
requireCanonical?: boolean;
|
|
2228
|
+
timeoutMs?: number;
|
|
2229
|
+
maxRetries?: number;
|
|
2230
|
+
waitForIndex?: number;
|
|
2231
|
+
}): Promise<MerkleTree>;
|
|
2232
|
+
declare function buildMerkleTreeFromChain(connection: Connection, programId: PublicKey, merkleTree: PublicKey, onProgress?: (message: string) => void): Promise<MerkleTree>;
|
|
2233
|
+
/**
|
|
2234
|
+
* Pre-flight root validation
|
|
2235
|
+
*
|
|
2236
|
+
* Validates that a Merkle root is still valid before generating a proof.
|
|
2237
|
+
* This prevents wasted time generating proofs that will fail on-chain.
|
|
2238
|
+
*
|
|
2239
|
+
* @param relayUrl Relay service URL
|
|
2240
|
+
* @param rootHex Root to validate (hex string, with or without 0x prefix)
|
|
2241
|
+
* @returns Validation result with status and helpful message
|
|
2242
|
+
*/
|
|
2243
|
+
declare function validateRoot(relayUrl: string, rootHex: string): Promise<{
|
|
2244
|
+
valid: boolean;
|
|
2245
|
+
currentRoot?: string;
|
|
2246
|
+
message: string;
|
|
2247
|
+
isRecent: boolean;
|
|
2248
|
+
}>;
|
|
2249
|
+
/**
|
|
2250
|
+
* Wait for root to be valid
|
|
2251
|
+
*
|
|
2252
|
+
* Polls the relay until the given root is accepted or timeout.
|
|
2253
|
+
* Useful when you know a transaction is being processed but root hasn't updated yet.
|
|
2254
|
+
*
|
|
2255
|
+
* @param relayUrl Relay service URL
|
|
2256
|
+
* @param rootHex Root to wait for
|
|
2257
|
+
* @param timeoutMs Maximum time to wait (default: 30000ms)
|
|
2258
|
+
* @param pollIntervalMs Polling interval (default: 1000ms)
|
|
2259
|
+
* @returns Whether root became valid in time
|
|
2260
|
+
*/
|
|
2261
|
+
declare function waitForRoot(relayUrl: string, rootHex: string, timeoutMs?: number, pollIntervalMs?: number): Promise<{
|
|
2262
|
+
success: boolean;
|
|
2263
|
+
currentRoot?: string;
|
|
2264
|
+
waitedMs: number;
|
|
2265
|
+
}>;
|
|
2266
|
+
/**
|
|
2267
|
+
* Smart pre-flight check with automatic retry suggestion
|
|
2268
|
+
*
|
|
2269
|
+
* Checks root validity and provides actionable guidance:
|
|
2270
|
+
* - If root is current: proceed
|
|
2271
|
+
* - If root is old: suggest fetching fresh Merkle proofs
|
|
2272
|
+
* - If root is very old: suggest full tree rebuild
|
|
2273
|
+
*
|
|
2274
|
+
* @param relayUrl Relay service URL
|
|
2275
|
+
* @param rootHex Root to check
|
|
2276
|
+
* @returns Action recommendation
|
|
2277
|
+
*/
|
|
2278
|
+
declare function preflightCheck(relayUrl: string, rootHex: string): Promise<{
|
|
2279
|
+
shouldProceed: boolean;
|
|
2280
|
+
action: "proceed" | "refresh_proofs" | "rebuild_tree" | "wait";
|
|
2281
|
+
message: string;
|
|
2282
|
+
estimatedWaitMs?: number;
|
|
2283
|
+
}>;
|
|
2284
|
+
|
|
2285
|
+
/**
|
|
2286
|
+
* Direct Circom WASM Proof Generation
|
|
2287
|
+
*
|
|
2288
|
+
* This module provides direct proof generation using snarkjs and Circom WASM,
|
|
2289
|
+
* matching the approach used in services-new/tests/src/proof.ts
|
|
2290
|
+
*
|
|
2291
|
+
* This uses pinned S3-hosted circuit artifacts and does not require
|
|
2292
|
+
* a backend prover service.
|
|
2293
|
+
*/
|
|
2294
|
+
|
|
2295
|
+
/**
|
|
2296
|
+
* Default URL for fetching circuit artifacts
|
|
2297
|
+
* Hosted in S3 and versioned by build.
|
|
2298
|
+
*/
|
|
2299
|
+
declare const DEFAULT_CIRCUITS_URL = "https://cloak-circuits.s3.us-east-1.amazonaws.com/circuits/0.1.0";
|
|
2300
|
+
interface WithdrawRegularInputs {
|
|
2301
|
+
root: bigint;
|
|
2302
|
+
nullifier: bigint;
|
|
2303
|
+
outputs_hash: bigint;
|
|
2304
|
+
public_amount: bigint;
|
|
2305
|
+
amount: bigint;
|
|
2306
|
+
leaf_index: bigint;
|
|
2307
|
+
sk: [bigint, bigint];
|
|
2308
|
+
r: [bigint, bigint];
|
|
2309
|
+
pathElements: bigint[];
|
|
2310
|
+
pathIndices: number[];
|
|
2311
|
+
num_outputs: number;
|
|
2312
|
+
out_addr: bigint[][];
|
|
2313
|
+
out_amount: bigint[];
|
|
2314
|
+
out_flags: number[];
|
|
2315
|
+
var_fee: bigint;
|
|
2316
|
+
rem: bigint;
|
|
2317
|
+
}
|
|
2318
|
+
interface WithdrawSwapInputs {
|
|
2319
|
+
sk_spend: bigint;
|
|
2320
|
+
r: bigint;
|
|
2321
|
+
amount: bigint;
|
|
2322
|
+
leaf_index: bigint;
|
|
2323
|
+
path_elements: bigint[];
|
|
2324
|
+
path_indices: number[];
|
|
2325
|
+
root: bigint;
|
|
2326
|
+
nullifier: bigint;
|
|
2327
|
+
outputs_hash: bigint;
|
|
2328
|
+
public_amount: bigint;
|
|
2329
|
+
input_mint: bigint[];
|
|
2330
|
+
output_mint: bigint[];
|
|
2331
|
+
recipient_ata: bigint[];
|
|
2332
|
+
min_output_amount: bigint;
|
|
2333
|
+
var_fee: bigint;
|
|
2334
|
+
rem: bigint;
|
|
2335
|
+
}
|
|
2336
|
+
interface ProofResult {
|
|
2337
|
+
proof: Groth16Proof;
|
|
2338
|
+
publicSignals: string[];
|
|
2339
|
+
proofBytes: Uint8Array;
|
|
2340
|
+
publicInputsBytes: Uint8Array;
|
|
2341
|
+
}
|
|
2342
|
+
/**
|
|
2343
|
+
* Generate Groth16 proof for regular withdrawal using Circom WASM
|
|
2344
|
+
*
|
|
2345
|
+
* This matches the approach in services-new/tests/src/proof.ts
|
|
2346
|
+
*
|
|
2347
|
+
* @param inputs - Circuit inputs
|
|
2348
|
+
* @param circuitsPath - Ignored. Proof generation always uses pinned S3 circuits.
|
|
2349
|
+
*/
|
|
2350
|
+
declare function generateWithdrawRegularProof(inputs: WithdrawRegularInputs, circuitsPath: string): Promise<ProofResult>;
|
|
2351
|
+
/**
|
|
2352
|
+
* Generate Groth16 proof for swap withdrawal using Circom WASM
|
|
2353
|
+
*
|
|
2354
|
+
* This matches the approach in services-new/tests/src/proof.ts
|
|
2355
|
+
*
|
|
2356
|
+
* @param inputs - Circuit inputs
|
|
2357
|
+
* @param circuitsPath - Ignored. Proof generation always uses pinned S3 circuits.
|
|
2358
|
+
*/
|
|
2359
|
+
declare function generateWithdrawSwapProof(inputs: WithdrawSwapInputs, circuitsPath: string): Promise<ProofResult>;
|
|
2360
|
+
/**
|
|
2361
|
+
* Check if circuits are available from the pinned S3 source.
|
|
2362
|
+
*/
|
|
2363
|
+
declare function areCircuitsAvailable(circuitsPath: string): Promise<boolean>;
|
|
2364
|
+
/**
|
|
2365
|
+
* Get default circuits URL.
|
|
2366
|
+
*/
|
|
2367
|
+
declare function getDefaultCircuitsPath(): Promise<string>;
|
|
2368
|
+
/**
|
|
2369
|
+
* Pinned circuit artifact hashes (SHA-256).
|
|
2370
|
+
*
|
|
2371
|
+
* These hashes must be updated whenever the trusted circuit artifacts change.
|
|
2372
|
+
*/
|
|
2373
|
+
declare const EXPECTED_CIRCUIT_HASHES: {
|
|
2374
|
+
withdraw_regular_wasm: string;
|
|
2375
|
+
withdraw_regular_zkey: string;
|
|
2376
|
+
withdraw_swap_wasm: string;
|
|
2377
|
+
withdraw_swap_zkey: string;
|
|
2378
|
+
};
|
|
2379
|
+
/**
|
|
2380
|
+
* Circuit verification result
|
|
2381
|
+
*/
|
|
2382
|
+
interface CircuitVerificationResult {
|
|
2383
|
+
/** Whether verification passed */
|
|
2384
|
+
valid: boolean;
|
|
2385
|
+
/** Which circuit was checked */
|
|
2386
|
+
circuit: 'withdraw_regular' | 'withdraw_swap';
|
|
2387
|
+
/** Error message if verification failed */
|
|
2388
|
+
error?: string;
|
|
2389
|
+
computed?: {
|
|
2390
|
+
wasm: string;
|
|
2391
|
+
zkey: string;
|
|
2392
|
+
};
|
|
2393
|
+
expected?: {
|
|
2394
|
+
wasm: string;
|
|
2395
|
+
zkey: string;
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
/**
|
|
2399
|
+
* Verify circuit integrity by checking verification key hashes
|
|
2400
|
+
*
|
|
2401
|
+
* This function fetches the verification key and computes its hash,
|
|
2402
|
+
* then compares against the expected hash embedded in the SDK.
|
|
2403
|
+
*
|
|
2404
|
+
* IMPORTANT: If the hashes don't match, the circuit may produce proofs
|
|
2405
|
+
* that will be rejected by the on-chain verifier!
|
|
2406
|
+
*
|
|
2407
|
+
* @param circuitsPath - Ignored. Verification always uses pinned S3 circuits.
|
|
2408
|
+
* @param circuit - Which circuit to verify ('withdraw_regular' or 'withdraw_swap')
|
|
2409
|
+
* @returns Verification result
|
|
2410
|
+
*
|
|
2411
|
+
* @example
|
|
2412
|
+
* ```typescript
|
|
2413
|
+
* const result = await verifyCircuitIntegrity('https://cloak-circuits.s3.us-east-1.amazonaws.com/circuits/0.1.0', 'withdraw_regular');
|
|
2414
|
+
* if (!result.valid) {
|
|
2415
|
+
* console.error('Circuit verification failed:', result.error);
|
|
2416
|
+
* // Don't proceed with proof generation!
|
|
2417
|
+
* }
|
|
2418
|
+
* ```
|
|
2419
|
+
*/
|
|
2420
|
+
declare function verifyCircuitIntegrity(circuitsPath: string, circuit: 'withdraw_regular' | 'withdraw_swap'): Promise<CircuitVerificationResult>;
|
|
2421
|
+
/**
|
|
2422
|
+
* Verify all circuits before use
|
|
2423
|
+
*
|
|
2424
|
+
* Call this at SDK initialization to ensure circuits are valid.
|
|
2425
|
+
*
|
|
2426
|
+
* @param circuitsPath - Ignored. Verification always uses pinned S3 circuits.
|
|
2427
|
+
* @returns Array of verification results (one per circuit)
|
|
2428
|
+
*/
|
|
2429
|
+
declare function verifyAllCircuits(circuitsPath: string): Promise<CircuitVerificationResult[]>;
|
|
2430
|
+
|
|
2431
|
+
/**
|
|
2432
|
+
* Pending Operations Manager
|
|
2433
|
+
*
|
|
2434
|
+
* Utility for persisting pending deposit/withdrawal operations in browser storage.
|
|
2435
|
+
* This enables recovery if the browser crashes or user navigates away mid-operation.
|
|
2436
|
+
*
|
|
2437
|
+
* IMPORTANT: This uses localStorage by default which has security implications.
|
|
2438
|
+
* Notes contain sensitive spending keys - consider using more secure storage
|
|
2439
|
+
* in production (e.g., encrypted IndexedDB, secure enclave).
|
|
2440
|
+
*/
|
|
2441
|
+
|
|
2442
|
+
/**
|
|
2443
|
+
* Pending deposit record
|
|
2444
|
+
*/
|
|
2445
|
+
interface PendingDeposit {
|
|
2446
|
+
/** The note (contains spending secrets!) */
|
|
2447
|
+
note: CloakNote;
|
|
2448
|
+
/** When the deposit was initiated */
|
|
2449
|
+
startedAt: number;
|
|
2450
|
+
/** Transaction signature if available */
|
|
2451
|
+
txSignature?: string;
|
|
2452
|
+
/** Status of the deposit */
|
|
2453
|
+
status: "pending" | "tx_sent" | "confirmed" | "failed";
|
|
2454
|
+
/** Error message if failed */
|
|
2455
|
+
error?: string;
|
|
2456
|
+
}
|
|
2457
|
+
/**
|
|
2458
|
+
* Pending withdrawal record
|
|
2459
|
+
*/
|
|
2460
|
+
interface PendingWithdrawal {
|
|
2461
|
+
/** The relay request ID (for resumption) */
|
|
2462
|
+
requestId: string;
|
|
2463
|
+
/** The note commitment being withdrawn */
|
|
2464
|
+
commitment: string;
|
|
2465
|
+
/** The nullifier being used */
|
|
2466
|
+
nullifier: string;
|
|
2467
|
+
/** When the withdrawal was initiated */
|
|
2468
|
+
startedAt: number;
|
|
2469
|
+
/** Status of the withdrawal */
|
|
2470
|
+
status: "pending" | "processing" | "completed" | "failed";
|
|
2471
|
+
/** Transaction signature if completed */
|
|
2472
|
+
txSignature?: string;
|
|
2473
|
+
/** Error message if failed */
|
|
2474
|
+
error?: string;
|
|
2475
|
+
}
|
|
2476
|
+
/**
|
|
2477
|
+
* Save a pending deposit
|
|
2478
|
+
* Call this BEFORE sending the on-chain transaction to ensure note is persisted
|
|
2479
|
+
*/
|
|
2480
|
+
declare function savePendingDeposit(deposit: PendingDeposit): void;
|
|
2481
|
+
/**
|
|
2482
|
+
* Load all pending deposits
|
|
2483
|
+
*/
|
|
2484
|
+
declare function loadPendingDeposits(): PendingDeposit[];
|
|
2485
|
+
/**
|
|
2486
|
+
* Update a pending deposit status
|
|
2487
|
+
*/
|
|
2488
|
+
declare function updatePendingDeposit(commitment: string, updates: Partial<PendingDeposit>): void;
|
|
2489
|
+
/**
|
|
2490
|
+
* Remove a pending deposit (e.g., after successful confirmation)
|
|
2491
|
+
*/
|
|
2492
|
+
declare function removePendingDeposit(commitment: string): void;
|
|
2493
|
+
/**
|
|
2494
|
+
* Clear all pending deposits
|
|
2495
|
+
*/
|
|
2496
|
+
declare function clearPendingDeposits(): void;
|
|
2497
|
+
/**
|
|
2498
|
+
* Save a pending withdrawal
|
|
2499
|
+
* Call this when you receive the request_id from the relay
|
|
2500
|
+
*/
|
|
2501
|
+
declare function savePendingWithdrawal(withdrawal: PendingWithdrawal): void;
|
|
2502
|
+
/**
|
|
2503
|
+
* Load all pending withdrawals
|
|
2504
|
+
*/
|
|
2505
|
+
declare function loadPendingWithdrawals(): PendingWithdrawal[];
|
|
2506
|
+
/**
|
|
2507
|
+
* Update a pending withdrawal status
|
|
2508
|
+
*/
|
|
2509
|
+
declare function updatePendingWithdrawal(requestId: string, updates: Partial<PendingWithdrawal>): void;
|
|
2510
|
+
/**
|
|
2511
|
+
* Remove a pending withdrawal (e.g., after successful completion)
|
|
2512
|
+
*/
|
|
2513
|
+
declare function removePendingWithdrawal(requestId: string): void;
|
|
2514
|
+
/**
|
|
2515
|
+
* Clear all pending withdrawals
|
|
2516
|
+
*/
|
|
2517
|
+
declare function clearPendingWithdrawals(): void;
|
|
2518
|
+
/**
|
|
2519
|
+
* Check if there are any pending operations that need recovery
|
|
2520
|
+
* Call this on page load to determine if recovery UI should be shown
|
|
2521
|
+
*/
|
|
2522
|
+
declare function hasPendingOperations(): boolean;
|
|
2523
|
+
/**
|
|
2524
|
+
* Get summary of pending operations for recovery UI
|
|
2525
|
+
*/
|
|
2526
|
+
declare function getPendingOperationsSummary(): {
|
|
2527
|
+
deposits: PendingDeposit[];
|
|
2528
|
+
withdrawals: PendingWithdrawal[];
|
|
2529
|
+
totalPending: number;
|
|
2530
|
+
};
|
|
2531
|
+
/**
|
|
2532
|
+
* Clean up stale pending operations
|
|
2533
|
+
* Call this periodically to remove old failed/completed operations
|
|
2534
|
+
*
|
|
2535
|
+
* @param maxAgeMs Maximum age in milliseconds before an operation is removed (default: 24 hours)
|
|
2536
|
+
*/
|
|
2537
|
+
declare function cleanupStalePendingOperations(maxAgeMs?: number): {
|
|
2538
|
+
removedDeposits: number;
|
|
2539
|
+
removedWithdrawals: number;
|
|
2540
|
+
};
|
|
2541
|
+
|
|
2542
|
+
/**
|
|
2543
|
+
* UTXO (Unspent Transaction Output) Model
|
|
2544
|
+
*
|
|
2545
|
+
* This module implements the UTXO model for the Cloak privacy protocol.
|
|
2546
|
+
* UTXOs allow for:
|
|
2547
|
+
* - Shield-to-shield transfers (privacy preserved)
|
|
2548
|
+
* - Partial withdrawals (change stays shielded)
|
|
2549
|
+
* - Combining multiple small deposits
|
|
2550
|
+
* - Multi-token support (SOL + any SPL token)
|
|
2551
|
+
*/
|
|
2552
|
+
|
|
2553
|
+
declare const NATIVE_SOL_MINT: PublicKey;
|
|
2554
|
+
/**
|
|
2555
|
+
* UTXO Keypair for ownership verification
|
|
2556
|
+
*
|
|
2557
|
+
* Uses Poseidon hash for key derivation:
|
|
2558
|
+
* - privateKey: random field element (kept secret)
|
|
2559
|
+
* - publicKey: Poseidon(privateKey, 0) - can be shared
|
|
2560
|
+
*/
|
|
2561
|
+
interface UtxoKeypair {
|
|
2562
|
+
/** Private key (random 252-bit field element) */
|
|
2563
|
+
privateKey: bigint;
|
|
2564
|
+
/** Public key derived as Poseidon(privateKey, 0) */
|
|
2565
|
+
publicKey: bigint;
|
|
2566
|
+
}
|
|
2567
|
+
/**
|
|
2568
|
+
* UTXO represents an unspent transaction output
|
|
2569
|
+
*
|
|
2570
|
+
* Contains all information needed to spend the UTXO:
|
|
2571
|
+
* - amount: Value in the smallest unit (lamports for SOL)
|
|
2572
|
+
* - keypair: Ownership keys
|
|
2573
|
+
* - blinding: Randomness for hiding
|
|
2574
|
+
* - mintAddress: Token type (SOL or SPL token)
|
|
2575
|
+
* - index: Leaf index in Merkle tree (set after deposit/creation)
|
|
2576
|
+
*/
|
|
2577
|
+
interface Utxo {
|
|
2578
|
+
/** Amount in the smallest unit (lamports for SOL, token units for SPL) */
|
|
2579
|
+
amount: bigint;
|
|
2580
|
+
/** Keypair for ownership */
|
|
2581
|
+
keypair: UtxoKeypair;
|
|
2582
|
+
/** Random blinding factor */
|
|
2583
|
+
blinding: bigint;
|
|
2584
|
+
/** Token mint address (NATIVE_SOL_MINT for SOL) */
|
|
2585
|
+
mintAddress: PublicKey;
|
|
2586
|
+
/** Leaf index in Merkle tree (set after the UTXO is in the tree) */
|
|
2587
|
+
index?: number;
|
|
2588
|
+
/** Commitment hash (computed from amount, pubkey, blinding, mint) */
|
|
2589
|
+
commitment?: bigint;
|
|
2590
|
+
/** Nullifier hash (computed when spending) */
|
|
2591
|
+
nullifier?: bigint;
|
|
2592
|
+
/**
|
|
2593
|
+
* Sibling commitment at level 0 of the Merkle tree.
|
|
2594
|
+
* Required for Merkle proofs since siblings aren't stored on-chain.
|
|
2595
|
+
* This is the commitment of the other output in the same transaction.
|
|
2596
|
+
*/
|
|
2597
|
+
siblingCommitment?: bigint;
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Encrypted UTXO note for recipient discovery
|
|
2601
|
+
*
|
|
2602
|
+
* When creating an output UTXO for someone else, the data is encrypted
|
|
2603
|
+
* so only the recipient can discover and spend it.
|
|
2604
|
+
*/
|
|
2605
|
+
interface EncryptedNote {
|
|
2606
|
+
/** Encrypted UTXO data (ECIES/ChaCha20 encrypted) */
|
|
2607
|
+
ciphertext: Uint8Array;
|
|
2608
|
+
/** Ephemeral public key for ECDH */
|
|
2609
|
+
ephemeralPubkey: Uint8Array;
|
|
2610
|
+
/** MAC for integrity verification */
|
|
2611
|
+
mac: Uint8Array;
|
|
2612
|
+
}
|
|
2613
|
+
/**
|
|
2614
|
+
* Transaction parameters for a UTXO transaction
|
|
2615
|
+
*/
|
|
2616
|
+
interface TransactParams {
|
|
2617
|
+
/** Input UTXOs to spend (max 2) */
|
|
2618
|
+
inputUtxos: Utxo[];
|
|
2619
|
+
/** Output UTXOs to create (max 2) */
|
|
2620
|
+
outputUtxos: Utxo[];
|
|
2621
|
+
/** External recipient for withdrawal (optional) */
|
|
2622
|
+
recipient?: PublicKey;
|
|
2623
|
+
/** Net external amount: positive = deposit, negative = withdraw */
|
|
2624
|
+
externalAmount?: bigint;
|
|
2625
|
+
/** Depositor address (for deposits, the source of funds) */
|
|
2626
|
+
depositor?: PublicKey;
|
|
2627
|
+
}
|
|
2628
|
+
/**
|
|
2629
|
+
* Result from a UTXO transaction
|
|
2630
|
+
*/
|
|
2631
|
+
interface TransactResult {
|
|
2632
|
+
/** Transaction signature */
|
|
2633
|
+
signature: string;
|
|
2634
|
+
/** Nullifiers of spent inputs */
|
|
2635
|
+
inputNullifiers: bigint[];
|
|
2636
|
+
/** Commitments of created outputs */
|
|
2637
|
+
outputCommitments: bigint[];
|
|
2638
|
+
/** New Merkle root after the transaction */
|
|
2639
|
+
newRoot: string;
|
|
2640
|
+
/** Merkle tree indices where output commitments were inserted */
|
|
2641
|
+
commitmentIndices: [number, number];
|
|
2642
|
+
/**
|
|
2643
|
+
* Sibling commitments for each output.
|
|
2644
|
+
* For output[0], sibling is output[1] and vice versa.
|
|
2645
|
+
* These are needed for Merkle proofs since siblings aren't stored on-chain.
|
|
2646
|
+
*/
|
|
2647
|
+
siblingCommitments: [bigint, bigint];
|
|
2648
|
+
/**
|
|
2649
|
+
* Left sibling from before the transaction (for odd-index handling).
|
|
2650
|
+
* When the first output ends up at an odd index due to concurrent access,
|
|
2651
|
+
* its sibling at index-1 comes from a previous transaction.
|
|
2652
|
+
* This value captures subtrees[0] before our transaction to enable
|
|
2653
|
+
* correct Merkle proof computation for odd indices.
|
|
2654
|
+
*/
|
|
2655
|
+
preTransactionLeftSibling?: bigint;
|
|
2656
|
+
/**
|
|
2657
|
+
* The actual output UTXOs created by this transaction.
|
|
2658
|
+
* These have all the data needed to spend them later (keypair, blinding, etc).
|
|
2659
|
+
* The UTXOs are already updated with their indices and sibling commitments.
|
|
2660
|
+
*/
|
|
2661
|
+
outputUtxos: Utxo[];
|
|
2662
|
+
/**
|
|
2663
|
+
* Whether the viewing key was registered with the relay for compliance.
|
|
2664
|
+
* True on first transaction when metadataBundle includes viewing_key.
|
|
2665
|
+
* Once registered, subsequent transactions don't need to send metadataBundle.
|
|
2666
|
+
*/
|
|
2667
|
+
viewingKeyRegistered?: boolean;
|
|
2668
|
+
/**
|
|
2669
|
+
* The Merkle tree used/built for this transaction, with output commitments inserted.
|
|
2670
|
+
* Pass this as `cachedMerkleTree` in the next transaction to skip relay fetching
|
|
2671
|
+
* and avoid needing `waitForCommitmentIndex`.
|
|
2672
|
+
*/
|
|
2673
|
+
merkleTree?: MerkleTree;
|
|
2674
|
+
/**
|
|
2675
|
+
* Address lookup table used for v0 transaction (when chain notes or risk oracle require it).
|
|
2676
|
+
* Pass this as `addressLookupTableAccounts` in the next deposit to avoid creating a new ALT.
|
|
2677
|
+
*/
|
|
2678
|
+
addressLookupTableAccounts?: AddressLookupTableAccount[];
|
|
2679
|
+
}
|
|
2680
|
+
/**
|
|
2681
|
+
* Generate a random field element suitable for BN254
|
|
2682
|
+
*/
|
|
2683
|
+
declare function randomFieldElement(): bigint;
|
|
2684
|
+
/**
|
|
2685
|
+
* Generate a new UTXO keypair
|
|
2686
|
+
*
|
|
2687
|
+
* @returns A new keypair with random private key and derived public key
|
|
2688
|
+
*/
|
|
2689
|
+
declare function generateUtxoKeypair(): Promise<UtxoKeypair>;
|
|
2690
|
+
/**
|
|
2691
|
+
* Derive a deterministic UTXO keypair from a wallet's spend key.
|
|
2692
|
+
* Use this for deposits and change outputs so all chain notes use the same nk,
|
|
2693
|
+
* enabling the compliance scan (scanTransactions + toComplianceReport) to decrypt them.
|
|
2694
|
+
*
|
|
2695
|
+
* @param skSpend - 32-byte spend key (from wallet key derivation)
|
|
2696
|
+
* @returns UtxoKeypair with deterministic private/public keys
|
|
2697
|
+
*/
|
|
2698
|
+
declare function deriveUtxoKeypairFromSpendKey(skSpend: Uint8Array): Promise<UtxoKeypair>;
|
|
2699
|
+
/**
|
|
2700
|
+
* Derive public key from private key
|
|
2701
|
+
*
|
|
2702
|
+
* @param privateKey The private key
|
|
2703
|
+
* @returns The corresponding public key
|
|
2704
|
+
*/
|
|
2705
|
+
declare function derivePublicKey(privateKey: bigint): Promise<bigint>;
|
|
2706
|
+
/**
|
|
2707
|
+
* Create a new UTXO
|
|
2708
|
+
*
|
|
2709
|
+
* @param amount Amount in smallest unit
|
|
2710
|
+
* @param keypair Owner's keypair
|
|
2711
|
+
* @param mintAddress Token mint (defaults to native SOL)
|
|
2712
|
+
* @returns A new UTXO (commitment will be computed)
|
|
2713
|
+
*/
|
|
2714
|
+
declare function createUtxo(amount: bigint, keypair: UtxoKeypair, mintAddress?: PublicKey): Promise<Utxo>;
|
|
2715
|
+
/**
|
|
2716
|
+
* Create a zero/padding UTXO
|
|
2717
|
+
*
|
|
2718
|
+
* Zero UTXOs are used as padding when we need fewer than 2 inputs/outputs.
|
|
2719
|
+
* They have zero amount and don't require valid Merkle proofs.
|
|
2720
|
+
* Uses salt-based keypair (privateKey = salt) with blinding=0 to match the circuit
|
|
2721
|
+
* test. By default, salt is random to avoid cross-process collisions under concurrency.
|
|
2722
|
+
* Callers can pass an explicit salt for deterministic behavior.
|
|
2723
|
+
*
|
|
2724
|
+
* @param mintAddress Token mint (defaults to native SOL)
|
|
2725
|
+
* @param salt Optional salt; if omitted, uses timestamp+counter for uniqueness
|
|
2726
|
+
*/
|
|
2727
|
+
declare function createZeroUtxo(mintAddress?: PublicKey, salt?: bigint): Promise<Utxo>;
|
|
2728
|
+
/**
|
|
2729
|
+
* Convert PublicKey to field element for circuit
|
|
2730
|
+
*
|
|
2731
|
+
* @param pubkey Solana PublicKey
|
|
2732
|
+
* @returns Field element representation
|
|
2733
|
+
*/
|
|
2734
|
+
declare function pubkeyToFieldElement(pubkey: PublicKey): bigint;
|
|
2735
|
+
/**
|
|
2736
|
+
* Compute the commitment for a UTXO
|
|
2737
|
+
*
|
|
2738
|
+
* commitment = Poseidon(amount, pubkey, blinding, mintAddress)
|
|
2739
|
+
*
|
|
2740
|
+
* @param utxo The UTXO to compute commitment for
|
|
2741
|
+
* @returns The commitment as a bigint
|
|
2742
|
+
*/
|
|
2743
|
+
declare function computeCommitment(utxo: Utxo): Promise<bigint>;
|
|
2744
|
+
/**
|
|
2745
|
+
* Compute the signature for nullifier derivation
|
|
2746
|
+
*
|
|
2747
|
+
* signature = Poseidon(privateKey, commitment, pathIndex)
|
|
2748
|
+
*
|
|
2749
|
+
* @param privateKey Owner's private key
|
|
2750
|
+
* @param commitment The UTXO commitment
|
|
2751
|
+
* @param pathIndex Merkle tree path index
|
|
2752
|
+
* @returns The signature
|
|
2753
|
+
*/
|
|
2754
|
+
declare function computeSignature(privateKey: bigint, commitment: bigint, pathIndex: bigint): Promise<bigint>;
|
|
2755
|
+
/**
|
|
2756
|
+
* Compute the nullifier for a UTXO
|
|
2757
|
+
*
|
|
2758
|
+
* nullifier = Poseidon(commitment, pathIndex, signature)
|
|
2759
|
+
*
|
|
2760
|
+
* The nullifier is a unique identifier that gets recorded on-chain
|
|
2761
|
+
* to prevent double-spending.
|
|
2762
|
+
*
|
|
2763
|
+
* @param utxo The UTXO being spent
|
|
2764
|
+
* @returns The nullifier
|
|
2765
|
+
*/
|
|
2766
|
+
declare function computeNullifier(utxo: Utxo): Promise<bigint>;
|
|
2767
|
+
/**
|
|
2768
|
+
* Serialize a UTXO to bytes for encryption
|
|
2769
|
+
*/
|
|
2770
|
+
declare function serializeUtxo(utxo: Utxo): Uint8Array;
|
|
2771
|
+
/**
|
|
2772
|
+
* Deserialize a UTXO from bytes
|
|
2773
|
+
*/
|
|
2774
|
+
declare function deserializeUtxo(bytes: Uint8Array): Promise<Utxo>;
|
|
2775
|
+
/**
|
|
2776
|
+
* Convert bigint to hex string (64 chars, padded)
|
|
2777
|
+
*/
|
|
2778
|
+
declare function bigintToHex(value: bigint): string;
|
|
2779
|
+
/**
|
|
2780
|
+
* Convert hex string to bigint
|
|
2781
|
+
*/
|
|
2782
|
+
declare function hexToBigint(hex: string): bigint;
|
|
2783
|
+
/**
|
|
2784
|
+
* Convert bigint to 32-byte array (big-endian for circuits)
|
|
2785
|
+
*/
|
|
2786
|
+
declare function bigintToBytes32(value: bigint): Uint8Array;
|
|
2787
|
+
/**
|
|
2788
|
+
* Check if two UTXOs are equal (same commitment)
|
|
2789
|
+
*/
|
|
2790
|
+
declare function utxoEquals(a: Utxo, b: Utxo): Promise<boolean>;
|
|
2791
|
+
/**
|
|
2792
|
+
* Calculate total amount from an array of UTXOs
|
|
2793
|
+
*/
|
|
2794
|
+
declare function sumUtxoAmounts(utxos: Utxo[]): bigint;
|
|
2795
|
+
/**
|
|
2796
|
+
* Select UTXOs to cover a target amount
|
|
2797
|
+
*
|
|
2798
|
+
* @param available Available UTXOs (sorted by amount descending)
|
|
2799
|
+
* @param targetAmount Target amount to cover
|
|
2800
|
+
* @returns Selected UTXOs that cover the target, or null if insufficient
|
|
2801
|
+
*/
|
|
2802
|
+
declare function selectUtxos(available: Utxo[], targetAmount: bigint): Utxo[] | null;
|
|
2803
|
+
|
|
2804
|
+
/**
|
|
2805
|
+
* UTXO Transaction Methods
|
|
2806
|
+
*
|
|
2807
|
+
* This module provides high-level methods for UTXO transactions:
|
|
2808
|
+
* - transact(): Core UTXO transaction
|
|
2809
|
+
* - transfer(): Shield-to-shield transfer
|
|
2810
|
+
* - partialWithdraw(): Withdraw with change
|
|
2811
|
+
*/
|
|
2812
|
+
|
|
2813
|
+
declare const DEFAULT_TRANSACTION_CIRCUITS_URL = "https://cloak-circuits.s3.us-east-1.amazonaws.com/circuits/0.1.0";
|
|
2814
|
+
/**
|
|
2815
|
+
* Set circuits base path: local directory containing `transaction_js/` and `transaction_final.zkey`,
|
|
2816
|
+
* or an `http(s)` base URL to those artifacts (Node will download once per process to a temp dir).
|
|
2817
|
+
*/
|
|
2818
|
+
declare function setCircuitsPath(next: string): void;
|
|
2819
|
+
/**
|
|
2820
|
+
* Get the current circuits path
|
|
2821
|
+
*/
|
|
2822
|
+
declare function getCircuitsPath(): string;
|
|
2823
|
+
declare function computeChainNoteHash(publicAmount: bigint, extDataHash: bigint, noteTimestamp: bigint, noteCommitment: bigint): Promise<bigint>;
|
|
2824
|
+
/**
|
|
2825
|
+
* Compute extDataHash for binding proof to external parameters
|
|
2826
|
+
*
|
|
2827
|
+
* extDataHash = Poseidon(recipient, relayerFee, relayer)
|
|
2828
|
+
*/
|
|
2829
|
+
declare function computeExtDataHash(recipient: PublicKey | null, relayerFee: bigint, relayer: PublicKey | null): Promise<bigint>;
|
|
2830
|
+
/**
|
|
2831
|
+
* Options for transact operation
|
|
2832
|
+
*/
|
|
2833
|
+
interface TransactOptions {
|
|
2834
|
+
/** Connection to Solana */
|
|
2835
|
+
connection: Connection;
|
|
2836
|
+
/** Program ID */
|
|
2837
|
+
programId: PublicKey;
|
|
2838
|
+
/** Callback for progress updates */
|
|
2839
|
+
onProgress?: (status: string) => void;
|
|
2840
|
+
/** Callback for proof generation progress */
|
|
2841
|
+
onProofProgress?: (percent: number) => void;
|
|
2842
|
+
/** Relayer fee in lamports */
|
|
2843
|
+
relayerFee?: bigint;
|
|
2844
|
+
/** Relayer address for fee payment */
|
|
2845
|
+
relayer?: PublicKey;
|
|
2846
|
+
/** Relay service URL for submitting transactions */
|
|
2847
|
+
relayUrl?: string;
|
|
2848
|
+
/** Keypair of the depositor (signs the deposit transaction) - for programmatic use */
|
|
2849
|
+
depositorKeypair?: Keypair;
|
|
2850
|
+
/**
|
|
2851
|
+
* Wallet adapter sign function - for web app use
|
|
2852
|
+
* If provided (along with depositorPublicKey), user will sign deposits via wallet.
|
|
2853
|
+
* Accepts both legacy Transaction and VersionedTransaction (for V0 with ALTs).
|
|
2854
|
+
*/
|
|
2855
|
+
signTransaction?: <T extends Transaction | VersionedTransaction>(transaction: T) => Promise<T>;
|
|
2856
|
+
/** Wallet adapter signMessage for viewing-key registration auth. */
|
|
2857
|
+
signMessage?: (message: Uint8Array) => Promise<Uint8Array>;
|
|
2858
|
+
/** Public key of the depositor when using signTransaction */
|
|
2859
|
+
depositorPublicKey?: PublicKey;
|
|
2860
|
+
/** Wallet public key for relay submissions when depositor keypair isn't used. */
|
|
2861
|
+
walletPublicKey?: PublicKey;
|
|
2862
|
+
/** Maximum retries on RootNotFound error (default: 5) */
|
|
2863
|
+
maxRootRetries?: number;
|
|
2864
|
+
/** Delay between retries in ms (default: 3000) */
|
|
2865
|
+
retryDelayMs?: number;
|
|
2866
|
+
/**
|
|
2867
|
+
* Switchboard oracle queue for risk check on deposits.
|
|
2868
|
+
* Required when program has risk oracle enabled and depositor signs directly.
|
|
2869
|
+
*/
|
|
2870
|
+
riskOracleQueue?: PublicKey;
|
|
2871
|
+
/**
|
|
2872
|
+
* URL for fetching the risk quote instruction (Range/Switchboard).
|
|
2873
|
+
* Used for deposits when riskOracleQueue is set. The backend must return a signed
|
|
2874
|
+
* quote instruction for the depositor wallet so the program can verify at index 0.
|
|
2875
|
+
* Defaults to `${relayUrl}/range-quote` when relayUrl is set.
|
|
2876
|
+
*/
|
|
2877
|
+
riskQuoteUrl?: string;
|
|
2878
|
+
/**
|
|
2879
|
+
* Optional: provide the risk quote instruction directly (e.g. from your backend).
|
|
2880
|
+
* If set, used instead of riskQuoteUrl for deposits with risk oracle.
|
|
2881
|
+
*/
|
|
2882
|
+
getRiskQuoteInstruction?: (wallet: PublicKey) => Promise<TransactionInstruction>;
|
|
2883
|
+
/**
|
|
2884
|
+
* Pre-built ALT addresses (base58 strings) for V0 transactions.
|
|
2885
|
+
* When relayUrl is set, ALTs are also fetched from relay /health.
|
|
2886
|
+
* Pass explicitly (e.g. from your config) instead of relying on env.
|
|
2887
|
+
*/
|
|
2888
|
+
altAddresses?: string[];
|
|
2889
|
+
/**
|
|
2890
|
+
* Address lookup table accounts for V0 transactions.
|
|
2891
|
+
* Required when risk oracle deposits exceed the legacy 1232-byte transaction limit.
|
|
2892
|
+
* The ALT should contain common read-only accounts (sysvars, system program, etc.)
|
|
2893
|
+
* to compress account addresses from 32 bytes to 1-byte indices.
|
|
2894
|
+
*/
|
|
2895
|
+
addressLookupTableAccounts?: AddressLookupTableAccount[];
|
|
2896
|
+
/**
|
|
2897
|
+
* Optional Range.org API key for direct SDK-side quote fetching.
|
|
2898
|
+
*
|
|
2899
|
+
* Prefer relay-managed quoting via `relayUrl` (default), where the relay owns
|
|
2900
|
+
* the Range API key and serves signed quotes from `${relayUrl}/range-quote`.
|
|
2901
|
+
*
|
|
2902
|
+
* This option is intended for server-side fallback/no-relay scenarios only.
|
|
2903
|
+
* In browser/client apps, do not expose Range API keys.
|
|
2904
|
+
*
|
|
2905
|
+
* When relayUrl is set and riskQuoteUrl is not provided, SDK defaults to
|
|
2906
|
+
* relay `${relayUrl}/range-quote` regardless of rangeApiKey. This keeps
|
|
2907
|
+
* protocol-default risk checks working out of the box via relay.
|
|
2908
|
+
*
|
|
2909
|
+
* Priority: getRiskQuoteInstruction > riskQuoteUrl > rangeApiKey.
|
|
2910
|
+
* If getRiskQuoteInstruction or riskQuoteUrl is also set, those take precedence.
|
|
2911
|
+
*/
|
|
2912
|
+
rangeApiKey?: string;
|
|
2913
|
+
/**
|
|
2914
|
+
* Metadata bundle for compliance tracking.
|
|
2915
|
+
* On first transaction, should include viewing_key for compliance registration.
|
|
2916
|
+
*/
|
|
2917
|
+
metadataBundle?: {
|
|
2918
|
+
encrypted_user: string;
|
|
2919
|
+
encrypted_compliance: string;
|
|
2920
|
+
user_pubkey: string;
|
|
2921
|
+
commitment: string;
|
|
2922
|
+
timestamp: number;
|
|
2923
|
+
tx_type?: string;
|
|
2924
|
+
viewing_key?: string;
|
|
2925
|
+
};
|
|
2926
|
+
/**
|
|
2927
|
+
* Optional encrypted output notes to embed on-chain for chain-native scanning.
|
|
2928
|
+
* Each entry must be base64-encoded note bytes.
|
|
2929
|
+
*/
|
|
2930
|
+
encryptedNotes?: string[];
|
|
2931
|
+
/**
|
|
2932
|
+
* Optional nk (32 bytes, hex or bytes) for diversified chain note encryption (Phase 3).
|
|
2933
|
+
* When provided, 2 per-output encrypted notes are embedded on-chain.
|
|
2934
|
+
*/
|
|
2935
|
+
chainNoteViewingKeyNk?: string | Uint8Array;
|
|
2936
|
+
/**
|
|
2937
|
+
* Optional async getter for chain note viewing key. When provided (and chainNoteViewingKeyNk
|
|
2938
|
+
* is not set), the SDK calls this when building chain notes. Use this to avoid deriving and
|
|
2939
|
+
* passing nk at every call site — e.g. pass a getter from your key manager.
|
|
2940
|
+
*/
|
|
2941
|
+
getChainNoteViewingKeyNk?: () => Promise<string | Uint8Array | null>;
|
|
2942
|
+
/**
|
|
2943
|
+
* Cached Merkle tree from a previous transaction.
|
|
2944
|
+
* When provided, the SDK skips fetching commitments from the relay and uses this
|
|
2945
|
+
* tree directly for Merkle proof generation. The tree should already contain the
|
|
2946
|
+
* output commitments from the previous transaction (returned in TransactResult.merkleTree).
|
|
2947
|
+
* This eliminates the need for `waitForCommitmentIndex` between sequential transactions.
|
|
2948
|
+
*/
|
|
2949
|
+
cachedMerkleTree?: MerkleTree;
|
|
2950
|
+
/**
|
|
2951
|
+
* Use chain indexing for Merkle tree instead of relay.
|
|
2952
|
+
* When true, commitments are fetched from chain via getSignaturesForAddress (slower).
|
|
2953
|
+
* Use when relay is unavailable or for no-relay mode. In browser, chain indexing is disabled.
|
|
2954
|
+
*/
|
|
2955
|
+
useChainForMerkle?: boolean;
|
|
2956
|
+
/**
|
|
2957
|
+
* Use unique nullifiers per run (timestamp-based salts for zero UTXOs).
|
|
2958
|
+
* Set when using surfpool or validators that don't support reset - avoids 0x1020 DoubleSpend
|
|
2959
|
+
* across runs. May trigger line 146 in some environments; if so, omit this option.
|
|
2960
|
+
*/
|
|
2961
|
+
useUniqueNullifiers?: boolean;
|
|
2962
|
+
/**
|
|
2963
|
+
* Optional DEX allow-list for swaps (Jupiter `dexes`).
|
|
2964
|
+
* Example: ["Orca V2", "Raydium CLMM"]
|
|
2965
|
+
*/
|
|
2966
|
+
swapDexes?: string[];
|
|
2967
|
+
/**
|
|
2968
|
+
* Optional DEX block-list for swaps (Jupiter `excludeDexes`).
|
|
2969
|
+
*/
|
|
2970
|
+
swapExcludeDexes?: string[];
|
|
2971
|
+
/**
|
|
2972
|
+
* Extra route retries inside the relay swap handler (0-5).
|
|
2973
|
+
* Default relay behavior is 2 extra retries when not provided.
|
|
2974
|
+
*/
|
|
2975
|
+
swapRouteRetryAttempts?: number;
|
|
2976
|
+
/**
|
|
2977
|
+
* Optional worker retry budget override for swap TX2 execution (1-10).
|
|
2978
|
+
* Higher values allow more background retries before final failure.
|
|
2979
|
+
*/
|
|
2980
|
+
swapMaxRetries?: number;
|
|
2981
|
+
/**
|
|
2982
|
+
* Slippage tolerance in basis points for swaps (passed to relay for Jupiter quotes).
|
|
2983
|
+
* Defaults to 500 bps (5%) if not provided.
|
|
2984
|
+
*/
|
|
2985
|
+
swapSlippageBps?: number;
|
|
2986
|
+
/**
|
|
2987
|
+
* Max polling attempts when waiting for swap TX2 completion.
|
|
2988
|
+
* Defaults to 60 attempts.
|
|
2989
|
+
*/
|
|
2990
|
+
swapStatusMaxAttempts?: number;
|
|
2991
|
+
/**
|
|
2992
|
+
* Poll interval (ms) when waiting for swap TX2 completion.
|
|
2993
|
+
* Defaults to 2000ms.
|
|
2994
|
+
*/
|
|
2995
|
+
swapStatusDelayMs?: number;
|
|
2996
|
+
/** Enforce viewing-key registration before any protocol transaction (default: true). */
|
|
2997
|
+
enforceViewingKeyRegistration?: boolean;
|
|
2998
|
+
/**
|
|
2999
|
+
* Use chain root instead of relay root for proof generation.
|
|
3000
|
+
* When true, readMerkleTreeState skips the relay /merkle-root and uses the on-chain root.
|
|
3001
|
+
* Use when relay may be behind the chain (e.g. commitment_sync lag) to avoid ProofInvalid.
|
|
3002
|
+
*/
|
|
3003
|
+
useChainRootForProof?: boolean;
|
|
3004
|
+
}
|
|
3005
|
+
/** Switchboard-style response: pre-built instruction. */
|
|
3006
|
+
interface RiskQuoteInstructionResponse {
|
|
3007
|
+
instruction: {
|
|
3008
|
+
programId: string;
|
|
3009
|
+
keys: Array<{
|
|
3010
|
+
pubkey: string;
|
|
3011
|
+
isSigner: boolean;
|
|
3012
|
+
isWritable: boolean;
|
|
3013
|
+
}>;
|
|
3014
|
+
data: string;
|
|
3015
|
+
};
|
|
3016
|
+
}
|
|
3017
|
+
/**
|
|
3018
|
+
* Fetch the risk quote instruction from a backend (e.g. relay /risk-quote).
|
|
3019
|
+
* The backend should call Switchboard's fetchQuoteIx for the given wallet
|
|
3020
|
+
* (Range Risk API) and return the serialized instruction.
|
|
3021
|
+
* See: https://www.range.org/blog/integrate-range-onchain-risk-verifier-into-your-solana-program
|
|
3022
|
+
*/
|
|
3023
|
+
declare function fetchRiskQuoteInstruction(riskQuoteUrl: string, wallet: PublicKey, options?: {
|
|
3024
|
+
recipient?: PublicKey;
|
|
3025
|
+
amount?: bigint;
|
|
3026
|
+
token?: PublicKey;
|
|
3027
|
+
}): Promise<TransactionInstruction>;
|
|
3028
|
+
declare function transact(params: TransactParams, options: TransactOptions): Promise<TransactResult>;
|
|
3029
|
+
/**
|
|
3030
|
+
* Execute a shield-to-shield transfer
|
|
3031
|
+
*
|
|
3032
|
+
* Transfers funds from your UTXOs to another recipient's public key,
|
|
3033
|
+
* keeping everything within the shielded pool.
|
|
3034
|
+
*
|
|
3035
|
+
* @param inputUtxos Your UTXOs to spend
|
|
3036
|
+
* @param recipientPubkey Recipient's UTXO public key
|
|
3037
|
+
* @param amount Amount to transfer
|
|
3038
|
+
* @param options Transaction options
|
|
3039
|
+
*/
|
|
3040
|
+
declare function transfer(inputUtxos: Utxo[], recipientPubkey: bigint, amount: bigint, options: TransactOptions): Promise<TransactResult>;
|
|
3041
|
+
/**
|
|
3042
|
+
* Execute a partial withdrawal
|
|
3043
|
+
*
|
|
3044
|
+
* Withdraws a portion of funds to an external Solana address,
|
|
3045
|
+
* keeping the remainder shielded.
|
|
3046
|
+
*
|
|
3047
|
+
* @param inputUtxos Your UTXOs to spend
|
|
3048
|
+
* @param recipient External Solana address
|
|
3049
|
+
* @param withdrawAmount Amount to withdraw
|
|
3050
|
+
* @param options Transaction options
|
|
3051
|
+
*/
|
|
3052
|
+
declare function partialWithdraw(inputUtxos: Utxo[], recipient: PublicKey, withdrawAmount: bigint, options: TransactOptions): Promise<TransactResult>;
|
|
3053
|
+
/**
|
|
3054
|
+
* Execute a full withdrawal
|
|
3055
|
+
*
|
|
3056
|
+
* Withdraws all funds from UTXOs to an external address.
|
|
3057
|
+
*
|
|
3058
|
+
* @param inputUtxos Your UTXOs to spend
|
|
3059
|
+
* @param recipient External Solana address
|
|
3060
|
+
* @param options Transaction options
|
|
3061
|
+
*/
|
|
3062
|
+
declare function fullWithdraw(inputUtxos: Utxo[], recipient: PublicKey, options: TransactOptions): Promise<TransactResult>;
|
|
3063
|
+
/**
|
|
3064
|
+
* Parameters for UTXO swap operation
|
|
3065
|
+
*/
|
|
3066
|
+
interface UtxoSwapParams {
|
|
3067
|
+
/** UTXOs to spend */
|
|
3068
|
+
inputUtxos: Utxo[];
|
|
3069
|
+
/** Optional change UTXO to create (remaining shielded funds) */
|
|
3070
|
+
changeUtxo?: Utxo;
|
|
3071
|
+
/** Amount to swap (lamports) */
|
|
3072
|
+
swapAmount: bigint;
|
|
3073
|
+
/** Output token mint address */
|
|
3074
|
+
outputMint: PublicKey;
|
|
3075
|
+
/** Recipient's Associated Token Account for output tokens */
|
|
3076
|
+
recipientAta: PublicKey;
|
|
3077
|
+
/** Optional recipient wallet (used by relay to create ATA if missing) */
|
|
3078
|
+
recipientWallet?: PublicKey;
|
|
3079
|
+
/** Minimum output amount (slippage protection) */
|
|
3080
|
+
minOutputAmount: bigint;
|
|
3081
|
+
}
|
|
3082
|
+
/**
|
|
3083
|
+
* Result of a UTXO swap operation
|
|
3084
|
+
*/
|
|
3085
|
+
interface UtxoSwapResult extends TransactResult {
|
|
3086
|
+
/** SwapState PDA address (used for executing the actual swap) */
|
|
3087
|
+
swapStatePda: string;
|
|
3088
|
+
/** Nullifier used for SwapState derivation (hex) */
|
|
3089
|
+
nullifier: string;
|
|
3090
|
+
/** Relay request ID for swap execution status */
|
|
3091
|
+
requestId?: string;
|
|
3092
|
+
}
|
|
3093
|
+
/**
|
|
3094
|
+
* Execute a UTXO swap withdrawal
|
|
3095
|
+
*
|
|
3096
|
+
* This spends input UTXOs and creates a SwapState PDA for swapping SOL to SPL tokens.
|
|
3097
|
+
* After this transaction, the relay can execute:
|
|
3098
|
+
* 1. PrepareSwapSol - Wrap SOL to wSOL
|
|
3099
|
+
* 2. ExecuteSwapViaOrca - Execute the swap on Orca
|
|
3100
|
+
*
|
|
3101
|
+
* @param params Swap parameters
|
|
3102
|
+
* @param options Transaction options
|
|
3103
|
+
* @returns UtxoSwapResult with SwapState PDA for executing the swap
|
|
3104
|
+
*/
|
|
3105
|
+
declare function swapUtxo(params: UtxoSwapParams, options: TransactOptions): Promise<UtxoSwapResult>;
|
|
3106
|
+
/**
|
|
3107
|
+
* Execute a swap with change
|
|
3108
|
+
*
|
|
3109
|
+
* Convenience function that creates a change UTXO automatically.
|
|
3110
|
+
*
|
|
3111
|
+
* @param inputUtxos UTXOs to spend
|
|
3112
|
+
* @param swapAmount Amount to swap
|
|
3113
|
+
* @param outputMint Output token mint
|
|
3114
|
+
* @param recipientAta Recipient's ATA
|
|
3115
|
+
* @param minOutputAmount Minimum output (slippage protection)
|
|
3116
|
+
* @param options Transaction options
|
|
3117
|
+
*/
|
|
3118
|
+
declare function swapWithChange(inputUtxos: Utxo[], swapAmount: bigint, outputMint: PublicKey, recipientAta: PublicKey, minOutputAmount: bigint, options: TransactOptions, recipientWallet?: PublicKey): Promise<UtxoSwapResult>;
|
|
3119
|
+
|
|
3120
|
+
/**
|
|
3121
|
+
* Compact deterministic chain note format (current format only).
|
|
3122
|
+
*
|
|
3123
|
+
* Envelope: [version 1][ciphertext (timestamp + tag)]
|
|
3124
|
+
*/
|
|
3125
|
+
type ChainNoteTxType = "deposit" | "withdraw" | "transfer" | "swap" | "unknown";
|
|
3126
|
+
interface CompactChainNote {
|
|
3127
|
+
timestamp: bigint;
|
|
3128
|
+
commitment: string;
|
|
3129
|
+
}
|
|
3130
|
+
/**
|
|
3131
|
+
* Encrypt a compact deterministic chain note.
|
|
3132
|
+
* Payload is minimal to keep relay withdrawals under Solana packet size limits.
|
|
3133
|
+
* Envelope: [version 1][ciphertext (timestamp + tag)]
|
|
3134
|
+
*/
|
|
3135
|
+
declare function encryptCompactChainNote(timestamp: bigint, nk: Uint8Array, commitmentHex: string): Promise<Uint8Array>;
|
|
3136
|
+
/**
|
|
3137
|
+
* Decrypt a compact deterministic chain note with candidate output commitments.
|
|
3138
|
+
* Tries each commitment-derived key until AES-GCM authentication succeeds.
|
|
3139
|
+
*/
|
|
3140
|
+
declare function decryptCompactChainNote(noteBytes: Uint8Array, nk: Uint8Array, candidateCommitments: string[]): Promise<CompactChainNote>;
|
|
3141
|
+
declare function chainNoteToBase64(noteBytes: Uint8Array): string;
|
|
3142
|
+
declare function chainNoteFromBase64(base64: string): Uint8Array;
|
|
3143
|
+
|
|
3144
|
+
/**
|
|
3145
|
+
* Transaction Scanner
|
|
3146
|
+
*
|
|
3147
|
+
* Scans on-chain transactions for the Cloak shield pool program,
|
|
3148
|
+
* extracts chain note envelopes from instruction data, and
|
|
3149
|
+
* trial-decrypts them with the caller's viewing key.
|
|
3150
|
+
*
|
|
3151
|
+
* This module is fully autonomous — it talks directly to a Solana
|
|
3152
|
+
* RPC node and does not depend on the relay.
|
|
3153
|
+
*/
|
|
3154
|
+
|
|
3155
|
+
/** A single decoded & verified transaction record. */
|
|
3156
|
+
interface ScannedTransaction {
|
|
3157
|
+
/** Transaction type (deposit / withdraw / transfer / swap) */
|
|
3158
|
+
txType: ChainNoteTxType;
|
|
3159
|
+
/** Absolute amount in lamports (gross — the full amount leaving the pool) */
|
|
3160
|
+
amount: bigint;
|
|
3161
|
+
/** Protocol fee in lamports (non-zero only for withdrawals/swaps) */
|
|
3162
|
+
fee: bigint;
|
|
3163
|
+
/** Net amount received by the recipient (amount - fee). For deposits this equals amount. */
|
|
3164
|
+
netAmount: bigint;
|
|
3165
|
+
/** Millisecond timestamp embedded in the chain note */
|
|
3166
|
+
timestamp: bigint;
|
|
3167
|
+
/** Recipient Solana address (base58) */
|
|
3168
|
+
recipient: string;
|
|
3169
|
+
/** Output commitment hex */
|
|
3170
|
+
commitment: string;
|
|
3171
|
+
/** Solana transaction signature */
|
|
3172
|
+
signature: string;
|
|
3173
|
+
/** Running balance in lamports (computed after sorting) */
|
|
3174
|
+
runningBalance: bigint;
|
|
3175
|
+
/** Input asset mint for this transaction (pool mint) */
|
|
3176
|
+
mint: string;
|
|
3177
|
+
/** Input asset decimals */
|
|
3178
|
+
decimals: number;
|
|
3179
|
+
/** Input asset symbol (best effort) */
|
|
3180
|
+
symbol: string;
|
|
3181
|
+
/** Swap output mint (when txType=swap) */
|
|
3182
|
+
outputMint?: string;
|
|
3183
|
+
/** Swap output symbol (best effort) */
|
|
3184
|
+
outputSymbol?: string;
|
|
3185
|
+
}
|
|
3186
|
+
/** Summary statistics for a scan result. */
|
|
3187
|
+
interface ScanSummary {
|
|
3188
|
+
totalDeposits: bigint;
|
|
3189
|
+
totalWithdrawals: bigint;
|
|
3190
|
+
/** Total protocol fees paid across all withdrawals/swaps */
|
|
3191
|
+
totalFees: bigint;
|
|
3192
|
+
netChange: bigint;
|
|
3193
|
+
transactionCount: number;
|
|
3194
|
+
finalBalance: bigint;
|
|
3195
|
+
}
|
|
3196
|
+
/** Full result of a scan operation. */
|
|
3197
|
+
interface ScanResult {
|
|
3198
|
+
transactions: ScannedTransaction[];
|
|
3199
|
+
summary: ScanSummary;
|
|
3200
|
+
/**
|
|
3201
|
+
* The most recent (newest) signature that was scanned.
|
|
3202
|
+
* Pass this as `untilSignature` in the next scan to only fetch new transactions.
|
|
3203
|
+
*/
|
|
3204
|
+
lastSignature?: string;
|
|
3205
|
+
/** Number of RPC getTransaction calls actually made (for diagnostics). */
|
|
3206
|
+
rpcCallsMade: number;
|
|
3207
|
+
}
|
|
3208
|
+
/** Options for `scanTransactions`. */
|
|
3209
|
+
interface ScanOptions {
|
|
3210
|
+
/** Solana RPC connection */
|
|
3211
|
+
connection: Connection;
|
|
3212
|
+
/** Cloak shield pool program ID */
|
|
3213
|
+
programId: PublicKey;
|
|
3214
|
+
/** nk (32 bytes) for diversified chain note decryption (Phase 3) */
|
|
3215
|
+
viewingKeyNk: Uint8Array;
|
|
3216
|
+
/** Maximum number of signatures to scan. Omit or set to 0 for no limit (scan everything). */
|
|
3217
|
+
limit?: number;
|
|
3218
|
+
/** Only include transactions after this timestamp (ms) */
|
|
3219
|
+
afterTimestamp?: number;
|
|
3220
|
+
/** Only include transactions before this timestamp (ms) */
|
|
3221
|
+
beforeTimestamp?: number;
|
|
3222
|
+
/**
|
|
3223
|
+
* Resume scanning from after this signature (exclusive).
|
|
3224
|
+
* Pass the `lastSignature` from a previous scan result to only fetch new transactions.
|
|
3225
|
+
* This is the most impactful optimization — avoids re-scanning the entire history.
|
|
3226
|
+
*/
|
|
3227
|
+
untilSignature?: string;
|
|
3228
|
+
/** Progress callback — called once per processed transaction */
|
|
3229
|
+
onProgress?: (processed: number, total: number) => void;
|
|
3230
|
+
/** Batch size for getTransaction calls (default 50) */
|
|
3231
|
+
batchSize?: number;
|
|
3232
|
+
/** Optional status callback for phase updates (signature fetch / tx fetch / done). */
|
|
3233
|
+
onStatus?: (status: string) => void;
|
|
3234
|
+
/** When true, log why each transaction is skipped (for debugging) */
|
|
3235
|
+
debug?: boolean;
|
|
3236
|
+
/**
|
|
3237
|
+
* Wallet public key (base58) for fallback detection of note-less transactions.
|
|
3238
|
+
* When provided, the scanner can detect withdrawals that lack chain notes by
|
|
3239
|
+
* matching the wallet's associated token account against the on-chain recipient ATA.
|
|
3240
|
+
*/
|
|
3241
|
+
walletPublicKey?: string;
|
|
3242
|
+
}
|
|
3243
|
+
/**
|
|
3244
|
+
* Scan on-chain transactions for the Cloak program, extract chain
|
|
3245
|
+
* notes, trial-decrypt with the provided viewing key, verify integrity,
|
|
3246
|
+
* and return a sorted list of the caller's transactions.
|
|
3247
|
+
*
|
|
3248
|
+
* This is fully self-contained — it only needs a Solana RPC connection
|
|
3249
|
+
* and the user's viewing key (private).
|
|
3250
|
+
*/
|
|
3251
|
+
declare function scanTransactions(opts: ScanOptions): Promise<ScanResult>;
|
|
3252
|
+
/** JSON-serializable compliance report (numbers instead of bigint). Used for cache and display. */
|
|
3253
|
+
interface ComplianceReport {
|
|
3254
|
+
transactions: Array<{
|
|
3255
|
+
txType: string;
|
|
3256
|
+
amount: number;
|
|
3257
|
+
fee: number;
|
|
3258
|
+
netAmount: number;
|
|
3259
|
+
runningBalance: number;
|
|
3260
|
+
timestamp: number;
|
|
3261
|
+
recipient: string;
|
|
3262
|
+
commitment: string;
|
|
3263
|
+
signature?: string;
|
|
3264
|
+
mint?: string;
|
|
3265
|
+
decimals?: number;
|
|
3266
|
+
symbol?: string;
|
|
3267
|
+
outputMint?: string;
|
|
3268
|
+
outputSymbol?: string;
|
|
3269
|
+
}>;
|
|
3270
|
+
summary: {
|
|
3271
|
+
totalDeposits: number;
|
|
3272
|
+
totalWithdrawals: number;
|
|
3273
|
+
totalFees: number;
|
|
3274
|
+
netChange: number;
|
|
3275
|
+
transactionCount: number;
|
|
3276
|
+
finalBalance: number;
|
|
3277
|
+
};
|
|
3278
|
+
lastSignature?: string;
|
|
3279
|
+
rpcCallsMade: number;
|
|
3280
|
+
}
|
|
3281
|
+
/** Convert ScanResult to JSON-serializable ComplianceReport. Use for cache and display. */
|
|
3282
|
+
declare function toComplianceReport(result: ScanResult): ComplianceReport;
|
|
3283
|
+
/** Format compliance report as CSV for export. */
|
|
3284
|
+
declare function formatComplianceCsv(report: ComplianceReport): string;
|
|
3285
|
+
|
|
3286
|
+
/**
|
|
3287
|
+
* Automatic UTXO Wallet Manager
|
|
3288
|
+
*
|
|
3289
|
+
* Provides ZCash-like automatic UTXO management:
|
|
3290
|
+
* - Tracks all UTXOs locally
|
|
3291
|
+
* - Auto-selects optimal inputs for transactions
|
|
3292
|
+
* - Handles change automatically
|
|
3293
|
+
* - User just sees a simple balance
|
|
3294
|
+
*/
|
|
3295
|
+
|
|
3296
|
+
/**
|
|
3297
|
+
* Stored UTXO with metadata for wallet management
|
|
3298
|
+
*/
|
|
3299
|
+
interface WalletUtxo extends Utxo {
|
|
3300
|
+
/** When this UTXO was discovered */
|
|
3301
|
+
discoveredAt: number;
|
|
3302
|
+
/** Merkle tree index (if known) */
|
|
3303
|
+
index?: number;
|
|
3304
|
+
/** Whether this UTXO has been spent */
|
|
3305
|
+
isSpent: boolean;
|
|
3306
|
+
/** When it was spent (if applicable) */
|
|
3307
|
+
spentAt?: number;
|
|
3308
|
+
/** Optional: human-readable label */
|
|
3309
|
+
label?: string;
|
|
3310
|
+
}
|
|
3311
|
+
/**
|
|
3312
|
+
* Automatic UTXO Wallet
|
|
3313
|
+
*
|
|
3314
|
+
* Manages UTXOs automatically like ZCash:
|
|
3315
|
+
* - You don't pick UTXOs, you just specify amount
|
|
3316
|
+
* - Wallet picks optimal inputs
|
|
3317
|
+
* - Change is handled automatically
|
|
3318
|
+
*/
|
|
3319
|
+
declare class UtxoWallet {
|
|
3320
|
+
private wallets;
|
|
3321
|
+
private viewingKey?;
|
|
3322
|
+
constructor(viewingKey?: Uint8Array);
|
|
3323
|
+
/**
|
|
3324
|
+
* Add a UTXO to the wallet (discovered from chain or created)
|
|
3325
|
+
*/
|
|
3326
|
+
addUtxo(utxo: Utxo, mint?: PublicKey): void;
|
|
3327
|
+
/**
|
|
3328
|
+
* Mark a UTXO as spent
|
|
3329
|
+
*/
|
|
3330
|
+
markSpent(utxo: Utxo, mint?: PublicKey): void;
|
|
3331
|
+
/**
|
|
3332
|
+
* Get total balance (unspent only)
|
|
3333
|
+
*/
|
|
3334
|
+
getBalance(mint?: PublicKey): bigint;
|
|
3335
|
+
/**
|
|
3336
|
+
* Get all unspent UTXOs
|
|
3337
|
+
*/
|
|
3338
|
+
getUnspentUtxos(mint?: PublicKey): WalletUtxo[];
|
|
3339
|
+
/**
|
|
3340
|
+
* Automatically select UTXOs for a transaction
|
|
3341
|
+
*
|
|
3342
|
+
* Strategy:
|
|
3343
|
+
* 1. Try to find exact match (avoid change)
|
|
3344
|
+
* 2. Use largest UTXO first (reduce UTXO count)
|
|
3345
|
+
* 3. Combine smallest UTXOs (consolidation)
|
|
3346
|
+
*
|
|
3347
|
+
* Returns selected inputs and change amount
|
|
3348
|
+
*/
|
|
3349
|
+
selectInputs(amount: bigint, mint?: PublicKey, strategy?: "exact" | "largest" | "smallest"): {
|
|
3350
|
+
inputs: Utxo[];
|
|
3351
|
+
change: bigint;
|
|
3352
|
+
total: bigint;
|
|
3353
|
+
};
|
|
3354
|
+
/**
|
|
3355
|
+
* Create a simple "send" transaction
|
|
3356
|
+
*
|
|
3357
|
+
* Just like ZCash: specify amount and recipient, wallet handles the rest
|
|
3358
|
+
*/
|
|
3359
|
+
prepareSend(amount: bigint, recipient: PublicKey, mint?: PublicKey, options?: {
|
|
3360
|
+
strategy?: "exact" | "largest" | "smallest";
|
|
3361
|
+
}): Promise<{
|
|
3362
|
+
inputs: Utxo[];
|
|
3363
|
+
outputs: Utxo[];
|
|
3364
|
+
changeAmount: bigint;
|
|
3365
|
+
}>;
|
|
3366
|
+
/**
|
|
3367
|
+
* Create a UTXO for a recipient
|
|
3368
|
+
*/
|
|
3369
|
+
private createOutputUtxo;
|
|
3370
|
+
/**
|
|
3371
|
+
* Create change output for self
|
|
3372
|
+
*/
|
|
3373
|
+
private createChangeUtxo;
|
|
3374
|
+
/**
|
|
3375
|
+
* Serialize wallet to JSON for storage
|
|
3376
|
+
*/
|
|
3377
|
+
serialize(): string;
|
|
3378
|
+
/**
|
|
3379
|
+
* Deserialize wallet from JSON
|
|
3380
|
+
*/
|
|
3381
|
+
static deserialize(json: string): UtxoWallet;
|
|
3382
|
+
/**
|
|
3383
|
+
* Get wallet statistics
|
|
3384
|
+
*/
|
|
3385
|
+
getStats(mint?: PublicKey): {
|
|
3386
|
+
totalUtxos: number;
|
|
3387
|
+
unspentUtxos: number;
|
|
3388
|
+
spentUtxos: number;
|
|
3389
|
+
totalBalance: bigint;
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
/**
|
|
3393
|
+
* Simple balance-only interface for apps
|
|
3394
|
+
*
|
|
3395
|
+
* Apps can use this instead of dealing with UTXOs directly
|
|
3396
|
+
*/
|
|
3397
|
+
declare class SimpleWallet {
|
|
3398
|
+
private utxoWallet;
|
|
3399
|
+
constructor(viewingKey?: Uint8Array);
|
|
3400
|
+
/**
|
|
3401
|
+
* Get balance
|
|
3402
|
+
*/
|
|
3403
|
+
getBalance(): bigint;
|
|
3404
|
+
/**
|
|
3405
|
+
* Send amount to recipient
|
|
3406
|
+
* Returns transaction parameters ready for transact()
|
|
3407
|
+
*/
|
|
3408
|
+
send(amount: bigint, recipient: PublicKey): Promise<{
|
|
3409
|
+
inputs: Utxo[];
|
|
3410
|
+
outputs: Utxo[];
|
|
3411
|
+
change: bigint;
|
|
3412
|
+
}>;
|
|
3413
|
+
/**
|
|
3414
|
+
* Scan and sync UTXOs from chain
|
|
3415
|
+
* (Would be implemented with chain scanning logic)
|
|
3416
|
+
*/
|
|
3417
|
+
sync(): Promise<void>;
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3420
|
+
/**
|
|
3421
|
+
* Cloak SDK - TypeScript SDK for Private Transactions on Solana
|
|
3422
|
+
*
|
|
3423
|
+
* @packageDocumentation
|
|
3424
|
+
*/
|
|
3425
|
+
|
|
3426
|
+
declare const VERSION = "1.0.0";
|
|
3427
|
+
/** True when scanner supports TransactSwap (tag 1). Check this to verify the correct SDK bundle is loaded. */
|
|
3428
|
+
declare const SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
3429
|
+
|
|
3430
|
+
export { CLOAK_PROGRAM_ID, type ChainNoteTxType, type CircuitVerificationResult, type CloakConfig, CloakError, type CloakKeyPair, type CloakNote, CloakSDK, type CommitmentEntry, type CommitmentsResponse, type CompactChainNote, type ComplianceReport, type ComplianceTxType, DEFAULT_CIRCUITS_URL, DEFAULT_TRANSACTION_CIRCUITS_URL, type DepositInstructionParams, type DepositOptions, type DepositResult, type DepositStatus, EXPECTED_CIRCUIT_HASHES, type EncryptedMetadataBundle, type EncryptedNote$1 as EncryptedNote, type ErrorCategory, type ExpandedSpendKey, FIXED_FEE_LAMPORTS, type Groth16Proof, LAMPORTS_PER_SOL, LocalStorageAdapter, type LogLevel, type Logger, MERKLE_TREE_HEIGHT, MIN_DEPOSIT_LAMPORTS, type MasterKey, type MaxLengthArray, MemoryStorageAdapter, type MerkleProof, type MerkleRootResponse, MerkleTree, NATIVE_SOL_MINT, type Network, type NoteData, type OnchainMerkleProof, type PendingDeposit, type PendingWithdrawal, type ProofResult, RelayService, type RiskQuoteInstructionResponse, RootNotFoundError, SCANNER_SUPPORTS_TRANSACT_SWAP, SIGN_IN_MESSAGE, type ScanOptions, type ScanResult, type ScanSummary, type ScannedTransaction, ShieldPoolErrors, type ShieldPoolPDAs, SimpleWallet, type SpendKey, type StorageAdapter, type SwapOptions, type SwapParams, type SwapResult, type TransactOptions, type TransactParams, type TransactResult, type TransactionMetadata, type Transfer, type TransferOptions, type TransferResult, type TxStatus, type UserFriendlyError, type Utxo, type EncryptedNote as UtxoEncryptedNote, type UtxoKeypair, type UtxoSwapParams, type UtxoSwapResult, UtxoWallet, VARIABLE_FEE_DENOMINATOR, VARIABLE_FEE_NUMERATOR, VARIABLE_FEE_RATE, VERSION, type ViewKey, type ViewingKeyPair, type WalletAdapter, type WalletUtxo, type WithdrawOptions, type WithdrawRegularInputs, type WithdrawSubmissionResult, type WithdrawSwapInputs, areCircuitsAvailable, bigintToBytes32$1 as bigintToBytes32, bigintToHex, buildMerkleTree, buildMerkleTreeFromChain, buildMerkleTreeFromRelay, buildPublicInputsBytes, bytesToHex, calculateFee, calculateFeeBigint, calculateRelayFee, chainNoteFromBase64, chainNoteToBase64, cleanupStalePendingOperations, clearPendingDeposits, clearPendingWithdrawals, computeChainNoteHash, computeCommitment$1 as computeCommitment, computeExtDataHash, computeMerkleRoot, computeNullifier$1 as computeNullifier, computeNullifierAsync, computeNullifierSync, computeOutputsHash, computeOutputsHashAsync, computeOutputsHashSync, computeProofForLatestDeposit, computeProofFromChain, computeSignature, computeSwapOutputsHash, computeSwapOutputsHashAsync, computeSwapOutputsHashSync, computeCommitment as computeUtxoCommitment, computeNullifier as computeUtxoNullifier, copyNoteToClipboard, createCloakError, createDepositInstruction, createLogger, createUtxo, createZeroUtxo, decryptCompactChainNote, decryptComplianceMetadataWithMasterKey, decryptTransactionMetadata, deriveDiversifiedViewingKey, deriveDiversifier, derivePublicKey, deriveSpendKey, deriveUserCompliancePublicKey, deriveUserComplianceScalar, deriveUtxoKeypairFromSpendKey, deriveViewKey, deriveViewingKeyFromNk, deriveViewingKeyFromSpendKey, deriveViewingKeyFromUtxoPrivateKey, deserializeUtxo, detectNetworkFromRpcUrl, downloadNote, encodeNoteSimple, encryptCompactChainNote, encryptNoteForRecipient, encryptTransactionMetadata, encryptTransactionMetadataBundle, expandSpendKey, exportKeys, exportNote, exportWalletKeys, fetchCommitments, fetchRiskQuoteInstruction, fetchRiskQuoteIx, filterNotesByNetwork, filterWithdrawableNotes, findNoteByCommitment, formatAmount, formatComplianceCsv, formatErrorForLogging, formatSol, fullWithdraw, generateCloakKeys, generateCommitment, generateCommitmentAsync, generateMasterSeed, generateNote, generateNoteFromWallet, generateUtxoKeypair, generateViewingKeyPair, generateWithdrawRegularProof, generateWithdrawSwapProof, getAddressExplorerUrl, getCircuitsPath, getDefaultCircuitsPath, getDistributableAmount, getExplorerUrl, getNkFromUtxoPrivateKey, getNullifierPDA, getPendingOperationsSummary, getPublicKey, getPublicViewKey, getRecipientAmount, getRpcUrlForNetwork, getShieldPoolPDAs, getSwapStatePDA, getViewKey, hasPendingOperations, hexToBigint$1 as hexToBigint, hexToBytes, importKeys, importWalletKeys, isDebugEnabled, isRootNotFoundError, isValidHex, isValidRpcUrl, isValidSolanaAddress, isWithdrawAmountSufficient, isWithdrawable, keypairToAdapter, loadPendingDeposits, loadPendingWithdrawals, parseAmount, parseError, parseNote, parseRelayErrorResponse, parseTransactionError, partialWithdraw, poseidonHash, preflightCheck, prepareEncryptedOutput, prepareEncryptedOutputForRecipient, proofToBytes, pubkeyToFieldElement, pubkeyToLimbs, randomBytes, randomFieldElement, readMerkleTreeState, registerViewingKey, removePendingDeposit, removePendingWithdrawal, savePendingDeposit, savePendingWithdrawal, scanNotesForWallet, scanTransactions, sdkLogger, selectUtxos, sendTransaction, serializeNote, serializeUtxo, setCircuitsPath, setDebugMode, signTransaction, splitTo2Limbs, sumUtxoAmounts, swapUtxo, swapWithChange, toComplianceReport, transact, transfer, truncate, tryDecryptNote, updateNoteWithDeposit, updatePendingDeposit, updatePendingWithdrawal, bigintToBytes32 as utxoBigintToBytes32, utxoEquals, hexToBigint as utxoHexToBigint, validateDepositParams, validateNote, validateOutputsSum, validateRoot, validateTransfers, validateWalletConnected, validateWithdrawableNote, verifyAllCircuits, verifyCircuitIntegrity, waitForRoot, withTiming };
|