PeerSwap

First-ever trustless P2P cross-chain swap: users securely trade tokens without DEXes/bridges

PeerSwap

Created At

ETHGlobal New Delhi

Project Description

PeerSwap - P2P Cross-Chain Swap Protocol

PeerSwap Flow Diagram

Available On Social platforms:

  • Farcaster: https://farcaster.xyz/miniapps/Fsw6avz8_EKu/peerswap
  • World App: https://world.org/mini-app?app_id=app_506a8a5565ba2fca4e523d0a4487d74a

A trustless P2P swap platform where two users can securely exchange tokens across chains without DEXes or bridges.

🚨 The Problem

Meet Mohit and Jack - two crypto enthusiasts with a simple problem.

Mohit has 1000 USDC sitting on Base chain, but he really wants some Tempo tokens that are only available on the Tempo chain. He's been waiting for weeks, checking every DEX and bridge, but there's just no way to get Tempo tokens.

Meanwhile, Jack has plenty of Tempo tokens on Tempo chain, but he needs USDC on Base for his next DeFi play. He's also been searching everywhere - no bridges, no DEXes, nothing.

The frustrating reality:

  • 🚫 No direct bridge between Base and Tempo chains
  • 💸 High slippage on existing DEXes (if they even have the pair)
  • 🏦 Centralized exchanges require KYC and take days
  • 🤝 No secure way for Mohit and Jack to trade directly

They're literally perfect trading partners, but the infrastructure doesn't exist for them to help each other out. This is the P2P swap gap - millions of users with complementary needs, but no trustless way to connect them.

💡 The Solution

A trustless P2P swap platform where two users can securely exchange tokens across chains without DEXes or bridges.

  • Uses hashlocked escrows + timelocks for security
  • Relayer coordinates but never controls funds
  • Works chain-to-chain, simple and effective

Key Features

  • Trustless: No dispute resolution needed
  • No middlemen: Only lightweight relayer
  • Secure & fault-proof: Cryptographic locks
  • Cross-chain compatible
  • User-friendly: Peer-to-peer experience

🏗️ Architecture

Core Components

  1. Smart Contracts (Solidity)

    • EscrowFactory - Main factory contract that deploys escrow instances
    • EscrowSrc - Source chain escrow contract that locks asker's tokens
    • EscrowDst - Destination chain escrow contract that locks fullfiller's tokens
    • BaseEscrow - Abstract base contract with common escrow functionality
  2. Backend Services (Node.js/TypeScript)

    • Express API server for swap management
    • Relayer service for cross-chain coordination
    • Event monitoring and automatic processing
    • In-memory swap storage
  3. Frontend Application (Next.js/React)

    • Farcaster Mini App interface
    • Wallet integration (Wagmi)
    • Real-time swap status tracking
    • Cross-chain transaction management

🔄 Technical Flow

  1. Create Swap – User A locks funds in escrow (Hashlock + Timelock)
  2. Fulfill Swap – User B locks funds on destination chain
  3. Set Fulfiller – Role is assigned
  4. Submit Secret – Secret revealed to unlock funds
  5. Completion – Both users receive tokens

Fail-safes:

  • 24h → Cancel option
  • 48h → Rescue possible
  • 72h → Only rescue available

🔄 Complete Swap Flow

graph TD
    A[User A Creates Swap] --> B[Secret Generated]
    B --> C[Source Escrow Deployed]
    C --> D[Tokens Locked with Hashlock]
    D --> E[User B Fulfills Swap]
    E --> F[Destination Escrow Deployed]
    F --> G[Relayer Sets Fulfiller]
    G --> H[User A Claims with Secret]
    H --> I[Secret Revealed]
    I --> J[Both Escrows Withdrawn]
    J --> K[Swap Completed]

🔐 Security Mechanisms

Hashlock System

  • Secret Generation: User generates a random secret
  • Hashlock Creation: Secret is hashed using keccak256
  • One-way Function: Prevents front-running and ensures atomic swaps
  • Secret Revelation: Only the original secret can unlock tokens

