@aintivirus-ai/mixer-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,711 @@
1
+ # AintiVirus Mixer SDK
2
+
3
+ TypeScript SDK for easy integration with AintiVirus Mixer - a privacy-preserving transaction mixer for both EVM (Ethereum) and Solana blockchains.
4
+
5
+ ## Features
6
+
7
+ - 🔒 **Privacy-Preserving Transactions**: Deposit and withdraw funds anonymously using zero-knowledge proofs
8
+ - 💰 **Multi-Asset Support**: Support for native tokens (ETH/SOL) and ERC20/SPL tokens
9
+ - 🎯 **Staking & Rewards**: Stake assets and earn rewards from mixer fees
10
+ - 🌐 **Cross-Chain**: Unified API for both EVM and Solana
11
+ - 📦 **TypeScript**: Full TypeScript support with type definitions
12
+ - 🚀 **Easy Integration**: Simple API designed for frontend applications
13
+ - ⚛️ **React Hooks**: Optimized React hooks for Next.js with code splitting support
14
+ - 📊 **View Functions**: Comprehensive read-only functions for contract data
15
+ - 🔧 **Admin Functions**: Admin operations for contract management
16
+ - 🏗️ **Deploy Mixers**: Deploy new mixer instances programmatically
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @aintivirus-ai/mixer-sdk
22
+ # or
23
+ yarn add @aintivirus-ai/mixer-sdk
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ### React Hooks (Recommended for Next.js)
29
+
30
+ The SDK provides optimized React hooks for Next.js applications with automatic code splitting:
31
+
32
+ ```typescript
33
+ import { useDeposit, ChainType } from "@aintivirus-ai/mixer-sdk/hooks";
34
+ import {
35
+ generateSecretAndNullifier,
36
+ computeCommitment,
37
+ } from "@aintivirus-ai/mixer-sdk";
38
+ import { parseEther } from "ethers";
39
+
40
+ function DepositPage() {
41
+ const { deposit, isEVMReady } = useDeposit({
42
+ evm: {
43
+ factoryAddress: "0x...",
44
+ },
45
+ });
46
+
47
+ const handleDeposit = async () => {
48
+ const { secret, nullifier } = generateSecretAndNullifier();
49
+ const commitment = computeCommitment(secret, nullifier);
50
+ const amount = parseEther("1");
51
+
52
+ await deposit(ChainType.EVM, amount, commitment);
53
+ };
54
+
55
+ return <button onClick={handleDeposit}>Deposit</button>;
56
+ }
57
+ ```
58
+
59
+ **Available Hooks:**
60
+
61
+ - `useDeposit` - For deposits only
62
+ - `useStake` - For staking/unstaking only
63
+ - `useClaim` - For claiming rewards only
64
+ - `useWithdraw` - For withdrawals only
65
+ - `useView` - For reading contract data only
66
+ - `useDeploy` - For deploying mixers only
67
+ - `useAdmin` - For admin operations only
68
+ - `useAintiVirus` - All-in-one hook (when you need multiple functions)
69
+
70
+ See [Examples](#examples) section for complete hook examples.
71
+
72
+ ### EVM (Ethereum) Example
73
+
74
+ ```typescript
75
+ import {
76
+ AintiVirusEVM,
77
+ AssetMode,
78
+ generateSecretAndNullifier,
79
+ computeCommitment,
80
+ } from "@aintivirus-ai/mixer-sdk";
81
+ import { ethers } from "ethers";
82
+
83
+ // Connect to Ethereum
84
+ const provider = new ethers.BrowserProvider(window.ethereum);
85
+ const signer = await provider.getSigner();
86
+
87
+ // Initialize SDK
88
+ const sdk = new AintiVirusEVM(
89
+ "0x...", // Factory contract address
90
+ "0x...", // Token contract address
91
+ signer
92
+ );
93
+
94
+ // Deposit ETH
95
+ const { secret, nullifier } = generateSecretAndNullifier();
96
+ const commitment = computeCommitment(secret, nullifier);
97
+ const amount = ethers.parseEther("1"); // 1 ETH
98
+
99
+ const result = await sdk.depositEth(amount, commitment);
100
+ console.log("Deposit transaction:", result.txHash);
101
+
102
+ // Withdraw (requires ZK proof - see proof generation section)
103
+ // const proof = await generateWithdrawalProof(...);
104
+ // await sdk.withdraw(proof, amount, AssetMode.ETH);
105
+
106
+ // Stake ETH
107
+ await sdk.stakeEther(ethers.parseEther("10"));
108
+
109
+ // Claim rewards
110
+ const currentSeason = await sdk.getCurrentStakeSeason();
111
+ await sdk.claimEth(currentSeason);
112
+ ```
113
+
114
+ ### Solana Example
115
+
116
+ ```typescript
117
+ import {
118
+ AintiVirusSolana,
119
+ AssetMode,
120
+ generateSecretAndNullifier,
121
+ computeCommitment,
122
+ } from "@aintivirus-ai/mixer-sdk";
123
+ import { Connection, Keypair } from "@solana/web3.js";
124
+ import { Wallet } from "@coral-xyz/anchor";
125
+
126
+ // Connect to Solana
127
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
128
+ const wallet = new Wallet(keypair); // Your wallet/keypair
129
+
130
+ // Initialize SDK
131
+ const sdk = new AintiVirusSolana(
132
+ "AinTiV1ru5FacTor1111111111111111111111111111", // Factory program ID
133
+ "AinTiV1ru5Mixer1111111111111111111111111111", // Mixer program ID
134
+ "AinTiV1ru5Staking1111111111111111111111111111", // Staking program ID
135
+ wallet,
136
+ connection,
137
+ "TokenMintAddress..." // Optional: Token mint address
138
+ );
139
+
140
+ // Deposit SOL
141
+ const { secret, nullifier } = generateSecretAndNullifier();
142
+ const commitment = computeCommitment(secret, nullifier);
143
+ const amount = 1_000_000_000n; // 1 SOL (in lamports)
144
+
145
+ const result = await sdk.depositSol(amount, commitment);
146
+ console.log("Deposit transaction:", result.txHash);
147
+
148
+ // Stake SOL
149
+ await sdk.stakeSol(10_000_000_000n); // 10 SOL
150
+ ```
151
+
152
+ ## React Hooks API
153
+
154
+ ### Individual Hooks (Recommended for Code Splitting)
155
+
156
+ Each hook only loads what it needs, improving bundle size and page load performance.
157
+
158
+ #### `useDeposit`
159
+
160
+ ```typescript
161
+ import { useDeposit, ChainType } from "@aintivirus-ai/mixer-sdk/hooks";
162
+
163
+ const { deposit, isEVMReady, isSolanaReady } = useDeposit({
164
+ evm: {
165
+ factoryAddress: "0x...",
166
+ tokenAddress: "0x...", // Optional
167
+ },
168
+ solana: {
169
+ factoryProgramId: "...",
170
+ mixerProgramId: "...",
171
+ stakingProgramId: "...",
172
+ tokenMint: "...", // Optional
173
+ },
174
+ solanaWallet: wallet, // Optional
175
+ solanaConnection: connection, // Optional
176
+ });
177
+
178
+ // Deposit
179
+ await deposit(ChainType.EVM, amount, commitment);
180
+ ```
181
+
182
+ #### `useStake`
183
+
184
+ ```typescript
185
+ import { useStake, ChainType } from "@aintivirus-ai/mixer-sdk/hooks";
186
+
187
+ const { stake, unstake, isEVMReady } = useStake({
188
+ evm: {
189
+ factoryAddress: "0x...",
190
+ },
191
+ });
192
+
193
+ // Stake
194
+ await stake(ChainType.EVM, amount);
195
+
196
+ // Unstake
197
+ await unstake(ChainType.EVM);
198
+ ```
199
+
200
+ #### `useClaim`
201
+
202
+ ```typescript
203
+ import { useClaim, ChainType } from "@aintivirus-ai/mixer-sdk/hooks";
204
+
205
+ const { claim, getCurrentSeason, isEVMReady } = useClaim({
206
+ evm: {
207
+ factoryAddress: "0x...",
208
+ },
209
+ });
210
+
211
+ // Get current season and claim
212
+ const season = await getCurrentSeason(ChainType.EVM);
213
+ if (season) {
214
+ await claim(ChainType.EVM, season);
215
+ }
216
+ ```
217
+
218
+ #### `useWithdraw`
219
+
220
+ ```typescript
221
+ import {
222
+ useWithdraw,
223
+ ChainType,
224
+ AssetMode,
225
+ } from "@aintivirus-ai/mixer-sdk/hooks";
226
+
227
+ const { withdraw, isEVMReady } = useWithdraw({
228
+ evm: {
229
+ factoryAddress: "0x...",
230
+ },
231
+ });
232
+
233
+ // Withdraw
234
+ await withdraw(ChainType.EVM, proof, amount, AssetMode.ETH);
235
+ ```
236
+
237
+ #### `useView`
238
+
239
+ ```typescript
240
+ import { useView, ChainType, AssetMode } from "@aintivirus-ai/mixer-sdk/hooks";
241
+
242
+ const {
243
+ getMixer,
244
+ mixerExists,
245
+ calculateDepositAmount,
246
+ getFeeRate,
247
+ getCurrentSeason,
248
+ getStakeSeason,
249
+ getStakerRecord,
250
+ hasClaimedEth,
251
+ getTokenBalance,
252
+ getEthBalance,
253
+ isEVMReady,
254
+ } = useView({
255
+ evm: {
256
+ factoryAddress: "0x...",
257
+ },
258
+ });
259
+
260
+ // Read contract data
261
+ const mixer = await getMixer(ChainType.EVM, AssetMode.ETH, amount);
262
+ const exists = await mixerExists(ChainType.EVM, AssetMode.ETH, amount);
263
+ const feeRate = await getFeeRate(ChainType.EVM);
264
+ ```
265
+
266
+ #### `useDeploy`
267
+
268
+ ```typescript
269
+ import {
270
+ useDeploy,
271
+ ChainType,
272
+ AssetMode,
273
+ } from "@aintivirus-ai/mixer-sdk/hooks";
274
+
275
+ const { deployMixer, isEVMReady } = useDeploy({
276
+ evm: {
277
+ factoryAddress: "0x...",
278
+ },
279
+ });
280
+
281
+ // Deploy new mixer
282
+ const result = await deployMixer(ChainType.EVM, AssetMode.ETH, amount);
283
+ console.log("Mixer address:", result.mixerAddress);
284
+ ```
285
+
286
+ #### `useAdmin`
287
+
288
+ ```typescript
289
+ import { useAdmin, ChainType } from "@aintivirus-ai/mixer-sdk/hooks";
290
+
291
+ const {
292
+ setFeeRate,
293
+ setStakingSeasonPeriod,
294
+ startStakeSeason,
295
+ setVerifier,
296
+ setHasher,
297
+ isEVMReady,
298
+ } = useAdmin({
299
+ evm: {
300
+ factoryAddress: "0x...",
301
+ },
302
+ });
303
+
304
+ // Admin operations (requires OPERATOR_ROLE)
305
+ await setFeeRate(ChainType.EVM, BigInt(250)); // 0.25%
306
+ await setStakingSeasonPeriod(ChainType.EVM, BigInt(86400)); // 1 day
307
+ await startStakeSeason(ChainType.EVM);
308
+ ```
309
+
310
+ #### `useAintiVirus` (Unified Hook)
311
+
312
+ Use this hook when you need multiple functions on the same page:
313
+
314
+ ```typescript
315
+ import { useAintiVirus, ChainType } from "@aintivirus-ai/mixer-sdk/hooks";
316
+
317
+ const {
318
+ deposit,
319
+ withdraw,
320
+ stake,
321
+ unstake,
322
+ claim,
323
+ getCurrentSeason,
324
+ getMixer,
325
+ mixerExists,
326
+ calculateDepositAmount,
327
+ isEVMReady,
328
+ isSolanaReady,
329
+ } = useAintiVirus({
330
+ evm: {
331
+ factoryAddress: "0x...",
332
+ },
333
+ });
334
+ ```
335
+
336
+ ### Code Splitting Benefits
337
+
338
+ Using individual hooks provides better code splitting:
339
+
340
+ ```typescript
341
+ // ✅ Good - Only loads deposit code
342
+ import { useDeposit } from "@aintivirus-ai/mixer-sdk/hooks";
343
+
344
+ // ❌ Bad - Loads everything (deposit, withdraw, stake, claim, etc.)
345
+ import { useAintiVirus } from "@aintivirus-ai/mixer-sdk/hooks";
346
+ ```
347
+
348
+ **Benefits:**
349
+
350
+ - Smaller bundle size per page
351
+ - Faster page loads
352
+ - Better tree-shaking
353
+ - Cleaner code organization
354
+
355
+ ## SDK Classes API Reference
356
+
357
+ ### EVM SDK (`AintiVirusEVM`)
358
+
359
+ #### Constructor
360
+
361
+ ```typescript
362
+ new AintiVirusEVM(
363
+ factoryAddress: string,
364
+ tokenAddress: string,
365
+ signerOrProvider: Signer | Provider
366
+ )
367
+ ```
368
+
369
+ #### Methods
370
+
371
+ ##### Deposits
372
+
373
+ - `depositEth(amount: bigint, commitment: bigint): Promise<TransactionResult>`
374
+ - `depositToken(amount: bigint, commitment: bigint): Promise<TransactionResult>`
375
+
376
+ ##### Withdrawals
377
+
378
+ - `withdraw(proof: WithdrawalProof, amount: bigint, mode: AssetMode): Promise<TransactionResult>`
379
+
380
+ ##### Staking
381
+
382
+ - `stakeEther(amount: bigint): Promise<TransactionResult>`
383
+ - `stakeToken(amount: bigint): Promise<TransactionResult>`
384
+ - `unstakeEth(): Promise<TransactionResult>`
385
+ - `unstakeToken(): Promise<TransactionResult>`
386
+
387
+ ##### Rewards
388
+
389
+ - `claimEth(seasonId: bigint): Promise<TransactionResult>`
390
+ - `claimToken(seasonId: bigint): Promise<TransactionResult>`
391
+
392
+ ##### View Functions
393
+
394
+ - `getMixer(mode: AssetMode, amount: bigint): Promise<string>`
395
+ - `mixerExists(mode: AssetMode, amount: bigint): Promise<boolean>`
396
+ - `calculateDepositAmount(amount: bigint): Promise<bigint>`
397
+ - `getFeeRate(): Promise<bigint>`
398
+ - `getCurrentStakeSeason(): Promise<bigint>`
399
+ - `getStakeSeason(seasonId: bigint): Promise<StakeSeason>`
400
+ - `getStakerRecord(address: string): Promise<StakerRecord>`
401
+ - `hasClaimedEth(address: string, seasonId: bigint): Promise<boolean>`
402
+ - `hasClaimedToken(address: string, seasonId: bigint): Promise<boolean>`
403
+ - `getTokenBalance(address: string): Promise<bigint>`
404
+ - `getEthBalance(address: string): Promise<bigint>`
405
+ - `getStakingAddress(): Promise<string>`
406
+
407
+ ##### Deployment
408
+
409
+ - `deployMixer(mode: AssetMode, amount: bigint): Promise<TransactionResult & { mixerAddress: string }>`
410
+
411
+ ### Solana SDK (`AintiVirusSolana`)
412
+
413
+ #### Constructor
414
+
415
+ ```typescript
416
+ new AintiVirusSolana(
417
+ factoryProgramId: string,
418
+ mixerProgramId: string,
419
+ stakingProgramId: string,
420
+ wallet: Wallet,
421
+ connection: Connection,
422
+ tokenMint?: string
423
+ )
424
+ ```
425
+
426
+ #### Methods
427
+
428
+ ##### Deposits
429
+
430
+ - `depositSol(amount: bigint, commitment: bigint): Promise<TransactionResult>`
431
+ - `depositToken(amount: bigint, commitment: bigint): Promise<TransactionResult>`
432
+
433
+ ##### Withdrawals
434
+
435
+ - `withdraw(instructionData: Buffer, nullifierHash: bigint, amount: bigint, mode: AssetMode): Promise<TransactionResult>`
436
+
437
+ ##### Staking
438
+
439
+ - `stakeSol(amount: bigint): Promise<TransactionResult>`
440
+ - `stakeToken(amount: bigint): Promise<TransactionResult>`
441
+ - `unstakeSol(): Promise<TransactionResult>`
442
+ - `unstakeToken(): Promise<TransactionResult>`
443
+
444
+ ##### Rewards
445
+
446
+ - `claimSol(seasonId: bigint): Promise<TransactionResult>`
447
+ - `claimToken(seasonId: bigint): Promise<TransactionResult>`
448
+
449
+ ##### View Functions
450
+
451
+ - `getMixer(mode: AssetMode, amount: bigint): Promise<PublicKey>`
452
+ - `mixerExists(mode: AssetMode, amount: bigint): Promise<boolean>`
453
+ - `calculateDepositAmount(amount: bigint): Promise<bigint>`
454
+ - `getFeeRate(): Promise<bigint>`
455
+ - `getCurrentStakeSeason(): Promise<bigint>`
456
+ - `getStakeSeason(seasonId: bigint): Promise<StakeSeason>`
457
+ - `getStakerRecord(address: PublicKey): Promise<StakerRecord>`
458
+ - `hasClaimedSol(address: PublicKey, seasonId: bigint): Promise<boolean>`
459
+ - `hasClaimedToken(address: PublicKey, seasonId: bigint): Promise<boolean>`
460
+ - `getSolBalance(address: PublicKey): Promise<bigint>`
461
+ - `getTokenBalance(address: PublicKey): Promise<bigint>`
462
+ - `getStakingAddress(): Promise<PublicKey>`
463
+
464
+ ##### Deployment
465
+
466
+ - `deployMixer(mode: AssetMode, amount: bigint): Promise<TransactionResult>`
467
+
468
+ ##### Admin Functions
469
+
470
+ - `setFeeRate(feeRate: bigint): Promise<TransactionResult>`
471
+ - `setStakingSeasonPeriod(period: bigint): Promise<TransactionResult>`
472
+ - `startStakeSeason(): Promise<TransactionResult>`
473
+ - `setVerifier(verifierAddress: string): Promise<TransactionResult>`
474
+ - `setHasher(hasherAddress: string): Promise<TransactionResult>`
475
+
476
+ ## Proof Generation
477
+
478
+ ### Generating Deposit Data
479
+
480
+ ```typescript
481
+ import {
482
+ generateSecretAndNullifier,
483
+ computeCommitment,
484
+ } from "@aintivirus-ai/mixer-sdk";
485
+
486
+ // Generate secret and nullifier
487
+ const { secret, nullifier } = generateSecretAndNullifier();
488
+
489
+ // Compute commitment
490
+ const commitment = computeCommitment(secret, nullifier);
491
+
492
+ // Store these securely - you'll need them for withdrawal
493
+ // secret and nullifier should be kept private
494
+ ```
495
+
496
+ ### Generating Withdrawal Proof
497
+
498
+ ```typescript
499
+ import {
500
+ generateWithdrawalProofFromData,
501
+ buildMerkleTree,
502
+ getMerklePath,
503
+ } from "@aintivirus-ai/mixer-sdk";
504
+ import { readFileSync } from "fs";
505
+
506
+ // Load circuit files (from your build directory)
507
+ const circuitWasm = readFileSync("path/to/mixer.wasm");
508
+ const circuitZkey = readFileSync("path/to/mixer.zkey");
509
+
510
+ // Get all commitments from deposit events
511
+ const commitments = [
512
+ /* ... commitments from events ... */
513
+ ];
514
+
515
+ // Build merkle tree
516
+ const tree = buildMerkleTree(commitments);
517
+ const root = BigInt(tree.root);
518
+
519
+ // Get merkle path for your commitment
520
+ const path = getMerklePath(tree, commitment);
521
+
522
+ // Generate proof
523
+ const proof = await generateWithdrawalProofFromData({
524
+ secret,
525
+ nullifier,
526
+ recipient: "0x...", // Recipient address
527
+ commitments,
528
+ circuitWasm,
529
+ circuitZkey,
530
+ });
531
+
532
+ // Withdraw
533
+ await sdk.withdraw(proof, amount, AssetMode.ETH);
534
+ ```
535
+
536
+ ## Staking & Rewards
537
+
538
+ ### Staking Flow
539
+
540
+ ```typescript
541
+ // 1. Stake assets
542
+ await sdk.stakeEther(ethers.parseEther("10"));
543
+
544
+ // 2. Wait for season to end (or check current season)
545
+ const currentSeason = await sdk.getCurrentStakeSeason();
546
+
547
+ // 3. Check if you can claim
548
+ const hasClaimed = await sdk.hasClaimedEth(userAddress, currentSeason);
549
+ if (!hasClaimed) {
550
+ // 4. Claim rewards
551
+ await sdk.claimEth(currentSeason);
552
+ }
553
+
554
+ // 5. Unstake (optional)
555
+ await sdk.unstakeEth();
556
+ ```
557
+
558
+ ### Viewing Staking Information
559
+
560
+ ```typescript
561
+ // Get current season
562
+ const season = await sdk.getCurrentStakeSeason();
563
+
564
+ // Get season details
565
+ const seasonInfo = await sdk.getStakeSeason(season);
566
+ console.log("Total rewards:", seasonInfo.totalRewardEthAmount);
567
+
568
+ // Get your staking record
569
+ const record = await sdk.getStakerRecord(userAddress);
570
+ console.log("Staked amount:", record.stakedEthAmount);
571
+ console.log("Weight value:", record.ethWeightValue);
572
+ ```
573
+
574
+ ## Types
575
+
576
+ ### AssetMode
577
+
578
+ ```typescript
579
+ enum AssetMode {
580
+ ETH = 0, // For EVM: ETH, For Solana: SOL
581
+ TOKEN = 1,
582
+ }
583
+ ```
584
+
585
+ ### WithdrawalProof
586
+
587
+ ```typescript
588
+ interface WithdrawalProof {
589
+ pA: [bigint, bigint];
590
+ pB: [[bigint, bigint], [bigint, bigint]];
591
+ pC: [bigint, bigint];
592
+ pubSignals: [bigint, bigint, bigint];
593
+ }
594
+ ```
595
+
596
+ ### TransactionResult
597
+
598
+ ```typescript
599
+ interface TransactionResult {
600
+ txHash: string;
601
+ blockNumber?: number;
602
+ blockTime?: number;
603
+ }
604
+ ```
605
+
606
+ ## Error Handling
607
+
608
+ ```typescript
609
+ try {
610
+ await sdk.depositEth(amount, commitment);
611
+ } catch (error) {
612
+ if (error.message.includes("Insufficient")) {
613
+ // Handle insufficient balance
614
+ } else if (error.message.includes("Mixer not deployed")) {
615
+ // Handle mixer not found
616
+ } else {
617
+ // Handle other errors
618
+ }
619
+ }
620
+ ```
621
+
622
+ ## Best Practices
623
+
624
+ 1. **Store Secrets Securely**: Always store `secret` and `nullifier` securely. You'll need them for withdrawals.
625
+
626
+ 2. **Check Mixer Existence**: Before depositing, check if the mixer exists:
627
+
628
+ ```typescript
629
+ const exists = await sdk.mixerExists(AssetMode.ETH, amount);
630
+ if (!exists) {
631
+ throw new Error("Mixer not deployed for this amount");
632
+ }
633
+ ```
634
+
635
+ 3. **Calculate Fees**: Always calculate the total amount including fees:
636
+
637
+ ```typescript
638
+ const totalAmount = await sdk.calculateDepositAmount(amount);
639
+ ```
640
+
641
+ 4. **Handle Approvals**: For token deposits/staking, ensure you approve the factory contract:
642
+
643
+ ```typescript
644
+ const allowance = await token.allowance(userAddress, factoryAddress);
645
+ if (allowance < amount) {
646
+ await token.approve(factoryAddress, amount);
647
+ }
648
+ ```
649
+
650
+ 5. **Monitor Transactions**: Always wait for transaction confirmations:
651
+ ```typescript
652
+ const result = await sdk.depositEth(amount, commitment);
653
+ await provider.waitForTransaction(result.txHash);
654
+ ```
655
+
656
+ ## Examples
657
+
658
+ Complete example implementations are available in the `examples/` directory:
659
+
660
+ - **`deposit-page.tsx`** - Deposit page using `useDeposit` hook
661
+ - **`stake-page.tsx`** - Staking page using `useStake` hook
662
+ - **`view-functions-page.tsx`** - View functions page using `useView` hook
663
+ - **`admin-page.tsx`** - Admin panel using `useAdmin` hook
664
+ - **`deploy-mixer-page.tsx`** - Deploy mixer page using `useDeploy` hook
665
+
666
+ Each example demonstrates:
667
+
668
+ - Proper hook usage
669
+ - Error handling
670
+ - Loading states
671
+ - Transaction status display
672
+
673
+ ## Next.js Integration
674
+
675
+ The hooks are optimized for Next.js with `wagmi` for EVM interactions. See the examples directory for complete Next.js integration patterns.
676
+
677
+ ### Setup
678
+
679
+ 1. Install dependencies:
680
+
681
+ ```bash
682
+ npm install @aintivirus-ai/mixer-sdk wagmi viem @tanstack/react-query
683
+ ```
684
+
685
+ 2. Configure wagmi in your Next.js app (see examples for full setup)
686
+
687
+ 3. Use hooks in your components:
688
+
689
+ ```typescript
690
+ import { useDeposit, ChainType } from "@aintivirus-ai/mixer-sdk/hooks";
691
+ ```
692
+
693
+ ## Development
694
+
695
+ ### Building
696
+
697
+ ```bash
698
+ npm run build
699
+ ```
700
+
701
+ ### TypeScript
702
+
703
+ The SDK is written in TypeScript and includes full type definitions. Make sure your project has TypeScript configured.
704
+
705
+ ## License
706
+
707
+ MIT
708
+
709
+ ## Support
710
+
711
+ For issues, questions, or contributions, please refer to the project repository.