-
Notifications
You must be signed in to change notification settings - Fork 34
Open
Description
Summary
Enable payment acceptance from multiple L2 chains (Base, Arbitrum, Optimism, Polygon) with dynamic chain selection and unified verification.
Motivation
Currently, MicroAI Paygate only supports Base (Chain ID 8453). As L2 adoption grows, users may prefer paying from their primary chain. Supporting multiple chains:
- Reduces friction - Users don't need to bridge funds
- Increases adoption - Access wider user base
- Future-proofs - Easy to add new chains
Proposed Architecture
flowchart TB
subgraph Client[Client Layer]
WEB[Web Frontend]
AGENT[Agent Bot]
end
subgraph Gateway[Multi-Chain Gateway]
GW[Gateway Service]
subgraph Registry[Chain Registry]
BASE[Base - 8453]
ARB[Arbitrum - 42161]
OP[Optimism - 10]
POLY[Polygon - 137]
end
end
subgraph Verifier[Verification Layer]
VER[Verifier Service]
end
WEB --> GW
AGENT --> GW
GW --> Registry
GW <--> VER
BASE -.-> VER
ARB -.-> VER
OP -.-> VER
POLY -.-> VER
Request Flow
sequenceDiagram
participant C as Client
participant G as Gateway
participant V as Verifier
C->>G: POST with X-402-ChainId: 42161
G->>G: Validate chainId in registry
G->>V: Verify with Arbitrum domain
V-->>G: is_valid
G-->>C: 200 OK
Supported Chains (Phase 1)
| Chain | ID | USDC Address | Explorer |
|---|---|---|---|
| Base | 8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
basescan.org |
| Arbitrum | 42161 | 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 |
arbiscan.io |
| Optimism | 10 | 0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85 |
optimistic.etherscan.io |
| Polygon | 137 | 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 |
polygonscan.com |
Implementation Details
Chain Configuration
Create config/chains.json:
{
"chains": [
{
"id": 8453,
"name": "Base",
"enabled": true,
"rpcUrl": "${BASE_RPC_URL}",
"usdc": {
"address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"decimals": 6
},
"blockTime": 2,
"explorer": "https://basescan.org"
},
{
"id": 42161,
"name": "Arbitrum",
"enabled": true,
"rpcUrl": "${ARBITRUM_RPC_URL}",
"usdc": {
"address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
"decimals": 6
},
"blockTime": 0.25,
"explorer": "https://arbiscan.io"
}
]
}Updated 402 Response
{
"error": "Payment Required",
"paymentContext": {
"recipient": "0x...",
"amount": "0.001",
"token": "USDC",
"nonce": "uuid"
},
"supportedChains": [
{ "id": 8453, "name": "Base", "recommended": true },
{ "id": 42161, "name": "Arbitrum" },
{ "id": 10, "name": "Optimism" },
{ "id": 137, "name": "Polygon" }
]
}New Request Headers
| Header | Description | Example |
|---|---|---|
X-402-ChainId |
Chain used for payment | 42161 |
X-402-Signature |
EIP-712 signature | 0x... |
X-402-Nonce |
Payment nonce | uuid |
EIP-712 Domain Updates
The domain separator must include the correct chainId:
const domain = {
name: "MicroAI Paygate",
version: "1",
chainId: selectedChainId, // Dynamic based on user selection
verifyingContract: ethers.ZeroAddress,
};Verifier Updates (Rust)
// Parse chainId from request and validate against allowed chains
fn verify_signature(
Json(payload): Json<VerifyRequest>,
) -> (StatusCode, Json<VerifyResponse>) {
let chain_id = payload.context.chain_id;
// Validate chain is supported
if !SUPPORTED_CHAINS.contains(&chain_id) {
return (StatusCode::BAD_REQUEST, Json(VerifyResponse {
is_valid: false,
error: Some("Unsupported chain".to_string()),
..Default::default()
}));
}
// Build domain with correct chainId
let domain = build_domain(chain_id);
// ... rest of verification
}Acceptance Criteria
Backend
- Create chain configuration system (
config/chains.json) - Update 402 response to include
supportedChains[] - Add
X-402-ChainIdheader parsing in Gateway - Validate chainId against supported list
- Update EIP-712 domain construction to use request chainId
- Add per-chain USDC address resolution
- Implement chain-specific RPC routing (for on-chain verification)
Frontend
- Add chain selector dropdown in UI
- Display supported chains from 402 response
- Auto-detect user's current chain from wallet
- Prompt chain switch if needed
- Include chainId in signed data
Testing & Docs
- Add unit tests for each supported chain
- E2E tests with multi-chain scenarios
- Update README with supported chains
- Document chain addition process
Frontend Chain Selector UX
┌─────────────────────────────────────────────┐
│ Select Payment Chain │
├─────────────────────────────────────────────┤
│ ◉ Base (Recommended) ~$0.001 fee │
│ ○ Arbitrum ~$0.002 fee │
│ ○ Optimism ~$0.001 fee │
│ ○ Polygon ~$0.0001 fee │
└─────────────────────────────────────────────┘
Future Considerations
- Dynamic pricing per chain (gas cost differences)
- Chain health monitoring (disable chains with issues)
- Priority chains for faster confirmation
- Cross-chain recipient address management
PR Requirements
⚠️ All PRs must include tests. PRs without adequate test coverage will not be merged.
- Unit tests for chain configuration loading
- Unit tests for EIP-712 domain construction per chain
- Unit tests for Rust verifier chain validation
- Integration tests for multi-chain signature verification
- Frontend tests for chain selector component
- Tests must pass:
go test -v ./...,cargo test, andbun test
Reactions are currently unavailable