Skip to content

[10] feat(checkout): fiat-first cash funding with live on-ramp quotes#803

Merged
chybisov merged 32 commits into
feat/widget-checkoutfrom
checkout/10-cash-fiat-quote-flow
Jul 8, 2026
Merged

[10] feat(checkout): fiat-first cash funding with live on-ramp quotes#803
chybisov merged 32 commits into
feat/widget-checkoutfrom
checkout/10-cash-fiat-quote-flow

Conversation

@tomiiide

Copy link
Copy Markdown
Contributor

Which Linear task is linked to this PR?

EMB-464 — Quote-aware Transak funding: live quote + dynamic fiat currencies

Why was it implemented this way?

This branch builds on checkout/09-wallet-any-route and replaces the faked cash quote (CheckoutFlowCtaButton computing fiatAmount = cryptoAmount × priceUSD, hardcoded USD/EUR/GBP) with the Core API's quote-aware Transak endpoints.

  • Fiat-first input. The cash flow now takes a fiat amount (cashFiatAmount) with presets and currency/payment-method selection driven by /v1/checkout/onramp/fiat-currencies. A debounced /v1/checkout/onramp/quote derives the crypto route amount, fees, and guaranteed minimum, gating the CTA until the quote and route agree.
  • Dynamic currencies. fiatCurrency is no longer a USD/EUR/GBP union; currencies, symbols, and names come from the API and Intl (fiatFormat/currencyToFlag), with the static list kept only as a fallback.
  • Session metadata for reconciliation. fundingSessionId is carried through OnRampSession state, the Transak/Mesh hosts, the checkout CheckoutResult, and the persisted pending record (bumped to v5) so resume/reconciliation can match the provider order.
  • Transak hand-off. A bottom sheet confirms the temporary deposit-address hand-off before launching Transak.

Visual showcase (Screenshots or Videos)

Not included; recommend a playground pass on the cash flow: pick a currency/payment method, type a fiat amount, confirm the receive card shows a live quote (fees + guaranteed minimum) and the CTA enables once the route matches.

Checklist before requesting a review

  • I have performed a self-review and testing of my code.
  • This pull request is focused and addresses a single problem.
  • If this PR modifies the Widget API or adds new features that require documentation, I have updated the documentation in the public-docs repository.

