feat(paywall): show a receipt for the settled payment before loading the content - #78
Closed
pedro-pelicioni wants to merge 4 commits into
Closed
feat(paywall): show a receipt for the settled payment before loading the content#78pedro-pelicioni wants to merge 4 commits into
pedro-pelicioni wants to merge 4 commits into
Conversation
`getExplorerTxUrl` maps the CAIP-2 `pubnet` reference onto Stellar Expert's `public`, returns null for anything non-Stellar, and escapes the hash into the path. `truncateHash` keeps both ends so a hash can be compared against an explorer by eye.
Decodes the `PAYMENT-RESPONSE` header on the settled response and times the settlement, then hands both to an optional `onReceipt`. It is awaited, so a caller can hold the hand-off — the paid response usually replaces the whole document, and anything rendered after it is gone before it can be read. Both success paths, the first response and the 402-retry, go through the same helper, each timed from its own submission.
The payer had no way to see what they were charged, which account was paid, or the hash it settled under — the one piece of evidence the payment was real and checkable on-ledger. `examples/simple-paywall` works around this by templating a tx link into its own paid page, which only helps hosts serving HTML they control. Show amount, recipient, hash linked to Stellar Expert, and settlement time, then load the content after the configured delay or as soon as Continue is pressed. The explorer link falls back to the network named in the requirement when the facilitator reports one that is not CAIP-2, rather than dropping the link. A hand-off left pending at unmount is resolved, so the paid content cannot be stranded behind an unresolved promise.
`stellarReceiptDelayMs` on `PaywallConfig` reaches the browser as `window.x402.config.receiptDelayMs`. Defaults to 3000; `0` skips the receipt and restores the previous hand-off-immediately behaviour exactly.
Author
|
Reopened from the Nearx-Labs fork as #82 — same commits, same diff. Closing this one to keep a single thread per change. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(paywall): show a receipt for the settled payment before loading the content
Branch:
feat/paywall-receiptScreenshot:
harness/shots/after-receipt.pngThe gap
On success the paywall calls
onSuccessfulResponseimmediately, and the defaultimplementation in
entry.tsxdoes:The whole document is replaced. The payer never sees what they were charged,
which account was paid, or the hash it settled under — the one piece of evidence
that the payment was real and checkable on-ledger.
examples/simple-paywallworks around this by injecting a{{TX_LINK}}placeholder into its own paid page (
txHashInjector.ts), but that only helpshosts serving HTML they control. Anyone serving JSON, a file, or a page they do
not template gets nothing.
The change
useStellarPaymentdecodes thePAYMENT-RESPONSEheader on the settledresponse and times the settlement, then reports both through a new optional
onReceipt.onReceiptis awaited, so the caller can hold the hand-off. The paywallshows amount, recipient, transaction hash linked to Stellar Expert, and how
long settlement took, then loads the content after
receiptDelayMs(default3000) or as soon as Continue is pressed.
stellarReceiptDelayMsonPaywallConfig.Setting it to
0skips the receipt and restores exactly the previoushand-off-immediately behaviour.
Behaviour change
The 3000ms pause is the one behavioural change in this PR. I think a payer
should see proof of a payment they just authorised, but it is your call —
happy to ship it as
0by default so the receipt is opt-in. Everything elsehere is additive.
Details worth flagging
when the facilitator reports one that is not CAIP-2, rather than dropping the
link.
paid content can never be stranded behind an unresolved promise.
same
completePayment, each timed from its own submission.Tests
12 new cases covering the explorer URL builder (testnet, the
pubnet→publicmapping, missing inputs, non-Stellar networks, and path-escaping a hostile
hash), hash truncation, and duration formatting.
Part of #74.