Skip to content

Commit 5ae16fb

Browse files
authored
fix: ccip fee amounts and limit handling[skip cypress] (#2240)
1 parent 6b5f861 commit 5ae16fb

File tree

8 files changed

+328
-273
lines changed

8 files changed

+328
-273
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { Trans } from '@lingui/macro';
2+
import { Typography, useTheme } from '@mui/material';
3+
import { formatEther } from 'ethers/lib/utils';
4+
import { FormattedNumber } from 'src/components/primitives/FormattedNumber';
5+
import { TextWithTooltip } from 'src/components/TextWithTooltip';
6+
import { GHO_SYMBOL } from 'src/utils/ghoUtilities';
7+
8+
import { DetailsNumberLine } from '../FlowCommons/TxModalDetails';
9+
10+
export const BridgeAmount = ({
11+
amount,
12+
maxAmountToBridgeFormatted,
13+
maxAmountReducedDueToBridgeLimit,
14+
maxAmountReducedDueToRateLimit,
15+
refillRate,
16+
maxRateLimitCapacity,
17+
}: {
18+
amount: string;
19+
maxAmountToBridgeFormatted: string;
20+
maxAmountReducedDueToBridgeLimit: boolean;
21+
maxAmountReducedDueToRateLimit: boolean;
22+
refillRate: string;
23+
maxRateLimitCapacity: string;
24+
}) => {
25+
const { palette } = useTheme();
26+
27+
const bridgeLimitTooltip = (
28+
<Typography variant="caption">
29+
Due to bridging limits, the maximum amount currently available to bridge is{' '}
30+
<FormattedNumber variant="caption" value={maxAmountToBridgeFormatted} visibleDecimals={2} />
31+
</Typography>
32+
);
33+
34+
const rateLimitTooltip = (
35+
<Typography variant="caption">
36+
The amount you can bridge is currently reduced because of the rate limit. The limit is raised
37+
at a rate of{' '}
38+
<FormattedNumber variant="caption" value={formatEther(refillRate)} visibleDecimals={2} /> GHO
39+
per second, until the maximum amount of{' '}
40+
<FormattedNumber
41+
variant="caption"
42+
value={formatEther(maxRateLimitCapacity)}
43+
visibleDecimals={2}
44+
/>{' '}
45+
is reached.
46+
</Typography>
47+
);
48+
49+
return (
50+
<DetailsNumberLine
51+
description={
52+
amount !== '' && (maxAmountReducedDueToBridgeLimit || maxAmountReducedDueToRateLimit) ? (
53+
<TextWithTooltip
54+
text={
55+
<Typography color={palette.warning.main}>
56+
<Trans>Amount</Trans>
57+
</Typography>
58+
}
59+
iconColor="warning.main"
60+
>
61+
<>
62+
{maxAmountReducedDueToBridgeLimit && bridgeLimitTooltip}
63+
{maxAmountReducedDueToRateLimit && rateLimitTooltip}
64+
</>
65+
</TextWithTooltip>
66+
) : (
67+
<Trans>Amount</Trans>
68+
)
69+
}
70+
iconSymbol={GHO_SYMBOL}
71+
symbol={GHO_SYMBOL}
72+
value={amount}
73+
/>
74+
);
75+
};
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import { Trans } from '@lingui/macro';
2+
import {
3+
Box,
4+
FormControl,
5+
MenuItem,
6+
Select,
7+
SelectChangeEvent,
8+
Skeleton,
9+
Stack,
10+
useTheme,
11+
} from '@mui/material';
12+
import { FormattedNumber } from 'src/components/primitives/FormattedNumber';
13+
import { Link } from 'src/components/primitives/Link';
14+
import { NoData } from 'src/components/primitives/NoData';
15+
import { Row } from 'src/components/primitives/Row';
16+
import { TokenIcon } from 'src/components/primitives/TokenIcon';
17+
import { TextWithTooltip } from 'src/components/TextWithTooltip';
18+
19+
interface FeeToken {
20+
address: string;
21+
symbol: string;
22+
}
23+
24+
export const BridgeFeeTokenSelector = ({
25+
feeTokens,
26+
selectedFeeToken,
27+
onFeeTokenChanged,
28+
bridgeFeeFormatted,
29+
bridgeFeeUSD,
30+
loading,
31+
}: {
32+
feeTokens: FeeToken[];
33+
selectedFeeToken: FeeToken;
34+
onFeeTokenChanged: (event: SelectChangeEvent) => void;
35+
bridgeFeeFormatted: string;
36+
bridgeFeeUSD: string;
37+
loading: boolean;
38+
}) => {
39+
const theme = useTheme();
40+
41+
const feeTooltip = (
42+
<TextWithTooltip text={<Trans>Fee</Trans>}>
43+
<Trans>
44+
The fee includes the gas cost to complete the transaction on the destination chain and the
45+
fee paid to Chainlink CCIP service providers. You can chose to pay in the network token or
46+
GHO.{' '}
47+
<Link
48+
href="https://docs.chain.link/ccip/billing"
49+
sx={{ textDecoration: 'underline' }}
50+
variant="caption"
51+
color="text.secondary"
52+
>
53+
Learn more
54+
</Link>
55+
</Trans>
56+
</TextWithTooltip>
57+
);
58+
59+
return (
60+
<Row caption={feeTooltip} captionVariant="description" mb={4}>
61+
<FormControl sx={{ mr: 'auto' }}>
62+
<Select
63+
labelId="token-select-label"
64+
value={selectedFeeToken.symbol}
65+
onChange={onFeeTokenChanged}
66+
sx={{
67+
fontSize: '1.0em',
68+
width: 'auto',
69+
height: '24px',
70+
minWidth: '70px',
71+
borderRadius: '4px',
72+
mb: 0.5,
73+
maxWidth: '80px',
74+
'.MuiSelect-select': {
75+
backgroundColor: theme.palette.mode === 'dark' ? '#292E41' : '#FFFFFF',
76+
77+
paddingLeft: '2px',
78+
},
79+
'& .MuiOutlinedInput-notchedOutline': {
80+
border: 'none',
81+
},
82+
'&:hover .MuiOutlinedInput-notchedOutline': {
83+
border: 'none',
84+
},
85+
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
86+
border: 'none',
87+
},
88+
}}
89+
MenuProps={{
90+
PaperProps: {
91+
sx: {
92+
backgroundColor: theme.palette.mode === 'dark' ? '#292E41' : '#FFFFFF',
93+
fontSize: '1.0em',
94+
},
95+
},
96+
}}
97+
>
98+
{feeTokens.map((token) => (
99+
<MenuItem
100+
key={token.symbol}
101+
value={token.symbol}
102+
sx={{
103+
backgroundColor: theme.palette.mode === 'dark' ? '#383D51' : '#FFFFFF',
104+
'&:hover': {
105+
backgroundColor: theme.palette.mode === 'dark' ? '#292E41' : '#EAEBEF',
106+
},
107+
'&.Mui-selected, &.Mui-selected:hover': {
108+
backgroundColor: theme.palette.mode === 'dark' ? '#292E41' : '#FFFFFF',
109+
boxShadow: '0px 1px 0px rgba(0, 0, 0, 0.05)',
110+
},
111+
}}
112+
>
113+
<Box display="flex" alignItems={'center'}>
114+
<TokenIcon sx={{ fontSize: '1em', paddingRight: '4px' }} symbol={token.symbol} />
115+
{token.symbol}
116+
</Box>
117+
</MenuItem>
118+
))}
119+
</Select>
120+
</FormControl>
121+
{!bridgeFeeFormatted && !loading ? (
122+
<NoData variant="secondary14" color="text.secondary" />
123+
) : loading ? (
124+
<Skeleton variant="rectangular" height={20} width={100} sx={{ borderRadius: '4px' }} />
125+
) : (
126+
<Stack direction="column" alignItems="flex-end" position="relative">
127+
<Stack direction="row" alignItems="center">
128+
<TokenIcon symbol={selectedFeeToken?.symbol} sx={{ mr: 1, fontSize: '16px' }} />
129+
<FormattedNumber
130+
value={bridgeFeeFormatted}
131+
symbol={selectedFeeToken?.symbol}
132+
variant="secondary14"
133+
/>
134+
</Stack>
135+
<FormattedNumber
136+
value={bridgeFeeUSD}
137+
variant="helperText"
138+
compact
139+
symbol="USD"
140+
color="text.secondary"
141+
sx={{ position: 'absolute', top: '20px' }}
142+
/>
143+
</Stack>
144+
)}
145+
</Row>
146+
);
147+
};

0 commit comments

Comments
 (0)