@cloak.dev/sdk 0.1.5 → 0.1.6
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/CHANGELOG.md +173 -0
- package/README.md +183 -96
- package/dist/index.cjs +295 -2255
- package/dist/index.d.cts +442 -1511
- package/dist/index.d.ts +442 -1511
- package/dist/index.js +251 -2160
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,376 +1,5 @@
|
|
|
1
1
|
import { PublicKey, Transaction, Connection, AddressLookupTableAccount, TransactionInstruction, Keypair, SendOptions, VersionedTransaction } from '@solana/web3.js';
|
|
2
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
3
|
/**
|
|
375
4
|
* Cloak Key Hierarchy (v2.0)
|
|
376
5
|
*
|
|
@@ -412,684 +41,353 @@ interface NoteData {
|
|
|
412
41
|
commitment: string;
|
|
413
42
|
}
|
|
414
43
|
/**
|
|
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
|
-
* ```
|
|
44
|
+
* Generate a new master seed from secure randomness
|
|
969
45
|
*/
|
|
970
|
-
declare function
|
|
46
|
+
declare function generateMasterSeed(): MasterKey;
|
|
971
47
|
/**
|
|
972
|
-
*
|
|
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
|
-
* ```
|
|
48
|
+
* Derive spend key from master seed
|
|
983
49
|
*/
|
|
984
|
-
declare function
|
|
50
|
+
declare function deriveSpendKey(masterSeed: Uint8Array): SpendKey;
|
|
985
51
|
/**
|
|
986
|
-
*
|
|
987
|
-
*
|
|
988
|
-
* @param outputs - Array of output amounts
|
|
989
|
-
* @param expectedTotal - Expected total amount
|
|
990
|
-
* @returns True if amounts match
|
|
52
|
+
* Derive view key from spend key
|
|
991
53
|
*/
|
|
992
|
-
declare function
|
|
993
|
-
amount: number;
|
|
994
|
-
}>, expectedTotal: number): boolean;
|
|
54
|
+
declare function deriveViewKey(sk_spend: Uint8Array): ViewKey;
|
|
995
55
|
/**
|
|
996
|
-
*
|
|
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
|
-
* ```
|
|
56
|
+
* Generate complete key hierarchy from master seed
|
|
1006
57
|
*/
|
|
1007
|
-
declare function
|
|
1008
|
-
|
|
58
|
+
declare function generateCloakKeys(masterSeed?: Uint8Array): CloakKeyPair;
|
|
1009
59
|
/**
|
|
1010
|
-
*
|
|
60
|
+
* Encrypt note data for a recipient using their public view key
|
|
1011
61
|
*
|
|
1012
|
-
*
|
|
1013
|
-
|
|
62
|
+
* Uses X25519 ECDH + XSalsa20-Poly1305 authenticated encryption
|
|
63
|
+
*/
|
|
64
|
+
declare function encryptNoteForRecipient(noteData: NoteData, recipientPvk: Uint8Array): EncryptedNote$1;
|
|
65
|
+
/**
|
|
66
|
+
* Attempt to decrypt an encrypted note using view key
|
|
1014
67
|
*
|
|
1015
|
-
*
|
|
1016
|
-
*
|
|
1017
|
-
* - Parse and validate notes
|
|
1018
|
-
* - Note utilities (formatting, fees, etc.)
|
|
1019
|
-
* - Key management (without storage)
|
|
68
|
+
* Returns null if decryption fails (note doesn't belong to this wallet)
|
|
69
|
+
* Returns NoteData if successful
|
|
1020
70
|
*/
|
|
1021
|
-
|
|
71
|
+
declare function tryDecryptNote(encryptedNote: EncryptedNote$1, viewKey: ViewKey): NoteData | null;
|
|
72
|
+
/**
|
|
73
|
+
* Scan a batch of encrypted outputs and return notes belonging to this wallet
|
|
74
|
+
*/
|
|
75
|
+
declare function scanNotesForWallet(encryptedOutputs: string[], // Base64 encoded encrypted note JSON
|
|
76
|
+
viewKey: ViewKey): NoteData[];
|
|
1022
77
|
/**
|
|
1023
|
-
*
|
|
1024
|
-
* Uses Poseidon hashing to match circuit implementation
|
|
1025
|
-
* @deprecated Use generateNoteFromWallet instead for enhanced security
|
|
78
|
+
* Export keys for backup (WARNING: contains secrets!)
|
|
1026
79
|
*/
|
|
1027
|
-
declare function
|
|
80
|
+
declare function exportKeys(keys: CloakKeyPair): string;
|
|
1028
81
|
/**
|
|
1029
|
-
*
|
|
1030
|
-
* Uses Poseidon hashing to match circuit implementation
|
|
82
|
+
* Import keys from backup
|
|
1031
83
|
*/
|
|
1032
|
-
declare function
|
|
84
|
+
declare function importKeys(exported: string): CloakKeyPair;
|
|
85
|
+
|
|
1033
86
|
/**
|
|
1034
|
-
*
|
|
87
|
+
* Supported Solana networks.
|
|
1035
88
|
*/
|
|
1036
|
-
|
|
89
|
+
type Network = "localnet" | "devnet" | "mainnet" | "testnet";
|
|
1037
90
|
/**
|
|
1038
|
-
*
|
|
91
|
+
* Minimal wallet adapter interface — compatible with `@solana/wallet-adapter-base`.
|
|
1039
92
|
*/
|
|
1040
|
-
|
|
93
|
+
interface WalletAdapter {
|
|
94
|
+
publicKey: PublicKey | null;
|
|
95
|
+
signTransaction?<T extends Transaction>(transaction: T): Promise<T>;
|
|
96
|
+
signAllTransactions?<T extends Transaction>(transactions: T[]): Promise<T[]>;
|
|
97
|
+
sendTransaction?(transaction: Transaction, connection: any, options?: any): Promise<string>;
|
|
98
|
+
}
|
|
1041
99
|
/**
|
|
1042
|
-
*
|
|
1043
|
-
* Note: merkleProof is optional - it may be fetched lazily at withdrawal time
|
|
100
|
+
* Cloak-specific error with categorization.
|
|
1044
101
|
*/
|
|
1045
|
-
declare
|
|
102
|
+
declare class CloakError extends Error {
|
|
103
|
+
category: "network" | "indexer" | "prover" | "relay" | "validation" | "wallet" | "environment" | "service";
|
|
104
|
+
retryable: boolean;
|
|
105
|
+
originalError?: Error | undefined;
|
|
106
|
+
constructor(message: string, category: "network" | "indexer" | "prover" | "relay" | "validation" | "wallet" | "environment" | "service", retryable?: boolean, originalError?: Error | undefined);
|
|
107
|
+
}
|
|
1046
108
|
/**
|
|
1047
|
-
*
|
|
1048
|
-
* Returns a new note object with deposit info added
|
|
109
|
+
* Merkle proof for a leaf in the commitment tree.
|
|
1049
110
|
*/
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
};
|
|
1059
|
-
}): CloakNote;
|
|
111
|
+
interface MerkleProof {
|
|
112
|
+
/** Sibling hashes along the path (hex strings) */
|
|
113
|
+
pathElements: string[];
|
|
114
|
+
/** Path directions (0 = left, 1 = right) */
|
|
115
|
+
pathIndices: number[];
|
|
116
|
+
/** Optional root for backward compatibility */
|
|
117
|
+
root?: string;
|
|
118
|
+
}
|
|
1060
119
|
/**
|
|
1061
|
-
*
|
|
120
|
+
* Snapshot of the active SDK configuration, returned by `CloakSDK.getConfig()`.
|
|
121
|
+
*
|
|
122
|
+
* This type is intentionally narrower than the constructor input
|
|
123
|
+
* (`CloakSDKOptions` in `core/CloakSDK.ts`): it omits `keypairBytes`,
|
|
124
|
+
* `wallet`, and `storage` because those are consumed into private SDK
|
|
125
|
+
* state (`this.keypair`, `this.wallet`, `this.storage`) at construction
|
|
126
|
+
* time and are never persisted on the config object. The type system
|
|
127
|
+
* therefore enforces the same invariant exercised at runtime by
|
|
128
|
+
* `cloak-sdk.test.ts`.
|
|
129
|
+
*
|
|
130
|
+
* If you're configuring the SDK at construction, use `CloakSDKOptions`.
|
|
1062
131
|
*/
|
|
1063
|
-
|
|
132
|
+
interface CloakConfig {
|
|
133
|
+
/** Network the SDK was constructed for. Defaults to `"mainnet"`. */
|
|
134
|
+
network?: Network;
|
|
135
|
+
/** Cloak key pair for note scanning / encryption (when provided). */
|
|
136
|
+
cloakKeys?: CloakKeyPair;
|
|
137
|
+
/** Resolved program ID (defaults to the mainnet shield-pool). */
|
|
138
|
+
programId?: PublicKey;
|
|
139
|
+
/** Pool PDA derived from `programId` + native SOL mint. */
|
|
140
|
+
poolAddress?: PublicKey;
|
|
141
|
+
/** Merkle-tree PDA. */
|
|
142
|
+
merkleTreeAddress?: PublicKey;
|
|
143
|
+
/** Treasury PDA. */
|
|
144
|
+
treasuryAddress?: PublicKey;
|
|
145
|
+
/**
|
|
146
|
+
* Whether structured debug logging was enabled at construction.
|
|
147
|
+
*
|
|
148
|
+
* Can also be enabled via env: `CLOAK_DEBUG=1` or `DEBUG=cloak:*`.
|
|
149
|
+
*/
|
|
150
|
+
debug?: boolean;
|
|
151
|
+
}
|
|
1064
152
|
/**
|
|
1065
|
-
*
|
|
153
|
+
* Merkle root response from the relay/indexer.
|
|
1066
154
|
*/
|
|
1067
|
-
|
|
155
|
+
interface MerkleRootResponse {
|
|
156
|
+
root: string;
|
|
157
|
+
next_index: number;
|
|
158
|
+
}
|
|
1068
159
|
/**
|
|
1069
|
-
*
|
|
160
|
+
* Transaction status returned by the relay.
|
|
1070
161
|
*/
|
|
1071
|
-
|
|
162
|
+
interface TxStatus {
|
|
163
|
+
status: "pending" | "processing" | "completed" | "failed";
|
|
164
|
+
txId?: string;
|
|
165
|
+
error?: string;
|
|
166
|
+
}
|
|
167
|
+
|
|
1072
168
|
/**
|
|
1073
|
-
*
|
|
1074
|
-
*
|
|
169
|
+
* Storage Interface
|
|
170
|
+
*
|
|
171
|
+
* Pluggable storage for Cloak wallet keys (master seed / spend / view keys).
|
|
172
|
+
*
|
|
173
|
+
* As of `0.1.6`, note persistence is the consumer's responsibility: the OLD
|
|
174
|
+
* `CloakNote` model was retired (see `CloakSDK` jsdoc), and UTXO persistence
|
|
175
|
+
* in the new flow is owned by callers.
|
|
1075
176
|
*/
|
|
1076
|
-
|
|
177
|
+
|
|
178
|
+
interface StorageAdapter {
|
|
179
|
+
/** Save wallet keys. */
|
|
180
|
+
saveKeys(keys: CloakKeyPair): Promise<void> | void;
|
|
181
|
+
/** Load wallet keys (`null` when none stored). */
|
|
182
|
+
loadKeys(): Promise<CloakKeyPair | null> | CloakKeyPair | null;
|
|
183
|
+
/** Delete wallet keys. */
|
|
184
|
+
deleteKeys(): Promise<void> | void;
|
|
185
|
+
}
|
|
1077
186
|
/**
|
|
1078
|
-
*
|
|
187
|
+
* In-memory storage adapter (default; no persistence). Useful for tests or
|
|
188
|
+
* when storage is handled externally.
|
|
1079
189
|
*/
|
|
1080
|
-
declare
|
|
190
|
+
declare class MemoryStorageAdapter implements StorageAdapter {
|
|
191
|
+
private keys;
|
|
192
|
+
saveKeys(keys: CloakKeyPair): void;
|
|
193
|
+
loadKeys(): CloakKeyPair | null;
|
|
194
|
+
deleteKeys(): void;
|
|
195
|
+
}
|
|
1081
196
|
/**
|
|
1082
|
-
*
|
|
197
|
+
* Browser `localStorage` adapter — only safe in browser environments.
|
|
198
|
+
*
|
|
199
|
+
* **Auto-purge on construction:** the first time any `LocalStorageAdapter`
|
|
200
|
+
* is constructed in a given browser, it removes the legacy `cloak_notes`
|
|
201
|
+
* localStorage entry (pre-0.1.6 plaintext `r` + `sk_spend` blob) and writes
|
|
202
|
+
* a sentinel under {@link LEGACY_PURGE_SENTINEL_KEY} so subsequent
|
|
203
|
+
* constructions skip the work. This closes the upgrade-time security gap
|
|
204
|
+
* without requiring every consumer to explicitly call
|
|
205
|
+
* {@link LocalStorageAdapter.purgeLegacyNoteStorage}. Consumers using a
|
|
206
|
+
* non-default legacy key can still call the static helper with their own
|
|
207
|
+
* key name.
|
|
1083
208
|
*/
|
|
1084
|
-
declare
|
|
209
|
+
declare class LocalStorageAdapter implements StorageAdapter {
|
|
210
|
+
private keysKey;
|
|
211
|
+
constructor(keysKey?: string);
|
|
212
|
+
private getStorage;
|
|
213
|
+
saveKeys(keys: CloakKeyPair): void;
|
|
214
|
+
loadKeys(): CloakKeyPair | null;
|
|
215
|
+
deleteKeys(): void;
|
|
216
|
+
/**
|
|
217
|
+
* Sentinel key set after the auto-purge runs. Persists across browser
|
|
218
|
+
* sessions so the purge never re-runs on the same origin.
|
|
219
|
+
*/
|
|
220
|
+
static readonly LEGACY_PURGE_SENTINEL_KEY = "cloak_purged_v0_1_5";
|
|
221
|
+
/**
|
|
222
|
+
* Default localStorage key the legacy `<= 0.1.5` SDK used for the
|
|
223
|
+
* plaintext `CloakNote[]` blob.
|
|
224
|
+
*/
|
|
225
|
+
static readonly LEGACY_NOTES_KEY = "cloak_notes";
|
|
226
|
+
/**
|
|
227
|
+
* Runs the legacy-purge exactly once per browser origin. Invoked
|
|
228
|
+
* automatically by the constructor; exposed as a static for tests and
|
|
229
|
+
* for callers who want to force the check before the first adapter
|
|
230
|
+
* instantiation.
|
|
231
|
+
*/
|
|
232
|
+
static runLegacyPurgeOnce(): void;
|
|
233
|
+
/**
|
|
234
|
+
* Manual cleanup helper for callers that stored notes under a non-default
|
|
235
|
+
* key. The auto-purge in the constructor only handles the canonical
|
|
236
|
+
* `cloak_notes` slot; pass the custom key here.
|
|
237
|
+
*
|
|
238
|
+
* Pre-0.1.6 versions stored the user's `CloakNote[]` (including
|
|
239
|
+
* `r` randomness and `sk_spend` secret-key hex) as JSON plaintext.
|
|
240
|
+
* Those notes are no longer usable (the OLD `withdraw_regular.circom`
|
|
241
|
+
* flow is incompatible with the deployed UTXO program) but the plaintext
|
|
242
|
+
* would otherwise linger indefinitely.
|
|
243
|
+
*
|
|
244
|
+
* Idempotent; safe to call when the key doesn't exist or when running
|
|
245
|
+
* outside a browser (no-op). Does NOT update the auto-purge sentinel.
|
|
246
|
+
*
|
|
247
|
+
* @param notesKey - localStorage key to remove (default `"cloak_notes"`,
|
|
248
|
+
* matching the pre-0.1.6 default).
|
|
249
|
+
*/
|
|
250
|
+
static purgeLegacyNoteStorage(notesKey?: string): void;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** Default Cloak Program ID on Solana mainnet. */
|
|
254
|
+
declare const CLOAK_PROGRAM_ID: PublicKey;
|
|
1085
255
|
/**
|
|
1086
|
-
*
|
|
256
|
+
* Constructor options for {@link CloakSDK}.
|
|
257
|
+
*
|
|
258
|
+
* Contains *all* the settings a caller can supply at construction time —
|
|
259
|
+
* including the secret-bearing fields (`keypairBytes`, `wallet`, `cloakKeys`).
|
|
260
|
+
* Those secrets are consumed into private SDK state and are NOT persisted on
|
|
261
|
+
* the snapshot returned by {@link CloakSDK.getConfig}; see
|
|
262
|
+
* {@link CloakConfig} for the (narrower) snapshot shape.
|
|
1087
263
|
*/
|
|
1088
|
-
|
|
264
|
+
interface CloakSDKOptions {
|
|
265
|
+
/** Keypair bytes for signing (Node.js mode). Consumed into a `Keypair`; not retained. */
|
|
266
|
+
keypairBytes?: Uint8Array;
|
|
267
|
+
/** Wallet adapter for signing (browser mode). */
|
|
268
|
+
wallet?: WalletAdapter;
|
|
269
|
+
/** Network the SDK targets. Defaults to `"mainnet"`. */
|
|
270
|
+
network?: Network;
|
|
271
|
+
/** Cloak key pair for note scanning / encryption. */
|
|
272
|
+
cloakKeys?: CloakKeyPair;
|
|
273
|
+
/** Storage adapter for wallet keys (defaults to in-memory). */
|
|
274
|
+
storage?: StorageAdapter;
|
|
275
|
+
/** Program ID override (defaults to the mainnet shield-pool). */
|
|
276
|
+
programId?: PublicKey;
|
|
277
|
+
/** Relay URL override (defaults to `https://api.cloak.ag`). */
|
|
278
|
+
relayUrl?: string;
|
|
279
|
+
/** Enable structured debug logging. Also via env `CLOAK_DEBUG=1` / `DEBUG=cloak:*`. */
|
|
280
|
+
debug?: boolean;
|
|
281
|
+
}
|
|
1089
282
|
/**
|
|
1090
|
-
*
|
|
283
|
+
* Lightweight Cloak client.
|
|
284
|
+
*
|
|
285
|
+
* Holds program/relay/storage configuration and exposes a small set of
|
|
286
|
+
* read-only chain helpers. **All transaction-emitting methods (deposit,
|
|
287
|
+
* privateTransfer, withdraw, send, swap) were removed in 0.1.6** — they
|
|
288
|
+
* shipped a legacy `[discriminator: 1, amount: u64, commitment: 32]` deposit
|
|
289
|
+
* instruction (`createDepositInstruction`) that the on-chain program no
|
|
290
|
+
* longer understands. Tag `1` is now `TransactSwap`, not `Deposit`, so every
|
|
291
|
+
* call hit `0x1063 MissingAccounts`. The OLD note model
|
|
292
|
+
* (3-input `Poseidon(amount, r0, r1, pk_spend)` for `withdraw_regular.circom`)
|
|
293
|
+
* is also incompatible with the deployed `transaction.circom` UTXO circuit.
|
|
294
|
+
*
|
|
295
|
+
* The supported flow is the functional UTXO API:
|
|
296
|
+
*
|
|
297
|
+
* ```ts
|
|
298
|
+
* import {
|
|
299
|
+
* transact,
|
|
300
|
+
* createUtxo,
|
|
301
|
+
* createZeroUtxo,
|
|
302
|
+
* generateUtxoKeypair,
|
|
303
|
+
* CLOAK_PROGRAM_ID,
|
|
304
|
+
* NATIVE_SOL_MINT,
|
|
305
|
+
* } from "@cloak.dev/sdk";
|
|
306
|
+
*
|
|
307
|
+
* const outputKeypair = await generateUtxoKeypair();
|
|
308
|
+
* const outputUtxo = await createUtxo(amountLamports, outputKeypair);
|
|
309
|
+
* const result = await transact(
|
|
310
|
+
* {
|
|
311
|
+
* inputUtxos: [await createZeroUtxo(), await createZeroUtxo()],
|
|
312
|
+
* outputUtxos: [outputUtxo, await createZeroUtxo()],
|
|
313
|
+
* externalAmount: amountLamports, // positive = deposit
|
|
314
|
+
* depositor: payer.publicKey,
|
|
315
|
+
* },
|
|
316
|
+
* {
|
|
317
|
+
* connection,
|
|
318
|
+
* programId: CLOAK_PROGRAM_ID,
|
|
319
|
+
* relayUrl: "https://api.cloak.ag",
|
|
320
|
+
* depositorKeypair: payer,
|
|
321
|
+
* },
|
|
322
|
+
* );
|
|
323
|
+
* ```
|
|
324
|
+
*
|
|
325
|
+
* See `transfer`, `partialWithdraw`, `fullWithdraw`, `swapUtxo` for the
|
|
326
|
+
* non-deposit flows.
|
|
1091
327
|
*/
|
|
1092
|
-
declare
|
|
328
|
+
declare class CloakSDK {
|
|
329
|
+
private config;
|
|
330
|
+
private keypair?;
|
|
331
|
+
private wallet?;
|
|
332
|
+
private cloakKeys?;
|
|
333
|
+
private relay;
|
|
334
|
+
private storage;
|
|
335
|
+
constructor(config: CloakSDKOptions);
|
|
336
|
+
/** Public key of the configured signer (keypair or wallet). */
|
|
337
|
+
getPublicKey(): PublicKey;
|
|
338
|
+
/** True when the SDK was constructed with a wallet adapter (browser). */
|
|
339
|
+
isWalletMode(): boolean;
|
|
340
|
+
/**
|
|
341
|
+
* Compute a Merkle proof for `leafIndex` from on-chain state. No relay /
|
|
342
|
+
* indexer round-trip required.
|
|
343
|
+
*/
|
|
344
|
+
getMerkleProof(connection: Connection, leafIndex: number): Promise<MerkleProof>;
|
|
345
|
+
/** Read the current SOL-pool Merkle root from on-chain state. */
|
|
346
|
+
getCurrentRoot(connection: Connection): Promise<string>;
|
|
347
|
+
/** Poll relay for the status of a previously-submitted request. */
|
|
348
|
+
getTransactionStatus(requestId: string): Promise<TxStatus>;
|
|
349
|
+
/** Import wallet keys from JSON; persists to the configured storage adapter. */
|
|
350
|
+
importWalletKeys(keysJson: string): Promise<void>;
|
|
351
|
+
/**
|
|
352
|
+
* Export wallet keys to JSON.
|
|
353
|
+
*
|
|
354
|
+
* WARNING: this exports secret keys. Store securely.
|
|
355
|
+
*/
|
|
356
|
+
exportWalletKeys(): string;
|
|
357
|
+
/**
|
|
358
|
+
* Snapshot of the active SDK configuration.
|
|
359
|
+
*
|
|
360
|
+
* The return type ({@link CloakConfig}) is structurally narrower than the
|
|
361
|
+
* constructor input ({@link CloakSDKOptions}): `keypairBytes`, `wallet`,
|
|
362
|
+
* and `storage` are intentionally absent from the snapshot. The secrets
|
|
363
|
+
* are consumed into private SDK state at construction time and are not
|
|
364
|
+
* re-exposable through this method — the type system enforces it. To
|
|
365
|
+
* sign, pass a `Keypair` / `WalletAdapter` directly to the standalone
|
|
366
|
+
* `transact` / `partialWithdraw` / `fullWithdraw` / `swapUtxo` helpers.
|
|
367
|
+
*/
|
|
368
|
+
getConfig(): CloakConfig;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
type ComplianceTxType = "deposit" | "withdraw" | "send" | "swap";
|
|
372
|
+
interface TransactionMetadata {
|
|
373
|
+
amount: number;
|
|
374
|
+
recipient: string;
|
|
375
|
+
timestamp: number;
|
|
376
|
+
txType: ComplianceTxType;
|
|
377
|
+
commitment: string;
|
|
378
|
+
signature?: string;
|
|
379
|
+
outputMint?: string;
|
|
380
|
+
}
|
|
381
|
+
interface EncryptedMetadataBundle {
|
|
382
|
+
encrypted_user: string;
|
|
383
|
+
encrypted_compliance: string;
|
|
384
|
+
user_pubkey: string;
|
|
385
|
+
commitment: string;
|
|
386
|
+
timestamp: number;
|
|
387
|
+
tx_type?: ComplianceTxType;
|
|
388
|
+
wallet_signature?: string;
|
|
389
|
+
viewing_key?: string;
|
|
390
|
+
}
|
|
1093
391
|
|
|
1094
392
|
interface ViewingKeyPair {
|
|
1095
393
|
privateKey: Uint8Array;
|
|
@@ -1229,151 +527,20 @@ declare function pubkeyToLimbs(pubkey: Uint8Array | PublicKey | {
|
|
|
1229
527
|
toBytes: () => Uint8Array;
|
|
1230
528
|
}): [bigint, bigint];
|
|
1231
529
|
/**
|
|
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)
|
|
530
|
+
* Compute Merkle root from leaf and path
|
|
1361
531
|
*
|
|
1362
|
-
* This matches the
|
|
532
|
+
* This matches the test implementation
|
|
1363
533
|
*
|
|
1364
|
-
* @param
|
|
1365
|
-
* @param
|
|
1366
|
-
* @param
|
|
1367
|
-
* @
|
|
1368
|
-
* @param amount - Note amount in lamports (public_amount)
|
|
1369
|
-
* @returns Outputs hash as bigint
|
|
534
|
+
* @param leaf - Leaf value as bigint
|
|
535
|
+
* @param pathElements - Sibling hashes along the path
|
|
536
|
+
* @param pathIndices - Path directions (0 = left, 1 = right)
|
|
537
|
+
* @returns Merkle root as bigint
|
|
1370
538
|
*/
|
|
1371
|
-
declare function
|
|
539
|
+
declare function computeMerkleRoot(leaf: bigint, pathElements: bigint[], pathIndices: number[]): Promise<bigint>;
|
|
1372
540
|
/**
|
|
1373
|
-
*
|
|
1374
|
-
* @deprecated Use computeSwapOutputsHashAsync instead
|
|
541
|
+
* Convert hex string to bigint
|
|
1375
542
|
*/
|
|
1376
|
-
declare function
|
|
543
|
+
declare function hexToBigint$1(hex: string): bigint;
|
|
1377
544
|
/**
|
|
1378
545
|
* Convert bigint to 32-byte big-endian Uint8Array
|
|
1379
546
|
*/
|
|
@@ -1436,37 +603,125 @@ declare function proofToBytes(proof: Groth16Proof): Uint8Array;
|
|
|
1436
603
|
declare function buildPublicInputsBytes(root: bigint, nullifier: bigint, outputsHash: bigint, publicAmount: bigint): Uint8Array;
|
|
1437
604
|
|
|
1438
605
|
/**
|
|
1439
|
-
*
|
|
606
|
+
* Fee calculation utilities for Cloak Protocol
|
|
1440
607
|
*
|
|
1441
|
-
*
|
|
1442
|
-
*
|
|
608
|
+
* The protocol charges a fixed fee plus a variable percentage fee
|
|
609
|
+
* to prevent sybil attacks and cover operational costs.
|
|
610
|
+
*
|
|
611
|
+
* IMPORTANT: These constants are the single source of truth for fee calculations.
|
|
612
|
+
* When updating fees, only change these values - all other code should import from here.
|
|
1443
613
|
*/
|
|
1444
|
-
|
|
614
|
+
/** Lamports per SOL */
|
|
615
|
+
declare const LAMPORTS_PER_SOL = 1000000000;
|
|
616
|
+
/** Fixed fee: 0.005 SOL (5M lamports) */
|
|
617
|
+
declare const FIXED_FEE_LAMPORTS = 5000000;
|
|
618
|
+
/** Variable fee numerator (3 = 0.3%) */
|
|
619
|
+
declare const VARIABLE_FEE_NUMERATOR = 3;
|
|
620
|
+
/** Variable fee denominator (1000 = divide by 1000) */
|
|
621
|
+
declare const VARIABLE_FEE_DENOMINATOR = 1000;
|
|
622
|
+
/** Variable fee rate as decimal: 0.3% = 0.003 */
|
|
623
|
+
declare const VARIABLE_FEE_RATE: number;
|
|
624
|
+
/** Minimum deposit amount to prevent dust/UX footguns (0.01 SOL). */
|
|
625
|
+
declare const MIN_DEPOSIT_LAMPORTS = 10000000;
|
|
626
|
+
/**
|
|
627
|
+
* Calculate the total protocol fee for a given amount
|
|
628
|
+
*
|
|
629
|
+
* Formula: FIXED_FEE + floor((amount * VARIABLE_FEE_NUMERATOR) / VARIABLE_FEE_DENOMINATOR)
|
|
630
|
+
*
|
|
631
|
+
* @param amountLamports - Amount in lamports
|
|
632
|
+
* @returns Total fee in lamports
|
|
633
|
+
*
|
|
634
|
+
* @example
|
|
635
|
+
* ```typescript
|
|
636
|
+
* const fee = calculateFee(1_000_000_000); // 1 SOL
|
|
637
|
+
* // Returns: 5_000_000 (fixed) + 3_000_000 (0.3%) = 8_000_000 lamports
|
|
638
|
+
* ```
|
|
639
|
+
*/
|
|
640
|
+
declare function calculateFee(amountLamports: number): number;
|
|
641
|
+
/**
|
|
642
|
+
* Bigint version of calculateFee (for UTXO flows that use bigint lamports).
|
|
643
|
+
*/
|
|
644
|
+
declare function calculateFeeBigint(amountLamports: bigint): bigint;
|
|
645
|
+
/**
|
|
646
|
+
* Returns true if a withdrawal amount can pay fees and still leave >0 lamports.
|
|
647
|
+
* (On-chain uses the same integer math and enforces this as well.)
|
|
648
|
+
*/
|
|
649
|
+
declare function isWithdrawAmountSufficient(amountLamports: bigint): boolean;
|
|
650
|
+
/**
|
|
651
|
+
* Calculate the distributable amount after protocol fees
|
|
652
|
+
*
|
|
653
|
+
* This is the amount available to send to recipients.
|
|
654
|
+
*
|
|
655
|
+
* @param amountLamports - Total note amount in lamports
|
|
656
|
+
* @returns Amount available for recipients in lamports
|
|
657
|
+
*
|
|
658
|
+
* @example
|
|
659
|
+
* ```typescript
|
|
660
|
+
* const distributable = getDistributableAmount(1_000_000_000);
|
|
661
|
+
* // Returns: 1_000_000_000 - 7_500_000 = 992_500_000 lamports
|
|
662
|
+
* ```
|
|
663
|
+
*/
|
|
664
|
+
declare function getDistributableAmount(amountLamports: number): number;
|
|
1445
665
|
/**
|
|
1446
|
-
*
|
|
666
|
+
* Format lamports as SOL string
|
|
667
|
+
*
|
|
668
|
+
* @param lamports - Amount in lamports
|
|
669
|
+
* @param decimals - Number of decimal places (default: 9)
|
|
670
|
+
* @returns Formatted string (e.g., "1.000000000")
|
|
1447
671
|
*
|
|
1448
|
-
* @
|
|
1449
|
-
*
|
|
672
|
+
* @example
|
|
673
|
+
* ```typescript
|
|
674
|
+
* formatAmount(1_000_000_000); // "1.000000000"
|
|
675
|
+
* formatAmount(1_500_000_000); // "1.500000000"
|
|
676
|
+
* formatAmount(123_456_789, 4); // "0.1235"
|
|
677
|
+
* ```
|
|
1450
678
|
*/
|
|
1451
|
-
declare function
|
|
679
|
+
declare function formatAmount(lamports: number, decimals?: number): string;
|
|
1452
680
|
/**
|
|
1453
|
-
*
|
|
681
|
+
* Parse SOL string to lamports
|
|
682
|
+
*
|
|
683
|
+
* @param sol - SOL amount as string (e.g., "1.5")
|
|
684
|
+
* @returns Amount in lamports
|
|
685
|
+
* @throws Error if invalid format
|
|
1454
686
|
*
|
|
1455
|
-
* @
|
|
1456
|
-
*
|
|
687
|
+
* @example
|
|
688
|
+
* ```typescript
|
|
689
|
+
* parseAmount("1.5"); // 1_500_000_000
|
|
690
|
+
* parseAmount("0.001"); // 1_000_000
|
|
691
|
+
* ```
|
|
1457
692
|
*/
|
|
1458
|
-
declare function
|
|
693
|
+
declare function parseAmount(sol: string): number;
|
|
1459
694
|
/**
|
|
1460
|
-
* Validate
|
|
695
|
+
* Validate that outputs sum equals expected amount
|
|
1461
696
|
*
|
|
1462
|
-
* @param
|
|
1463
|
-
* @param
|
|
1464
|
-
* @
|
|
697
|
+
* @param outputs - Array of output amounts
|
|
698
|
+
* @param expectedTotal - Expected total amount
|
|
699
|
+
* @returns True if amounts match
|
|
1465
700
|
*/
|
|
1466
|
-
declare function
|
|
1467
|
-
recipient: PublicKey;
|
|
701
|
+
declare function validateOutputsSum(outputs: Array<{
|
|
1468
702
|
amount: number;
|
|
1469
|
-
}>,
|
|
703
|
+
}>, expectedTotal: number): boolean;
|
|
704
|
+
/**
|
|
705
|
+
* Calculate relay fee from basis points
|
|
706
|
+
*
|
|
707
|
+
* @param amountLamports - Amount in lamports
|
|
708
|
+
* @param feeBps - Fee in basis points (100 bps = 1%)
|
|
709
|
+
* @returns Relay fee in lamports
|
|
710
|
+
*
|
|
711
|
+
* @example
|
|
712
|
+
* ```typescript
|
|
713
|
+
* calculateRelayFee(1_000_000_000, 50); // 0.5% = 5_000_000 lamports
|
|
714
|
+
* ```
|
|
715
|
+
*/
|
|
716
|
+
declare function calculateRelayFee(amountLamports: number, feeBps: number): number;
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Validate that a string is a valid Solana public key.
|
|
720
|
+
*
|
|
721
|
+
* @param address - Address string to validate
|
|
722
|
+
* @returns True if valid Solana address
|
|
723
|
+
*/
|
|
724
|
+
declare function isValidSolanaAddress(address: string): boolean;
|
|
1470
725
|
|
|
1471
726
|
/**
|
|
1472
727
|
* Network Utilities
|
|
@@ -2349,36 +1604,6 @@ declare function fetchRiskQuoteIx(connection: Connection, wallet: PublicKey, ran
|
|
|
2349
1604
|
queue: PublicKey;
|
|
2350
1605
|
}>;
|
|
2351
1606
|
|
|
2352
|
-
/**
|
|
2353
|
-
* Encrypted Output Helpers
|
|
2354
|
-
*
|
|
2355
|
-
* Functions for creating encrypted outputs that enable note scanning
|
|
2356
|
-
*/
|
|
2357
|
-
|
|
2358
|
-
/**
|
|
2359
|
-
* Prepare encrypted output for scanning by wallet owner
|
|
2360
|
-
*
|
|
2361
|
-
* @param note - Note to encrypt
|
|
2362
|
-
* @param cloakKeys - Wallet's Cloak keys (for self-encryption)
|
|
2363
|
-
* @returns Base64-encoded encrypted output
|
|
2364
|
-
*/
|
|
2365
|
-
declare function prepareEncryptedOutput(note: CloakNote, cloakKeys: CloakKeyPair): string;
|
|
2366
|
-
/**
|
|
2367
|
-
* Prepare encrypted output for a specific recipient
|
|
2368
|
-
*
|
|
2369
|
-
* @param note - Note to encrypt
|
|
2370
|
-
* @param recipientPvkHex - Recipient's public view key (hex)
|
|
2371
|
-
* @returns Base64-encoded encrypted output
|
|
2372
|
-
*/
|
|
2373
|
-
declare function prepareEncryptedOutputForRecipient(note: CloakNote, recipientPvkHex: string): string;
|
|
2374
|
-
/**
|
|
2375
|
-
* Simple base64 encoding for v1.0 notes (no encryption)
|
|
2376
|
-
*
|
|
2377
|
-
* @param note - Note to encode
|
|
2378
|
-
* @returns Base64-encoded note data
|
|
2379
|
-
*/
|
|
2380
|
-
declare function encodeNoteSimple(note: CloakNote): string;
|
|
2381
|
-
|
|
2382
1607
|
/**
|
|
2383
1608
|
* Wallet Integration Helpers
|
|
2384
1609
|
*
|
|
@@ -2406,58 +1631,6 @@ declare function signTransaction<T extends Transaction>(transaction: T, wallet:
|
|
|
2406
1631
|
*/
|
|
2407
1632
|
declare function keypairToAdapter(keypair: Keypair): WalletAdapter;
|
|
2408
1633
|
|
|
2409
|
-
/**
|
|
2410
|
-
* Create a deposit instruction
|
|
2411
|
-
*
|
|
2412
|
-
* Deposits SOL into the Cloak protocol by creating a commitment.
|
|
2413
|
-
*
|
|
2414
|
-
* Instruction format:
|
|
2415
|
-
* - Byte 0: Discriminant (0x01 for Deposit, per ShieldPoolInstruction enum)
|
|
2416
|
-
* - Bytes 1-8: Amount (u64, little-endian)
|
|
2417
|
-
* - Bytes 9-40: Commitment (32 bytes)
|
|
2418
|
-
*
|
|
2419
|
-
* @param params - Deposit parameters
|
|
2420
|
-
* @returns Transaction instruction
|
|
2421
|
-
*
|
|
2422
|
-
* @example
|
|
2423
|
-
* ```typescript
|
|
2424
|
-
* const instruction = createDepositInstruction({
|
|
2425
|
-
* programId: CLOAK_PROGRAM_ID,
|
|
2426
|
-
* payer: wallet.publicKey,
|
|
2427
|
-
* pool: POOL_ADDRESS,
|
|
2428
|
-
* commitments: COMMITMENTS_ADDRESS,
|
|
2429
|
-
* amount: 1_000_000_000, // 1 SOL
|
|
2430
|
-
* commitment: commitmentBytes
|
|
2431
|
-
* });
|
|
2432
|
-
* ```
|
|
2433
|
-
*/
|
|
2434
|
-
declare function createDepositInstruction(params: {
|
|
2435
|
-
programId: PublicKey;
|
|
2436
|
-
payer: PublicKey;
|
|
2437
|
-
pool: PublicKey;
|
|
2438
|
-
merkleTree: PublicKey;
|
|
2439
|
-
amount: number;
|
|
2440
|
-
commitment: Uint8Array;
|
|
2441
|
-
}): TransactionInstruction;
|
|
2442
|
-
/**
|
|
2443
|
-
* Deposit instruction parameters for type safety
|
|
2444
|
-
*/
|
|
2445
|
-
interface DepositInstructionParams {
|
|
2446
|
-
programId: PublicKey;
|
|
2447
|
-
payer: PublicKey;
|
|
2448
|
-
pool: PublicKey;
|
|
2449
|
-
merkleTree: PublicKey;
|
|
2450
|
-
amount: number;
|
|
2451
|
-
commitment: Uint8Array;
|
|
2452
|
-
}
|
|
2453
|
-
/**
|
|
2454
|
-
* Validate deposit instruction parameters
|
|
2455
|
-
*
|
|
2456
|
-
* @param params - Parameters to validate
|
|
2457
|
-
* @throws Error if invalid
|
|
2458
|
-
*/
|
|
2459
|
-
declare function validateDepositParams(params: DepositInstructionParams): void;
|
|
2460
|
-
|
|
2461
1634
|
/**
|
|
2462
1635
|
* Program Derived Address (PDA) utilities for Shield Pool
|
|
2463
1636
|
*
|
|
@@ -2678,263 +1851,6 @@ declare function preflightCheck(relayUrl: string, rootHex: string): Promise<{
|
|
|
2678
1851
|
estimatedWaitMs?: number;
|
|
2679
1852
|
}>;
|
|
2680
1853
|
|
|
2681
|
-
/**
|
|
2682
|
-
* Direct Circom WASM Proof Generation
|
|
2683
|
-
*
|
|
2684
|
-
* This module provides direct proof generation using snarkjs and Circom WASM,
|
|
2685
|
-
* matching the approach used in services-new/tests/src/proof.ts
|
|
2686
|
-
*
|
|
2687
|
-
* This uses pinned S3-hosted circuit artifacts and does not require
|
|
2688
|
-
* a backend prover service.
|
|
2689
|
-
*/
|
|
2690
|
-
|
|
2691
|
-
/**
|
|
2692
|
-
* Default URL for fetching circuit artifacts
|
|
2693
|
-
* Hosted in S3 and versioned by build.
|
|
2694
|
-
*/
|
|
2695
|
-
declare const DEFAULT_CIRCUITS_URL = "https://cloak-circuits.s3.us-east-1.amazonaws.com/circuits/0.1.0";
|
|
2696
|
-
interface WithdrawRegularInputs {
|
|
2697
|
-
root: bigint;
|
|
2698
|
-
nullifier: bigint;
|
|
2699
|
-
outputs_hash: bigint;
|
|
2700
|
-
public_amount: bigint;
|
|
2701
|
-
amount: bigint;
|
|
2702
|
-
leaf_index: bigint;
|
|
2703
|
-
sk: [bigint, bigint];
|
|
2704
|
-
r: [bigint, bigint];
|
|
2705
|
-
pathElements: bigint[];
|
|
2706
|
-
pathIndices: number[];
|
|
2707
|
-
num_outputs: number;
|
|
2708
|
-
out_addr: bigint[][];
|
|
2709
|
-
out_amount: bigint[];
|
|
2710
|
-
out_flags: number[];
|
|
2711
|
-
var_fee: bigint;
|
|
2712
|
-
rem: bigint;
|
|
2713
|
-
}
|
|
2714
|
-
interface WithdrawSwapInputs {
|
|
2715
|
-
sk_spend: bigint;
|
|
2716
|
-
r: bigint;
|
|
2717
|
-
amount: bigint;
|
|
2718
|
-
leaf_index: bigint;
|
|
2719
|
-
path_elements: bigint[];
|
|
2720
|
-
path_indices: number[];
|
|
2721
|
-
root: bigint;
|
|
2722
|
-
nullifier: bigint;
|
|
2723
|
-
outputs_hash: bigint;
|
|
2724
|
-
public_amount: bigint;
|
|
2725
|
-
input_mint: bigint[];
|
|
2726
|
-
output_mint: bigint[];
|
|
2727
|
-
recipient_ata: bigint[];
|
|
2728
|
-
min_output_amount: bigint;
|
|
2729
|
-
var_fee: bigint;
|
|
2730
|
-
rem: bigint;
|
|
2731
|
-
}
|
|
2732
|
-
interface ProofResult {
|
|
2733
|
-
proof: Groth16Proof;
|
|
2734
|
-
publicSignals: string[];
|
|
2735
|
-
proofBytes: Uint8Array;
|
|
2736
|
-
publicInputsBytes: Uint8Array;
|
|
2737
|
-
}
|
|
2738
|
-
/**
|
|
2739
|
-
* Generate Groth16 proof for regular withdrawal using Circom WASM
|
|
2740
|
-
*
|
|
2741
|
-
* This matches the approach in services-new/tests/src/proof.ts
|
|
2742
|
-
*
|
|
2743
|
-
* @param inputs - Circuit inputs
|
|
2744
|
-
* @param circuitsPath - Ignored. Proof generation always uses pinned S3 circuits.
|
|
2745
|
-
*/
|
|
2746
|
-
declare function generateWithdrawRegularProof(inputs: WithdrawRegularInputs, circuitsPath: string): Promise<ProofResult>;
|
|
2747
|
-
/**
|
|
2748
|
-
* Generate Groth16 proof for swap withdrawal using Circom WASM
|
|
2749
|
-
*
|
|
2750
|
-
* This matches the approach in services-new/tests/src/proof.ts
|
|
2751
|
-
*
|
|
2752
|
-
* @param inputs - Circuit inputs
|
|
2753
|
-
* @param circuitsPath - Ignored. Proof generation always uses pinned S3 circuits.
|
|
2754
|
-
*/
|
|
2755
|
-
declare function generateWithdrawSwapProof(inputs: WithdrawSwapInputs, circuitsPath: string): Promise<ProofResult>;
|
|
2756
|
-
/**
|
|
2757
|
-
* Check if circuits are available from the pinned S3 source.
|
|
2758
|
-
*/
|
|
2759
|
-
declare function areCircuitsAvailable(circuitsPath: string): Promise<boolean>;
|
|
2760
|
-
/**
|
|
2761
|
-
* Get default circuits URL.
|
|
2762
|
-
*/
|
|
2763
|
-
declare function getDefaultCircuitsPath(): Promise<string>;
|
|
2764
|
-
/**
|
|
2765
|
-
* Pinned circuit artifact hashes (SHA-256).
|
|
2766
|
-
*
|
|
2767
|
-
* These hashes must be updated whenever the trusted circuit artifacts change.
|
|
2768
|
-
*/
|
|
2769
|
-
declare const EXPECTED_CIRCUIT_HASHES: {
|
|
2770
|
-
withdraw_regular_wasm: string;
|
|
2771
|
-
withdraw_regular_zkey: string;
|
|
2772
|
-
withdraw_swap_wasm: string;
|
|
2773
|
-
withdraw_swap_zkey: string;
|
|
2774
|
-
};
|
|
2775
|
-
/**
|
|
2776
|
-
* Circuit verification result
|
|
2777
|
-
*/
|
|
2778
|
-
interface CircuitVerificationResult {
|
|
2779
|
-
/** Whether verification passed */
|
|
2780
|
-
valid: boolean;
|
|
2781
|
-
/** Which circuit was checked */
|
|
2782
|
-
circuit: 'withdraw_regular' | 'withdraw_swap';
|
|
2783
|
-
/** Error message if verification failed */
|
|
2784
|
-
error?: string;
|
|
2785
|
-
computed?: {
|
|
2786
|
-
wasm: string;
|
|
2787
|
-
zkey: string;
|
|
2788
|
-
};
|
|
2789
|
-
expected?: {
|
|
2790
|
-
wasm: string;
|
|
2791
|
-
zkey: string;
|
|
2792
|
-
};
|
|
2793
|
-
}
|
|
2794
|
-
/**
|
|
2795
|
-
* Verify circuit integrity by checking verification key hashes
|
|
2796
|
-
*
|
|
2797
|
-
* This function fetches the verification key and computes its hash,
|
|
2798
|
-
* then compares against the expected hash embedded in the SDK.
|
|
2799
|
-
*
|
|
2800
|
-
* IMPORTANT: If the hashes don't match, the circuit may produce proofs
|
|
2801
|
-
* that will be rejected by the on-chain verifier!
|
|
2802
|
-
*
|
|
2803
|
-
* @param circuitsPath - Ignored. Verification always uses pinned S3 circuits.
|
|
2804
|
-
* @param circuit - Which circuit to verify ('withdraw_regular' or 'withdraw_swap')
|
|
2805
|
-
* @returns Verification result
|
|
2806
|
-
*
|
|
2807
|
-
* @example
|
|
2808
|
-
* ```typescript
|
|
2809
|
-
* const result = await verifyCircuitIntegrity('https://cloak-circuits.s3.us-east-1.amazonaws.com/circuits/0.1.0', 'withdraw_regular');
|
|
2810
|
-
* if (!result.valid) {
|
|
2811
|
-
* console.error('Circuit verification failed:', result.error);
|
|
2812
|
-
* // Don't proceed with proof generation!
|
|
2813
|
-
* }
|
|
2814
|
-
* ```
|
|
2815
|
-
*/
|
|
2816
|
-
declare function verifyCircuitIntegrity(circuitsPath: string, circuit: 'withdraw_regular' | 'withdraw_swap'): Promise<CircuitVerificationResult>;
|
|
2817
|
-
/**
|
|
2818
|
-
* Verify all circuits before use
|
|
2819
|
-
*
|
|
2820
|
-
* Call this at SDK initialization to ensure circuits are valid.
|
|
2821
|
-
*
|
|
2822
|
-
* @param circuitsPath - Ignored. Verification always uses pinned S3 circuits.
|
|
2823
|
-
* @returns Array of verification results (one per circuit)
|
|
2824
|
-
*/
|
|
2825
|
-
declare function verifyAllCircuits(circuitsPath: string): Promise<CircuitVerificationResult[]>;
|
|
2826
|
-
|
|
2827
|
-
/**
|
|
2828
|
-
* Pending Operations Manager
|
|
2829
|
-
*
|
|
2830
|
-
* Utility for persisting pending deposit/withdrawal operations in browser storage.
|
|
2831
|
-
* This enables recovery if the browser crashes or user navigates away mid-operation.
|
|
2832
|
-
*
|
|
2833
|
-
* IMPORTANT: This uses localStorage by default which has security implications.
|
|
2834
|
-
* Notes contain sensitive spending keys - consider using more secure storage
|
|
2835
|
-
* in production (e.g., encrypted IndexedDB, secure enclave).
|
|
2836
|
-
*/
|
|
2837
|
-
|
|
2838
|
-
/**
|
|
2839
|
-
* Pending deposit record
|
|
2840
|
-
*/
|
|
2841
|
-
interface PendingDeposit {
|
|
2842
|
-
/** The note (contains spending secrets!) */
|
|
2843
|
-
note: CloakNote;
|
|
2844
|
-
/** When the deposit was initiated */
|
|
2845
|
-
startedAt: number;
|
|
2846
|
-
/** Transaction signature if available */
|
|
2847
|
-
txSignature?: string;
|
|
2848
|
-
/** Status of the deposit */
|
|
2849
|
-
status: "pending" | "tx_sent" | "confirmed" | "failed";
|
|
2850
|
-
/** Error message if failed */
|
|
2851
|
-
error?: string;
|
|
2852
|
-
}
|
|
2853
|
-
/**
|
|
2854
|
-
* Pending withdrawal record
|
|
2855
|
-
*/
|
|
2856
|
-
interface PendingWithdrawal {
|
|
2857
|
-
/** The relay request ID (for resumption) */
|
|
2858
|
-
requestId: string;
|
|
2859
|
-
/** The note commitment being withdrawn */
|
|
2860
|
-
commitment: string;
|
|
2861
|
-
/** The nullifier being used */
|
|
2862
|
-
nullifier: string;
|
|
2863
|
-
/** When the withdrawal was initiated */
|
|
2864
|
-
startedAt: number;
|
|
2865
|
-
/** Status of the withdrawal */
|
|
2866
|
-
status: "pending" | "processing" | "completed" | "failed";
|
|
2867
|
-
/** Transaction signature if completed */
|
|
2868
|
-
txSignature?: string;
|
|
2869
|
-
/** Error message if failed */
|
|
2870
|
-
error?: string;
|
|
2871
|
-
}
|
|
2872
|
-
/**
|
|
2873
|
-
* Save a pending deposit
|
|
2874
|
-
* Call this BEFORE sending the on-chain transaction to ensure note is persisted
|
|
2875
|
-
*/
|
|
2876
|
-
declare function savePendingDeposit(deposit: PendingDeposit): void;
|
|
2877
|
-
/**
|
|
2878
|
-
* Load all pending deposits
|
|
2879
|
-
*/
|
|
2880
|
-
declare function loadPendingDeposits(): PendingDeposit[];
|
|
2881
|
-
/**
|
|
2882
|
-
* Update a pending deposit status
|
|
2883
|
-
*/
|
|
2884
|
-
declare function updatePendingDeposit(commitment: string, updates: Partial<PendingDeposit>): void;
|
|
2885
|
-
/**
|
|
2886
|
-
* Remove a pending deposit (e.g., after successful confirmation)
|
|
2887
|
-
*/
|
|
2888
|
-
declare function removePendingDeposit(commitment: string): void;
|
|
2889
|
-
/**
|
|
2890
|
-
* Clear all pending deposits
|
|
2891
|
-
*/
|
|
2892
|
-
declare function clearPendingDeposits(): void;
|
|
2893
|
-
/**
|
|
2894
|
-
* Save a pending withdrawal
|
|
2895
|
-
* Call this when you receive the request_id from the relay
|
|
2896
|
-
*/
|
|
2897
|
-
declare function savePendingWithdrawal(withdrawal: PendingWithdrawal): void;
|
|
2898
|
-
/**
|
|
2899
|
-
* Load all pending withdrawals
|
|
2900
|
-
*/
|
|
2901
|
-
declare function loadPendingWithdrawals(): PendingWithdrawal[];
|
|
2902
|
-
/**
|
|
2903
|
-
* Update a pending withdrawal status
|
|
2904
|
-
*/
|
|
2905
|
-
declare function updatePendingWithdrawal(requestId: string, updates: Partial<PendingWithdrawal>): void;
|
|
2906
|
-
/**
|
|
2907
|
-
* Remove a pending withdrawal (e.g., after successful completion)
|
|
2908
|
-
*/
|
|
2909
|
-
declare function removePendingWithdrawal(requestId: string): void;
|
|
2910
|
-
/**
|
|
2911
|
-
* Clear all pending withdrawals
|
|
2912
|
-
*/
|
|
2913
|
-
declare function clearPendingWithdrawals(): void;
|
|
2914
|
-
/**
|
|
2915
|
-
* Check if there are any pending operations that need recovery
|
|
2916
|
-
* Call this on page load to determine if recovery UI should be shown
|
|
2917
|
-
*/
|
|
2918
|
-
declare function hasPendingOperations(): boolean;
|
|
2919
|
-
/**
|
|
2920
|
-
* Get summary of pending operations for recovery UI
|
|
2921
|
-
*/
|
|
2922
|
-
declare function getPendingOperationsSummary(): {
|
|
2923
|
-
deposits: PendingDeposit[];
|
|
2924
|
-
withdrawals: PendingWithdrawal[];
|
|
2925
|
-
totalPending: number;
|
|
2926
|
-
};
|
|
2927
|
-
/**
|
|
2928
|
-
* Clean up stale pending operations
|
|
2929
|
-
* Call this periodically to remove old failed/completed operations
|
|
2930
|
-
*
|
|
2931
|
-
* @param maxAgeMs Maximum age in milliseconds before an operation is removed (default: 24 hours)
|
|
2932
|
-
*/
|
|
2933
|
-
declare function cleanupStalePendingOperations(maxAgeMs?: number): {
|
|
2934
|
-
removedDeposits: number;
|
|
2935
|
-
removedWithdrawals: number;
|
|
2936
|
-
};
|
|
2937
|
-
|
|
2938
1854
|
/**
|
|
2939
1855
|
* UTXO Transaction Methods
|
|
2940
1856
|
*
|
|
@@ -3558,10 +2474,25 @@ declare class SimpleWallet {
|
|
|
3558
2474
|
* Cloak SDK - TypeScript SDK for Private Transactions on Solana
|
|
3559
2475
|
*
|
|
3560
2476
|
* @packageDocumentation
|
|
2477
|
+
*
|
|
2478
|
+
* # 0.1.6 — breaking changes
|
|
2479
|
+
*
|
|
2480
|
+
* The legacy `CloakNote` API (`CloakSDK.deposit/privateTransfer/withdraw/
|
|
2481
|
+
* send/swap`, `createDepositInstruction`, `generateNote`, `withdraw_regular`
|
|
2482
|
+
* proofs, etc.) was removed because every code path eventually emitted a
|
|
2483
|
+
* legacy `[discriminator: 1, amount: u64, commitment: 32]` instruction that
|
|
2484
|
+
* the deployed shield-pool program no longer accepts (tag `1` is now
|
|
2485
|
+
* `TransactSwap`, not `Deposit`). The OLD 3-input commitment scheme is
|
|
2486
|
+
* also incompatible with the deployed `transaction.circom` UTXO circuit.
|
|
2487
|
+
*
|
|
2488
|
+
* Use the functional UTXO API instead — `transact`, `transfer`,
|
|
2489
|
+
* `partialWithdraw`, `fullWithdraw`, `swapUtxo`, `createUtxo`,
|
|
2490
|
+
* `createZeroUtxo`, `generateUtxoKeypair`. The `CloakSDK` class is kept as
|
|
2491
|
+
* a thin config + read-only chain helper.
|
|
3561
2492
|
*/
|
|
3562
2493
|
|
|
3563
|
-
declare const VERSION = "0.1.
|
|
3564
|
-
/** True when scanner supports TransactSwap (tag 1).
|
|
2494
|
+
declare const VERSION = "0.1.6";
|
|
2495
|
+
/** True when scanner supports TransactSwap (tag 1). */
|
|
3565
2496
|
declare const SCANNER_SUPPORTS_TRANSACT_SWAP = true;
|
|
3566
2497
|
|
|
3567
|
-
export { CLOAK_PROGRAM_ID, type ChainNoteTxType, type
|
|
2498
|
+
export { CLOAK_PROGRAM_ID, type ChainNoteTxType, type CloakConfig, CloakError, type CloakKeyPair, CloakSDK, type CloakSDKOptions, type CommitmentEntry, type CommitmentsResponse, type CompactChainNote, type ComplianceReport, type ComplianceTxType, DEFAULT_TRANSACTION_CIRCUITS_URL, 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, MemoryStorageAdapter, type MerkleProof, type MerkleRootResponse, MerkleTree, NATIVE_SOL_MINT, type Network, type NoteData, type OnchainMerkleProof, RelayInternalError, RelayService, type RiskQuoteInstructionResponse, RootNotFoundError, SCANNER_SUPPORTS_TRANSACT_SWAP, SIGN_IN_MESSAGE, SanctionsQuoteError, type ScanOptions, type ScanResult, type ScanSummary, type ScannedTransaction, ShieldPoolErrors, type ShieldPoolPDAs, SimpleWallet, type SpendKey, type StorageAdapter, type TransactOptions, type TransactParams, type TransactResult, type TransactionMetadata, type TxStatus, type UserFriendlyError, type Utxo, UtxoAlreadySpentError, type EncryptedNote as UtxoEncryptedNote, type UtxoKeypair, type UtxoSwapParams, type UtxoSwapResult, UtxoWallet, VARIABLE_FEE_DENOMINATOR, VARIABLE_FEE_NUMERATOR, VARIABLE_FEE_RATE, VERSION, type VerifyUtxosResult, type ViewKey, type ViewingKeyPair, type WalletAdapter, type WalletUtxo, type WithdrawSubmissionResult, bigintToBytes32$1 as bigintToBytes32, bigintToHex, buildMerkleTree, buildMerkleTreeFromChain, buildMerkleTreeFromRelay, buildPublicInputsBytes, bytesToHex, calculateFee, calculateFeeBigint, calculateRelayFee, chainNoteFromBase64, chainNoteToBase64, classifyRelayError, computeChainNoteHash, computeExtDataHash, computeMerkleRoot, computeProofForLatestDeposit, computeProofFromChain, computeSignature, computeCommitment as computeUtxoCommitment, computeNullifier as computeUtxoNullifier, createCloakError, createLogger, createUtxo, createZeroUtxo, decryptCompactChainNote, decryptComplianceMetadataWithMasterKey, decryptTransactionMetadata, deriveDiversifiedViewingKey, deriveDiversifier, derivePublicKey, deriveSpendKey, deriveUserCompliancePublicKey, deriveUserComplianceScalar, deriveUtxoKeypairFromSpendKey, deriveViewKey, deriveViewingKeyFromNk, deriveViewingKeyFromSpendKey, deriveViewingKeyFromUtxoPrivateKey, deserializeUtxo, detectNetworkFromRpcUrl, encryptCompactChainNote, encryptNoteForRecipient, encryptTransactionMetadata, encryptTransactionMetadataBundle, expandSpendKey, exportKeys, fetchCommitments, fetchRiskQuoteInstruction, fetchRiskQuoteIx, formatAmount, formatComplianceCsv, formatErrorForLogging, formatSol, fullWithdraw, generateCloakKeys, generateMasterSeed, generateUtxoKeypair, generateViewingKeyPair, getAddressExplorerUrl, getCircuitsPath, getDistributableAmount, getExplorerUrl, getNkFromUtxoPrivateKey, getNullifierPDA, getPublicKey, getRpcUrlForNetwork, getShieldPoolPDAs, getSwapStatePDA, hexToBigint$1 as hexToBigint, hexToBytes, importKeys, isDebugEnabled, isRootNotFoundError, isValidHex, isValidRpcUrl, isValidSolanaAddress, isWithdrawAmountSufficient, keypairToAdapter, parseAmount, parseError, parseRelayErrorResponse, parseTransactionError, partialWithdraw, poseidonHash, preflightCheck, preflightNullifiers, proofToBytes, pubkeyToFieldElement, pubkeyToLimbs, randomBytes, randomFieldElement, readMerkleTreeState, registerViewingKey, scanNotesForWallet, scanTransactions, sdkLogger, selectUtxos, sendTransaction, serializeUtxo, setCircuitsPath, setDebugMode, signTransaction, splitTo2Limbs, sumUtxoAmounts, swapUtxo, swapWithChange, toComplianceReport, transact, transfer, truncate, tryDecryptNote, bigintToBytes32 as utxoBigintToBytes32, utxoEquals, hexToBigint as utxoHexToBigint, validateOutputsSum, validateRoot, validateWalletConnected, verifyUtxos, waitForRoot, withTiming };
|