Private Transfers
The Send tab lets you pay any invoice privately — funds pass through the V7 shielded pool, breaking the on-chain link between you and the recipient.
How It Works
Your Wallet ── deposit (commitment) ──▶ Shield Pool (V7)
│
ZK proof ──▶ Proxy ──▶ withdraw ──▶ Recipient
- Your wallet deposits funds into the V7 pool with a cryptographic commitment
- The proxy generates a Groth16 ZK proof proving you own a valid deposit — without revealing which one
- The proxy withdraws to your recipient's address
- The recipient receives the funds with no on-chain link back to you
Two Transfer Modes
DOT → DOT (Same-Token Transfer)
Send DOT/PAS directly to any address on the same network.
- Enter the amount and recipient address
- Supports both H160 (
0x...) and SS58 (Substrate) addresses - SS58 addresses are automatically forwarded via Substrate transfer
- Gas fee estimate displayed before confirming
DOT → ANY (Cross-Currency Transfer)
Send DOT from the pool and receive BTC, ETH, SOL, or any of 70+ supported currencies at the destination.
- Enter amount, select destination currency, enter recipient address
- View the live exchange rate: "1 DOT ≈ X BTC"
- Confirm — your deposit goes into the V7 pool
- The proxy withdraws to a swap-generated deposit address
- The swap provider completes the conversion to your destination currency
Note: The Send tab is available on mainnet only. Testnet selections will show it as disabled.
Async Withdrawal Flow
Because ZK proof generation takes time (~4 seconds with rapidsnark, ~15 seconds with snarkjs), withdrawals are asynchronous:
| Stage | What Happens |
|---|---|
| Depositing | Your wallet submits the depositNative transaction |
| Building Tree | Proxy syncs the Merkle tree from recent blocks |
| Generating Proof | Proxy produces the Groth16 ZK proof |
| Withdrawing | Proxy submits the withdrawal transaction |
| Complete | Funds delivered to recipient |
The UI polls every 3 seconds for progress updates and displays a toast-driven progress indicator.
Proof generation takes ~4.3 seconds on the backend using rapidsnark (C++ prover).
Exchange Rate & Gas Estimation
- Live Rate: Fetched from the swap provider in real-time before you confirm
- Gas Estimate: Uses a real Poseidon commitment for accurate
estimateGas, so you know exactly what you'll pay - Minimum Amounts: Swap minimums are enforced (e.g., 13.422 DOT for DOT→BTC)
Supported Address Formats
| Format | Example | Handling |
|---|---|---|
| H160 (EVM) | 0x13594E535099Aef344807fa8fE7aABe2a371b383 | Direct pool withdrawal |
| SS58 (EVM-derived) | 5GBb8s3oANu6BdbXn... | Auto-converted to H160 |
| SS58 (Native) | 16Ziip8mK44sh7uKFkZ... | Pool → H160 → Substrate forward |
| BTC / Other | bc1qxy2kgdygjrsqtz... | Routed through swap provider |
Native SS58 addresses go through a two-step forwarding process: the pool withdraws to an intermediate H160, then a Substrate transfer_keep_alive sends funds to the final SS58 destination.
API Endpoints
| Endpoint | Purpose |
|---|---|
POST /pool-withdraw | Initiate async withdrawal (returns withdraw_id) |
GET /pool-withdraw-status/<id> | Poll withdrawal progress |
POST /ff-create-order | Create swap order for cross-currency transfers |
POST /exchange_rate | Get live exchange rate between currencies |
POST /tree-rebuild/<network> | Rebuild Merkle tree from deployment block |
Required Setup
- Wallet: Google Chrome + Talisman (or any Polkadot/EVM wallet via Reown AppKit)
- Network: Mainnet only (Polkadot or Kusama AssetHub)
- Gas: Your wallet needs enough DOT/KSM for the deposit transaction; the proxy covers withdrawal gas
- SharedArrayBuffer: Required for multi-threaded ZK proofs in browser