tomiiide added 29 commits June 15, 2026 10:45
Add vitest coverage for the session HTTP client and sessions store.
Rename the page-local StepActionsList to ExecutionStepActionsList to
drop the duplicate component name, and document the Host session
memoization contract.
Drop duplicate ExecutionProgress* components and export the canonical
ExecutionStatusCard/StatusIcon/useExecutionRows stack instead. Also stop
shipping src in the published widget tarball.
Gate the Transak debug logger to development (integrator bundlers
dead-code-strip it from production) and drop the wallet address from
its payload. Read onError/close/cancel/openDepositFlow through latest
refs in the SDK init effect so an unstable callback identity no longer
tears down and remounts the iframe mid-session. Document useMeshBalance
as a non-wired stub that callers must not gate funding on.
Scan all live pending records (not just the connected wallet's key) in
useResumeKey and useIsCheckoutBusy, so a deposit-keyed record stays
visible once a wallet connects; add useResumeKey regression coverage.
Move the useResumeRecord expiry check into useMemo. Hoist the
cash/exchange default source token to a shared constant and document
the deny-list assumption. Serve exchange/card funding logos from the
@lifi/types assets instead of an external CDN.
Expose remainingMs from useFrozenQuote and drop the duplicate
per-second interval in TransferDepositPage. Gate the preview-only
deposit-error kinds (which render mocked amounts) to development so
production only renders the kinds the status poll actually produces
(unexpected, address-expired).
Replace the removed ExecutionProgressCards with a checkout-local component
built on the canonical widget execution-status primitives.
ExecutionStatusCard renders motion's m-components, which stay hidden
without a LazyMotion feature provider. Declare motion and wrap the
checkout execution card like the widget's own execution page.
- Capture linked Mesh accounts (MMT tokenId); show one-tap "Pay with
{exchange}" rows on return, with disconnect to switch
- Persist in sessionStorage per integrator+user with TTL expiry
- Pass theme/language/fiat to Mesh Link; add Mesh preconnect origin
- Pause deposit polling while the on-ramp session loads, not just
while the modal is open
- Catalog-skip needs a backend change, tracked in EXBE-372
- Add opt-in `allowUserDestinationAddress`: user sets recipient in-widget
  (paste/ENS or connect wallet) when `toAddress` is omitted
- Validate against destination ecosystem, persist per integrator
- Quote walletless funding using the destination as from-address
- Export `useAddressValidation`/`AddressType` from the widget
addConnectedAccounts no longer prunes every integrator's records on
each write; it sweeps only the key being written (whole-store hygiene
still runs once on rehydrate). Add a regression test.
Deposit terms remain only where mechanism-accurate (transfer deposit
address flow, "Deposit with cash") or API-bound (depositAddress,
custom deposit mode gate).
- Replace deep-resume-on-mount with a tappable activity list, each deposit
  polled by address to reconcile done/failed states.
- Quote through shared useRoutes via a new quoteFromAddress placeholder
  instead of a parallel getRoutes.
- Re-key pending records by a stable per-deposit id to avoid collisions.
- Wallet flow drops the Intent-Factory-only exchange override; the
  deposit flows (transfer/exchange/cash) keep it.
- Records with no deposit address poll status by tx hash, deriving
  cross-chain bridge hints from the frozen route; resume opens the
  status page by hash.
- Wallet records now always persist the frozen quote so those hints
  are available to the activity list and resume.
- Pre-fills the recipient with the connected account matching the
  destination ecosystem when the integrator leaves it user-settable;
  the field stays editable.
- Falls back to the manual "where to send it" prompt when no connected
  account matches the destination chain.
Stops the seeded default (e.g. USDC) from rendering pre-highlighted;
a per-flow tokenSelected flag gates it until a genuine tap.
Fixes already-connected wallets being unselectable: the old commit
only fired on a new connection event, never for an existing wallet.
- Poll relayer/gasless routes by taskId, not as a txHash (distinct keys in
  the SDK status API), so they no longer hang on NOT_FOUND
- Resume an unfinished wallet route (in flight or failed) on the execution
  page so the SDK re-prompts/retries, instead of the poll-only status page
- Re-seed an evicted route from the 24h snapshot before resuming
- Force chains.types to EVM-only; cascades to chains, tokens, routes, wallets
- Hide native gas token in transfer/exchange/cash flows (IF can't accept it)
- Wallet menu now honors chains.types ecosystem allow/deny config
@changeset-bot

changeset-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8e4b3f3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@lifi/widget-provider Minor
@lifi/widget-provider-transak Major
@lifi/widget-provider-mesh Major
@lifi/widget-checkout Minor
@lifi/widget Minor
@lifi/wallet-management Patch
@lifi/widget-provider-bitcoin Patch
@lifi/widget-provider-ethereum Patch
@lifi/widget-provider-solana Patch
@lifi/widget-provider-sui Patch
@lifi/widget-provider-tron Patch
vite-iframe Patch
nft-checkout Patch
tanstack-router-example Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@tomiiide
tomiiide marked this pull request as ready for review June 23, 2026 23:20

@chybisov chybisov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved as part of checkout stack review (clean tier).

Base automatically changed from checkout/09-wallet-any-route to feat/widget-checkout July 8, 2026 08:44
…out/10-cash-fiat-quote-flow

# Conflicts:
#	.gitignore
#	packages/widget-checkout/src/components/CheckoutAmountInput.tsx
#	packages/widget-checkout/src/components/CheckoutFlowCtaButton.tsx
#	packages/widget-checkout/src/components/CheckoutPriceFormHelperText.tsx
#	packages/widget-checkout/src/components/CheckoutReceiveCard.tsx
#	packages/widget-checkout/src/components/CheckoutRecipientCard.tsx
#	packages/widget-checkout/src/components/FiatCurrencyChip.tsx
#	packages/widget-checkout/src/hooks/useCheckoutStatusSources.ts
#	packages/widget-checkout/src/hooks/useFrozenQuote.tsx
#	packages/widget-checkout/src/hooks/usePendingCheckoutWriter.ts
#	packages/widget-checkout/src/pages/CheckoutTransactionDetailsPage/CheckoutTransactionDetailsPage.tsx
#	packages/widget-checkout/src/pages/CheckoutTransactionStatusPage/CheckoutTransactionStatusPage.tsx
#	packages/widget-checkout/src/pages/CheckoutTransactionStatusPage/StatusExecuting.tsx
#	packages/widget-checkout/src/pages/EnterAmountPage/EnterAmountPage.tsx
#	packages/widget-checkout/src/pages/SelectCashCurrencyPage/SelectCashCurrencyPage.tsx
#	packages/widget-checkout/src/pages/SelectSourcePage/SelectSourcePage.tsx
#	packages/widget-checkout/src/providers/OnRampProvider/OnRampProvider.tsx
#	packages/widget-checkout/src/providers/PendingCheckoutPersistenceBridge.tsx
#	packages/widget-checkout/src/stores/useFiatCurrencyStore.tsx
#	packages/widget-checkout/src/stores/usePendingCheckoutStore.ts
#	packages/widget-provider-mesh/src/MeshHost.tsx
#	packages/widget-provider-transak/src/TransakHost.tsx
#	packages/widget-provider/src/checkout/api.ts
#	packages/widget-provider/src/checkout/contexts/OnRampSessionsContext.test.ts
#	packages/widget-provider/src/checkout/index.ts
#	packages/widget-provider/src/checkout/types.ts
#	packages/widget-provider/src/checkout/utils/sessionClient.ts
#	packages/widget/src/i18n/en.json
#	pnpm-lock.yaml
@chybisov
chybisov merged commit 166f34f into feat/widget-checkout Jul 8, 2026
2 checks passed
@chybisov
chybisov deleted the checkout/10-cash-fiat-quote-flow branch July 8, 2026 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants