fix: offline gating for onramp, staking, card & add-asset surfaces [PERA-4584]#1023
Open
fmsouza wants to merge 12 commits into
Open
fix: offline gating for onramp, staking, card & add-asset surfaces [PERA-4584]#1023fmsouza wants to merge 12 commits into
fmsouza wants to merge 12 commits into
Conversation
…rror copy [PERA-4584]
…al spinner [PERA-4584]
…lures [PERA-4584]
…ding paused into isLoading [PERA-4584]
…copy in card error toast [PERA-4584]
…ape case [PERA-4584]
…success [PERA-4584]
…h useGlobalSearch [PERA-4584]
…PageParam guard [PERA-4584]
… precheck on opt-in [PERA-4584]
wjbeau
approved these changes
Jul 24, 2026
Comment on lines
+105
to
+123
| isOffline ? ( | ||
| <EmptyView | ||
| title={t('common.offline_mode')} | ||
| body={t('common.offline_refresh_body')} | ||
| icon='globe' | ||
| /> | ||
| ) : isError ? ( | ||
| <EmptyView | ||
| title={t('common.error.title')} | ||
| body={t('common.error.body')} | ||
| icon='info' | ||
| /> | ||
| ) : ( | ||
| <EmptyView | ||
| title={t('add_asset.no_results')} | ||
| body='' | ||
| icon='magnifying-glass' | ||
| /> | ||
| ) |
Contributor
There was a problem hiding this comment.
It might be cleaner (since I suspect I'm going to see a few of these) to have an or something that shows hte offline case if offline and shows the children otherwise?
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.
Summary
PERA-4543 Part B for the onramp, staking, card, and add-asset surfaces: every remote-only action attempted offline now yields a readable localized error or a disabled state — never an eternal spinner, never a fake success. Builds on PERA-4573 (fail-fast mutations →
NoConnectionError) and PERA-4574 (typedPeraNetworkError+getNetworkErrorMessageKeys), applying the canonical precedence fromdocs/OFFLINE_PAUSED_STATE.md:data → offline (isPaused || (isError && !hasInternet)) → error → loading → empty.No new i18n keys — all copy reuses existing
common.offline_mode,common.offline_refresh_body,errors.network.no_connection.*,common.error.*,common.retry.label,staking.retry.Acceptance criteria → commits
ac6cc0a98:useOnrampScreengainspairsState: 'ready' | 'loading' | 'offline' | 'error'+handleRetryPairs; the Fund tab's bareActivityIndicatorfork now has offline/errorEmptyViewbranches.ad7cf84f1:isConnectivityErrorbranch in the create/cancel/quote catches (the existingfinallyresetsisConfirming); shared predicate added ind54f98130.isErrorretry branch reachable fake-online (both tested) —cce851a27(hook:isPaused= paused AND uncached; paused no longer folded intoisLoading) +fb0689bb8(screen: offlineEmptyViewwith retry that short-circuits while offline; error branch untouched and still reachable online).144a46bbc(useCardErrorToastconnectivity short-circuit →errors.network.no_connection.*) +83124c2e0(set-PIN/freeze rows and reveal button disabled while offline viaisOffline = !hasInternet || status paused; new regression pinuseFreezeCardMutation.offline.spec.tsxproves an offline freeze rejection leaves the cached status untouched).packages/card/src/hooks/types.tsexposesisPaused(typederrorwas already carried), consumed byusePeraCardDetailsgating —144a46bbc+83124c2e0.e2ccb7063(useAssetSearchQuery.isPaused,useGlobalSearch.isRemoteError/isRemotePausedthreading) +fa747361b(isError: falsehardcode removed;ListEmptyComponentforks offline/error/no-results;assertOnline()precheck inuseAssetOptInMutationthrowsNoConnectionErrorbefore any algod call, whichuseErrorToastnow renders as the shared offline copy viad54f98130).onlineManager.setOnline(false), restored in afterEach) and fake-online (error result +useNetworkStatusStoretoggling) cases.networkModechanges anywhere; all new branches require paused/offline/error signals that are false while online-and-healthy. All pre-existing tests pass unmodified.Bare awaited-mutation sweep (required by ticket)
All 26
mutateAsynccall sites across the onramp/card modules audited (staking and assets have none — their mutations use named wrapper methods, covered above): 26/26 have catch coverage; no fixes needed. Notable by-design cases:useCardOnboardingAddressScreen.ts:294linkConsent— documented best-effort swallow (.catch(() => undefined)); a link hiccup must not strand a registered user.useCardFundingDelegation.ts/useEscrowCardCreation.ts— composable primitives that intentionally propagate rejections to the caller (caller-side try/catch; the former has no consumer yet).useCardAddFundsScreen.tsx:167deposit — every rejection routes toshowComingSoon()per theTODO(card)(no real Baanx backend yet).Full 26-site sweep table
useOnrampOrderDetails.tsx:94cancelOrderuseOnrampQuotes.ts:76createQuoteuseOnrampConfirm.tsx:86createOrderuseCardOnboardingEmailVerifyScreen.ts:89sendEmailVerificationuseCardOnboardingPasswordScreen.ts:134verifyEmailuseCardOnboardingPhoneVerifyScreen.ts:111sendPhoneVerificationuseCardOnboardingPhoneVerifyScreen.ts:166verifyPhoneuseCardAddFundsScreen.tsx:167deposit.catch→ showComingSoon, per TODO)useCardOnboardingPhoneScreen.ts:124sendPhoneVerificationuseCardOnboardingEmailScreen.ts:133sendEmailVerificationuseCardOnboardingEmailScreen.ts:173requestCountryAvailabilityuseCardOnboardingAddressScreen.ts:273submitConsentuseCardOnboardingAddressScreen.ts:284submitAddressuseCardOnboardingAddressScreen.ts:294linkConsentuseCardOnboardingPersonalDetailsScreen.ts:204submitPersonalDetailsuseCardSignInScreen.ts:98loginuseCardOnboardingStatusScreen.ts:203connectFundingSourceAsyncuseCardOnboardingStatusScreen.ts(createPeraCard)createCarduseCardOnboardingVerificationScreen.ts:82startVerificationusePeraCardDetails.tsx:225cardDetails(reveal)usePeraCardDetails.tsx:299setPinusePeraCardDetails.tsx:332connectFundingSourceAsyncuseCardWithdrawConfirmationSheet.ts:82withdrawuseCardConfirmMutation.ts:67useCardFundingDelegation.ts:44updateDelegationAsyncuseEscrowCardCreation.ts:59createEscrowCardAsyncVerification
pnpm build47/47 tasks,pnpm pre-push --no-fail-on-errorgreen,pnpm run format --checkclean,pnpm test554 files / 3989 tests passing.getNetworkErrorMessageKeysthe connectivity branch and swap the literal-key call sites onto it; gateuseGlobalSearch's new flags byshouldRunRemoteAssetsfor symmetry with its pagination flags; allow "Hide" on the revealed card while offline (pure local flip); add an'empty'arm to onramppairsState(pre-existing online edge, out of ticket scope).Out of scope (per ticket)
Buy/sell webview checkout (PERA-4582); card status caching policy (PII exclusion stands); staking data persistence beyond existing keys.
🤖 Generated with Claude Code