From 5e9b5107f1d633a37d4fd81eb529997a50739a85 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Fri, 13 Sep 2024 22:22:01 +0200 Subject: [PATCH] Refactor callback (#130) --- src/components/MyDelegations.tsx | 24 ++++---- src/hooks/useGetSigningCallback.tsx | 41 +++++++++++++ src/pages/Delegate/MultiTransactionDialog.tsx | 59 ++++++++----------- src/pages/Delegate/index.tsx | 37 +++--------- 4 files changed, 86 insertions(+), 75 deletions(-) create mode 100644 src/hooks/useGetSigningCallback.tsx diff --git a/src/components/MyDelegations.tsx b/src/components/MyDelegations.tsx index 403650f..25bc59c 100644 --- a/src/components/MyDelegations.tsx +++ b/src/components/MyDelegations.tsx @@ -11,7 +11,7 @@ import { Button } from './ui/button' import { useAccounts } from '@/contexts/AccountsContext' import { Transaction } from 'polkadot-api' import { DelegationByAmountConviction } from './DelegationByAmountConviction' -import { toast } from 'sonner' +import { useGetSigningCallback } from '@/hooks/useGetSigningCallback' export const MyDelegations = () => { const { api } = useNetwork() @@ -42,6 +42,7 @@ export const MyDelegations = () => { return result }, [delegations]) + const getSubscriptionCallback = useGetSigningCallback() const onUndelegate = useCallback( (delegate: string) => { if (!api || !selectedAccount || !delegations) return @@ -62,23 +63,20 @@ export const MyDelegations = () => { tx = api.tx.Utility.batch({ calls: batchTx }) } - tx.signSubmitAndWatch(selectedAccount.polkadotSigner).subscribe({ - next: (event) => { - console.log(event) - toast.info(`Event ${event.type}`) - if (event.type === 'finalized') { - setDelegatesLoading((prev) => prev.filter((id) => id !== delegate)) - refreshLocks() - } + const subscriptionCallback = getSubscriptionCallback({ + onError: () => { + setDelegatesLoading((prev) => prev.filter((id) => id !== delegate)) }, - error: (error) => { - console.error(error) - toast.info(`Event Error: ${JSON.stringify(error)}`) + onFinalized: () => { setDelegatesLoading((prev) => prev.filter((id) => id !== delegate)) + refreshLocks() }, }) + tx.signSubmitAndWatch(selectedAccount.polkadotSigner).subscribe( + subscriptionCallback, + ) }, - [api, delegations, refreshLocks, selectedAccount], + [api, delegations, getSubscriptionCallback, refreshLocks, selectedAccount], ) return ( diff --git a/src/hooks/useGetSigningCallback.tsx b/src/hooks/useGetSigningCallback.tsx new file mode 100644 index 0000000..67a7dff --- /dev/null +++ b/src/hooks/useGetSigningCallback.tsx @@ -0,0 +1,41 @@ +import { DispatchError } from '@polkadot-api/descriptors' +import { TxEvent } from 'polkadot-api' +import { toast } from 'sonner' + +interface Props { + onInBlock?: () => void + onFinalized?: () => void + onError?: () => void +} + +export const useGetSigningCallback = + () => + ({ onError, onFinalized, onInBlock }: Props) => { + return { + next: (event: TxEvent) => { + const promise = () => + new Promise((resolve) => setTimeout(resolve, 2000)) + + if (event.type === 'broadcasted') { + toast.promise(promise, { + loading: 'Broadcasting tx', + success: 'Tx broadcasted', + duration: 2000, + }) + } + if (event.type === 'txBestBlocksState') { + toast.success(`Tx in block`) + } + onInBlock && onInBlock() + if (event.type === 'finalized') { + toast.success(`Tx finalized in block: ${event.block.number}`) + onFinalized && onFinalized() + } + }, + error: (error: DispatchError) => { + console.error(error) + toast.error(`Error: ${JSON.stringify(error)}`) + onError && onError() + }, + } + } diff --git a/src/pages/Delegate/MultiTransactionDialog.tsx b/src/pages/Delegate/MultiTransactionDialog.tsx index b23b85d..eff7129 100644 --- a/src/pages/Delegate/MultiTransactionDialog.tsx +++ b/src/pages/Delegate/MultiTransactionDialog.tsx @@ -12,6 +12,7 @@ import { DelegateTxs } from '@/hooks/useGetDelegateTx' import { useTestTx } from '@/hooks/useTestTx' import { useState } from 'react' import { TooLargeDialog } from './TooLargeDialog' +import { useGetSigningCallback } from '@/hooks/useGetSigningCallback' interface Props { isOpen: boolean @@ -35,6 +36,7 @@ export const MultiTransactionDialog = ({ const { selectedAccount } = useAccounts() const [waitingForFinalization, setWaitingForFinalization] = useState(false) const [promptForHelpCallData, setPromptForHelpCallData] = useState('') + const getSubscriptionCallBack = useGetSigningCallback() const onSign = () => { step === 1 && onSignStep1() @@ -43,6 +45,7 @@ export const MultiTransactionDialog = ({ const onSignStep1 = async () => { if (!api || !selectedAccount) return + setIsTxInitiated(true) const step1Txs = api.tx.Utility.batch_all({ calls: [ @@ -63,24 +66,17 @@ export const MultiTransactionDialog = ({ return } - setIsTxInitiated(true) + const subscriptionCallBack1 = getSubscriptionCallBack({ + onError: () => setIsTxInitiated(false), + onFinalized: () => { + setStep(2) + setIsTxInitiated(false) + }, + }) + ;(await step1Txs) .signSubmitAndWatch(selectedAccount?.polkadotSigner) - .subscribe((event) => { - console.info(event) - - if (event.type === 'txBestBlocksState' && event.found) { - if (event.dispatchError) { - console.error('Tx error', event) - setIsTxInitiated(false) - - return - } - - setStep(2) - setIsTxInitiated(false) - } - }) + .subscribe(subscriptionCallBack1) } const onSignStep2 = async () => { @@ -106,25 +102,22 @@ export const MultiTransactionDialog = ({ return } + const subscriptionCallBack2 = getSubscriptionCallBack({ + onError: () => { + setIsTxInitiated(false) + setWaitingForFinalization(true) + }, + onInBlock: () => setWaitingForFinalization(true), + onFinalized: () => { + onProcessFinished() + setIsTxInitiated(false) + setWaitingForFinalization(false) + }, + }) + await step2Txs .signSubmitAndWatch(selectedAccount?.polkadotSigner, { at: 'best' }) - .subscribe((event) => { - console.info(event) - - if (event.type === 'txBestBlocksState' && event.found) { - if (event.dispatchError) { - console.error('Tx error', event) - setIsTxInitiated(false) - } - setWaitingForFinalization(true) - } - - if (event.type === 'finalized') { - onProcessFinished() - setIsTxInitiated(false) - setWaitingForFinalization(false) - } - }) + .subscribe(subscriptionCallBack2) } if (promptForHelpCallData) diff --git a/src/pages/Delegate/index.tsx b/src/pages/Delegate/index.tsx index 33c4330..f0263ac 100644 --- a/src/pages/Delegate/index.tsx +++ b/src/pages/Delegate/index.tsx @@ -8,8 +8,6 @@ import { Button } from '@/components/ui/button' import { useAccounts } from '@/contexts/AccountsContext' import { Slider } from '@/components/ui/slider' import { Link, useLocation, useNavigate, useParams } from 'react-router-dom' -import { toast } from 'sonner' - import { ArrowLeft } from 'lucide-react' import { msgs } from '@/lib/constants' import { evalUnits, planckToUnit } from '@polkadot-ui/utils' @@ -18,6 +16,7 @@ import { DelegateTxs, useGetDelegateTx } from '@/hooks/useGetDelegateTx' import { AlertNote } from '@/components/Alert' import { useTestTx } from '@/hooks/useTestTx' import { MultiTransactionDialog } from './MultiTransactionDialog' +import { useGetSigningCallback } from '@/hooks/useGetSigningCallback' export const Delegate = () => { const { api, assetInfo } = useNetwork() @@ -45,6 +44,7 @@ export const Delegate = () => { const [isMultiTxDialogOpen, setIsMultiTxDialogOpen] = useState(false) const [delegateTxs, setDelegateTxs] = useState({} as DelegateTxs) const { refreshLocks } = useLocks() + const getSubscriptionCallBack = useGetSigningCallback() const { display: convictionTimeDisplay, multiplier: convictionMultiplier } = getConvictionLockTimeDisplay(convictionNo) @@ -165,35 +165,14 @@ export const Delegate = () => { return } + const subscriptionCallBack = getSubscriptionCallBack({ + onError: () => setIsTxInitiated(false), + onFinalized: () => onProcessFinished(), + }) + await allTxs .signSubmitAndWatch(selectedAccount?.polkadotSigner) - .subscribe((event) => { - let msg: string - switch (event.type) { - case 'signed': - msg = 'Tx signed.' - break - case 'broadcasted': - msg = `Tx broadcasted.` - break - case 'txBestBlocksState': - msg = `Tx in block.` - break - case 'finalized': - msg = `Tx finalized in block: ${event.block.number}` - onProcessFinished() - break - } - toast.info(msg) - - if (event.type === 'txBestBlocksState' && event.found) { - if (event.dispatchError) { - console.error('Tx error', event) - toast.error(`Tx error: ${JSON.stringify(event)}`) - setIsTxInitiated(false) - } - } - }) + .subscribe(subscriptionCallBack) } return (