fix(trading,web3): prevent deposit toasts reappearing (#4797)

Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
This commit is contained in:
Matthew Russell 2023-09-15 05:51:28 -07:00 committed by GitHub
parent 6d35f2b39d
commit ba39720f05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 14 deletions

View File

@ -15,6 +15,7 @@ const requestedTransactionUpdate = {
status: EthTxStatus.Requested,
error: null,
confirmations: 0,
notify: true,
};
const mockDepositAsset = jest.fn();
@ -57,6 +58,7 @@ const createTransaction = (
dialogOpen: false,
txHash: null,
receipt: null,
notify: true,
...transaction,
});
@ -158,6 +160,7 @@ describe('useVegaTransactionManager', () => {
expect(update.mock.calls[1][1]).toEqual({
status: EthTxStatus.Pending,
txHash,
notify: true,
});
});
@ -197,6 +200,7 @@ describe('useVegaTransactionManager', () => {
expect(update.mock.calls[3][1]).toEqual({
status: EthTxStatus.Confirmed,
receipt,
notify: true,
});
});

View File

@ -25,6 +25,7 @@ export const useEthTransactionManager = () => {
status: EthTxStatus.Requested,
error: null,
confirmations: 0,
notify: true,
});
const {
contract,
@ -48,6 +49,7 @@ export const useEthTransactionManager = () => {
update(transaction.id, {
status: EthTxStatus.Error,
error: err as EthereumError,
notify: true,
});
return;
}
@ -61,6 +63,7 @@ export const useEthTransactionManager = () => {
update(transaction.id, {
status: EthTxStatus.Pending,
txHash: tx.hash,
notify: true,
});
for (let i = 1; i <= requiredConfirmations; i++) {
@ -77,19 +80,31 @@ export const useEthTransactionManager = () => {
}
if (requiresConfirmation) {
update(transaction.id, { status: EthTxStatus.Complete, receipt });
update(transaction.id, {
status: EthTxStatus.Complete,
receipt,
});
} else {
update(transaction.id, { status: EthTxStatus.Confirmed, receipt });
update(transaction.id, {
status: EthTxStatus.Confirmed,
receipt,
notify: true,
});
}
} catch (err) {
if (err instanceof Error || isEthereumError(err)) {
if (!isExpectedEthereumError(err)) {
update(transaction.id, { status: EthTxStatus.Error, error: err });
update(transaction.id, {
status: EthTxStatus.Error,
error: err,
notify: true,
});
}
} else {
update(transaction.id, {
status: EthTxStatus.Error,
error: new Error('Something went wrong'),
notify: true,
});
}
return;

View File

@ -27,7 +27,13 @@ export interface EthStoredTxState extends EthTxState {
methodName: ContractMethod;
args: string[];
requiredConfirmations: number;
requiresConfirmation: boolean; // whether or not the tx needs external confirmation (IE from a subscription even)
// whether or not the tx needs external confirmation (IE from a subscription even)
requiresConfirmation: boolean;
// whether or not to notify via toast
// true = force open toast
// false = force close toast
// undefined = leave alone
notify: boolean | undefined;
assetId?: string;
deposit?: DepositBusEventFieldsFragment;
withdrawal?: WithdrawalBusEventFieldsFragment;
@ -49,7 +55,7 @@ export interface EthTransactionStore {
update?: Partial<
Pick<
EthStoredTxState,
'status' | 'error' | 'receipt' | 'confirmations' | 'txHash'
'status' | 'error' | 'receipt' | 'confirmations' | 'txHash' | 'notify'
>
>
) => void;
@ -89,6 +95,7 @@ export const useEthTransactionStore = create<EthTransactionStore>()(
requiresConfirmation,
assetId,
withdrawal,
notify: true,
};
set({ transactions: transactions.concat(transaction) });
return transaction.id;
@ -135,6 +142,7 @@ export const useEthTransactionStore = create<EthTransactionStore>()(
transaction.deposit = deposit;
transaction.dialogOpen = true;
transaction.updatedAt = new Date();
transaction.notify = true;
})
);
},

View File

@ -1,4 +1,5 @@
import type { ReactNode } from 'react';
import { useEffect } from 'react';
import { useAssetsDataProvider } from '@vegaprotocol/assets';
import { EtherscanLink } from '@vegaprotocol/environment';
import { formatNumber, toBigNum } from '@vegaprotocol/utils';
@ -169,11 +170,13 @@ export const useEthereumTransactionToasts = () => {
]);
const dismissTx = useEthTransactionStore((state) => state.dismiss);
const updateTx = useEthTransactionStore((state) => state.update);
const onClose = useCallback(
(tx: EthStoredTxState) => () => {
dismissTx(tx.id);
removeToast(`eth-${tx.id}`);
updateTx(tx.id, { notify: false });
// closes related "Funds released" toast after successful withdrawal
if (
isWithdrawTransaction(tx) &&
@ -183,7 +186,7 @@ export const useEthereumTransactionToasts = () => {
closeToastBy({ withdrawalId: tx.withdrawal.id });
}
},
[closeToastBy, dismissTx, removeToast]
[closeToastBy, dismissTx, removeToast, updateTx]
);
const fromEthTransaction = useCallback(
@ -213,17 +216,25 @@ export const useEthereumTransactionToasts = () => {
loader: [EthTxStatus.Pending, EthTxStatus.Complete].includes(tx.status),
content,
closeAfter,
hidden: !tx.notify,
};
},
[onClose]
);
useEthTransactionStore.subscribe(
(state) => compact(state.transactions.filter((tx) => tx?.dialogOpen)),
(txs) => {
txs.forEach((tx) => {
setToast(fromEthTransaction(tx));
});
}
);
// Only register a subscription once
useEffect(() => {
const unsubscribe = useEthTransactionStore.subscribe(
(state) => compact(state.transactions.filter((tx) => tx?.dialogOpen)),
(txs) => {
txs.forEach((tx) => {
setToast(fromEthTransaction(tx));
});
}
);
return () => {
unsubscribe();
};
}, [fromEthTransaction, setToast]);
};