Skip to content

Payments X402

payments_x402 — x402 HTTP 402 agent payment protocol for G6.

Cluster: Uncategorised | Type: component | MCP Tools: 14

Overview

Implements the HTTP 402 agent payment protocol for G6, enabling autonomous agents to make and manage cryptocurrency payments. Provides a full payment pipeline: policy evaluation (spending limits, token/chain allowlists, anti-structuring detection), human-in-the-loop (HITL) approval gates, wallet signing (with dry-run adapter for testing), and immutable audit logging.

Enforces safety-first defaults including mandatory HITL for first transactions and high-value payments.

When to use:

  • Enabling autonomous agents to pay for external API calls or compute resources
  • Enforcing spending policy with HITL approval gates before any real payment
  • Auditing payment history with immutable, tamper-evident logs

Example:

from mvp.payments_x402 import PaymentsX402Block, PaymentsX402Input

block = PaymentsX402Block()
result = block.infer(PaymentsX402Input(
    operation="pay",
    amount_wei=1000,
    token="USDC",
    chain="base",
    payee="0xrecipient...",
))
# result.value -> PaymentsX402Output with status, tx_hash, policy_decision

Dry-run by default

The block ships with DryRunWalletAdapter — no real transactions occur unless a production wallet adapter is injected. First-ever and high-value payments always require HITL approval regardless of policy.

Production wallet validation required

Passing the payments_x402 tests proves the policy, HITL, idempotency, retry, and audit paths for the component. It does not prove the paid-customer payment path is production-ready. Before enabling x402 payments for launch pilots or paid users, inject the real production WalletAdapter and run a staging end-to-end test that covers policy evaluation, HITL approval, approved payment execution, idempotent retry after client or network failure, wallet/provider failure retry, audit export, and balance checks. Keep DryRunWalletAdapter in development and demos only.

Caveats and known limitations:

  • The default wallet adapter is dry-run only; real transactions require an injected production WalletAdapter. A simulated settlement is machine-readable via completion_state="qualified-draft" and audit_fields.dry_run=True / evidence.dry_run=True (not just the 0xdryrun_ hash prefix).
  • The real wallet/payment-provider path must pass staging E2E before paid-user launch
  • Audit records include full payment details including addresses — consider PII and compliance implications
  • No explicit rate limiting on approval requests — an agent could spam the HITL queue
  • Modify/delete audit operations are blocked at the protocol level (returns error, never executes)
  • verify_facilitator is a string allowlist check only (it compares the facilitator against facilitator_allowlist); it is not cryptographic facilitator attestation.
  • KYC is declared but not enforced: kyc_threshold_wei exists on SpendingPolicy but is currently inert. Enforcing it would tighten the HITL approval gate and is a human-reviewed policy decision (see the remediation plan), not an automated capability.
  • The MCP surface (payments_x402_mcp/) is narrowed: read-only discovery/query/verify ops are open, HITL approval-lifecycle ops require an operator-authority gate, and pay is never exposed (no settlement over MCP without a certified real wallet).

Works well with: token_budget, work_loop, align_csf

Public API

AuditStore

Append-only SQLite audit trail for payment transactions.

Constructor:

Parameter Type Default
db_path str ':memory:'

Methods:

record(fields: dict[str, Any]) -> str

Insert an audit record and return the row id as a string.

query(filters: dict[str, Any], limit: int = 100) -> list[dict[str, Any]]

SELECT records matching filters (equality on each key).

approval_history() -> list[dict[str, Any]]

Return every row carrying an approval_token, oldest first.

export(payer: str, date_range: dict[str, str] | None = None, format: str = 'json') -> list[dict[str, Any]]

Export audit records for a given payer, optionally filtered by date range.

check_idempotency(key: str) -> dict[str, Any] | None

Return the existing record if idempotency_key matches, else None.

ApprovalStatus(Enum)

ApprovalRecord

Mutable record tracking a single approval request.

Field Type Default
token str required
payer str required
payee str required
amount_wei str required
reason str required
status ApprovalStatus required
created_at str required
token_name str ''
chain str ''
facilitator str ''
nonce int 0
idempotency_key str ''
approver str ''
resolution_reason str ''
conditions dict field(default_factory=dict)
payer_attested str ''
payer_attested_user str ''

HITLGate

Human-in-the-loop gate that mediates payment approvals.

Methods:

restore_pending(records: Iterable[ApprovalRecord]) -> int

Seed in-memory state with reconstructed pending approvals.

create_approval(payer: str, payee: str, amount_wei: str, reason: str, token_name: str = '', chain: str = '', facilitator: str = '', nonce: int = 0, idempotency_key: str = '', payer_attested: str = '', payer_attested_user: str = '') -> str

Create a new pending approval and return its token.

approve(token: str, approver: str, conditions: dict | None = None, approver_user: str = '') -> Result[ApprovalRecord]

Approve a pending request.

reject(token: str, approver: str, reason: str = '') -> Result[ApprovalRecord]

Reject a pending request.

cancel(token: str, requester: str) -> Result[ApprovalRecord]

Cancel a pending request.

complete(token: str) -> Result[ApprovalRecord]

Mark an approved request as completed after successful signing.

check_status(token: str, current_time: str | None = None, timeout_seconds: int = 300) -> Result[ApprovalRecord]

Return the current status, marking expired if timed out.

get_pending(payer: str) -> list[ApprovalRecord]

Return all pending records for payer.

bulk_approve(tokens: list[str], approver: str, approver_user: str = '') -> Result[list[ApprovalRecord]]

Approve every token in tokens atomically.

PaymentsX402Block(AIBlock[PaymentsX402Input, PaymentsX402Output, None])

AIBlock orchestrating x402 payment flow.

Methods:

infer(data: PaymentsX402Input) -> Result[PaymentsX402Output]

process(inp: PaymentsX402Input) -> Result[PaymentsX402Output]

PolicyDecision(Enum)

PolicyResult

Field Type Default
decision PolicyDecision required
reason str ''
security_flag str ''
hitl_reason str ''

PolicyEngine

Constructor:

Parameter Type Default
policy SpendingPolicy required

Methods:

evaluate(inp: PaymentsX402Input, context: dict | None = None, commit: bool = True) -> PolicyResult

record_approved(inp: PaymentsX402Input) -> None

Commit spend/nonce bookkeeping after a payment is actually signed.

PaymentOperation(Enum)

SpendingPolicy

Field Type Default
enabled bool False
daily_limit_wei int 100000000
weekly_limit_wei int 500000000
monthly_limit_wei int 2000000000
per_tx_limit_wei int 50000000
auto_approve_threshold_wei int 0
allowed_tokens list[str] field(default_factory=lambda: ['USDC'])
allowed_chains list[str] field(default_factory=lambda: ['base'])
facilitator_allowlist list[str] field(default_factory=lambda: ['0xCoinbaseFacilitator'])
payee_denylist list[str] field(default_factory=list)
payer_denylist list[str] field(default_factory=list)
first_tx_requires_hitl bool True
hitl_threshold_wei int 70000000
hitl_limit_threshold_pct int 80
max_nonce_gap int 10
tx_per_minute_limit int 10
approval_rate_limit int 5
approval_rate_window_sec int 60
max_amount_wei str _UINT256_MAX
escalation_threshold_wei int 100000000
tax_reportable_threshold_wei int 600000000
reporting_threshold_wei int 10000000000
kyc_threshold_wei int 1000000000
structuring_detection bool True

X402Header

Field Type Default
amount str required
token str required
chain str required
facilitator str required

PaymentsX402Input

Field Type Default
operation PaymentOperation required
amount_wei str '0'
token str 'USDC'
chain str 'base'
payee str ''
payer str ''
facilitator str ''
nonce int 0
x402_header X402Header \| None None
memo str ''
idempotency_key str ''
approval_token str ''
approver str ''
reason str ''
conditions dict field(default_factory=dict)
metadata dict field(default_factory=dict)
payer_attested str ''
payer_attested_user str ''
approver_user str ''

PaymentsX402Output

Field Type Default
status str required
policy_decision str required
block_reason str ''
tx_hash str ''
approval_token str ''
hitl_reason str ''
security_flag str ''
audit_fields dict field(default_factory=dict)
completion_state str 'qualified-draft'
warning_card dict \| None None
evidence dict field(default_factory=dict)
request_id str ''
task_id str ''
run_id str ''

WalletAdapter(Protocol)

Signing interface for x402 payment transactions.

Methods:

sign_payment(payee: str, amount_wei: str, token: str, chain: str, nonce: int) -> Result[str]

Sign a payment and return the transaction hash.

get_balance(token: str, chain: str) -> Result[str]

Return the balance in wei for the given token on chain.

DryRunWalletAdapter

Test / dry-run wallet that NEVER makes real transactions.

Methods:

sign_payment(payee: str, amount_wei: str, token: str, chain: str, nonce: int) -> Result[str]

get_balance(token: str, chain: str) -> Result[str]

X402ParseResult

Parsed representation of an x402 payment header.

Field Type Default
valid bool required
amount str required
token str required
chain str required
facilitator str required
error str field(default='')

Functions

parse_x402_header(header: dict | None) -> X402ParseResult

Parse a raw x402 header dict into an X402ParseResult.

validate_request_matches_header(amount_wei: str, token: str, chain: str, facilitator: str, header: X402ParseResult) -> Result[None]

Check that the caller's request parameters match the parsed header.

MCP Tools

Operation Source
check_balance payments_x402_mcp
query_history payments_x402_mcp
query_limits payments_x402_mcp
get_policy payments_x402_mcp
get_receipt payments_x402_mcp
verify_facilitator payments_x402_mcp
check_approval_status payments_x402_mcp
get_pending_approvals payments_x402_mcp
export_audit payments_x402_mcp
describe payments_x402_mcp
approve_payment payments_x402_mcp
reject_payment payments_x402_mcp
cancel_payment payments_x402_mcp
bulk_approve payments_x402_mcp