Skip to content

feat(epic): implement cashouts/topups/transfers#621

Merged
islandbitcoin merged 108 commits into
mainfrom
feat/fygaro
Jul 3, 2026
Merged

feat(epic): implement cashouts/topups/transfers#621
islandbitcoin merged 108 commits into
mainfrom
feat/fygaro

Conversation

@Nodirbek75

@Nodirbek75 Nodirbek75 commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • implements the Fygaro cash wallet epic: cash top-ups, local/Bridge cash-outs, Bridge KYC/external-account flows, and cash-wallet send/receive UI updates
  • consumes backend Globals.topupEnabled from flash PR [Bug] - QR code does not scan when attempted twice #421 to hide local top-up entry points (card webview + local bank-transfer support) when the server-side topup flag is off
  • folds in the ENG-465 Bridge client kill switch from feat(flags): gate Bridge top-up/KYC queries behind bridgeTopupEnabled (ENG-465) #658: bridgeTopupEnabled defaults off in Firebase Remote Config, is on for Local, skips Bridge KYC/external-account queries when off, and hides Bridge top-up/cash-out/KYC entry points instead of letting users click into disabled backend resolvers
  • includes the UAT follow-up fixes merged into feat/fygaro: USDT settlement/display amounts now use cents, not micros
  • includes final transfer-flow cleanup for stale review blockers: top-up success screen no longer shows hardcoded amounts, local cash-out avoids $NaN and stuck spinners, and send wallet selection no longer passes [undefined]

UAT Context

Supersedes

Test Plan

  • yarn check-code
  • yarn test --runInBand
  • yarn test __tests__/hooks/use-display-currency.spec.tsx --runInBand
  • yarn test __tests__/payment-details --runInBand
  • yarn tsc:check
  • yarn graphql-check
  • git diff --check

islandbitcoin and others added 25 commits July 14, 2025 20:33
@Nodirbek75 Nodirbek75 self-assigned this Apr 22, 2026
@islandbitcoin islandbitcoin added the enhancement New feature or request label Apr 22, 2026
forge0x and others added 3 commits June 19, 2026 12:28
Cash wallet transactions were using the backend-provided
settlementDisplayAmount/settlementDisplayCurrency for the primary
line, which always showed USD regardless of the user's configured
display currency. Now uses moneyAmountToDisplayCurrencyString (same
as BTC transactions) to convert through the price feed to the user's
actual display currency.
The formatMoneyAmount output for USDT changed from '$0.179554 USDT'
to '$0.179554 USD' after mapping USDT currencyCode to usdDisplayCurrency.id.
#650)

* fix selfie step on the bridge kyc flow not showing the overlay with informative texts

* fix term of services and privacy policy links not opening on the external browser

* fix(bridge-kyc): scope ToS legal-link external-open to bridge.xyz host

The ToS-step handler opened any URL containing '/legal' in the external
browser. Restrict it to bridge.xyz (and subdomains) + a /legal path so an
unrelated host can't be shelled out via Linking.openURL.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dread <dread@example.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@islandbitcoin islandbitcoin removed the enhancement New feature or request label Jun 25, 2026
@islandbitcoin islandbitcoin changed the title feat: implement Cashout/Topups/Transfers feat: [epic] implement cashouts/topups/transfers Jun 26, 2026
# Conflicts:
#	.github/workflows/check-code.yml
#	.github/workflows/test.yml
#	.node-version
#	package.json
@github-actions

Copy link
Copy Markdown

this PR needs to be updated to follow conventional commits message

@bobodread876 bobodread876 changed the title feat: [epic] implement cashouts/topups/transfers feat(epic): implement cashouts/topups/transfers Jun 26, 2026
* fix(bridge): prevent back-stack trap after manual bank link

Use navigation.replace instead of navigate after successful external
account creation so the manual form is removed from the stack —
pressing back from CashoutDetails returns to TopupCashout, not the
form. Also handle the duplicate-submission case: if the user re-enters
the same account details and Bridge returns an error, treat it as
'already linked' and proceed to cashout instead of showing a 400.

* fix(topup): replace hardcoded bank details with WhatsApp support CTA

The local bank transfer screen had hardcoded Flash banking details
(BBW/Banco Hipotecario). These should come from ERPNext dynamically
with a per-user reference code — tracked as part of TopUp V1 in
Linear. Until that's built, show a message directing users to
contact support via WhatsApp for banking information.

* fix(topup): skip amount entry for disabled bank transfer

* fix(topup): polish WhatsApp support CTA

* test(send-confirmation): fix flaky fee-display assertion

The realtimePrice mock typed me.defaultAccount as the "Account"
interface while every other mock uses the concrete "ConsumerAccount".
This normalized to a separate Apollo cache entity, so whichever query
wrote me.defaultAccount last won; when a ConsumerAccount query (no
realtimePrice field) resolved after realtimePrice, the display currency
reverted to USD and the fee's display-currency amount rendered empty.
Aligning the __typename makes realtimePrice persist regardless of
resolution order, so SendScreen Confirmation settles deterministically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
islandbitcoin and others added 3 commits July 2, 2026 13:45
Co-authored-by: Vandana <forge@getflash.io>
* feat(bridge): show virtual account details in settings

* feat(bridge): scaffold unified Bank accounts hub (money-in + money-out)

Introduce a single "Bank accounts" settings surface that unifies the Bridge
virtual (receive) account and the user's withdrawal banks behind one
rail-agnostic view model, replacing the standalone routing-number row.

- add normalized BankAccountVM + useBankAccounts() hook merging
  bridgeVirtualAccount (receive), bridgeExternalAccounts (USD withdraw) and
  me.bankAccounts (local withdraw), with per-currency default resolution
- add BankAccountsScreen: Receive card (reveal/copy, KYC-gated) + currency
  grouped Withdraw list with default selection, status pills and add flow
- interim client-side default store (AsyncStorage) until backend adds
  isDefault + bridgeSetDefaultExternalAccount (kept isolated from the
  persistentState migration chain for a one-file swap later)
- wire BankAccounts route + settings row; hub handles KYC state internally

Scaffolding only: set-default persists client-side; remove is gated on a
future bridgeDeleteExternalAccount mutation. tsc + eslint clean.

* feat(bridge): cancel button on add-account + WhatsApp support link

- Add Cancel button in the Add Bank Account header (navigation.goBack)
- Add Contact Support button at the bottom of the Bank accounts hub
  that opens WhatsApp support (wa.flashapp.me) via openWhatsAppUrl

* feat(bridge): add Upgrade button to locked Bank accounts card

 KYC-not-approved state now shows an Upgrade your account button that
 navigates to the AccountType upgrade flow — same destination as the
 QuickStart upgrade card on the Home screen.

* feat(bridge): finish Bank accounts follow-ups

* fix(bridge): allow Bank accounts screen to scroll

* polish(bank-accounts): i18n already-linked alert + small UX fixes

- extract the #652 already-linked alert strings to i18n
  (BridgeAddExternalAccount.alreadyLinkedTitle/Message)
- toast confirmation when a default withdrawal account is set in the
  hub (no feedback before beyond the radio moving)
- CashoutWithdrawTo: reload the stored default on screen focus instead
  of mount only, so a default changed in Settings is reflected when
  returning to an already-mounted cash-out screen
- promote serverDefault to a proper optional field on BankAccountVM
  instead of smuggling it through type casts

Verified: tsc:check clean, eslint clean on touched files, jest
36 suites / 159 tests green on the merged tree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(i18n): backfill Bank accounts keys into all locale files

The translation-drift check (added in #604) requires every locale to
contain all en.json keys. Backfill the 72 new Bank accounts / add-bank
keys into all 23 locale files with English placeholder values — same
interim convention as existing untranslated keys (e.g. Cashout section).
Proper translations can follow the ENG-242 machine-translate process.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Patoo <262265744+patoo0x@users.noreply.github.com>
Co-authored-by: Dread <dread@example.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…switch

The Bank accounts hub (#653) landed after the ENG-465 remote-config gate
was folded into feat/fygaro and missed it: the settings row rendered for
everyone and the hub fired Bridge KYC/virtual-account/external-account
queries with the kill switch off — violating the gate's contract (hide
Bridge entry points, skip Bridge queries) and dead-ending users at an
Upgrade CTA whose Bridge path is hidden.

- hide BankAccountsSetting when !bridgeTopupEnabled (same contract as
  AccountType / TopupCashout)
- skip useBridgeKycStatusQuery in useBankAccounts when the flag is off;
  the virtual/external account queries already skip on !kycApproved and
  are now transitively gated
- split the AsyncStorage default-account helpers into
  default-account-store.ts: CashoutWithdrawTo/CashoutDetails only need
  the stored id, and importing the hook module would have pulled
  feature-flags-context (and Firebase Remote Config) into their module
  graph — breaking home.spec and coupling cash-out to settings

Verified: tsc:check clean, eslint clean, jest 36 suites / 159 tests
green (home.spec included).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@islandbitcoin islandbitcoin merged commit 14a57c2 into main Jul 3, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants