Skip to content

fix(paywall/evm): route Mezo users to mezo.org/feature/borrow faucet link#3

Closed
ryanRfox wants to merge 1 commit intocandidate/2.10.0-mezo.5from
candidate/2.10.0-mezo.7
Closed

fix(paywall/evm): route Mezo users to mezo.org/feature/borrow faucet link#3
ryanRfox wants to merge 1 commit intocandidate/2.10.0-mezo.5from
candidate/2.10.0-mezo.7

Conversation

@ryanRfox
Copy link
Copy Markdown
Owner

Summary

Fix the hardcoded testnet "Need {tokenName} on {chainName}? Get some here" link on the EVM paywall. It was pointing to https://faucet.circle.com/ — Circle's USDC faucet — which is a dead-end for Mezo users (paying in Mezo USD, not USDC, on a non-Circle chain).

Reported by docscrew from novice-tester feedback on the x402 quickstart. Tracked as hq-eb54v. Mayor routed for tiny-PR + release ship path as v2.10.0-mezo.7.

What changed

  • typescript/packages/http/paywall/src/evm/EvmPaywall.tsx — added a chain-conditional faucetUrl:
    • Mezo Testnet (31611) or Mezo Mainnet (31612) → https://mezo.org/feature/borrow (canonical MUSD mint flow)
    • All other chains → https://faucet.circle.com/ (correct for Base Sepolia USDC, Arbitrum Sepolia USDC, etc.)
  • Regenerated EVM paywall bundle (via pnpm run build:paywall): src/evm/gen/template.ts, go/http/evm_paywall_template.go, python/x402/http/paywall/evm_paywall_template.py.

Scope

Intentionally tight: EVM only. SVM (Solana) and AVM (Algorand) keep faucet.circle.com — that IS the correct faucet for Solana Devnet USDC and Algorand Testnet USDC, so no change warranted there.

Why chain-conditional and not metadata-driven

This is the short-term Mezo-preview fix so we can ship v2.10.0-mezo.7 today (novice testers are hitting the dead-end now). The broader metadata-driven fix (drive the faucet URL from payment-requirement asset/extra metadata so any chain/token can ship its own pointer) is being handled separately by @x402/fox via an upstream PR to x402-foundation/x402, coordinated with x402-foundation#1971.

Ship plan after merge

  1. gh release create v2.10.0-mezo.7 on vativ/x402-mezo-preview with tgz artifacts
  2. Pin humor.vativ.io to 2.10.0-mezo.7 and redeploy
  3. Browser-verify the "Get some here" link resolves to mezo.org/feature/borrow

Test plan

  • Manual verify on live https://humor.vativ.io/joke after mezo.7 deploy — "Get some here" href = https://mezo.org/feature/borrow
  • Smoke-test on a non-Mezo testnet (Base Sepolia or similar) to confirm the link still falls back to faucet.circle.com (no regression for canonical-preview consumers)

…link

The testnet-only "Need {tokenName} on {chainName}? Get some here" link was
hardcoded to https://faucet.circle.com/, which is Circle's USDC faucet for
Circle-native chains. On Mezo (chainId 31611 testnet, 31612 mainnet), users
are paying in Mezo USD and the Circle faucet is a dead-end.

Make the link conditional on chain: Mezo chains route to the canonical MUSD
mint flow at https://mezo.org/feature/borrow; all other chains continue to
use faucet.circle.com (correct for Base Sepolia USDC, Arbitrum Sepolia USDC,
etc., which the upstream paywall is designed for).

Regenerates the EVM paywall bundle (TS/Go/Python templates).

Reported by docscrew from novice-tester feedback on the x402 quickstart.
Ships on 2.10.0-mezo.7 for the Mezo hackathon preview. After this lands,
queue an upstream PR to x402-foundation/x402 (broader fix needed there —
should drive the URL from chain/token metadata, not a hardcoded list).
@ryanRfox
Copy link
Copy Markdown
Owner Author

@ryanRfox ready for review + merge. Per mayor's ship plan (hq-wisp-tbblud): tiny PR first, then release v2.10.0-mezo.7, then humor.vativ.io redeploy + browser-verify. x402/fox is separately owning the upstream metadata-driven fix.

@ryanRfox
Copy link
Copy Markdown
Owner Author

Code-review from x402/fox (hq-c1hfz): LGTM for mezo.7. Surgical, no regressions. Ship it.

Verified:

  • Bundles regen consistent across TS/Go/Py: mezo.org/feature/borrow, faucet.circle.com, and chain IDs 31611/31612 each appear in all three generated templates.
  • EVM-only scope correct — SVM (Solana Devnet USDC) and AVM (Algorand Testnet USDC) correctly remain on faucet.circle.com.
  • isTestnetNetwork(network) + {testnet && ...} gate preserved; non-testnet renders unchanged.

Minor, cosmetic — not blocking mezo.7:

  • The chainId === 31612 (Mezo mainnet) branch in the faucetUrl ternary is effectively dead code today: the link only renders under {testnet && ...}, and viem's testnet property is false for mainnet chain IDs. Defensive / future-proof. The upstream metadata-driven fix I'm drafting drops the testnet gate and replaces the ternary with a registry lookup, so the dead-code concern evaporates there. No action needed on this PR.

Upstream track: design doc in progress at .beads/drafts/paywall-url-metadata-design.md (add faucetUrl?: string to ExactDefaultAssetInfo in DEFAULT_STABLECOINS, paywall reads from registry, drop hardcoded URL + testnet gate). Will NOT open the upstream PR until (1) humor.vativ.io is verified on mezo.7 and (2) Ryan signs off on the metadata approach.

@ryanRfox
Copy link
Copy Markdown
Owner Author

Code review from @x402/fox: LGTM, ship it (couldn't self-approve via button — same GH user). One cosmetic note they flagged and are aware of: the chainId === 31612 branch is dead code under the current {testnet && ...} gate (Mezo mainnet never renders the faucet prompt). Leaving as-is for forward-proofing; it naturally goes away in the upstream metadata-driven fix x402/fox is carrying separately.

@ryanRfox cleared for merge whenever you're ready.

@ryanRfox
Copy link
Copy Markdown
Owner Author

Rejecting this approach. x402 is an open standard; the paywall should stay chain-neutral. Hardcoding Mezo chain IDs (31611/31612) into EvmPaywall.tsx privileges one consumer over others and doesn't scale.

Correct design: the "Need {token}" faucet URL is a configurable variable in the paywall's SDK config. The paywall defines a default (e.g. faucet.circle.com for current USDC behavior — no regression) and the dev overrides it at paywall construction time. The paywall displays the configured variable, never a hardcoded URL.

Not merging. x402/fox will redesign along these lines. Mezo's humor app adopts the override once the new SDK pattern lands.

@ryanRfox
Copy link
Copy Markdown
Owner Author

Closing per @ryanRfox's rejection + mayor's ship redirect (hq-wisp-ufqxf6): chain-ID conditionals are the wrong shape for an open chain-neutral standard. Paywall API should expose faucetUrl as a paywall-construction-time config override (default: faucet.circle.com preserved for USDC consumers). That redesign is now owned by @x402/fox and will land as a minor-version paywall release; humor will then pass faucetUrl: 'https://mezo.org/feature/borrow' at init time. Leaving candidate/2.10.0-mezo.7 branch in place for now; will delete after the new override-capable paywall ships.

@ryanRfox ryanRfox closed this Apr 22, 2026
@ryanRfox ryanRfox deleted the candidate/2.10.0-mezo.7 branch April 22, 2026 21:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant