Skip to main content

Quick Start Guide

This guide walks through deploying and interacting with Lunarys Protocol contracts.

Prerequisites

  • Node.js v20 or higher
  • pnpm package manager
  • A wallet with testnet ETH (Sepolia or Arbitrum Sepolia)

Installation

Clone the repository and install dependencies:

git clone https://github.com/lunarys-protocol/lunarys-dex.git
cd lunarys-dex/cofhe-hardhat-starter
pnpm install

Configuration

Set Up Environment

Configure your wallet mnemonic:

npx hardhat vars set MNEMONIC

Enter your 12 or 24 word mnemonic when prompted.

Compile Contracts

pnpm compile

This compiles all Solidity contracts and generates TypeChain types.

Deployment

Deploy All Contracts

Deploy the full protocol to a testnet:

npx hardhat deploy-all --network eth-sepolia

This deploys:

  1. PoolFactory
  2. Two test FHERC20 tokens
  3. A PrivacyPool for the token pair
  4. PositionNFT for the pool

Deploy Individual Components

Deploy only the factory:

npx hardhat deploy-factory --network eth-sepolia

Create a new pool:

npx hardhat create-pool \
--factory 0x... \
--tokena 0x... \
--tokenb 0x... \
--fee 3000 \
--network eth-sepolia

Interacting with Contracts

Using Hardhat Console

npx hardhat console --network eth-sepolia
// Get contract instances
const pool = await ethers.getContractAt("PrivacyPool", "0x...");
const tokenA = await ethers.getContractAt("TestFHERC20", "0x...");
const tokenB = await ethers.getContractAt("TestFHERC20", "0x...");

// Mint test tokens
await tokenA.mint(signer.address, ethers.parseEther("1000"));
await tokenB.mint(signer.address, ethers.parseEther("1000"));

// Wrap to encrypted
await tokenA.wrap(ethers.parseEther("100"));
await tokenB.wrap(ethers.parseEther("100"));

Bootstrap Pool

Initialize the pool with liquidity:

// Encrypt amounts using cofhejs
const amountA = await cofhe.encrypt(100n * 10n**18n, FheType.Uint64);
const amountB = await cofhe.encrypt(100n * 10n**18n, FheType.Uint64);

// Bootstrap pool
await pool.bootstrap(amountA, amountB);

Execute a Swap

// Encrypt swap amount
const swapAmount = await cofhe.encrypt(10n * 10n**18n, FheType.Uint64);

// Swap A for B
await pool.swapExactAForB(
swapAmount,
recipientAddress,
"0x" // hook context
);

Running Tests

Execute the test suite:

pnpm test

Run specific tests:

pnpm test test/PoolFactory.ts

Frontend Integration

Start the frontend development server:

cd ../frontend
npm install
npm run dev

Configure environment:

# Create .env.local
NEXT_PUBLIC_REOWN_PROJECT_ID=your_project_id

Open http://localhost:3000 to access the interface.

Network Configuration

Supported Networks

NetworkChain IDRPC
Ethereum Sepolia11155111Public RPC
Arbitrum Sepolia421614Public RPC

Hardhat Configuration

The hardhat.config.ts includes network configurations:

networks: {
"eth-sepolia": {
url: "https://ethereum-sepolia-rpc.publicnode.com",
accounts: { mnemonic },
chainId: 11155111
},
"arb-sepolia": {
url: "https://sepolia-rollup.arbitrum.io/rpc",
accounts: { mnemonic },
chainId: 421614
}
}

Troubleshooting

Transaction Reverts

  • Ensure tokens are wrapped (encrypted) before interacting with the pool
  • Check that the pool is bootstrapped before swapping
  • Verify sufficient encrypted balance for transfers

Gas Issues

  • FHE operations require more gas than standard operations
  • Set higher gas limits for swap transactions (~1,000,000)
  • Use gasPrice parameter if transactions are pending

Permission Errors

  • FHE values require explicit permissions
  • Ensure FHE.allow() is called for recipients
  • Check that the contract has permission via FHE.allowThis()