x402 V2 Migration Plan (Deepened)
Created: January 1, 2026
Deepened: January 1, 2026 via /deepen-plan
Author: SAGE
Deadline: January 14, 2026 (Cronos Hackathon Phase 1)
Enhancement Summary (from /deepen-plan)
Review Agents Used: security-sentinel, kieran-python-reviewer, kieran-typescript-reviewer, architecture-strategist, data-integrity-guardian, best-practices-researcher
Key Improvements:
| Priority |
Finding |
Fix |
| CRITICAL |
Chain detection bypassable via signature heuristics |
Use explicit chain field from payment network |
| CRITICAL |
Nonce consumed before verification complete |
Two-phase reserve/commit/release pattern |
| CRITICAL |
Unbounded local cache (memory exhaustion) |
Add TTL + size limit (10k max) |
| HIGH |
No nonce format validation |
Regex: ^[a-zA-Z0-9_-]{16,64}$ |
| HIGH |
TypeScript uses unsafe unknown types |
Zod schemas with CAIP-2 validation |
| HIGH |
Wallet validation is Solana-only |
Chain-aware validation (EVM: 0x..., Solana: base58) |
| MEDIUM |
CDP Facilitator is SPOF |
Circuit breaker per chain |
| MEDIUM |
Bare exception handling |
Specific exception types |
Executive Summary
Migrate the existing SAGE x402 DeFi API from x402 V1 to V2. The core API (12 exchange integrations, arbitrage analysis, caching, alerts) is production-ready and unchanged. This migration focuses solely on the payment verification layer.
Scope: ~50-100 lines of code changes
Risk: Low (core API untouched)
Outcome: Multi-chain x402 V2 API discoverable on Bazaar
1. Context & Background
1.1 What is x402?
x402 is an open protocol that operationalizes HTTP 402 "Payment Required" for machine-to-machine micropayments. Instead of API keys or subscriptions, agents pay per-request using stablecoins (USDC).
V1 Flow (current):
Request → 402 Response → Client signs payment → X-Payment header → Server verifies → Success
V2 Flow (target):
Request → 402 Response with PAYMENT-REQUIRED header → Client signs → PAYMENT-SIGNATURE header → Server verifies → Success
V2 Key Changes:
- New headers:
PAYMENT-SIGNATURE and PAYMENT-REQUIRED (replaces X-Payment)
- Multi-chain via CAIP-2 standard (single endpoint, multiple chains)
- Plugin architecture (
@x402/evm, @x402/svm)
- Reusable sessions (Sign-In-With-X) for reduced latency
- Bazaar discovery extension for agent discoverability
1.2 Why Migrate Now?
- V1 is deprecated -
X-Payment header no longer works with V2 clients
- Solana dominance - 72% of x402 volume is on Solana (400ms finality vs 2s on Base)
- Cronos Hackathon - 300+ builders seeking DeFi APIs (ends Jan 23, 2026)
- CDP fees started Jan 1 - need proper facilitator integration
2. Current State Analysis
2.1 Architecture Overview
x402/
├── main.py # FastAPI app entry point
├── config.py # Configuration (NETWORK, PRICE_PER_CALL, WALLET_ADDRESS)
├── utils.py # create_402_response() - NEEDS V2 UPDATE
├── routers/
│ ├── funding_rates.py # Main API endpoints - NEEDS V2 UPDATE
│ └── ...
├── services/
│ ├── exchange_service.py # 12 exchange integrations (unchanged)
│ ├── rate_limiter.py # Wallet-based rate limiting (unchanged)
│ └── ...
└── packages/
└── x402-payment/ # TypeScript payment module - NEEDS V2 UPDATE
├── package.json # Currently: @coinbase/x402: ^0.7.1 (V1)
└── src/index.ts # Payment verification logic
2.2 What's Working (Don't Touch)
| Component |
File |
Status |
| 12 Exchange Integrations |
exchanges/*.py |
Production-ready |
| Arbitrage Analysis |
services/analysis_service.py |
Production-ready |
| Redis Caching |
services/cache_service.py |
Production-ready |
| Rate Limiting |
services/rate_limiter.py |
Production-ready |
3. Target State
3.1 V2 Architecture
Client → PAYMENT-SIGNATURE header → FastAPI
│
parse_payment()
│
validate_wallet(chain) ← NEW: chain-aware
│
+------- chain routing -------+
│ │
EVMVerifier SolanaVerifier
│ │
+--- circuit breaker ---+ +--- circuit breaker ---+ ← NEW
│ │
CDP Facilitator CDP Facilitator
│ │
+----- nonce check (Redis, fail-closed) ----+ ← NEW: two-phase
│
rate_limit (Redis/memory)
│
API Response
3.2 V2 402 Response Schema
{
"x402Version": "2",
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"maxAmountRequired": "10000",
"resource": "/api/funding-rates",
"payTo": "0xae3cDa2A4c50782868EAD3be4bFAedd96D07c17e",
"token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
},
{
"scheme": "exact",
"network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
"maxAmountRequired": "10000",
"resource": "/api/funding-rates",
"payTo": "<solana-wallet-address>",
"token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
}
]
}
4. Migration Steps (Updated with Research)
Step 1: Update TypeScript SDK
File: packages/x402-payment/package.json
{
"dependencies": {
"@x402/core": "^2.0.0",
"@x402/evm": "^2.1.0",
"@x402/svm": "^2.0.0",
"@coinbase/x402": "^2.0.0",
"zod": "^3.22.0"
}
}
Research Finding: Add CAIP-2 type system:
type EVMChainId = 'eip155:1' | 'eip155:8453' | 'eip155:84532';
type SVMChainId = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';
export type ChainId = EVMChainId | SVMChainId;
type ChainConfig =
| { chainType: 'evm'; chainId: EVMChainId; wallet: `0x${string}` }
| { chainType: 'svm'; chainId: SVMChainId; wallet: string };
Research Finding: Add Zod validation:
const PaymentPayloadSchema = z.object({
x402Version: z.literal(2),
network: z.string().regex(/^(eip155|solana):/), // CAIP-2
signature: z.string()
});
Step 2: Update Python Config
File: config.py
X402_VERSION = "2"
NETWORKS = {
"base": "eip155:8453",
"ethereum": "eip155:1",
"solana": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
}
USDC_ADDRESSES = {
"base": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"solana": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
}
Step 3: Update 402 Response
File: utils.py
- Change
x402Version from "1" to "2"
- Use CAIP-2 network identifiers
- Add
PAYMENT-REQUIRED header
Step 4: Update Payment Verification (CRITICAL FIXES)
File: routers/funding_rates.py
Research Finding - Chain Detection Fix:
def detect_payment_chain(payment_data: dict) -> str:
"""Use explicit chain from payment network, not signature format."""
network = payment_data.get("network", "")
chain = network.split(":")[0]
if chain == "eip155":
return "evm"
elif chain == "solana":
return "solana"
raise ValueError(f"Unsupported chain: {chain}")
Research Finding - Error Handling Fix:
# Instead of bare except Exception:
except json.JSONDecodeError as e:
return False, None, f"Invalid payment signature: {e}"
except PaymentVerificationError as e:
return False, None, f"Payment verification failed: {e}"
except (ConnectionError, TimeoutError) as e:
return False, None, f"Network error: {e}"
Step 5: Add Nonce Service (CRITICAL - NEW)
File: services/nonce_service.py
Research Finding - Two-Phase Pattern:
class NonceService:
NONCE_TTL = 86400
MAX_LOCAL_CACHE = 10000
NONCE_PATTERN = re.compile(r'^[a-zA-Z0-9_-]{16,64}$')
async def reserve_nonce(self, nonce: str, ttl: int = 60) -> bool:
"""Reserve nonce temporarily during verification."""
if not self.NONCE_PATTERN.match(nonce):
raise ValueError("Invalid nonce format")
key = f"nonce:pending:{nonce}"
return await self.redis.set(key, "1", nx=True, ex=ttl) is not None
async def commit_nonce(self, nonce: str) -> bool:
"""Permanently consume after successful verification."""
pipe = self.redis.pipeline()
pipe.delete(f"nonce:pending:{nonce}")
pipe.set(f"nonce:{nonce}", str(int(time.time())), nx=True, ex=self.NONCE_TTL)
results = await pipe.execute()
return results[1] is not None
async def release_nonce(self, nonce: str):
"""Release on verification failure."""
await self.redis.delete(f"nonce:pending:{nonce}")
Research Finding - Fail Closed:
if not self.redis:
raise NonceServiceUnavailable("Redis required for replay protection")
Step 6: Add Bazaar Metadata Endpoint
File: routers/discovery.py (NEW)
@router.get("/.well-known/x402")
async def get_x402_metadata():
return {
"x402Version": "2",
"name": "sage-defi-oracle",
"endpoints": [...],
"networks": [...]
}
5. Critical Research Findings (Detailed)
Security Review (security-sentinel)
-
Chain detection is bypassable - Any JSON with "signature" key routes to EVM, any base64 to Solana. Fix: use explicit network field.
-
Local nonce cache has no TTL - Memory exhaustion DoS + replay after restart. Fix: OrderedDict with max size + TTL.
-
Nonce format not validated - Empty/malformed nonces pass through. Fix: regex validation.
Data Integrity Review (data-integrity-guardian)
-
Nonce consumed before verification - If verification fails, nonce is burned, user can't retry. Fix: two-phase reserve/commit/release.
-
In-memory fallback is risky - Replay attacks possible across instances. Fix: fail closed for nonces.
TypeScript Review (kieran-typescript-reviewer)
-
Type-unsafe unknown with forced assertions - Runtime crashes possible. Fix: Zod schemas.
-
Missing CAIP-2 type system - Invalid chains pass compile-time checks. Fix: discriminated unions.
-
Wallet validation is Solana-only - EVM wallets fail. Fix: chain-aware validation.
Architecture Review (architecture-strategist)
-
CDP Facilitator is SPOF - Both chains route through single point. Fix: circuit breaker per chain.
-
Error boundaries undefined - Chain-specific errors not normalized. Fix: error taxonomy.
6. Success Criteria
7. Design Decisions (Confirmed)
- Solana via CDP Facilitator: ✅ Confirmed available. CDP supports both Base and Solana with fee-free USDC payments.
- EVM chains beyond Base: ❌ No. Base only for Phase 1. Rationale: Base is 28% of volume, Solana is 72%. Other EVM chains have minimal x402 volume. Can add later if demand exists.
- Traffic ratio: ~30% EVM (Base) / ~70% Solana. Solana flipped Base in Dec 2025 due to 400ms finality. Most agent builders are on Solana now.
8. Reference Links
x402 V2 Migration Plan (Deepened)
Created: January 1, 2026
Deepened: January 1, 2026 via
/deepen-planAuthor: SAGE
Deadline: January 14, 2026 (Cronos Hackathon Phase 1)
Enhancement Summary (from /deepen-plan)
Review Agents Used: security-sentinel, kieran-python-reviewer, kieran-typescript-reviewer, architecture-strategist, data-integrity-guardian, best-practices-researcher
Key Improvements:
^[a-zA-Z0-9_-]{16,64}$unknowntypesExecutive Summary
Migrate the existing SAGE x402 DeFi API from x402 V1 to V2. The core API (12 exchange integrations, arbitrage analysis, caching, alerts) is production-ready and unchanged. This migration focuses solely on the payment verification layer.
Scope: ~50-100 lines of code changes
Risk: Low (core API untouched)
Outcome: Multi-chain x402 V2 API discoverable on Bazaar
1. Context & Background
1.1 What is x402?
x402 is an open protocol that operationalizes HTTP 402 "Payment Required" for machine-to-machine micropayments. Instead of API keys or subscriptions, agents pay per-request using stablecoins (USDC).
V1 Flow (current):
V2 Flow (target):
V2 Key Changes:
PAYMENT-SIGNATUREandPAYMENT-REQUIRED(replacesX-Payment)@x402/evm,@x402/svm)1.2 Why Migrate Now?
X-Paymentheader no longer works with V2 clients2. Current State Analysis
2.1 Architecture Overview
2.2 What's Working (Don't Touch)
exchanges/*.pyservices/analysis_service.pyservices/cache_service.pyservices/rate_limiter.py3. Target State
3.1 V2 Architecture
3.2 V2 402 Response Schema
{ "x402Version": "2", "accepts": [ { "scheme": "exact", "network": "eip155:8453", "maxAmountRequired": "10000", "resource": "/api/funding-rates", "payTo": "0xae3cDa2A4c50782868EAD3be4bFAedd96D07c17e", "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, { "scheme": "exact", "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", "maxAmountRequired": "10000", "resource": "/api/funding-rates", "payTo": "<solana-wallet-address>", "token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" } ] }4. Migration Steps (Updated with Research)
Step 1: Update TypeScript SDK
File:
packages/x402-payment/package.json{ "dependencies": { "@x402/core": "^2.0.0", "@x402/evm": "^2.1.0", "@x402/svm": "^2.0.0", "@coinbase/x402": "^2.0.0", "zod": "^3.22.0" } }Research Finding: Add CAIP-2 type system:
Research Finding: Add Zod validation:
Step 2: Update Python Config
File:
config.pyStep 3: Update 402 Response
File:
utils.pyx402Versionfrom "1" to "2"PAYMENT-REQUIREDheaderStep 4: Update Payment Verification (CRITICAL FIXES)
File:
routers/funding_rates.pyResearch Finding - Chain Detection Fix:
Research Finding - Error Handling Fix:
Step 5: Add Nonce Service (CRITICAL - NEW)
File:
services/nonce_service.pyResearch Finding - Two-Phase Pattern:
Research Finding - Fail Closed:
Step 6: Add Bazaar Metadata Endpoint
File:
routers/discovery.py(NEW)5. Critical Research Findings (Detailed)
Security Review (security-sentinel)
Chain detection is bypassable - Any JSON with "signature" key routes to EVM, any base64 to Solana. Fix: use explicit
networkfield.Local nonce cache has no TTL - Memory exhaustion DoS + replay after restart. Fix:
OrderedDictwith max size + TTL.Nonce format not validated - Empty/malformed nonces pass through. Fix: regex validation.
Data Integrity Review (data-integrity-guardian)
Nonce consumed before verification - If verification fails, nonce is burned, user can't retry. Fix: two-phase reserve/commit/release.
In-memory fallback is risky - Replay attacks possible across instances. Fix: fail closed for nonces.
TypeScript Review (kieran-typescript-reviewer)
Type-unsafe
unknownwith forced assertions - Runtime crashes possible. Fix: Zod schemas.Missing CAIP-2 type system - Invalid chains pass compile-time checks. Fix: discriminated unions.
Wallet validation is Solana-only - EVM wallets fail. Fix: chain-aware validation.
Architecture Review (architecture-strategist)
CDP Facilitator is SPOF - Both chains route through single point. Fix: circuit breaker per chain.
Error boundaries undefined - Chain-specific errors not normalized. Fix: error taxonomy.
6. Success Criteria
7. Design Decisions (Confirmed)
8. Reference Links