ProBridgeDocumentation

Deployment Guide

Everything you need to deploy ProBridge on your own chains — contracts, frontend config, and production checklist.

Overview

How ProBridge works

ProBridge is a full-stack cross-chain bridge built on Hyperlane — a permissionless interoperability protocol. It includes Solidity contracts, a Next.js frontend, and a config system that lets you add any EVM chain without touching component code.

Smart Contracts

Solidity warp routes on both chains

Frontend

Next.js + wagmi + RainbowKit

Protocol

Hyperlane messaging + relayer

Bridge flow:

User calls transferRemote()Tokens locked/burned on sourceHyperlane Mailbox dispatches messageValidators sign checkpointRelayer delivers to destinationTokens minted/released

Requirements

What you need before deploying

Node.js 18+For running the frontend
node --version
FoundryFor compiling & deploying contracts
forge --version
GitFor cloning the repository
git --version

Install Foundry

bash
curl -L https://foundry.paradigm.xyz | bash
foundryup

Install frontend dependencies

bash
cd probridge-ui
npm install

You also need a WalletConnect Project ID (free at cloud.walletconnect.com) and a deployer wallet with gas on both chains.

Deploy Contracts

Using Remix IDE (recommended) or Foundry

Remix IDE is the easiest approach — no local setup needed. Open remix.ethereum.org, paste each contract file, set compiler to 0.8.24 + EVM Cancun, and deploy.

1

Deploy BlockBridgeIGP on the source chain

No constructor arguments needed. Copy the deployed address.

solidity
// Constructor: none
// After deployment, save:
// IGP_ADDRESS = "0x..."
2

Deploy BlockBridgeMultisigISM on the source chain

No constructor arguments needed.

solidity
// Constructor: none
// After deployment, save:
// ISM_ADDRESS = "0x..."
3

Deploy HypERC20Collateral on the source chain

This locks existing ERC20 tokens (e.g. USDC) on the source chain.

solidity
// Constructor args:
// _mailbox: Hyperlane Mailbox address on source chain
// _token:   Address of the ERC20 you want to bridge
//
// Example (Base Sepolia USDC):
// mailbox: 0x6966b0E55883d49BFB0b8E4AcEA2855b4C9Bf4e9
// token:   0x036CbD53842c5426634e7929541eC2318f3dCF7e
4

Deploy HypERC20 (synthetic) on the destination chain

This mints synthetic tokens on the destination chain when a bridge message arrives.

solidity
// Constructor args:
// _mailbox:  Hyperlane Mailbox on destination chain
// _name:     Token name  (e.g. "ProBridge USDC")
// _symbol:   Token symbol (e.g. "pbUSDC")
// _decimals: 6 for USDC
//
// Example (BNB Testnet):
// mailbox: 0xF9F6F5646F478d5ab4e20B0F910C92F1CCC9Cc6D
5

Enroll remote routers (link the two contracts)

Call enrollRemoteRouter() on each contract so they trust messages from each other.

solidity
// On HypERC20Collateral (source chain):
// domain:  destination chain ID (e.g. 97 for BNB Testnet)
// router:  pad destination contract address to bytes32
//          e.g. 0x000000000000000000000000{HypERC20_ADDRESS}

// On HypERC20 (destination chain):
// domain:  source chain ID (e.g. 84532 for Base Sepolia)
// router:  pad source contract address to bytes32
//          e.g. 0x000000000000000000000000{HypERC20Collateral_ADDRESS}

Both enrollments must be done or messages will be rejected. Pad the address with 24 leading zeros to convert from 20-byte address to 32-byte bytes32.

Configure Frontend

Update 3 config files with your deployed addresses

1

Add your contract addresses to contracts.config.ts

typescript
// config/contracts.config.ts
export const CONTRACTS_CONFIG: Record<number, ContractAddresses> = {
  84532: {                                           // Source chain ID
    warpRoute: '0xYOUR_HYP_ERC20_COLLATERAL',
    igp:       '0xYOUR_IGP',
    ism:       '0xYOUR_ISM',
    mailbox:   '0xHYPERLANE_MAILBOX_SOURCE',
  },
  97: {                                              // Destination chain ID
    warpRoute: '0xYOUR_HYP_ERC20',
    mailbox:   '0xHYPERLANE_MAILBOX_DEST',
  },
};
2

Add your token to tokens.config.ts

typescript
// config/tokens.config.ts
export const TOKENS_CONFIG: TokenConfig[] = [
  {
    symbol:   'USDC',
    name:     'USD Coin',
    decimals: 6,
    addresses: {
      84532: '0xYOUR_TOKEN_ON_SOURCE',       // original ERC20
      97:    '0xYOUR_SYNTHETIC_ON_DEST',     // HypERC20 address
    },
    type: {
      84532: 'collateral',
      97:    'synthetic',
    },
    coingeckoId: 'usd-coin',
  },
];
3

Set your WalletConnect Project ID

bash
# Create .env.local in the project root
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_id_here
4

Run the frontend

bash
npm run dev
# Open http://localhost:3000

Add a New Chain

No component code needed — config only

ProBridge is designed so adding a chain requires editing config files only. No changes to UI components.

