Skip to content

Latest commit

 

History

History
488 lines (376 loc) · 20.6 KB

File metadata and controls

488 lines (376 loc) · 20.6 KB

V5.2 Implementation Plan — x402 Facilitator + Payment Channel

Version: 1.1.0 | Date: 2026-03-22 | Duration: 6 weeks Branch: feature/v5.2-x402-facilitator (from feature/uups-migration)

References:


1. Objective

Transform SuperPaymaster from a Gas-only paymaster into a full x402 Facilitator with Payment Channel support. Three parallel workstreams:

  1. On-chain: x402 verify/settle + Payment Channel contract
  2. Off-chain: Operator Node framework (Facilitator HTTP service)
  3. SDK: @aastar/x402 + @aastar/channel packages

Dependency: Requires V5.1 _consumeCredit() to be merged first for the shared billing kernel.


2. Task Breakdown

Phase A: x402 On-Chain Settlement (Week 1-3)

T1: verifyX402Payment() View Function (Week 1)

Description: Read-only verification of x402 payment credential (EIP-3009 signature check).

function verifyX402Payment(
    address from,           // Payer (Agent wallet)
    address to,             // Payee (Resource Server)
    address asset,          // ERC-20 (USDC)
    uint256 amount,
    uint256 validAfter,     // EIP-3009 time window
    uint256 validBefore,
    bytes32 nonce,          // EIP-3009 random nonce
    bytes calldata signature
) external view returns (bool valid, string memory reason);

Sub-tasks:

# Task Est. File
T1.1 Implement EIP-3009 signature reconstruction and verification 3h SuperPaymaster.sol
T1.2 Check from balance and allowance for asset 1h SuperPaymaster.sol
T1.3 Validate time window (validAfter <= now <= validBefore) 0.5h SuperPaymaster.sol
T1.4 Return structured reason on failure 1h SuperPaymaster.sol
T1.5 Unit tests: valid payment, expired, insufficient balance, bad sig 3h test/v3/X402Settle.t.sol

Acceptance Criteria:

  • Valid EIP-3009 signature → (true, "")
  • Invalid signature → (false, "InvalidSignature")
  • Expired time window → (false, "Expired")
  • Insufficient payer balance → (false, "InsufficientBalance")
  • Zero gas cost (view function)

T2: settleX402Payment() External Function (Week 1-2)

Description: Execute x402 payment settlement — transfer tokens + charge facilitator fee.

function settleX402Payment(
    address from,
    address to,
    address asset,
    uint256 amount,
    uint256 validAfter,
    uint256 validBefore,
    bytes32 nonce,
    bytes calldata signature
) external nonReentrant returns (bytes32 txHash);

Settlement Flow:

1. Verify EIP-3009 signature (reuse verifyX402Payment logic)
2. Call asset.transferWithAuthorization(from, to, netAmount, validAfter, validBefore, nonce, signature)
3. Deduct facilitator fee from transfer amount
4. Fee split: operatorFee → operator earnings, protocolFee → protocolRevenue
5. Emit X402PaymentSettled event

Sub-tasks:

# Task Est. File
T2.1 Implement settleX402Payment() with EIP-3009 transferWithAuthorization call 4h SuperPaymaster.sol
T2.2 Implement fee calculation: amount * facilitatorFeeBPS / BPS_DENOMINATOR 1h SuperPaymaster.sol
T2.3 Implement fee split: operator share + protocol share 1h SuperPaymaster.sol
T2.4 Add X402PaymentSettled event with full details 0.5h SuperPaymaster.sol
T2.5 Add x402SettlementNonces mapping to prevent replay 1h SuperPaymaster.sol
T2.6 Unit tests: happy path, double-settle, fee calculation, zero fee 4h test/v3/X402Settle.t.sol

Acceptance Criteria:

  • USDC transferred from from to to (minus fee)
  • Facilitator fee correctly split between operator and protocol
  • Double-settle with same nonce → revert
  • X402PaymentSettled event emitted
  • Works with USDC (6 decimals) and other EIP-3009 tokens

T3: settleX402PaymentPermit2() Fallback (Week 2)

Description: For non-EIP-3009 tokens, use Uniswap Permit2.

