From 67aa6aad5e785d1ee7e94e6e32deb3067aeace80 Mon Sep 17 00:00:00 2001 From: Micaela Estabillo <100321200+micaelae@users.noreply.github.com> Date: Wed, 19 Feb 2025 10:25:38 -0800 Subject: [PATCH] chore: set swap input parameters (#30284) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Modifying bridge input component logic to allow fetching swap quotes [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30284?quickstart=1) ## **Related issues** Fixes:NA ## **Manual testing steps** 1. Load flask build and activate non-EVM chain 3. Click "Swap" 4. Page should match Swap mocks (using Bridge ui) 5. Select dest token 6. "Switch inputs" button should be enabled and switch token selections on click 7. Verify that quotes are fetched in the background 8. Bridge experience should not be affected ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [X] 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). - [X] 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. --- .../controllers/bridge/bridge-controller.ts | 4 +- .../components/bridge-asset-picker-button.tsx | 4 +- .../bridge/prepare/prepare-bridge-page.tsx | 137 ++++++++++-------- 3 files changed, 80 insertions(+), 65 deletions(-) diff --git a/app/scripts/controllers/bridge/bridge-controller.ts b/app/scripts/controllers/bridge/bridge-controller.ts index 90a2a4dee193..27d7f230805d 100644 --- a/app/scripts/controllers/bridge/bridge-controller.ts +++ b/app/scripts/controllers/bridge/bridge-controller.ts @@ -207,9 +207,7 @@ export default class BridgeController extends StaticIntervalPollingController
{ this.#abortController?.abort('New quote request'); this.#abortController = new AbortController(); - if (updatedQuoteRequest.srcChainId === updatedQuoteRequest.destChainId) { - return; - } + const { bridgeState } = this.state; this.update((_state) => { _state.bridgeState = { diff --git a/ui/pages/bridge/prepare/components/bridge-asset-picker-button.tsx b/ui/pages/bridge/prepare/components/bridge-asset-picker-button.tsx index b04da2b981fa..8296a950f541 100644 --- a/ui/pages/bridge/prepare/components/bridge-asset-picker-button.tsx +++ b/ui/pages/bridge/prepare/components/bridge-asset-picker-button.tsx @@ -68,9 +68,9 @@ export const BridgeAssetPickerButton = ({ diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.tsx index affc55ccde9f..afc6ad6886c1 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.tsx @@ -178,6 +178,8 @@ const PrepareBridgePage = () => { const millisecondsUntilNextRefresh = useCountdownTimer(); + const isSwap = useIsMultichainSwap(); + const [rotateSwitchTokens, setRotateSwitchTokens] = useState(false); // Resets the banner visibility when the estimated return is low @@ -275,9 +277,10 @@ const PrepareBridgePage = () => { srcChainId: fromChain?.chainId ? Number(hexToDecimal(fromChain.chainId)) : undefined, - destChainId: toChain?.chainId - ? Number(hexToDecimal(toChain.chainId)) - : undefined, + destChainId: + isSwap && fromChain?.chainId + ? Number(hexToDecimal(fromChain.chainId)) + : toChain?.chainId && Number(hexToDecimal(toChain.chainId)), // This override allows quotes to be returned when the rpcUrl is a tenderly fork // Otherwise quotes get filtered out by the bridge-api when the wallet's real // balance is less than the tenderly balance @@ -285,6 +288,7 @@ const PrepareBridgePage = () => { slippage, }), [ + isSwap, fromToken, toToken, fromChain?.chainId, @@ -366,8 +370,6 @@ const PrepareBridgePage = () => { } }, [fromChain, fromToken, fromTokens, search, isFromTokensLoading]); - const isSwap = useIsMultichainSwap(); - return ( { value: token.address, }); }} - networkProps={{ - network: fromChain, - networks: fromChains, - onNetworkChange: (networkConfig) => { - networkConfig.chainId !== fromChain?.chainId && - trackInputEvent({ - input: 'chain_source', - value: networkConfig.chainId, - }); - if (networkConfig.chainId === toChain?.chainId) { - dispatch(setToChainId(null)); - dispatch(setToToken(null)); - } - if (isNetworkAdded(networkConfig)) { - dispatch( - setActiveNetwork( - networkConfig.rpcEndpoints[ - networkConfig.defaultRpcEndpointIndex - ].networkClientId, - ), - ); - } - dispatch(setFromToken(null)); - dispatch(setFromTokenInputValue(null)); - }, - header: t('yourNetworks'), - }} - isMultiselectEnabled + networkProps={ + isSwap + ? undefined + : { + network: fromChain, + networks: fromChains, + onNetworkChange: (networkConfig) => { + networkConfig.chainId !== fromChain?.chainId && + trackInputEvent({ + input: 'chain_source', + value: networkConfig.chainId, + }); + if (networkConfig.chainId === toChain?.chainId) { + dispatch(setToChainId(null)); + dispatch(setToToken(null)); + } + if (isNetworkAdded(networkConfig)) { + dispatch( + setActiveNetwork( + networkConfig.rpcEndpoints[ + networkConfig.defaultRpcEndpointIndex + ].networkClientId, + ), + ); + } + dispatch(setFromToken(null)); + dispatch(setFromTokenInputValue(null)); + }, + header: t('yourNetworks'), + } + } + isMultiselectEnabled={!isSwap} onMaxButtonClick={(value: string) => { dispatch(setFromTokenInputValue(value)); }} @@ -468,10 +474,10 @@ const PrepareBridgePage = () => { disabled={ isSwitchingTemporarilyDisabled || !isValidQuoteRequest(quoteRequest, false) || - !isNetworkAdded(toChain) + (!isSwap && !isNetworkAdded(toChain)) } onClick={() => { - if (!isNetworkAdded(toChain)) { + if (!isSwap && !isNetworkAdded(toChain)) { return; } setRotateSwitchTokens(!rotateSwitchTokens); @@ -480,15 +486,19 @@ const PrepareBridgePage = () => { event: MetaMetricsEventName.InputSourceDestinationFlipped, properties: flippedRequestProperties, }); - const toChainClientId = - toChain?.defaultRpcEndpointIndex !== undefined && - toChain?.rpcEndpoints - ? toChain.rpcEndpoints[toChain.defaultRpcEndpointIndex] - .networkClientId - : undefined; - toChainClientId && dispatch(setActiveNetwork(toChainClientId)); + if (!isSwap) { + // Only flip networks if bridging + const toChainClientId = + toChain?.defaultRpcEndpointIndex !== undefined && + toChain?.rpcEndpoints && + isNetworkAdded(toChain) + ? toChain.rpcEndpoints[toChain.defaultRpcEndpointIndex] + .networkClientId + : undefined; + toChainClientId && dispatch(setActiveNetwork(toChainClientId)); + fromChain?.chainId && dispatch(setToChainId(fromChain.chainId)); + } dispatch(setFromToken(toToken)); - fromChain?.chainId && dispatch(setToChainId(fromChain.chainId)); dispatch(setToToken(fromToken)); }} /> @@ -505,23 +515,30 @@ const PrepareBridgePage = () => { }); dispatch(setToToken(token)); }} - networkProps={{ - network: toChain, - networks: toChains, - onNetworkChange: (networkConfig) => { - networkConfig.chainId !== toChain?.chainId && - trackInputEvent({ - input: 'chain_destination', - value: networkConfig.chainId, - }); - dispatch(setToChainId(networkConfig.chainId)); - dispatch(setToToken(null)); - }, - header: isSwap ? t('swapSwapTo') : t('bridgeTo'), - shouldDisableNetwork: ({ chainId }) => - chainId === fromChain?.chainId, - }} - customTokenListGenerator={toChain ? toTokenListGenerator : undefined} + networkProps={ + isSwap + ? undefined + : { + network: toChain, + networks: toChains, + onNetworkChange: (networkConfig) => { + networkConfig.chainId !== toChain?.chainId && + trackInputEvent({ + input: 'chain_destination', + value: networkConfig.chainId, + }); + dispatch(setToChainId(networkConfig.chainId)); + dispatch(setToToken(null)); + }, + header: isSwap ? t('swapSwapTo') : t('bridgeTo'), + shouldDisableNetwork: ({ chainId }) => + chainId === fromChain?.chainId, + } + } + customTokenListGenerator={ + // TODO use custom generator when we have a way to get all tokens for an unimported chain + toChain && !isSwap ? toTokenListGenerator : undefined + } amountInFiat={ activeQuote?.toTokenAmount?.valueInCurrency || undefined }