Skip to content

genlayer-foundation/genlayer-studio-bridge-boilerplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GenLayer Bridge Boilerplate

Connect your blockchain to the Resolution Layer.

License Status

This boilerplate provides the complete infrastructure to connect GenLayer Intelligent Contracts with EVM chains (Base, Ethereum, etc.) via LayerZero V2. It enables any blockchain to offload complex, non-deterministic workβ€”AI reasoning, web access, data verificationβ€”to GenLayer and receive verified results.

πŸ“š Table of Contents


🌐 The Resolution Layer

Blockchains are powerful but blind. They cannot read news, verify events, or access the web. GenLayer solves this by acting as the Resolution Layer for the ecosystem.

  • Your Chain (Backbone): Holds liquidity, users, and core logic.
  • GenLayer (Brain): Handles intelligence, web data, and AI processing.

This bridge connects the two, allowing you to build "Intelligent dApps" without migrating your users or liquidity.

πŸ— Architecture

The bridge implements a Hub-and-Spoke model with ZKsync Era serving as the central hub for GenLayer's interactions with the wider EVM ecosystem via LayerZero.

graph TD
    subgraph "The World"
        Web["Web Data / APIs"]
        AI["LLM Reasoning"]
    end

    subgraph "GenLayer (The Brain)"
        IC["Intelligent Contract<br/>(Your Logic)"]
        BR_GL["BridgeReceiver.py<br/>(Receiver)"]
        BS_GL["BridgeSender.py<br/>(Outbox)"]
    end

    subgraph "Transport"
        Service["Relay Service<br/>(Node.js)"]
        BF["BridgeForwarder.sol<br/>(Hub - ZKsync Era)"]
        BR_HUB["BridgeReceiver.sol<br/>(Hub - ZKsync Era)"]
        LZ["LayerZero V2"]
    end

    subgraph "EVM Chain (The Backbone)"
        dApp["Your dApp"]
        BS_EVM["BridgeSender.sol"]
        BR_EVM["BridgeReceiver.sol"]
    end

    dApp -.->|"0. Quote Fee"| BS_EVM
    dApp -->|"1. Request Resolution (+Fees)"| BS_EVM
    BS_EVM --> LZ
    LZ -->|"2. Relay Message"| BR_HUB
    BR_HUB -.->|"2a. Poll Hub"| Service
    Service -->|"3. Deliver to Receiver"| BR_GL
    BR_GL -->|"4. Dispatch via emit()"| IC
    Web -->|"5. Web Data"| IC
    AI -->|"6. AI Consensus"| IC
    IC -->|"7. Send Result"| BS_GL
    BS_GL -.->|"8. Poll Event"| Service
    Service -.->|"8a. Quote Fee"| BF
    Service -->|"9. Relay Result (+Fees)"| BF
    BF --> LZ
    LZ --> BR_EVM
    BR_EVM -->|"10. Callback"| dApp
Loading

Message Flow

GenLayer β†’ EVM

  1. Source IC calls BridgeSender.send_message(target_chain_eid, target_contract, data).
  2. Service polls get_message_hashes() and get_message() on GenLayer.
  3. Service calls BridgeForwarder.quoteCallRemoteArbitrary() to determine the fee.
  4. Service calls BridgeForwarder.callRemoteArbitrary() on ZKsync Era (Hub) with the required native fee.
  5. LayerZero delivers to BridgeReceiver on destination chain (Target).
  6. BridgeReceiver dispatches to target contract via processBridgeMessage().

EVM β†’ GenLayer

  1. dApp calls BridgeSender.quoteSendToGenLayer() to get the fee.
  2. dApp calls BridgeSender.sendToGenLayer(targetContract, data, options) with msg.value >= fee.
  3. LayerZero delivers to BridgeReceiver.sol on ZKsync Era (Hub).
  4. BridgeReceiver (Hub) stores message (not just event) for polling.
  5. Service polls getPendingGenLayerMessages() on ZKsync Era (Hub).
  6. Service calls BridgeReceiver.receive_message() on GenLayer.
  7. BridgeReceiver dispatches to target IC via emit().process_bridge_message().
  8. Service calls markMessageRelayed() on ZKsync Era (Hub).

πŸ“‚ Repository Structure

This is a monorepo containing all components of the bridge:

  • /smart-contracts: Solidity contracts for EVM chains (Hardhat).
  • /intelligent-contracts: Python contracts for GenLayer.
  • /service: Node.js relay service that polls and relays messages.
  • /example: Complete bidirectional example with StringSender/StringReceiver.

πŸ”‘ Key Contracts

Contract Chain Purpose
BridgeSender.py GenLayer Stores outbound GL→EVM messages
BridgeReceiver.py GenLayer Receives EVM→GL messages, dispatches to target
BridgeForwarder.sol ZKsync Era Relays GL→EVM via LayerZero
BridgeReceiver.sol ZKsync Era Stores EVM→GL messages for polling
BridgeSender.sol Base/EVM Entry point for EVM→GL messages

πŸ“‹ Prerequisites

To bridge intelligence to your dApp, you need:

  • Node.js: v18+ & npm: v9+
  • GenLayer Studio: GenLayer Studio
  • Wallet: A private key with testnet funds on:
    • Base Sepolia (Example Target Chain)
    • ZKsync Era Sepolia (Hub Chain)

πŸš€ Deployment Guide

Follow these steps to deploy your own instance of the bridge infrastructure.

1. Installation

# 1. Install Smart Contracts dependencies (EVM)
cd smart-contracts && npm install && cd ..

# 2. Install Bridge Service dependencies (Relayer)
cd service && npm install && cd ..

2. Configuration

Create your environment files.

Smart Contracts (.env)

cp smart-contracts/.env.example smart-contracts/.env
# EDIT: Add your PRIVATE_KEY and RPC URLs

Service (.env)

cp service/.env.example service/.env
# EDIT: Add your PRIVATE_KEY and GENLAYER_RPC_URL (e.g. https://studio.genlayer.com/api/rpc)

3. Deploy EVM Infrastructure

Deploy the "mailbox" contracts to the EVM chains.

cd smart-contracts

# 1. Deploy Receiver (Target & Hub)
CONTRACT=receiver npx hardhat run scripts/deploy.ts --network baseSepoliaTestnet
CONTRACT=receiver npx hardhat run scripts/deploy.ts --network zkSyncSepoliaTestnet

# 2. Deploy Forwarder (Hub - ZKsync Era)
CONTRACT=forwarder npx hardhat run scripts/deploy.ts --network zkSyncSepoliaTestnet

# 3. Deploy Sender (Target - Base)
CONTRACT=sender npx hardhat run scripts/deploy.ts --network baseSepoliaTestnet

4. Link EVM Contracts

Configure the trust relationships so messages can flow securely.

# Configure Hub (ZKsync Era)
ACTION=set-trusted-forwarder npx hardhat run scripts/configure.ts --network zkSyncSepoliaTestnet
ACTION=set-authorized-relayer npx hardhat run scripts/configure.ts --network zkSyncSepoliaTestnet
ACTION=set-bridge-address npx hardhat run scripts/configure.ts --network zkSyncSepoliaTestnet

# Configure Target (Base)
ACTION=set-sender-receiver npx hardhat run scripts/configure.ts --network baseSepoliaTestnet
ACTION=set-trusted-forwarder npx hardhat run scripts/configure.ts --network baseSepoliaTestnet

5. Deploy GenLayer "Brain"

Deploy the Intelligent Contracts via GenLayer Studio:

  1. Deploy BridgeSender.py: The exit point for results returning to EVM.
    • No constructor args.
  2. Deploy BridgeReceiver.py: Receives and dispatches incoming requests to target ICs.
    • No constructor args. After deployment, call set_authorized_relayer(wallet_address, true).

6. Activate the Resolution Layer

Update service/.env with your new contract addresses:

BRIDGE_SENDER_ADDRESS=<GenLayer BridgeSender Address>
BRIDGE_RECEIVER_IC_ADDRESS=<GenLayer BridgeReceiver Address>
ZKSYNC_BRIDGE_FORWARDER_ADDRESS=<ZKsync Era BridgeForwarder Address>
ZKSYNC_BRIDGE_RECEIVER_ADDRESS=<ZKsync Era BridgeReceiver Address>

Start the relay:

cd service
npm run build
npm start

The service is now polling. Your bridge is live.

πŸ›  Development & Debugging

The service directory includes a CLI for debugging the bridge state.

cd service

# Check ZKsync Era BridgeReceiver state
npx ts-node cli.ts check-receiver

# Check Base BridgeSender state
npx ts-node cli.ts check-sender

# Check ZKsync Era BridgeForwarder state
npx ts-node cli.ts check-forwarder

# Verify all configurations
npx ts-node cli.ts check-config

# List pending messages on ZKsync Era
npx ts-node cli.ts pending-messages

# Debug a specific transaction
npx ts-node cli.ts debug-tx <hash>

πŸ§ͺ Example: "Hello World"

To demonstrate the capability, we provide a bidirectional messaging example.

πŸ‘‰ Run the Example

  • EVM β†’ GenLayer: Send a string from Base. The BridgeReceiver dispatches it to your Intelligent Contract.
  • GenLayer β†’ EVM: The Intelligent Contract sends a response back to the EVM chain.

πŸ›  Troubleshooting

  • Service Logs: The service console is your best debugging tool. It tracks every step of the relay.
  • Gas: Ensure your relayer wallet has ETH on both Base Sepolia and ZKsync Era Sepolia.
  • Trust: If messages fail to deliver, check that set-trusted-forwarder was run on the target chain.
  • LayerZero Endpoints: Ensure you are using the correct Endpoint IDs for your networks.
    • ZKsync Era Sepolia: 40305
    • Base Sepolia: 40245

πŸ“„ License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors