Conversation
Implements the Yield boost card from Figma 26134:23293 with its Claim
button, and puts the card back on the funded savings vault screen (the
redesign had dropped it), under the balance card.
- The boost is paid by Merkl campaigns (one per vault, all WFUSE on
Fuse). lib/merklYieldBoost.ts reads the WFUSE leaf from
/v4/users/{address}/rewards, scopes "Total Earned" to the campaign ids
in EXPO_PUBLIC_MERKL_YIELD_BOOST_CAMPAIGN_IDS, and builds the claim.
It doesn't import @merkl/api, so it can be tested without it.
- Claim is one user operation: Distributor.claim with the cumulative
amount, then WFUSE.withdraw of exactly what the claim pays, measured
against the Distributor's own claimed record so a stale index can't
revert the batch. Proofs are re-read (bypassing Merkl's cache) right
before signing, and the query is refreshed the same way afterwards.
- Total Earned is the boost campaigns' credited amount plus pending, in
USD at the app's FUSE price (Merkl's quote as a fallback).
- The card stays visible with a disabled "—" boost for a user who lost
their tier but still has something to claim.
- The rewards yield-boost sheet now describes the FUSE boost and its
balance cap ("on your first $10,000") when the backend sends
yieldBoostBalanceCap, and keeps the old copy when it doesn't.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EupadZ9qYL5nDLM6dDtu5n
…mentation-nogeis Add Merkl yield boost claiming to savings screen
The rail only existed in the wallet flow. It now appears in all three card funding modals — Wirex, and Rain on mobile and desktop. The steps are the same screens; only the shell differs. OrchestraFlow renders them with the host's own navigator, the way BuyCryptoFlow already does for TransFi, and lib/orchestraFlow supplies the title and back target so each host asks the owning flow rather than keeping its own copy. Both embedded flows now route through one pair of helpers in each modal. Which balance gets funded is the entry point's to decide, not the screen's: useOrchestraCardEntry sets it to 'card' and the amount screen sends it, so the server resolves the card's own address instead of the Safe. The receive line follows suit — "in your card balance" rather than "in your wallet". A modal that forgot to set it would quietly fund the wallet from a screen titled Fund your card, which is why that lives in a shared hook rather than three copies. The row is passed only when the server says the deposit is available, so it stays hidden rather than disabled outside the US. Worth noting the neighbouring "Buy crypto" row is dead code today: it takes onBuyCryptoPress and none of the three modals pass it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Onramper's hosted widget is back, as an "Apple Pay" method under USD in both deposit flows. - Wallet: Cash → USD → "Deposit US Dollars" lists Wire transfer/ACH, Cash App where the server allows it, and Apple Pay. The bank rail and Apple Pay are offered everywhere, so USD now always opens the chooser instead of going straight to the bank rail outside the US. - Card (Rain mobile and desktop): USD opens the same list — Wire transfer/ACH and Apple Pay — as a step of the funding modal, and back from the widget returns to it. Wirex's funding screen has no USD section and is unchanged. - The rows live in one UsdMethodList shared by both flows, and Cash App availability in one useIsCashAppAvailable hook shared by the cash list's chips and the USD list. - The widget session now names its destination: the card funding modals ask for `card`, so the purchase lands on the card deposit address and arrives as card balance, while the wallet flow keeps `wallet`. Until the matching backend change deploys, the field is ignored and card-screen purchases keep landing in the wallet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nramp feat(deposit): offer Cash App under Fund your card
Resolves the conflicts with a4b43a8 (Cash App under Fund your card) in both Rain card funding modals. Titles and back targets come from the shared getEmbeddedTitle and getEmbeddedBackTarget, and the Onramper widget still returns to the USD methods step it is opened from. useOrchestraCardEntry now reads Cash App availability from useIsCashAppAvailable, so the rule lives in one place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(deposit): Apple Pay under USD, funding the card from card screens
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…page On STANDARD_KYC_REQUIRED / ENHANCED_KYC_REQUIRED the error screen offered "Verify identity", which opened our own identity flow. The user is already verified there, so it bounced them back to the amount screen and into the same refusal - a loop with no way out. The screen now reads "Upgrade your verification" and asks the backend for TransFi's page for the level the refusal names (POST /transfi/kyc/upgrade), then opens it. When TransFi already has a submission it shows "Verification in review" instead, and it offers "Buy a smaller amount", since the limit only caps this purchase. Every other complete_kyc error behaves as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(buy-crypto): send a KYC-limit refusal to TransFi's verification page
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
Cash App was a row of its own at the bottom of "Fund your card", in the Other group, while the wallet flow lists it under USD beside Apple Pay. The card screens now do the same. - Rain (mobile and desktop): USD opens "Deposit US Dollars", which lists Wire transfer/ACH, Cash App where the server allows it, and Apple Pay. The USD row's chips name Cash App when it is offered, and back from the Cash App amount screen returns to the USD methods rather than the list. - Wirex has no USD section, so it no longer offers Cash App at all. Its modal is back to what it was before Cash App was added to it, and the Other group's Cash App row goes with its last caller. - The USD chips come from one getUsdMethodChips helper beside UsdMethodList, shared by the wallet's cash list and the card options, so the two USD rows cannot drift apart. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-position-faaa69 fix(deposit): list Cash App under USD on Fund your card
A Wirex cardholder's "Add funds" opens the wallet deposit flow, whose USD step offered "Wire transfer, ACH". Nothing sent that way reaches their card: the Wirex virtual account has no wire rail, and what it receives settles into the Wirex balance rather than the Safe the card spends from. "Fund your card" already leaves the rail off for Wirex (WIREX_CARD_FUND_SECTIONS.cashDeposit). - canFundByUsdBankTransfer(provider) is false for a Wirex card. - DepositUsdOptions drops the bank row for them; Apple Pay and Cash App stay. - getUsdMethodChips takes a hasBankTransfer flag, so the cash list's USD row stops naming ACH and Wire for them too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…jection-4c4df8 fix(deposit): hide the USD bank rail from Wirex cardholders
TransFi refuses to onboard users from UA, RU and BY (among others), so the local-currency cash deposit rows led them into a flow that could only fail. The list comes from EXPO_PUBLIC_TRANSFI_PROHIBITED_COUNTRIES (comma-separated alpha-2 codes), falling back to UA,RU,BY when unset so a build missing the var does not silently re-open them. The rows are hidden in the deposit cash screen and the card funding options; USD (virtual account) is unaffected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(deposit): hide TransFi cash deposits in prohibited countries
"Deposit with cash" only expanded to MXN: the screen kept its own allowlist of codes, left over from when each row fetched its payment methods from TransFi. Chips now come from the committed corridor list, so "Show more" lists every currency in localCurrencies.tsx after the featured four, and the chooser's "+N" counts them all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l-currencies Show every cash currency behind "Show more" on Deposit with cash
Apple Pay (Onramper's widget) is still being tested, so gate its USD row and chip behind isDevFeatureEnabled: shown on qa/preview, hidden in production until launch. Without Apple Pay, a Wirex cardholder outside the US has no USD method at all, so the cash list hides its USD row rather than opening an empty chooser. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(deposit): offer Apple Pay on qa builds only
The yield boost is now paid by the backend from its own ledger instead of Merkl: earned daily on the user's savings across soUSD, soETH and soFUSE together, and claimed in soFUSE. Because it belongs to the whole portfolio rather than one vault, the card moves from the vault screen to the Earn page, under the portfolio total, keeping the Figma 26134:23293 design. - New GET /rewards/yield-boost summary and POST /rewards/yield-boost/ claim calls, with hooks keyed per account under the rewards cache. Claiming needs no passkey: the backend sends the transfer. The card polls while a claim is still being paid and refreshes savings and the tier once it lands. - The card says why a claim was refused (the backend's message), when a payout is still on its way, and when claims are paused. - New yield_boost_claim activity type, shown as a reward. - Rewards sheet copy now says soFUSE, and shows earnings to the cent. Removed the Merkl yield boost client (campaign reads, claim batching, EXPO_PUBLIC_MERKL_YIELD_BOOST_CAMPAIGN_IDS) and the vault-screen card. The general Merkl rewards claim is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EupadZ9qYL5nDLM6dDtu5n
…mentation-nogeis feat(earn): claim the yield boost from the Earn page, paid in soFUSE
Quotes and swaps now go through Algebra only. - Remove the Voltage router, its swap callback and its approval hook. - Work out the quote once in DerivedSwapInfoProvider, for the active direction only, instead of in every swap component. - Quote 300 ms after typing pauses, refresh every 15 s, and re-check the quote before signing, so a moved price stops the swap instead of letting it revert. - Exact-out picks the route with the least input; it was comparing against the output list. - Approve only when the allowance falls short, for the exact amount. Drop the unlimited-approval fallback and the "Approve & Swap" label, since approval and swap share one signature. - Log each distinct quote under [swap-quote]. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Redesign rewards tiers and category cashback details
…uilds The Earn card ran the boost rate through resolveTierBenefitRates with isDevFeatureEnabled, the rewards screen's design-QA preview, which swaps a locked 0% boost for a stock 2% on every non-production build. On QA a Core user therefore saw '+2% Boost' and a Claim button for a boost they don't earn. The card now shows only the rate the backend reports for the user, so Core users with nothing to claim see no card at all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EupadZ9qYL5nDLM6dDtu5n
…mentation-nogeis fix(earn): don't show a yield boost to Core users on non-production b…
This branch was successfully deployed
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.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.