Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2c15f3e
feat: attach a Pimlico sponsorship policy to every userop
MayankMittal1 Sep 24, 2026
4c5f93b
Merge pull request #2581 from Solid-Money/mayank/feat/pimlico-sponsor…
MayankMittal1 Sep 24, 2026
04c43fc
Merge pull request #2576 from Solid-Money/qa
MayankMittal1 Sep 25, 2026
65138da
fix(card-spend): disable the retired v2 module when moving a Safe ont…
MayankMittal1 Sep 25, 2026
5fd6011
Merge pull request #2589 from Solid-Money/mayank/fix/retired-cash-mod…
MayankMittal1 Sep 25, 2026
4ebf183
fix(card-spend): skip the module read on a Safe not yet deployed on Fuse
MayankMittal1 Sep 26, 2026
65de8ad
Merge pull request #2590 from Solid-Money/mayank/fix/undeployed-safe-…
MayankMittal1 Sep 26, 2026
d972af0
fix(card): ignore the retired Bridge endorsement once a card customer…
claude Sep 27, 2026
ca48cdc
Merge pull request #2591 from Solid-Money/claude/vigilant-volta-sq8umw
MusabShakeel576 Sep 27, 2026
2ca044b
fix(prices): batch and cache Alchemy price lookups to stay under the …
claude Sep 27, 2026
05e2602
Update app.config.ts
fuseiosa Sep 27, 2026
d442211
feat(swap): enable Swap on iOS
claude Sep 27, 2026
f4f664e
Merge pull request #2594 from Solid-Money/claude/blissful-curie-whwta0
MusabShakeel576 Sep 27, 2026
9cd285e
fix(ui): stop iOS clipping the vault and rewards balance figures
claude Sep 28, 2026
fd12c42
feat(prices): ask the backend's shared price cache first, fall back t…
claude Sep 28, 2026
88472fe
fix(ui): give the balance cards room on Android as well as iOS
claude Sep 28, 2026
04c847f
Merge pull request #2596 from Solid-Money/claude/monday-tasks-review-…
MusabShakeel576 Sep 28, 2026
2274ce5
fix(prices): send the backend only the chains its price route covers
claude Sep 28, 2026
0de3947
revert(polling): restore the 5s balance, 5s native price and 3s vault…
claude Sep 28, 2026
cc27db0
Merge pull request #2593 from Solid-Money/claude/alchemy-threshold-li…
MusabShakeel576 Sep 28, 2026
9498072
feat(deposit): quote the deposit fee the backend charges for each route
MayankMittal1 Sep 28, 2026
19fc28e
fix(withdraw): keep soETH and soFUSE balances in wei for max and vali…
MayankMittal1 Sep 28, 2026
98fd77b
chore(assets): register the rewards-tier upgrade card and credit-noti…
MayankMittal1 Sep 28, 2026
216f4c1
Merge pull request #2599 from Solid-Money/mayank/feat/deposit-fee-fro…
MayankMittal1 Sep 28, 2026
b8ef187
feat(recovery): prefill the identifier, and accept a username
claude Sep 28, 2026
f055b7a
Merge pull request #2602 from Solid-Money/claude/monday-ota-bug-revie…
MusabShakeel576 Sep 29, 2026
78e8f0c
feat(card): add animated spend mode help and delay What's New
creatix Sep 29, 2026
bc789c6
Merge pull request #2604 from Solid-Money/codex/spend-mode-help-whats…
MayankMittal1 Sep 30, 2026
7a1bedf
fix: refresh account activity and improve wallet interactions
creatix Sep 30, 2026
97ec140
Merge pull request #2610 from Solid-Money/codex/spend-mode-help-whats…
MusabShakeel576 Sep 30, 2026
be0969c
fix: name the spend-mode balance in USD and quote one yield boost
claude Oct 1, 2026
6b9d12a
Merge pull request #2613 from Solid-Money/claude/practical-mccarthy-5…
MusabShakeel576 Oct 1, 2026
c7cca5e
Merge master into qa, resolving release conflicts
claude Oct 1, 2026
9643635
fix(rewards): quote Ultra's real yield boost in the fallback table
claude Oct 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ EXPO_PUBLIC_BASE_URL= # Frontend domain (e.g., https://app.solix.xyz)
EXPO_PUBLIC_ALCHEMY_API_KEY=
# TODO: Move Pimlico API Key to backend
EXPO_PUBLIC_PIMLICO_API_KEY=
EXPO_PUBLIC_PIMLICO_SPONSORSHIP_POLICY_ID=sp_romantic_fallen_one
EXPO_PUBLIC_FLASH_API_BASE_URL=
EXPO_PUBLIC_FLASH_ANALYTICS_API_BASE_URL=
EXPO_PUBLIC_BRIDGE_AUTO_DEPOSIT_ADDRESS=
Expand Down Expand Up @@ -68,6 +69,12 @@ EXPO_PUBLIC_CARD_SPEND_V2=true
EXPO_PUBLIC_CASH_MODULE_V2_ADDRESS=
# SolidSpendLens on Fuse — the cohort-aware read serving both module generations.
EXPO_PUBLIC_SPEND_LENS_V2_ADDRESS=
# Earlier SolidCashModuleV2 cores the address above replaced, comma-separated. Any of
# these still enabled on a Safe is disabled in the same batch that puts it on the live
# core — the backend no longer reads them, so a Safe left there declines every payment.
# Empty means the 2026-09-24 retiree (0xE2d4FB3d1eeD6Bdc3fD62A93ab35A33FC3c97b2B).
# Append here on the next redeploy, and change BOTH addresses above in the same release.
EXPO_PUBLIC_RETIRED_CASH_MODULE_V2_ADDRESSES=