function settleX402PaymentPermit2(
    ISignatureTransfer.PermitTransferFrom calldata permit,
    ISignatureTransfer.SignatureTransferDetails calldata transferDetails,
    bytes calldata signature
) external nonReentrant returns (bytes32 txHash);

Sub-tasks:

# Task Est. File
T3.1 Add Permit2 interface import (Uniswap canonical address) 0.5h SuperPaymaster.sol
T3.2 Implement settleX402PaymentPermit2() 3h SuperPaymaster.sol
T3.3 Fee deduction from Permit2 transfer 1h SuperPaymaster.sol
T3.4 Unit tests with mock Permit2 3h test/v3/X402Permit2.t.sol

Acceptance Criteria:

  • Works with any ERC-20 token via Permit2
  • Fee correctly calculated and split
  • Correct Permit2 canonical address used per chain

T4: Facilitator Fee Configuration (Week 2)

Sub-tasks:

# Task Est. File
T4.1 Add facilitatorFeeBPS state variable (default: 30 = 0.3%) 0.5h SuperPaymaster.sol
T4.2 Add operatorFacilitatorFees mapping for per-operator override 0.5h SuperPaymaster.sol
T4.3 setFacilitatorFeeBPS(uint256) owner-only 0.5h SuperPaymaster.sol
T4.4 setOperatorFacilitatorFee(address, uint256) 0.5h SuperPaymaster.sol
T4.5 Add MAX_FACILITATOR_FEE constant (500 = 5%) 0.5h SuperPaymaster.sol
T4.6 Storage layout check: add after V5.1 variables 0.5h
T4.7 Unit tests for fee config 2h test/v3/X402Settle.t.sol

Acceptance Criteria:

  • Default fee: 30 BPS (0.3%)
  • Owner can change global fee
  • Per-operator override takes precedence
  • Fee > MAX → revert
  • Storage layout: no collision with V5.1 slots

T5: Operator Earnings Conversion (Week 3)

function convertFacilitatorEarnings(
    address operator,
    address stablecoin,
    uint256 amount
) external;

Sub-tasks:

# Task Est. File
T5.1 Add facilitatorEarnings mapping per operator 0.5h SuperPaymaster.sol
T5.2 Accumulate earnings in settleX402Payment() 0.5h SuperPaymaster.sol
T5.3 Implement convertFacilitatorEarnings() — stablecoin→aPNTs swap + deposit 3h SuperPaymaster.sol
T5.4 Integration with DEX (placeholder — manual conversion in V5.2) 1h SuperPaymaster.sol
T5.5 Unit tests 2h test/

Note: V5.2 implements manual conversion (operator calls convert). Automated DEX swap is V5.4+.

Acceptance Criteria:

  • Facilitator earnings tracked per operator
  • Conversion correctly updates operators[].aPNTsBalance
  • Only operator or owner can convert
  • 经济飞轮验证 (Roadmap §V5.2 经济模型): Agent 支付 $1.00 → $0.997 payee + $0.002 operator fee + $0.001 protocol fee → operator fee 可 convert 为 aPNTs → 补充 Gas 赞助余额 → 为更多 Agent 赞助 → 更多手续费 → 闭环

Phase B: Payment Channel Contract (Week 2-5)

T6: MicroPaymentChannel.sol — New Independent Contract (Week 2-4)

Description: Unidirectional payment channel for streaming micropayments. Deployed as a separate contract, not part of SuperPaymaster proxy.

Design References: V5 Roadmap §V5.2 F6, Tempo Research §8.6.2

Core Data Structure:

struct MicroPaymentChannel {
    address payer;              // Agent (depositor)
    address payee;              // Service provider
    address token;              // Payment token (USDC, aPNTs, etc.)
    address authorizedSigner;   // Delegated signer (AirAccount Session Key)
    uint128 deposit;            // Total deposited amount
    uint128 settled;            // Total settled amount
    uint64  closeRequestedAt;   // Dispute window start (0 = open)
    bool    finalized;          // Channel closed
}

bytes32 constant VOUCHER_TYPEHASH =
    keccak256("Voucher(bytes32 channelId,uint128 cumulativeAmount)");

Sub-tasks:

