MetaMask-compatible middleware for Canton Network, enabling ERC-20 style interactions with CIP-56 tokens.
This project provides:
- API Server: Ethereum JSON-RPC facade that translates MetaMask transactions to Canton CIP-56 operations
- Relayer: Bridges PROMPT tokens between Ethereum and Canton
- Interoperability: Native Canton users and MetaMask users can seamlessly transfer tokens to each other
# Clone the repository
git clone https://github.com/ChainSafe/canton-middleware.git
cd canton-middleware
# Run the bootstrap script (handles everything)
./scripts/setup/bootstrap-all.shThis will:
- Generate encryption keys (
CANTON_MASTER_KEY) - Start Docker services (Canton, Anvil, PostgreSQL, API Server, Relayer)
- Wait for healthy status
- Register test users
- Mint DEMO tokens (500 each) and deposit PROMPT tokens
| Tool | Version | Install |
|---|---|---|
| Go | 1.23+ | https://go.dev/dl/ |
| Docker | Latest | https://docs.docker.com/get-docker/ |
| Docker Compose | v2+ | (included with Docker Desktop) |
| Foundry | Latest | curl -L https://foundry.paradigm.xyz | bash && foundryup |
After bootstrap completes, configure MetaMask:
| Setting | Value |
|---|---|
| Network Name | Canton Local |
| RPC URL | http://localhost:8081/eth |
| Chain ID | 31337 |
| Currency Symbol | ETH |
Test Accounts (Anvil defaults):
| User | Address | Private Key |
|---|---|---|
| User 1 | 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 |
ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 |
| User 2 | 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 |
59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d |
Token Addresses:
| Token | Address | Type |
|---|---|---|
| DEMO | 0xDE30000000000000000000000000000000000001 |
Native Canton token |
| PROMPT | 0x5FbDB2315678afecb367f032d93F642f64180aa3 |
Bridged ERC-20 |
| Service | URL |
|---|---|
| API Server (MetaMask RPC) | http://localhost:8081/eth |
| API Server Health | http://localhost:8081/health |
| Canton gRPC | localhost:5011 |
| Canton HTTP | http://localhost:5013 |
| Anvil (Ethereum) | http://localhost:8545 |
| PostgreSQL | localhost:5432 |
βββββββββββββββββββ βββββββββββββββββββ
β MetaMask β β Native Canton β
β (EVM Wallet) β β User / CLI β
ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ
β JSON-RPC β gRPC
βΌ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β API SERVER β
β β’ /eth - JSON-RPC facade (eth_call, eth_sendRawTx) β
β β’ /register - User registration β
β β’ Custodial Canton key management β
β β’ Balance reconciliation with Canton β
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββΌβββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β PostgreSQL β β Canton β β Relayer β
β (Cache) β β (CIP-56) β β (Bridge) β
βββββββββββββββ βββββββββββββββ ββββββββ¬βββββββ
β
ββββββββΌβββββββ
β Ethereum β
β (ERC-20) β
βββββββββββββββ
Key Components:
- API Server - Translates ERC-20 calls to CIP-56 DAML operations
- Relayer - Bridges PROMPT token between Ethereum β Canton
- PostgreSQL - Caches user data and balances for fast queries
- Canton Ledger - Source of truth for all token balances
canton-middleware/
βββ cmd/
β βββ api-server/ # API server entry point
β βββ relayer/ # Relayer entry point
βββ pkg/
β βββ apidb/ # Database operations
β βββ auth/ # JWT and EVM authentication
β βββ canton/ # Canton client (gRPC)
β β βββ lapi/v2/ # Generated Ledger API protobufs
β βββ config/ # Configuration handling
β βββ db/ # Database schema
β βββ ethereum/ # Ethereum client
β βββ ethrpc/ # JSON-RPC server
β βββ keys/ # Key management (secp256k1)
β βββ registration/ # User registration
β βββ service/ # Token service
βββ scripts/
β βββ setup/ # Bootstrap and setup scripts
β βββ testing/ # Test and demo scripts
β βββ bridge/ # Bridge operation scripts
β βββ utils/ # Diagnostic utilities
β βββ lib/ # Shared bash functions
β βββ archive/ # Migration scripts (reference)
βββ contracts/
β βββ canton-erc20/ # DAML contracts (CIP-56)
β βββ ethereum-wayfinder/ # Solidity contracts
βββ docs/ # Documentation
βββ deployments/ # Docker, deployment configs
| Script | Description |
|---|---|
bootstrap-all.sh |
Full automated setup (recommended) |
bootstrap-bridge.go |
Bootstrap bridge contracts on Canton |
bootstrap-demo.go |
Mint DEMO tokens to users |
setup-local.sh |
Alternative local setup |
setup-devnet.sh |
DevNet setup |
| Script | Description |
|---|---|
canton-transfer-demo.go |
Demo transfers and reconciliation |
register-native-user.go |
Register native Canton user |
register-user.go |
Register EVM user |
e2e-local.go |
End-to-end local tests |
| Script | Description |
|---|---|
query-canton-holdings.sh |
Query Canton holdings |
verify-canton-holdings.go |
Verify/compare holdings |
metamask-info.sh |
Show MetaMask config |
check-mappings.go |
Check fingerprint mappings |
# Install dependencies
go mod download
# Build binaries
make build
# Run tests
make test# Set environment variables
export CANTON_MASTER_KEY=$(openssl rand -base64 32)
export SKIP_CANTON_SIG_VERIFY=true
# Start services
docker compose up -d
# Wait for healthy status
docker compose ps
# Run bootstrap scripts
go run scripts/setup/bootstrap-bridge.go -config config.e2e-local.yaml
go run scripts/setup/bootstrap-demo.go -config config.e2e-local.yaml# Health checks
curl http://localhost:8081/health
curl http://localhost:5013/v2/version
# Check balances
./scripts/utils/query-canton-holdings.sh
# Compare DB vs Canton
go run scripts/utils/verify-canton-holdings.go -config config.e2e-local.yaml -compare| Document | Description |
|---|---|
| Architecture | System design and data flows |
| Setup & Testing | Local setup and environment configuration |
| API Documentation | Endpoint reference |
| CIP-0086 Overview | CIP-0086 compliance |
| Deployment Requirements | Production deployment checklist |
Configuration files:
| Environment | Config File |
|---|---|
| Local | config.e2e-local.yaml |
| Docker | config.docker.yaml |
| Example | config.example.yaml |
See Setup & Testing Guide for DevNet/Production configuration.
[License details here]