diff --git a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketBuyForm.tsx b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketBuyForm.tsx index 7a01fd64c8f..a87af7e1c0b 100644 --- a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketBuyForm.tsx +++ b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketBuyForm.tsx @@ -4,7 +4,7 @@ import useDebounce from 'react-use/lib/useDebounce'; import type { BuyTrade, BuyTradeQuoteRequest, CryptoId } from 'invity-api'; import { isChanged } from '@suite-common/suite-utils'; import { formatAmount } from '@suite-common/wallet-utils'; -import { useActions, useDispatch, useSelector } from 'src/hooks/suite'; +import { useDispatch, useSelector } from 'src/hooks/suite'; import invityAPI from 'src/services/suite/invityAPI'; import { createQuoteLink, @@ -64,35 +64,6 @@ const useCoinmarketBuyForm = ({ useCoinmarketCommonOffers({ selectedAccount, type }); const { paymentMethods, getPaymentMethods, getQuotesByPaymentMethod } = useCoinmarketPaymentMethod(); - const { - saveTrade, - saveQuotes, - saveSelectedQuote, - setIsFromRedirect, - openCoinmarketBuyConfirmModal, - addNotification, - saveTransactionDetailId, - verifyAddress, - submitRequestForm, - goto, - savePaymentMethods, - saveQuoteRequest, - saveCachedAccountInfo, - } = useActions({ - saveTrade: coinmarketBuyActions.saveTrade, - saveQuotes: coinmarketBuyActions.saveQuotes, - saveSelectedQuote: coinmarketBuyActions.saveSelectedQuote, - setIsFromRedirect: coinmarketBuyActions.setIsFromRedirect, - openCoinmarketBuyConfirmModal: coinmarketBuyActions.openCoinmarketBuyConfirmModal, - addNotification: notificationsActions.addToast, - saveTransactionDetailId: coinmarketBuyActions.saveTransactionDetailId, - submitRequestForm: coinmarketCommonActions.submitRequestForm, - verifyAddress: coinmarketBuyActions.verifyAddress, - goto: routerActions.goto, - savePaymentMethods: coinmarketInfoActions.savePaymentMethods, - saveQuoteRequest: coinmarketBuyActions.saveQuoteRequest, - saveCachedAccountInfo: coinmarketBuyActions.saveCachedAccountInfo, - }); const { navigateToBuyForm, navigateToBuyOffers, navigateToBuyConfirm } = useCoinmarketNavigation(account); @@ -266,9 +237,9 @@ const useCoinmarketBuyForm = ({ } setInnerQuotes(quotesSuccess); - dispatch(saveQuotes(quotesSuccess)); - dispatch(saveQuoteRequest(quoteRequest)); - dispatch(savePaymentMethods(paymentMethodsFromQuotes)); + dispatch(coinmarketBuyActions.saveQuotes(quotesSuccess)); + dispatch(coinmarketBuyActions.saveQuoteRequest(quoteRequest)); + dispatch(coinmarketInfoActions.savePaymentMethods(paymentMethodsFromQuotes)); setAmountLimits(limits); if (!paymentMethodSelected || !isSelectedPaymentMethodAvailable) { @@ -293,9 +264,6 @@ const useCoinmarketBuyForm = ({ getQuotesRequest, getPaymentMethods, dispatch, - saveQuotes, - saveQuoteRequest, - savePaymentMethods, setValue, ], ); @@ -303,17 +271,26 @@ const useCoinmarketBuyForm = ({ const goToOffers = async () => { await handleChange(); - dispatch(saveCachedAccountInfo(account.symbol, account.index, account.accountType)); + dispatch( + coinmarketBuyActions.saveCachedAccountInfo( + account.symbol, + account.index, + account.accountType, + ), + ); navigateToBuyOffers(); }; const selectQuote = async (quote: BuyTrade) => { const provider = buyInfo && quote.exchange ? buyInfo.providerInfos[quote.exchange] : null; if (quotesRequest) { - const result = await openCoinmarketBuyConfirmModal( - provider?.companyName, - cryptoIdToCoinSymbol(quote.receiveCurrency!), + const result = await dispatch( + coinmarketBuyActions.openCoinmarketBuyConfirmModal( + provider?.companyName, + cryptoIdToCoinSymbol(quote.receiveCurrency!), + ), ); + if (result) { // empty quoteId means the partner requests login first, requestTrade to get login screen if (!quote.quoteId) { @@ -321,7 +298,9 @@ const useCoinmarketBuyForm = ({ const response = await invityAPI.doBuyTrade({ trade: quote, returnUrl }); if (response) { if (response.trade.status === 'LOGIN_REQUEST' && response.tradeForm) { - submitRequestForm(response.tradeForm.form); + dispatch( + coinmarketCommonActions.submitRequestForm(response.tradeForm.form), + ); } else { const errorMessage = `[doBuyTrade] ${response.trade.status} ${response.trade.error}`; console.log(errorMessage); @@ -329,13 +308,15 @@ const useCoinmarketBuyForm = ({ } else { const errorMessage = 'No response from the server'; console.log(`[doBuyTrade] ${errorMessage}`); - addNotification({ - type: 'error', - error: errorMessage, - }); + dispatch( + notificationsActions.addToast({ + type: 'error', + error: errorMessage, + }), + ); } } else { - saveSelectedQuote(quote); + dispatch(coinmarketBuyActions.saveSelectedQuote(quote)); timer.stop(); @@ -364,23 +345,33 @@ const useCoinmarketBuyForm = ({ }); if (!response || !response.trade || !response.trade.paymentId) { - addNotification({ - type: 'error', - error: 'No response from the server', - }); + dispatch( + notificationsActions.addToast({ + type: 'error', + error: 'No response from the server', + }), + ); } else if (response.trade.error) { - addNotification({ - type: 'error', - error: response.trade.error, - }); + dispatch( + notificationsActions.addToast({ + type: 'error', + error: response.trade.error, + }), + ); } else { - saveTrade(response.trade, account, new Date().toISOString()); + dispatch( + coinmarketBuyActions.saveTrade(response.trade, account, new Date().toISOString()), + ); if (response.tradeForm) { - submitRequestForm(response.tradeForm.form); + dispatch(coinmarketCommonActions.submitRequestForm(response.tradeForm.form)); } if (isDesktop()) { - saveTransactionDetailId(response.trade.paymentId); - goto('wallet-coinmarket-buy-detail', { params: selectedAccount.params }); + dispatch(coinmarketBuyActions.saveTransactionDetailId(response.trade.paymentId)); + dispatch( + routerActions.goto('wallet-coinmarket-buy-detail', { + params: selectedAccount.params, + }), + ); } } setCallInProgress(false); @@ -451,7 +442,7 @@ const useCoinmarketBuyForm = ({ } if (isFromRedirect && quotesRequest) { - setIsFromRedirect(false); + dispatch(coinmarketBuyActions.setIsFromRedirect(false)); } checkQuotesTimer(handleChange); @@ -525,7 +516,7 @@ const useCoinmarketBuyForm = ({ selectQuote, confirmTrade, goToOffers, - verifyAddress, + verifyAddress: coinmarketBuyActions.verifyAddress, removeDraft, setAmountLimits, }; diff --git a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketExchangeForm.ts b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketExchangeForm.ts index e28566e5be9..1113d9b80a6 100644 --- a/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketExchangeForm.ts +++ b/packages/suite/src/hooks/wallet/coinmarket/form/useCoinmarketExchangeForm.ts @@ -9,7 +9,7 @@ import type { import useDebounce from 'react-use/lib/useDebounce'; import { amountToSatoshi, formatAmount, toFiatCurrency } from '@suite-common/wallet-utils'; import { isChanged } from '@suite-common/suite-utils'; -import { useActions, useDispatch, useSelector } from 'src/hooks/suite'; +import { useDispatch, useSelector } from 'src/hooks/suite'; import invityAPI from 'src/services/suite/invityAPI'; import { saveQuoteRequest, saveQuotes } from 'src/actions/wallet/coinmarketExchangeActions'; import { @@ -62,7 +62,6 @@ import { networks } from '@suite-common/wallet-config'; import { useCoinmarketAccount } from 'src/hooks/wallet/coinmarket/form/common/useCoinmarketAccount'; import { useCoinmarketInfo } from 'src/hooks/wallet/coinmarket/useCoinmarketInfo'; import { analytics, EventType } from '@trezor/suite-analytics'; -import { setCoinmarketModalAccount } from 'src/actions/wallet/coinmarket/coinmarketCommonActions'; export const useCoinmarketExchangeForm = ({ selectedAccount, @@ -112,26 +111,6 @@ export const useCoinmarketExchangeForm = ({ navigateToExchangeConfirm, } = useCoinmarketNavigation(account); - const { - saveTrade, - openCoinmarketExchangeConfirmModal, - saveTransactionId, - addNotification, - verifyAddress, - saveSelectedQuote, - setCoinmarketExchangeAccount, - } = useActions({ - saveTrade: coinmarketExchangeActions.saveTrade, - openCoinmarketExchangeConfirmModal: - coinmarketExchangeActions.openCoinmarketExchangeConfirmModal, - saveTransactionId: coinmarketExchangeActions.saveTransactionId, - addNotification: notificationsActions.addToast, - verifyAddress: coinmarketExchangeActions.verifyAddress, - saveSelectedQuote: coinmarketExchangeActions.saveSelectedQuote, - setCoinmarketExchangeAccount: coinmarketExchangeActions.setCoinmarketExchangeAccount, - setCoinmarketModalAccount: coinmarketCommonActions.setCoinmarketModalAccount, - }); - const { symbol } = account; const { shouldSendInSats } = useBitcoinAmountUnit(symbol); const network = networks[account.symbol]; @@ -326,7 +305,7 @@ export const useCoinmarketExchangeForm = ({ changeFeeLevel, composeRequest, setAccountOnChange: newAccount => { - dispatch(setCoinmarketExchangeAccount(newAccount)); + dispatch(coinmarketExchangeActions.setCoinmarketExchangeAccount(newAccount)); setAccount(newAccount); }, }); @@ -337,14 +316,16 @@ export const useCoinmarketExchangeForm = ({ ? exchangeInfo?.providerInfos[quote.exchange] : null; if (quotesRequest) { - const result = await openCoinmarketExchangeConfirmModal( - provider?.companyName, - quote.isDex, - quote.send, - quote.receive, + const result = await dispatch( + coinmarketExchangeActions.openCoinmarketExchangeConfirmModal( + provider?.companyName, + quote.isDex, + quote.send, + quote.receive, + ), ); if (result) { - saveSelectedQuote(quote); + dispatch(coinmarketExchangeActions.saveSelectedQuote(quote)); navigateToExchangeConfirm(); timer.stop(); @@ -380,27 +361,31 @@ export const useCoinmarketExchangeForm = ({ }); if (!response) { - addNotification({ - type: 'error', - error: 'No response from the server', - }); + dispatch( + notificationsActions.addToast({ + type: 'error', + error: 'No response from the server', + }), + ); } else if ( response.error || !response.status || !response.orderId || response.status === 'ERROR' ) { - addNotification({ - type: 'error', - error: response.error || 'Error response from the server', - }); - saveSelectedQuote(response); + dispatch( + notificationsActions.addToast({ + type: 'error', + error: response.error || 'Error response from the server', + }), + ); + dispatch(coinmarketExchangeActions.saveSelectedQuote(response)); } else if (response.status === 'APPROVAL_REQ' || response.status === 'APPROVAL_PENDING') { - saveSelectedQuote(response); + dispatch(coinmarketExchangeActions.saveSelectedQuote(response)); setExchangeStep('SEND_APPROVAL_TRANSACTION'); ok = true; } else if (response.status === 'CONFIRM') { - saveSelectedQuote(response); + dispatch(coinmarketExchangeActions.saveSelectedQuote(response)); if (response.isDex) { if (exchangeStep === 'RECEIVING_ADDRESS' || trade.approvalType === 'ZERO') { setExchangeStep('SEND_APPROVAL_TRANSACTION'); @@ -413,8 +398,10 @@ export const useCoinmarketExchangeForm = ({ ok = true; } else { // CONFIRMING, SUCCESS - saveTrade(response, account, new Date().toISOString()); - saveTransactionId(response.orderId); + dispatch( + coinmarketExchangeActions.saveTrade(response, account, new Date().toISOString()), + ); + dispatch(coinmarketExchangeActions.saveTransactionId(response.orderId)); ok = true; navigateToExchangeDetail(); } @@ -449,7 +436,13 @@ export const useCoinmarketExchangeForm = ({ if (selectedQuote.status === 'CONFIRM' && selectedQuote.approvalType !== 'ZERO') { quote.receiveTxHash = txid; quote.status = 'CONFIRMING'; - saveTrade(quote, account, new Date().toISOString()); + dispatch( + coinmarketExchangeActions.saveTrade( + quote, + account, + new Date().toISOString(), + ), + ); confirmTrade(quote.receiveAddress || '', undefined, quote); } else { quote.approvalSendTxHash = txid; @@ -458,15 +451,17 @@ export const useCoinmarketExchangeForm = ({ } } } else { - addNotification({ - type: 'error', - error: 'Cannot send transaction, missing data', - }); + dispatch( + notificationsActions.addToast({ + type: 'error', + error: 'Cannot send transaction, missing data', + }), + ); } }; const sendTransaction = async () => { - dispatch(setCoinmarketModalAccount(account)); + dispatch(coinmarketCommonActions.setCoinmarketModalAccount(account)); if (selectedQuote?.isDex) { sendDexTransaction(); @@ -494,15 +489,23 @@ export const useCoinmarketExchangeForm = ({ ); // in case of not success, recomposeAndSign shows notification if (result?.success) { - saveTrade(selectedQuote, account, new Date().toISOString()); - saveTransactionId(selectedQuote.orderId); + dispatch( + coinmarketExchangeActions.saveTrade( + selectedQuote, + account, + new Date().toISOString(), + ), + ); + dispatch(coinmarketExchangeActions.saveTransactionId(selectedQuote.orderId)); navigateToExchangeDetail(); } } else { - addNotification({ - type: 'error', - error: 'Cannot send transaction, missing data', - }); + dispatch( + notificationsActions.addToast({ + type: 'error', + error: 'Cannot send transaction, missing data', + }), + ); } }; @@ -649,7 +652,7 @@ export const useCoinmarketExchangeForm = ({ goToOffers, setExchangeStep, sendTransaction, - verifyAddress, + verifyAddress: coinmarketExchangeActions.verifyAddress, selectQuote, confirmTrade, }; diff --git a/packages/suite/src/types/coinmarket/coinmarketForm.ts b/packages/suite/src/types/coinmarket/coinmarketForm.ts index 9707b596f33..888a0609eee 100644 --- a/packages/suite/src/types/coinmarket/coinmarketForm.ts +++ b/packages/suite/src/types/coinmarket/coinmarketForm.ts @@ -30,7 +30,7 @@ import type { } from 'invity-api'; import { Timer } from '@trezor/react-utils'; import { AppState } from 'src/reducers/store'; -import { ExtendedMessageDescriptor } from 'src/types/suite'; +import { Dispatch, ExtendedMessageDescriptor, GetState } from 'src/types/suite'; import { PropsWithChildren } from 'react'; import { AmountLimits, @@ -162,6 +162,12 @@ export interface CoinmarketCommonFormBuySellProps { amountLimits?: AmountLimits; } +type CoinmarketVerifyAccountProps = ( + account: Account, + address?: string, + path?: string, +) => (dispatch: Dispatch, getState: GetState) => Promise; + export interface CoinmarketBuyFormContextProps extends UseFormReturn, CoinmarketCommonFormProps, @@ -180,7 +186,7 @@ export interface CoinmarketBuyFormContextProps selectQuote: (quote: BuyTrade) => Promise; confirmTrade: (address: string) => void; - verifyAddress: (account: Account, address?: string, path?: string) => Promise; + verifyAddress: CoinmarketVerifyAccountProps; removeDraft: (key: string) => void; setAmountLimits: (limits?: AmountLimits) => void; } @@ -256,7 +262,7 @@ export interface CoinmarketExchangeFormContextProps confirmTrade: (address: string, extraField?: string, trade?: ExchangeTrade) => Promise; sendTransaction: () => void; selectQuote: (quote: ExchangeTrade) => void; - verifyAddress: (account: Account, address?: string, path?: string) => Promise; + verifyAddress: CoinmarketVerifyAccountProps; } export type CoinmarketFormMapProps = { diff --git a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketLayout/CoinmarketAccountTransactions/ExchangeTransaction.tsx b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketLayout/CoinmarketAccountTransactions/ExchangeTransaction.tsx index e63c5b4e0d9..4a799c2cf0e 100644 --- a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketLayout/CoinmarketAccountTransactions/ExchangeTransaction.tsx +++ b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketLayout/CoinmarketAccountTransactions/ExchangeTransaction.tsx @@ -116,8 +116,8 @@ export const ExchangeTransaction = ({ trade, providers, account }: ExchangeTrans const { date, data } = trade; const { send, sendStringAmount, receive, receiveStringAmount, exchange } = data; - const viewDetail = async () => { - await dispatch(saveTransactionId(trade.key || '')); + const viewDetail = () => { + dispatch(saveTransactionId(trade.key || '')); dispatch( goto('wallet-coinmarket-exchange-detail', { params: { diff --git a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketSelectedOffer/CoinmarketVerify/CoinmarketVerify.tsx b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketSelectedOffer/CoinmarketVerify/CoinmarketVerify.tsx index 346ec3d2076..ea0f3840616 100644 --- a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketSelectedOffer/CoinmarketVerify/CoinmarketVerify.tsx +++ b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketSelectedOffer/CoinmarketVerify/CoinmarketVerify.tsx @@ -244,10 +244,12 @@ export const CoinmarketVerify = ({ coinmarketVerifyAccount, currency }: Coinmark isDisabled={callInProgress} onClick={() => { if (selectedAccountOption.account && accountAddress) { - verifyAddress( - selectedAccountOption.account, - accountAddress.address, - accountAddress.path, + dispatch( + verifyAddress( + selectedAccountOption.account, + accountAddress.address, + accountAddress.path, + ), ); } }}