diff --git a/src/app/components/TransactionDialog/TxRequestDialog.tsx b/src/app/components/TransactionDialog/TxRequestDialog.tsx
index 238507a37a..876947f0d3 100644
--- a/src/app/components/TransactionDialog/TxRequestDialog.tsx
+++ b/src/app/components/TransactionDialog/TxRequestDialog.tsx
@@ -16,6 +16,7 @@ import {
TxType,
} from 'store/global/transactions-store/types';
import { Dialog } from 'app/containers/Dialog';
+import { useGetNormalizedError } from './hooks/useGetNormalizedError';
export const TxRequestDialog: React.FC = ({
open,
@@ -28,6 +29,9 @@ export const TxRequestDialog: React.FC = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
const wallet = useMemo(() => detectWeb3Wallet(), [address]);
+
+ const { hasUserDeclinedTx, normalizedError } = useGetNormalizedError();
+
return (
<>
+
+ {!hasUserDeclinedTx && (
+
+ )}
+ {normalizedError && (
+
{normalizedError}
+ )}
+
dispatch(actions.closeTransactionRequestDialog())
diff --git a/src/app/components/TransactionDialog/hooks/useGetNormalizedError.ts b/src/app/components/TransactionDialog/hooks/useGetNormalizedError.ts
new file mode 100644
index 0000000000..3b032c0d3f
--- /dev/null
+++ b/src/app/components/TransactionDialog/hooks/useGetNormalizedError.ts
@@ -0,0 +1,44 @@
+import { translations } from 'locales/i18n';
+import { useMemo } from 'react';
+import { useTranslation } from 'react-i18next';
+import { useSelector } from 'react-redux';
+import { selectRequestDialogState } from 'store/global/transactions-store/selectors';
+
+export const useGetNormalizedError = () => {
+ const { t } = useTranslation();
+ const { error } = useSelector(selectRequestDialogState);
+
+ const hasUserDeclinedTx = useMemo(
+ () =>
+ error?.includes('User denied transaction signature') ||
+ error?.includes('UserDeclinedError'),
+ [error],
+ );
+
+ const normalizedError = useMemo(() => {
+ if (hasUserDeclinedTx) {
+ return t(translations.walletProvider.userDenied);
+ }
+ if (error?.includes('LIQUALITY_ERROR_FROM_ERROR_PARSER_PACKAGE')) {
+ const searchReason = error.match(
+ /(?<=\\"reason\\":\\")([A-Za-z0-9 ]+)(?=\\")/g,
+ );
+ if (searchReason?.length) {
+ return searchReason[0];
+ }
+
+ const searchErrorName = error.match(
+ /(?<=\\"name\\":\\")([A-Za-z0-9 ]+)(?=\\")/g,
+ );
+ if (searchErrorName?.length) {
+ return searchErrorName[0];
+ }
+ }
+ return error;
+ }, [hasUserDeclinedTx, error, t]);
+
+ return {
+ hasUserDeclinedTx,
+ normalizedError,
+ };
+};
diff --git a/src/app/components/TransactionDialog/index.tsx b/src/app/components/TransactionDialog/index.tsx
index e45bb76846..ffbca62503 100644
--- a/src/app/components/TransactionDialog/index.tsx
+++ b/src/app/components/TransactionDialog/index.tsx
@@ -14,6 +14,7 @@ import { getStatusImage } from './utils';
import { WalletLogo } from './WalletLogo';
import { getWalletName } from './utils';
import { WalletContext } from '@sovryn/react-wallet';
+import { useGetNormalizedError } from './hooks/useGetNormalizedError';
interface ITransactionDialogProps {
tx: ResetTxResponseInterface;
@@ -38,6 +39,9 @@ export const TransactionDialog: React.FC = ({
}) => {
const { t } = useTranslation();
const { address } = useContext(WalletContext);
+
+ const { hasUserDeclinedTx, normalizedError } = useGetNormalizedError();
+
const onCloseHandler = useCallback(() => {
onClose?.();
if (tx.status === TxStatus.CONFIRMED) {
@@ -86,9 +90,20 @@ export const TransactionDialog: React.FC = ({
alt="failed"
className="tw-w-8 tw-mx-auto tw-mb-4 tw-opacity-75"
/>
-
-
-
+ {!hasUserDeclinedTx && (
+
+
+
+ )}
+
+ {normalizedError && (
+
+ {normalizedError}
+
+ )}
+
{wallet === 'ledger' && (
{t(translations.transactionDialog.txStatus.abortedLedger)}
diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index 7d38c026b7..48ba641905 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -1187,7 +1187,8 @@
"description": "Confirm transaction in your wallet to approve token spending in this smart-contract.",
"error": "Approve request failed:"
}
- }
+ },
+ "userDenied": "Transaction rejected"
},
"sendTxProgress": {
"pending_for_user": {