feat(web): add JSON receipt export for paid queries (#52)#100
feat(web): add JSON receipt export for paid queries (#52)#100D-Lord-15 wants to merge 2 commits into
Conversation
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 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
|
@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! 🚀 |
|
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/webResults: 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 |
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
query402ReceiptSchema(zod) with literalschema: \"query402.receipt.v1\"discriminator inpackages/shared/src/schemas.ts.buildReceipt+serializeReceipt+downloadReceipt+copyReceiptToClipboardhelpers inapps/web/src/lib/receipt.ts(new file).copyReceiptToClipboardfalls back to a download when the Clipboard API is unavailable.apps/web/src/pages/ControlDeckPage.tsx) shows a receipt card withExport JSON receiptandCopy JSONbuttons (bothdisabled={!receipt}before the first query).apps/api/src/lib/idempotency/x402.tsbuildPaidResponsenow spreadsnetwork/payTo/facilitatorUrlinto the bare{kind,status}settlement-pending fallback, andapps/web/src/types.tsPublicPaymentEvidencealigns to that wire shape.paymentResponseHeaderfield on the webPaidQueryResponse.paymentwith the real public-safe evidence shape the API actually returns.Tests
apps/web/src/lib/receipt.test.ts(node:test, matchingwallet/machine.test.ts) locks in zod round-trip, null normalisations, the absence of payer leak, the defensive path, and a stable filename.Closes #52