@cloak.dev/sdk 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -183
- package/dist/index.cjs +2289 -288
- package/dist/index.d.cts +1502 -433
- package/dist/index.d.ts +1502 -433
- package/dist/index.js +2199 -249
- package/package.json +1 -2
- package/CHANGELOG.md +0 -173
package/README.md
CHANGED
|
@@ -4,12 +4,12 @@ TypeScript SDK for the Cloak Protocol - Private transactions on Solana using zer
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- 🔒 **Private Transfers**:
|
|
8
|
-
-
|
|
9
|
-
- 💱 **Token Swaps**: Swap
|
|
10
|
-
- 🔐 **Type-Safe**: Full TypeScript
|
|
11
|
-
- 🌐 **Cross-Platform**:
|
|
12
|
-
- ⚡ **
|
|
7
|
+
- 🔒 **Private Transfers**: Send SOL privately using zero-knowledge proofs
|
|
8
|
+
- 👥 **Multi-Recipient**: Support for 1-5 recipients in a single transaction
|
|
9
|
+
- 💱 **Token Swaps**: Swap SOL for SPL tokens privately (SOL → USDC, etc.)
|
|
10
|
+
- 🔐 **Type-Safe**: Full TypeScript support with comprehensive types
|
|
11
|
+
- 🌐 **Cross-Platform**: Works in browser (React, Next.js) and Node.js
|
|
12
|
+
- ⚡ **Simple API**: Easy-to-use high-level client with wallet adapter support
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
@@ -155,215 +155,146 @@ npm run test:examples
|
|
|
155
155
|
### Node.js (with Keypair)
|
|
156
156
|
|
|
157
157
|
```typescript
|
|
158
|
-
import {
|
|
159
|
-
CLOAK_PROGRAM_ID,
|
|
160
|
-
NATIVE_SOL_MINT,
|
|
161
|
-
createUtxo,
|
|
162
|
-
createZeroUtxo,
|
|
163
|
-
fullWithdraw,
|
|
164
|
-
generateUtxoKeypair,
|
|
165
|
-
transact,
|
|
166
|
-
} from "@cloak.dev/sdk";
|
|
158
|
+
import { CloakSDK } from "@cloak.dev/sdk";
|
|
167
159
|
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
|
168
160
|
|
|
169
|
-
|
|
170
|
-
const
|
|
161
|
+
// Initialize connection and keypair
|
|
162
|
+
const connection = new Connection("https://api.devnet.solana.com");
|
|
163
|
+
const keypair = Keypair.fromSecretKey(/* your secret key */);
|
|
171
164
|
|
|
172
|
-
//
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const output = await createUtxo(amountLamports, owner, NATIVE_SOL_MINT);
|
|
165
|
+
// Initialize SDK
|
|
166
|
+
const sdk = new CloakSDK({
|
|
167
|
+
keypairBytes: keypair.secretKey,
|
|
168
|
+
network: "devnet",
|
|
169
|
+
});
|
|
178
170
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
outputUtxos: [output, await createZeroUtxo(NATIVE_SOL_MINT)],
|
|
183
|
-
externalAmount: amountLamports, // positive = deposit
|
|
184
|
-
depositor: signer.publicKey,
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
connection,
|
|
188
|
-
programId: CLOAK_PROGRAM_ID,
|
|
189
|
-
relayUrl: "https://api.cloak.ag",
|
|
190
|
-
depositorKeypair: signer,
|
|
191
|
-
},
|
|
192
|
-
);
|
|
193
|
-
console.log("Deposit signature:", deposited.signature);
|
|
171
|
+
// Deposit SOL into the privacy pool
|
|
172
|
+
const depositResult = await sdk.deposit(connection, 100_000_000); // 0.1 SOL
|
|
173
|
+
console.log("Deposited! Leaf index:", depositResult.leafIndex);
|
|
194
174
|
|
|
195
|
-
//
|
|
196
|
-
const
|
|
197
|
-
const withdrawn = await fullWithdraw(deposited.outputUtxos, recipient, {
|
|
175
|
+
// Withdraw to a recipient
|
|
176
|
+
const withdrawResult = await sdk.withdraw(
|
|
198
177
|
connection,
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
console.log("Withdraw signature:", withdrawn.signature);
|
|
178
|
+
depositResult.note,
|
|
179
|
+
new PublicKey("RECIPIENT_ADDRESS"),
|
|
180
|
+
{ withdrawAll: true }
|
|
181
|
+
);
|
|
182
|
+
console.log("Withdrawn! TX:", withdrawResult.signature);
|
|
205
183
|
```
|
|
206
184
|
|
|
207
185
|
### React/Next.js (with Wallet Adapter)
|
|
208
186
|
|
|
209
187
|
```typescript
|
|
210
|
-
import {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
createUtxo,
|
|
214
|
-
createZeroUtxo,
|
|
215
|
-
generateUtxoKeypair,
|
|
216
|
-
transact,
|
|
217
|
-
} from "@cloak.dev/sdk";
|
|
218
|
-
import { useConnection, useWallet } from "@solana/wallet-adapter-react";
|
|
219
|
-
import { useCallback } from "react";
|
|
188
|
+
import { CloakSDK } from "@cloak.dev/sdk";
|
|
189
|
+
import { useWallet, useConnection } from "@solana/wallet-adapter-react";
|
|
190
|
+
import { PublicKey } from "@solana/web3.js";
|
|
220
191
|
|
|
221
|
-
|
|
192
|
+
function PrivateTransfer() {
|
|
193
|
+
const { publicKey, signTransaction, sendTransaction } = useWallet();
|
|
222
194
|
const { connection } = useConnection();
|
|
223
|
-
const wallet = useWallet();
|
|
224
195
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
inputUtxos: [await createZeroUtxo(NATIVE_SOL_MINT), await createZeroUtxo(NATIVE_SOL_MINT)],
|
|
235
|
-
outputUtxos: [output, await createZeroUtxo(NATIVE_SOL_MINT)],
|
|
236
|
-
externalAmount: amount,
|
|
237
|
-
depositor: wallet.publicKey,
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
connection,
|
|
241
|
-
programId: CLOAK_PROGRAM_ID,
|
|
242
|
-
relayUrl: "https://api.cloak.ag",
|
|
243
|
-
wallet: {
|
|
244
|
-
publicKey: wallet.publicKey,
|
|
245
|
-
signTransaction: wallet.signTransaction,
|
|
246
|
-
},
|
|
196
|
+
// Initialize SDK with wallet adapter
|
|
197
|
+
const sdk = useMemo(() => {
|
|
198
|
+
if (!publicKey) return null;
|
|
199
|
+
return new CloakSDK({
|
|
200
|
+
network: "devnet",
|
|
201
|
+
wallet: {
|
|
202
|
+
publicKey,
|
|
203
|
+
signTransaction: (tx) => signTransaction!(tx),
|
|
204
|
+
sendTransaction: (tx, conn, opts) => sendTransaction(tx, conn, opts),
|
|
247
205
|
},
|
|
248
|
-
);
|
|
249
|
-
|
|
250
|
-
}, [connection, wallet]);
|
|
206
|
+
});
|
|
207
|
+
}, [publicKey, signTransaction, sendTransaction]);
|
|
251
208
|
|
|
252
|
-
|
|
209
|
+
const handleDeposit = async () => {
|
|
210
|
+
const result = await sdk.deposit(connection, 100_000_000);
|
|
211
|
+
console.log("Deposited!", result.signature);
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
return <button onClick={handleDeposit}>Deposit 0.1 SOL</button>;
|
|
253
215
|
}
|
|
254
216
|
```
|
|
255
217
|
|
|
256
|
-
|
|
257
|
-
(`getPublicKey`, `getCurrentRoot`, `getMerkleProof`, `getTransactionStatus`,
|
|
258
|
-
`importWalletKeys`, `exportWalletKeys`, `getConfig`). All transaction-emitting
|
|
259
|
-
calls use the standalone helpers above.
|
|
218
|
+
## Core Methods
|
|
260
219
|
|
|
261
|
-
|
|
220
|
+
### Deposit
|
|
262
221
|
|
|
263
|
-
|
|
222
|
+
Deposit SOL into the privacy pool:
|
|
264
223
|
|
|
265
224
|
```typescript
|
|
266
|
-
const result = await
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
outputUtxos: [outputUtxo, await createZeroUtxo()],
|
|
270
|
-
externalAmount: 10_000_000n, // positive = deposit
|
|
271
|
-
depositor: signer.publicKey,
|
|
272
|
-
},
|
|
273
|
-
{ connection, programId: CLOAK_PROGRAM_ID, relayUrl: "https://api.cloak.ag", depositorKeypair: signer },
|
|
274
|
-
);
|
|
275
|
-
console.log("Leaf index:", result.commitmentIndices[0]);
|
|
276
|
-
console.log("Output UTXO:", result.outputUtxos[0]);
|
|
225
|
+
const result = await sdk.deposit(connection, 100_000_000); // 0.1 SOL
|
|
226
|
+
// Save the note securely - you need it to withdraw!
|
|
227
|
+
console.log(result.note);
|
|
277
228
|
```
|
|
278
229
|
|
|
279
230
|
### Withdraw
|
|
280
231
|
|
|
281
|
-
|
|
282
|
-
import { fullWithdraw, partialWithdraw } from "@cloak.dev/sdk";
|
|
232
|
+
Withdraw to a single recipient:
|
|
283
233
|
|
|
284
|
-
|
|
285
|
-
const result = await
|
|
286
|
-
connection,
|
|
287
|
-
programId: CLOAK_PROGRAM_ID,
|
|
288
|
-
relayUrl: "https://api.cloak.ag",
|
|
289
|
-
depositorKeypair: signer,
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
// Or withdraw a portion and keep the change shielded.
|
|
293
|
-
const partial = await partialWithdraw(myUtxos, recipientPublicKey, 5_000_000n, {
|
|
234
|
+
```typescript
|
|
235
|
+
const result = await sdk.withdraw(
|
|
294
236
|
connection,
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
237
|
+
note,
|
|
238
|
+
recipientPublicKey,
|
|
239
|
+
{ withdrawAll: true }
|
|
240
|
+
);
|
|
299
241
|
```
|
|
300
242
|
|
|
301
|
-
###
|
|
243
|
+
### Send to Multiple Recipients
|
|
302
244
|
|
|
303
|
-
|
|
304
|
-
import { transfer } from "@cloak.dev/sdk";
|
|
245
|
+
Send to up to 5 recipients:
|
|
305
246
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
});
|
|
247
|
+
```typescript
|
|
248
|
+
const result = await sdk.send(connection, note, [
|
|
249
|
+
{ recipient: addr1, amount: 50_000_000 },
|
|
250
|
+
{ recipient: addr2, amount: 47_000_000 },
|
|
251
|
+
]);
|
|
312
252
|
```
|
|
313
253
|
|
|
314
|
-
### Swap
|
|
254
|
+
### Swap
|
|
255
|
+
|
|
256
|
+
Swap SOL for SPL tokens:
|
|
315
257
|
|
|
316
258
|
```typescript
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
inputUtxos: myUtxos,
|
|
322
|
-
swapAmount: 10_000_000n,
|
|
323
|
-
outputMint: new PublicKey("TOKEN_MINT_ADDRESS"),
|
|
324
|
-
recipientAta: recipientTokenAccount,
|
|
325
|
-
minOutputAmount: 1_000_000n,
|
|
326
|
-
},
|
|
327
|
-
{
|
|
328
|
-
connection,
|
|
329
|
-
programId: CLOAK_PROGRAM_ID,
|
|
330
|
-
relayUrl: "https://api.cloak.ag",
|
|
331
|
-
depositorKeypair: signer,
|
|
332
|
-
},
|
|
333
|
-
);
|
|
259
|
+
const result = await sdk.swap(connection, note, recipientPublicKey, {
|
|
260
|
+
outputMint: "TOKEN_MINT_ADDRESS",
|
|
261
|
+
minOutputAmount: 1000000,
|
|
262
|
+
});
|
|
334
263
|
```
|
|
335
264
|
|
|
336
265
|
## Fee Structure
|
|
337
266
|
|
|
338
|
-
- **Fixed Fee**: 0.005 SOL (5,000,000 lamports)
|
|
339
|
-
- **Variable Fee**: 0.3% of
|
|
267
|
+
- **Fixed Fee**: 0.005 SOL (5,000,000 lamports)
|
|
268
|
+
- **Variable Fee**: 0.3% of deposit amount
|
|
340
269
|
|
|
341
|
-
Use `getDistributableAmount()` to calculate the amount
|
|
270
|
+
Use `getDistributableAmount()` to calculate the amount after fees:
|
|
342
271
|
|
|
343
272
|
```typescript
|
|
344
273
|
import { getDistributableAmount } from "@cloak.dev/sdk";
|
|
345
274
|
|
|
346
|
-
const
|
|
347
|
-
const
|
|
275
|
+
const deposited = 100_000_000; // 0.1 SOL
|
|
276
|
+
const afterFees = getDistributableAmount(deposited); // ~94,700,000 lamports
|
|
348
277
|
```
|
|
349
278
|
|
|
350
|
-
##
|
|
279
|
+
## Notes
|
|
351
280
|
|
|
352
|
-
A **
|
|
281
|
+
A **Cloak Note** is a cryptographic commitment representing a private amount of SOL:
|
|
353
282
|
|
|
354
283
|
```typescript
|
|
355
|
-
interface
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
284
|
+
interface CloakNote {
|
|
285
|
+
version: string;
|
|
286
|
+
amount: number; // Amount in lamports
|
|
287
|
+
commitment: string; // Commitment hash
|
|
288
|
+
sk_spend: string; // Spending key (keep secret!)
|
|
289
|
+
r: string; // Randomness
|
|
290
|
+
timestamp: number;
|
|
291
|
+
network: Network;
|
|
292
|
+
leafIndex?: number; // Set after deposit
|
|
293
|
+
depositSignature?: string;
|
|
363
294
|
}
|
|
364
295
|
```
|
|
365
296
|
|
|
366
|
-
**⚠️ Important**:
|
|
297
|
+
**⚠️ Important**: Save your notes securely! Without the note, you cannot withdraw your funds.
|
|
367
298
|
|
|
368
299
|
## Compliance Chain Scanning
|
|
369
300
|
|
|
@@ -403,31 +334,13 @@ sequenceDiagram
|
|
|
403
334
|
## Error Handling
|
|
404
335
|
|
|
405
336
|
```typescript
|
|
406
|
-
import {
|
|
407
|
-
CloakError,
|
|
408
|
-
UtxoAlreadySpentError,
|
|
409
|
-
RootNotFoundError,
|
|
410
|
-
classifyRelayError,
|
|
411
|
-
fullWithdraw,
|
|
412
|
-
CLOAK_PROGRAM_ID,
|
|
413
|
-
} from "@cloak.dev/sdk";
|
|
337
|
+
import { CloakError } from "@cloak.dev/sdk";
|
|
414
338
|
|
|
415
339
|
try {
|
|
416
|
-
await
|
|
417
|
-
connection,
|
|
418
|
-
programId: CLOAK_PROGRAM_ID,
|
|
419
|
-
relayUrl: "https://api.cloak.ag",
|
|
420
|
-
depositorKeypair: signer,
|
|
421
|
-
});
|
|
340
|
+
await sdk.withdraw(connection, note, recipient);
|
|
422
341
|
} catch (error) {
|
|
423
|
-
if (error instanceof
|
|
424
|
-
|
|
425
|
-
// carries which nullifiers collided.
|
|
426
|
-
console.log("Spent nullifiers:", error.nullifiers);
|
|
427
|
-
} else if (error instanceof RootNotFoundError) {
|
|
428
|
-
// Relay/chain root mismatch; retry against a fresh tree.
|
|
429
|
-
} else if (error instanceof CloakError) {
|
|
430
|
-
console.log("Category:", error.category); // 'wallet' | 'network' | 'prover' | 'relay' | 'validation' | 'environment' | 'service' | 'indexer'
|
|
342
|
+
if (error instanceof CloakError) {
|
|
343
|
+
console.log("Category:", error.category); // 'wallet', 'network', 'prover', etc.
|
|
431
344
|
console.log("Retryable:", error.retryable);
|
|
432
345
|
}
|
|
433
346
|
}
|