# Task Est. File
T6.1 Create MicroPaymentChannel.sol with struct + storage (继承 solady EIP712) 2h contracts/src/paymasters/superpaymaster/v3/
T6.2 openChannel(payee, token, deposit, salt, authorizedSigner) — 含 salt 参数 3h MicroPaymentChannel.sol
T6.3 settleChannel(channelId, cumulativeAmount, signature) 4h MicroPaymentChannel.sol
T6.4 topUpChannel(channelId, amount) 1h MicroPaymentChannel.sol
T6.5 requestCloseChannel(channelId) + dispute window 2h MicroPaymentChannel.sol
T6.6 closeChannel(channelId) — finalize after dispute window 1.5h MicroPaymentChannel.sol
T6.7 withdrawChannel(channelId) — payer 在 grace period 后提款(Design §7.7.3) 1.5h MicroPaymentChannel.sol
T6.8 EIP-712 Voucher signature verification (使用 SignatureCheckerLib) 2h MicroPaymentChannel.sol
T6.9 Events: ChannelOpened, ChannelSettled, ChannelClosed, ChannelTopUp, ChannelWithdrawn 1h MicroPaymentChannel.sol
T6.10 getChannel(channelId) view function 0.5h MicroPaymentChannel.sol
T6.11 Configurable dispute window (CLOSE_TIMEOUT, default 15 min — 借鉴 Tempo grace period) 1h MicroPaymentChannel.sol

Core Logic (借鉴 Design Doc §7.7.3 Tempo TempoStreamChannel):

openChannel:
  1. Transfer deposit from payer to contract (SafeERC20)
  2. channelId = keccak256(payer, payee, token, salt, authorizedSigner, address(this), block.chainid)
     → 绑定合约地址 + chainId → 防跨链、跨合约重放
  3. Store channel struct
  4. Emit ChannelOpened

settleChannel (payee 中间结算):
  1. Verify EIP-712 voucher: _hashTypedData(Voucher(channelId, cumulativeAmount))
     → SignatureCheckerLib.isValidSignatureNow(payer OR authorizedSigner)
  2. Verify cumulativeAmount > channel.settled (累积式,非增量)
  3. delta = cumulativeAmount - channel.settled
  4. Transfer delta to payee
  5. channel.settled = cumulativeAmount
  6. Emit ChannelSettled

requestCloseChannel (payer 请求关闭):
  1. payer calls → sets closeRequestedAt = block.timestamp
  2. Emit CloseRequested

closeChannel (payee 带最终 voucher 关闭):
  1. Verify final voucher + settle remaining
  2. Refund (deposit - settled) to payer
  3. channel.finalized = true

withdrawChannel (payer grace period 后提款):
  1. Require closeRequestedAt > 0 && block.timestamp > closeRequestedAt + CLOSE_TIMEOUT
  2. Refund (deposit - settled) to payer
  3. channel.finalized = true

关键设计 (Design Doc §7.7.3):

  • 累积式 Voucher (cumulative, 非 delta) → 天然防重放,无需 per-session nonce
  • authorizedSigner 委托 → AirAccount Session Key 签 Voucher,冷钱包无需在线
  • channelId 绑定 chainId + contract address → 防跨链重放

Acceptance Criteria:

  • Open channel: tokens transferred from payer to contract
  • Sign voucher off-chain (EIP-712), settle on-chain — tokens to payee
  • Cumulative voucher: settle(0.50) after settle(0.30) transfers only 0.20
  • Cumulative voucher: settle(0.20) after settle(0.30) → revert (non-decreasing)
  • authorizedSigner can sign vouchers instead of payer
  • Invalid voucher signature → revert
  • Top up increases deposit
  • Close: dispute window enforced, refund excess to payer
  • Cannot settle after finalized
  • Cannot double-close
  • Reentrancy protection on all state-changing functions

T7: Payment Channel Security Hardening (Week 4-5)

# Task Est. File
T7.1 Reentrancy guard on all external functions 1h MicroPaymentChannel.sol
T7.2 Settlement cannot exceed deposit 0.5h MicroPaymentChannel.sol
T7.3 Only payer can top up or request close 0.5h MicroPaymentChannel.sol
T7.4 Only payee can settle 0.5h MicroPaymentChannel.sol
T7.5 ERC-20 token safety (SafeERC20) 0.5h MicroPaymentChannel.sol
T7.6 Fuzz testing: random voucher amounts, concurrent settle 4h test/
T7.7 Edge case: zero deposit, zero amount voucher, max uint128 2h test/

