Skip to content

x402 payment surfaces in the GUI: authorization card, per-asset budget gauge, paid-domain activity rows #207

Description

@hellno

Standalone; sequenced after #34 (x402 phase 2). Composes with #198 (origin attribution, shipped) and #187 (transaction detail — NOT yet shipped).

Why: the $5-a-day story is only believable if you can watch the budget drain and see exactly what each site collected — in the same review language as every other request.

Corrected 2026-07-10 (codebase re-verified): this is L, not M — the shared Review body is tx/wei-shaped and a payment authorization is a gasless off-chain signature, so it needs a genuine non-tx body variant, not an origin_header tweak. Details below. Also: the #187 dependency is on an unshipped issue, but only the detail-VIEW beat needs it.

Problem

#34 is daemon/policy/MCP-scoped. Without GUI work the $5/day demo is headless: there is no review-card shape for a payment authorization (it is an off-chain signature, not a transaction — "you are authorizing site X to collect $0.05 in USDC, valid until T"), the budget gauge assumes wei/ETH, and Activity has no payment row carrying the paid domain as origin.

Scope (with verified constraints)

  • Payment authorization review card through the shared Review (E5) + widgets vocabulary. Constraint: the shared body is tx-coupled — review_authority_row (commit_view.rs:335) hard-uses format_amount(..., 18, 4) + authority_for(kind, value: U256), and there are gas/network-fee rows. A payment auth is an off-chain EIP-3009 signature with a validity window and no gas, so "route through the ONE review" requires a new non-tx body variant (token units, validAfter/validBefore, budget line, no gas). Payee domain is the origin — a third origin flavor next to dapp and agent (the origin_header rail extends trivially; the body does not).
  • Per-asset budget gauge fed by x402 phase 2: exact/EIP-3009 payments on the Ethereum reference path, fully local demo loop #34's token_budgets. Constraint: the budget_gauge widget itself (widgets.rs:183) is unit-agnostic (takes frac: f32 + free-form strings), but every current caller (welcome.rs:363-377, agent_view.rs:185) formats wei at 18 decimals, and the Policy wire exposes only daily_cap_wei/spent_today_wei. A per-asset USDC/$ gauge needs x402 phase 2: exact/EIP-3009 payments on the Ethereum reference path, fully local demo loop #34's new wire fields + a new $-framing 6-decimal caller. Spent-today + rollover time, honest "—" when unknown (E4 rules).
  • Activity rows + detail view for payments — including the honest intermediate state: authorization signed, settlement is the facilitator's move (show both, never fabricate a "settled" the chain hasn't confirmed). Note: E7 · Transaction detail view #187 is unshipped (no transaction_view.rs, no Surface variant — Surface = Home/Receive/Send/Shield/Activity/Swap/Settings). Only the detail-VIEW beat needs E7 · Transaction detail view #187; the Activity rows can ship without it.
  • All states per DESIGN.md; no new widget primitives without checking widgets.rs first.

Non-goals

  • MPP session surfaces.
  • Fiat price feeds beyond the fixed USDC $1 framing.

Depends on

#34 (token_budgets on the PolicyGet wire); partially #187 for the detail view only.

Acceptance

  1. On the fork demo: screenshots of the card, the gauge at partial spend, and a payment row in Activity.
  2. DoD green; before/after screenshots (GUI change); every new action ⌘K-reachable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions