Running a Hyperbridge Relayer : A Complete Guide
As blockchain ecosystems become increasingly fragmented across different chains, the ability to move assets and messages between them…
Running Hyperbridge Relayers: A Complete Guide

As blockchain ecosystems become increasingly fragmented across different chains, the ability to move assets and messages between them becomes critical. Traditional bridges have lost over $2.8 billion to hacks because they rely on small groups of validators who can be compromised or collude.
This is where Hyperbridge changes the game. Instead of trusting a committee, Hyperbridge uses cryptographic proofs that can be verified by anyone. But these proofs don’t move themselves — they need relayers to transmit them across chains.

Think of relayers as the postal service of the blockchain world. They pick up messages from one chain and deliver them to another, getting paid for successful deliveries. What makes Hyperbridge special is that anyone can become a relayer — no permission needed, no stake required.
What Makes Hyperbridge Relayers Different?
Traditional cross-chain protocols require relayers to:
- Lock up significant capital as stake (often $100K+)
- Get whitelisted by the protocol team
- Trust other validators in the network
Hyperbridge removes all these barriers:
- Zero stake required — Start relaying immediately
- Fully permissionless — No approval process needed
- Trust-free — Cryptographic proofs ensure security
- Competitive marketplace — Multiple relayers race to deliver messages
This means you can start earning rewards today with just a server and some gas funds.
Understanding the Two Types of Relayers
Before diving into setup, it’s important to understand that Hyperbridge has two distinct relayer types, each serving a different purpose:
Consensus Relayers
A Consensus Relayer in Hyperbridge is a permissionless node that monitors a source blockchain, generates verifiable proofs of its finalized state, and submits them to Hyperbridge so the network can stay in sync. The first relayer to submit a valid proof is rewarded in $BRIDGE tokens, making it a competitive process where rewards directly depend on how quickly and reliably the relayer updates the system’s consensus state.
What they do: Monitor blockchains and submit consensus proofs to Hyperbridge Compensation: BRIDGE tokens from the protocol Requirements: No upfront funding needed Best for: Consistent, predictable rewards
Messaging Relayers
A Messaging Relayer in Hyperbridge is a permissionless operator that delivers user-initiated messages across chains. Users pay fees upfront (in stablecoins like DAI) to cover delivery and execution, and relayers compete to process these requests profitably. Their earnings depend on how efficiently they can detect, relay, and execute messages, making performance and infrastructure speed critical to success.
What they do: Deliver cross-chain messages between chains Compensation: DAI stablecoins from users & daily incentives capped at 6kb of messages per day Requirements: Gas funds on each supported chain
You can run either type or both, you can use separate docker configuration files or bundle them together in a docker-compose file
Prerequisites and System Requirements
To maximize the performance of your relayers and ensure they relay proofs and messages effectively, it’s critical to optimize your host machine setup. Relaying is highly competitive, and your rewards are directly tied to the volume and efficiency of the activity your node can successfully process.
Before starting, ensure you have:
Hardware Requirements (Minimum)
- CPU: 4 cores
- RAM: 4GB
- Storage: 100GB SSD
- Network: 100Mb/s connection
Software Requirements
Before proceeding, make sure your server has the required tools installed, run the following commands on your server to setup docker and docker-compose at the minimum:
# install_dependencies.sh
## Install Docker - the container runtime for our relayers
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
## Install Docker Compose - for managing multiple containers
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
## Install jq - for parsing JSON responses
sudo apt-get update && sudo apt-get install -y jq
## Verify everything is installed correctly
docker --version
docker-compose --version
jq --version
You should see version numbers for all three tools:
Docker version 24.0.7, build afdd53b
docker-compose version 1.29.2
Jq-1.6
Setting Up Your Environment
Now that you have the prerequisites installed, let’s create a proper directory structure for your relayer.
Creating Your Workspace
## Create and navigate to your relayer directory
mkdir -p ~/hyperbridge-relayer
cd ~/hyperbridge-relayer
## Create subdirectories for different components
mkdir -p config data logs keys
## Secure the keys directory
chmod 700 keys
## Verify the structure was created
tree -L 1
You should see:
├── config
├── data
├── keys
└── logs
Getting the Official Docker Images
Hyperbridge provides pre-built Docker images, so you don’t need to compile anything:
## Pull the messaging relayer (Tesseract)
docker pull polytopelabs/tesseract:latest
## Pull the consensus relayer
docker pull polytopelabs/tesseract-consensus:latest
## Verify the images were downloaded
docker images | grep polytope
You should see both images listed:
polytopelabs/tesseract-consensus latest 4583b2c96f3f 2 days ago 184MB
polytopelabs/tesseract latest 785c94acf9a2 2 days ago 155MB
Finding and Configuring RPC Endpoints
Your relayer needs to communicate with the blockchains it’s supporting. This requires RPC endpoints — think of them as the phone numbers your relayer uses to call each blockchain.
Understanding RPC Requirements
Different chains have different requirements:
For EVM chains (Ethereum, Arbitrum, Optimism, etc.)
- HTTP/HTTPS RPC endpoint for transactions
- Debug namespace enabled for transaction tracing
- Etherscan API key for gas price data
For Substrate chains (Polkadot, Kusama parachains)
- WebSocket RPC endpoint
- Unsafe RPC methods enabled
For Consensus relaying (additional requirements)
- Beacon chain endpoints for Ethereum
- Specific L2 contract addresses
Finding and Configuring RPC Endpoints
Your relayer needs reliable RPC endpoints to communicate with other blockchains. For best performance, we recommend using our RPC which provides both execution and beacon chain endpoints that are fully optimized for relayer operations.
We currently provide endpoints for Polkadot/Kusama, Ethereum, Polygon, BNB Chain, Arbitrum, Optimism, Avalanche, Solana, Starknet, Sui, Aptos, Base with support extending to 50+ protocols.
To get started, create your account if you haven’t already: How to Create an Account
Then get your API endpoints from our API Service: API Service Documentation

