Skip to content

Commit

Permalink
feat: display a warning if the output amount changes on the confirm s…
Browse files Browse the repository at this point in the history
…wap page
  • Loading branch information
Ikari-Shinji-re committed Nov 12, 2024
1 parent 1ec9b81 commit af6bada
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 285 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PropTypes } from './ConfirmWalletsModal.types';
import type { ConnectedWallet } from '../../store/wallets';
import type { ConfirmSwapWarnings, Wallet } from '../../types';
import type { Wallet } from '../../types';

import { i18n } from '@lingui/core';
import {
Expand All @@ -17,7 +17,6 @@ import { useNavigate } from 'react-router-dom';

import { WIDGET_UI_ID } from '../../constants';
import { getQuoteErrorMessage } from '../../constants/errors';
import { getQuoteUpdateWarningMessage } from '../../constants/warnings';
import { useAppStore } from '../../store/AppStore';
import { useQuoteStore } from '../../store/quote';
import { useWalletsStore } from '../../store/wallets';
Expand Down Expand Up @@ -60,9 +59,6 @@ export function ConfirmWalletsModal(props: PropTypes) {
const [showMoreWalletFor, setShowMoreWalletFor] = useState('');
const [balanceWarnings, setBalanceWarnings] = useState<string[]>([]);
const [error, setError] = useState('');
const [quoteWarning, setQuoteWarning] = useState<
ConfirmSwapWarnings['quoteUpdate'] | null
>(null);

const [isCustomDestinationOpen, setCustomDestinationOpen] = useState(
!!customDestination
Expand Down Expand Up @@ -226,7 +222,6 @@ export function ConfirmWalletsModal(props: PropTypes) {
const onConfirmWallets = async () => {
setBalanceWarnings([]);
setError('');
setQuoteWarning(null);

const result = await onCheckBalance?.({
selectedWallets: selectableWallets.filter((wallet) => wallet.selected),
Expand All @@ -236,9 +231,7 @@ export function ConfirmWalletsModal(props: PropTypes) {
if (warnings?.balance?.messages) {
setBalanceWarnings(warnings.balance.messages);
}
if (warnings?.quoteUpdate) {
setQuoteWarning(warnings.quoteUpdate);
}

if (result.error) {
setError(getQuoteErrorMessage(result.error));
}
Expand Down Expand Up @@ -418,16 +411,6 @@ export function ConfirmWalletsModal(props: PropTypes) {
<Divider size={12} />
</>
)}
{quoteWarning && (
<>
<Alert
variant="alarm"
type="warning"
title={getQuoteUpdateWarningMessage(quoteWarning)}
/>
<Divider size={12} />
</>
)}
<Wallets>
{quoteWallets.map((requiredWallet, index) => {
const blockchain = blockchains.find(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,50 @@ export function makeAlerts(
return alertInfo;
}
if (warning) {
if (warning.type === QuoteWarningType.HIGH_VALUE_LOSS) {
const warningLevel = getPriceImpactLevel(warning.priceImpact);
if (warningLevel === 'high') {
alertInfo.alertType = 'error';
switch (warning.type) {
case QuoteWarningType.HIGH_VALUE_LOSS: {
const warningLevel = getPriceImpactLevel(warning.priceImpact);
if (warningLevel === 'high') {
alertInfo.alertType = 'error';
}
alertInfo.action = 'show-info';
alertInfo.title = errorMessages().highValueLossError.title;
break;
}
alertInfo.action = 'show-info';
alertInfo.title = errorMessages().highValueLossError.title;
}
if (warning.type === QuoteWarningType.UNKNOWN_PRICE) {
alertInfo.title = errorMessages().unknownPriceError.title;
}
if (warning.type === QuoteWarningType.INSUFFICIENT_SLIPPAGE) {
alertInfo.title = i18n.t({
id: 'We recommend you to increase slippage to at least {minRequiredSlippage} for this route.',
values: {
minRequiredSlippage: warning.minRequiredSlippage,
},
});
alertInfo.action = 'change-settings';
}
if (warning.type === QuoteWarningType.HIGH_SLIPPAGE) {
alertInfo.title = i18n.t('Caution, your slippage is high.');
alertInfo.action = 'change-settings';
case QuoteWarningType.EXCESSIVE_OUTPUT_AMOUNT_CHANGE: {
alertInfo.title = i18n.t({
id: 'Output amount changed by {percentageChange}% (${usdValueChange}).',
values: {
percentageChange: warning.percentageChange,
usdValueChange: warning.usdValueChange,
},
});
break;
}
case QuoteWarningType.UNKNOWN_PRICE: {
alertInfo.title = errorMessages().unknownPriceError.title;
break;
}
case QuoteWarningType.INSUFFICIENT_SLIPPAGE: {
alertInfo.title = i18n.t({
id: 'We recommend you to increase slippage to at least {minRequiredSlippage} for this route.',
values: {
minRequiredSlippage: warning.minRequiredSlippage,
},
});
alertInfo.action = 'change-settings';
break;
}
case QuoteWarningType.HIGH_SLIPPAGE: {
alertInfo.title = i18n.t('Caution, your slippage is high.');
alertInfo.action = 'change-settings';
break;
}

default:
break;
}

return alertInfo;
}
return null;
Expand Down
5 changes: 2 additions & 3 deletions widget/embedded/src/components/Quotes/Quotes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ export function Quotes(props: PropTypes) {
...quote,
};

return generateQuoteWarnings(mergedQuote, {
fromToken,
toToken,
return generateQuoteWarnings({
currentQuote: mergedQuote,
userSlippage,
findToken,
});
Expand Down
26 changes: 0 additions & 26 deletions widget/embedded/src/constants/warnings.ts

This file was deleted.

12 changes: 3 additions & 9 deletions widget/embedded/src/containers/QuoteInfo/QuoteInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { Quote } from '../../components/Quote';
import { QuoteSkeleton } from '../../components/QuoteSkeleton';
import { useQuoteStore } from '../../store/quote';
import { QuoteErrorType } from '../../types';
import { getQuoteToTokenUsdPrice } from '../../utils/quote';
import { calcOutputUsdValue } from '../../utils/swap';
import { getUsdOutputFrom } from '../../utils/swap';

import { QuoteContainer } from './QuoteInfo.styles';

Expand All @@ -28,17 +27,12 @@ export function QuoteInfo(props: PropTypes) {
fullExpandedMode = false,
container,
} = props;
const { inputAmount, inputUsdValue, toToken } = useQuoteStore();
const { inputAmount, inputUsdValue } = useQuoteStore();

const outputAmount = !!quote?.outputAmount
? new BigNumber(quote?.outputAmount)
: null;
const outputUsdValue = !!quote?.outputAmount
? calcOutputUsdValue(
quote?.outputAmount,
getQuoteToTokenUsdPrice(quote) || toToken?.usdPrice
)
: null;
const outputUsdValue = quote ? getUsdOutputFrom(quote) : null;

const noResult =
error &&
Expand Down
95 changes: 29 additions & 66 deletions widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,18 @@ import type {
SelectedQuote,
Wallet,
} from '../../types';
import type { BlockchainMeta, SwapResult, Token } from 'rango-sdk';
import type BigNumber from 'bignumber.js';
import type { BlockchainMeta, SwapResult } from 'rango-sdk';

import { errorMessages } from '../../constants/errors';
import { QuoteErrorType, QuoteUpdateType } from '../../types';
import { numberToString } from '../../utils/numbers';
import {
generateQuoteWarnings,
getPriceImpact,
isNumberOfSwapsChanged,
isQuoteChanged,
isQuoteInternalCoinsUpdated,
isQuoteSwappersUpdated,
} from '../../utils/quote';
import { QuoteErrorType } from '../../types';
import { generateQuoteWarnings } from '../../utils/quote';
import {
checkSlippageErrors,
generateBalanceWarnings,
getLimitErrorMessage,
getMinRequiredSlippage,
getQuoteOutputAmount,
hasLimitError,
isOutputAmountChangedALot,
} from '../../utils/swap';

/**
Expand Down Expand Up @@ -82,72 +73,44 @@ export function getQuoteError(swaps: SwapResult[]): QuoteErrorResponse | null {
return null;
}

export function generateWarnings(
previousQuote: SelectedQuote | undefined,
currentQuote: SelectedQuote,
params: {
fromToken: Token;
toToken: Token;
meta: { blockchains: BlockchainMeta[] };
selectedWallets: Wallet[];
userSlippage: number;
findToken: FindToken;
}
): ConfirmSwapWarnings {
let quoteChanged = false;
if (previousQuote) {
quoteChanged = isQuoteChanged(previousQuote, currentQuote);
}
export function generateWarnings(params: {
currentQuote: SelectedQuote;
previousQuote?: SelectedQuote;
meta: { blockchains: BlockchainMeta[] };
selectedWallets: Wallet[];
userSlippage: number;
inputUsdValue: BigNumber | null;
findToken: FindToken;
}): ConfirmSwapWarnings {
const {
currentQuote,
previousQuote,
meta,
selectedWallets,
userSlippage,
findToken,
} = params;

const output: ConfirmSwapWarnings = {
quote: null,
quoteUpdate: null,
balance: null,
};

const quoteWarning = generateQuoteWarnings(currentQuote, {
fromToken: params.fromToken,
toToken: params.toToken,
findToken: params.findToken,
userSlippage: params.userSlippage,
const quoteWarning = generateQuoteWarnings({
previousQuote,
currentQuote,
findToken,
userSlippage,
});

if (quoteWarning) {
output.quote = quoteWarning;
}

if (previousQuote && quoteChanged) {
if (isOutputAmountChangedALot(previousQuote, currentQuote)) {
output.quoteUpdate = {
type: QuoteUpdateType.QUOTE_AND_OUTPUT_AMOUNT_UPDATED,
newOutputAmount: numberToString(getQuoteOutputAmount(currentQuote)),
percentageChange: numberToString(
getPriceImpact(
getQuoteOutputAmount(previousQuote) ?? '',
getQuoteOutputAmount(currentQuote) ?? ''
),
null,
2
),
};
} else if (isNumberOfSwapsChanged(previousQuote, currentQuote)) {
output.quoteUpdate = {
type: QuoteUpdateType.QUOTE_UPDATED,
};
} else if (isQuoteSwappersUpdated(previousQuote, currentQuote)) {
output.quoteUpdate = {
type: QuoteUpdateType.QUOTE_SWAPPERS_UPDATED,
};
} else if (isQuoteInternalCoinsUpdated(previousQuote, currentQuote)) {
output.quoteUpdate = {
type: QuoteUpdateType.QUOTE_COINS_UPDATED,
};
}
}

const balanceWarnings = generateBalanceWarnings(
currentQuote,
params.selectedWallets,
params.meta.blockchains
selectedWallets,
meta.blockchains
);

const enoughBalance = balanceWarnings.length === 0;
Expand Down
25 changes: 10 additions & 15 deletions widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export function useConfirmSwap(): ConfirmSwap {
fromToken,
toToken,
inputAmount,
inputUsdValue,
setSelectedQuote,
selectedQuote: initialQuote,
customDestination: customDestinationFromStore,
setQuoteWarningsConfirmed,
resetAlerts,
} = useQuoteStore();

Expand Down Expand Up @@ -95,21 +95,16 @@ export function useConfirmSwap(): ConfirmSwap {
disabledSwappersGroups: disabledLiquiditySources,
};

const confirmSwapWarnings = generateWarnings(
initialQuote ?? undefined,
const confirmSwapWarnings = generateWarnings({
previousQuote: initialQuote ?? undefined,
currentQuote,
{
fromToken,
toToken,
meta: { blockchains },
findToken,
selectedWallets,
userSlippage,
}
);
if (confirmSwapWarnings.quoteUpdate) {
setQuoteWarningsConfirmed(false);
}
meta: { blockchains },
selectedWallets,
userSlippage,
inputUsdValue,
findToken,
});

resetAlerts();

const proceedAnyway = !!confirmSwapWarnings.balance;
Expand Down
Loading

0 comments on commit af6bada

Please sign in to comment.