Timelock Stages

Source Chain

  • SrcWithdrawal: Only asker can withdraw with secret (0-24h)
  • SrcPublicWithdrawal: Anyone with access token can withdraw (24-48h)
  • SrcCancellation: Only asker can cancel (24-48h)
  • SrcPublicCancellation: Anyone with access token can cancel (48-72h)

Destination Chain

  • DstWithdrawal: Only asker can withdraw with secret (0-24h)
  • DstPublicWithdrawal: Anyone with access token can withdraw (24-48h)
  • DstCancellation: Only fullfiller can cancel (24-48h)

Cross-Chain Security

  • Atomic Operations: Both escrows must succeed or both fail
  • Execution Data Validation: All operations verify execution data integrity
  • Access Token Control: Public functions require access token ownership
  • Emergency Recovery: Rescue mechanism for stuck funds after 72h

💰 Fee Structure

  • Platform Fee: 1% of asker amount (configurable, max 10%)
  • Gas Fee: Native token fee paid by fullfiller, returned to withdrawal caller
  • Fee Collector: Configurable address to receive platform fees

🛠️ Technical Implementation

Smart Contract Features

  • Deterministic Addresses: Using CREATE2 for predictable escrow addresses
  • Clone Pattern: Gas-efficient deployment using OpenZeppelin Clones
  • SafeERC20: Secure token transfers with proper error handling
  • Timelock Library: Compact storage of time-based restrictions

Backend Services

  • Event Monitoring: Real-time blockchain event processing
  • Relayer Coordination: Automated cross-chain transaction execution
  • Swap Storage: In-memory database for swap state management
  • API Endpoints: RESTful interface for frontend integration

Frontend Features

  • Wallet Integration: Support for multiple wallet providers
  • Chain Switching: Automatic network switching for cross-chain swaps
  • Real-time Updates: Live swap status tracking
  • Transaction Management: Comprehensive transaction history

🎯 Use Cases

  • Secondary / pre-listing token markets
  • Low fees, simple UX
  • Swaps with friends/social circles
  • Large trades possible without slippage/liquidity issues

🚀 Demo

Available on:

  • Farcaster - Mini App integration
  • Worldcoin - Miniapp
  • Web App - Direct browser access

Live now: peerswap.vercel.app

🚀 Getting Started

Prerequisites

  • Node.js 18+
  • Foundry (latest version)
  • Solidity 0.8.20+

Installation

  1. Clone the repository
git clone <repository-url>
cd peerswap
  1. Install dependencies
# Backend
cd backend
npm install

# Frontend
cd ../miniapp/peerswap
npm install

# Smart contracts
cd ../../peerswap-contracts
forge install
  1. Environment Setup
# Backend
cp backend/.env.example backend/.env
# Configure your environment variables

# Frontend
cp miniapp/peerswap/.env.example miniapp/peerswap/.env.local
# Configure your environment variables

Development

  1. Start the backend
cd backend
npm run dev
  1. Start the frontend
cd miniapp/peerswap
npm run dev
  1. Deploy smart contracts
cd peerswap-contracts
forge script script/Deploy.s.sol --rpc-url <RPC_URL> --private-key <PRIVATE_KEY> --broadcast

Testing

# Smart contracts
cd peerswap-contracts
forge test

# Backend
cd backend
npm test

# Frontend
cd miniapp/peerswap
npm test

📊 API Endpoints

Swap Management

  • POST /swaps - Create a new swap
  • GET /swaps - List all swaps
  • GET /swap-status/:hashlock - Check swap status
  • POST /claim - Submit secret for claiming

System Management

  • GET /health - Health check
  • POST /check-deployments - Check all swap deployments
  • GET /check-relayer - Check relayer addresses

🔧 Configuration

Environment Variables

Backend

  • RELAYER_PRIVATE_KEY - Private key for relayer operations
  • PORT - Server port (default: 8787)
  • RPC_URL_SEPOLIA - Sepolia RPC endpoint
  • RPC_URL_BASE_SEPOLIA - Base Sepolia RPC endpoint

Frontend

  • NEXT_PUBLIC_BACKEND_URL - Backend API URL
  • NEXT_PUBLIC_FACTORY_ADDRESS_SEPOLIA - Sepolia factory address
  • NEXT_PUBLIC_FACTORY_ADDRESS_BASE_SEPOLIA - Base Sepolia factory address

🌐 Supported Networks

  • Ethereum Sepolia (Chain ID: 11155111)
  • Base Sepolia (Chain ID: 84532)

🔒 Security Considerations

  • Private Key Management: Never expose private keys in client-side code
  • Access Token Requirements: Public functions require access token ownership
  • Timelock Enforcement: Operations only available after specific time periods
  • Emergency Recovery: Rescue mechanism for stuck funds
  • Gas Fee Protection: Gas fees are returned to withdrawal callers

📈 Performance Optimizations

  • Clone Pattern: Gas-efficient contract deployment
  • Event-driven Architecture: Real-time processing without polling
  • In-memory Storage: Fast swap state management
  • Batch Operations: Efficient multi-swap processing

🔮 Future Additions

  • [ ] Private P2P swaps
  • [ ] Integrations with WhatsApp, Telegram, etc.
  • [ ] P2P Net Swaps (multi-party settlements)
  • [ ] Support for additional blockchain networks
  • [ ] Mobile application development
  • [ ] Enhanced security features
  • [ ] Governance token integration

Built with ❤️ for the decentralized future

How it's Made

How I Built PeerSwap - The Real Story

So I was thinking about this problem where people have tokens on different chains but can't easily trade them. Like, you have USDC on Base but want some random token that only exists on Tempo chain. There's no bridge, no DEX has the pair, and centralized exchanges are a pain.

The Core Idea

I wanted to build something where two people could trade directly - no middleman, no bridges, just pure P2P. The key insight was using hashlocked escrows with timelocks. It's like a cryptographic handshake where both parties have to commit before either can back out.

The Tech Stack I Chose

Smart Contracts (Solidity) I went with a factory pattern using OpenZeppelin's clone system. This was crucial because deploying new escrows for each swap would be expensive. The clone pattern lets me deploy cheaply while keeping each escrow as a separate contract. I used CREATE2 for deterministic addresses - this was important for the relayer to know where escrows would be deployed.

The contracts are pretty complex with multiple timelock stages. I spent a lot of time getting the security right - there are different permissions at different time periods, and I had to handle edge cases like stuck funds.

Backend (Node.js/TypeScript) I built an Express API that acts as a relayer. The key thing here is that the relayer coordinates but never holds funds - it's just facilitating the cross-chain communication. I used in-memory storage for speed, and built an event-driven system that listens to blockchain events in real-time.

Frontend (Next.js/React) I integrated with Farcaster as a mini app because I wanted social discovery. People can find trading partners through their social network, which builds trust. I used Wagmi for wallet integration and built a smooth UX for cross-chain transactions.

The Really Hacky Parts

Multi-Stage Timelock System This was probably the most complex part. I created different permission levels at different time periods:

  • First 24 hours: Only the original user can withdraw with the secret
  • 24-48 hours: Anyone with an access token can withdraw
  • 48-72 hours: Public cancellation becomes available
  • After 72 hours: Only rescue is possible

The access token system was my solution to the "what if someone disappears" problem. It lets the community help complete stuck swaps.

Cross-Chain Secret Revelation Getting the secret to work across chains while maintaining atomicity was tricky. I had to make sure that revealing the secret on one chain would unlock funds on both chains, but only if both escrows were properly set up.

Emergency Recovery I built a 72-hour rescue mechanism. If someone disappears or something goes wrong, the community can rescue funds after a long enough period. This was important for user confidence.

Partner Technology Benefits

Farcaster Integration This was huge for user experience. Instead of just posting "I want to trade X for Y" on random forums, people can do it through their social network. It builds trust because you're trading with people you know or have mutual connections with.

