x402lint
Original:🇺🇸 English
Translated
Validate and create x402 payment endpoint responses (HTTP 402 Payment Required). Use when the user asks to: (1) validate an x402 config or 402 response, (2) create/generate an x402 payment config, (3) build an HTTP 402 endpoint that returns payment requirements, (4) debug why an x402 config is invalid, (5) convert between x402 v1 and v2 formats, (6) check EVM/Solana addresses for x402, or (7) work with CAIP-2 network identifiers for payment configs. Triggers on keywords: x402, 402 payment, payment-required header, paywall config, CAIP-2 payment.
6installs
Sourcerawgroundbeef/x402lint
Added on
NPX Install
npx skill4agent add rawgroundbeef/x402lint x402lintTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →x402lint
Validate and create x402 payment configurations. The x402 protocol defines how HTTP 402 responses communicate payment requirements to clients.
For full protocol details, field rules, registries, and error codes, read references/protocol-spec.md.
Workflow
- Determine task type: Validating an existing config? -> Follow "Validation" below Creating a new config? -> Follow "Creation" below Debugging a failing config? -> Follow "Debugging" below
Validation
Validate using the SDK in the project at .
x402lintpackages/x402lint/typescript
import { check } from './packages/x402lint/src/index'
const result = check({
body: configObject, // or parse from header
headers: { 'payment-required': base64String }
})
// result.valid - boolean
// result.errors - ValidationIssue[] (blocking)
// result.warnings - ValidationIssue[] (non-blocking)
// result.normalized - canonical v2 shape
// result.summary - display-ready per-accept entries with registry dataFor strict mode (warnings become errors):
check(response, { strict: true })Also available: for raw config objects, for parsing HTTP responses.
validate(input)extractConfig(response)Creation
When creating an x402 config, always produce v2 format. Template:
json
{
"x402Version": 2,
"accepts": [
{
"scheme": "exact",
"network": "<CAIP-2 identifier>",
"amount": "<atomic units as string>",
"asset": "<token contract address>",
"payTo": "<recipient address with proper checksum>",
"maxTimeoutSeconds": 300
}
],
"resource": {
"url": "<the protected resource URL>",
"method": "GET"
}
}Critical rules when generating configs
- : Always a string of digits in atomic units (e.g.,
amountfor 1 USDC with 6 decimals). Never use decimal notation."1000000" - : Always CAIP-2 format (
network). Use registry from protocol-spec.md. Never use simple names likenamespace:reference."base" - EVM /
payTo: Use EIP-55 checksummed addresses (mixed-case). All-lowercase is valid but not recommended.asset - Solana /
payTo: Use base58 addresses (32-44 characters).asset - : Always include; positive integer. 300 is a safe default.
maxTimeoutSeconds - : Always include with at least a
resource.url
Common network + asset combinations
Base (USDC):
json
{ "network": "eip155:8453", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }Base Sepolia testnet (USDC):
json
{ "network": "eip155:84532", "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e" }Avalanche (USDC):
json
{ "network": "eip155:43114", "asset": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E" }Solana Mainnet (USDC):
json
{ "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", "asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" }HTTP 402 endpoint pattern
typescript
// Express/Node example
app.get('/api/premium', (req, res) => {
// Check for valid payment proof in request...
// If no payment, return 402:
res.status(402).json({
x402Version: 2,
accepts: [{
scheme: "exact",
network: "eip155:8453",
amount: "1000000",
asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
payTo: "0xYourChecksummedAddress",
maxTimeoutSeconds: 300
}],
resource: {
url: "https://yourapi.com/api/premium",
method: "GET"
}
})
})Alternative: deliver via header with base64-encoded JSON body.
Payment-RequiredDebugging
When a config fails validation:
- Run or
check()against the configvalidate() - Inspect -- each has
result.errors,code,field, and optionalmessagefix - Common issues and fixes:
- : Use CAIP-2, e.g.,
INVALID_NETWORK_FORMATnot"eip155:8453""base" - : Must be digit-only string in atomic units, not
INVALID_AMOUNTor"1.5"1000000 - : Fix address casing per EIP-55
BAD_EVM_CHECKSUM - /
MISSING_PAY_TO: Required fields omittedMISSING_ASSET - : Config is v1; normalize to v2 with
LEGACY_FORMATnormalize()
- Apply the suggestion from each issue when available
fix - Re-validate after fixes