@rango-dev/ui 0.1.10-next.78 → 0.1.10-next.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/components/Alert/Alert.d.ts +2 -2
  2. package/dist/components/Alert/Alert.stories.d.ts +2 -1
  3. package/dist/components/BestRoute/BestRoute.d.ts +4 -1
  4. package/dist/components/SecondaryPage/SecondaryPage.d.ts +3 -5
  5. package/dist/components/SelectableWalletList/SelectableWalletList.d.ts +1 -1
  6. package/dist/components/TextField/TextField.stories.d.ts +1 -1
  7. package/dist/containers/ConfirmSwap/ConfirmSwap.d.ts +8 -4
  8. package/dist/containers/ConfirmWallets/ConfirmWallets.d.ts +4 -2
  9. package/dist/containers/History/types.d.ts +1 -0
  10. package/dist/helper/index.d.ts +0 -5
  11. package/dist/types/wallet.d.ts +8 -0
  12. package/dist/ui.cjs.development.js +288 -262
  13. package/dist/ui.cjs.development.js.map +1 -1
  14. package/dist/ui.cjs.production.min.js +1 -1
  15. package/dist/ui.cjs.production.min.js.map +1 -1
  16. package/dist/ui.esm.js +288 -262
  17. package/dist/ui.esm.js.map +1 -1
  18. package/package.json +1 -1
  19. package/src/components/Alert/Alert.tsx +5 -9
  20. package/src/components/BestRoute/BestRoute.tsx +55 -21
  21. package/src/components/BlockchainSelector/BlockchainSelector.tsx +13 -11
  22. package/src/components/LiquiditySourceList/LiquiditySourceList.tsx +21 -20
  23. package/src/components/LiquiditySourcesSelector/LiquiditySourcesSelector.tsx +3 -2
  24. package/src/components/Radio/Radio.tsx +1 -0
  25. package/src/components/SecondaryPage/SecondaryPage.tsx +5 -6
  26. package/src/components/SelectableWalletList/SelectableWalletList.tsx +1 -1
  27. package/src/components/Settings/Settings.tsx +12 -13
  28. package/src/components/SwapContainer/SwapContainer.tsx +1 -0
  29. package/src/components/Switch/Switch.tsx +1 -0
  30. package/src/components/TokenSelector/TokenSelector.tsx +3 -2
  31. package/src/containers/ConfirmSwap/ConfirmSwap.tsx +92 -54
  32. package/src/containers/ConfirmWallets/ConfirmWallets.tsx +66 -62
  33. package/src/containers/History/History.tsx +3 -2
  34. package/src/containers/History/types.tsx +10 -1
  35. package/src/containers/SwapHistory/SwapHistory.tsx +87 -95
  36. package/src/helper/index.ts +1 -22
  37. package/src/types/wallet.ts +9 -0
  38. package/dist/containers/ConfirmWallets/types.d.ts +0 -9
  39. package/src/containers/ConfirmWallets/types.ts +0 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/ui",
3
- "version": "0.1.10-next.78",
3
+ "version": "0.1.10-next.80",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { PropsWithChildren } from 'react';
2
2
  import { CheckCircleIcon, InfoCircleIcon, WarningIcon } from '../Icon';
3
3
  import { Typography } from '../Typography';
4
4
  import { darkTheme, styled } from '../../theme';
@@ -30,10 +30,7 @@ const MainContainer = styled('div', {
30
30
  },
31
31
  });
32
32
 
33
- const ContentContainer = styled('div', {
34
- display: 'flex',
35
- flexDirection: 'column',
36
- });
33
+ const ContentContainer = styled('div', {});
37
34
 
