Skip to content

codeakki/MoveSwap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

17 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

MoveSwap - Cross-Chain Atomic Swap Protocol

πŸš€ Overview

MoveSwap is a comprehensive cross-chain atomic swap protocol enabling secure token exchanges between Base (Ethereum L2) and Sui networks. The protocol combines Hash Time Lock Contracts (HTLCs) with 1inch Limit Order Protocol integration for efficient, trustless cross-chain swaps. The project includes both CLI tools and a modern React frontend for seamless user experience.

🎯 Core Concepts

Atomic Swaps

An atomic swap is a cryptographic technique that allows the exchange of cryptocurrencies from different blockchains without requiring a trusted third party or centralized exchange.

Hash Time Lock Contracts (HTLCs)

HTLCs are smart contracts that use cryptographic hash functions and time-based conditions to create escrow-like functionality:

  • Hash Lock: Funds can only be released by providing the correct secret (preimage)
  • Time Lock: Funds are automatically refunded if not claimed within a specified timeframe

The Escrow Mechanism

In our design, HTLC contracts act as escrow accounts:

  • Ethereum HTLC: Holds ETH/ERC20 tokens in smart contract escrow
  • Sui HTLC: Holds SUI/custom tokens in Move object escrow
  • Conditional Release: Funds only released when cryptographic conditions are met
  • Time Protection: Auto-refund prevents indefinite locking

πŸ“ Project Structure

MoveSwap/
β”œβ”€β”€ contracts/
β”‚   β”œβ”€β”€ ethereum/
β”‚   β”‚   └── HTLC.sol           # Ethereum Hash Time Lock Contracts contract
β”‚   └── sui/
β”‚       β”œβ”€β”€ sources/
β”‚       β”‚   └── htlc.move      # Sui Move HTLC contract
β”‚       β”œβ”€β”€ Move.toml          # Sui package configuration
β”‚       └── build/             # Compiled Move bytecode
β”œβ”€β”€ frontend/                  # React frontend application
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ App.jsx           # Main application component
β”‚   β”‚   β”œβ”€β”€ components/       # UI components
β”‚   β”‚   └── assets/           # Static assets
β”‚   β”œβ”€β”€ package.json          # Frontend dependencies
β”‚   └── vite.config.js        # Vite configuration
β”œβ”€β”€ test/
β”‚   β”œβ”€β”€ atomic_swap_cli.ts    # Interactive CLI for atomic swaps
β”‚   └── test_cli.js           # CLI test suite
β”œβ”€β”€ examples/
β”‚   └── eth_sui_swap.ts       # Complete atomic swap implementation
β”œβ”€β”€ scripts/
β”‚   └── deploy.ts             # Contract deployment scripts
β”œβ”€β”€ config.json               # Multi-network configuration
β”œβ”€β”€ package.json              # Main project dependencies
β”œβ”€β”€ hardhat.config.js         # Hardhat configuration
└── README.md                 # This documentation

🎯 Key Features

  • Cross-Chain Atomic Swaps: Secure token exchanges between Base and Sui
  • 1inch Integration: Efficient DEX integration for Base chain swaps
  • HTLC Security: Hash Time Lock Contracts ensure atomic execution
  • Interactive CLI: Step-by-step swap execution with progress tracking
  • Modern Frontend: React-based UI for user-friendly swap interface
  • Multi-Network Support: Mainnet and testnet configurations
  • Comprehensive Testing: CLI test suite and validation tools

βš™οΈ Environment Setup

1. Prerequisites

  • Node.js: v18 or higher
  • npm/yarn: Package manager
  • Sui CLI: For Sui blockchain interaction
  • Git: Version control
  • pnpm: For frontend dependencies (optional)

2. Installation

# Clone the repository
git clone https://github.com/codeakki/MoveSwap.git
cd MoveSwap

# Install main dependencies
npm install

# Install frontend dependencies (optional)
cd frontend
npm install
cd ..

# Copy environment template
cp env.example .env

3. Environment Variables

Create a .env file with the following variables:

# Base Configuration
BASE_PRIVATE_KEY=your_base_private_key_here
BASE_RPC_URL=https://base-mainnet.g.alchemy.com/v2/YOUR_KEY

# Sui Configuration  
SUI_PRIVATE_KEY=your_sui_private_key_here
SUI_RPC_URL=https://sui-mainnet-rpc.allthatnode.com

# Network Selection
NETWORK=mainnet  # or base-sepolia for testnet

# Optional: 1inch Integration
DEV_PORTAL_API_TOKEN=your_1inch_api_key

# Gas Configuration
MAX_FEE_PER_GAS=0.001
MAX_PRIORITY_FEE_PER_GAS=0.0001
GAS_LIMIT=300000

# Timelock Configuration (in seconds)
BASE_TIMELOCK_DURATION=7200  # 2 hours
SUI_TIMELOCK_DURATION=3600   # 1 hour