Worldcoin Integration I added Worldcoin for identity verification. This prevents spam and multiple accounts from the same person. It also helps with compliance - regulators like knowing who's doing what.

Self SDK Integration I integrated Self SDK for enhanced user experience and identity management. This provides additional layers of user verification and helps create a more trusted environment for P2P trading. The SDK's identity features complement the Worldcoin verification, creating a robust user authentication system.

Fluence Virtual Server I used Fluence's virtual server infrastructure for decentralized backend services. This was crucial for maintaining the decentralized nature of the platform - instead of relying on centralized servers, the relayer services run on Fluence's decentralized network. This ensures that even the coordination layer remains decentralized and resilient.

The Clever Bits

Gas Fee Protection I made sure that whoever calls the withdrawal function gets their gas fees back. This prevents users from being penalized for completing swaps.

Event-Driven Architecture Instead of polling the blockchain constantly, I built an event-driven system that responds immediately when things happen. This makes the UX much smoother.

Clone Pattern for Gas Efficiency Using OpenZeppelin's clone pattern was crucial for keeping costs down. Each swap needs its own escrow, but deploying full contracts would be expensive.

Decentralized Infrastructure The combination of Fluence's virtual servers and Self SDK creates a truly decentralized experience. Users don't have to trust any centralized entity - not even for the coordination services.

What Made It Work

The combination of social integration (Farcaster), identity verification (Worldcoin + Self SDK), decentralized infrastructure (Fluence), and trustless P2P mechanics creates something that's both secure and user-friendly. The timelock system handles edge cases while maintaining the trustless nature.

The relayer coordination without custody was key - it enables cross-chain functionality while keeping the system decentralized. The relayer just facilitates communication, it never touches the funds.

The Result

I ended up with a system where two people can trade tokens across chains without trusting each other or any centralized entity. The social integration makes it easy to find trading partners, and the security mechanisms handle all the edge cases.

It's live at peerswap.vercel.app and works on Ethereum Sepolia and Base Sepolia. The whole thing took about 48 hours of intense coding, but the result is something that actually solves a real problem in a trustless way.

Technical Deep Dive

Security Mechanisms - The "Hacky" Parts

Hashlock System

  • Secret Generation: Users generate random secrets
  • One-way Hashing: keccak256 prevents front-running
  • Atomic Swaps: Both escrows succeed or both fail

Multi-Stage Timelock System

Source Chain Stages:

  • SrcWithdrawal (0-24h): Only asker with secret
  • SrcPublicWithdrawal (24-48h): Anyone with access token
  • SrcCancellation (24-48h): Only asker can cancel
  • SrcPublicCancellation (48-72h): Public cancellation

Destination Chain Stages:

  • DstWithdrawal (0-24h): Only asker with secret
  • DstPublicWithdrawal (24-48h): Public withdrawal
  • DstCancellation (24-48h): Only fulfiller can cancel

Cross-Chain Security

  • Execution Data Validation: All operations verify data integrity
  • Access Token Control: Public functions require token ownership
  • Emergency Recovery: Rescue mechanism after 72h

Notable Technical Innovations

1. Relayer Coordination Without Custody

The relayer coordinates cross-chain operations but never controls funds - this is particularly clever because it maintains decentralization while enabling cross-chain functionality.

2. Multi-Stage Timelock System

The complex timelock system with different permissions at different stages is quite sophisticated - it handles edge cases like stuck funds while maintaining security.

3. Clone Pattern for Gas Efficiency

Using OpenZeppelin's clone pattern for escrow deployment is gas-efficient and allows for predictable addresses.

4. Event-Driven Architecture

Real-time blockchain event processing without polling - this is efficient and responsive.

Performance Optimizations

  • In-memory Storage: Fast swap state management
  • Batch Operations: Efficient multi-swap processing
  • Event-driven Architecture: No polling required
  • Clone Pattern: Gas-efficient deployments

Supported Networks

  • Ethereum Sepolia (Chain ID: 11155111)
  • Base Sepolia (Chain ID: 84532)
background image mobile

Join the mailing list

Get the latest news and updates