Payments — Crypto Floor, Fiat On-Ramp Enhancement
ChainRender lets developers add payments to their apps with the same discipline as everything else: the on-chain crypto payment is the floor (trustless, Grade A), and a fiat/card on-ramp is an optional enhancement (a convenience for non-native users, off-chain, honestly graded). ChainRender defines the payment primitive and the honest trust signal; the developer brings their own on-ramp / wallet SDK — ChainRender blesses no processor, the same way it blesses no oracle.
Why not "card payments, fully on-chain"?
A card payment fundamentally needs off-chain trusted parties (card networks, banks, chargebacks, KYC). Those are irreversible-vs-reversible and permissioned-vs-permissionless — the opposite of a blockchain. So a card payment can never be fully on-chain; there is always an off-chain processor. ChainRender does not pretend otherwise. Instead it makes the boundary explicit and honest.
The model: a payment intent with two paths
A payment in a ChainRender app is a declared intent — "the user needs to pay amount of currency to
destination to unlock X" — resolved by one of two paths:
| Path | What it is | Trust grade |
|---|---|---|
| Crypto (the floor) | A declared on-chain action (transfer / pay), signed by the user's wallet, decoded honestly before signing. |
A — Trustless. Fully on-chain, no processor. |
| Fiat on-ramp (the enhancement) | A card/bank payment via an external on-ramp (Stripe, MoonPay, Transak, Coinbase Onramp, etc.) that delivers the crypto / executes the on-chain result. | C / ⚙ — off-chain convenience. Clearly labeled; the app cannot claim this flow is fully on-chain. |
This mirrors ChainRender's floor-vs-enhancement principle exactly: the trustless path is always present and is the default; the convenient off-chain path is optional and fails closed to the floor — if the on-ramp is unavailable, the user can still pay in crypto.
How a developer expresses it
A payment is not a new on-chain node type (the tag vocabulary is a closed on-chain set). It is a pattern built from the existing action model plus an honest capability flag:
- The crypto payment is a
buttonwith a declaredaction: { to, sig: "transfer(address,uint256)" | "pay(...)", value, args }— exactly the declared-action model, decoded by the "you see what you sign" panel. - The fiat on-ramp is an
externalelement (a link/embed to the developer's chosen on-ramp) that carries the existingCLIENT_FETCHcapability — the same off-chain-dependency flagexternalmedia already uses. Because the on-ramp is a client-side, off-chain concern, it needs no new on-chain capability and no change to the immutable grading contract: it reuses the honesty machinery that already exists. An app that presents an on-ramp must declareCLIENT_FETCH; the validator rejects an app that has an off-chain dependency without declaring it (honesty is enforced, not optional).
So a developer adds payments by: (1) a crypto payment action (the floor), and optionally (2) an on-ramp element with
the CLIENT_FETCH capability (the enhancement). Both together give a non-native user a card path while the crypto path
stays trustless.
Design note. The fiat path deliberately reuses
CLIENT_FETCHrather than adding a new capability. The capability bits are mirrored on-chain in the immutable grading contract, so a new bit would be an invasive on-chain change — and it is unnecessary, because an off-chain on-ramp is exactly the kind of client-side off-chain dependencyCLIENT_FETCHalready models. The primitive is a client-side pattern + the existing honesty machinery, not a new on-chain type.
The honest grading (why the ethos holds)
The trust grade tells the truth about which path the user is on:
- A crypto payment with a self-custody wallet → A (Trustless).
- A fiat on-ramp / hosted-wallet path → C or ⚙ — the app discloses the off-chain trust rather than hiding it.
This is the ethos in action: marketing never exceeds what code enforces. An app can offer card payments for onboarding, but it cannot be graded "fully on-chain" for that flow — the user sees the honest grade and knows exactly what they are trusting. The capability flag makes this non-optional: use an on-ramp, declare it, grade drops, truth is told.
Bring your own provider (ChainRender blesses none)
ChainRender defines the intent + the grading, not the provider. The developer chooses:
- On-ramp: Stripe, MoonPay, Transak, Coinbase Onramp, Ramp, or any card→crypto provider.
- Wallet onboarding (for users without a wallet at all): an embedded/smart-wallet SDK (email/social login → an invisible wallet), e.g. via account abstraction (ERC-4337 / EIP-7702). ChainRender's ProvenanceRegistry already verifies smart-account signatures (ERC-1271/6492), so account-abstracted users are first-class.
- Gas: a paymaster can sponsor gas so a non-native user never buys ETH for gas separately.
ChainRender stays provider-neutral: it gives the honest primitive and the honest grade; the developer plugs in the off-chain pieces their users need.
The full non-native onboarding stack (developer-assembled)
Non-native user
├─ email/social login → embedded smart wallet (developer's wallet SDK; off-chain until funded)
├─ payment intent: "Pay $5"
│ ├─ has crypto → on-chain action → Grade A (floor, trustless)
│ └─ no crypto → card on-ramp → Grade C/⚙ (enhancement, declared CLIENT_FETCH)
└─ gas sponsored by paymaster (developer's paymaster; invisible to the user)
The developer declares the intent and the honest capabilities; ChainRender renders it, decodes the crypto action, and grades every path truthfully. The user gets a card path; the on-chain guarantee is preserved for the crypto path and never overstated for the fiat path.
Honest boundaries
- The card/on-ramp path is off-chain and is graded so. ChainRender cannot make a card payment trustless — it can only make the boundary honest.
- ChainRender never custodies funds or processes cards. The crypto action executes on the destination contract; the card payment executes at the developer's chosen processor. ChainRender renders and declares; it is not a PSP.
- The crypto floor is always the default. The fiat path is an enhancement that fails closed to the crypto floor, never the only option — so an app is never dependent on an off-chain processor to function.
Adding a payment in the visual builder
The builder ships a Payment starter that seeds a working payment pattern:
- In the builder, choose the Payment (crypto floor + card on-ramp) starter.
- It creates: an amount input, a "Pay with crypto" button (the on-chain action — the trustless floor), an optional "Pay with card" link (the off-chain on-ramp), and an honest note.
- Wire the crypto action — set the button's
action.toto your payment contract andaction.sigto your pay/transfer method (e.g.pay(uint256)ortransfer(address,uint256)), with the amount as an arg. - Wire the on-ramp — replace the placeholder URL on the "Pay with card" link with your chosen provider's checkout URL (Stripe / MoonPay / Transak / Coinbase Onramp), passing the destination + amount.
- The grade updates automatically: crypto-only stays A (Trustless); adding the card on-ramp makes the app
grade C — because the on-ramp link is tagged
provenance: "external", which the grader recognizes as an off-chain dependency and reflects honestly. You cannot present a card on-ramp and still grade A.
If you drop the card link entirely, the app is a pure crypto payment and grades A. The card path is always optional and always falls back to the crypto floor.
Related
- Actions & Signing — the declared-action model the crypto payment uses.
- Trust Grade — how the honest grade classifies on-chain vs off-chain paths.
- The Floor — the floor-vs-enhancement principle payments follow.