End-to-End Tutorial
This walkthrough combines contract deployments, frontend usage, and the relayer loop so you can experience Lunarys as a user and as an integrator.
1. Deployments at a Glance
| Contract | Sepolia Address | Role |
|---|---|---|
PrivacyPoolV2 | 0x6686134CC77b9eB6D5926D3d9bEC62b1888F0A00 | Constant-product AMM bridging public USDC and encrypted balances |
PositionNFT | 0x86D8eb5153670D4917EbCDb2fFAB859050AAaE60 | ERC-721 receipts for encrypted liquidity |
CERC20 | 0x1Bd921F250BB97631CAD1c87c53cd981668380e9 | Confidential token paired with USDC |
USDC | 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238 | Public asset used by the pool |
Local deployments follow the same flow; addresses are regenerated each time you run the Hardhat scripts.
2. Local Setup
- Install dependencies:
npm install - Start the Hardhat node:
npm run hardhat-node - Deploy and seed contracts:
npm run deploy:hardhat-node - Launch the frontend:
npm run dev:mock - Connect a wallet to chain ID
31337and explore swaps, liquidity, and positions - Reset by rerunning the deploy script and
npm run generate-abi
3. Sepolia Deployment
- Export credentials (
MNEMONIC,INFURA_API_KEY, optionalETHERSCAN_API_KEY) - Deploy with
npm run deploy:sepolia - Regenerate ABIs and restart the frontend with
npm run dev - Connect your wallet to Sepolia and interact with the deployed contracts listed above
4. Frontend Journeys
Swap USDC → ctKN
- On
/pool/<address>, keep the default direction (USDC → ctKN) - Enter an amount and approve USDC if prompted
- Submit the swap and observe immediate encrypted transfer
- Inspect the browser console: you should see a toast confirming the transaction hash and gas usage
Swap ctKN → USDC (Relayer Finalized)
- Toggle direction to ctKN → USDC
- Enter desired USDC output and authorize the pool as a temporary operator
- Submit the swap, wait for relayer confirmation, and watch
finalizeSwapdeliver USDC - Monitor
Statuscard messages: it will cycle through Encrypting → Sending swap → Waiting for external decryption → Confirming. Final state should read✅ Confidential swap finalized. - Optional: open Hardhat console (
npx hardhat console --network localhost) and query_pending(<requestId>)to observe entries disappearing once finalized.
Provide Liquidity
ProvidePanelhandles USDC-only depositsProvideConfidentialPanelshows encrypted balances, decrypts on demand, encrypts deposits, and tracks status
Manage Positions
- Visit
/pool/positions - Fetch your NFTs and click Decrypt amounts to view encrypted liquidity
- Jump back to pools via the Manage shortcut or burn positions on-chain when finished
- Under the hood,
decryptHandlesrequests signatures from the FHE service. Capture the returned map in devtools to verify decrypted bigints.
5. Relayer Loop Summary
- Frontend encrypts the confidential amount
swapToken1ForToken0ExactOutstores aPendingSwapand triggersFHE.requestDecryption- Frontend polls
https://relayer.testnet.zama.cloud/v1/public-decrypt - Once a signature threshold is met, the UI assembles proofs and finalizes the swap
- USDC is released and reserves are updated
Manual Verification
- Contract Logs: Use
npx hardhat console --network localhostand callawait ethers.getContractAt('PrivacyPoolV2', '<pool>').then(p => p.getReserves())to verify reserve changes before and after swaps. - Relayer Request: Manually call the relayer with
curl(see Relayer doc) to ensure decrypted payload matches expectations. - Event Stream: Listen for
SwapConfidentialviaethers.jsto confirm both swap directions emit events.
6. Troubleshooting
| Issue | Action |
|---|---|
| Swap stuck pending | Check relayer status, retry, or resubmit |
Slippage() revert | Increase tolerance or re-quote |
| Wallet showing zero balances after reset | Redeploy, regenerate ABIs, and clear wallet cache |
NoPending during finalization | Request expired—resubmit the swap |
Continue exploring specific components via the architecture documentation or revisit the Quickstart for setup commands.