From 328168a26341fabd86a0f79ff650e02d24018e8f Mon Sep 17 00:00:00 2001 From: tommasini Date: Mon, 7 Aug 2023 21:18:49 +0100 Subject: [PATCH 01/29] swaps when amount is insufficient --- app/components/UI/Swaps/index.js | 32 ++++++++- app/components/Views/SendFlow/Amount/index.js | 70 ++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/app/components/UI/Swaps/index.js b/app/components/UI/Swaps/index.js index 73af0449289..056aada1af9 100644 --- a/app/components/UI/Swaps/index.js +++ b/app/components/UI/Swaps/index.js @@ -206,6 +206,8 @@ function SwapsAmountView({ const explorer = useBlockExplorer(providerConfig, frequentRpcList); const initialSource = route.params?.sourceToken ?? SWAPS_NATIVE_ADDRESS; + const initialDestination = route.params?.destinationToken; + const [amount, setAmount] = useState('0'); const [slippage, setSlippage] = useState(AppConstants.SWAPS.DEFAULT_SLIPPAGE); const [isInitialLoadingTokens, setInitialLoadingTokens] = useState(false); @@ -217,13 +219,18 @@ function SwapsAmountView({ ), ), ); + const [isDestinationSet, setIsDestinationSet] = useState(false); const [sourceToken, setSourceToken] = useState(() => swapsTokens?.find((token) => toLowerCaseEquals(token.address, initialSource), ), ); - const [destinationToken, setDestinationToken] = useState(null); + const [destinationToken, setDestinationToken] = useState( + swapsTokens?.find((token) => + toLowerCaseEquals(token.address, initialDestination), + ), + ); const [hasDismissedTokenAlert, setHasDismissedTokenAlert] = useState(true); const [contractBalance, setContractBalance] = useState(null); const [contractBalanceAsUnits, setContractBalanceAsUnits] = useState( @@ -365,6 +372,29 @@ function SwapsAmountView({ swapsTokens, ]); + useEffect(() => { + if ( + !isDestinationSet && + initialDestination && + swapsControllerTokens && + swapsTokens?.length > 0 && + !destinationToken + ) { + setIsDestinationSet(true); + setDestinationToken( + swapsTokens.find((token) => + toLowerCaseEquals(token.address, initialDestination), + ), + ); + } + }, [ + initialDestination, + isDestinationSet, + destinationToken, + swapsControllerTokens, + swapsTokens, + ]); + useEffect(() => { setHasDismissedTokenAlert(false); }, [destinationToken]); diff --git a/app/components/Views/SendFlow/Amount/index.js b/app/components/Views/SendFlow/Amount/index.js index cd66328afbb..5308437edb5 100644 --- a/app/components/Views/SendFlow/Amount/index.js +++ b/app/components/Views/SendFlow/Amount/index.js @@ -89,6 +89,7 @@ import { } from '../../../../../wdio/screen-objects/testIDs/Screens/AmountScreen.testIds.js'; import generateTestId from '../../../../../wdio/utils/generateTestId'; import { + selectChainId, selectProviderType, selectTicker, } from '../../../../selectors/networkController'; @@ -103,6 +104,13 @@ import { selectContractBalances } from '../../../../selectors/tokenBalancesContr import { selectSelectedAddress } from '../../../../selectors/preferencesController'; import { PREFIX_HEX_STRING } from '../../../../constants/transaction'; import Routes from '../../../../constants/navigation/Routes'; +import Button from '../../../../component-library/components/Buttons/Button/Button'; +import { ButtonVariants } from '../../../../component-library/components/Buttons/Button'; +import { isNetworkBuySupported } from '../../../UI/Ramp/utils'; +import { getRampNetworks } from '../../../../reducers/fiatOrders'; +import { swapsLivenessSelector } from '../../../../reducers/swaps'; +import { isSwapsAllowed } from '../../../../components/UI/Swaps/utils'; +import { swapsUtils } from '@metamask/swaps-controller'; const KEYBOARD_OFFSET = Device.isSmallDevice() ? 80 : 120; @@ -342,6 +350,7 @@ const createStyles = (colors) => marginTop: 20, marginHorizontal: 20, }, + swapOrBuyButton: { width: '100%', marginTop: 16 }, }); /** @@ -437,6 +446,18 @@ class Amount extends PureComponent { * Resets transaction state */ resetTransaction: PropTypes.func, + /** + * Boolean that indicates if the network supports buy + */ + isNetworkBuySupported: PropTypes.bool, + /** + * Boolean that indicates if the swap is live + */ + swapsIsLive: PropTypes.bool, + /** + * String that indicates the current chain id + */ + chainId: PropTypes.string, }; state = { @@ -1191,10 +1212,30 @@ class Amount extends PureComponent { internalPrimaryCurrencyIsCrypto, currentBalance, } = this.state; - const { currentCurrency } = this.props; + const { + currentCurrency, + selectedAsset, + navigation, + isNetworkBuySupported, + swapsIsLive, + chainId, + } = this.props; const colors = this.context.colors || mockTheme.colors; const themeAppearance = this.context.themeAppearance || 'light'; const styles = createStyles(colors); + const navigateToSwap = () => { + navigation.replace('Swaps', { + screen: 'SwapsAmountView', + params: { + sourceToken: swapsUtils.NATIVE_SWAPS_TOKEN_ADDRESS, + destinationToken: selectedAsset.address, + }, + }); + }; + + const navigateToBuy = () => { + navigation.navigate(Routes.FIAT_ON_RAMP_AGGREGATOR.ID); + }; return ( @@ -1259,6 +1300,27 @@ class Amount extends PureComponent { {...generateTestId(Platform, AMOUNT_ERROR)} > + {isNetworkBuySupported && selectedAsset.isETH && ( +