38
35
  const TitleContainer = styled('div', {
39
36
  marginBottom: '$8',
@@ -49,12 +46,11 @@ const StyledTypography = styled(Typography, {
49
46
 
50
47
  export interface PropTypes {
51
48
  type: 'primary' | 'secondary' | 'success' | 'warning' | 'error';
52
- description: string;
53
49
  title?: string;
54
50
  }
55
51
 
56
- export function Alert(props: PropTypes) {
57
- const { type, description, title } = props;
52
+ export function Alert(props: PropsWithChildren<PropTypes>) {
53
+ const { type, children, title } = props;
58
54
 
59
55
  const showIcon = (
60
56
  ['error', 'success', 'warning'] as PropTypes['type'][]
@@ -75,7 +71,7 @@ export function Alert(props: PropTypes) {
75
71
  <StyledTypography variant="h6">{title}</StyledTypography>
76
72
  </TitleContainer>
77
73
  )}
78
- <StyledTypography variant="body2">{description}</StyledTypography>
74
+ {children}
79
75
  </ContentContainer>
80
76
  </MainContainer>
81
77
  );
@@ -2,8 +2,7 @@ import React, { Fragment, PropsWithChildren } from 'react';
2
2
  import { GasIcon, TimeIcon } from '../../components/Icon';
3
3
  import { StepDetail } from '../../components/StepDetail';
4
4
  import { Typography } from '../../components/Typography';
5
- import { rawFees, secondsToString, totalArrivalTime } from '../../helper';
6
- import { styled } from '../../theme';
5
+ import { keyframes, styled } from '../../theme';
7
6
  import { Skeleton } from '../Skeleton';
8
7
  import { Spinner } from '../Spinner';
9
8
  import { BestRouteResponse } from 'rango-sdk';
@@ -77,6 +76,18 @@ const ArrowRight = styled('div', {
77
76
  borderLeft: '5px solid $foreground',
78
77
  });
79
78
 
79
+ const pulse = keyframes({
80
+ '0%': {
81
+ opacity: 1,
82
+ },
83
+ '50%': {
84
+ opacity: 0.3,
85
+ },
86
+ '100%': {
87
+ opacity: 1,
88
+ },
89
+ });
90
+
80
91
  const GasContainer = styled('div', {
81
92
  backgroundColor: '$neutrals300',
82
93
  borderRadius: '5px',
@@ -91,6 +102,30 @@ const GasContainer = styled('div', {
91
102
  margin: '$8',
92
103
  },
93
104
  });
105
+
106
+ const FeeContainer = styled('div', {
107
+ display: 'flex',
108
+ flexDirection: 'column',
109
+ alignItems: 'center',
110
+ variants: {
111
+ warning: {
112
+ true: {
113
+ animation: `${pulse} 2s ease-in-out infinite`,
114
+ },
115
+ },
116
+ },
117
+ });
118
+
119
+ const TotalFee = styled(Typography, {
120
+ variants: {
121
+ warning: {
122
+ true: {
123
+ color: '$warning300',
124
+ },
125
+ },
126
+ },
127
+ });
128
+
94
129
  const SkeletonContainer = styled('div', {
95
130
  padding: '$4',
96
131
  '@md': {
@@ -105,22 +140,14 @@ const SwapperContainer = styled('div', {
105
140
 
106
141
  export interface PropTypes {
107
142
  data: BestRouteResponse | null;
143
+ totalFee: string;
144
+ feeWarning: boolean;
145
+ totalTime: string;
108
146
  loading?: boolean;
109
147
  error?: string;
110
148
  }
111
- export function BestRoute({
112
- data,
113
- loading,
114
- error,
115
- }: PropsWithChildren<PropTypes>) {
116
- let fee,
117
- time: string = '';
118
-
119
- if (!!data) {
120
- fee = rawFees(data);
121
- time = secondsToString(totalArrivalTime(data));
122
- }
123
-
149
+ export function BestRoute(props: PropsWithChildren<PropTypes>) {
150
+ const { data, loading, error, totalFee, feeWarning, totalTime } = props;
124
151
  return (
125
152
  <Container>
126
153
  {loading ? (
@@ -129,16 +156,23 @@ export function BestRoute({
129
156
  </SkeletonContainer>
130
157
  ) : (
131
158
  <GasContainer>
132
- <GasIcon size={20} />
133
- <Typography mt={4} align="center" variant="caption">
134
- {error && '-'}
135
- {!!data && `$${fee}`}
136
- </Typography>
159
+ <FeeContainer warning={feeWarning}>
160
+ <GasIcon size={20} color={feeWarning ? 'warning' : undefined} />
161
+ <TotalFee
162
+ mt={4}
163
+ align="center"
164
+ variant="caption"
165
+ warning={feeWarning}
166
+ >
167
+ {error && '-'}
168
+ {!!data && `$${totalFee}`}
169
+ </TotalFee>
170
+ </FeeContainer>
137
171
  <HR />
138
172
  <TimeIcon size={20} />
139
173
  <Typography mt={4} align="center" variant="caption">
140
174
  {error && '-'}
141
- {!!data && `~${time}m`}
175
+ {!!data && `~${totalTime}m`}
142
176
  </Typography>
143
177
  </GasContainer>
144
178
  )}
@@ -7,6 +7,7 @@ import { Spinner } from '../Spinner';
7
7
  import { styled } from '../../theme';
8
8
  import { CSSProperties } from '@stitches/react';
9
9
  import { containsText } from '../../helper';
10
+ import { Typography } from '../Typography';
10
11
 
11
12
  const ListContainer = styled('div', {
12
13
  height: '450px',
@@ -58,20 +59,22 @@ export function BlockchainSelector(props: PropTypes) {
58
59
  textFieldPlaceholder="Search Blockchain By Name"
59
60
  title={`Select ${type} Network`}
60
61
  onBack={onBack}
61
- Content={({ searchedFor }) => {
62
+ >
63
+ {(searchedFor) => {
62
64
  const filteredBlockchains = filterBlockchains(list, searchedFor);
63
65
  return (
64
- <ListContainer style={listContainerStyle}>
66
+ <ListContainer style={listContainerStyle} key="1">
65
67
  {loadingStatus === 'loading' && (
66
68
  <div>
67
69
  <Spinner size={24} />
68
70
  </div>
69
71
  )}
70
72
  {loadingStatus === 'failed' && (
71
- <Alert
72
- type="error"
73
- description="Error connecting server, please reload the app and try again"
74
- />
73
+ <Alert type="error">
74
+ <Typography variant="body2">
75
+ Error connecting server, please reload the app and try again
76
+ </Typography>
77
+ </Alert>
75
78
  )}
76
79
  {loadingStatus === 'success' && (
77
80
  <>
@@ -84,16 +87,15 @@ export function BlockchainSelector(props: PropTypes) {
84
87
  onChange={onChange}
85
88
  />
86
89
  ) : (
87
- <Alert
88
- type="secondary"
89
- description={`${searchedFor} not found`}
90
- />
90
+ <Alert type="secondary">
91
+ <Typography variant="body2">{`${searchedFor} not found`}</Typography>
92
+ </Alert>
91
93
  )}
92
94
  </>
93
95
  )}
94
96
  </ListContainer>
95
97
  );
96
98
  }}
97
- />
99
+ </SecondaryPage>
98
100
  );
99
101
  }
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties } from '@stitches/react';
2
- import React, { useState } from 'react';
2
+ import React, { useEffect, useState } from 'react';
3
3
  import { styled } from '../../theme';
4
4
  import { LiquiditySource } from '../../types/meta';
5
5
  import { Button } from '../Button/Button';
@@ -21,6 +21,7 @@ const groupLiquiditySources = (
21
21
 
22
22
  const LiquiditySourceType = styled(Typography, {
23
23
  position: 'sticky',
24
+ display: 'block',
24
25
  top: '0',
25
26
  marginTop: '$8',
26
27
  marginBottom: '$8',
@@ -55,14 +56,16 @@ export function LiquiditySourceList(props: PropTypes) {
55
56
  if (clickedItem.selected) return [...prevState, clickedItem];
56
57
  return prevState.filter((item) => item.title != clickedItem.title);
57
58
  });
58
- setTimeout(() => {
59
- onChange(clickedItem);
60
- }, 200);
59
+ onChange(clickedItem);
61
60
  };
62
61
 
63
62
  const isSelected = (liquiditySource: LiquiditySource) =>
64
63
  !!selected.find((item) => liquiditySource.title === item.title);
65
64
 
65
+ useEffect(() => {
66
+ setSelected(list.filter((item) => item.selected));
67
+ }, [list]);
68
+
66
69
  return (
67
70
  <div style={{ height: '450px', ...listContainerStyle }}>
68
71
  <div>
@@ -102,19 +105,17 @@ const LiquiditySourceItem = ({
102
105
  liquiditySource: LiquiditySource;
103
106
  selected: boolean;
104
107
  onChange: (clickedItem: LiquiditySource) => void;
105
- }) => {
106
- return (
107
- <Button
108
- size="large"
109
- align="start"
110
- variant="outlined"
111
- prefix={<LiquidityImage src={liquiditySource.logo} />}
112
- suffix={<Switch checked={selected} />}
113
- style={{ marginBottom: '12px' }}
114
- type={selected ? 'primary' : undefined}
115
- onClick={onChange.bind(null, liquiditySource)}
116
- >
117
- <Typography variant="body1">{liquiditySource.title}</Typography>
118
- </Button>
119
- );
120
- };
108
+ }) => (
109
+ <Button
110
+ size="large"
111
+ align="start"
112
+ variant="outlined"
113
+ prefix={<LiquidityImage src={liquiditySource.logo} />}
114
+ suffix={<Switch checked={selected} />}
115
+ style={{ marginBottom: '12px' }}
116
+ type={selected ? 'primary' : undefined}
117
+ onClick={onChange.bind(null, liquiditySource)}
118
+ >
119
+ <Typography variant="body1">{liquiditySource.title}</Typography>
120
+ </Button>
121
+ );
@@ -43,13 +43,14 @@ export function LiquiditySourcesSelector(props: PropTypes) {
43
43
  }
44
44
  hasHeader={hasHeader}
45
45
  onBack={onBack}
46
- Content={({ searchedFor }) => (
46
+ >
47
+ {(searchedFor) => (
47
48
  <LiquiditySourceList
48
49
  listContainerStyle={listContainerStyle}
49
50
  list={filterLiquiditySources(list, searchedFor)}
50
51
  onChange={onChange}
51
52
  />
52
53
  )}
53
- />
54
+ </SecondaryPage>
54
55
  );
55
56
  }
@@ -26,6 +26,7 @@ const ItemContainer = styled('div', {
26
26
  marginRight: '$8',
27
27
  });
28
28
  const StyledItem = styled(RadioGroup.Item, {
29
+ padding: '0',
29
30
  backgroundColor: '$neutrals300',
30
31
  width: '20px',
31
32
  height: '20px',
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { ReactNode, useState } from 'react';
2
2
  import { styled } from '../../theme';
3
3
  import { AngleLeftIcon, SearchIcon } from '../Icon';
4
4
  import { TextField } from '../TextField/TextField';
@@ -7,12 +7,12 @@ import { Typography } from '../Typography';
7
7
  export type PropTypes = (
8
8
  | {
9
9
  textField: true;
10
- Content: React.ElementType<{ searchedFor: string }>;
10
+ children?: (searchedFor: string) => ReactNode;
11
11
  textFieldPlaceholder: string;
12
12
  }
13
13
  | {
14
14
  textField: false;
15
- Content: React.ReactNode;
15
+ children?: ReactNode;
16
16
  }
17
17
  ) & {
18
18
  title?: string;
@@ -84,10 +84,9 @@ export function SecondaryPage(props: PropTypes) {
84
84
  </div>
85
85
  )}
86
86
  <ContentContainer>
87
- {props.textField && <props.Content searchedFor={searchedFor} />}
88
- {!props.textField && props.Content}
87
+ {props.textField && props.children?.(searchedFor)}
88
+ {!props.textField && props.children}
89
89
  </ContentContainer>
90
-
91
90
  {Footer}
92
91
  </Container>
93
92
  );
@@ -1,6 +1,6 @@
1
1
  import React, { PropsWithChildren, useEffect, useState } from 'react';
2
- import { SelectableWallet } from '../../containers/ConfirmWallets/types';
3
2
  import { styled } from '../../theme';
3
+ import { SelectableWallet } from '../../types';
4
4
  import { Typography } from '../Typography';
5
5
 
6
6
  const Row = styled('div', {
@@ -14,10 +14,12 @@ const BaseContainer = styled('div', {
14
14
  padding: '$16',
15
15
  });
16
16
 
17
+ const Title = styled(Typography, { marginBottom: '$16' });
18
+
17
19
  const SlippageChipsContainer = styled('div', {
18
- display: 'flex',
19
- flexWrap: 'wrap',
20
- marginTop: '$16',
20
+ display: 'grid',
21
+ rowGap: '$16',
22
+ gridTemplateColumns: 'repeat(auto-fill, 64px)',
21
23
  });
22
24
 
23
25
  const LiquiditySourceContainer = styled(BaseContainer, {
@@ -27,7 +29,7 @@ const LiquiditySourceContainer = styled(BaseContainer, {
27
29
  cursor: 'pointer',
28
30
  });
29
31
 
30
- const StyledAngleRight = styled(AngleRightIcon, { marginLeft: '8px' });
32
+ const StyledAngleRight = styled(AngleRightIcon, { marginLeft: '$8' });
31
33
 
32
34
  const LiquiditySourceNumber = styled('div', {
33
35
  display: 'flex',
@@ -85,7 +87,7 @@ export function Settings(props: PropTypes) {
85
87
  const PageContent = (
86
88
  <>
87
89
  <BaseContainer>
88
- <Typography variant="body1">Slippage tolerance per swap</Typography>
90
+ <Title variant="body1">Slippage tolerance per swap</Title>
89
91
  <SlippageChipsContainer>
90
92
  {slippages.map((slippage, index) => (
91
93
  <Chip
@@ -126,7 +128,7 @@ export function Settings(props: PropTypes) {
126
128
  </SlippageChipsContainer>
127
129
  </BaseContainer>
128
130
  <ThemesContainer>
129
- <Typography variant="body2">Theme</Typography>
131
+ <Title variant="body2">Theme</Title>
130
132
  <Radio
131
133
  defaultValue={selectedTheme}
132
134
  options={[
@@ -141,7 +143,7 @@ export function Settings(props: PropTypes) {
141
143
  </ThemesContainer>
142
144
  <LiquiditySourceContainer onClick={onLiquiditySourcesClick}>
143
145
  <Typography variant="body1">Liquidity Sources</Typography>
144
- <LiquiditySourceNumber onClick={onLiquiditySourcesClick}>
146
+ <LiquiditySourceNumber>
145
147
  <Typography variant="body2">{`( ${selectedLiquiditySources.length} / ${liquiditySources.length} )`}</Typography>
146
148
  <StyledAngleRight />
147
149
  </LiquiditySourceNumber>
@@ -150,11 +152,8 @@ export function Settings(props: PropTypes) {
150
152
  );
151
153
 
152
154
  return (
153
- <SecondaryPage
154
- title="Settings"
155
- textField={false}
156
- Content={PageContent}
157
- onBack={onBack}
158
- />
155
+ <SecondaryPage title="Settings" textField={false} onBack={onBack}>
156
+ {PageContent}
157
+ </SecondaryPage>
159
158
  );
160
159
  }
@@ -14,6 +14,7 @@ const MainContainer = styled('div', {
14
14
  flexDirection: 'column',
15
15
  alignItems: 'end',
16
16
  padding: '$16 $24',
17
+ boxSizing: 'border-box',
17
18
  });
18
19
 
19
20
  const ContentContainer = styled('div', {
@@ -13,6 +13,7 @@ const StyledSwitchRoot = styled(RadixSwitch.Root, {
13
13
  borderColor: '$neutrals400',
14
14
  borderRadius: '99999px',
15
15
  position: 'relative',
16
+ padding: '0',
16
17
  cursor: 'pointer',
17
18
  '&[data-state="checked"]': {
18
19
  backgroundColor: '$primary100',
@@ -33,7 +33,8 @@ export function TokenSelector(props: PropTypes) {
33
33
  title={`Select ${type} Token`}
34
34
  hasHeader={hasHeader}
35
35
  onBack={onBack}
36
- Content={({ searchedFor }) => (
36
+ >
37
+ {(searchedFor) => (
37
38
  <TokenList
38
39
  searchedText={searchedFor}
39
40
  list={list}
@@ -43,6 +44,6 @@ export function TokenSelector(props: PropTypes) {
43
44
  onChange={onChange}
44
45
  />
45
46
  )}
46
- />
47
+ </SecondaryPage>
47
48
  );
48
49
  }
@@ -1,5 +1,5 @@
1
1
  import { BestRouteResponse } from 'rango-sdk';
2
- import React, { Fragment, PropsWithChildren } from 'react';
2
+ import React, { Fragment, PropsWithChildren, ReactNode } from 'react';
3
3
  import { Alert } from '../../components/Alert';
4
4
  import { Button } from '../../components/Button';
5
5
  import { RetryIcon, GasIcon } from '../../components/Icon';
@@ -8,6 +8,10 @@ import { StepDetail } from '../../components/StepDetail';
8
8
  import { Typography } from '../../components/Typography';
9
9
  import { styled } from '../../theme';
10
10
 
11
+ const MainContainer = styled('div', {
12
+ overflow: 'hidden',
13
+ });
14
+
11
15
  export const Line = styled('div', {
12
16
  width: '0',
13
17
  marginLeft: '$12',
@@ -68,24 +72,38 @@ export const StyledUpdateIcon = styled(UpdateIcon, {
68
72
  cursor: 'pointer',
69
73
  });
70
74
 
75
+ const BestRouteContainer = styled('div', {
76
+ overflow: 'auto',
77
+ });
78
+
71
79
  const Alerts = styled('div', { paddingBottom: '$16' });
72
80
 
73
81
  export interface PropTypes {
74
82
  bestRoute: BestRouteResponse | null;
83
+ onRefresh?: React.MouseEventHandler<SVGElement>;
84
+ confirmButtonTitle: string;
85
+ confirmButtonDisabled: boolean;
75
86
  onBack: () => void;
76
87
  onConfirm?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
77
88
  loading?: boolean;
78
- error?: string;
79
- warning?: string;
89
+ errors?: ReactNode[];
90
+ warnings?: ReactNode[];
91
+ extraMessages?: ReactNode;
80
92
  }
81
- export function ConfirmSwap({
82
- bestRoute,
83
- onBack,
84
- onConfirm,
85
- loading,
86
- error,
87
- warning,
88
- }: PropsWithChildren<PropTypes>) {
93
+ export function ConfirmSwap(props: PropsWithChildren<PropTypes>) {
94
+ const {
95
+ bestRoute,
96
+ onRefresh,
97
+ onBack,
98
+ onConfirm,
99
+ loading,
100
+ errors,
101
+ warnings,
102
+ extraMessages,
103
+ confirmButtonTitle,
104
+ confirmButtonDisabled,
105
+ } = props;
106
+
89
107
  return (
90
108
  <SecondaryPage
91
109
  textField={false}
@@ -99,56 +117,76 @@ export function ConfirmSwap({
99
117
  loading={loading}
100
118
  variant="contained"
101
119
  onClick={onConfirm}
120
+ disabled={confirmButtonDisabled}
102
121
  >
103
- Swap
122
+ {confirmButtonTitle}
104
123
  </Button>
105
124
  </Footer>
106
125
  }
107
- Content={bestRoute?.result?.swaps.map((swap, index) => (
108
- <Fragment key={index}>
126
+ TopButton={<StyledUpdateIcon size={24} onClick={onRefresh} />}
127
+ >
128
+ <MainContainer>
129
+ <div>
130
+ {extraMessages || null}
109
131
  <Alerts>
110
- {error && <Alert description={error} type="error" />}
111
- {warning && <Alert description={warning} type="warning" />}
132
+ {errors?.map((error, index) => (
133
+ <Alert type="error" key={index}>
134
+ {error}
135
+ </Alert>
136
+ ))}
137
+ {/* {error && warnings && <Spacer direction="vertical" size={16} />} */}
138
+ {warnings?.map((warning, index) => (
139
+ <Alert type="warning" key={index}>
140
+ {warning}
141
+ </Alert>
142
+ ))}
112
143
  </Alerts>
113
- {index === 0 && (
114
- <RelativeContainer>
144
+ </div>
145
+ <BestRouteContainer>
146
+ {bestRoute?.result?.swaps.map((swap, index) => (
147
+ <Fragment key={index}>
148
+ {index === 0 && (
149
+ <RelativeContainer>
150
+ <StepDetail
151
+ logo={swap.from.logo}
152
+ symbol={swap.from.symbol}
153
+ chainLogo={swap.from.blockchainLogo}
154
+ blockchain={swap.from.blockchain}
155
+ amount={swap.fromAmount}
156
+ />
157
+ <Dot />
158
+ </RelativeContainer>
159
+ )}
160
+ <Line />
161
+ <SwapperContainer>
162
+ <SwapperLogo src={swap.swapperLogo} alt={swap.swapperId} />
163
+ <div>
164
+ <Typography ml={4} variant="caption">
165
+ {swap.swapperType} from {swap.from.symbol} to{' '}
166
+ {swap.to.symbol} via {swap.swapperId}{' '}
167
+ </Typography>
168
+ <Fee>
169
+ <GasIcon />
170
+ <Typography ml={4} variant="caption">
171
+ {parseFloat(swap.fee[0].amount).toFixed(6)} estimated gas
172
+ fee
173
+ </Typography>
174
+ </Fee>
175
+ </div>
176
+ </SwapperContainer>
177
+ <Line />
178
+ {index + 1 === bestRoute.result?.swaps.length && <ArrowDown />}
115
179
  <StepDetail
116
- logo={swap.from.logo}
117
- symbol={swap.from.symbol}
118
- chainLogo={swap.from.blockchainLogo}
119
- blockchain={swap.from.blockchain}
120
- amount={swap.fromAmount}
180
+ logo={swap.to.logo}
181
+ symbol={swap.to.symbol}
182
+ chainLogo={swap.to.blockchainLogo}
183
+ blockchain={swap.to.blockchain}
184
+ amount={swap.toAmount}
121
185
  />
122
- <Dot />
123
- </RelativeContainer>
124
- )}
125
- <Line />
126
- <SwapperContainer>
127
- <SwapperLogo src={swap.swapperLogo} alt={swap.swapperId} />
128
- <div>
129
- <Typography ml={4} variant="caption">
130
- {swap.swapperType} from {swap.from.symbol} to {swap.to.symbol}{' '}
131
- via {swap.swapperId}{' '}
132
- </Typography>
133
- <Fee>
134
- <GasIcon />
135
- <Typography ml={4} variant="caption">
136
- {parseFloat(swap.fee[0].amount).toFixed(6)} estimated gas fee
137
- </Typography>
138
- </Fee>
139
- </div>
140
- </SwapperContainer>
141
- <Line />
142
- {index + 1 === bestRoute.result?.swaps.length && <ArrowDown />}
143
- <StepDetail
144
- logo={swap.to.logo}
145
- symbol={swap.to.symbol}
146
- chainLogo={swap.to.blockchainLogo}
147
- blockchain={swap.to.blockchain}
148
- amount={swap.toAmount}
149
- />
150
- </Fragment>
151
- ))}
152
- />
186
+ </Fragment>
187
+ ))}
188
+ </BestRouteContainer>
189
+ </MainContainer>
190
+ </SecondaryPage>
153
191
  );
154
192
  }