Note — Work in progress: The repository already includes all the main components, services, UI and smart contracts . We're actively finishing the final end-to-end integration and the local AggSandbox setup to enable easy local testing and full deployment.
Demo / Announcement: See the demo announcement for a short showcase: POC Demo on X.
EggSwap is an educational cross-chain swap platform that demonstrates how to bridge tokens from one blockchain and execute swaps on another using Agglayer's Unified Bridge. It enables seamless token transfers between Sepolia and Cardona with automatic swap execution on the destination chain.
| Feature | Description | Example |
|---|---|---|
| Cross-Chain Swapping | Bridge tokens and execute swaps atomically | TOKEN_A on Sepolia → TOKEN_B on Cardona |
| Automatic Execution | Swap executes automatically upon token arrival | Bridge + swap in single user transaction |
| Bi-directional Support | Works in both directions between chains | Sepolia ↔ Cardona |
| Pre-approval System | Smart contract permissions for seamless UX | Bridge executor approval management |
- Application Architecture
- API Layer Components
- Backend Service Implementation
- Bridge Integration Strategy
- Smart Contract Integration
- Component Architecture
- Configuration Management
- Error Handling & Resilience
- Troubleshooting Guide
User Journey: Select Tokens → Bridge & Swap → Verify
- Token Selection - Choose source and destination tokens
- Amount Input - Specify swap amount and calculate estimates
- Pre-approval - Ensure contract permissions on destination
- Bridge & Call - Submit bridge transaction with swap calldata
- Automatic Execution - Swap executes on destination chain
- Status Monitoring - Track transaction and bridge status
Source Chain: Lock Tokens → Bridge Message
↓
Agglayer Bridge: Transport Assets + Calldata
↓
Destination Chain: Mint Tokens → Execute Swap
File: api/cross-chain-swap.ts
Purpose: Primary orchestration endpoint for cross-chain operations
1. Validate Parameters
2. Determine Token Routes
3. Calculate Swap Paths
4. Execute Bridge & Call
5. Return Transaction Hash
File: api/swap-tokens.ts
Purpose: Local chain swap execution and estimation
- Gas estimation for swap operations
- Slippage calculation
- Route optimization
File: api/check-transaction-status.ts
Purpose: Real-time transaction monitoring
- Transaction receipt polling
- Bridge status tracking
- Error detection and reporting
- Progress state management
File: api/claim-message.ts
Purpose: Manual bridge message claiming when required
File: api/token-options.ts
Purpose: Token metadata and configuration management
File: backend/chainSwap.ts
Purpose: Core implementation for cross-chain swap orchestration
- Token configuration management
- Pre-approval system coordination
- Swap calldata generation
- Bridge transaction execution
- RPC resilience implementation
// Critical approval chain
1. Approve Bridge Executor → Token spending rights
2. Approve Router → Swap execution rights
3. Execute Bridge & Call → Atomic operationFile: backend/crossChainSwap.ts
Purpose: High-level coordinator for bridge operations
Input Validation → Route Calculation → Bridge Preparation → Execution → Monitoring
File: backend/claimMessage.ts
Purpose: Bridge message finalization logic
File: backend/utils_lxly.ts
Purpose: Agglayer bridge client integration utilities
- LxLy client initialization
- Bridge parameter configuration
- Message encoding utilities
- Status polling helpers
Pattern: Bridge & Call Architecture
| Phase | Location | Action |
|---|---|---|
| Prepare | Source Chain | Create swap calldata for destination |
| Bridge | Bridge Layer | Lock tokens and send message |
| Execute | Destination | Mint tokens and execute swap |
// Core bridge operation
await client.bridgeExtensions[sourceNetworkId].bridgeAndCall(
sourceTokenAddress,
amount,
destinationNetworkId,
routerAddress,
userAddress,
swapCalldata,
forceUpdateGlobalExitRoot,
permitData
);// Swap instruction encoding
const iface = new ethers.Interface(RouterAbi);
const calldata = iface.encodeFunctionData("swapExactTokensForTokens", [
amountInWei,
minAmountOut.toString(),
swapPath,
userAddress,
deadline
]);Networks: Sepolia (Network 0), Cardona (Network 1)
const TOKENS = {
0: { // Sepolia
TOKEN_A: "0x794203e2982EDA39b4cfC3e1F802D6ab635FcDcB",
TOKEN_B: "0x5eE2DeAd28817153F6317a3A21F1e8609da0c498"
},
1: { // Cardona
TOKEN_A: "0x19956fa010ECAeA67bd8eAa91b18A0026F1c31D7",
TOKEN_B: "0xD6395Ee1b7DFDB64ba691fdB5B71b3624F168C4C"
}
};Purpose: Uniswap-compatible swap execution
swapExactTokensForTokens- Execute token swapsgetAmountsOut- Calculate swap outputsaddLiquidity- Liquidity provision
// Required approvals for cross-chain swaps
token.approve(bridgeExecutorAddress, maxAmount);
token.approve(routerAddress, maxAmount);| Component | File | Purpose |
|---|---|---|
| CrossChainSwapForm | components/CrossChainSwapForm.tsx |
Main swap interface |
| SwapForm | components/SwapForm.tsx |
Local swap operations |
| LiquidityForm | components/LiquidityForm.tsx |
Liquidity management |
- Token selection interface
- Amount input and validation
- Cross-chain route calculation
- Transaction status monitoring
- Error handling and user feedback
- Single-chain swap operations
- Slippage configuration
- Gas estimation display
- Add/remove liquidity operations
- Pool information display
- Yield calculation
# RPC Configuration
NETWORK_0_RPC=<sepolia_rpc_url>
NETWORK_1_RPC=<cardona_rpc_url>
# Bridge Addresses
NETWORK_0_BRIDGE=<sepolia_bridge_address>
NETWORK_1_BRIDGE=<cardona_bridge_address>
# Signer Configuration
USER1_PRIVATE_KEY=<server_signer_key>const configuration = {
0: { // Sepolia
rpcUrl: process.env.NETWORK_0_RPC,
bridgeAddress: process.env.NETWORK_0_BRIDGE,
bridgeExtensionAddress: "0x...",
routerAddress: "0x..."
},
1: { // Cardona
rpcUrl: process.env.NETWORK_1_RPC,
bridgeAddress: process.env.NETWORK_1_BRIDGE,
bridgeExtensionAddress: "0x...",
routerAddress: "0x..."
}
};