Skip to content

Commit c703bba

Browse files
authored
Merge branch 'main' into feat/tat-2906-update-latest-hyperliquid-sdk
2 parents c1db023 + 5517bff commit c703bba

File tree

136 files changed

+11287
-14451
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+11287
-14451
lines changed

.github/workflows/build-rc-auto.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
# It runs on every commit pushed to a release branch, but only when the release PR
55
# has the 'auto-rc-builds' label.
66
#
7+
# Rolling builds: when a new run starts for the same release branch, any queued or
8+
# in-progress run of this workflow for that branch is cancelled (same behavior as
9+
# Bitrise “Rolling builds” / “Abort running builds” for one branch + one workflow).
10+
#
711
# Builds are triggered via the Runway OTA/build pipeline (runway-ota-build-core.yml):
812
# - iOS runs first and performs the version bump.
913
# - Android runs after, skipping the version bump (already done by iOS).
@@ -16,6 +20,10 @@ on:
1620
branches:
1721
- 'release/*'
1822

23+
concurrency:
24+
group: ${{ github.workflow }}-${{ github.ref }}
25+
cancel-in-progress: true
26+
1927
permissions:
2028
contents: write
2129
pull-requests: write

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,8 @@ jobs:
396396
# Build with retry logic. Timeouts: 55min per attempt, 115min total for step, 120min job
397397
- name: Build ${{ matrix.platform }}
398398
timeout-minutes: 115
399+
env:
400+
GIT_BRANCH: ${{ inputs.source_branch || github.ref_name }}
399401
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 #v3.0.2
400402
with:
401403
timeout_minutes: 55

.github/workflows/slack-rc-notification.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
- uses: actions/checkout@v4
4141
with:
4242
ref: ${{ inputs.source_branch }}
43-
fetch-depth: 1
43+
fetch-depth: 0
4444
- uses: actions/setup-node@v4
4545
with:
4646
node-version-file: '.nvmrc'

