@fairblock/stabletrust 1.0.22 → 2.0.1

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.
@@ -0,0 +1,338 @@
1
+ /**
2
+ * Anonymous Confidential Transfer — Basic Flow
3
+ *
4
+ * [1] Generate two UUIDs as account IDs
5
+ * [2] Derive ElGamal keypairs for both accounts
6
+ * [3] Create both anonymous accounts via Fairycloak
7
+ * [4] Deposit tokens into anon1
8
+ * [5] Transfer anon1 → anon2
9
+ * [6] Apply pending balance for anon2
10
+ * [7] Withdraw anon2 → public address
11
+ *
12
+ * Run:
13
+ * node examples/anonymous-flow.js
14
+ */
15
+
16
+ import { ethers } from "ethers";
17
+ import { randomUUID } from "crypto";
18
+ import dotenv from "dotenv";
19
+ import { AnonymousTransferClient } from "@fairblock/stabletrust";
20
+
21
+ dotenv.config();
22
+
23
+ // ── Config ────────────────────────────────────────────────────────────────────
24
+
25
+ const EVM_RPC = process.env.EVM_RPC ?? "http://127.0.0.1:8545";
26
+ const FAIRYCLOAK_URL = process.env.FAIRYCLOAK_URL ?? "http://127.0.0.1:8080";
27
+ const CHAIN_ID = Number(process.env.CHAIN_ID ?? "31337");
28
+ const TOKEN_ADDRESS =
29
+ process.env.TOKEN_ADDRESS ?? "0xE915164570b027C2A0FfadcB1B672192E35BF008";
30
+ const TOKEN_DECIMALS = Number(process.env.TOKEN_DECIMALS ?? "6");
31
+
32
+ // Amounts in raw ERC-20 units (6 decimals — matches complete-flow.js)
33
+ const DEPOSIT_AMOUNT = 100_000n; // 0.1 USDC
34
+ const TRANSFER_AMOUNT = 50_000n; // 0.05 USDC
35
+ const WITHDRAW_AMOUNT = 25_000n; // 0.025 USDC
36
+
37
+ // Anvil test accounts — override via .env
38
+ const ANON1_PK =
39
+ process.env.ANON1_PRIVATE_KEY ??
40
+ "0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6";
41
+ const ANON2_PK =
42
+ process.env.ANON2_PRIVATE_KEY ??
43
+ "0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba";
44
+ const WITHDRAW_DEST_PK =
45
+ process.env.WITHDRAW_DEST_PK ??
46
+ "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
47
+
48
+ // ── Helpers ───────────────────────────────────────────────────────────────────
49
+
50
+ const log = console.log;
51
+ const fmt = (n, decimals) => ethers.formatUnits(BigInt(n), decimals);
52
+
53
+ async function logBalance(client, accountId, keys, token, _decimals, label) {
54
+ const bal = await client.getBalance(accountId, token, keys.privateKey);
55
+
56
+ // getBalance() returns amounts in contract scale (rawAmount * 100 / 10^tokenDecimals).
57
+ // Formatting with 2 decimal places gives the correct human-readable value: e.g.
58
+ // contract scale 10 → formatUnits(10, 2) = "0.10" (= 0.1 USDC)
59
+ // contract scale 5 → formatUnits(5, 2) = "0.05" (= 0.05 USDC)
60
+ console.log(
61
+ `[BALANCE][${label}] acc=${accountId} | ` +
62
+ `avail=${fmt(bal.available, 2)} | ` +
63
+ `pending=${fmt(bal.pending, 2)} | ` +
64
+ `total=${fmt(bal.amount, 2)}`,
65
+ );
66
+
67
+ return bal;
68
+ }
69
+
70
+ /**
71
+ * Poll until hasPendingAction flips to false (CW→EVM state settled).
72
+ */
73
+ async function waitForAccountReady(
74
+ client,
75
+ accountId,
76
+ { timeoutMs = 180_000, label = "" } = {},
77
+ ) {
78
+ const tag = label ? `[${label}] ` : "";
79
+ process.stdout.write(
80
+ ` → ${tag}waiting for account ${accountId} to be ready`,
81
+ );
82
+ const deadline = Date.now() + timeoutMs;
83
+ while (Date.now() < deadline) {
84
+ const info = await client.getAnonymousAccountInfo(accountId);
85
+ if (!info.hasPendingAction) {
86
+ console.log(" ✓");
87
+ return info;
88
+ }
89
+ process.stdout.write(".");
90
+ await new Promise((r) => setTimeout(r, 2000));
91
+ }
92
+ console.log(" ✗");
93
+ throw new Error(`Timeout waiting for account ${accountId} to be ready`);
94
+ }
95
+
96
+ // ── Main ──────────────────────────────────────────────────────────────────────
97
+
98
+ async function main() {
99
+ console.log("\n═══════════════════════════════════════════════════════");
100
+ console.log(" Anonymous Confidential Transfer — Basic Flow");
101
+ console.log("═══════════════════════════════════════════════════════");
102
+ log("Fairycloak :", FAIRYCLOAK_URL);
103
+ log("Token :", TOKEN_ADDRESS);
104
+
105
+ const provider = new ethers.JsonRpcProvider(EVM_RPC);
106
+ const anon1Wallet = new ethers.Wallet(ANON1_PK, provider);
107
+ const anon2Wallet = new ethers.Wallet(ANON2_PK, provider);
108
+ const withdrawDest = new ethers.Wallet(WITHDRAW_DEST_PK, provider).address;
109
+
110
+ log("Anon1 :", anon1Wallet.address);
111
+ log("Anon2 :", anon2Wallet.address);
112
+ log("Withdraw → :", withdrawDest);
113
+
114
+ const client = new AnonymousTransferClient({
115
+ fairycloakUrl: FAIRYCLOAK_URL,
116
+ chainId: CHAIN_ID,
117
+ rpcUrl: EVM_RPC,
118
+ });
119
+
120
+ // ── [1] Generate account IDs ─────────────────────────────────────────────────
121
+
122
+ console.log("\n── [1] Generate anonymous account IDs ──────────────────");
123
+
124
+ const anon1Id = randomUUID();
125
+ const anon2Id = randomUUID();
126
+ log("anon1 id:", anon1Id);
127
+ log("anon2 id:", anon2Id);
128
+
129
+ // ── [2] Derive ElGamal keypairs ──────────────────────────────────────────────
130
+
131
+ console.log("\n── [2] Derive ElGamal keypairs ─────────────────────────");
132
+ log("Deriving ElGamal keypairs from wallets + account IDs …");
133
+
134
+ const [anon1Keys, anon2Keys] = await Promise.all([
135
+ client.deriveAnonymousKeys(anon1Wallet, anon1Id),
136
+ client.deriveAnonymousKeys(anon2Wallet, anon2Id),
137
+ ]);
138
+ log("anon1 pubkey:", anon1Keys.publicKey);
139
+ log("anon2 pubkey:", anon2Keys.publicKey);
140
+
141
+ // ── [3] Create accounts ──────────────────────────────────────────────────────
142
+
143
+ console.log("\n── [3] Create anonymous accounts ───────────────────────");
144
+
145
+ log(` creating anon1 (id=${anon1Id}) …`);
146
+ const cr1 = await client.createAccount(anon1Wallet, anon1Id, anon1Keys.publicKey);
147
+ log(` request_id: ${cr1.request_id} status: ${cr1.status}`);
148
+ if (cr1.error) log(` [!] Error: ${cr1.error}`);
149
+
150
+ log(` creating anon2 (id=${anon2Id}) …`);
151
+ const cr2 = await client.createAccount(anon2Wallet, anon2Id, anon2Keys.publicKey);
152
+ log(` request_id: ${cr2.request_id} status: ${cr2.status}`);
153
+ if (cr2.error) log(` [!] Error: ${cr2.error}`);
154
+
155
+ log("Waiting for Fairycloak to confirm account creations …");
156
+ const [r1, r2] = await Promise.all([
157
+ client.waitForRequest(cr1.request_id, { timeoutMs: 180_000 }),
158
+ client.waitForRequest(cr2.request_id, { timeoutMs: 180_000 }),
159
+ ]);
160
+ if (r1.error) log(" [!] create anon1 failed:", r1.error);
161
+ if (r2.error) log(" [!] create anon2 failed:", r2.error);
162
+
163
+ await waitForAccountReady(client, anon1Id, { label: "anon1" });
164
+ await waitForAccountReady(client, anon2Id, { label: "anon2" });
165
+
166
+ const [i1, i2] = await Promise.all([
167
+ client.getAnonymousAccountInfo(anon1Id),
168
+ client.getAnonymousAccountInfo(anon2Id),
169
+ ]);
170
+ log(`anon1 exists=${i1.exists} finalized=${i1.finalized}`);
171
+ log(`anon2 exists=${i2.exists} finalized=${i2.finalized}`);
172
+
173
+ await logBalance(
174
+ client,
175
+ anon1Id,
176
+ anon1Keys,
177
+ TOKEN_ADDRESS,
178
+ TOKEN_DECIMALS,
179
+ "anon1:post-create",
180
+ );
181
+ await logBalance(
182
+ client,
183
+ anon2Id,
184
+ anon2Keys,
185
+ TOKEN_ADDRESS,
186
+ TOKEN_DECIMALS,
187
+ "anon2:post-create",
188
+ );
189
+
190
+ // ── [4] Deposit ──────────────────────────────────────────────────────────────
191
+
192
+ console.log("\n── [4] Deposit into anon1 ──────────────────────────────");
193
+ log(`Depositing ${fmt(DEPOSIT_AMOUNT, TOKEN_DECIMALS)} tokens into anon1 (anon1 pays gas) …`);
194
+
195
+ const dep = await client.deposit(
196
+ anon1Wallet,
197
+ anon1Id,
198
+ TOKEN_ADDRESS,
199
+ DEPOSIT_AMOUNT,
200
+ );
201
+ log(" request_id:", dep.request_id, " status:", dep.status);
202
+ if (dep.error) log(" [!] Error:", dep.error);
203
+ if (dep.tx_hash) log(" tx_hash :", dep.tx_hash);
204
+
205
+ const depFinal = await client.waitForRequest(dep.request_id, {
206
+ timeoutMs: 180_000,
207
+ });
208
+ log(" status :", depFinal.status, " tx_hash:", depFinal.tx_hash ?? "—");
209
+
210
+ await waitForAccountReady(client, anon1Id, { label: "deposit" });
211
+
212
+ await logBalance(
213
+ client,
214
+ anon1Id,
215
+ anon1Keys,
216
+ TOKEN_ADDRESS,
217
+ TOKEN_DECIMALS,
218
+ "anon1:post-deposit",
219
+ );
220
+
221
+ // ── [5] Transfer anon1 → anon2 ───────────────────────────────────────────────
222
+
223
+ console.log("\n── [5] Transfer anon1 → anon2 ──────────────────────────");
224
+ log(`Transferring ${fmt(TRANSFER_AMOUNT, TOKEN_DECIMALS)} tokens …`);
225
+
226
+ const txAnon = await client.transferToAnonymous(anon1Wallet, anon1Id, {
227
+ recipientId: anon2Id,
228
+ token: TOKEN_ADDRESS,
229
+ elGamalPrivateKey: anon1Keys.privateKey,
230
+ amount: TRANSFER_AMOUNT,
231
+ });
232
+ log(" request_id:", txAnon.request_id, " status:", txAnon.status);
233
+ if (txAnon.error) log(" [!] Error:", txAnon.error);
234
+
235
+ const txAnonFinal = await client.waitForRequest(txAnon.request_id, {
236
+ timeoutMs: 180_000,
237
+ });
238
+ log(
239
+ " status :",
240
+ txAnonFinal.status,
241
+ " tx_hash:",
242
+ txAnonFinal.tx_hash ?? "—",
243
+ );
244
+ if (txAnonFinal.error) log(" [!] Error:", txAnonFinal.error);
245
+
246
+ await waitForAccountReady(client, anon1Id, { label: "transfer sender" });
247
+ await waitForAccountReady(client, anon2Id, { label: "transfer recipient" });
248
+
249
+ await logBalance(
250
+ client,
251
+ anon1Id,
252
+ anon1Keys,
253
+ TOKEN_ADDRESS,
254
+ TOKEN_DECIMALS,
255
+ "anon1:post-transfer",
256
+ );
257
+ await logBalance(
258
+ client,
259
+ anon2Id,
260
+ anon2Keys,
261
+ TOKEN_ADDRESS,
262
+ TOKEN_DECIMALS,
263
+ "anon2:post-transfer",
264
+ );
265
+
266
+ // ── [6] Apply pending for anon2 ──────────────────────────────────────────────
267
+
268
+ console.log("\n── [6] Apply pending balance for anon2 ─────────────────");
269
+ log("Moving incoming credit from pending → available …");
270
+
271
+ const ap = await client.applyPending(anon2Wallet, anon2Id);
272
+ log(" request_id:", ap.request_id, " status:", ap.status);
273
+ if (ap.error) log(" [!] Error:", ap.error);
274
+
275
+ const apFinal = await client.waitForRequest(ap.request_id, {
276
+ timeoutMs: 180_000,
277
+ });
278
+ log(" status :", apFinal.status, " tx_hash:", apFinal.tx_hash ?? "—");
279
+ if (apFinal.error) log(" [!] Error:", apFinal.error);
280
+
281
+ await waitForAccountReady(client, anon2Id, { label: "applyPending" });
282
+
283
+ await logBalance(
284
+ client,
285
+ anon2Id,
286
+ anon2Keys,
287
+ TOKEN_ADDRESS,
288
+ TOKEN_DECIMALS,
289
+ "anon2:post-apply",
290
+ );
291
+
292
+ // ── [7] Withdraw anon2 → public address ──────────────────────────────────────
293
+
294
+ console.log("\n── [7] Withdraw from anon2 ─────────────────────────────");
295
+ log(`Withdrawing ${fmt(WITHDRAW_AMOUNT, TOKEN_DECIMALS)} tokens → ${withdrawDest} …`);
296
+
297
+ const wd = await client.withdraw(anon2Wallet, anon2Id, {
298
+ destination: withdrawDest,
299
+ token: TOKEN_ADDRESS,
300
+ plainAmount: WITHDRAW_AMOUNT,
301
+ elGamalPrivateKey: anon2Keys.privateKey,
302
+ });
303
+ log(" request_id:", wd.request_id, " status:", wd.status);
304
+ if (wd.error) log(" [!] Error:", wd.error);
305
+
306
+ const wdFinal = await client.waitForRequest(wd.request_id, {
307
+ timeoutMs: 180_000,
308
+ });
309
+ log(" status :", wdFinal.status, " tx_hash:", wdFinal.tx_hash ?? "—");
310
+ if (wdFinal.error) log(" [!] Error:", wdFinal.error);
311
+
312
+ await waitForAccountReady(client, anon2Id, { label: "withdraw" });
313
+
314
+ await logBalance(
315
+ client,
316
+ anon2Id,
317
+ anon2Keys,
318
+ TOKEN_ADDRESS,
319
+ TOKEN_DECIMALS,
320
+ "anon2:post-withdraw",
321
+ );
322
+
323
+ // ── Done ─────────────────────────────────────────────────────────────────────
324
+
325
+ console.log("\n═══════════════════════════════════════════════════════");
326
+ console.log(" ✅ Anonymous flow completed!");
327
+ console.log("═══════════════════════════════════════════════════════");
328
+ log("anon1 id :", anon1Id);
329
+ log("anon2 id :", anon2Id);
330
+ log("Deposited :", ethers.formatUnits(DEPOSIT_AMOUNT, TOKEN_DECIMALS), "tokens → anon1");
331
+ log("Transferred:", ethers.formatUnits(TRANSFER_AMOUNT, TOKEN_DECIMALS), "tokens → anon2");
332
+ log("Withdrawn :", ethers.formatUnits(WITHDRAW_AMOUNT, TOKEN_DECIMALS), "tokens →", withdrawDest);
333
+ }
334
+
335
+ main().catch((err) => {
336
+ console.error("\n[!]", err.message ?? err);
337
+ process.exit(1);
338
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fairblock/stabletrust",
3
- "version": "1.0.22",
3
+ "version": "2.0.1",
4
4
  "description": "SDK for confidential transfers using homomorphic encryption and zero-knowledge proofs",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
package/pkg/README.md ADDED
@@ -0,0 +1,310 @@
1
+ # Confidential Tokens - Privacy-First Digital Assets
2
+
3
+ A complete implementation of confidential token operations using ElGamal encryption and zero-knowledge proofs. This project includes both a Solidity smart contract (GatewayContract) and a professional web frontend for confidential token management.
4
+
5
+ ## 🚀 Features
6
+
7
+ ### Smart Contract (GatewayContract.sol)
8
+ - **Account Management**: Create and manage confidential accounts with ElGamal keypairs
9
+ - **Token Conversion**: Convert ERC20 tokens to confidential tokens
10
+ - **Private Transfers**: Transfer confidential tokens with zero-knowledge proofs
11
+ - **Secure Withdrawals**: Convert confidential tokens back to ERC20 tokens
12
+ - **Access Control**: Role-based permissions for admin and relayer operations
13
+ - **Event Logging**: Comprehensive event system for tracking operations
14
+
15
+ ### Frontend Application
16
+ - **Professional UI**: Modern, responsive design optimized for real-world usage
17
+ - **Wallet Integration**: MetaMask connection for Ethereum blockchain access
18
+ - **Account Dashboard**: View encrypted balances and account status
19
+ - **Token Operations**: Convert, transfer, and withdraw confidential tokens
20
+ - **Client-Side Security**: All cryptographic operations performed in WebAssembly
21
+ - **Real-Time Updates**: Live status updates and transaction tracking
22
+
23
+ ## 🏗️ Architecture
24
+
25
+ ```
26
+ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
27
+ │ Frontend │ │ GatewayContract │ │ Relayer │
28
+ │ (Web App) │◄──►│ (Solidity) │◄──►│ (Off-chain) │
29
+ │ │ │ │ │ │
30
+ │ • MetaMask │ │ • Account Mgmt │ │ • Proof Verify │
31
+ │ • WebAssembly │ │ • Token Escrow │ │ • State Update │
32
+ │ • Proof Gen │ │ • Event Logging │ │ • Balance Mgmt │
33
+ └─────────────────┘ └──────────────────┘ └─────────────────┘
34
+ ```
35
+
36
+ ## 📁 Project Structure
37
+
38
+ ```
39
+ elgamal-demo/
40
+ ├── GatewayContract.sol # Main smart contract
41
+ ├── src/ # Rust cryptographic library
42
+ │ ├── components/ # Core cryptographic components
43
+ │ │ ├── elgamal.rs # ElGamal encryption implementation
44
+ │ │ ├── proofs.rs # Zero-knowledge proofs
45
+ │ │ └── ...
46
+ │ ├── transfer.rs # Transfer proof generation
47
+ │ ├── withdraw.rs # Withdraw proof generation
48
+ │ └── lib.rs # Library exports
49
+ ├── frontend/ # Web application
50
+ │ ├── index.html # Main application page
51
+ │ ├── styles.css # Professional styling
52
+ │ ├── app.js # Main application logic
53
+ │ ├── deployment-config.js # Configuration file
54
+ │ ├── src/lib.rs # WebAssembly bindings
55
+ │ └── pkg/ # Built WebAssembly files
56
+ └── scripts/ # Deployment scripts
57
+ ```
58
+
59
+ ## 🛠️ Installation & Setup
60
+
61
+ ### Prerequisites
62
+ - **Rust**: Latest stable version
63
+ - **Node.js**: 16+ with npm
64
+ - **Solidity**: For smart contract development
65
+ - **MetaMask**: Browser extension for wallet connection
66
+
67
+ ### 1. Clone and Setup
68
+
69
+ ```bash
70
+ git clone <repository-url>
71
+ cd elgamal-demo
72
+
73
+ # Install Rust dependencies
74
+ cargo build
75
+
76
+ # Setup frontend
77
+ cd frontend
78
+ npm install
79
+ npm run build:wasm
80
+ ```
81
+
82
+ ### 2. Smart Contract Deployment
83
+
84
+ ```bash
85
+ # Deploy GatewayContract (example using Hardhat)
86
+ npx hardhat compile
87
+ npx hardhat run scripts/deploy.js --network <network>
88
+ ```
89
+
90
+ ### 3. Configuration
91
+
92
+ Update `frontend/deployment-config.js` with your deployed contract address and network settings:
93
+
94
+ ```javascript
95
+ export const CONFIG = {
96
+ GATEWAY_CONTRACT_ADDRESS: '0xYourDeployedContractAddress',
97
+ NETWORK: {
98
+ chainId: 1, // Mainnet or testnet
99
+ name: 'Ethereum Mainnet',
100
+ // ... other settings
101
+ }
102
+ };
103
+ ```
104
+
105
+ ### 4. Start Development Server
106
+
107
+ ```bash
108
+ cd frontend
109
+ npm run dev
110
+ # Open http://localhost:8080
111
+ ```
112
+
113
+ ## 🔧 Usage
114
+
115
+ ### 1. Connect Wallet
116
+ - Click "Connect Wallet" in the header
117
+ - Approve MetaMask connection
118
+ - Verify your address is displayed
119
+
120
+ ### 2. Create Confidential Account
121
+ - Click "Create Account" card
122
+ - Generate ElGamal keypair (stored locally)
123
+ - Submit account creation to contract
124
+
125
+ ### 3. Convert Tokens
126
+ - Select token (USDC, USDT, DAI)
127
+ - Enter amount to convert
128
+ - Approve token transfer and confirm conversion
129
+
130
+ ### 4. Private Transfers
131
+ - Enter recipient address
132
+ - Select token and amount
133
+ - Generate zero-knowledge proof
134
+ - Submit confidential transfer
135
+
136
+ ### 5. Withdraw Tokens
137
+ - Select token and amount
138
+ - Generate withdrawal proof
139
+ - Convert back to ERC20 tokens
140
+
141
+ ## 🔐 Security Features
142
+
143
+ ### Cryptographic Security
144
+ - **ElGamal Encryption**: All balances encrypted with user-specific keys
145
+ - **Zero-Knowledge Proofs**: Transfer amounts and balances remain private
146
+ - **Client-Side Generation**: All proofs generated locally in WebAssembly
147
+ - **No Server Dependency**: Cryptographic operations don't require server trust
148
+
149
+ ### Smart Contract Security
150
+ - **Access Control**: Role-based permissions for sensitive operations
151
+ - **Reentrancy Protection**: Guards against reentrancy attacks
152
+ - **Pausable Operations**: Admin can pause contract in emergencies
153
+ - **Event Logging**: Comprehensive audit trail for all operations
154
+
155
+ ### Frontend Security
156
+ - **Local Key Storage**: Private keys stored in browser (use secure storage in production)
157
+ - **Input Validation**: All user inputs validated before processing
158
+ - **Error Handling**: Comprehensive error handling and user feedback
159
+ - **HTTPS Required**: All operations require secure connections
160
+
161
+ ## 🌐 Network Support
162
+
163
+ ### Mainnet
164
+ - Ethereum Mainnet
165
+ - Token addresses for USDC, USDT, DAI
166
+
167
+ ### Testnet
168
+ - Sepolia Testnet
169
+ - Test token addresses
170
+ - Faucet integration for testing
171
+
172
+ ## 📊 API Reference
173
+
174
+ ### WebAssembly Functions
175
+
176
+ ```javascript
177
+ // Generate ElGamal keypair
178
+ const keypair = await generate_keypair();
179
+
180
+ // Encrypt amount with public key
181
+ const encrypted = await encrypt_amount(amount, pubkey);
182
+
183
+ // Generate transfer proof
184
+ const proof = await generate_transfer_proof({
185
+ current_balance_ciphertext,
186
+ current_balance,
187
+ transfer_amount,
188
+ source_keypair,
189
+ destination_pubkey
190
+ });
191
+
192
+ // Generate withdraw proof
193
+ const proof = await generate_withdraw_proof({
194
+ current_balance_ciphertext,
195
+ current_balance,
196
+ withdraw_amount,
197
+ keypair
198
+ });
199
+ ```
200
+
201
+ ### Smart Contract Functions
202
+
203
+ ```solidity
204
+ // Create confidential account
205
+ function createConfidentialAccount(bytes calldata elgamalPubkey)
206
+ external returns (bytes32);
207
+
208
+ // Convert tokens to confidential
209
+ function deposit(DepositItem[] calldata items)
210
+ external returns (bytes32);
211
+
212
+ // Private transfer
213
+ function transferConfidential(address recipient, string calldata denom, bytes calldata transferProofData)
214
+ external returns (bytes32);
215
+
216
+ // Withdraw tokens
217
+ function withdraw(string calldata denom, uint256 amount, bytes calldata withdrawProofData)
218
+ external returns (bytes32);
219
+ ```
220
+
221
+ ## 🚀 Deployment
222
+
223
+ ### Frontend Deployment (Vercel)
224
+
225
+ ```bash
226
+ # Install Vercel CLI
227
+ npm i -g vercel
228
+
229
+ # Deploy
230
+ cd frontend
231
+ vercel --prod
232
+ ```
233
+
234
+ ### Smart Contract Deployment
235
+
236
+ ```bash
237
+ # Using Hardhat
238
+ npx hardhat run scripts/deploy.js --network mainnet
239
+
240
+ # Using Foundry
241
+ forge create --rpc-url <RPC_URL> --private-key <PRIVATE_KEY> GatewayContract
242
+ ```
243
+
244
+ ## 🔍 Testing
245
+
246
+ ### Frontend Testing
247
+
248
+ ```bash
249
+ cd frontend
250
+ npm test
251
+ ```
252
+
253
+ ### Smart Contract Testing
254
+
255
+ ```bash
256
+ npx hardhat test
257
+ ```
258
+
259
+ ### WebAssembly Testing
260
+
261
+ ```bash
262
+ cd frontend
263
+ npm run test:wasm
264
+ ```
265
+
266
+ ## 📝 Development
267
+
268
+ ### Adding New Features
269
+
270
+ 1. **Smart Contract**: Add functions to `GatewayContract.sol`
271
+ 2. **Cryptography**: Implement in Rust library (`src/`)
272
+ 3. **WebAssembly**: Expose functions in `frontend/src/lib.rs`
273
+ 4. **Frontend**: Add UI components in `app.js`
274
+
275
+ ### Code Style
276
+
277
+ - **Rust**: Follow standard Rust conventions
278
+ - **JavaScript**: Use ES6+ features, async/await
279
+ - **Solidity**: Follow OpenZeppelin patterns
280
+ - **CSS**: Use CSS custom properties for theming
281
+
282
+ ## 🤝 Contributing
283
+
284
+ 1. Fork the repository
285
+ 2. Create feature branch (`git checkout -b feature/amazing-feature`)
286
+ 3. Commit changes (`git commit -m 'Add amazing feature'`)
287
+ 4. Push to branch (`git push origin feature/amazing-feature`)
288
+ 5. Open Pull Request
289
+
290
+ ## 📄 License
291
+
292
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
293
+
294
+ ## 🆘 Support
295
+
296
+ - **Issues**: Report bugs and feature requests on GitHub Issues
297
+ - **Discussions**: Join community discussions on GitHub Discussions
298
+ - **Documentation**: Check the [USAGE.md](frontend/USAGE.md) for detailed usage guide
299
+
300
+ ## 🔮 Roadmap
301
+
302
+ - [ ] Multi-asset support
303
+ - [ ] Batch operations
304
+ - [ ] Mobile app
305
+ - [ ] Advanced privacy features
306
+ - [ ] Integration with other DeFi protocols
307
+
308
+ ---
309
+
310
+ **Built with ❤️ for privacy and decentralization**