Skip to content

Commit 04b823b

Browse files
authored
fix: set swap src chain based on selected asset cp-13.0.0 (#34385)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** The Asset overview pages and the useBridging hook use the current selected network to set the native asset when navigating to the Swap page. When the user navigates to the Swap page from portfolio view, the src network is not set correctly if the selected asset is not in the current selected network Changes - Remove `defaultSwapsToken` prop from asset/account overview components and only retrieve the value from state as needed (`CoinButtons` and `useBridging`) - Deprecate `getSwapsDefaultToken` selector since it only supports EVM networks - `CoinButtons` uses the `getNativeAssetForChainId` util to get the native asset when loading the Swap page - `useBridging` defaults to the selected network's native asset if not passed in as a parameter <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/34385?quickstart=1) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: #34483 ## **Manual testing steps** 1. Go to Swap page and note src network 2. Go back to home page 3. Click on native asset of other network 4. Click Swap 5. The asset from step 3 should be set as the src token ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> See recording in linked issue ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
1 parent 3ecc4d1 commit 04b823b

File tree

10 files changed

+41
-48
lines changed

10 files changed

+41
-48
lines changed

shared/constants/bridge.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ export const ALLOWED_BRIDGE_CHAIN_IDS = [
3535
///: END:ONLY_INCLUDE_IF
3636
];
3737

38-
const ALLOWED_BRIDGE_CHAIN_IDS_IN_CAIP = ALLOWED_EVM_BRIDGE_CHAIN_IDS.map(
39-
toEvmCaipChainId,
40-
).concat(ALLOWED_MULTICHAIN_BRIDGE_CHAIN_IDS);
38+
export const ALLOWED_BRIDGE_CHAIN_IDS_IN_CAIP =
39+
ALLOWED_EVM_BRIDGE_CHAIN_IDS.map(toEvmCaipChainId).concat(
40+
ALLOWED_MULTICHAIN_BRIDGE_CHAIN_IDS,
41+
);
4142

4243
export type AllowedBridgeChainIds =
4344
| (typeof ALLOWED_BRIDGE_CHAIN_IDS)[number]

ui/components/app/wallet-overview/coin-buttons.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useDispatch, useSelector } from 'react-redux';
33
import { useHistory, useLocation } from 'react-router-dom';
44
import { toHex } from '@metamask/controller-utils';
55
import { isCaipChainId, CaipChainId } from '@metamask/utils';
6+
import { getNativeAssetForChainId } from '@metamask/bridge-controller';
67

78
///: BEGIN:ONLY_INCLUDE_IF(multichain)
89
import { isEvmAccountType } from '@metamask/keyring-api';
@@ -16,11 +17,11 @@ import {
1617
SEND_ROUTE,
1718
} from '../../../helpers/constants/routes';
1819
import {
19-
SwapsEthToken,
2020
getCurrentKeyring,
2121
getUseExternalServices,
2222
getNetworkConfigurationIdByChainId,
2323
isNonEvmAccount,
24+
getSwapsDefaultToken,
2425
} from '../../../selectors';
2526
import Tooltip from '../../ui/tooltip';
2627
import { setSwapsFromToken } from '../../../ducks/swaps/swaps';
@@ -71,7 +72,6 @@ type CoinButtonsProps = {
7172
isSigningEnabled: boolean;
7273
isBridgeChain: boolean;
7374
isBuyableChain: boolean;
74-
defaultSwapsToken?: SwapsEthToken;
7575
classPrefix?: string;
7676
iconButtonClassName?: string;
7777
};
@@ -84,7 +84,6 @@ const CoinButtons = ({
8484
isSigningEnabled,
8585
isBridgeChain,
8686
isBuyableChain,
87-
defaultSwapsToken,
8887
classPrefix = 'coin',
8988
}: CoinButtonsProps) => {
9089
const t = useContext(I18nContext);
@@ -102,6 +101,15 @@ const CoinButtons = ({
102101
const currentChainId = useSelector(getCurrentChainId);
103102
const displayNewIconButtons = process.env.REMOVE_GNS;
104103

104+
const defaultSwapsToken = useSelector((state) =>
105+
getSwapsDefaultToken(state, chainId.toString()),
106+
);
107+
108+
// Pre-conditions
109+
if (isSwapsChain && defaultSwapsToken === undefined) {
110+
throw new Error('defaultSwapsToken is required');
111+
}
112+
105113
///: BEGIN:ONLY_INCLUDE_IF(multichain)
106114
const handleSendNonEvm = useHandleSendNonEvm();
107115
///: END:ONLY_INCLUDE_IF
@@ -286,17 +294,15 @@ const CoinButtons = ({
286294

287295
const handleBridgeOnClick = useCallback(
288296
async (isSwap: boolean) => {
289-
if (!defaultSwapsToken) {
290-
return;
291-
}
292297
await setCorrectChain();
298+
// Handle clicking from the wallet overview page
293299
openBridgeExperience(
294300
MetaMetricsSwapsEventSource.MainView,
295-
defaultSwapsToken,
301+
getNativeAssetForChainId(chainId),
296302
isSwap,
297303
);
298304
},
299-
[defaultSwapsToken, location, openBridgeExperience],
305+
[location, openBridgeExperience],
300306
);
301307

302308
const handleSwapOnClick = useCallback(async () => {

ui/components/app/wallet-overview/coin-overview.tsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import {
3939
getDataCollectionForMarketing,
4040
getMetaMetricsId,
4141
getParticipateInMetaMetrics,
42-
SwapsEthToken,
4342
getEnabledNetworksByNamespace,
4443
isGlobalNetworkSelectorRemoved,
4544
} from '../../../selectors';
@@ -72,8 +71,6 @@ export type CoinOverviewProps = {
7271
className?: string;
7372
classPrefix?: string;
7473
chainId: CaipChainId | Hex;
75-
// FIXME: This seems to be for Ethereum only
76-
defaultSwapsToken?: SwapsEthToken;
7774
isBridgeChain: boolean;
7875
isBuyableChain: boolean;
7976
isSwapsChain: boolean;
@@ -197,19 +194,13 @@ export const CoinOverview = ({
197194
className,
198195
classPrefix = 'coin',
199196
chainId,
200-
defaultSwapsToken,
201197
isBridgeChain,
202198
isBuyableChain,
203199
isSwapsChain,
204200
isSigningEnabled,
205201
}: CoinOverviewProps) => {
206202
const enabledNetworks = useSelector(getEnabledNetworksByNamespace);
207203

208-
// Pre-conditions
209-
if (isSwapsChain && defaultSwapsToken === undefined) {
210-
throw new Error('defaultSwapsToken is required');
211-
}
212-
213204
const t: ReturnType<typeof useI18nContext> = useContext(I18nContext);
214205

215206
const trackEvent = useContext(MetaMetricsContext);
@@ -355,7 +346,6 @@ export const CoinOverview = ({
355346
isSigningEnabled,
356347
isBridgeChain,
357348
isBuyableChain,
358-
defaultSwapsToken,
359349
classPrefix,
360350
}}
361351
/>

ui/components/app/wallet-overview/eth-overview.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
getIsSwapsChain,
1010
getSelectedInternalAccount,
1111
getSelectedAccountCachedBalance,
12-
getSwapsDefaultToken,
1312
getIsBridgeChain,
1413
} from '../../../selectors';
1514
import { getIsNativeTokenBuyable } from '../../../ducks/ramps';
@@ -18,8 +17,6 @@ import { CoinOverview } from './coin-overview';
1817
const EthOverview = ({ className }) => {
1918
const isBridgeChain = useSelector(getIsBridgeChain);
2019
const isBuyableChain = useSelector(getIsNativeTokenBuyable);
21-
// FIXME: This causes re-renders, so use isEqual to avoid this
22-
const defaultSwapsToken = useSelector(getSwapsDefaultToken, isEqual);
2320
const balanceIsCached = useSelector(isBalanceCached);
2421
const chainId = useSelector(getCurrentChainId);
2522
const balance = useSelector(getSelectedAccountCachedBalance);
@@ -43,7 +40,6 @@ const EthOverview = ({ className }) => {
4340
isSwapsChain={isSwapsChain}
4441
isBridgeChain={isBridgeChain}
4542
isBuyableChain={isBuyableChain}
46-
defaultSwapsToken={defaultSwapsToken}
4743
/>
4844
);
4945
};

ui/components/app/wallet-overview/non-evm-overview.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
getIsBridgeChain,
1111
///: END:ONLY_INCLUDE_IF
1212
getSelectedInternalAccount,
13-
getSwapsDefaultToken,
1413
} from '../../../selectors';
1514
import { CoinOverview } from './coin-overview';
1615

@@ -23,7 +22,6 @@ const NonEvmOverview = ({ className }: NonEvmOverviewProps) => {
2322
const balance = useSelector(getMultichainSelectedAccountCachedBalance);
2423
const account = useSelector(getSelectedInternalAccount);
2524
const isNativeTokenBuyable = useSelector(getIsNativeTokenBuyable);
26-
const defaultSwapsToken = useSelector(getSwapsDefaultToken);
2725

2826
let isSwapsChain = false;
2927
let isBridgeChain = false;
@@ -42,7 +40,6 @@ const NonEvmOverview = ({ className }: NonEvmOverviewProps) => {
4240
chainId={chainId}
4341
isSigningEnabled={true}
4442
isSwapsChain={isSwapsChain}
45-
defaultSwapsToken={defaultSwapsToken}
4643
isBridgeChain={isBridgeChain}
4744
isBuyableChain={isNativeTokenBuyable}
4845
/>

ui/components/multichain/account-overview/account-overview-layout.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useContext, useState, useCallback } from 'react';
22
import { useDispatch, useSelector } from 'react-redux';
3-
import { isEqual } from 'lodash';
43
import { useHistory } from 'react-router-dom';
54

65
import {
@@ -15,7 +14,6 @@ import { Carousel } from '..';
1514
import {
1615
getAppIsLoading,
1716
getSelectedAccount,
18-
getSwapsDefaultToken,
1917
///: BEGIN:ONLY_INCLUDE_IF(solana)
2018
hasCreatedSolanaAccount,
2119
///: END:ONLY_INCLUDE_IF
@@ -74,8 +72,6 @@ export const AccountOverviewLayout = ({
7472
const selectedSolanaAccount = useSelector(getLastSelectedSolanaAccount);
7573
///: END:ONLY_INCLUDE_IF
7674

77-
const defaultSwapsToken = useSelector(getSwapsDefaultToken, isEqual);
78-
7975
const [showDownloadMobileAppModal, setShowDownloadMobileAppModal] =
8076
useState(false);
8177

@@ -85,7 +81,8 @@ export const AccountOverviewLayout = ({
8581

8682
const handleCarouselClick = (id: string) => {
8783
if (id === 'bridge') {
88-
openBridgeExperience('Carousel', defaultSwapsToken);
84+
// Handle clicking from the wallet overview page carousel
85+
openBridgeExperience('Carousel');
8986
}
9087

9188
if (id === BASIC_FUNCTIONALITY_SLIDE.id) {

ui/hooks/bridge/useBridging.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
type BridgeAsset,
66
formatChainIdToCaip,
77
type GenericQuoteRequest,
8+
getNativeAssetForChainId,
89
UnifiedSwapBridgeEventName,
910
} from '@metamask/bridge-controller';
1011
import { trackUnifiedSwapBridgeEvent } from '../../ducks/bridge/actions';
@@ -26,9 +27,10 @@ import {
2627
PREPARE_SWAP_ROUTE,
2728
} from '../../helpers/constants/routes';
2829
import { BridgeQueryParams } from '../../../shared/lib/deep-links/routes/swap';
29-
import { getProviderConfig } from '../../../shared/modules/selectors/networks';
3030
import { trace, TraceName } from '../../../shared/lib/trace';
3131
import { toAssetId } from '../../../shared/lib/asset-utils';
32+
import { ALLOWED_BRIDGE_CHAIN_IDS_IN_CAIP } from '../../../shared/constants/bridge';
33+
import { getMultichainProviderConfig } from '../../selectors/multichain';
3234
import { useCrossChainSwapsEventTracker } from './useCrossChainSwapsEventTracker';
3335

3436
const useBridging = () => {
@@ -40,19 +42,30 @@ const useBridging = () => {
4042
const metaMetricsId = useSelector(getMetaMetricsId);
4143
const isMetaMetricsEnabled = useSelector(getParticipateInMetaMetrics);
4244
const isMarketingEnabled = useSelector(getDataCollectionForMarketing);
43-
const providerConfig = useSelector(getProviderConfig);
4445

45-
const isBridgeChain = useSelector(getIsBridgeChain);
46+
const providerConfig = useSelector(getMultichainProviderConfig);
4647

48+
const isBridgeChain = useSelector((state) =>
49+
getIsBridgeChain(state, providerConfig?.chainId),
50+
);
4751
const openBridgeExperience = useCallback(
4852
(
4953
location: string,
50-
token: Pick<BridgeAsset, 'symbol' | 'address'> & {
54+
srcToken?: Pick<BridgeAsset, 'symbol' | 'address'> & {
5155
chainId: GenericQuoteRequest['srcChainId'];
5256
},
5357
isSwap = false,
5458
) => {
55-
if (!isBridgeChain || !providerConfig) {
59+
const token =
60+
srcToken ?? getNativeAssetForChainId(providerConfig.chainId);
61+
const isBridgeToken =
62+
token?.chainId &&
63+
ALLOWED_BRIDGE_CHAIN_IDS_IN_CAIP.includes(
64+
formatChainIdToCaip(token.chainId),
65+
);
66+
const isChainOrTokenSupported = isBridgeChain || isBridgeToken;
67+
68+
if (!isChainOrTokenSupported || !providerConfig) {
5669
return;
5770
}
5871

ui/pages/asset/components/asset-page.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ import {
5555
getSelectedAccountNativeTokenCachedBalanceByChainId,
5656
getSelectedInternalAccount,
5757
getShowFiatInTestnets,
58-
getSwapsDefaultToken,
5958
} from '../../../selectors';
6059
import {
6160
getImageForChainId,
@@ -101,11 +100,6 @@ const AssetPage = ({
101100

102101
const isNative = type === AssetType.native;
103102

104-
// These need to be specific to the asset and not the current chain
105-
const defaultSwapsToken = useSelector(
106-
(state) => getSwapsDefaultToken(state, chainId),
107-
isEqual,
108-
);
109103
const isSwapsChain = useSelector((state) => getIsSwapsChain(state, chainId));
110104
const isBridgeChain = useSelector((state) =>
111105
getIsBridgeChain(state, chainId),
@@ -315,7 +309,6 @@ const AssetPage = ({
315309
isSwapsChain,
316310
isBridgeChain,
317311
chainId,
318-
defaultSwapsToken,
319312
}}
320313
/>
321314
) : (

ui/pages/asset/components/token-buttons.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,10 @@ const TokenButtons = ({
216216
const handleBridgeOnClick = useCallback(
217217
async (isSwap: boolean) => {
218218
await setCorrectChain();
219+
// Handle clicking from the asset details page
219220
openBridgeExperience(
220221
MetaMetricsSwapsEventSource.TokenView,
221-
{
222-
...token,
223-
},
222+
token,
224223
isSwap,
225224
);
226225
},

ui/selectors/selectors.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,6 +1832,7 @@ export function getWeb3ShimUsageStateForOrigin(state, origin) {
18321832
* `balance` and `string` values of the same type as in regular ERC-20 token
18331833
* objects, per the above description.
18341834
*
1835+
* @deprecated Use getNativeAssetForChainId instead because this only supports EVM chains
18351836
* @param {object} state - the redux state object
18361837
* @param {string} overrideChainId - the chainId to override the current chainId
18371838
* @returns {SwapsEthToken} The token object representation of the currently

0 commit comments

Comments
 (0)