diff --git a/CHANGELOG.md b/CHANGELOG.md index dfd037886..6d4ab1843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ - Feature list [#2092](https://github.com/thorchain/asgardex-electron/pull/2092) - [TxModal|Send] Add copy button [#1998](https://github.com/thorchain/asgardex-electron/issues/1998) +## Update + +- [Send] Use TxModal [#2073](https://github.com/thorchain/asgardex-electron/issues/2073) + # 0.8.0 (2022-02-18) ## Add diff --git a/src/renderer/components/wallet/txs/send/Send.stories.tsx b/src/renderer/components/wallet/txs/send/Send.stories.tsx deleted file mode 100644 index ee984faa9..000000000 --- a/src/renderer/components/wallet/txs/send/Send.stories.tsx +++ /dev/null @@ -1,206 +0,0 @@ -import React, { useMemo } from 'react' - -import * as RD from '@devexperts/remote-data-ts' -import { Story, Meta } from '@storybook/react' -import { BTC_DECIMAL } from '@xchainjs/xchain-bitcoin' -import { Address, FeeRates, Fees, FeeType, TxHash } from '@xchainjs/xchain-client' -import { - assetAmount, - AssetBNB, - AssetBTC, - AssetETH, - AssetLTC, - AssetRune67C, - assetToBase, - assetToString, - baseAmount, - baseToAsset, - formatAssetAmount -} from '@xchainjs/xchain-util' -import * as O from 'fp-ts/lib/Option' -import * as Rx from 'rxjs' -import * as RxOp from 'rxjs/operators' - -import { Network } from '../../../../../shared/api/types' -import { BNB_TRANSFER_FEES } from '../../../../../shared/mock/fees' -import { RDStatus, getMockRDValueFactory } from '../../../../../shared/mock/rdByStatus' -import { mockValidatePassword$ } from '../../../../../shared/mock/wallet' -import { WalletType } from '../../../../../shared/wallet/types' -import { mockWalletBalance } from '../../../../helpers/test/testWalletHelper' -import { INITIAL_SEND_STATE } from '../../../../services/chain/const' -import { SendTxParams, SendTxState } from '../../../../services/chain/types' -import { WalletBalances } from '../../../../services/clients' -import { ErrorId, TxHashRD, WalletBalance } from '../../../../services/wallet/types' -import { Send } from './Send' -import { SendFormBNB } from './SendFormBNB' -import { SendFormBTC } from './SendFormBTC' -import { SendFormETH } from './SendFormETH' -import { SendFormLTC } from './SendFormLTC' - -const defaultProps = { - txRD: RD.initial, - finishActionHandler: () => console.log('finish action'), - viewTxHandler: (txHash: TxHash) => { - console.log(`view tx handler: ${txHash}`) - return Promise.resolve(true) - }, - getExplorerTxUrl: (txHash: TxHash) => O.some(`url/asset-${txHash}`), - errorActionHandler: () => console.log('error action') -} - -const bnbAsset: WalletBalance = mockWalletBalance({ - asset: AssetBNB, - amount: assetToBase(assetAmount(12.3)), - walletAddress: 'AssetBNB wallet address' -}) - -const btcBalance: WalletBalance = mockWalletBalance({ - asset: AssetBTC, - amount: assetToBase(assetAmount(23.45, BTC_DECIMAL)), - walletAddress: 'btc wallet address' -}) - -const runeAsset: WalletBalance = mockWalletBalance({ - asset: AssetRune67C, - amount: assetToBase(assetAmount(34.56)), - walletAddress: 'AssetRune67C wallet address' -}) - -const ethBalance: WalletBalance = mockWalletBalance({ - asset: AssetETH, - amount: assetToBase(assetAmount(45.67)), - walletAddress: 'AssetETH wallet address' -}) - -const ltcBalance: WalletBalance = mockWalletBalance({ - asset: AssetLTC, - amount: assetToBase(assetAmount(56.78)), - walletAddress: 'AssetLTC wallet address' -}) - -const SendFormsComponents = { - SendFormBNB: { - component: SendFormBNB, - balance: bnbAsset - }, - SendFormBTC: { - component: SendFormBTC, - balance: btcBalance - }, - SendFormETH: { - component: SendFormETH, - balance: ethBalance - }, - SendFormLTC: { - component: SendFormLTC, - balance: ltcBalance - } -} - -type SendForm = keyof typeof SendFormsComponents - -const getSendForm = (component: SendForm) => { - return SendFormsComponents[component].component -} - -const getSendBalance = (component: SendForm) => { - return SendFormsComponents[component].balance -} - -const balances: WalletBalances = [bnbAsset, runeAsset, btcBalance, ethBalance] - -const fees: Fees = { - type: FeeType.FlatFee, - fastest: baseAmount(3000), - fast: baseAmount(2000), - average: baseAmount(1000) -} - -const rates: FeeRates = { - fastest: 5, - fast: 3, - average: 2 -} - -const defaultComponentProps = { - walletType: 'keystore' as WalletType, - walletAddress: 'bnb-address' as Address, - walletIndex: 0, - balances, - balance: bnbAsset, - feesWithRates: RD.success({ fees, rates }), - onSubmit: (p: SendTxParams) => { - const { recipient, amount, asset, memo, walletIndex, walletType, sender } = p - console.log(` - to: ${recipient}, - amount ${formatAssetAmount({ amount: baseToAsset(amount) })}, - asset: ${assetToString(asset)}, - memo: ${memo}, - sender: ${sender}, - walletType: ${walletType}, - walletIndex: ${walletIndex} - `) - }, - - isLoading: false, - addressValidation: (_: unknown) => true, - fee: RD.success(assetToBase(BNB_TRANSFER_FEES.single)), - network: 'testnet' as Network, - - fees: RD.success(fees), - reloadFeesHandler: () => console.log('reloadFees'), - validatePassword$: mockValidatePassword$, - // mock successfull result of transfer$ - transfer$: (params: SendTxParams) => - Rx.of(params).pipe( - RxOp.tap((params) => console.log('transfer$ ', params)), - RxOp.switchMap((_) => - Rx.of({ - ...INITIAL_SEND_STATE, - steps: { current: 1, total: 1 }, - status: RD.success('tx-hash') - }) - ) - ), - openExplorerTxUrl: (txHash: TxHash) => { - console.log(`Open explorer - tx hash ${txHash}`) - return Promise.resolve(true) - }, - getExplorerTxUrl: (txHash: TxHash) => O.some(`url/asset-${txHash}`) -} - -const getTxRdFromStatus = getMockRDValueFactory( - () => '0xabc123', - () => ({ errorId: ErrorId.SEND_TX, msg: 'Sending tx failed' }) -) - -type Args = { - sendForm: SendForm - txRDStatus: RDStatus -} - -export const Default: Story = ({ sendForm, txRDStatus }) => { - const Component = useMemo(() => getSendForm(sendForm), [sendForm]) - const balance = useMemo(() => getSendBalance(sendForm), [sendForm]) - const txRD: TxHashRD = useMemo(() => getTxRdFromStatus(txRDStatus), [txRDStatus]) - - return } /> -} - -Default.args = { sendForm: 'SendFormBNB', txRDStatus: 'initial' } - -const meta: Meta = { - component: Send, - title: 'Wallet/Send', - argTypes: { - sendForm: { - control: { - type: 'select', - options: Object.keys(SendFormsComponents) - } - }, - txRDStatus: { control: { type: 'select', options: ['initial', 'pending', 'error', 'success'] } } - } -} - -export default meta diff --git a/src/renderer/components/wallet/txs/send/Send.tsx b/src/renderer/components/wallet/txs/send/Send.tsx deleted file mode 100644 index 66308ea13..000000000 --- a/src/renderer/components/wallet/txs/send/Send.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import React, { useEffect, useMemo, useCallback } from 'react' - -import * as RD from '@devexperts/remote-data-ts' -import * as FP from 'fp-ts/function' -import * as O from 'fp-ts/lib/Option' -import { useIntl } from 'react-intl' - -import { GetExplorerTxUrl, OpenExplorerTxUrl } from '../../../../services/clients' -import { TxHashRD } from '../../../../services/wallet/types' -import { ErrorView } from '../../../shared/error/' -import { SuccessView } from '../../../shared/success/' -import { ViewTxButton } from '../../../uielements/button/ViewTxButton' -import * as Styled from '../TxForm.styles' - -/** - * Send is a generic component to display states of `TxRD` for any chain - * - * initial: SendFormXYZ - * pending: SendFormXYZ (which handles a loading state itself) - * failure: ErrorView - * success: SuccessView - * - * */ -export type Props = { - txRD: TxHashRD - sendForm: JSX.Element - inititalActionHandler?: FP.Lazy - viewTxHandler: OpenExplorerTxUrl - getExplorerTxUrl: GetExplorerTxUrl - finishActionHandler?: FP.Lazy - errorActionHandler?: FP.Lazy -} - -export const Send: React.FC = (props): JSX.Element => { - const { - txRD, - inititalActionHandler = FP.constVoid, - viewTxHandler, - getExplorerTxUrl, - finishActionHandler = FP.constVoid, - sendForm, - errorActionHandler = FP.constVoid - } = props - const intl = useIntl() - - useEffect(() => { - inititalActionHandler() - }, [inititalActionHandler]) - - const renderErrorBtn = useMemo( - () => ( - errorActionHandler()}>{intl.formatMessage({ id: 'common.back' })} - ), - [errorActionHandler, intl] - ) - - const renderSuccessExtra = useCallback( - (txHash: string) => { - const onClickHandler = () => viewTxHandler(txHash) - const txUrl = getExplorerTxUrl(txHash) - return ( - - - {intl.formatMessage({ id: 'common.back' })} - - - - ) - }, - [finishActionHandler, intl, getExplorerTxUrl, viewTxHandler] - ) - - return ( - <> - {FP.pipe( - txRD, - RD.fold( - () => sendForm, - () => sendForm, - (error) => , - (hash) => ( - - ) - ) - )} - - ) -} diff --git a/src/renderer/components/wallet/txs/send/SendFormDOGE.stories.tsx b/src/renderer/components/wallet/txs/send/SendFormDOGE.stories.tsx index dff17c0e6..b8b4bf85b 100644 --- a/src/renderer/components/wallet/txs/send/SendFormDOGE.stories.tsx +++ b/src/renderer/components/wallet/txs/send/SendFormDOGE.stories.tsx @@ -1,103 +1,130 @@ -import React from 'react' - -import * as RD from '@devexperts/remote-data-ts' import { Meta, Story } from '@storybook/react' -import { Address, FeeRates, Fees, FeeType } from '@xchainjs/xchain-client' +import { Address, FeeRates, Fees, FeesWithRates, FeeType, TxHash } from '@xchainjs/xchain-client' import { DOGE_DECIMAL } from '@xchainjs/xchain-doge' -import { assetAmount, AssetDOGE, assetToBase, baseAmount, formatBaseAmount } from '@xchainjs/xchain-util' +import { assetAmount, AssetDOGE, assetToBase, baseAmount } from '@xchainjs/xchain-util' +import * as FP from 'fp-ts/lib/function' +import * as O from 'fp-ts/lib/Option' +import * as Rx from 'rxjs' +import { getMockRDValueFactory, RDStatus } from '../../../../../shared/mock/rdByStatus' import { mockValidatePassword$ } from '../../../../../shared/mock/wallet' +import { WalletType } from '../../../../../shared/wallet/types' import { THORCHAIN_DECIMAL } from '../../../../helpers/assetHelper' import { mockWalletBalance } from '../../../../helpers/test/testWalletHelper' -import { SendTxParams } from '../../../../services/chain/types' -import { WalletBalance } from '../../../../services/wallet/types' -import { SendFormDOGE as Component, Props as ComponentProps } from './SendFormDOGE' - -const dogeBalance: WalletBalance = mockWalletBalance({ - asset: AssetDOGE, - amount: assetToBase(assetAmount(1.23, DOGE_DECIMAL)), - walletAddress: 'DOGE wallet address' -}) +import { SendTxStateHandler } from '../../../../services/chain/types' +import { FeesWithRatesRD } from '../../../../services/doge/types' +import { ApiError, ErrorId, WalletBalance } from '../../../../services/wallet/types' +import { SendFormDOGE as Component } from './SendFormDOGE' -const runeBalance: WalletBalance = mockWalletBalance({ - amount: assetToBase(assetAmount(2, THORCHAIN_DECIMAL)) -}) - -const fees: Fees = { - type: FeeType.FlatFee, - fastest: baseAmount(3000), - fast: baseAmount(2000), - average: baseAmount(1000) +type Args = { + txRDStatus: RDStatus + feeRDStatus: RDStatus + balance: string + validAddress: boolean + walletType: WalletType } -const rates: FeeRates = { - fastest: 5, - fast: 3, - average: 2 -} +const Template: Story = ({ txRDStatus, feeRDStatus, balance, validAddress, walletType }) => { + const transfer$: SendTxStateHandler = (_) => + Rx.of({ + steps: { current: txRDStatus === 'initial' ? 0 : 1, total: 1 }, + status: FP.pipe( + txRDStatus, + getMockRDValueFactory( + () => 'tx-hash', + () => ({ + msg: 'error message', + errorId: ErrorId.SEND_TX + }) + ) + ) + }) -const defaultProps: ComponentProps = { - walletType: 'keystore', - walletIndex: 0, - balances: [dogeBalance, runeBalance], - balance: dogeBalance, - onSubmit: ({ recipient, amount, feeOption, memo }: SendTxParams) => - console.log(`to: ${recipient}, amount ${formatBaseAmount(amount)}, feeOptionKey: ${feeOption}, memo: ${memo}`), - isLoading: false, - addressValidation: (_: Address) => true, - feesWithRates: RD.success({ fees, rates }), - reloadFeesHandler: () => console.log('reload fees'), - validatePassword$: mockValidatePassword$, - sendTxStatusMsg: '', - network: 'testnet' -} + const dogeBalance: WalletBalance = mockWalletBalance({ + asset: AssetDOGE, + amount: assetToBase(assetAmount(balance, DOGE_DECIMAL)), + walletAddress: 'DOGE wallet address' + }) -export const Default: Story = () => -Default.storyName = 'default' + const runeBalance: WalletBalance = mockWalletBalance({ + amount: assetToBase(assetAmount(2, THORCHAIN_DECIMAL)) + }) -export const Pending: Story = () => { - const props: ComponentProps = { - ...defaultProps, - isLoading: true, - sendTxStatusMsg: 'step 1 / 2' + const fees: Fees = { + type: FeeType.FlatFee, + fastest: baseAmount(3000), + fast: baseAmount(2000), + average: baseAmount(1000) } - return -} -Pending.storyName = 'pending' -export const FeesInitial: Story = () => { - const props: ComponentProps = { ...defaultProps, feesWithRates: RD.initial } - return -} -FeesInitial.storyName = 'fees initial' + const rates: FeeRates = { + fastest: 5, + fast: 3, + average: 2 + } -export const FeesLoading: Story = () => { - const props: ComponentProps = { ...defaultProps, feesWithRates: RD.pending } - return -} -FeesLoading.storyName = 'fees loading' + const feesWithRates: FeesWithRatesRD = FP.pipe( + feeRDStatus, + getMockRDValueFactory( + () => ({ fees, rates }), + () => Error('getting fees failed') + ) + ) -export const FeesFailure: Story = () => { - const props: ComponentProps = { - ...defaultProps, - feesWithRates: RD.failure(Error('Could not load fees and rates for any reason')) - } - return + return ( + validAddress} + feesWithRates={feesWithRates} + reloadFeesHandler={() => console.log('reload fees')} + validatePassword$={mockValidatePassword$} + network="testnet" + openExplorerTxUrl={(txHash: TxHash) => { + console.log(`Open explorer - tx hash ${txHash}`) + return Promise.resolve(true) + }} + getExplorerTxUrl={(txHash: TxHash) => O.some(`url/asset-${txHash}`)} + /> + ) } -FeesFailure.storyName = 'fees failure' -export const FeesNotCovered: Story = () => { - const props: ComponentProps = { - ...defaultProps, - balance: { ...dogeBalance, amount: baseAmount(1, DOGE_DECIMAL) } - } - return -} -FeesNotCovered.storyName = 'fees not covered' +export const Default = Template.bind({}) -const meta: Meta = { +const meta: Meta = { component: Component, - title: 'Wallet/SendFormDOGE' + title: 'Wallet/SendFormDOGE', + argTypes: { + txRDStatus: { + name: 'txRDStatus', + control: { type: 'select', options: ['pending', 'error', 'success'] }, + defaultValue: 'success' + }, + feeRDStatus: { + name: 'feeRD', + control: { type: 'select', options: ['initial', 'pending', 'error', 'success'] }, + defaultValue: 'success' + }, + walletType: { + name: 'wallet type', + control: { type: 'select', options: ['keystore', 'ledger'] }, + defaultValue: 'keystore' + }, + balance: { + name: 'DOGE Balance', + control: { type: 'text' }, + defaultValue: '2' + }, + validAddress: { + name: 'valid address', + control: { type: 'boolean' }, + defaultValue: true + } + } } export default meta diff --git a/src/renderer/components/wallet/txs/send/SendFormDOGE.tsx b/src/renderer/components/wallet/txs/send/SendFormDOGE.tsx index da0550788..6597d15af 100644 --- a/src/renderer/components/wallet/txs/send/SendFormDOGE.tsx +++ b/src/renderer/components/wallet/txs/send/SendFormDOGE.tsx @@ -23,9 +23,11 @@ import { useIntl } from 'react-intl' import { Network } from '../../../../../shared/api/types' import { WalletType } from '../../../../../shared/wallet/types' import { ZERO_BASE_AMOUNT, ZERO_BN } from '../../../../const' +import { useSubscriptionState } from '../../../../hooks/useSubscriptionState' import { FeesWithRatesRD } from '../../../../services/bitcoin/types' -import { FeeRD, Memo, SendTxParams } from '../../../../services/chain/types' -import { AddressValidation, WalletBalances } from '../../../../services/clients' +import { INITIAL_SEND_STATE } from '../../../../services/chain/const' +import { FeeRD, Memo, SendTxState, SendTxStateHandler } from '../../../../services/chain/types' +import { AddressValidation, GetExplorerTxUrl, OpenExplorerTxUrl, WalletBalances } from '../../../../services/clients' import { ValidatePasswordHandler } from '../../../../services/wallet/types' import { WalletBalance } from '../../../../services/wallet/types' import { WalletPasswordConfirmationModal } from '../../../modal/confirmation' @@ -39,7 +41,7 @@ import * as H from '../TxForm.helpers' import * as Styled from '../TxForm.styles' import { validateTxAmountInput } from '../TxForm.util' import { DEFAULT_FEE_OPTION } from './Send.const' -import { useChangeAssetHandler } from './Send.hooks' +import * as Shared from './Send.shared' export type FormValues = { recipient: string @@ -51,11 +53,12 @@ export type FormValues = { export type Props = { walletType: WalletType walletIndex: number + walletAddress: Address balances: WalletBalances balance: WalletBalance - onSubmit: (p: SendTxParams) => void - isLoading: boolean - sendTxStatusMsg: string + transfer$: SendTxStateHandler + openExplorerTxUrl: OpenExplorerTxUrl + getExplorerTxUrl: GetExplorerTxUrl addressValidation: AddressValidation feesWithRates: FeesWithRatesRD reloadFeesHandler: (memo?: Memo) => void @@ -67,11 +70,12 @@ export const SendFormDOGE: React.FC = (props): JSX.Element => { const { walletType, walletIndex, + walletAddress, balances, balance, - onSubmit, - isLoading, - sendTxStatusMsg, + transfer$, + openExplorerTxUrl, + getExplorerTxUrl, addressValidation, feesWithRates: feesWithRatesRD, reloadFeesHandler, @@ -81,10 +85,18 @@ export const SendFormDOGE: React.FC = (props): JSX.Element => { const intl = useIntl() - const changeAssetHandler = useChangeAssetHandler() + const { asset } = balance const [amountToSend, setAmountToSend] = useState(ZERO_BASE_AMOUNT) + const { + state: sendTxState, + reset: resetSendTxState, + subscribe: subscribeSendTxState + } = useSubscriptionState(INITIAL_SEND_STATE) + + const isLoading = useMemo(() => RD.isPending(sendTxState.status), [sendTxState.status]) + const [selectedFeeOption, setSelectedFeeOption] = useState(DEFAULT_FEE_OPTION) const [form] = Form.useForm() @@ -226,36 +238,80 @@ export const SendFormDOGE: React.FC = (props): JSX.Element => { [intl, maxAmount] ) + // Send tx start time + const [sendTxStartTime, setSendTxStartTime] = useState(0) + // State for visibility of Modal to confirm tx const [showPwModal, setShowPwModal] = useState(false) - const sendHandler = useCallback(() => { + const submitTx = useCallback(() => { // close PW modal setShowPwModal(false) - onSubmit({ - walletType, - walletIndex, - recipient: form.getFieldValue('recipient'), - asset: balance.asset, - amount: assetToBase(assetAmount(form.getFieldValue('amount'))), - feeOption: selectedFeeOption, - memo: form.getFieldValue('memo') - }) - }, [onSubmit, walletType, walletIndex, form, balance.asset, selectedFeeOption]) + setSendTxStartTime(Date.now()) + + subscribeSendTxState( + transfer$({ + walletType, + walletIndex, + sender: walletAddress, + recipient: form.getFieldValue('recipient'), + asset: balance.asset, + amount: amountToSend, + feeOption: selectedFeeOption, + memo: form.getFieldValue('memo') + }) + ) + }, [ + subscribeSendTxState, + transfer$, + walletType, + walletIndex, + walletAddress, + form, + balance.asset, + amountToSend, + selectedFeeOption + ]) const renderPwModal = useMemo( () => showPwModal ? ( setShowPwModal(false)} validatePassword$={validatePassword$} /> ) : ( <> ), - [sendHandler, showPwModal, validatePassword$] + [submitTx, showPwModal, validatePassword$] + ) + + const renderTxModal = useMemo( + () => + Shared.renderTxModal({ + asset, + amountToSend, + network, + sendTxState, + resetSendTxState, + sendTxStartTime, + openExplorerTxUrl, + getExplorerTxUrl, + intl + }), + [ + asset, + amountToSend, + network, + sendTxState, + resetSendTxState, + sendTxStartTime, + openExplorerTxUrl, + getExplorerTxUrl, + intl + ] ) const uiFeesRD: UIFeesRD = useMemo( @@ -356,12 +412,7 @@ export const SendFormDOGE: React.FC = (props): JSX.Element => { <> - + = (props): JSX.Element => { {renderFeeOptions} - {sendTxStatusMsg} {intl.formatMessage({ id: 'wallet.action.send' })} @@ -416,6 +466,7 @@ export const SendFormDOGE: React.FC = (props): JSX.Element => { {renderPwModal} + {renderTxModal} ) } diff --git a/src/renderer/components/wallet/txs/send/index.ts b/src/renderer/components/wallet/txs/send/index.ts index ca5e79ec8..44b0e65ac 100644 --- a/src/renderer/components/wallet/txs/send/index.ts +++ b/src/renderer/components/wallet/txs/send/index.ts @@ -1,4 +1,3 @@ -export { Send } from './Send' export { SendFormBNB } from './SendFormBNB' export { SendFormBCH } from './SendFormBCH' export { SendFormBTC } from './SendFormBTC' diff --git a/src/renderer/views/wallet/send/SendView.helper.ts b/src/renderer/views/wallet/send/SendView.helper.ts deleted file mode 100644 index 65785439a..000000000 --- a/src/renderer/views/wallet/send/SendView.helper.ts +++ /dev/null @@ -1,37 +0,0 @@ -import * as RD from '@devexperts/remote-data-ts' -import { Asset } from '@xchainjs/xchain-util' -import * as FP from 'fp-ts/lib/function' -import { IntlShape } from 'react-intl' - -import { emptyString } from '../../../helpers/stringHelper' -import { SendTxState } from '../../../services/chain/types' - -export const sendTxStatusMsg = ({ - sendTxState, - asset, - intl -}: { - sendTxState: SendTxState - asset: Asset - intl: IntlShape -}) => { - const stepDescriptions = [ - intl.formatMessage({ id: 'common.tx.sendingAsset' }, { assetTicker: asset.ticker }), - intl.formatMessage({ id: 'common.tx.checkResult' }) - ] - const { steps, status } = sendTxState - - return FP.pipe( - status, - RD.fold( - () => emptyString, - () => - `${stepDescriptions[steps.current - 1]} (${intl.formatMessage( - { id: 'common.step' }, - { current: steps.current, total: steps.total } - )})`, - () => emptyString, - () => emptyString - ) - ) -} diff --git a/src/renderer/views/wallet/send/SendView.tsx b/src/renderer/views/wallet/send/SendView.tsx index ee0cef89e..6ed40ddd2 100644 --- a/src/renderer/views/wallet/send/SendView.tsx +++ b/src/renderer/views/wallet/send/SendView.tsx @@ -80,7 +80,7 @@ export const SendView: React.FC = (): JSX.Element => { case LTCChain: return case DOGEChain: - return + return default: return (

diff --git a/src/renderer/views/wallet/send/SendViewBCH.tsx b/src/renderer/views/wallet/send/SendViewBCH.tsx index 85c30501f..c5ebd40cb 100644 --- a/src/renderer/views/wallet/send/SendViewBCH.tsx +++ b/src/renderer/views/wallet/send/SendViewBCH.tsx @@ -8,6 +8,7 @@ import * as O from 'fp-ts/Option' import { useObservableState } from 'observable-hooks' import { WalletType } from '../../../../shared/wallet/types' +import { LoadingView } from '../../../components/shared/loading' import { SendFormBCH } from '../../../components/wallet/txs/send' import { useBitcoinCashContext } from '../../../contexts/BitcoinCashContext' import { useChainContext } from '../../../contexts/ChainContext' @@ -62,7 +63,7 @@ export const SendViewBCH: React.FC = (props): JSX.Element => { return FP.pipe( oWalletBalance, O.fold( - () => <>, + () => , (walletBalance) => ( = (props): JSX.Element => { return FP.pipe( oWalletBalance, O.fold( - () => <>, + () => , (walletBalance) => ( = (props): JSX.Element => { - const { walletType, walletIndex, asset } = props - - const intl = useIntl() - const history = useHistory() + const { walletType, walletIndex, walletAddress } = props const { network } = useNetwork() const { @@ -52,22 +43,15 @@ export const SendViewDOGE: React.FC = (props): JSX.Element => { const { openExplorerTxUrl, getExplorerTxUrl } = useOpenExplorerTxUrl(O.some(DOGEChain)) - const oWalletBalance = useMemo(() => getWalletBalanceByAsset(oBalances, asset), [oBalances, asset]) - - const { transfer$ } = useChainContext() - - const { - state: sendTxState, - reset: resetSendTxState, - subscribe: subscribeSendTxState - } = useSubscriptionState(INITIAL_SEND_STATE) - - const onSend = useCallback( - (params: SendTxParams) => { - subscribeSendTxState(transfer$(params)) - }, - [subscribeSendTxState, transfer$] + const oWalletBalance = useMemo( + () => + FP.pipe( + oBalances, + O.chain((balances) => getWalletBalanceByAddress(balances, walletAddress)) + ), + [oBalances, walletAddress] ) + const { transfer$ } = useChainContext() const { feesWithRates$, reloadFeesWithRates } = useDogeContext() @@ -76,67 +60,28 @@ export const SendViewDOGE: React.FC = (props): JSX.Element => { const { validateAddress } = useValidateAddress(DOGEChain) - const isLoading = useMemo(() => RD.isPending(sendTxState.status), [sendTxState.status]) - - const sendTxStatusMsg = useMemo( - () => Helper.sendTxStatusMsg({ sendTxState, asset, intl }), - [asset, intl, sendTxState] - ) - /** - * Custom send form used by DOGE only - */ - const sendForm = useCallback( - (walletBalance: WalletBalance) => ( - (() => []) - )} - balance={walletBalance} - isLoading={isLoading} - onSubmit={onSend} - addressValidation={validateAddress} - feesWithRates={feesWithRatesRD} - reloadFeesHandler={reloadFeesWithRates} - validatePassword$={validatePassword$} - sendTxStatusMsg={sendTxStatusMsg} - network={network} - /> - ), - [ - walletType, - walletIndex, - oBalances, - isLoading, - onSend, - validateAddress, - feesWithRatesRD, - reloadFeesWithRates, - validatePassword$, - sendTxStatusMsg, - network - ] - ) - - const finishActionHandler = useCallback(() => { - resetSendTxState() - history.goBack() - }, [history, resetSendTxState]) - return FP.pipe( oWalletBalance, O.fold( - () => <>, + () => , (walletBalance) => ( - (() => []) + )} + balance={walletBalance} + transfer$={transfer$} + openExplorerTxUrl={openExplorerTxUrl} getExplorerTxUrl={getExplorerTxUrl} - finishActionHandler={finishActionHandler} - errorActionHandler={resetSendTxState} - sendForm={sendForm(walletBalance)} + addressValidation={validateAddress} + feesWithRates={feesWithRatesRD} + reloadFeesHandler={reloadFeesWithRates} + validatePassword$={validatePassword$} + network={network} /> ) ) diff --git a/src/renderer/views/wallet/send/SendViewETH.tsx b/src/renderer/views/wallet/send/SendViewETH.tsx index 6187dec8a..49b379691 100644 --- a/src/renderer/views/wallet/send/SendViewETH.tsx +++ b/src/renderer/views/wallet/send/SendViewETH.tsx @@ -9,6 +9,7 @@ import * as O from 'fp-ts/lib/Option' import { useObservableState } from 'observable-hooks' import { WalletType } from '../../../../shared/wallet/types' +import { LoadingView } from '../../../components/shared/loading' import { SendFormETH } from '../../../components/wallet/txs/send/' import { useChainContext } from '../../../contexts/ChainContext' import { useEthereumContext } from '../../../contexts/EthereumContext' @@ -73,7 +74,7 @@ export const SendViewETH: React.FC = (props): JSX.Element => { return FP.pipe( oWalletBalance, O.fold( - () => <>, + () => , (walletBalance) => ( = (props): JSX.Element => { return FP.pipe( oWalletBalance, O.fold( - () => <>, + () => , (walletBalance) => (