Make sure to grab WebSocket endpoints if you’re running a consensus relayer — you’ll need real-time updates for consensus proofs.
You’ll also need Etherscan API keys for gas prices, You can obtain the required etherscan API key by following this guide for the appropriate network. Do note that since Ethereum and its L2s all use Ether as the gas token. They can all share the same etherscan API key.
Deploying Your First Messaging Relayer
Let’s start with a messaging relayer, which is simpler to set up and can start earning DAI rewards immediately.
Creating Your Configuration
First, let’s create a configuration file that tells your relayer which chains to support and how to connect to them.
Create config/messaging-config.toml:
[hyperbridge]
state_machine = "POLKADOT-3367" # Hyperbridge on Polkadot mainnet
hashing = "Keccak"
signer = "" // add your hyperbridge signer key here
consensus_state_id = "DOT0"
rpc_ws = "wss://nexus-rpc.hyperbridge.blockops.network:443"
## Ethereum Mainnet
[ethereum]
type = "ethereum"
poll_interval = 15
state_machine = "EVM-1"
rpc_urls = [
"https://ethereum-mainnet.blockops.network/YOUR_API_KEY" # Replace YOUR_API_KEY
]
consensus_state_id = "ETH0"
etherscan_api_key = "YOUR_ETHERSCAN_KEY"
ismp_host = "0x792A6236AF69787C40cF76b69B4c8c7B28c4cA20"
signer = "YOUR_PRIVATE_KEY" # Your wallet private key (without 0x prefix)
tracing_batch_size = 5
query_batch_size = 10000
gas_price_buffer = 1
## Binance Smart Chain
[bsc]
type = "evm"
poll_interval = 15
state_machine = "EVM-56"
rpc_urls = [
"https://bsc-mainnet.blockops.network/YOUR_API_KEY"
consensus_state_id = "BSC0"
etherscan_api_key = "YOUR_ETHERSCAN_KEY"
ismp_host = "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7"
signer = "YOUR_PRIVATE_KEY" # Same key works for all chains
tracing_batch_size = 5
query_batch_size = 10000
## Gnosis Chain
[gnosis]
type = "evm"
poll_interval = 15
state_machine = "EVM-100"
rpc_urls = [
"https://gnosis-mainnet.blockops.network/YOUR_API_KEY" # Replace YOUR_API_KEY
]
consensus_state_id = "GNO0"
etherscan_api_key = "YOUR_ETHERSCAN_KEY"
ismp_host = "0x50c236247447B9d4Ee0561054ee596fbDa7791b1"
signer = "YOUR_PRIVATE_KEY" # Same key works for all chains
tracing_batch_size = 5
query_batch_size = 10000
## Relayer Business Logic
[relayer]
minimum_profit_percentage = 1 # Require 1% profit minimum
unprofitable_retry_frequency = 120 # Retry every 2 minutes
# the delivery endpoint should have all the evm chain configured above
delivery_endpoints = [
"EVM-1", # Ethereum
"EVM-100", # Gnosis
"EVM-56" # BSC
]
Remember to replace:
- YOUR_API_KEY — Get this from your Blockops account
- YOUR_ETHERSCAN_KEY — From etherscan.io (works for Ethereum and L2s)
- YOUR_PRIVATE_KEY — Your relayer wallet private key (keep this secure!)
Now the next step is to run the messaging relayers. Now let’s run your relayer:
docker run -d \
--name=tesseract \
--network=host \
--restart=always \
--volume=$(pwd)/config:/home/root:ro \
--volume=$(pwd)/data:/data \
--volume=$(pwd)/logs:/logs \
polytopelabs/tesseract:latest \
--config=/home/root/messaging-config.toml \
--db=/data/tesseract.db
## Check if it started successfully
docker ps | grep tesseract
You should see your container running:
tech-blog docker ps | grep tesseract
3d583ba280cf polytopelabs/tesseract:latest "./tesseract --confi..." 4 minutes ago Up 4 minutes tesseract
➜ tech-blog
Verifying Your Relayer is Working
Let’s check the logs to ensure everything is running correctly:
tech-blog docker logs -f tesseract
2025-09-16T19:10:10.621154Z INFO tesseract::cli: 🧊 Initializing tesseract
2025-09-16T19:10:10.666453Z INFO quaint::pooled: Starting a sqlite pool with 25 connections.
2025-09-16T19:10:10.738819Z INFO migration_core::commands::apply_migrations: Analysis run in 27ms analysis_duration_ms=27
2025-09-16T19:10:10.739218Z INFO Applying migration{migration_name="20240227154307_"}: migration_core::commands::apply_migrations: Applying `20240227154307_` script="-- CreateTable\nCREATE TABLE \"Deliveries\" (\n \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n \"hash\" TEXT NOT NULL,\n \"source_chain\" TEXT NOT NULL,\n \"dest_chain\" TEXT NOT NULL,\n \"delivery_type\" INTEGER NOT NULL,\n \"created_at\" INTEGER NOT NULL,\n \"height\" INTEGER NOT NULL\n);\n"
2025-09-16T19:10:10.749442Z INFO Applying migration{migration_name="20240315095442_pending_withdrawals"}: migration_core::commands::apply_migrations: Applying `20240315095442_pending_withdrawals` script="-- CreateTable\nCREATE TABLE \"PendingWithdrawal\" (\n \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n \"dest\" TEXT NOT NULL,\n \"encoded\" BLOB NOT NULL\n);\n"
2025-09-16T19:10:10.751924Z INFO Applying migration{migration_name="20240327084356_unproitable_retries"}: migration_core::commands::apply_migrations: Applying `20240327084356_unproitable_retries` script="-- CreateTable\nCREATE TABLE \"UnprofitableMessages\" (\n \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n \"dest\" TEXT NOT NULL,\n \"encoded\" BLOB NOT NULL\n);\n"
2025-09-16T19:10:13.821654Z INFO tesseract_evm: Initialized height for Evm(100) at 42155907
2025-09-16T19:10:15.173344Z INFO tesseract_evm: Initialized height for Evm(1) at 23377529
2025-09-16T19:10:16.419903Z INFO tesseract_evm: Initialized height for Evm(56) at 61401324
2025-09-16T19:10:18.102534Z INFO tesseract_substrate: Initialized height for Polkadot(3367)->Evm(100) at 6996392
2025-09-16T19:10:19.517199Z INFO tesseract_substrate: Initialized height for Polkadot(3367)->Evm(1) at 6996392
2025-09-16T19:10:20.999692Z INFO tesseract_substrate: Initialized height for Polkadot(3367)->Evm(56) at 6996392
2025-09-16T19:10:21.011825Z INFO tesseract::cli: 💬 Initialized messaging tasks
2025-09-16T19:10:21.011907Z INFO tesseract::fees: Auto-withdraw frequency set to 86400s
2025-09-16T19:10:21.014645Z INFO tesseract::fees: Minimum auto-withdrawal amount set to $100.000000000000000000
2025-09-16T19:10:52.940253Z INFO tesseract_messaging: Skipping latest finalized height 61401324 on Polkadot(3367), no new messages from EVM-56 in range 61401324..=61401324
2025-09-16T19:11:21.084436Z INFO tesseract_primitives: Waiting for challenge period 90s for EVM-100 on Polkadot(3367)
2025-09-16T19:11:45.509441Z INFO tesseract_messaging: Skipping latest finalized height 61401387 on Polkadot(3367), no new messages from EVM-56 in range 61401324..=61401387
2025-09-16T19:12:03.742736Z INFO tesseract_primitives: Waiting for challenge period 90s for EVM-1 on Polkadot(3367)
Congratulations! Your messaging relayer is now running on mainnet.
Running a Consensus Relayer
Consensus relayers submit blockchain state proofs to Hyperbridge and earn BRIDGE tokens. They require more complex configuration but provide steady rewards.
Creating Your Consensus Configuration
Create config/consensus-config.toml:
```toml
[hyperbridge]
type = "grandpa"
rpc_ws =
[hyperbridge.substrate]
state_machine = "POLKADOT-3367"
hashing = "Keccak"
rpc_ws = "wss://nexus-rpc.hyperbridge.blockops.network:443"
[hyperbridge.grandpa]
rpc = "wss://nexus-rpc.hyperbridge.blockops.network"
slot_duration = 12000
para_ids = [3367]
[ethereum]
type = "ethereum"
state_machine = "EVM-1"
# This should be execution layer rpc
rpc_urls = [
"https://eth.rpc.blockops.network?api_key=<api_key>"
]
consensus_state_id = "ETH0"
etherscan_api_key = "YOUR_ETHERSCAN_KEY"
ismp_host = "0x792A6236AF69787C40cF76b69B4c8c7B28c4cA20"
signer = "0xYOUR_PRIVATE_KEY"
[ethereum.host]
beacon_http_urls = [
"Your_beacon_node_url"
]
consensus_update_frequency = 60
[gnosis]
type = "gnosis"
state_machine = "EVM-100"
rpc_urls = [
"https://gnosis.rpc.blockops.network?<api_key>"
]
consensus_state_id = "GNO0"
etherscan_api_key = "YOUR_ETHERSCAN_KEY"
ismp_host = "0x50c236247447B9d4Ee0561054ee596fbDa7791b1"
signer = "0xYOUR_PRIVATE_KEY"
[gnosis.host]
beacon_http_urls = [
"You_beano_url"
]
consensus_update_frequency = 60
[arbitrum]
type = "arbitrum_orbit"
state_machine = "EVM-42161"
rpc_urls = [
"https://arbitrum.rpc.blockops.network?api_key="
]
consensus_state_id = "ARB0"
etherscan_api_key = "YOUR_ETHERSCAN_KEY"
ismp_host = "0xE05AFD4Eb2ce6d65c40e1048381BD0Ef8b4B299e"
signer = "0xYOUR_PRIVATE_KEY"
gas_price_buffer = 8
[arbitrum.host]
# this shold be L1 execution rpc
beacon_rpc_url = [
"https://arbitrum.rpc.blockops.network?api_key="
]
rollup_core = "0x4DCeB440657f21083db8aDd07665f8ddBe1DCfc0"
l1_state_machine = "EVM-1"
l1_consensus_state_id = "ETH0"
consensus_update_frequency = 60
[bsc]
type = "bsc"
state_machine = "EVM-56"
rpc_urls = [
"https://bsc.rpc.blockops.network?api_key="
]
consensus_state_id = "BSC0"
etherscan_api_key = "${ETHERSCAN_KEY}"
ismp_host = "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7"
signer = "0xYOUR_PRIVATE_KEY"
[bsc.host]
consensus_update_frequency = 60
epoch_length = 1000
[relayer]
challenge_period = 0
enable_hyperbridge_consensus = false
maximum_update_intervals = [
[{state_id = "EVM-1", consensus_state_id = "ETH0"}, 900],
[{state_id = "EVM-100", consensus_state_id = "GNO0"}, 420],
[{state_id = "EVM-56", consensus_state_id = "BSC0"}, 300]
]
You should see:
➜ tech-blog docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
19f4cacb7bb0 polytopelabs/tesseract-consensus:latest "./tesseract-consens..." 20 seconds ago Up 20 seconds tesseract-consensus
3d583ba280cf polytopelabs/tesseract:latest "./tesseract --confi..." 4 hours ago Up 4 hours tesseract
➜ tech-blog

➜ tech-blog docker logs tesseract-consensus
2025-09-16T22:47:23.270109Z INFO tesseract_consensus::cli: 🧊 Initializing tesseract consensus
2025-09-16T22:47:26.860297Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:47:26.874052Z INFO redis_async::reconnect: Connection established
2025-09-16T22:47:37.103871Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:47:37.107573Z INFO redis_async::reconnect: Connection established
2025-09-16T22:47:40.848310Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:47:40.856722Z INFO redis_async::reconnect: Connection established
2025-09-16T22:47:44.192576Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:47:44.195459Z INFO redis_async::reconnect: Connection established
2025-09-16T22:47:48.033398Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:47:48.039538Z INFO redis_async::reconnect: Connection established
2025-09-16T22:47:51.424825Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:47:51.428228Z INFO redis_async::reconnect: Connection established
2025-09-16T22:47:55.363087Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:47:55.371333Z INFO redis_async::reconnect: Connection established
2025-09-16T22:47:58.963930Z INFO tesseract: 🛰️ Transmitting consensus message from Evm(56) to Polkadot(3367)
2025-09-16T22:47:59.128059Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:47:59.130885Z INFO redis_async::reconnect: Connection established
2025-09-16T22:47:59.184667Z INFO tesseract_substrate::extrinsic: Unsigned extrinsic successfully inserted into pool with hash: 0xbd250f2d1240a7c6fe0e788b3a4eff278bdcb995da490ed01b3c8d3b7c9f3c19
2025-09-16T22:48:02.508161Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:48:02.513582Z INFO redis_async::reconnect: Connection established
2025-09-16T22:48:02.516039Z INFO tesseract_consensus::cli: Initializing consensus update monitoring task
2025-09-16T22:48:02.517214Z INFO tesseract_consensus::cli: Initialized consensus tasks
2025-09-16T22:48:06.544686Z INFO redis_async::reconnect: Attempting to reconnect, current state: ReconnectState::NotConnected
2025-09-16T22:48:06.550496Z INFO redis_async::reconnect: Connection established
2025-09-16T22:48:57.918883Z INFO tesseract: 🛰️ Transmitting consensus message from Evm(56) to Polkadot(3367)
2025-09-16T22:48:58.142934Z INFO tesseract_substrate::extrinsic: Unsigned extrinsic successfully inserted into pool with hash: 0x44342916ea7528030c12384515eb65671d58edda19baee562bc60ba88a5e317f
2025-09-16T22:49:57.362904Z INFO tesseract: 🛰️ Transmitting consensus message from Evm(56) to Polkadot(3367)
2025-09-16T22:49:57.586720Z INFO tesseract_substrate::extrinsic: Unsigned extrinsic successfully inserted into pool with hash: 0x493cc9b2476520b3f12c00e351018499596ad91105636c062f99ca037f5cb85a
➜ tech-blog

Congratulations! Your consensus relayer is now running on mainnet.
Conclusion
You now have both relayers running successfully — your messaging relayer facilitating cross-chain communication and your consensus relayer submitting blockchain state proofs to Hyperbridge. Your relayers are now part of Hyperbridge’s decentralized infrastructure, helping secure cross-chain communication 24/7.
For further technical documentation:
Messaging Relayer Guide: https://docs.hyperbridge.network/developers/network/relayer/messaging/relayer
Consensus Relayer Guide: https://docs.hyperbridge.network/developers/network/relayer/consensus/relayer
Welcome to the Hyperbridge relayer network!
메타데이터
- post_id
- c42e255dcc92
- slug
- running-a-hyperbridge-relayer-a-complete-guide-c42e255dcc92
- url
- https://blog.blockops.network/running-a-hyperbridge-relayer-a-complete-guide-c42e255dcc92
- canonical_url
- https://blog.blockops.network/running-a-hyperbridge-relayer-a-complete-guide-c42e255dcc92
- author_url
- https://medium.com/@blockopsnetwork
- status
- ok
- fetched_at
- 2026-07-13 06:23:13