πŸ”— Smart Contracts Documentation

Ethereum HTLC Contract (contracts/ethereum/HTLC.sol)

Contract Structure

struct Lock {
    bytes32 htlc_id;      // Unique identifier
    bytes32 hashlock;     // SHA256 hash of secret
    uint256 timelock;     // Expiration timestamp
    address sender;       // Who created the HTLC
    address receiver;     // Who can claim the funds
    uint256 amount;       // Amount locked
    bytes32 secret;       // Revealed secret (initially 0)
    bool withdrawn;       // Has been claimed
    bool refunded;        // Has been refunded
    uint256 created_at;   // Creation timestamp
    address token;        // Token address (0x0 for ETH)
}

Core Functions

createHTLC()
function createHTLC(
    bytes32 _htlc_id,      // Unique swap identifier
    address _receiver,     // Who can claim funds
    bytes32 _hashlock,     // SHA256(secret)
    uint256 _timelock,     // Expiration timestamp
    address _token         // Token address (0x0 for ETH)
) external payable

Purpose: Creates a new HTLC escrow account Process:

  1. Validates timelock is in future
  2. Locks ETH (if token = 0x0) or transfers ERC20 tokens to contract
  3. Creates Lock struct with provided parameters
  4. Emits HTLCCreated event
claimHTLC()
function claimHTLC(
    bytes32 _htlc_id,      // HTLC identifier
    bytes32 _secret        // Secret that hashes to hashlock
) external

Purpose: Claims funds from HTLC by revealing secret Process:

  1. Verifies caller is designated receiver
  2. Checks HTLC hasn't been withdrawn/refunded
  3. Verifies timelock hasn't expired
  4. Validates SHA256(secret) == hashlock
  5. Transfers funds to receiver
  6. Stores revealed secret
  7. Emits HTLCClaimed event
refundHTLC()
function refundHTLC(bytes32 _htlc_id) external

Purpose: Refunds locked funds after timelock expiry Process:

  1. Verifies caller is original sender
  2. Checks HTLC hasn't been withdrawn/refunded
  3. Verifies timelock has expired
  4. Returns funds to sender
  5. Emits HTLCRefunded event
getHTLC() / getSecret()

View functions to query HTLC state and revealed secrets.

Sui HTLC Contract (contracts/sui/sources/htlc.move)

Object Structure

struct HTLC has key, store {
    id: UID,                    // Sui object identifier
    htlc_id: vector<u8>,       // Unique swap identifier
    hashlock: vector<u8>,      // SHA256 hash of secret
    timelock: u64,             // Expiration timestamp
    sender: address,           // Who created the HTLC
    receiver: address,         // Who can claim funds
    amount: u64,               // Amount locked (in MIST)
    secret: vector<u8>,        // Revealed secret (initially empty)
    withdrawn: bool,           // Has been claimed
    refunded: bool,            // Has been refunded
    created_at: u64,           // Creation timestamp
    coin: Option<Coin<SUI>>    // Locked SUI coins
}

Core Functions

create_htlc()
public entry fun create_htlc(
    clock: &Clock,             // System clock for timestamps
    htlc_id: vector<u8>,      // Unique identifier
    receiver: address,         // Who can claim funds
    hashlock: vector<u8>,     // SHA256 hash of secret
    timelock: u64,            // Expiration timestamp
    payment: Coin<SUI>,       // SUI coins to lock
    ctx: &mut TxContext       // Transaction context
)

Purpose: Creates new HTLC object with locked SUI Process:

  1. Creates HTLC object with provided parameters
  2. Stores payment coin in Option<Coin>
  3. Shares object publicly for access
  4. Emits HTLCCreatedEvent
claim_with_secret()
public entry fun claim_with_secret(
    clock: &Clock,             // System clock
    htlc: &mut HTLC,          // HTLC object to claim
    secret: vector<u8>,       // Secret to reveal
    ctx: &mut TxContext       // Transaction context
)

Purpose: Claims SUI by revealing secret Process:

  1. Verifies caller is designated receiver
  2. Checks timelock hasn't expired
  3. Validates SHA256(secret) == hashlock
  4. Extracts coin from Option and transfers to receiver
  5. Stores revealed secret
  6. Emits HTLCClaimedEvent
refund_htlc()
public entry fun refund_htlc(
    clock: &Clock,             // System clock
    htlc: &mut HTLC,          // HTLC object to refund
    ctx: &mut TxContext       // Transaction context
)

Purpose: Refunds SUI after timelock expiry Process:

  1. Verifies caller is original sender
  2. Checks timelock has expired
  3. Returns coin to sender
  4. Emits HTLCRefundedEvent

πŸ”„ Atomic Swap Flow

Complete ETH to SUI Swap Process

