Skip to content

Potential x402 header mismatch in agentic seller 402 response #36

Description

@chenshj73

Hi, I noticed a possible x402 transport mismatch in the agentic seller Lambda.

In agentic/lambda/seller.js, the /generate_image middleware checks for PAYMENT-SIGNATURE first, with X-PAYMENT as a legacy fallback:

// Check for PAYMENT-SIGNATURE header (x402 v2 standard) or X-PAYMENT (legacy)
const paymentHeader = c.req.header('PAYMENT-SIGNATURE') || c.req.header('X-PAYMENT');

When no payment header is present, it builds a response with x402Version: 1 and returns it as a JSON 402 body:

const x402Response = {
x402Version: 1,
accepts: [paymentRequirements],
error: 'Payment required'
};
console.log('=== 402 RESPONSE ===');
console.log(JSON.stringify(x402Response, null, 2));
return c.json(x402Response, 402);

However, unlike the serverless seller implementation, this response does not set a PAYMENT-REQUIRED response header:

// x402 spec: PAYMENT-REQUIRED header with Base64-encoded requirements
c.header('PAYMENT-REQUIRED', Buffer.from(JSON.stringify(paymentRequirements)).toString('base64'));
return c.json(paymentRequirements, 402);

This seems potentially inconsistent with the rest of the agentic flow and docs, which describe the x402 client receiving the 402, signing, and retrying with PAYMENT-SIGNATURE:

7. **Initial x402 Request:** The agent calls `generate_image` again. The tool finds `auth:true` and creates an x402 HTTP client that signs with the CDP AgentKit wallet through CDP APIs (no private key export). The client sends a POST request to Amazon API Gateway without an `PAYMENT-SIGNATURE` header.
8. **402 Payment Required:** AWS Lambda receives the request and returns `HTTP 402` with payment requirements. The response includes the USDC amount in wei, seller wallet address, USDC contract address, and `EIP-712` domain parameters (name: 'USDC', version: '2', chainId: 84532).
9. **EIP-712 Signature Generation:** The x402 client receives the 402 response and constructs `EIP-712` typed data. It requests a signature from the CDP-managed wallet, base64-encodes the signature payload, and retries the POST request with the signature in the `PAYMENT-SIGNATURE` header.
10. **Payment Verification:** Lambda extracts the payment payload from the `PAYMENT-SIGNATURE` header. Lambda sends the signature to the x402.org facilitator's `/verify` endpoint, which validates the `EIP-712` signature against the USDC contract domain on Base Sepolia.

If the x402 client expects payment requirements from the PAYMENT-REQUIRED response header, it may not be able to automatically handle the 402 response from the agentic endpoint.

Should the agentic /generate_image 402 response also set PAYMENT-REQUIRED, similar to the serverless implementation?

c.header('PAYMENT-REQUIRED', Buffer.from(JSON.stringify(paymentRequirements)).toString('base64'));
return c.json(paymentRequirements, 402);

Or is the agentic path intentionally pinned to a body-based x402 v1 client contract?

I have not tested this against a live deployment; this is based on the current main branch source.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions