Skip to content

Commit

Permalink
feat: add error messages for process
Browse files Browse the repository at this point in the history
  • Loading branch information
chybisov committed May 17, 2022
1 parent 93c2052 commit 20542bc
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 38 deletions.
2 changes: 1 addition & 1 deletion packages/widget/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"@emotion/styled": "^11.8.1",
"@ethersproject/experimental": "^5.6.1",
"@ethersproject/providers": "^5.6.6",
"@lifinance/sdk": "^1.0.0-beta.5",
"@lifinance/sdk": "^1.0.0-beta.6",
"@lifinance/wallet-management": "0.1.0",
"@mui/icons-material": "^5.8.0",
"@mui/lab": "^5.0.0-alpha.82",
Expand Down
2 changes: 1 addition & 1 deletion packages/widget/src/components/SwapRoutes/SwapRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const SwapRoutes: React.FC<BoxProps> = ({ mb }) => {
key={index}
variant="rectangular"
width="75%"
height={195}
height={193}
sx={{ borderRadius: 1, minWidth: '75%' }}
/>
))
Expand Down
46 changes: 44 additions & 2 deletions packages/widget/src/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,53 @@
},
"swapping": {
"swap": "Swap",
"estimatedTime": "~{{value}} min." ,
"estimatedTime": "~{{value}} min.",
"done": "Done",
"networkIsBusy": "Network is busy...",
"crossChainDetails": "{{from}} to {{to}} via {{via}}",
"transactionDetails": "Transaction Details"
"transactionDetails": "Transaction Details",
"process": {
"tokenAllowance": {
"started": "Setting token allowance.",
"pending": "Waiting for token allowance approval.",
"done": "Token allowance approved."
},
"switchChain": {
"pending": "Chain switch required.",
"done": "Chain switched successfully."
},
"swap": {
"started": "Preparing swap.",
"actionRequired": "Please sign the transaction.",
"pending": "Swapping.",
"done": "Swap completed."
},
"crossChain": {
"started": "Preparing transaction.",
"actionRequired": "Please sign the transaction.",
"pending": "Waiting for transaction.",
"done": "Transaction approved."
},
"receivingChain": {
"pending": "Waiting for receiving chain.",
"done": "Funds received."
}
},
"error": {
"title": {
"chainSwitch": "Chain switch required.",
"transactionFailed": "Transaction has failed.",
"transactionUnderpriced": "Transaction is underpriced.",
"transactionUnprepared": "Unable to prepare transaction.",
"unknown": "Something went wrong.",
"userRejectedSignatureRequest": "Signature required."
},
"message": {
"signatureRequired": "Your signature is required to complete the transaction. {{amount}} {{tokenSymbol}} on {{chainName}} remain in your wallet.",
"transactionFailed": "Please check the block explorer for more information.",
"transactionNotSent": "Transaction was not sent, your funds are still in your wallet ({{amount}} {{tokenSymbol}} on {{chainName}})."
}
}
},
"settings": {
"routePriority": {
Expand Down
29 changes: 22 additions & 7 deletions packages/widget/src/pages/SwappingPage/ExecutionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
import { Process } from '@lifinance/sdk';
import { Process, Step } from '@lifinance/sdk';
import { useChains } from '@lifinance/widget/hooks';
import { Box, Link, Typography } from '@mui/material';
import { useTranslation } from 'react-i18next';
import { CircularProgress } from './CircularProgress';
import { getProcessMessage } from './utils';

export const ExecutionItem: React.FC<{
step: Step;
process: Process;
}> = ({ process }) => {
}> = ({ step, process }) => {
const { t } = useTranslation();

const { getChainById } = useChains();
const { title, message } = getProcessMessage(t, getChainById, step, process);
return (
<Box px={2} py={1}>
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Box
sx={{
display: 'flex',
alignItems: process.error ? 'flex-start' : 'center',
}}
>
<CircularProgress status={process.status} />
<Typography ml={2}>
{getProcessMessage(process.type, process.status)}
</Typography>
<Box ml={2}>
<Typography fontWeight={process.error ? 700 : 500}>
{title}
</Typography>
{message ? (
<Typography fontSize={14} fontWeight={500} color="text.secondary">
{message}
</Typography>
) : null}
</Box>
</Box>
{process.txLink ? (
<Box ml={6}>
Expand Down
2 changes: 1 addition & 1 deletion packages/widget/src/pages/SwappingPage/StepItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const StepItem: React.FC<{
) : null}
<ToolItem step={step} />
{step.execution?.process.map((process, index) => (
<ExecutionItem key={index} process={process} />
<ExecutionItem key={index} step={step} process={process} />
))}
{toToken ? (
<Box px={2} py={1} sx={{ display: 'flex', alignItems: 'center' }}>
Expand Down
111 changes: 89 additions & 22 deletions packages/widget/src/pages/SwappingPage/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import { ProcessType, Status } from '@lifinance/sdk';
import {
EVMChain,
LifiErrorCode,
MetaMaskProviderErrorCode,
Process,
ProcessType,
Status,
Step,
} from '@lifinance/sdk';
import { TFunction } from 'react-i18next';
import { formatTokenAmount } from '../../utils/format';

const formatProcessMessage = (
initialMessage: string,
Expand All @@ -9,39 +19,96 @@ const formatProcessMessage = (
}, initialMessage);
};

const processMessages: Record<ProcessType, Partial<Record<Status, string>>> = {
const processMessages: Record<
ProcessType,
Partial<Record<Status, (t: TFunction<'translation', undefined>) => string>>
> = {
TOKEN_ALLOWANCE: {
STARTED: 'Setting token allowance.',
PENDING: 'Waiting for token allowance approval.',
DONE: 'Token allowance approved.',
STARTED: (t) => t(`swapping.process.tokenAllowance.started`),
PENDING: (t) => t(`swapping.process.tokenAllowance.pending`),
DONE: (t) => t(`swapping.process.tokenAllowance.done`),
},
SWITCH_CHAIN: {
PENDING: 'Chain switch required.',
DONE: 'Chain switched successfully.',
PENDING: (t) => t(`swapping.process.switchChain.pending`),
DONE: (t) => t(`swapping.process.switchChain.done`),
},
SWAP: {
STARTED: 'Preparing swap.',
ACTION_REQUIRED: 'Please sign the transaction.',
PENDING: 'Swapping.',
DONE: 'Swap completed.',
STARTED: (t) => t(`swapping.process.swap.started`),
ACTION_REQUIRED: (t) => t(`swapping.process.swap.actionRequired`),
PENDING: (t) => t(`swapping.process.swap.pending`),
DONE: (t) => t(`swapping.process.swap.done`),
},
CROSS_CHAIN: {
STARTED: 'Preparing transaction.',
ACTION_REQUIRED: 'Please sign the transaction.',
PENDING: 'Waiting for transaction.',
DONE: 'Transaction approved.',
STARTED: (t) => t(`swapping.process.crossChain.started`),
ACTION_REQUIRED: (t) => t(`swapping.process.crossChain.actionRequired`),
PENDING: (t) => t(`swapping.process.crossChain.pending`),
DONE: (t) => t(`swapping.process.crossChain.done`),
},
RECEIVING_CHAIN: {
PENDING: 'Waiting for receiving chain.',
DONE: 'Funds received.',
PENDING: (t) => t(`swapping.process.receivingChain.pending`),
DONE: (t) => t(`swapping.process.receivingChain.done`),
},
TRANSACTION: {},
};

export function getProcessMessage(
type: ProcessType,
status: Status,
): string | undefined {
const processMessage = processMessages[type][status];
return processMessage;
t: TFunction<'translation', undefined>,
getChainById: (chainId: number) => EVMChain | undefined,
step: Step,
process: Process,
): {
title?: string;
message?: string;
} {
if (process.error) {
const getTransactionNotSentMessage = () =>
t(`swapping.error.message.transactionNotSent`, {
amount: formatTokenAmount(
step.action.fromAmount,
step.action.fromToken.decimals,
),
tokenSymbol: step.action.fromToken.symbol,
chainName: getChainById(step.action.fromChainId)?.name ?? '',
});
let title: string = '';
let message: string = '';
switch (process.error.code) {
case LifiErrorCode.ChainSwitchError:
title = t(`swapping.error.title.chainSwitch`);
message = getTransactionNotSentMessage();
break;
case LifiErrorCode.TransactionFailed:
title = t(`swapping.error.title.transactionFailed`);
message = t(`swapping.error.message.transactionFailed`);
break;
case LifiErrorCode.TransactionUnderpriced:
title = t(`swapping.error.title.transactionUnderpriced`);
message = getTransactionNotSentMessage();
break;
case LifiErrorCode.TransactionUnprepared:
title = t(`swapping.error.title.transactionUnprepared`);
message = getTransactionNotSentMessage();
break;
case MetaMaskProviderErrorCode.userRejectedRequest:
title = t(`swapping.error.title.userRejectedSignatureRequest`);
message = t(`swapping.error.message.signatureRequired`, {
amount: formatTokenAmount(
step.action.fromAmount,
step.action.fromToken.decimals,
),
tokenSymbol: step.action.fromToken.symbol,
chainName: getChainById(step.action.fromChainId)?.name ?? '',
});
break;
default:
title = t(`swapping.error.title.unknown`);
if (process.txLink) {
message = t(`swapping.error.message.transactionFailed`);
}
break;
}
return { title, message };
}
const title = processMessages[process.type][process.status]?.(t);
return { title };
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2798,10 +2798,10 @@
npmlog "^4.1.2"
write-file-atomic "^3.0.3"

"@lifinance/sdk@^1.0.0-beta.5":
version "1.0.0-beta.5"
resolved "https://registry.yarnpkg.com/@lifinance/sdk/-/sdk-1.0.0-beta.5.tgz#6e760cafc01c998fb4ac2b8ab44a96c8b2c33018"
integrity sha512-31nmci/yfMcCYJ97F0K3Di1MM7v54WU4yV85DnqmMI8qTsjA9MtrKq8XpQyeJTt94QrUaUBaHUZWkibvQlFeKA==
"@lifinance/sdk@^1.0.0-beta.6":
version "1.0.0-beta.6"
resolved "https://registry.yarnpkg.com/@lifinance/sdk/-/sdk-1.0.0-beta.6.tgz#4966c7ee257e2a169421baa96152db93d74ae727"
integrity sha512-gp1Gnas1Ri9ul+bomz30yl6UhjL/3XXLs7IQ0+KlaZNmzZ3RHvKRoqJNTf5qE/kdyKBPs/S/QCPczNXTwr0nmA==
dependencies:
"@ethersproject/abi" "^5.6.2"
"@ethersproject/contracts" "^5.6.1"
Expand Down

0 comments on commit 20542bc

Please sign in to comment.