sequenceDiagram
    participant Alice as Alice (Base)
    participant OneInch as 1inch Limit Order
    participant SuiHTLC as Sui HTLC
    participant Bob as Bob (SUI)

    Note over Alice,Bob: 1. Setup Phase
    Alice->>Alice: Generate secret & hashlock
    Alice->>Bob: Share hashlock (not secret)

    Note over Alice,Bob: 2. Lock Phase
    Alice->>OneInch: createBaseLimitOrder(WETH→USDC, hashlock, timelock)
    Bob->>SuiHTLC: create_htlc(id, Alice, hashlock, timelock, SUI)

    Note over Alice,Bob: 3. Wait for Finalization
    Alice->>Alice: waitForSuiFinalization()
    Note over Alice: Sui HTLC transaction finalized

    Note over Alice,Bob: 4. Claim Phase (Order matters!)
    Alice->>SuiHTLC: claim_with_secret(secret)
    Note over SuiHTLC: Secret now revealed on-chain
    Alice->>OneInch: executeLimitOrder(secret) [using revealed secret]

    Note over Alice,Bob: 5. Result
    Note over Alice: Alice gets SUI from Sui HTLC
    Note over Alice: Alice gets USDC from 1inch swap
    Note over Bob: Bob gets WETH from 1inch swap
Loading

Implementation Example

// examples/eth_sui_swap.ts
class AtomicSwap {
    async performAtomicSwap(
        fromChain: 'base' | 'sui',
        fromTokenSymbol: string,
        toTokenSymbol: string,
        amount: string,
        fromAddress: string,
        toAddress: string
    ): Promise<boolean> {
        // 1. Generate cryptographic materials
        const { secret, hashlock, htlcId, baseTimelock, suiTimelock } = 
            this.generateSwapDetails();

        let baseLimitOrder: { order: any, signature: string, orderHash: string } | null = null;
        let suiHtlcResult: any = null;

        if (fromChain === 'base') {
            // 2. Create Base 1inch Limit Order (Alice creates order)
            const orderParams: SwapParams = {
                fromToken: this.getTokenInfo(fromTokenSymbol),
                toToken: this.getTokenInfo(toTokenSymbol),
                amount,
                fromAddress: this.baseWallet.address,
                toAddress,
                secretHash: htlcId,
                validUntil: baseTimelock
            };
            baseLimitOrder = await this.createBaseLimitOrder(orderParams);

            // 3. Create Sui HTLC (Bob locks SUI)
            suiHtlcResult = await this.createSuiHTLC(
                htlcId, toAddress, hashlock, suiTimelock, amount
            );
        } else {
            // 3. Create Sui HTLC first (Bob locks SUI)
            suiHtlcResult = await this.createSuiHTLC(
                htlcId, fromAddress, hashlock, suiTimelock, amount
            );

            // 2. Create Base 1inch Limit Order (Alice creates order)
            const orderParams: SwapParams = {
                fromToken: this.getTokenInfo(fromTokenSymbol),
                toToken: this.getTokenInfo(toTokenSymbol),
                amount,
                fromAddress,
                toAddress: this.baseWallet.address,
                secretHash: htlcId,
                validUntil: baseTimelock
            };
            baseLimitOrder = await this.createBaseLimitOrder(orderParams);
        }

        // 4. Wait for Sui transaction finalization
        await this.suiClient.waitForTransaction({
            digest: suiHtlcResult.digest
        });

        // 5. Claim Sui HTLC (Alice reveals secret)
        const suiClaimResult = await this.claimSuiHTLC(
            htlcId, secret, hashlock, suiHtlcResult.digest
        );

        // 6. Execute Base 1inch Limit Order (using revealed secret)
        if (baseLimitOrder) {
            await this.executeLimitOrder(
                baseLimitOrder.order, 
                baseLimitOrder.signature, 
                secret
            );
        }

        return true;
    }
}

πŸ› οΈ Usage Examples

1. Interactive CLI

The project includes a comprehensive CLI for step-by-step atomic swap execution:

# Start the interactive CLI
npx ts-node test/atomic_swap_cli.ts

# Initialize a Base to SUI swap
init-swap base ETH USDC 0.001 0x_sender_address 0x_receiver_address

# Create Base 1inch Limit Order
create-base-order

# Create Sui HTLC
create-sui-htlc

# Wait for Sui finalization
wait-for-sui-finalization

# Claim Sui HTLC (reveals secret)
claim-sui-htlc

# Execute Base 1inch Limit Order
execute-base-order

2. Frontend Application

Launch the React frontend for a user-friendly interface:

# Start the frontend development server
cd frontend
npm run dev

# Build for production
npm run build

3. Programmatic Usage

import { AtomicSwap } from './examples/eth_sui_swap';

const swap = new AtomicSwap();

