Signature Validation
X402 Protocol implements strict signature and business rule validation for ERC-3009 authorized transfers. This ensures only valid, non-replayable, and authorized payments are settled on-chain.
Validation Process
1. Payload Structure Validation
The backend validates the payload structure using a strict schema (pseudo-code):
payloadSchema = {
from: ethereumAddress,
to: ethereumAddress,
value: string (digits only),
nonce: string (0x-prefixed 64 hex chars),
validAfter: string (digits only),
validBefore: string (digits only),
v: integer (0-255),
r: string (0x-prefixed 64 hex chars),
s: string (0x-prefixed 64 hex chars)
}
2. Business Rule Validation
Amount Validation
- Must be a positive integer
- Cannot exceed the payment link's required amount
- Must match the payment link exactly (no partial/overpayment)
Timestamp Validation
validAftermust be<=current timevalidBeforemust be>current time- Maximum validity window enforced (default: 6 hours)
Address Validation
fromandtomust be valid Ethereum addressestomust match the merchant's wallet address
3. Nonce Validation
Nonces prevent replay attacks. The backend checks:
Pseudo-code:
if (nonce already used for this address) {
throw ValidationError('Nonce already used')
}
4. Signature Verification
The backend reconstructs the EIP-712 domain separator and transfer digest, then recovers the address from the signature:
recoveredAddress = recoverAddress(digest, signature)
if (recoveredAddress.toLowerCase() != payload.from.toLowerCase()) {
throw ValidationError('Invalid signature')
}
Error Types
Validation Errors
INVALID_PAYLOAD_STRUCTURE
{
"error": "INVALID_PAYLOAD_STRUCTURE",
"message": "Payload does not match expected schema",
"details": {
"field": "value",
"issue": "must be positive integer"
}
}
INVALID_SIGNATURE
{
"error": "INVALID_SIGNATURE",
"message": "Signature verification failed",
"details": {
"expected": "0x123...",
"recovered": "0x456..."
}
}
NONCE_ALREADY_USED
{
"error": "NONCE_ALREADY_USED",
"message": "Payment nonce has already been processed",
"details": {
"nonce": "0x789...",
"usedAt": "2024-01-01T12:00:00Z"
}
}
PAYMENT_EXPIRED
{
"error": "PAYMENT_EXPIRED",
"message": "Payment validity period has expired",
"details": {
"validBefore": "1704067200",
"currentTime": "1704067300"
}
}
AMOUNT_EXCEEDS_MAXIMUM
{
"error": "AMOUNT_EXCEEDS_MAXIMUM",
"message": "Payment amount exceeds maximum allowed",
"details": {
"amount": "1000000000",
"maximum": "500000000"
}
}
Security Measures
Rate Limiting & Monitoring
- Per-IP and per-wallet rate limits
- Exponential backoff for repeated failures
- All validation attempts and failures are logged and monitored
Testing Validation
Unit Tests (pseudo-code)
Test: should validate correct ERC-3009 signatures
- create valid payload
- validate(payload) => valid
Test: should reject expired transfers
- create expired payload
- validate(payload) => throws PAYMENT_EXPIRED
Test: should prevent nonce reuse
- create valid payload
- validate(payload) // first use
- validate(payload) => throws NONCE_ALREADY_USED
Integration Tests (pseudo-code)
Test: should process valid payments
- create payment link
- create signed payload for link
- process payment
- expect success and txHash
Performance Considerations
Caching & Optimization
- Domain separator/type hash caching
- Recently used nonces caching
- Batch/parallel validation for high throughput
Future Improvements
Advanced Validation
- Multi-signature and threshold signature support
- Hardware security module integration
Enhanced Security
- Zero-knowledge proofs
- Privacy-preserving validation