Acceptance Criteria:

  • No reentrancy attack vector
  • Settlement capped at deposit
  • SafeERC20 for all token transfers
  • Fuzz tests pass (1000+ runs)

Phase C: Off-Chain Operator Node (Week 4-6)

T8: Operator Node Framework (Week 4-6)

Description: Open-source Node.js framework for running an x402 Facilitator node.

Architecture (from Research §8.6.3):

Operator Node (Hono HTTP server)
├── GET  /health           → Node status
├── POST /verify           → Call verifyX402Payment() on-chain
├── POST /settle           → Call settleX402Payment() on-chain
├── GET  /quote            → Return fee rates
├── GET  /.well-known/x-payment-info  → x402 discovery
└── POST /channel/open     → Call openChannel() on-chain

Key Design (Design Doc §7.7.2 + §7.7.4 战术级借鉴):

  • HMAC-SHA256 无状态 Challenge (MPP mppx/src/Challenge.ts): challenge_id = HMAC-SHA256(server_secret, realm|method|intent|request|expires|digest|opaque) — 无需 Redis/DB
  • Method 插件 + compose 模式 (MPP mppx/src/server/Mppx.ts): 支付方法可插拔组合
  • Transport 抽象 (MPP mppx/src/Transport.ts): HTTP / MCP / SSE 三种传输协议共用同一支付逻辑
  • Push/Pull 凭证模式: Push = Agent 广播交易发 txHash,Pull = Agent 签名由服务端广播

Sub-tasks:

# Task Est. File
T8.1 Project scaffolding: Hono + viem + TypeScript (借鉴 mppx 项目结构) 2h packages/x402-facilitator-node/
T8.2 /health endpoint 0.5h server.ts
T8.3 /verify endpoint → calls verifyX402Payment() view 2h verify.ts
T8.4 /settle endpoint → calls settleX402Payment() tx 3h settle.ts
T8.5 /quote endpoint → returns fee rates from contract 1h quote.ts
T8.6 /.well-known/x-payment-info → x402 discovery metadata 1h discovery.ts
T8.7 HMAC-SHA256 challenge: 7 positional slots (realm|method|intent|base64url(JCS(request))|expires|digest|opaque),完全无状态 (Design §7.7.2) 2h challenge.ts
T8.8 Method 插件架构: superpaymaster.charge() + superpaymaster.session() 可 compose (Design §7.7.4) 3h methods/
T8.9 Transport 抽象层: HTTP 402 + MCP -32042 共用支付逻辑 (Design §7.7.4) 2h transport.ts
T8.10 Configuration: env vars for chain, operator key, contract addresses 1h config.ts
T8.11 Docker compose setup 1h Dockerfile
T8.12 Integration test: full x402 flow (client → node → chain) 4h test/

Acceptance Criteria:

  • Node starts with single OPERATOR_PRIVATE_KEY env var
  • /health returns 200 with operator status
  • /verify returns { valid: true/false, reason } from on-chain call
  • /settle executes on-chain settlement and returns tx hash
  • /quote returns current fee rates
  • HMAC challenge is stateless (no Redis/DB)
  • Docker compose: docker compose up starts node
  • Full E2E: HTTP 402 → payment → 200 flow works

Phase D: Testing and Integration (Week 5-6)

T9: Comprehensive Test Suite (Week 5-6)

New Test Files:

File Tests Focus
test/v3/X402Settle.t.sol 15+ x402 verify/settle/Permit2
test/v3/MicroPaymentChannel.t.sol 20+ Channel lifecycle + voucher signing
test/v3/FacilitatorFee.t.sol 8+ Fee config, split, conversion
test/v3/X402Integration.t.sol 5+ End-to-end x402 + channel flow

Sub-tasks:

# Task Est. File
T9.1 Mock USDC with EIP-3009 support for tests 2h test/mocks/
T9.2 x402 settle tests (USDC path) 4h X402Settle.t.sol
T9.3 Permit2 settle tests 3h X402Settle.t.sol
T9.4 Channel lifecycle tests (open/settle/top-up/close) 6h MicroPaymentChannel.t.sol
T9.5 Channel + AirAccount Session Key simulation (mock SessionKeyValidator algId 0x08) 3h MicroPaymentChannel.t.sol
T9.5b AirAccount 跨合约集成测试 (evaluate-roadmap §6 P0 要求): 1) 创建 Session Key 2) 用 Session Key 签 EIP-712 Voucher (链下) 3) payee 提交 Voucher 结算 (链上) → 验证 authorizedSigner 路径完整 3h test/v3/IntegrationAirAccountChannel.t.sol
T9.6 Fee configuration and split tests 3h FacilitatorFee.t.sol
T9.7 Integration: x402 settle → fee → operator balance update 3h X402Integration.t.sol
T9.8 Regression: all V5.1 + existing tests 1h

Acceptance Criteria:

  • 380+ total tests, 0 failures
  • 100% branch coverage for x402 settlement functions
  • 100% branch coverage for MicroPaymentChannel
  • V5.1 regression: all tests still pass
  • V4.1 regression: all existing tests still pass

T10: Sepolia Deployment and E2E (Week 6)

# Task Est. File
T10.1 Deploy MicroPaymentChannel.sol to Sepolia 1h
T10.2 Upgrade SuperPaymaster proxy with V5.2 impl 1h
T10.3 Configure facilitator fees on-chain 0.5h
T10.4 E2E: x402 payment flow with real USDC (testnet) 3h script/gasless-tests/
T10.5 E2E: Payment Channel open/settle/close with test tokens 3h script/gasless-tests/
T10.6 Start Operator Node on staging server 1h
T10.7 E2E: Full stack — HTTP 402 → Operator Node → on-chain settle 2h
T10.8 Update deployments/config.sepolia.json 0.5h deployments/

Acceptance Criteria:

  • SuperPaymaster V5.2 upgraded successfully on Sepolia
  • MicroPaymentChannel deployed on Sepolia
  • x402 payment settles correctly with testnet USDC
  • Payment Channel open/settle/close works E2E
  • Operator Node running and responding on staging
  • All existing E2E gasless tests still pass

3. SDK Coordination (V5.2)

Package Task Effort Repo
@aastar/x402 New package: Facilitator client SDK (verify/settle/fetch) 3-5 days aastar-sdk
@aastar/channel New package: Payment Channel client (open/sign/settle) 3-5 days aastar-sdk
@aastar/operator-node New package: Facilitator node framework 5-7 days aastar-sdk

AirAccount Coordination:

Task Effort Repo
Session Key EIP-712 Voucher signing E2E test 1 day airaccount-contract
AgentSessionKey + MicroPaymentChannel callTarget config 0.5 day airaccount-contract

4. Risk Register

Risk Likelihood Impact Mitigation
EIP-3009 not widely supported Medium Medium Permit2 fallback (T3) covers all ERC-20 tokens
Payment Channel dispute attack Low High Configurable timeout + AirAccount spendCap
Operator Node key compromise Medium Medium HMAC-SHA256 challenges are stateless; rotate key only
Fee calculation rounding Low Medium Round in protocol's favor; fuzz test edge cases
MicroPaymentChannel reentrancy Low Critical ReentrancyGuard + SafeERC20 + fuzz testing

5. Weekly Schedule

Week Focus Key Deliverable
Week 1 T1 + T2 x402 verify + settle implemented
Week 2 T3 + T4 + T6 start Permit2 fallback + fee config + Channel contract start
Week 3 T5 + T6 continue Earnings conversion + Channel core functions
Week 4 T6 complete + T7 + T8 start Channel security + Operator Node start
Week 5 T8 continue + T9 Operator Node + comprehensive tests
Week 6 T10 + T9 remaining Sepolia deployment + E2E validation

Total Estimated Effort: ~120-150 hours (contract + off-chain + tests + deployment)


6. Definition of Done (V5.2)

  • verifyX402Payment() and settleX402Payment() deployed and tested
  • settleX402PaymentPermit2() deployed and tested
  • MicroPaymentChannel.sol deployed independently
  • Facilitator fee system working (global + per-operator)
  • Payment Channel: open/sign/settle/close lifecycle E2E verified
  • Operator Node: HTTP service running, serving /verify, /settle, /quote
  • AirAccount Session Key can sign Payment Channel vouchers (E2E)
  • 380+ Foundry tests, 0 failures
  • Sepolia deployment successful, all E2E tests pass
  • Competitive score: 33/50 (within 2 points of Tempo)