diff --git a/packages/suite-desktop-ui/src/support/Router.tsx b/packages/suite-desktop-ui/src/support/Router.tsx index 3dd34e139e1..1af5091d11c 100644 --- a/packages/suite-desktop-ui/src/support/Router.tsx +++ b/packages/suite-desktop-ui/src/support/Router.tsx @@ -18,9 +18,11 @@ import WalletAnonymize from 'src/views/wallet/anonymize'; import WalletCoinmarketBuy from 'src/views/wallet/coinmarket/buy'; import WalletCoinmarketBuyDetail from 'src/views/wallet/coinmarket/buy/detail'; import WalletCoinmarketBuyOffers from 'src/views/wallet/coinmarket/buy/offers'; +import { CoinmarketBuyConfirm } from 'src/views/wallet/coinmarket/buy/CoinmarketBuyConfirm'; import { CoinmarketSellForm } from 'src/views/wallet/coinmarket/sell_new/CoinmarketSellForm'; import WalletCoinmarketSellDetail from 'src/views/wallet/coinmarket/sell_new/detail'; import { CoinmarketSellOffers } from 'src/views/wallet/coinmarket/sell_new/CoinmarketSellOffers'; +import { CoinmarketSellConfirm } from 'src/views/wallet/coinmarket/sell_new/CoinmarketSellConfirm'; import WalletCoinmarketExchange from 'src/views/wallet/coinmarket/exchange'; import WalletCoinmarketExchangeDetail from 'src/views/wallet/coinmarket/exchange/detail'; import WalletCoinmarketExchangeOffers from 'src/views/wallet/coinmarket/exchange/offers'; @@ -49,9 +51,11 @@ const components: { [key: string]: ComponentType } = { 'wallet-coinmarket-buy': WalletCoinmarketBuy, 'wallet-coinmarket-buy-detail': WalletCoinmarketBuyDetail, 'wallet-coinmarket-buy-offers': WalletCoinmarketBuyOffers, + 'wallet-coinmarket-buy-confirm': CoinmarketBuyConfirm, 'wallet-coinmarket-sell': CoinmarketSellForm, 'wallet-coinmarket-sell-detail': WalletCoinmarketSellDetail, 'wallet-coinmarket-sell-offers': CoinmarketSellOffers, + 'wallet-coinmarket-sell-confirm': CoinmarketSellConfirm, 'wallet-coinmarket-exchange': WalletCoinmarketExchange, 'wallet-coinmarket-exchange-detail': WalletCoinmarketExchangeDetail, 'wallet-coinmarket-exchange-offers': WalletCoinmarketExchangeOffers, diff --git a/packages/suite-web/e2e/tests/coinmarket/buy.test.ts b/packages/suite-web/e2e/tests/coinmarket/buy.test.ts index 80802a89418..d9a618e93b9 100644 --- a/packages/suite-web/e2e/tests/coinmarket/buy.test.ts +++ b/packages/suite-web/e2e/tests/coinmarket/buy.test.ts @@ -14,7 +14,7 @@ describe('Coinmarket buy', () => { let { href } = win.location; // simulate redirect from partner back to Suite, prefix independent href = href.replace( - '/accounts/coinmarket/buy/offers#/btc/0', + '/accounts/coinmarket/buy/confirm#/btc/0', '/coinmarket-redirect#detail/btc/normal/0/mockedPaymentId3', ); win.location.href = href; diff --git a/packages/suite-web/src/support/Router.tsx b/packages/suite-web/src/support/Router.tsx index 1b2ed7f310d..803747f85e9 100644 --- a/packages/suite-web/src/support/Router.tsx +++ b/packages/suite-web/src/support/Router.tsx @@ -58,6 +58,11 @@ const components: Record>> = { 'wallet-coinmarket-buy-offers': lazy( () => import(/* webpackChunkName: "coinmarket" */ 'src/views/wallet/coinmarket/buy/offers'), ), + 'wallet-coinmarket-buy-confirm': lazy(() => + import( + /* webpackChunkName: "coinmarket" */ 'src/views/wallet/coinmarket/buy/CoinmarketBuyConfirm' + ).then(({ CoinmarketBuyConfirm }) => ({ default: CoinmarketBuyConfirm })), + ), 'wallet-coinmarket-sell': lazy(() => import( /* webpackChunkName: "coinmarket" */ 'src/views/wallet/coinmarket/sell_new/CoinmarketSellForm' @@ -74,6 +79,11 @@ const components: Record>> = { /* webpackChunkName: "coinmarket" */ 'src/views/wallet/coinmarket/sell_new/CoinmarketSellOffers' ).then(({ CoinmarketSellOffers }) => ({ default: CoinmarketSellOffers })), ), + 'wallet-coinmarket-sell-confirm': lazy(() => + import( + /* webpackChunkName: "coinmarket" */ 'src/views/wallet/coinmarket/sell_new/CoinmarketSellConfirm' + ).then(({ CoinmarketSellConfirm }) => ({ default: CoinmarketSellConfirm })), + ), 'wallet-coinmarket-exchange': lazy( () => import(/* webpackChunkName: "coinmarket" */ 'src/views/wallet/coinmarket/exchange'), ), diff --git a/packages/suite/src/actions/wallet/coinmarketBuyActions.ts b/packages/suite/src/actions/wallet/coinmarketBuyActions.ts index c7e12eed686..ac19bd4fbcd 100644 --- a/packages/suite/src/actions/wallet/coinmarketBuyActions.ts +++ b/packages/suite/src/actions/wallet/coinmarketBuyActions.ts @@ -42,6 +42,7 @@ export type CoinmarketBuyAction = type: typeof COINMARKET_BUY.SAVE_QUOTES; quotes: BuyTrade[]; } + | { type: typeof COINMARKET_BUY.SAVE_QUOTE; quote: BuyTrade | undefined } | { type: typeof COINMARKET_BUY.CLEAR_QUOTES } | { type: typeof COINMARKET_COMMON.SAVE_TRADE; @@ -176,6 +177,11 @@ export const saveQuotes = (quotes: BuyTrade[]): CoinmarketBuyAction => ({ quotes, }); +export const saveSelectedQuote = (quote: BuyTrade | undefined): CoinmarketBuyAction => ({ + type: COINMARKET_BUY.SAVE_QUOTE, + quote, +}); + export const clearQuotes = (): CoinmarketBuyAction => ({ type: COINMARKET_BUY.CLEAR_QUOTES, }); diff --git a/packages/suite/src/actions/wallet/coinmarketSellActions.ts b/packages/suite/src/actions/wallet/coinmarketSellActions.ts index 53d45605856..b01e3d2d850 100644 --- a/packages/suite/src/actions/wallet/coinmarketSellActions.ts +++ b/packages/suite/src/actions/wallet/coinmarketSellActions.ts @@ -28,6 +28,10 @@ export type CoinmarketSellAction = type: typeof COINMARKET_SELL.SAVE_QUOTES; quotes: SellFiatTrade[]; } + | { + type: typeof COINMARKET_SELL.SAVE_QUOTE; + quote: SellFiatTrade | undefined; + } | { type: typeof COINMARKET_SELL.CLEAR_QUOTES } | { type: typeof COINMARKET_COMMON.SAVE_TRADE; @@ -108,6 +112,11 @@ export const saveQuotes = (quotes: SellFiatTrade[]): CoinmarketSellAction => ({ quotes, }); +export const saveSelectedQuote = (quote: SellFiatTrade | undefined): CoinmarketSellAction => ({ + type: COINMARKET_SELL.SAVE_QUOTE, + quote, +}); + export const clearQuotes = (): CoinmarketSellAction => ({ type: COINMARKET_SELL.CLEAR_QUOTES, }); diff --git a/packages/suite/src/actions/wallet/constants/coinmarketBuyConstants.ts b/packages/suite/src/actions/wallet/constants/coinmarketBuyConstants.ts index b0b2f2686b8..0c01fd338c5 100644 --- a/packages/suite/src/actions/wallet/constants/coinmarketBuyConstants.ts +++ b/packages/suite/src/actions/wallet/constants/coinmarketBuyConstants.ts @@ -3,6 +3,7 @@ export const SAVE_QUOTE_REQUEST = '@coinmarket-buy/save_buy_quote_request'; export const SAVE_TRANSACTION_DETAIL_ID = '@coinmarket-buy/save_transaction_detail_id'; export const SET_IS_FROM_REDIRECT = '@coinmarket-buy/set_is_from_redirect'; export const SAVE_QUOTES = '@coinmarket-buy/save_buy_quotes'; +export const SAVE_QUOTE = '@coinmarket-buy/save_buy_quote'; export const CLEAR_QUOTES = '@coinmarket-buy/clear_buy_quotes'; export const VERIFY_ADDRESS = '@coinmarket-buy/verify_address'; export const SAVE_TRANSACTION_ID = '@coinmarket-buy/save_transaction_id'; diff --git a/packages/suite/src/actions/wallet/constants/coinmarketSellConstants.ts b/packages/suite/src/actions/wallet/constants/coinmarketSellConstants.ts index ad5a255f687..a460f564831 100644 --- a/packages/suite/src/actions/wallet/constants/coinmarketSellConstants.ts +++ b/packages/suite/src/actions/wallet/constants/coinmarketSellConstants.ts @@ -1,6 +1,7 @@ export const SAVE_SELL_INFO = '@coinmarket-sell/save_sell_info'; export const SAVE_QUOTE_REQUEST = '@coinmarket-sell/save_quote_request'; export const SAVE_QUOTES = '@coinmarket-sell/save_quotes'; +export const SAVE_QUOTE = '@coinmarket-sell/save_quote'; export const CLEAR_QUOTES = '@coinmarket-sell/clear_quotes'; export const SAVE_TRANSACTION_ID = '@coinmarket-sell/save_transaction_id'; export const SET_IS_FROM_REDIRECT = '@coinmarket-sell/set_is_from_redirect'; diff --git a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketBuyForm.tsx b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketBuyForm.tsx index dd0f92376e3..56fa2f938a1 100644 --- a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketBuyForm.tsx +++ b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketBuyForm.tsx @@ -48,26 +48,18 @@ const useCoinmarketBuyForm = ({ pageType = 'form', }: UseCoinmarketFormProps): CoinmarketBuyFormContextProps => { const type = 'buy'; - const isPageOffers = pageType === 'offers'; + const isNotFormPage = pageType !== 'form'; const dispatch = useDispatch(); - const { addressVerified, buyInfo, isFromRedirect, quotes, quotesRequest } = useSelector( - state => state.wallet.coinmarket.buy, - ); - const { - callInProgress, - account, - selectedQuote, - timer, - device, - setCallInProgress, - setSelectedQuote, - checkQuotesTimer, - } = useCoinmarketCommonOffers({ selectedAccount, type }); + const { addressVerified, buyInfo, isFromRedirect, quotes, quotesRequest, selectedQuote } = + useSelector(state => state.wallet.coinmarket.buy); + const { callInProgress, account, timer, device, setCallInProgress, checkQuotesTimer } = + useCoinmarketCommonOffers({ selectedAccount, type }); const { paymentMethods, getPaymentMethods, getQuotesByPaymentMethod } = useCoinmarketPaymentMethod(); const { saveTrade, saveQuotes, + saveSelectedQuote, setIsFromRedirect, openCoinmarketBuyConfirmModal, addNotification, @@ -81,6 +73,7 @@ const useCoinmarketBuyForm = ({ } = useActions({ saveTrade: coinmarketBuyActions.saveTrade, saveQuotes: coinmarketBuyActions.saveQuotes, + saveSelectedQuote: coinmarketBuyActions.saveSelectedQuote, setIsFromRedirect: coinmarketBuyActions.setIsFromRedirect, openCoinmarketBuyConfirmModal: coinmarketBuyActions.openCoinmarketBuyConfirmModal, addNotification: notificationsActions.addToast, @@ -92,12 +85,13 @@ const useCoinmarketBuyForm = ({ saveQuoteRequest: coinmarketBuyActions.saveQuoteRequest, saveCachedAccountInfo: coinmarketBuyActions.saveCachedAccountInfo, }); - const { navigateToBuyForm, navigateToBuyOffers } = useCoinmarketNavigation(account); + const { navigateToBuyForm, navigateToBuyOffers, navigateToBuyOffer } = + useCoinmarketNavigation(account); // states const [amountLimits, setAmountLimits] = useState(undefined); const [innerQuotes, setInnerQuotes] = useState( - isPageOffers ? quotes : undefined, + isNotFormPage ? quotes : undefined, ); const [isSubmittingHelper, setIsSubmittingHelper] = useState(false); const abortControllerRef = useRef(null); @@ -131,14 +125,14 @@ const useCoinmarketBuyForm = ({ } : null; - const isDraft = !!draftUpdated || !!isPageOffers; + const isDraft = !!draftUpdated || !!isNotFormPage; const methods = useForm({ mode: 'onChange', defaultValues: isDraft && draftUpdated ? draftUpdated : defaultValues, }); const { register, control, formState, reset, setValue, handleSubmit } = methods; const values = useWatch({ control }); - const previousValues = useRef(isPageOffers ? draftUpdated : null); + const previousValues = useRef(isNotFormPage ? draftUpdated : null); // form states const formIsValid = Object.keys(formState.errors).length === 0; @@ -327,12 +321,14 @@ const useCoinmarketBuyForm = ({ }); } } else { - setSelectedQuote(quote); + saveSelectedQuote(quote); dispatch({ type: SET_MODAL_CRYPTO_CURRENCY, modalCryptoSymbol: quote.receiveCurrency, }); timer.stop(); + + navigateToBuyOffer(); } } } @@ -405,7 +401,7 @@ const useCoinmarketBuyForm = ({ previousValues.current = values; } - }, [previousValues, values, handleChange, handleSubmit, isPageOffers]); + }, [previousValues, values, handleChange, handleSubmit, isNotFormPage]); useEffect(() => { // when draft doesn't exist, we need to bind actual default values - that happens when we've got buyInfo from Invity API server diff --git a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketSellForm.ts b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketSellForm.ts index d7e001e9e7b..72265dd3c7b 100644 --- a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketSellForm.ts +++ b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketSellForm.ts @@ -64,14 +64,21 @@ export const useCoinmarketSellForm = ({ pageType = 'form', }: UseCoinmarketFormProps): CoinmarketSellFormContextProps => { const type = 'sell'; - const isPageOffers = pageType === 'offers'; + const isNotFormPage = pageType !== 'form'; const dispatch = useDispatch(); - const { sellInfo, quotesRequest, isFromRedirect, quotes, transactionId, coinmarketAccount } = - useSelector(state => state.wallet.coinmarket.sell); + const { + sellInfo, + quotesRequest, + isFromRedirect, + quotes, + transactionId, + coinmarketAccount, + selectedQuote, + } = useSelector(state => state.wallet.coinmarket.sell); // selectedAccount is used as initial state if this is form page // coinmarketAccount is used on offers page const [account, setAccount] = useState(() => { - if (coinmarketAccount && isPageOffers) { + if (coinmarketAccount && isNotFormPage) { return coinmarketAccount; } @@ -79,15 +86,8 @@ export const useCoinmarketSellForm = ({ }); const { translationString } = useTranslation(); - const { - callInProgress, - selectedQuote, - timer, - device, - setCallInProgress, - setSelectedQuote, - checkQuotesTimer, - } = useCoinmarketCommonOffers({ selectedAccount, type }); + const { callInProgress, timer, device, setCallInProgress, checkQuotesTimer } = + useCoinmarketCommonOffers({ selectedAccount, type }); const { paymentMethods, getPaymentMethods, getQuotesByPaymentMethod } = useCoinmarketPaymentMethod(); const { @@ -99,6 +99,7 @@ export const useCoinmarketSellForm = ({ goto, saveTrade, saveQuotes, + saveSelectedQuote, setIsFromRedirect, saveQuoteRequest, saveTransactionId, @@ -110,6 +111,7 @@ export const useCoinmarketSellForm = ({ goto: routerActions.goto, saveTrade: coinmarketSellActions.saveTrade, saveQuotes: coinmarketSellActions.saveQuotes, + saveSelectedQuote: coinmarketSellActions.saveSelectedQuote, setIsFromRedirect: coinmarketSellActions.setIsFromRedirect, saveQuoteRequest: coinmarketSellActions.saveQuoteRequest, saveTransactionId: coinmarketSellActions.saveTransactionId, @@ -120,7 +122,8 @@ export const useCoinmarketSellForm = ({ savePaymentMethods: coinmarketInfoActions.savePaymentMethods, }); const accounts = useSelector(selectAccounts); - const { navigateToSellForm, navigateToSellOffers } = useCoinmarketNavigation(account); + const { navigateToSellForm, navigateToSellOffers, navigateToSellOffer } = + useCoinmarketNavigation(account); const { symbol, networkType } = account; const localCurrency = useSelector(selectLocalCurrency); @@ -162,7 +165,7 @@ export const useCoinmarketSellForm = ({ const draft = getDraft(sellDraftKey); // eslint-disable-next-line no-nested-ternary const draftUpdated: CoinmarketSellFormProps | null = draft - ? isPageOffers + ? isNotFormPage ? { ...draft, fiatInput: draft.fiatInput && draft.fiatInput !== '' ? draft.fiatInput : '', @@ -191,7 +194,7 @@ export const useCoinmarketSellForm = ({ formState, } = methods; const values = useWatch({ control }); - const previousValues = useRef(isPageOffers ? draftUpdated : null); + const previousValues = useRef(isNotFormPage ? draftUpdated : null); const initState = useCoinmarketCommonFormState({ account, @@ -416,7 +419,7 @@ export const useCoinmarketSellForm = ({ previousValues.current = values; } - }, [previousValues, values, handleChange, handleSubmit, isPageOffers]); + }, [previousValues, values, handleChange, handleSubmit, isNotFormPage]); const doSellTrade = async (quote: SellFiatTrade) => { const provider = @@ -434,6 +437,7 @@ export const useCoinmarketSellForm = ({ { selectedFee: selectedFeeRecomposedAndSigned, composed }, orderId, ); + const response = await invityAPI.doSellTrade({ trade: { ...quote, refundAddress: getUnusedAddressFromAccount(account).address }, returnUrl, @@ -459,7 +463,7 @@ export const useCoinmarketSellForm = ({ if (provider.flow === 'PAYMENT_GATE') { dispatch(saveTrade(response.trade, account, new Date().toISOString())); dispatch(saveTransactionId(response.trade.orderId)); - setSelectedQuote(response.trade); + saveSelectedQuote(response.trade); setSellStep('SEND_TRANSACTION'); } // dispatch(submitRequestForm(response.tradeForm?.form)); @@ -479,7 +483,6 @@ export const useCoinmarketSellForm = ({ }), ); }; - const needToRegisterOrVerifyBankAccount = (quote: SellFiatTrade) => { const provider = sellInfo?.providerInfos && quote.exchange @@ -515,13 +518,10 @@ export const useCoinmarketSellForm = ({ ); if (result) { - // empty quoteId means the partner requests login first, requestTrade to get login screen - if (!quote.quoteId || needToRegisterOrVerifyBankAccount(quote)) { - doSellTrade(quote); - } else { - setSelectedQuote(quote); - timer.stop(); - } + saveSelectedQuote(quote); + timer.stop(); + + navigateToSellOffer(); } } }; @@ -531,7 +531,7 @@ export const useCoinmarketSellForm = ({ const quote = { ...selectedQuote, bankAccount }; const response = await doSellTrade(quote); if (response) { - setSelectedQuote(response); + saveSelectedQuote(response); setSellStep('SEND_TRANSACTION'); } }; @@ -692,7 +692,7 @@ export const useCoinmarketSellForm = ({ if (!isDraft && sellInfo && !formState.isDirty) { reset(defaultValues); } - }, [reset, sellInfo, defaultValues, isDraft, isPageOffers, formState.isDirty]); + }, [reset, sellInfo, defaultValues, isDraft, isNotFormPage, formState.isDirty]); useDebounce( () => { @@ -719,6 +719,15 @@ export const useCoinmarketSellForm = ({ ], ); + useDebounce(() => { + if (selectedQuote && pageType === 'confirm') { + // empty quoteId means the partner requests login first, requestTrade to get login screen + if (!selectedQuote.quoteId || needToRegisterOrVerifyBankAccount(selectedQuote)) { + doSellTrade(selectedQuote); + } + } + }, 50); + useEffect(() => { if (!quotesRequest) { navigateToSellForm(); @@ -728,7 +737,7 @@ export const useCoinmarketSellForm = ({ if (isFromRedirect) { if (transactionId && trade) { - setSelectedQuote(trade.data); + saveSelectedQuote(trade.data); setSellStep('SEND_TRANSACTION'); } @@ -746,7 +755,7 @@ export const useCoinmarketSellForm = ({ dispatch, navigateToSellForm, checkQuotesTimer, - setSelectedQuote, + saveSelectedQuote, setIsFromRedirect, handleChange, ]); diff --git a/packages/suite/src/hooks/wallet/useCoinmarketNavigation.ts b/packages/suite/src/hooks/wallet/useCoinmarketNavigation.ts index 9d905b74d9d..cc512cf44cd 100644 --- a/packages/suite/src/hooks/wallet/useCoinmarketNavigation.ts +++ b/packages/suite/src/hooks/wallet/useCoinmarketNavigation.ts @@ -27,6 +27,7 @@ export const useCoinmarketNavigation = (account: Account) => { navigateToBuyForm: useNavigateToRouteName('wallet-coinmarket-buy'), navigateToBuyOffers: useNavigateToRouteName('wallet-coinmarket-buy-offers'), navigateToBuyDetail: useNavigateToRouteName('wallet-coinmarket-buy-detail'), + navigateToBuyOffer: useNavigateToRouteName('wallet-coinmarket-buy-confirm'), navigateToExchangeForm: useNavigateToRouteName('wallet-coinmarket-exchange'), navigateToExchangeOffers: useNavigateToRouteName('wallet-coinmarket-exchange-offers'), @@ -34,5 +35,6 @@ export const useCoinmarketNavigation = (account: Account) => { navigateToSellForm: useNavigateToRouteName('wallet-coinmarket-sell'), navigateToSellOffers: useNavigateToRouteName('wallet-coinmarket-sell-offers'), + navigateToSellOffer: useNavigateToRouteName('wallet-coinmarket-sell-confirm'), }; }; diff --git a/packages/suite/src/hooks/wallet/useCoinmarketRedirect.ts b/packages/suite/src/hooks/wallet/useCoinmarketRedirect.ts index 37f07dd60cc..57d9e1a6967 100644 --- a/packages/suite/src/hooks/wallet/useCoinmarketRedirect.ts +++ b/packages/suite/src/hooks/wallet/useCoinmarketRedirect.ts @@ -73,7 +73,7 @@ export const useCoinmarketRedirect = () => { dispatch(coinmarketBuyActions.saveQuoteRequest(request)); dispatch(coinmarketBuyActions.setIsFromRedirect(true)); dispatch( - goto('wallet-coinmarket-buy-offers', { + goto('wallet-coinmarket-buy-confirm', { params: { symbol, accountIndex: index, accountType }, }), ); @@ -120,7 +120,7 @@ export const useCoinmarketRedirect = () => { dispatch(saveComposedTransactionInfo({ selectedFee: selectedFee || 'normal', composed })); dispatch(coinmarketSellActions.saveTransactionId(orderId)); dispatch( - goto('wallet-coinmarket-sell-offers', { + goto('wallet-coinmarket-sell-confirm', { params: { symbol, accountIndex: index, accountType }, }), ); diff --git a/packages/suite/src/reducers/wallet/coinmarketReducer.ts b/packages/suite/src/reducers/wallet/coinmarketReducer.ts index b1555e000e3..0bf96e33986 100644 --- a/packages/suite/src/reducers/wallet/coinmarketReducer.ts +++ b/packages/suite/src/reducers/wallet/coinmarketReducer.ts @@ -50,6 +50,7 @@ interface Buy extends CoinmarketTradeCommonProps { isFromRedirect: boolean; quotesRequest?: BuyTradeQuoteRequest; quotes: BuyTrade[] | undefined; + selectedQuote: BuyTrade | undefined; cachedAccountInfo: { accountType?: Account['accountType']; index?: Account['index']; @@ -71,6 +72,7 @@ interface Sell extends CoinmarketTradeCommonProps { sellInfo?: SellInfo; quotesRequest?: SellFiatTradeQuoteRequest; quotes: SellFiatTrade[] | undefined; + selectedQuote: SellFiatTrade | undefined; transactionId?: string; isFromRedirect: boolean; coinmarketAccount?: Account; @@ -98,6 +100,7 @@ export const initialState: State = { isFromRedirect: false, buyInfo: undefined, quotesRequest: undefined, + selectedQuote: undefined, cachedAccountInfo: { accountType: undefined, index: undefined, @@ -119,6 +122,7 @@ export const initialState: State = { sellInfo: undefined, quotesRequest: undefined, quotes: [], + selectedQuote: undefined, transactionId: undefined, isFromRedirect: false, coinmarketAccount: undefined, @@ -160,6 +164,9 @@ const coinmarketReducer = ( case COINMARKET_BUY.SAVE_QUOTES: draft.buy.quotes = action.quotes; break; + case COINMARKET_BUY.SAVE_QUOTE: + draft.buy.selectedQuote = action.quote; + break; case COINMARKET_BUY.CLEAR_QUOTES: draft.buy.quotes = undefined; break; @@ -218,6 +225,9 @@ const coinmarketReducer = ( case COINMARKET_SELL.SAVE_QUOTES: draft.sell.quotes = action.quotes; break; + case COINMARKET_SELL.SAVE_QUOTE: + draft.sell.selectedQuote = action.quote; + break; case COINMARKET_SELL.CLEAR_QUOTES: draft.sell.quotes = undefined; break; diff --git a/packages/suite/src/types/coinmarket/coinmarket.ts b/packages/suite/src/types/coinmarket/coinmarket.ts index 8db58f02463..928ef5f9994 100644 --- a/packages/suite/src/types/coinmarket/coinmarket.ts +++ b/packages/suite/src/types/coinmarket/coinmarket.ts @@ -58,6 +58,7 @@ export interface UseCoinmarketCommonReturnProps { setSelectedQuote: (quote: CoinmarketTradeDetailMapProps[T] | undefined) => void; checkQuotesTimer: (callback: () => Promise) => void; } +export type CoinmarketPageType = 'form' | 'offers' | 'confirm'; export type UseCoinmarketFormProps = UseCoinmarketProps & { /** * Difference between form and offers is that on the offers page are used all data filled in the form @@ -65,7 +66,7 @@ export type UseCoinmarketFormProps = UseCoinmarketProps & { * * default value is 'form' */ - pageType?: 'form' | 'offers'; + pageType?: CoinmarketPageType; }; export type CoinmarketTradeBuyType = 'buy'; diff --git a/packages/suite/src/views/wallet/coinmarket/buy/CoinmarketBuyConfirm.tsx b/packages/suite/src/views/wallet/coinmarket/buy/CoinmarketBuyConfirm.tsx new file mode 100644 index 00000000000..9c84affaa59 --- /dev/null +++ b/packages/suite/src/views/wallet/coinmarket/buy/CoinmarketBuyConfirm.tsx @@ -0,0 +1,28 @@ +import { withSelectedAccountLoaded } from 'src/components/wallet'; +import { UseCoinmarketProps } from 'src/types/coinmarket/coinmarket'; +import useCoinmarketBuyForm from 'src/hooks/wallet/coinmarket/form/useCoinmarketBuyForm'; +import { CoinmarketFormContext } from 'src/hooks/wallet/coinmarket/form/useCoinmarketCommonForm'; +import { withCoinmarketLayoutWrap } from 'src/views/wallet/coinmarket/common/CoinmarketLayout/withCoinmarketLayoutWrap'; +import { CoinmarketSelectedOffer } from 'src/views/wallet/coinmarket/common/CoinmarketSelectedOffer/CoinmarketSelectedOffer'; + +const CoinmarketBuyConfirmComponent = (props: UseCoinmarketProps) => { + const coinmarketBuyContextValues = useCoinmarketBuyForm({ + ...props, + pageType: 'confirm', + }); + + return ( + + + + ); +}; + +export const CoinmarketBuyConfirm = withSelectedAccountLoaded( + withCoinmarketLayoutWrap(CoinmarketBuyConfirmComponent, { + backRoute: 'wallet-coinmarket-buy', + }), + { + title: 'TR_NAV_BUY', + }, +); diff --git a/packages/suite/src/views/wallet/coinmarket/buy/offers/Offers/index.tsx b/packages/suite/src/views/wallet/coinmarket/buy/offers/Offers/index.tsx index 0405ade9091..6c90fdc4b01 100644 --- a/packages/suite/src/views/wallet/coinmarket/buy/offers/Offers/index.tsx +++ b/packages/suite/src/views/wallet/coinmarket/buy/offers/Offers/index.tsx @@ -1,15 +1,10 @@ import { CoinmarketFooter } from 'src/views/wallet/coinmarket/common'; -import { CoinmarketTradeBuyType } from 'src/types/coinmarket/coinmarket'; -import { useCoinmarketOffersContext } from 'src/hooks/wallet/coinmarket/offers/useCoinmarketCommonOffers'; import CoinmarketOffers from 'src/views/wallet/coinmarket/common/CoinmarketOffers/CoinmarketOffers'; -import { CoinmarketSelectedOffer } from 'src/views/wallet/coinmarket/common/CoinmarketSelectedOffer/CoinmarketSelectedOffer'; const Offers = () => { - const { selectedQuote } = useCoinmarketOffersContext(); - return (
- {!selectedQuote ? : } +
); diff --git a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormLayout.tsx b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormLayout.tsx index 550c8595cea..1098829424a 100644 --- a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormLayout.tsx +++ b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormLayout.tsx @@ -1,9 +1,7 @@ import { Card } from '@trezor/components'; import { spacingsPx } from '@trezor/theme'; import styled from 'styled-components'; -import { useCoinmarketFormContext } from 'src/hooks/wallet/coinmarket/form/useCoinmarketCommonForm'; import { SCREEN_QUERY } from '@trezor/components/src/config/variables'; -import { CoinmarketSelectedOffer } from 'src/views/wallet/coinmarket/common/CoinmarketSelectedOffer/CoinmarketSelectedOffer'; import CoinmarketFormInputs from 'src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormInputs'; import CoinmarketFormOffer from 'src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormOffer'; import CoinmarketFeaturedOffers from 'src/views/wallet/coinmarket/common/CoinmarketFeaturedOffers/CoinmarketFeaturedOffers'; @@ -47,26 +45,18 @@ const CoinmarketFormOfferWrapper = styled(Card)` } `; -const CoinmarketFormLayout = () => { - const { selectedQuote } = useCoinmarketFormContext(); - - if (selectedQuote) { - return ; - } - - return ( - <> - - - - - - - - - - - ); -}; +const CoinmarketFormLayout = () => ( + <> + + + + + + + + + + +); export default CoinmarketFormLayout; diff --git a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketLayout/CoinmarketAccountTransactions/SellTransaction.tsx b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketLayout/CoinmarketAccountTransactions/SellTransaction.tsx index 0e554a0ddfd..342eb7c1b8c 100644 --- a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketLayout/CoinmarketAccountTransactions/SellTransaction.tsx +++ b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketLayout/CoinmarketAccountTransactions/SellTransaction.tsx @@ -165,7 +165,7 @@ export const SellTransaction = ({ trade, providers, account }: SellTransactionPr }), ); dispatch( - goto('wallet-coinmarket-sell-offers', { + goto('wallet-coinmarket-sell-confirm', { params: { symbol: account.symbol, accountIndex: account.index, diff --git a/packages/suite/src/views/wallet/coinmarket/sell_new/CoinmarketSellConfirm.tsx b/packages/suite/src/views/wallet/coinmarket/sell_new/CoinmarketSellConfirm.tsx new file mode 100644 index 00000000000..e0999c17839 --- /dev/null +++ b/packages/suite/src/views/wallet/coinmarket/sell_new/CoinmarketSellConfirm.tsx @@ -0,0 +1,28 @@ +import { withSelectedAccountLoaded } from 'src/components/wallet'; +import { UseCoinmarketProps } from 'src/types/coinmarket/coinmarket'; +import { CoinmarketFormContext } from 'src/hooks/wallet/coinmarket/form/useCoinmarketCommonForm'; +import { withCoinmarketLayoutWrap } from 'src/views/wallet/coinmarket/common/CoinmarketLayout/withCoinmarketLayoutWrap'; +import { CoinmarketSelectedOffer } from 'src/views/wallet/coinmarket/common/CoinmarketSelectedOffer/CoinmarketSelectedOffer'; +import { useCoinmarketSellForm } from 'src/hooks/wallet/coinmarket/form/useCoinmarketSellForm'; + +const CoinmarketSellConfirmComponent = (props: UseCoinmarketProps) => { + const coinmarketSellContextValues = useCoinmarketSellForm({ + ...props, + pageType: 'confirm', + }); + + return ( + + + + ); +}; + +export const CoinmarketSellConfirm = withSelectedAccountLoaded( + withCoinmarketLayoutWrap(CoinmarketSellConfirmComponent, { + backRoute: 'wallet-coinmarket-sell', + }), + { + title: 'TR_NAV_SELL', + }, +); diff --git a/packages/suite/src/views/wallet/coinmarket/sell_new/CoinmarketSellOffers.tsx b/packages/suite/src/views/wallet/coinmarket/sell_new/CoinmarketSellOffers.tsx index 6a560312347..f68d0ec5e64 100644 --- a/packages/suite/src/views/wallet/coinmarket/sell_new/CoinmarketSellOffers.tsx +++ b/packages/suite/src/views/wallet/coinmarket/sell_new/CoinmarketSellOffers.tsx @@ -5,7 +5,6 @@ import { CoinmarketFormContext } from 'src/hooks/wallet/coinmarket/form/useCoinm import { useCoinmarketSellForm } from 'src/hooks/wallet/coinmarket/form/useCoinmarketSellForm'; import { CoinmarketFooter } from 'src/views/wallet/coinmarket/common'; import CoinmarketOffers from 'src/views/wallet/coinmarket/common/CoinmarketOffers/CoinmarketOffers'; -import { CoinmarketSelectedOffer } from 'src/views/wallet/coinmarket/common/CoinmarketSelectedOffer/CoinmarketSelectedOffer'; import { withCoinmarketLayoutWrap } from 'src/views/wallet/coinmarket/common/CoinmarketLayout/withCoinmarketLayoutWrap'; const CoinmarketSellOffersComponent = (props: UseCoinmarketProps) => { @@ -13,13 +12,12 @@ const CoinmarketSellOffersComponent = (props: UseCoinmarketProps) => { ...props, pageType: 'offers', }); - const { selectedQuote } = coinmarketSellFormContextValues; // CoinmarketOffersContext.Provider is temporary FIX return ( - {!selectedQuote ? : } + diff --git a/suite-common/suite-config/src/routes.ts b/suite-common/suite-config/src/routes.ts index 448e81c2ebd..a90230b0f54 100644 --- a/suite-common/suite-config/src/routes.ts +++ b/suite-common/suite-config/src/routes.ts @@ -221,6 +221,19 @@ export const routes = [ app: 'wallet', params: walletParams, }, + { + name: 'wallet-coinmarket-buy-confirm', + pattern: '/accounts/coinmarket/buy/confirm', + app: 'wallet', + params: walletParams, + exact: true, + }, + { + name: 'wallet-coinmarket-sell-confirm', + pattern: '/accounts/coinmarket/sell/confirm', + app: 'wallet', + params: walletParams, + }, { name: 'wallet-coinmarket-redirect', pattern: '/coinmarket-redirect',