Mock Bridge
The Mock Bridge is a test deposit relayer that verifies user EIP-712 signatures and submits Kaizen:Deposit transactions to Kaizen Core.
Overview
In production, a bridge relayer would:
- Watch L1 deposit events
- Submit
Deposittransactions to Kaizen Core with the L1 tx hash
The mock bridge simulates this by:
- Accepting signed deposit requests from users
- Generating mock external tx hashes
- Submitting
Deposittransactions to Kaizen Core
Running
# Start on default port (3000)
pnpm run --filter @kaizen-core/mock-bridge dev
# Custom port
pnpm run --filter @kaizen-core/mock-bridge dev -- --port 3002
# With custom RPC
pnpm run --filter @kaizen-core/mock-bridge dev -- --rpc-url http://localhost:8545CLI Options
| Option | Description | Default |
|---|---|---|
-p, --port <port> | HTTP server port | 3000 |
-r, --rpc-url <url> | Kaizen Core RPC URL | http://localhost:8545 |
-k, --private-key <key> | Bridge relayer private key (0x...) | From env |
Environment Variables
| Variable | Description |
|---|---|
KAIZEN_RPC_URL | Kaizen Core RPC URL |
BRIDGE_PRIVATE_KEY | Bridge relayer wallet private key |
API Reference
GET /health
Health check endpoint.
Response{
"status": "healthy",
"rpc": true,
"bridge": "0x...",
"timestamp": 1700000000000
}GET /info
Bridge info.
Response{
"name": "Kaizen Bridge (Test)",
"version": "0.1.0",
"bridge": "0x...",
"rpcUrl": "http://localhost:8545"
}GET /typed-data
Get EIP-712 typed data for signing deposits.
Response{
"domain": {
"name": "Kaizen Bridge",
"version": "1",
"chainId": 1
},
"types": {
"Kaizen:Deposit": [
{ "name": "user", "type": "address" },
{ "name": "amount", "type": "uint256" },
{ "name": "nonce", "type": "uint256" },
{ "name": "deadline", "type": "uint256" }
]
},
"primaryType": "Kaizen:Deposit"
}POST /deposit
Process a signed deposit request.
Request Body{
"user": "0x...",
"amount": "1000000000",
"nonce": "1",
"deadline": 1700000060000,
"signature": "0x..."
}| Field | Type | Description |
|---|---|---|
user | string | User address to credit |
amount | string | Deposit amount (6 decimals for USDC) |
nonce | string | Unique nonce to prevent replay attacks |
deadline | number | Request deadline (Unix timestamp in ms) |
signature | string | EIP-712 signature (65 bytes hex) |
{
"success": true,
"txHash": "0x..."
}{
"success": false,
"error": "Deposit request expired"
}Deposit Flow
EIP-712 Signing Example
import { signTypedData } from "viem/accounts";
// 1. Get typed data from bridge
const response = await fetch("http://localhost:3000/typed-data");
const { domain, types, primaryType } = await response.json();
// 2. Build deposit message
const message = {
user: walletAddress,
amount: 1000000000n, // 1000 USDC
nonce: 1n,
deadline: BigInt(Date.now() + 5 * 60 * 1000), // 5 min
};
// 3. Sign with wallet
const signature = await signTypedData({
domain,
types,
primaryType,
message,
});
// 4. Submit to bridge
const result = await fetch("http://localhost:3000/deposit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user: walletAddress,
amount: message.amount.toString(),
nonce: message.nonce.toString(),
deadline: Number(message.deadline),
signature,
}),
});Security Notes
Transaction Type
The bridge submits Kaizen:Deposit transactions to Core:
struct DepositTx {
user: Address, // User receiving funds
amount: u64, // Deposit amount
external_tx_hash: B256, // L1 tx hash (mock in test)
}EIP-712 Type: Kaizen:Deposit(uint64 timestamp,address from,address user,uint64 amount,bytes32 externalTxHash)
Permission: Relayer only