app/components/Nav/App/App.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,14 @@ const OnboardingSuccessFlow = () => {
181181
const { colors } = useTheme();
182182

183183
return (
184-
<Stack.Navigator initialRouteName={Routes.ONBOARDING.SUCCESS}>
184+
<Stack.Navigator
185+
initialRouteName={Routes.ONBOARDING.SUCCESS}
186+
screenOptions={{
187+
cardStyle: { backgroundColor: colors.background.default },
188+
headerStyle: { backgroundColor: colors.background.default },
189+
headerShadowVisible: false,
190+
}}
191+
>
185192
<Stack.Screen
186193
name={Routes.ONBOARDING.SUCCESS}
187194
component={OnboardingSuccess}
@@ -192,10 +199,6 @@ const OnboardingSuccessFlow = () => {
192199
<Stack.Screen
193200
name={Routes.ONBOARDING.DEFAULT_SETTINGS}
194201
component={DefaultSettings}
195-
options={{
196-
headerStyle: { backgroundColor: colors.background.default },
197-
cardStyle: { backgroundColor: colors.background.default },
198-
}}
199202
/>
200203
<Stack.Screen
201204
name={Routes.ONBOARDING.GENERAL_SETTINGS}
@@ -221,7 +224,12 @@ const OnboardingNav = () => {
221224
const { colors } = useTheme();
222225

223226
return (
224-
<Stack.Navigator initialRouteName={'Onboarding'}>
227+
<Stack.Navigator
228+
initialRouteName={'Onboarding'}
229+
screenOptions={{
230+
cardStyle: { backgroundColor: colors.background.default },
231+
}}
232+
>
225233
<Stack.Screen name="Onboarding" component={Onboarding} />
226234
<Stack.Screen
227235
name={Routes.ONBOARDING.SOCIAL_LOGIN_SUCCESS_NEW_USER}
@@ -253,7 +261,6 @@ const OnboardingNav = () => {
253261
component={DefaultSettings}
254262
options={{
255263
headerStyle: { backgroundColor: colors.background.default },
256-
cardStyle: { backgroundColor: colors.background.default },
257264
}}
258265
/>
259266
<Stack.Screen name="ManualBackupStep1" component={ManualBackupStep1} />
@@ -669,6 +676,7 @@ const ImportSRPView = () => (
669676
<Stack.Navigator
670677
screenOptions={{
671678
headerShown: false,
679+
presentation: 'transparentModal',
672680
}}
673681
>
674682
<Stack.Screen
@@ -684,7 +692,6 @@ const ImportSRPView = () => (
684692
name={Routes.SHEET.SEEDPHRASE_MODAL}
685693
component={SeedphraseModal}
686694
options={{
687-
presentation: 'modal',
688695
cardStyle: { backgroundColor: 'transparent' },
689696
cardStyleInterpolator: () => ({
690697
overlayStyle: {

app/components/Nav/Main/index.js

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import {
9494
} from '../../hooks/useNetworksByNamespace/useNetworksByNamespace';
9595
import { useNetworkSelection } from '../../hooks/useNetworkSelection/useNetworkSelection';
9696
import { useIsOnBridgeRoute } from '../../UI/Bridge/hooks/useIsOnBridgeRoute';
97+
import { shouldShowNetworkListToast } from './utils';
9798

9899
const Stack = createStackNavigator();
99100

@@ -298,11 +299,9 @@ const Main = (props) => {
298299
);
299300

300301
// Emit network addition/deletion toast if network list changes
301-
// Bridge routes are skipped as they interfere with bridge UI
302302
if (
303303
previousNetworkValues.length &&
304-
currentNetworkValues.length !== previousNetworkValues.length &&
305-
!isOnBridgeRoute
304+
currentNetworkValues.length !== previousNetworkValues.length
306305
) {
307306
// Find the newly added network by comparing chainIds
308307
const newNetwork = currentNetworkValues.find(
@@ -318,27 +317,33 @@ const Main = (props) => {
318317
),
319318
);
320319

321-
toastRef?.current?.showToast({
322-
variant: ToastVariants.Plain,
323-
labelOptions: [
324-
{
325-
label: `${
326-
(newNetwork?.name || deletedNetwork?.name) ??
327-
strings('asset_details.network')
328-
} `,
329-
isBold: true,
330-
},
331-
{
332-
label: deletedNetwork
333-
? strings('toast.network_removed')
334-
: strings('toast.network_added'),
335-
},
336-
],
337-
networkImageSource: networkImage,
320+
const shouldShowToast = shouldShowNetworkListToast({
321+
newNetworkChainId: newNetwork?.chainId,
322+
hasDeletedNetwork: Boolean(deletedNetwork),
338323
});
324+
if (shouldShowToast) {
325+
toastRef?.current?.showToast({
326+
variant: ToastVariants.Plain,
327+
labelOptions: [
328+
{
329+
label: `${
330+
(deletedNetwork?.name || newNetwork?.name) ??
331+
strings('asset_details.network')
332+
} `,
333+
isBold: true,
334+
},
335+
{
336+
label: deletedNetwork
337+
? strings('toast.network_removed')
338+
: strings('toast.network_added'),
339+
},
340+
],
341+
networkImageSource: networkImage,
342+
});
343+
}
339344
}
340345
previousNetworkConfigurations.current = networkConfigurations;
341-
}, [isOnBridgeRoute, networkConfigurations, networkImage, toastRef]);
346+
}, [networkConfigurations, networkImage, toastRef]);
342347

343348
useEffect(() => {
344349
if (locale.current !== I18n.locale) {

app/components/Nav/Main/utils.test.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
import { ImageSourcePropType } from 'react-native';
2-
import { handleShowNetworkActiveToast } from './utils';
2+
import {
3+
handleShowNetworkActiveToast,
4+
shouldShowNetworkListToast,
5+
} from './utils';
36
import { ToastVariants } from '../../../component-library/components/Toast';
47
import { strings } from '../../../../locales/i18n';
8+
import {
9+
clearSuppressedNetworkAddedToast,
10+
consumeSuppressedNetworkAddedToast,
11+
resetSuppressedNetworkAddedToasts,
12+
suppressNextNetworkAddedToast,
13+
} from '../../../util/networks/networkToastSuppression';
514

615
describe('handleShowNetworkActiveToast', () => {
716
const mockToastRef = {
@@ -16,6 +25,7 @@ describe('handleShowNetworkActiveToast', () => {
1625

1726
beforeEach(() => {
1827
jest.clearAllMocks();
28+
resetSuppressedNetworkAddedToasts();
1929
});
2030

2131
it('shows toast when not on bridge route', () => {
@@ -134,3 +144,39 @@ describe('handleShowNetworkActiveToast', () => {
134144
expect(calledWith.networkImageSource).toBe(customNetworkImage);
135145
});
136146
});
147+
148+
describe('shouldShowNetworkListToast', () => {
149+
beforeEach(() => {
150+
resetSuppressedNetworkAddedToasts();
151+
});
152+
153+
it('suppresses an added-network toast only once', () => {
154+
suppressNextNetworkAddedToast('0xa');
155+
156+
expect(
157+
shouldShowNetworkListToast({
158+
newNetworkChainId: '0xa',
159+
hasDeletedNetwork: false,
160+
}),
161+
).toBe(false);
162+
163+
expect(
164+
shouldShowNetworkListToast({
165+
newNetworkChainId: '0xa',
166+
hasDeletedNetwork: false,
167+
}),
168+
).toBe(true);
169+
});
170+
171+
it('clears suppressed added-network toasts explicitly', () => {
172+
suppressNextNetworkAddedToast('0xa');
173+
174+
clearSuppressedNetworkAddedToast('0xa');
175+
176+
expect(consumeSuppressedNetworkAddedToast('0xa')).toBe(false);
177+
});
178+
179+
it('returns false when consuming without a chain id', () => {
180+
expect(consumeSuppressedNetworkAddedToast()).toBe(false);
181+
});
182+
});

app/components/Nav/Main/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ImageSourcePropType } from 'react-native';
22
import { ToastVariants } from '../../../component-library/components/Toast';
33
import { strings } from '../../../../locales/i18n';
4+
import { consumeSuppressedNetworkAddedToast } from '../../../util/networks/networkToastSuppression';
45

56
export const handleShowNetworkActiveToast = (
67
isOnBridgeRoute: boolean,
@@ -23,3 +24,17 @@ export const handleShowNetworkActiveToast = (
2324
});
2425
}
2526
};
27+
28+
export const shouldShowNetworkListToast = ({
29+
newNetworkChainId,
30+
hasDeletedNetwork,
31+
}: {
32+
newNetworkChainId?: string;
33+
hasDeletedNetwork: boolean;
34+
}) => {
35+
const shouldShowNetworkAddedToast =
36+
Boolean(newNetworkChainId) &&
37+
!consumeSuppressedNetworkAddedToast(newNetworkChainId);
38+
39+
return shouldShowNetworkAddedToast || hasDeletedNetwork;
40+
};

app/components/UI/Bridge/hooks/useTokenSelection.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ import { createMockToken } from '../testUtils/fixtures';
1313
import Routes from '../../../../constants/navigation/Routes';
1414
import { BridgeToken, TokenSelectorType } from '../types';
1515
import { selectNetworkConfigurations } from '../../../../selectors/networkController';
16+
import {
17+
consumeSuppressedNetworkAddedToast,
18+
resetSuppressedNetworkAddedToasts,
19+
} from '../../../../util/networks/networkToastSuppression';
1620

1721
const mockDispatch = jest.fn();
1822
const mockHandleSwitchTokensInner = jest.fn().mockResolvedValue(undefined);
@@ -176,6 +180,7 @@ const renderTokenSelectionHook = (
176180
describe('useTokenSelection', () => {
177181
beforeEach(() => {
178182
jest.clearAllMocks();
183+
resetSuppressedNetworkAddedToasts();
179184
// Non-stock token behavior
180185
mockIsStockToken.mockReturnValue(false);
181186
mockIsTokenTradingOpen.mockReturnValue(true);
@@ -312,6 +317,7 @@ describe('useTokenSelection', () => {
312317
expect(mockDispatch).not.toHaveBeenCalled();
313318
expect(mockAutoUpdateDestToken).not.toHaveBeenCalled();
314319
expect(mockGoBack).toHaveBeenCalledTimes(1);
320+
expect(consumeSuppressedNetworkAddedToast('0xa')).toBe(false);
315321
});
316322

317323
it('continues dest selection when addNetwork rejects', async () => {

app/components/UI/Bridge/hooks/useTokenSelection.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ import { Hex } from '@metamask/utils';
2222
import Engine from '../../../../core/Engine';
2323
import { selectNetworkConfigurations } from '../../../../selectors/networkController';
2424
import { PopularList } from '../../../../util/networks/customNetworks';
25+
import {
26+
clearSuppressedNetworkAddedToast,
27+
suppressNextNetworkAddedToast,
28+
} from '../../../../util/networks/networkToastSuppression';
2529

2630
/**
2731
* Hook to manage token selection logic for Bridge token selector
@@ -69,6 +73,7 @@ export const useTokenSelection = (type: TokenSelectorType) => {
6973
try {
7074
const hexChainId = toHex(popularNetwork.chainId) as Hex;
7175
const { blockExplorerUrl } = popularNetwork.rpcPrefs;
76+
suppressNextNetworkAddedToast(popularNetwork.chainId);
7277
await Engine.context.NetworkController.addNetwork({
7378
chainId: hexChainId,
7479
blockExplorerUrls: blockExplorerUrl ? [blockExplorerUrl] : [],
@@ -86,6 +91,7 @@ export const useTokenSelection = (type: TokenSelectorType) => {
8691
],
8792
});
8893
} catch {
94+
clearSuppressedNetworkAddedToast(popularNetwork.chainId);
8995
if (isSourcePicker) {
9096
// Source requires a configured network to sign transactions.
9197
// Abort selection if the network couldn't be added.

app/components/UI/Card/Views/CardAuthentication/CardAuthentication.test.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,6 @@ describe('CardAuthentication Component', () => {
198198
screen.getByTestId(CardAuthenticationSelectors.VERIFY_ACCOUNT_BUTTON),
199199
).toBeOnTheScreen();
200200
});
201-
202-
it('matches login step snapshot', () => {
203-
const { toJSON } = render();
204-
205-
expect(toJSON()).toMatchSnapshot();
206-
});
207201
});
208202

209203
describe('Login Step - Location Selection', () => {

0 commit comments

Comments
 (0)