From c3bbfe570e8241307b77182065b16a04a7f45fd3 Mon Sep 17 00:00:00 2001 From: vutuanlinh2k2 <69841784+vutuanlinh2k2@users.noreply.github.com> Date: Fri, 12 Apr 2024 18:34:41 +0700 Subject: [PATCH 1/2] chore: update handling tx with noti (#2222) --- .../BondMoreTxContainer.tsx | 26 +--- .../PayoutAllTxContainer.tsx | 20 +--- .../PayoutTxContainer/PayoutTxContainer.tsx | 24 +--- .../RebondTxContainer/RebondTxContainer.tsx | 21 +--- .../StopNominationTxContainer.tsx | 29 +---- .../UnbondTxContainer/UnbondTxContainer.tsx | 21 +--- .../UpdateNominationsTxContainer.tsx | 22 +--- .../UpdatePayeeTxContainer.tsx | 29 +---- .../WithdrawUnbondedTxContainer.tsx | 29 +---- .../hooks/useExecuteTxWithNotification.ts | 63 ---------- .../hooks/useExecuteTxWithNotification.tsx | 113 ++++++++++++++++++ apps/tangle-dapp/utils/polkadot/utils.ts | 70 +++-------- .../Notification/NotificationItem.tsx | 2 +- 13 files changed, 163 insertions(+), 306 deletions(-) delete mode 100644 apps/tangle-dapp/hooks/useExecuteTxWithNotification.ts create mode 100644 apps/tangle-dapp/hooks/useExecuteTxWithNotification.tsx diff --git a/apps/tangle-dapp/containers/BondMoreTxContainer/BondMoreTxContainer.tsx b/apps/tangle-dapp/containers/BondMoreTxContainer/BondMoreTxContainer.tsx index 489e738575..8135ebce99 100644 --- a/apps/tangle-dapp/containers/BondMoreTxContainer/BondMoreTxContainer.tsx +++ b/apps/tangle-dapp/containers/BondMoreTxContainer/BondMoreTxContainer.tsx @@ -2,7 +2,6 @@ import { BN, BN_ZERO } from '@polkadot/util'; import { useWebContext } from '@webb-tools/api-provider-environment'; -import { isSubstrateAddress } from '@webb-tools/dapp-types'; import { Button, Modal, @@ -17,7 +16,6 @@ import Link from 'next/link'; import { type FC, useCallback, useEffect, useMemo, useState } from 'react'; import AmountInput from '../../components/AmountInput/AmountInput'; -import { useTxConfirmationModal } from '../../context/TxConfirmationContext'; import useNetworkStore from '../../context/useNetworkStore'; import useTokenWalletFreeBalance from '../../data/NominatorStats/useTokenWalletFreeBalance'; import useExecuteTxWithNotification from '../../hooks/useExecuteTxWithNotification'; @@ -33,7 +31,6 @@ const BondMoreTxContainer: FC = ({ const { notificationApi } = useWebbUI(); const { activeAccount } = useWebContext(); const executeTx = useExecuteTxWithNotification(); - const { setTxConfirmationState } = useTxConfirmationModal(); const [amountToBond, setAmountToBond] = useState(null); const { rpcEndpoint, nativeTokenSymbol } = useNetworkStore(); const [isBondMoreTxLoading, setIsBondMoreTxLoading] = useState(false); @@ -86,11 +83,9 @@ const BondMoreTxContainer: FC = ({ setIsBondMoreTxLoading(true); try { - if (amountToBond === null) { - throw new Error('Amount to bond more is required.'); - } + if (amountToBond === null) return; const bondingAmount = +formatBnToDisplayAmount(amountToBond); - const hash = await executeTx( + await executeTx( () => bondExtraTokensEvm(walletAddress, bondingAmount), () => bondExtraTokensSubstrate(rpcEndpoint, walletAddress, bondingAmount), @@ -98,28 +93,15 @@ const BondMoreTxContainer: FC = ({ 'Failed to bond extra tokens!' ); - setTxConfirmationState({ - isOpen: true, - status: 'success', - hash: hash, - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } catch { - setTxConfirmationState({ - isOpen: true, - status: 'error', - hash: '', - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } finally { closeModal(); + } catch { + setIsBondMoreTxLoading(false); } }, [ amountToBond, closeModal, executeTx, rpcEndpoint, - setTxConfirmationState, walletAddress, nativeTokenSymbol, ]); diff --git a/apps/tangle-dapp/containers/PayoutAllTxContainer/PayoutAllTxContainer.tsx b/apps/tangle-dapp/containers/PayoutAllTxContainer/PayoutAllTxContainer.tsx index d611589d17..bb40c123e6 100644 --- a/apps/tangle-dapp/containers/PayoutAllTxContainer/PayoutAllTxContainer.tsx +++ b/apps/tangle-dapp/containers/PayoutAllTxContainer/PayoutAllTxContainer.tsx @@ -1,7 +1,6 @@ 'use client'; import { useWebContext } from '@webb-tools/api-provider-environment'; -import { isSubstrateAddress } from '@webb-tools/dapp-types'; import { Button, InputField, @@ -14,7 +13,6 @@ import { import { WEBB_TANGLE_DOCS_STAKING_URL } from '@webb-tools/webb-ui-components/constants'; import { type FC, useCallback, useMemo, useState } from 'react'; -import { useTxConfirmationModal } from '../../context/TxConfirmationContext'; import useNetworkStore from '../../context/useNetworkStore'; import useExecuteTxWithNotification from '../../hooks/useExecuteTxWithNotification'; import { batchPayoutStakers as batchPayoutStakersEvm } from '../../utils/evm'; @@ -31,7 +29,6 @@ const PayoutAllTxContainer: FC = ({ const { activeAccount } = useWebContext(); const executeTx = useExecuteTxWithNotification(); const { rpcEndpoint } = useNetworkStore(); - const { setTxConfirmationState } = useTxConfirmationModal(); const [isPayoutAllTxLoading, setIsPayoutAllTxLoading] = useState(false); const walletAddress = useMemo(() => { @@ -69,7 +66,7 @@ const PayoutAllTxContainer: FC = ({ setIsPayoutAllTxLoading(true); try { - const hash = await executeTx( + await executeTx( () => batchPayoutStakersEvm(walletAddress, payoutValidatorsAndEras), () => batchPayoutStakersSubstrate( @@ -91,20 +88,8 @@ const PayoutAllTxContainer: FC = ({ ); updatePayouts(updatedPayouts); - - setTxConfirmationState({ - isOpen: true, - status: 'success', - hash: hash, - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); } catch { - setTxConfirmationState({ - isOpen: true, - status: 'error', - hash: '', - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); + setIsPayoutAllTxLoading(false); } finally { closeModal(); } @@ -112,7 +97,6 @@ const PayoutAllTxContainer: FC = ({ executeTx, payouts, updatePayouts, - setTxConfirmationState, walletAddress, payoutValidatorsAndEras, rpcEndpoint, diff --git a/apps/tangle-dapp/containers/PayoutTxContainer/PayoutTxContainer.tsx b/apps/tangle-dapp/containers/PayoutTxContainer/PayoutTxContainer.tsx index 55a642dd9c..433b68bef7 100644 --- a/apps/tangle-dapp/containers/PayoutTxContainer/PayoutTxContainer.tsx +++ b/apps/tangle-dapp/containers/PayoutTxContainer/PayoutTxContainer.tsx @@ -1,7 +1,6 @@ 'use client'; import { useWebContext } from '@webb-tools/api-provider-environment'; -import { isSubstrateAddress } from '@webb-tools/dapp-types'; import { Button, InputField, @@ -14,7 +13,6 @@ import { import { WEBB_TANGLE_DOCS_STAKING_URL } from '@webb-tools/webb-ui-components/constants'; import { type FC, useCallback, useMemo, useState } from 'react'; -import { useTxConfirmationModal } from '../../context/TxConfirmationContext'; import useNetworkStore from '../../context/useNetworkStore'; import useExecuteTxWithNotification from '../../hooks/useExecuteTxWithNotification'; import { payoutStakers as payoutStakersEvm } from '../../utils/evm'; @@ -31,7 +29,6 @@ const PayoutTxContainer: FC = ({ const { activeAccount } = useWebContext(); const { validatorAddress, era } = payoutTxProps; const executeTx = useExecuteTxWithNotification(); - const { setTxConfirmationState } = useTxConfirmationModal(); const { rpcEndpoint } = useNetworkStore(); const [isPayoutTxLoading, setIsPayoutTxLoading] = useState(false); @@ -54,7 +51,7 @@ const PayoutTxContainer: FC = ({ setIsPayoutTxLoading(true); try { - const hash = await executeTx( + await executeTx( () => payoutStakersEvm(walletAddress, validatorAddress, Number(era)), () => payoutStakersSubstrate( @@ -77,21 +74,11 @@ const PayoutTxContainer: FC = ({ updatePayouts(updatedPayouts); - setTxConfirmationState({ - isOpen: true, - status: 'success', - hash, - txType: isSubstrateAddress(validatorAddress) ? 'substrate' : 'evm', - }); - } catch { - setTxConfirmationState({ - isOpen: true, - status: 'error', - hash: '', - txType: isSubstrateAddress(validatorAddress) ? 'substrate' : 'evm', - }); - } finally { closeModal(); + + closeModal(); + } catch { + setIsPayoutTxLoading(false); } }, [ closeModal, @@ -99,7 +86,6 @@ const PayoutTxContainer: FC = ({ executeTx, payouts, rpcEndpoint, - setTxConfirmationState, updatePayouts, validatorAddress, walletAddress, diff --git a/apps/tangle-dapp/containers/RebondTxContainer/RebondTxContainer.tsx b/apps/tangle-dapp/containers/RebondTxContainer/RebondTxContainer.tsx index 7b4684d8f3..1e4bca0c61 100644 --- a/apps/tangle-dapp/containers/RebondTxContainer/RebondTxContainer.tsx +++ b/apps/tangle-dapp/containers/RebondTxContainer/RebondTxContainer.tsx @@ -18,7 +18,6 @@ import { type FC, useCallback, useMemo, useState } from 'react'; import { BondedTokensBalanceInfo } from '../../components'; import AmountInput from '../../components/AmountInput/AmountInput'; -import { useTxConfirmationModal } from '../../context/TxConfirmationContext'; import useNetworkStore from '../../context/useNetworkStore'; import useTotalUnbondedAndUnbondingAmount from '../../data/NominatorStats/useTotalUnbondedAndUnbondingAmount'; import useUnbondingAmountSubscription from '../../data/NominatorStats/useUnbondingAmountSubscription'; @@ -36,7 +35,6 @@ const RebondTxContainer: FC = ({ const { notificationApi } = useWebbUI(); const { activeAccount } = useWebContext(); const executeTx = useExecuteTxWithNotification(); - const { setTxConfirmationState } = useTxConfirmationModal(); const { rpcEndpoint, nativeTokenSymbol } = useNetworkStore(); const [amountToRebond, setAmountToRebond] = useState(null); @@ -110,35 +108,22 @@ const RebondTxContainer: FC = ({ throw new Error('There is no amount to rebond.'); } const rebondAmount = +formatBnToDisplayAmount(amountToRebond); - const hash = await executeTx( + await executeTx( () => rebondTokensEvm(walletAddress, rebondAmount), () => rebondTokensSubstrate(rpcEndpoint, walletAddress, rebondAmount), `Successfully rebonded ${rebondAmount} ${nativeTokenSymbol}.`, 'Failed to rebond tokens!' ); - setTxConfirmationState({ - isOpen: true, - status: 'success', - hash, - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } catch { - setTxConfirmationState({ - isOpen: true, - status: 'error', - hash: '', - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } finally { closeModal(); + } catch { + setIsRebondTxLoading(false); } }, [ amountToRebond, closeModal, executeTx, rpcEndpoint, - setTxConfirmationState, walletAddress, nativeTokenSymbol, ]); diff --git a/apps/tangle-dapp/containers/StopNominationTxContainer/StopNominationTxContainer.tsx b/apps/tangle-dapp/containers/StopNominationTxContainer/StopNominationTxContainer.tsx index 75b883eabb..c3511c2fce 100644 --- a/apps/tangle-dapp/containers/StopNominationTxContainer/StopNominationTxContainer.tsx +++ b/apps/tangle-dapp/containers/StopNominationTxContainer/StopNominationTxContainer.tsx @@ -15,7 +15,6 @@ import { WEBB_TANGLE_DOCS_STAKING_URL } from '@webb-tools/webb-ui-components/con import Link from 'next/link'; import { type FC, useCallback, useMemo, useState } from 'react'; -import { useTxConfirmationModal } from '../../context/TxConfirmationContext'; import useNetworkStore from '../../context/useNetworkStore'; import useNominations from '../../data/NominationsPayouts/useNominations'; import useExecuteTxWithNotification from '../../hooks/useExecuteTxWithNotification'; @@ -30,7 +29,6 @@ const StopNominationTxContainer: FC = ({ }) => { const { activeAccount } = useWebContext(); const executeTx = useExecuteTxWithNotification(); - const { setTxConfirmationState } = useTxConfirmationModal(); const { rpcEndpoint } = useNetworkStore(); const [isStopNominationTxLoading, setIsStopNominationTxLoading] = @@ -70,36 +68,17 @@ const StopNominationTxContainer: FC = ({ setIsStopNominationTxLoading(true); try { - const hash = await executeTx( + await executeTx( () => stopNominationEvm(walletAddress), () => stopNominationSubstrate(rpcEndpoint, walletAddress), `Successfully stopped nomination!`, 'Failed to stop nomination!' ); - - setTxConfirmationState({ - isOpen: true, - status: 'success', - hash, - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } catch { - setTxConfirmationState({ - isOpen: true, - status: 'error', - hash: '', - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } finally { closeModal(); + } catch { + setIsStopNominationTxLoading(false); } - }, [ - closeModal, - executeTx, - rpcEndpoint, - setTxConfirmationState, - walletAddress, - ]); + }, [closeModal, executeTx, rpcEndpoint, walletAddress]); return ( diff --git a/apps/tangle-dapp/containers/UnbondTxContainer/UnbondTxContainer.tsx b/apps/tangle-dapp/containers/UnbondTxContainer/UnbondTxContainer.tsx index f792ff800a..f343a435f2 100644 --- a/apps/tangle-dapp/containers/UnbondTxContainer/UnbondTxContainer.tsx +++ b/apps/tangle-dapp/containers/UnbondTxContainer/UnbondTxContainer.tsx @@ -17,7 +17,6 @@ import Link from 'next/link'; import { type FC, useCallback, useMemo, useState } from 'react'; import AmountInput from '../../components/AmountInput/AmountInput'; -import { useTxConfirmationModal } from '../../context/TxConfirmationContext'; import useNetworkStore from '../../context/useNetworkStore'; import useTotalStakedAmountSubscription from '../../data/NominatorStats/useTotalStakedAmountSubscription'; import useUnbondingAmountSubscription from '../../data/NominatorStats/useUnbondingAmountSubscription'; @@ -35,7 +34,6 @@ const UnbondTxContainer: FC = ({ const { notificationApi } = useWebbUI(); const { activeAccount } = useWebContext(); const executeTx = useExecuteTxWithNotification(); - const { setTxConfirmationState } = useTxConfirmationModal(); const { rpcEndpoint, nativeTokenSymbol } = useNetworkStore(); const [amountToUnbond, setAmountToUnbond] = useState(null); @@ -136,7 +134,7 @@ const UnbondTxContainer: FC = ({ throw new Error('Amount to unbond is required.'); } const unbondingAmount = +formatBnToDisplayAmount(amountToUnbond); - const hash = await executeTx( + await executeTx( () => unbondTokensEvm(walletAddress, unbondingAmount), () => unbondTokensSubstrate(rpcEndpoint, walletAddress, unbondingAmount), @@ -144,28 +142,15 @@ const UnbondTxContainer: FC = ({ 'Failed to unbond tokens!' ); - setTxConfirmationState({ - isOpen: true, - status: 'success', - hash: hash, - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } catch { - setTxConfirmationState({ - isOpen: true, - status: 'error', - hash: '', - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } finally { closeModal(); + } catch { + setIsUnbondTxLoading(false); } }, [ amountToUnbond, closeModal, executeTx, rpcEndpoint, - setTxConfirmationState, walletAddress, nativeTokenSymbol, ]); diff --git a/apps/tangle-dapp/containers/UpdateNominationsTxContainer/UpdateNominationsTxContainer.tsx b/apps/tangle-dapp/containers/UpdateNominationsTxContainer/UpdateNominationsTxContainer.tsx index dc9036ace9..547d2adc26 100644 --- a/apps/tangle-dapp/containers/UpdateNominationsTxContainer/UpdateNominationsTxContainer.tsx +++ b/apps/tangle-dapp/containers/UpdateNominationsTxContainer/UpdateNominationsTxContainer.tsx @@ -1,7 +1,6 @@ 'use client'; import { useWebContext } from '@webb-tools/api-provider-environment'; -import { isSubstrateAddress } from '@webb-tools/dapp-types'; import { Alert, Button, @@ -12,7 +11,6 @@ import { } from '@webb-tools/webb-ui-components'; import { type FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { useTxConfirmationModal } from '../../context/TxConfirmationContext'; import useNetworkStore from '../../context/useNetworkStore'; import useExecuteTxWithNotification from '../../hooks/useExecuteTxWithNotification'; import useMaxNominationQuota from '../../hooks/useMaxNominationQuota'; @@ -28,7 +26,6 @@ const UpdateNominationsTxContainer: FC = ({ }) => { const { activeAccount } = useWebContext(); const executeTx = useExecuteTxWithNotification(); - const { setTxConfirmationState } = useTxConfirmationModal(); const maxNominationQuota = useMaxNominationQuota(); const { rpcEndpoint } = useNetworkStore(); @@ -86,7 +83,7 @@ const UpdateNominationsTxContainer: FC = ({ setIsSubmitAndSignTxLoading(true); try { - const hash = await executeTx( + await executeTx( () => nominateValidatorsEvm(walletAddress, selectedValidators), () => nominateValidatorsSubstrate( @@ -97,21 +94,9 @@ const UpdateNominationsTxContainer: FC = ({ `Successfully updated nominations!`, 'Failed to update nominations!' ); - setTxConfirmationState({ - isOpen: true, - status: 'success', - hash, - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } catch { - setTxConfirmationState({ - isOpen: true, - status: 'error', - hash: '', - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } finally { closeModal(); + } catch { + setIsSubmitAndSignTxLoading(false); } }, [ closeModal, @@ -119,7 +104,6 @@ const UpdateNominationsTxContainer: FC = ({ isReadyToSubmitAndSignTx, rpcEndpoint, selectedValidators, - setTxConfirmationState, walletAddress, ]); diff --git a/apps/tangle-dapp/containers/UpdatePayeeTxContainer/UpdatePayeeTxContainer.tsx b/apps/tangle-dapp/containers/UpdatePayeeTxContainer/UpdatePayeeTxContainer.tsx index 208a647670..70dd01df9c 100644 --- a/apps/tangle-dapp/containers/UpdatePayeeTxContainer/UpdatePayeeTxContainer.tsx +++ b/apps/tangle-dapp/containers/UpdatePayeeTxContainer/UpdatePayeeTxContainer.tsx @@ -15,7 +15,6 @@ import Link from 'next/link'; import { type FC, useCallback, useMemo, useState } from 'react'; import { PAYMENT_DESTINATION_OPTIONS } from '../../constants'; -import { useTxConfirmationModal } from '../../context/TxConfirmationContext'; import useNetworkStore from '../../context/useNetworkStore'; import usePaymentDestinationSubscription from '../../data/NominatorStats/usePaymentDestinationSubscription'; import useExecuteTxWithNotification from '../../hooks/useExecuteTxWithNotification'; @@ -34,7 +33,6 @@ const UpdatePayeeTxContainer: FC = ({ const { activeAccount } = useWebContext(); const executeTx = useExecuteTxWithNotification(); const { rpcEndpoint } = useNetworkStore(); - const { setTxConfirmationState } = useTxConfirmationModal(); const [paymentDestination, setPaymentDestination] = useState( PaymentDestination.STAKED @@ -82,7 +80,7 @@ const UpdatePayeeTxContainer: FC = ({ setIsUpdatePaymentDestinationTxLoading(true); try { - const hash = await executeTx( + await executeTx( () => updatePaymentDestinationEvm(walletAddress, paymentDestination), () => updatePaymentDestinationSubstrate( @@ -94,30 +92,11 @@ const UpdatePayeeTxContainer: FC = ({ 'Failed to update payment destination!' ); - setTxConfirmationState({ - isOpen: true, - status: 'success', - hash, - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } catch { - setTxConfirmationState({ - isOpen: true, - status: 'error', - hash: '', - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } finally { closeModal(); + } catch { + setIsUpdatePaymentDestinationTxLoading(false); } - }, [ - closeModal, - executeTx, - paymentDestination, - rpcEndpoint, - setTxConfirmationState, - walletAddress, - ]); + }, [closeModal, executeTx, paymentDestination, rpcEndpoint, walletAddress]); if (currentPaymentDestinationError) { notificationApi({ diff --git a/apps/tangle-dapp/containers/WithdrawUnbondedTxContainer/WithdrawUnbondedTxContainer.tsx b/apps/tangle-dapp/containers/WithdrawUnbondedTxContainer/WithdrawUnbondedTxContainer.tsx index 9eef9ac828..79360fa8ed 100644 --- a/apps/tangle-dapp/containers/WithdrawUnbondedTxContainer/WithdrawUnbondedTxContainer.tsx +++ b/apps/tangle-dapp/containers/WithdrawUnbondedTxContainer/WithdrawUnbondedTxContainer.tsx @@ -15,7 +15,6 @@ import { import { type FC, useCallback, useMemo, useState } from 'react'; import { BondedTokensBalanceInfo } from '../../components/BondedTokensBalanceInfo'; -import { useTxConfirmationModal } from '../../context/TxConfirmationContext'; import useNetworkStore from '../../context/useNetworkStore'; import useTotalUnbondedAndUnbondingAmount from '../../data/NominatorStats/useTotalUnbondedAndUnbondingAmount'; import useExecuteTxWithNotification from '../../hooks/useExecuteTxWithNotification'; @@ -33,7 +32,6 @@ const WithdrawUnbondedTxContainer: FC = ({ const { notificationApi } = useWebbUI(); const { activeAccount } = useWebContext(); const executeTx = useExecuteTxWithNotification(); - const { setTxConfirmationState } = useTxConfirmationModal(); const [isRebondModalOpen, setIsRebondModalOpen] = useState(false); const { rpcEndpoint } = useNetworkStore(); @@ -97,7 +95,7 @@ const WithdrawUnbondedTxContainer: FC = ({ setIsWithdrawUnbondedTxLoading(true); try { - const hash = await executeTx( + await executeTx( async () => { const slashingSpans = await getSlashingSpans( rpcEndpoint, @@ -125,30 +123,11 @@ const WithdrawUnbondedTxContainer: FC = ({ 'Failed to withdraw tokens!' ); - setTxConfirmationState({ - isOpen: true, - status: 'success', - hash, - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } catch { - setTxConfirmationState({ - isOpen: true, - status: 'error', - hash: '', - txType: isSubstrateAddress(walletAddress) ? 'substrate' : 'evm', - }); - } finally { closeModal(); + } catch { + setIsWithdrawUnbondedTxLoading(false); } - }, [ - closeModal, - executeTx, - rpcEndpoint, - setTxConfirmationState, - substrateAddress, - walletAddress, - ]); + }, [closeModal, executeTx, rpcEndpoint, substrateAddress, walletAddress]); const onRebondClick = () => { closeModal(); diff --git a/apps/tangle-dapp/hooks/useExecuteTxWithNotification.ts b/apps/tangle-dapp/hooks/useExecuteTxWithNotification.ts deleted file mode 100644 index 99a09dfbbb..0000000000 --- a/apps/tangle-dapp/hooks/useExecuteTxWithNotification.ts +++ /dev/null @@ -1,63 +0,0 @@ -import type { HexString } from '@polkadot/util/types'; -import { useWebContext } from '@webb-tools/api-provider-environment'; -import { useWebbUI } from '@webb-tools/webb-ui-components'; -import { useCallback } from 'react'; - -import ensureError from '../utils/ensureError'; -import { evmPublicClient } from '../utils/evm'; - -const useExecuteTxWithNotification = () => { - const { notificationApi } = useWebbUI(); - const { activeWallet } = useWebContext(); - - const executeTx = useCallback( - async ( - evmFnc: () => Promise, - substrateFnc: () => Promise, - successMessage: string, - errorMessage: string - ): Promise => { - let txHash: HexString = '0x0'; - - try { - if (activeWallet?.platform === 'EVM') { - txHash = await evmFnc(); - - if (!txHash) { - throw new Error(errorMessage); - } - - const tx = await evmPublicClient.waitForTransactionReceipt({ - hash: txHash, - }); - - if (tx.status !== 'success') { - throw new Error(errorMessage); - } - } else if (activeWallet?.platform === 'Substrate') { - txHash = await substrateFnc(); - - if (!txHash) { - throw new Error(errorMessage); - } - } - - notificationApi({ variant: 'success', message: successMessage }); - - return txHash; - } catch (error) { - notificationApi({ - variant: 'error', - message: ensureError(error).message, - }); - - throw error; - } - }, - [notificationApi, activeWallet?.platform] - ); - - return executeTx; -}; - -export default useExecuteTxWithNotification; diff --git a/apps/tangle-dapp/hooks/useExecuteTxWithNotification.tsx b/apps/tangle-dapp/hooks/useExecuteTxWithNotification.tsx new file mode 100644 index 0000000000..181f10b666 --- /dev/null +++ b/apps/tangle-dapp/hooks/useExecuteTxWithNotification.tsx @@ -0,0 +1,113 @@ +import type { HexString } from '@polkadot/util/types'; +import { useWebContext } from '@webb-tools/api-provider-environment'; +import { Button, Typography } from '@webb-tools/webb-ui-components'; +import { useSnackbar } from 'notistack'; +import { useCallback } from 'react'; + +import ensureError from '../utils/ensureError'; +import { evmPublicClient } from '../utils/evm'; +import useExplorerUrl, { ExplorerType } from './useExplorerUrl'; + +const useExecuteTxWithNotification = () => { + const { activeWallet } = useWebContext(); + const getExplorerUrl = useExplorerUrl(); + const { enqueueSnackbar: enqueueNotifications } = useSnackbar(); + + /** + * Executes a transaction based on the active wallet's platform. + * + * @param evmFnc - A function that returns a Promise resolving to a HexString. This function is used when the active wallet's platform is 'EVM'. + * @param substrateFnc - A function that returns a Promise resolving to a HexString. This function is used when the active wallet's platform is 'Substrate'. + * @param successMessage - The message to display when the transaction is successful. + * @param errorMessage - The message to display when the transaction fails. + * + * @returns A Promise that resolves to a boolean. The Promise resolves to true if the transaction was successful, and false otherwise. + */ + const executeTx = useCallback( + async ( + evmFnc: () => Promise, + substrateFnc: () => Promise, + successMessage: string, + errorMessage: string + ): Promise => { + let txHash: HexString | null = null; + try { + if (activeWallet?.platform === 'EVM') { + const evmTxHash = await evmFnc(); + + const tx = await evmPublicClient.waitForTransactionReceipt({ + hash: evmTxHash, + }); + + if (tx.status === 'success') { + txHash = evmTxHash; + } + } else if (activeWallet?.platform === 'Substrate') { + const substrateTxHash = await substrateFnc(); + txHash = substrateTxHash; + } + + if (!txHash) { + throw new Error(errorMessage); + } + + // TODO: tx explorer url is incorrect + const txExplorerUrl = getExplorerUrl( + txHash, + activeWallet?.platform === 'EVM' + ? ExplorerType.EVM + : ExplorerType.Substrate + ); + + // Currently using SnackbarProvider for managing NotificationStacked + // For one-off configurations, must use enqueueSnackbar + enqueueNotifications( +
+ + {successMessage} + + {txExplorerUrl !== null && ( + + )} +
, + { + variant: 'success', + autoHideDuration: null, + } + ); + + return txHash; + } catch (error) { + enqueueNotifications( +
+ + {errorMessage} + + + {ensureError(error).message} + +
, + { + variant: 'error', + autoHideDuration: 5000, + } + ); + + throw error; + } + }, + [activeWallet?.platform, getExplorerUrl, enqueueNotifications] + ); + + return executeTx; +}; + +export default useExecuteTxWithNotification; diff --git a/apps/tangle-dapp/utils/polkadot/utils.ts b/apps/tangle-dapp/utils/polkadot/utils.ts index 702ac3b750..fc9988d3f8 100644 --- a/apps/tangle-dapp/utils/polkadot/utils.ts +++ b/apps/tangle-dapp/utils/polkadot/utils.ts @@ -14,58 +14,22 @@ export const getTxPromise = async ( throw new Error('Failed to get Polkadot injector'); } - return new Promise((resolve, reject) => { - try { - tx.signAndSend( - address, - { - signer: injector.signer, - // Uncomment and understand the nonce when you need to deal with nonce manually - nonce: -1, - }, - ({ status, dispatchError, events }) => { - if (status.isInBlock || status.isFinalized) { - for (const event of events) { - const { - event: { method }, - } = event; + try { + const hash = await tx.signAndSend(address, { + signer: injector.signer, + // prevent txs having the same nonce + // https://polkadot.js.org/docs/api/cookbook/tx#how-do-i-take-the-pending-tx-pool-into-account-in-my-nonce + nonce: -1, + }); - if (dispatchError && method === 'ExtrinsicFailed') { - let message: string = dispatchError.type; - - if (dispatchError.isModule) { - try { - const mod = dispatchError.asModule; - const error = dispatchError.registry.findMetaError(mod); - message = `${error.section}.${error.name}`; - } catch (error) { - console.error(error); - reject(message); - } - } else if (dispatchError.isToken) { - message = `${dispatchError.type}.${dispatchError.asToken.type}`; - } - - reject(message); - } else if (method === 'ExtrinsicSuccess' && status.isFinalized) { - resolve(status.asFinalized.toHex()); - } - } - } - } - ).catch((error) => { - reject( - `An error occurred during transaction submission: ${error.message}` - ); - }); - } catch (error) { - reject( - typeof error === 'string' - ? `Error: ${error}` - : error instanceof Error - ? error.message - : 'An unknown error occurred.' - ); - } - }); + return hash.toHex(); + } catch (error) { + throw new Error( + typeof error === 'string' + ? `Error: ${error}` + : error instanceof Error + ? error.message + : 'Failed to get statement' + ); + } }; diff --git a/libs/webb-ui-components/src/components/Notification/NotificationItem.tsx b/libs/webb-ui-components/src/components/Notification/NotificationItem.tsx index 01262370e5..b9f0cc0943 100644 --- a/libs/webb-ui-components/src/components/Notification/NotificationItem.tsx +++ b/libs/webb-ui-components/src/components/Notification/NotificationItem.tsx @@ -64,7 +64,7 @@ export const NotificationItem = forwardRef( )} >
-
{Icon ?? DefaultIcon}
+
{Icon ?? DefaultIcon}
{typeof message === 'string' ? ( From 037d15fdd40e58759e2b821ca9dc436bf8dedf8e Mon Sep 17 00:00:00 2001 From: Yurixander R <101931215+yurixander@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:19:28 -0400 Subject: [PATCH 2/2] [RELEASE] 2024 April 12 - Tangle Dapp (#2228) --- apps/tangle-dapp/CHANGELOG.md | 23 +++++++++++++++++++++++ apps/tangle-dapp/package.json | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/apps/tangle-dapp/CHANGELOG.md b/apps/tangle-dapp/CHANGELOG.md index fae2509474..6fd2bb2fb2 100644 --- a/apps/tangle-dapp/CHANGELOG.md +++ b/apps/tangle-dapp/CHANGELOG.md @@ -165,3 +165,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - EVM transfers for EVM -> Substrate now work correctly - https://github.com/webb-tools/webb-dapp/pull/2202 - Free balance for EVM accounts is now shown correctly - https://github.com/webb-tools/webb-dapp/pull/2205 - `Open Explorer` link now opens Polkadot/Substrate Explorer or Blockscout, depending on whether the active/connected account is a Substrate or EVM account - https://github.com/webb-tools/webb-dapp/pull/2205 + +## [0.0.7] - 2024-04-12 + +### Added + +- Added `View Account` button to Nomination page - https://github.com/webb-tools/webb-dapp/pull/2211 + +### Changed + +- Vesting schedules are now sorted by earliest unlock block, in ascending order - https://github.com/webb-tools/webb-dapp/pull/2218 +- UI now gets updated after transaction completes, not before - https://github.com/webb-tools/webb-dapp/pull/2222 + +### Fixed + +- Use proper balance for account summary card (free vs. transferrable) - https://github.com/webb-tools/webb-dapp/pull/2209 +- Validator list was in a perpetual loading state under mainnet network - https://github.com/webb-tools/webb-dapp/pull/2220 +- Visual improvements - https://github.com/webb-tools/webb-dapp/pull/2223 +- Add or switch chain on EVM wallets to the active chain on the Tangle dApp - https://github.com/webb-tools/webb-dapp/pull/2225 +- Significantly improved performance of all transactions in the Nomination page - https://github.com/webb-tools/webb-dapp/pull/2222 + +### Removed + +- Transaction confirmation modal, replaced with a notification that also includes a link to the explorer - https://github.com/webb-tools/webb-dapp/pull/2222 diff --git a/apps/tangle-dapp/package.json b/apps/tangle-dapp/package.json index 4966c51b32..8fb4a884da 100644 --- a/apps/tangle-dapp/package.json +++ b/apps/tangle-dapp/package.json @@ -1,5 +1,5 @@ { "name": "@webb-tools/tangle-dapp", - "version": "0.0.6", + "version": "0.0.7", "license": "Apache-2.0" }