Documentation
Everything you need to deploy BlockBridge on your own chain
Product Overview
Deploy a production-ready cross-chain bridge to any EVM chain.
BlockBridge is a complete, white-label token bridge powered by Hyperlane, the permissionless interoperability framework. It ships with auditable smart contracts, a polished Next.js frontend, deployment scripts, and agent configuration — everything needed to connect your L1, L2, or L3 to any other EVM chain.
What's Included
- • Solidity contracts with 80+ Foundry tests (unit, integration, security, fork)
- • Next.js 14 frontend with AppKit wallet connection and real-time fee quoting
- • Shell deployment scripts for any EVM chain
- • Docker-ready agent configurations for validators and relayers
- • Comprehensive documentation (this page)
Quick Start
Prerequisites
Get Running
# Download and unzip BlockBridge from web3.market, then: cd blockbridge pnpm install
cd contracts forge test
cd bridge-ui cp .env.example .env.local # add your WalletConnect ID pnpm dev
Deploy to Your Chain
3a. Prerequisites
- • Foundry installed (
curl -L https://foundry.paradigm.xyz | bash) - • RPC URLs for both your origin and destination chains
- • Deployer wallet with native gas tokens on both chains
- • Hyperlane Mailbox address on each chain — check the Hyperlane Registry
3b. Deploy Contracts
Deploy the warp route contracts using forge create. Replace placeholders with your values.
forge create --json --broadcast \ --rpc-url $ORIGIN_RPC \ --private-key $DEPLOYER_PK \ src/warp/BlockBridgeHypNative.sol:BlockBridgeHypNative \ --constructor-args $MAILBOX_ORIGIN
forge create --json --broadcast \ --rpc-url $DEST_RPC \ --private-key $DEPLOYER_PK \ src/warp/BlockBridgeHypERC20.sol:BlockBridgeHypERC20 \ --constructor-args 18 $MAILBOX_DEST "Token Name" "TKN"
forge create --json --broadcast \ --rpc-url $ORIGIN_RPC \ --private-key $DEPLOYER_PK \ src/warp/BlockBridgeHypERC20Collateral.sol:BlockBridgeHypERC20Collateral \ --constructor-args $ERC20_TOKEN_ADDRESS $MAILBOX_ORIGIN
3c. Enroll Remote Routers
Each warp contract must know about its counterpart on the remote chain. Call enrollRemoteRouter on both sides.
cast send $ORIGIN_CONTRACT \ "enrollRemoteRouter(uint32,bytes32)" \ $DEST_DOMAIN_ID \ $(cast --to-bytes32 $DEST_CONTRACT) \ --rpc-url $ORIGIN_RPC \ --private-key $DEPLOYER_PK
cast send $DEST_CONTRACT \ "enrollRemoteRouter(uint32,bytes32)" \ $ORIGIN_DOMAIN_ID \ $(cast --to-bytes32 $ORIGIN_CONTRACT) \ --rpc-url $DEST_RPC \ --private-key $DEPLOYER_PK
3d. Configure Security
cast send $CONTRACT \ "setInterchainSecurityModule(address)" \ $ISM_ADDRESS \ --rpc-url $RPC_URL \ --private-key $DEPLOYER_PK
cast send $HYP_NATIVE \ "setMaxTransferAmount(uint256)" \ $(cast --to-wei 100) \ --rpc-url $RPC_URL \ --private-key $DEPLOYER_PK
# Pause cast send $CONTRACT "pause()" --rpc-url $RPC_URL --private-key $DEPLOYER_PK # Unpause cast send $CONTRACT "unpause()" --rpc-url $RPC_URL --private-key $DEPLOYER_PK
3e. Transfer Ownership
Once everything is configured, transfer ownership to a multisig (e.g., Gnosis Safe).
cast send $CONTRACT \ "transferOwnership(address)" \ $MULTISIG_ADDRESS \ --rpc-url $RPC_URL \ --private-key $DEPLOYER_PK
3f. Verify on Block Explorer
forge verify-contract \ $CONTRACT_ADDRESS \ src/warp/BlockBridgeHypNative.sol:BlockBridgeHypNative \ --chain-id $CHAIN_ID \ --etherscan-api-key $ETHERSCAN_API_KEY \ --constructor-args $(cast abi-encode "constructor(address)" $MAILBOX)
Configure the Frontend
After deploying contracts, update the frontend configuration to match your chains and tokens.
config/chains.ts
Add your chain configuration.
export const MY_CHAIN: ChainConfig = {
id: 42161, // Chain ID
name: 'arbitrum', // Internal name
displayName: 'Arbitrum', // Display name
domainId: 42161, // Hyperlane domain ID
rpcUrl: process.env.NEXT_PUBLIC_RPC_ARBITRUM || 'https://arb1.arbitrum.io/rpc',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
blockExplorer: 'https://arbiscan.io',
logoUrl: '/chains/arbitrum.svg',
isTestnet: false,
};config/tokens.ts
Add your token with contract addresses per chain.
export const MY_TOKEN: Token = {
symbol: 'USDC',
name: 'USD Coin',
decimals: 6,
addresses: {
1: '0xA0b8...eB48', // Ethereum
42161: '0xaf88...3f2c', // Arbitrum (synthetic)
},
isNative: false,
};config/warpRoutes.ts
Add route entries for each direction.
{
originChainId: 1,
destinationChainId: 42161,
originContract: '0x...', // HypERC20Collateral on Ethereum
destinationContract: '0x...', // HypERC20 on Arbitrum
tokenSymbol: 'USDC',
type: 'collateral',
},
{
originChainId: 42161,
destinationChainId: 1,
originContract: '0x...', // HypERC20 on Arbitrum
destinationContract: '0x...', // HypERC20Collateral on Ethereum
tokenSymbol: 'USDC',
type: 'synthetic',
},lib/wagmi/chains.ts
Define the chain for viem/wagmi.
import { defineChain } from 'viem';
export const myChain = defineChain({
id: 42161,
name: 'Arbitrum One',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrls: { default: { http: ['https://arb1.arbitrum.io/rpc'] } },
blockExplorers: { default: { name: 'Arbiscan', url: 'https://arbiscan.io' } },
});lib/wagmi/config.ts & app/appkit-init.tsx
Add your chain to the WagmiAdapter networks array and AppKit networks.
Environment Variables
NEXT_PUBLIC_WALLETCONNECT_ID=your_project_id NEXT_PUBLIC_RPC_ARBITRUM=https://arb1.arbitrum.io/rpc
Validators & Relayers
Hyperlane uses a validator + relayer model for cross-chain messaging.
Watch the origin chain Mailbox for dispatched messages and sign merkle root checkpoints. Multiple validators form a multisig for security.
Pick up signed messages and submit them to the destination chain Mailbox, which verifies them against the ISM before delivering to the warp route contract.
Running Agents
Refer to the Hyperlane Agent documentation for full setup instructions. Key environment variables:
HYP_VALIDATOR_KEY=<private-key-or-aws-kms-id> HYP_CHAINS_<CHAIN>_CONNECTION_URL=<rpc-url> HYP_CHECKPOINTSYNCER_TYPE=localStorage HYP_CHECKPOINTSYNCER_PATH=/tmp/checkpoints
HYP_RELAYER_KEY=<private-key> HYP_CHAINS_<ORIGIN>_CONNECTION_URL=<rpc-url> HYP_CHAINS_<DEST>_CONNECTION_URL=<rpc-url>
Security Best Practices
Security Feature Matrix
| Feature | HypNative | HypERC20 | HypERC20Collateral |
|---|---|---|---|
| Pausable | ✓ | ✓ | ✓ |
| ReentrancyGuard | ✓ | — | — |
| Transfer Caps | ✓ | — | — |
| Zero-Address Check | ✓ | ✓ | ✓ |
| Configurable ISM | ✓ | ✓ | ✓ |
Multisig ISM
Configure a Multisig ISM for production. Testnet: 2-of-3 validators. Mainnet: 3-of-5 or higher threshold for economic security.
Key Management
- • Use hardware wallets (Ledger/Trezor) for deployer keys
- • Use AWS KMS or GCP Cloud HSM for validator signing keys
- • Transfer contract ownership to a Gnosis Safe multisig
- • Never store private keys in environment variables in production
Audit Recommendations
- • Engage a professional security auditor before mainnet launch
- • Run the full Foundry test suite:
forge test -vvv - • Consider a bug bounty program for ongoing security
Mainnet Checklist
Customize the UI
globals.css — CSS Custom Properties
Colors are defined as HSL values. Edit these to change the entire color scheme.
:root {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--primary: 217 91% 60%;
--accent: 240 3.7% 15.9%;
/* ... */
}config/theme.ts — Hex Colors
Used for non-Tailwind contexts (e.g., charts, dynamic styles).
tailwind.config.ts
Maps CSS variables to Tailwind utility classes. Extend here for custom colors.
Branding
- • Logo & name: Edit
components/layout/Header.tsx - • Page title & meta: Edit
app/layout.tsxmetadata - • AppKit theme: Edit
app/appkit-init.tsxthemeVariables - • Chain logos: Add SVGs to
public/chains/
Architecture Reference
Hyperlane Message Lifecycle
User calls transferRemote() on the origin warp route. Tokens are locked (native/collateral) or burned (synthetic). A message is dispatched to the Hyperlane Mailbox.
Validators observe the dispatched message on the origin chain and sign a merkle root checkpoint attesting to the message.
The relayer picks up the validated message and submits it (with validator signatures) to the destination Mailbox.
The destination Mailbox verifies the message against the ISM, then calls handle() on the destination warp route, which mints or unlocks tokens to the recipient.
Warp Route Types
| Type | Origin Action | Destination Action | Use Case |
|---|---|---|---|
| Native | Lock ETH/native | Mint synthetic | Bridge native gas token |
| Collateral | Lock ERC20 | Mint synthetic | Bridge existing ERC20 |
| Synthetic | Burn synthetic | Unlock original | Return to origin chain |
Contract Security Model
All BlockBridge contracts inherit from Ownable (access control) + Pausable (emergency stop). HypNative adds ReentrancyGuard for safe ETH handling and configurable transfer caps.
Troubleshooting & FAQ
Common Errors
"No router enrolled for destination"You forgot to call enrollRemoteRouter() on the origin contract. Run the enrollment command from section 3c for both directions.
"Contract is paused"The contract owner has paused the bridge. The owner must call unpause() to re-enable transfers.
"Exceeds maximum transfer amount"The transfer amount exceeds the configured cap on HypNative. The owner can increase it via setMaxTransferAmount() or set to 0 to disable the cap.
Message dispatched but not deliveredCheck that: (1) the relayer is running and funded, (2) the ISM on the destination matches the validators signing checkpoints, (3) call delivered(messageId) on the destination Mailbox to verify status.
FAQ
How long does a bridge transfer take?
Typically 2-5 minutes. This depends on origin chain finality and relayer speed. The Hyperlane relayer automatically picks up and delivers messages.
What fees are involved?
You pay the Hyperlane protocol fee (quoted by quoteTransferRemote on the warp contract) plus the origin chain gas fee. The protocol fee covers validator signing and relayer delivery on the destination chain.
Where can I get testnet tokens?
Sepolia ETH from Google Cloud Web3 Faucet or Alchemy Faucet. BSC testnet BNB from the BNB Chain Faucet. HYPL tokens are minted during deployment.
Can I bridge in both directions?
Yes. Each warp route supports bidirectional transfers when both sides have enrolled remote routers.
Can I add more tokens later?
Yes. Deploy new warp route contract pairs, enroll routers, and add the token/route to the frontend config. No existing contracts need to change.
What happens if my transfer fails?
If the origin transaction reverts, your tokens are never locked/burned. If destination delivery fails (e.g., contract paused), the relayer will retry once the issue is resolved. Your tokens are safe.