# ---- Base: the EURC spend instance -------------------------------------------
# A SECOND, INDEPENDENT deployment of the spend module, not a setting on the Fuse
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ Key environment variables (see `.env.example`):
- `EXPO_PUBLIC_ALCHEMY_API_KEY`: Alchemy API key for blockchain data
- `EXPO_PUBLIC_ETHEREUM_API_KEY`: Ethereum API key
- `EXPO_PUBLIC_PIMLICO_API_KEY`: Pimlico paymaster API key
- `EXPO_PUBLIC_PIMLICO_SPONSORSHIP_POLICY_ID`: Pimlico sponsorship policy attached to every user operation
- `EXPO_PUBLIC_FLASH_API_BASE_URL`: Solid API configuration
- `EXPO_PUBLIC_FLASH_ANALYTICS_API_BASE_URL`: Solid analytics endpoint
- `EXPO_PUBLIC_BRIDGE_AUTO_DEPOSIT_ADDRESS`: Bridge auto-deposit address
Expand Down
2 changes: 1 addition & 1 deletion app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
name: 'Solid',
slug: 'flash-frontend',
version: '2.0.1',
version: '2.0.2',
orientation: 'portrait',
icon: './assets/images/adaptive-icon.png',
scheme: 'solid',
Expand Down
4 changes: 3 additions & 1 deletion app/(protected)/(tabs)/index.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import LazyWalletTabs from '@/components/Wallet/LazyWalletTabs';
import TokenListSkeleton from '@/components/Wallet/WalletTokenTab/TokenListSkeleton';
import { SPIN_WIN_MODAL } from '@/constants/modals';
import { useActivityRefresh } from '@/hooks/useActivityRefresh';
import { useUserTransactions } from '@/hooks/useAnalytics';
import { useCardDetails } from '@/hooks/useCardDetails';
import { useCardStatus } from '@/hooks/useCardStatus';
Expand All @@ -43,11 +44,12 @@
* qa/preview builds see the redesigned `HomeScreenNew`; production keeps this
* `LegacyHome`. The gate lives in the default export below.
*/
function LegacyHome() {

Check warning on line 47 in app/(protected)/(tabs)/index.native.tsx

View workflow job for this annotation

GitHub Actions / lint

'LegacyHome' is defined but never used. Allowed unused vars must match /^_/u
useRenderMonitor({ componentName: MONITORED_COMPONENTS.HOME_SCREEN });

const { user } = useUser();
const queryClient = useQueryClient();
const { refetchAll, isRefreshing } = useActivityRefresh();
const { data: balance, isLoading: isBalanceLoading } = useVaultBalance(
user?.safeAddress as Address,
);
Expand Down Expand Up @@ -127,7 +129,7 @@
const showAssets = isLoadingTokens || hasTokens || !!tokenError;

return (
<PageLayout mobileTitle={mobileHeaderBalance}>
<PageLayout mobileTitle={mobileHeaderBalance} onRefresh={refetchAll} refreshing={isRefreshing}>
<View className="mb-5 w-full gap-8 pb-20">
{isBalanceSectionLoading ? (
<View className="items-center pt-6">
Expand Down
45 changes: 32 additions & 13 deletions app/(protected)/activity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export default function Activity() {
items,
isLoading,
isSyncing,
isRefreshing,
isSyncStale,
hasNextPage,
isFetchingNextPage,
Expand All @@ -73,7 +74,11 @@ export default function Activity() {
const searchTerm = query.trim();

const pageHeader = (
<View className="mx-auto w-full max-w-7xl px-4 pb-[10px] pt-6 md:pt-12">
<View
className={cn('mx-auto w-full max-w-7xl pb-[10px] pt-6 md:pt-12', {
'px-4': isWeb,
})}
>
<View className="flex-row items-center justify-between">
<Text className="text-3xl font-semibold">Activity</Text>

Expand All @@ -89,42 +94,56 @@ export default function Activity() {
</View>
);

const filters = (
<View className="pb-2 pt-2">
<ActivityFilters
value={tab}
onChange={handleTabChange}
query={query}
onQueryChange={setQuery}
isSearchOpen={isSearchOpen}
onSearchOpenChange={setIsSearchOpen}
showSourceFilters={userHasCard}
/>
</View>
);

return (
<PageLayout
isLoading={isCardStatusLoading}
mobileHeaderLeftAction="back"
mobileHeaderRightAction="help"
onMobileHeaderHelpPress={() => openSupportDrawer()}
scrollable={isWeb}
>
{pageHeader}
{isWeb && pageHeader}
<View
className={cn('mx-auto w-full max-w-7xl px-4 pb-8 md:pb-12', {
'flex-1': !isWeb,
})}
>
<View className="pb-2 pt-2">
<ActivityFilters
value={tab}
onChange={handleTabChange}
query={query}
onQueryChange={setQuery}
isSearchOpen={isSearchOpen}
onSearchOpenChange={setIsSearchOpen}
showSourceFilters={userHasCard}
/>
</View>
{isWeb && filters}

<UnifiedActivityList
items={visibleItems}
tab={tab}
userHasCard={userHasCard}
isLoading={isLoading}
isSyncing={isSyncing}
isRefreshing={isRefreshing}
isSyncStale={isSyncStale}
hasNextPage={hasNextPage}
isFetchingNextPage={isFetchingNextPage}
onLoadMore={loadMore}
onRefresh={refetchAll}
listHeaderComponent={
!isWeb ? (
<>
{pageHeader}
{filters}
</>
) : undefined
}
emptyTitle={searchTerm ? 'No matching activity' : 'No transactions found'}
emptyDescription={
searchTerm
Expand Down
6 changes: 5 additions & 1 deletion app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import CashbackStoreReviewTrigger from '@/components/StoreReview/CashbackStoreRe
import ThirdwebConnectionBridge from '@/components/ThirdwebConnectionBridge';
import { toastProps } from '@/components/Toast';
import { TurnkeyProvider } from '@/components/TurnkeyProvider';
import { path } from '@/constants/path';
import { getInfoClient } from '@/graphql/clients';
import { useAttributionInitialization } from '@/hooks/useAttributionInitialization';
import { useDimension } from '@/hooks/useDimension';
Expand All @@ -57,6 +58,7 @@ import { EXPO_PUBLIC_ENVIRONMENT, isProduction } from '@/lib/config';
import { configureObserve, markAppInteractive, withObserve } from '@/lib/observe';
import { config } from '@/lib/wagmi';
import { useUserStore } from '@/store/useUserStore';
import { useWhatsNewStore } from '@/store/useWhatsNewStore';

import type { ErrorBoundaryProps } from 'expo-router';

Expand Down Expand Up @@ -162,7 +164,9 @@ SplashScreen.setOptions({
// Note: Only rendered when hasSelectedUser is true (see conditional render below)
// Uses LazyWhatsNewModal to defer react-native-reanimated-carousel bundle
function WhatsNewWrapper() {
const { whatsNew, isVisible, closeWhatsNew } = useWhatsNew();
const pathname = usePathname();
const isHomeReady = useWhatsNewStore(state => state.isHomeReady);
const { whatsNew, isVisible, closeWhatsNew } = useWhatsNew(pathname === path.HOME && isHomeReady);

if (!whatsNew) return null;

Expand Down
Loading
Loading