// Execute Base to SUI swap
await swap.performAtomicSwap(
    'base',                     // from chain
    'ETH',                      // from token (mapped to WETH)
    'USDC',                     // to token
    "0.001",                    // amount
    "0x_base_sender_address",   // Base sender
    "0x_sui_receiver_address"   // SUI recipient
);

// Execute SUI to Base swap
await swap.performAtomicSwap(
    'sui',                      // from chain
    'ETH',                      // from token (SUI amount)
    'USDC',                     // to token on Base
    "0.00001",                  // amount
    "0x_sui_sender_address",    // SUI sender
    "0x_base_receiver_address"  // Base recipient
);

4. Testing

# Run CLI tests
node test/test_cli.js

# Run Hardhat tests
npm run test:hardhat

# Run all tests
npm test

πŸ”§ Development

Local Testing

# Install dependencies
npm install

# Run tests
npm test

# Build TypeScript
npm run build

Contract Deployment

Ethereum (Sepolia Testnet)

# Using Hardhat
npx hardhat deploy --network sepolia

# Verify contract
npx hardhat verify --network sepolia DEPLOYED_ADDRESS

Sui (Testnet)

# Build Move package
sui move build

# Deploy to testnet
sui client publish --gas-budget 100000000

# Update package ID in config.json

Configuration

The project uses a comprehensive config.json for multi-network support:

{
    "base": {
        "rpc": "https://base-mainnet.g.alchemy.com/v2/YOUR_KEY",
        "htlcContract": "0x_deployed_htlc_address",
        "limitOrderProtocol": "0x111111125421ca6dc452d289314280a0f8842a65",
        "weth": "0x4200000000000000000000000000000000000006",
        "usdc": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "privateKey": "YOUR_BASE_PRIVATE_KEY",
        "chainId": 8453
    },
    "sui": {
        "packageId": "0x_deployed_sui_package_id",
        "privateKey": "YOUR_SUI_PRIVATE_KEY"
    },
    "tokens": {
        "ETH": "0x0000000000000000000000000000000000000000",
        "WETH": "0x4200000000000000000000000000000000000006",
        "USDC": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
    },
    "networks": {
        "mainnet": { /* mainnet configuration */ },
        "base-sepolia": { /* testnet configuration */ }
    }
}

🎨 Frontend Application

The project includes a modern React frontend built with Vite and Tailwind CSS:

Features

  • Interactive Swap Interface: User-friendly token swap interface
  • Real-time Progress Tracking: Visual progress indicators for swap steps
  • Multi-Chain Support: Support for Base and Sui networks
  • Responsive Design: Mobile-friendly interface
  • Modern UI Components: Built with Radix UI and Tailwind CSS

Frontend Structure

frontend/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ App.jsx              # Main application component
β”‚   β”œβ”€β”€ components/          # Reusable UI components
β”‚   β”‚   └── ui/             # Base UI components (Button, Card, etc.)
β”‚   β”œβ”€β”€ hooks/              # Custom React hooks
β”‚   β”œβ”€β”€ lib/                # Utility functions
β”‚   └── assets/             # Static assets
β”œβ”€β”€ package.json            # Frontend dependencies
└── vite.config.js          # Vite configuration

Development Commands

# Start development server
cd frontend
npm run dev

# Build for production
npm run build

# Preview production build
npm run preview

πŸ›‘οΈ Security Considerations

Timelock Strategy

  • Base timelock: Longer (2 hours) - gives time for Sui claim
  • Sui timelock: Shorter (1 hour) - forces Alice to claim first
  • Critical: Sui must be claimed before Base to reveal secret

Best Practices

  1. Test with small amounts first
  2. Monitor gas prices before execution
  3. Verify contract addresses before deploying
  4. Use proper error handling for network issues
  5. Implement retry mechanisms for failed transactions

Common Pitfalls

  • Timelock ordering: Sui timelock must be shorter than Base
  • Gas estimation: Set explicit gas limits for reliable execution
  • Secret management: Never share secrets before both HTLCs are created
  • Network delays: Account for block confirmation times
  • 1inch Integration: Ensure proper order validation and gas estimation

πŸ“Š Transaction Monitoring

The implementation includes comprehensive logging with:

  • πŸ”— Transaction hashes for all operations
  • πŸ” Block explorer links (BaseScan & Sui Explorer)
  • β›½ Gas usage tracking
  • πŸ’° Amount and balance verification
  • 🎯 Step-by-step progress indicators
  • πŸ”„ CLI progress tracking with detailed logs

🀝 Contributing

  1. Fork the repository
  2. Create feature branch: git checkout -b feature/new-feature
  3. Commit changes: git commit -am 'Add new feature'
  4. Push to branch: git push origin feature/new-feature
  5. Submit a Pull Request

πŸ“œ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

About

Atomic Swap for one inch Fusion+

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •