Skip to content

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

Open
D-Lord-15 wants to merge 2 commits 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 2 commits 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

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
@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.

Resolves merge conflicts introduced by upstream/main landing
sponsorship preview + trace/proof-link UI while
feat/issue-52-receipt-export was open.

Resolution summary:
- packages/shared/src/schemas.ts: kept upstream sponsorshipPreviewRequestSchema /
  sponsorshipPreviewResponseSchema and appended query402ReceiptSchema plus its
  receipt-payment-mode / status / evidence-kind enums (24/24 shared tests pass).
- apps/web/src/types.ts: dropped the local PublicPaymentEvidence interface and
  adopted upstream PaymentProofLinks + PaymentEvidenceSummary + PaidQueryResponse.
- apps/web/src/styles.css: kept receipt-card / receipt-btn / receipt-toast /
  receipt-tx-pill rules and appended upstream .trace-box .proof-links and
  .feed-row .proof-link rules. Removed an orphan close brace left behind by the
  Python merge substitution; added a .trace-box .trace-box-dev-tag rule so the
  new developer-audit caption is visually distinct from the secret-bearing
  payment-response / network lines.
- apps/web/src/pages/ControlDeckPage.tsx: unified the Lucide-react import block
  to a single list and placed the receipt card as a sibling of the new
  trace-box, ahead of item-stack. Mitigated the secret-leak hazard by inserting
  a "Developer audit view - do not paste publicly." caption at the top of the
  trace-box before the raw paymentResponseHeader / stellar.expert proof-link.

Receipt test fixtures were migrated to satisfy the new
PaymentEvidenceSummary.required.proofLinks field plus the new
PaidQueryResponse.payment.paymentResponseHeader requirement. Receipt builder
itself does not read payer/proofLinks, so the exported JSON still strips
wallet identities and explorer URLs.

Validation after resolution:
- typecheck: pass (all four workspaces)
- vite build: pass (apps/web production bundle compiles)
- vitest shared: 24 / 24
- vitest api: 123 / 123
- vitest agent-client: 9 / 9
- no leftover <<<<<<< / >>>>>>> conflict markers

Refs emrekayat#52
@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.

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