Self-hosted lock-and-mint bridge for ERC-20 tokens between EVM chains. Users lock on a source-chain Bridge; a Go relayer collects EIP-712 signatures from your validator set and mints on a destination-chain BridgeHub.
This is for appchain and token-issuer teams who operate their own validators. It is not a general-purpose messaging protocol (LayerZero, Hyperlane) and not a retail swap router.
The source-chain Bridge contract is adapted from Hyperliquid Bridge2.sol.
中文文档 · Docs · Contributing
Bridge connects two EVM chains through a pair of contracts:
Bridge— deployed on the source chain where users lock or deposit tokensBridgeHub— deployed on the destination chain where bridged tokens are minted and withdrawals are initiated
The relayer runs block scanners on both sides, collects validator signatures, and relays confirmations across chains. Any EVM network with a stable RPC endpoint and a configured chain ID can be used — Ethereum, BSC, Polygon, Arbitrum, Base, or a custom chain.
Source chain (EVM) Destination chain (EVM)
┌─────────────────────┐ ┌─────────────────────┐
│ Bridge.sol │ │ BridgeHub.sol │
│ lock / deposit │ │ mint / withdraw │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
└──────────► Relayer ◄──────────────┘
(scan · sign · submit)
- EVM-agnostic — works with any EVM-compatible chain; configure RPC URLs and chain IDs in
config.toml - ERC-20 support — bridge whitelisted tokens via lock-and-mint on deposit, burn-and-release on withdrawal
- Validator quorum — cross-chain messages are authorized with EIP-712 signatures from a configured validator set
- Dispute period — withdrawals on the source chain enter a pending state before finalization
- Resilient scanning — block progress is persisted in BadgerDB with configurable confirmation depth and retry logic
- Flexible gas control — fee history, gas caps, and a dry-run (
no_send) mode for testing
- Solana cross-chain — bridging between Solana and EVM chains
| Tool | Version |
|---|---|
| Go | 1.25+ |
| Node.js | 22.18.0+ |
| npm | 10.9.3+ |
git clone https://github.com/zakir-web3/bridge.git
cd bridge
make buildDeploy Bridge on the source chain and BridgeHub on the destination chain. See solidity/README.md for the full deployment guide.
Copy the template and fill in your values:
cp .config.toml config.tomlKey settings:
| Section | Purpose |
|---|---|
priv_key |
Validator private key used for signing |
[bridge] |
Source chain RPC, chain ID, contract address, and token list |
[bridge_hub] |
Destination chain RPC, chain ID, and BridgeHub address |
source |
BadgerDB path for persisting scan progress |
Both [bridge] and [bridge_hub] accept any EVM chain — set node_url and chain_id to match your networks.
./bin/bridgeThe service starts two block scanners (one per chain) and optionally a withdrawal finalizer when send_finalize_withdrawals = true.
| Doc | Contents |
|---|---|
| docs/README.md | Operator, deposit/withdraw, and wallet integration guides (Chinese) |
| solidity/README.md | Contract deployment (Bridge, BridgeHub, token pairs) |
| CONTRIBUTING.md | How to build, test, and open a pull request |
| SECURITY.md | Vulnerability reporting |
config.toml controls logging, caching, network endpoints, contract addresses, scan intervals, block confirmation depth, and transaction gas parameters. See .config.toml for a fully annotated template.
Notable options:
bridge_tokens— ERC-20 contract addresses to watch on the source chainblock_delay— number of confirmations before processing a blockclear_cache— reset scan progress and restart fromstart_blockno_send— simulate transactions without broadcasting (useful for dry runs)ENABLE_FINALIZE_WITHDRAWALS=true— environment variable gate for the withdrawal finalizer task
bridge/
├── main.go # CLI entry point
├── server.go # Service orchestration
├── config.go # Configuration types
├── .config.toml # Configuration template
├── docs/ # Operator and wallet guides
├── internal/
│ ├── bridge/ # Source-chain logic
│ ├── bridgehub/ # Destination-chain logic
│ ├── scanner/ # Block range scanner
│ ├── scheduler/ # Periodic task runner
│ ├── cache/ # BadgerDB block cache
│ ├── contract/ # Generated contract bindings
│ └── evm/ # RPC client and account manager
└── solidity/
├── contracts/ # Bridge, BridgeHub, BridgeERC20
├── scripts/ # Hardhat deployment scripts
└── deploy.sh # Deployment helper
make build # compile to ./bin/bridge
make install # install to $GOPATH/bin
make lint # run golangci-lint
make format # auto-format Go codeContract development:
cd solidity
npm install
npm run compileThe source-chain Bridge contract is adapted from Hyperliquid Bridge2.sol in the hyperliquid-dex/contracts repository (Apache-2.0). It inherits the validator quorum, dispute period, and withdrawal finalization model from the upstream design.
This project handles cross-chain asset transfers. Review SECURITY.md before deploying to production, and report vulnerabilities through GitHub Security Advisories rather than public issues.
See CONTRIBUTING.md. Open an issue to discuss significant changes before submitting a pull request.