1

Deploy contracts on the new chain (same steps as above)

Make sure the new chain has a Hyperlane Mailbox. Check the Hyperlane registry for supported chains. For custom chains you'll need to deploy a Mailbox using the Hyperlane CLI.

2

Add chain to chains.config.ts

typescript
// config/chains.config.ts — add inside CHAINS_CONFIG array:
{
  id:   42161,                          // Arbitrum One
  name: 'Arbitrum One',
  shortName: 'ARB',
  label: 'Arbitrum Mainnet',
  nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
  rpcUrls: [
    'https://arb1.arbitrum.io/rpc',
    'https://arbitrum-one-rpc.publicnode.com',
  ],
  explorerUrl:    'https://arbiscan.io',
  explorerTxPath: '/tx/',
  color:    '#28A0F0',
  iconSvg:  `<svg viewBox="0 0 32 32">...</svg>`,
},
3

Add contract addresses to contracts.config.ts

typescript
42161: {
  warpRoute: '0xYOUR_WARP_ROUTE_ON_ARBITRUM',
  mailbox:   '0xHYPERLANE_MAILBOX_ARBITRUM',
},
4

Add token address on the new chain to tokens.config.ts

typescript
// Inside the USDC token entry:
addresses: {
  84532: '0x036CbD...',   // Base Sepolia
  97:    '0x779508...',   // BNB Testnet
  42161: '0xYOUR_USDC_OR_SYNTHETIC_ON_ARBITRUM',  // ← add this
},
type: {
  84532: 'collateral',
  97:    'synthetic',
  42161: 'collateral',   // ← add this
},

That's it — the chain selector, balance reader, progress tracker and history all pick up the new chain automatically.

Add a New Token

Bridge any ERC20 with a new warp route

1

Deploy warp route contracts for the new token

Deploy HypERC20Collateral on the source chain (pointing to your token), and HypERC20 on the destination chain. Enroll remote routers on both.

2

Add token entry to tokens.config.ts

typescript
{
  symbol:   'WBTC',
  name:     'Wrapped Bitcoin',
  decimals: 8,
  addresses: {
    84532: '0xYOUR_WBTC_ON_SOURCE',
    97:    '0xYOUR_SYNTHETIC_WBTC_ON_DEST',
  },
  type: {
    84532: 'collateral',
    97:    'synthetic',
  },
  coingeckoId: 'wrapped-bitcoin',
  iconId: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', // mainnet WBTC for icon
},

The iconId field is used to load the token logo from the Trust Wallet CDN. Use the Ethereum mainnet address of the token for the best icon coverage.

Go to Production

Checklist before handling real value

Replace testnet chains with mainnet chains in chains.config.ts
Update all contract addresses to mainnet deployments
Set NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID in production environment
Verify contracts on block explorers (builds user trust)
Transfer contract ownership to a multisig (Gnosis Safe)
Test bridge with small amounts before announcing
Run Hyperlane validator + relayer for custom chains (see below)
Get a security audit before handling significant TVL
Deploy frontend to Vercel or your own hosting

Deploy to Vercel

bash
npm install -g vercel
vercel --prod

Hyperlane Mailbox addresses (mainnet)

ChainChain IDMailbox Address
Ethereum10xc005dc82818d67AF737725bD4bf75435d065D239
BNB Chain560x2971b9Aec44bE4eb673DF1B88cDB57b96eefe8a4
Arbitrum421610x979Ca5202784112f4738403dBec5D0F3B9daabB9
Optimism100xd4C1905BB1D26BC93DAC913e13CaCC278CdCC892
Base84530xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D
Polygon1370x5d934f4e2f797775e53561bB72aca21ba36B96BB

Full list of supported chains and Mailbox addresses: hyperlane-xyz/hyperlane-registry

Contract Reference

Key functions and security features

HypERC20Collateral

Deployed on the source chain. Locks existing ERC20 tokens and dispatches a Hyperlane message.

transferRemote(uint32 dest, bytes32 recipient, uint256 amount)

Initiates a bridge transfer. Must send ETH for Hyperlane gas fee.

quoteFee(uint32 dest, bytes32 recipient, uint256 amount)

Returns the required ETH fee to pay for gas on the destination chain.

enrollRemoteRouter(uint32 domain, bytes32 router)

Owner only. Registers the destination contract as a trusted router.

pause() / unpause()

Owner only. Emergency stop for all transfers.

HypERC20 (Synthetic)

Deployed on the destination chain. Mints tokens when a verified message arrives, burns them when bridging back.

handle(uint32 origin, bytes32 sender, bytes message)

Called by Hyperlane Mailbox on message delivery. Mints tokens to recipient.

transferRemote(uint32 dest, bytes32 recipient, uint256 amount)

Burns tokens and dispatches return message to source chain.

BlockBridgeIGP

Interchain Gas Paymaster. Collects ETH from users to pay for gas on the destination chain.

payForGas(bytes32 messageId, uint32 dest, uint256 gasAmount, address refund)

Called internally during transferRemote() to pay for destination gas.

quoteGasPayment(uint32 dest, uint256 gasAmount)

Returns ETH cost for a given gas amount on the destination chain.