Skip to content

feat(web): add JSON receipt export for paid queries (#52)#100

Open
D-Lord-15 wants to merge 1 commit into
emrekayat:mainfrom
D-Lord-15:feat/issue-52-receipt-export
Open

feat(web): add JSON receipt export for paid queries (#52)#100
D-Lord-15 wants to merge 1 commit into
emrekayat:mainfrom
D-Lord-15:feat/issue-52-receipt-export

Conversation

@D-Lord-15

Copy link
Copy Markdown

What

Adds an Export receipt action to the Control Deck result panel on the web app. After a successful paid (wallet / sponsored) or demo query, reviewers can download a JSON file or copy a paste-ready string containing the public-safe payment trail: query mode, provider id/name, quoted price, trace id, result timestamp, payment mode (wallet / sponsored / demo), payment status, payment evidence kind, and the on-chain transaction hash when available.

Belt-and-suspenders safety: the exported payload never contains the payer wallet, the facilitator result (which could include signed Soroban auth entries), the raw base64 payment header, the grant signature, or any facilitator API key / wallet secret. Missing payment fields render as null (not "not_available") so the JSON stays diff-friendly in SCF issue threads.

How

  • New query402ReceiptSchema (zod) with literal schema: \"query402.receipt.v1\" discriminator in packages/shared/src/schemas.ts.
  • Pure buildReceipt + serializeReceipt + downloadReceipt + copyReceiptToClipboard helpers in apps/web/src/lib/receipt.ts (new file). copyReceiptToClipboard falls back to a download when the Clipboard API is unavailable.
  • Control Deck (apps/web/src/pages/ControlDeckPage.tsx) shows a receipt card with Export JSON receipt and Copy JSON buttons (both disabled={!receipt} before the first query).
  • API contract alignment: apps/api/src/lib/idempotency/x402.ts buildPaidResponse now spreads network / payTo / facilitatorUrl into the bare {kind,status} settlement-pending fallback, and apps/web/src/types.ts PublicPaymentEvidence aligns to that wire shape.
  • Replaced the unused paymentResponseHeader field on the web PaidQueryResponse.payment with the real public-safe evidence shape the API actually returns.

Tests

  • shared: 24 / 24 vitest pass (new describe blocks for the receipt schemas).
  • api: 83 / 83 vitest pass.
  • agent-client: 9 / 9 vitest pass.
  • web typecheck + production build pass (Vite + tsc).
  • New web file apps/web/src/lib/receipt.test.ts (node:test, matching wallet/machine.test.ts) locks in zod round-trip, null normalisations, the absence of payer leak, the defensive path, and a stable filename.

Closes #52

@vercel

vercel Bot commented Jun 30, 2026

Copy link
Copy Markdown

@D-Lord-15 is attempting to deploy a commit to the emrekayat's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jun 30, 2026

Copy link
Copy Markdown

@D-Lord-15 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@emrekayat

Copy link
Copy Markdown
Owner

Thanks for the PR. I rechecked the merge ref from the maintainer account. The relevant checks pass:

git diff --check main...pr-100-merge
npm run test --workspace @query402/shared
npm run typecheck --workspace @query402/api
npm run typecheck --workspace @query402/web
npm run build --workspace @query402/web

Results: shared schema tests pass (24), API typecheck passes, web typecheck passes, and web build passes. The receipt payload intentionally omits raw payment headers, payer wallet, proof links, facilitator responses, grant/signature data, and secret material.

I tried to merge, but GitHub currently reports this branch as conflicting with latest main. Please rebase/merge current main, resolve the conflicts, and push again. Once GitHub can merge it and the same checks stay green, this looks ready.

Add a public-safe JSON receipt export action in the ControlDeck result panel. The exported payload contains no payer wallet, no facilitatorResult, no payment header, no auth entry, and no grant signature. Missing payment fields render as null so receipts stay diff-friendly. New receipt schemas live in packages/shared/src/schemas.ts; buildReceipt/serializeReceipt/downloadReceipt live in apps/web/src/lib/receipt.ts. Closes emrekayat#52
@D-Lord-15 D-Lord-15 force-pushed the feat/issue-52-receipt-export branch from cf316c5 to 59d1024 Compare July 3, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add payment evidence receipt export for paid query results

2 participants