@rango-dev/widget-embedded 0.30.1 → 0.31.1-next.0
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.
- package/CHANGELOG.md +35 -0
- package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +1 -653
- package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts.map +1 -1
- package/dist/components/ConfirmWalletsModal/ConfirmWalletsModal.d.ts.map +1 -1
- package/dist/components/ConfirmWalletsModal/WalletList.d.ts.map +1 -1
- package/dist/components/CustomDestination/CustomDestination.d.ts +4 -0
- package/dist/components/CustomDestination/CustomDestination.d.ts.map +1 -0
- package/dist/components/CustomDestination/CustomDestination.styles.d.ts +495 -0
- package/dist/components/CustomDestination/CustomDestination.styles.d.ts.map +1 -0
- package/dist/components/CustomDestination/CustomDestination.types.d.ts +7 -0
- package/dist/components/CustomDestination/CustomDestination.types.d.ts.map +1 -0
- package/dist/components/FilterSelector/FilterSelector.d.ts +4 -0
- package/dist/components/FilterSelector/FilterSelector.d.ts.map +1 -0
- package/dist/components/FilterSelector/FilterSelector.style.d.ts +962 -0
- package/dist/components/FilterSelector/FilterSelector.style.d.ts.map +1 -0
- package/dist/components/FilterSelector/FilterSelector.type.d.ts +14 -0
- package/dist/components/FilterSelector/FilterSelector.type.d.ts.map +1 -0
- package/dist/components/FilterSelector/FilterSelectorContent.d.ts +4 -0
- package/dist/components/FilterSelector/FilterSelectorContent.d.ts.map +1 -0
- package/dist/components/FilterSelector/index.d.ts +2 -0
- package/dist/components/FilterSelector/index.d.ts.map +1 -0
- package/dist/components/Quote/Quote.styles.d.ts +3 -3
- package/dist/components/RefreshModal/RefreshModal.styles.d.ts +3 -3
- package/dist/components/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
- package/dist/components/SwapDetails/SwapDetails.styles.d.ts.map +1 -1
- package/dist/components/SwapDetailsModal/SwapDetailsModal.WalletState.d.ts.map +1 -1
- package/dist/components/TokenList/TokenList.d.ts.map +1 -1
- package/dist/containers/Inputs/Inputs.d.ts.map +1 -1
- package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
- package/dist/containers/WidgetInfo/WidgetInfo.d.ts.map +1 -1
- package/dist/containers/WidgetInfo/WidgetInfo.types.d.ts +5 -1
- package/dist/containers/WidgetInfo/WidgetInfo.types.d.ts.map +1 -1
- package/dist/hooks/useObserveBalanceChanges/index.d.ts +2 -0
- package/dist/hooks/useObserveBalanceChanges/index.d.ts.map +1 -0
- package/dist/hooks/useObserveBalanceChanges/useObserveBalanceChanges.d.ts +4 -0
- package/dist/hooks/useObserveBalanceChanges/useObserveBalanceChanges.d.ts.map +1 -0
- package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.d.ts +2 -2
- package/dist/hooks/useTheme.d.ts.map +1 -1
- package/dist/hooks/useUpdateQuoteInputs/index.d.ts +2 -0
- package/dist/hooks/useUpdateQuoteInputs/index.d.ts.map +1 -0
- package/dist/hooks/useUpdateQuoteInputs/useUpdateQuoteInputs.d.ts +3 -0
- package/dist/hooks/useUpdateQuoteInputs/useUpdateQuoteInputs.d.ts.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +4 -4
- package/dist/pages/HistoryPage.d.ts.map +1 -1
- package/dist/pages/Home.d.ts.map +1 -1
- package/dist/pages/WalletsPage.d.ts.map +1 -1
- package/dist/services/cacheService.d.ts +21 -0
- package/dist/services/cacheService.d.ts.map +1 -0
- package/dist/store/notification.d.ts.map +1 -1
- package/dist/store/slices/config.d.ts +2 -1
- package/dist/store/slices/config.d.ts.map +1 -1
- package/dist/store/slices/data.d.ts +2 -1
- package/dist/store/slices/data.d.ts.map +1 -1
- package/dist/store/utils/data.d.ts +20 -0
- package/dist/store/utils/data.d.ts.map +1 -0
- package/dist/store/utils/data.test.d.ts +2 -0
- package/dist/store/utils/data.test.d.ts.map +1 -0
- package/dist/store/utils/index.d.ts +2 -0
- package/dist/store/utils/index.d.ts.map +1 -0
- package/dist/test-utils/fixtures.d.ts +1 -0
- package/dist/test-utils/fixtures.d.ts.map +1 -1
- package/dist/types/config.d.ts +5 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/event.d.ts +21 -15
- package/dist/types/event.d.ts.map +1 -1
- package/dist/types/notification.d.ts +1 -0
- package/dist/types/notification.d.ts.map +1 -1
- package/dist/types/quote.d.ts +9 -1
- package/dist/types/quote.d.ts.map +1 -1
- package/dist/types/wallets.d.ts +1 -1
- package/dist/types/wallets.d.ts.map +1 -1
- package/dist/utils/events.d.ts +8 -0
- package/dist/utils/events.d.ts.map +1 -0
- package/dist/utils/settings.d.ts +1 -1
- package/dist/utils/swap.d.ts +1 -1
- package/dist/utils/swap.d.ts.map +1 -1
- package/dist/widget-embedded.build.json +1 -1
- package/package.json +10 -10
- package/src/components/ConfirmWalletsModal/ConfirmWallets.styles.ts +1 -49
- package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +61 -179
- package/src/components/ConfirmWalletsModal/WalletList.tsx +16 -4
- package/src/components/CustomDestination/CustomDestination.styles.ts +45 -0
- package/src/components/CustomDestination/CustomDestination.tsx +148 -0
- package/src/components/CustomDestination/CustomDestination.types.ts +7 -0
- package/src/components/FilterSelector/FilterSelector.style.ts +95 -0
- package/src/components/FilterSelector/FilterSelector.tsx +42 -0
- package/src/components/FilterSelector/FilterSelector.type.ts +15 -0
- package/src/components/FilterSelector/FilterSelectorContent.tsx +60 -0
- package/src/components/FilterSelector/index.ts +1 -0
- package/src/components/SearchInput/SearchInput.tsx +2 -0
- package/src/components/SwapDetails/SwapDetails.styles.ts +10 -0
- package/src/components/SwapDetails/SwapDetails.tsx +25 -13
- package/src/components/SwapDetailsModal/SwapDetailsModal.WalletState.tsx +28 -13
- package/src/components/TokenList/TokenList.tsx +8 -2
- package/src/containers/Inputs/Inputs.tsx +1 -0
- package/src/containers/Wallets/Wallets.tsx +7 -2
- package/src/containers/WidgetInfo/WidgetInfo.tsx +26 -0
- package/src/containers/WidgetInfo/WidgetInfo.types.ts +5 -1
- package/src/hooks/useObserveBalanceChanges/index.ts +1 -0
- package/src/hooks/useObserveBalanceChanges/useObserveBalanceChanges.ts +68 -0
- package/src/hooks/useTheme.ts +11 -5
- package/src/hooks/useUpdateQuoteInputs/index.ts +1 -0
- package/src/hooks/useUpdateQuoteInputs/useUpdateQuoteInputs.ts +50 -0
- package/src/index.ts +4 -0
- package/src/pages/HistoryPage.tsx +180 -26
- package/src/pages/Home.tsx +6 -3
- package/src/pages/WalletsPage.tsx +29 -13
- package/src/services/cacheService.ts +35 -0
- package/src/store/notification.ts +13 -1
- package/src/store/quote.ts +1 -1
- package/src/store/slices/config.ts +39 -1
- package/src/store/slices/data.test.ts +84 -0
- package/src/store/slices/data.ts +44 -24
- package/src/store/utils/data.test.ts +175 -0
- package/src/store/utils/data.ts +117 -0
- package/src/store/utils/index.ts +1 -0
- package/src/test-utils/fixtures.ts +14 -7
- package/src/types/config.ts +3 -1
- package/src/types/event.ts +32 -16
- package/src/types/notification.ts +1 -0
- package/src/types/quote.ts +11 -0
- package/src/types/wallets.ts +1 -1
- package/src/utils/events.ts +27 -0
- package/src/utils/swap.ts +4 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rango-dev/widget-embedded",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.1-next.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"source": "./src/index.ts",
|
|
@@ -24,15 +24,15 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@lingui/core": "4.2.1",
|
|
26
26
|
"@lingui/react": "4.2.1",
|
|
27
|
-
"@rango-dev/logging-core": "^0.
|
|
28
|
-
"@rango-dev/provider-all": "^0.
|
|
29
|
-
"@rango-dev/queue-manager-core": "^0.
|
|
30
|
-
"@rango-dev/queue-manager-rango-preset": "^0.
|
|
31
|
-
"@rango-dev/queue-manager-react": "^0.
|
|
32
|
-
"@rango-dev/signer-solana": "^0.
|
|
33
|
-
"@rango-dev/ui": "^0.
|
|
34
|
-
"@rango-dev/wallets-react": "^0.
|
|
35
|
-
"@rango-dev/wallets-shared": "^0.
|
|
27
|
+
"@rango-dev/logging-core": "^0.6.0",
|
|
28
|
+
"@rango-dev/provider-all": "^0.36.1-next.0",
|
|
29
|
+
"@rango-dev/queue-manager-core": "^0.27.0",
|
|
30
|
+
"@rango-dev/queue-manager-rango-preset": "^0.36.0",
|
|
31
|
+
"@rango-dev/queue-manager-react": "^0.27.0",
|
|
32
|
+
"@rango-dev/signer-solana": "^0.31.1-next.0",
|
|
33
|
+
"@rango-dev/ui": "^0.37.0",
|
|
34
|
+
"@rango-dev/wallets-react": "^0.22.0",
|
|
35
|
+
"@rango-dev/wallets-shared": "^0.36.0",
|
|
36
36
|
"bignumber.js": "^9.1.1",
|
|
37
37
|
"copy-to-clipboard": "^3.3.3",
|
|
38
38
|
"dayjs": "^1.11.7",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { css, darkTheme, IconButton, styled
|
|
1
|
+
import { css, darkTheme, IconButton, styled } from '@rango-dev/ui';
|
|
2
2
|
|
|
3
3
|
export const Title = styled('div', {
|
|
4
4
|
display: 'flex',
|
|
@@ -93,56 +93,8 @@ export const walletsListStyles = css({
|
|
|
93
93
|
height: '100%',
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
-
export const CustomDestination = styled('div', {
|
|
97
|
-
padding: '$10 $0',
|
|
98
|
-
'& .button__content': {
|
|
99
|
-
display: 'flex',
|
|
100
|
-
alignItems: 'center',
|
|
101
|
-
},
|
|
102
|
-
'& .alarms': { paddingTop: '$5' },
|
|
103
|
-
'& .collapsible_content': {
|
|
104
|
-
backgroundColor: '$neutral100',
|
|
105
|
-
},
|
|
106
|
-
'& .collapsible_root': {
|
|
107
|
-
backgroundColor: '$neutral100',
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
export const alarmsStyles = css({
|
|
112
|
-
paddingTop: '$5',
|
|
113
|
-
});
|
|
114
|
-
|
|
115
96
|
export const ConfirmButton = styled('div', {
|
|
116
97
|
display: 'flex',
|
|
117
98
|
});
|
|
118
99
|
|
|
119
|
-
export const StyledTextField = styled(TextField, {
|
|
120
|
-
backgroundColor: '$neutral100',
|
|
121
|
-
padding: '$15',
|
|
122
|
-
});
|
|
123
|
-
|
|
124
100
|
export const Wallets = styled('div', { overflow: 'visible', width: '100%' });
|
|
125
|
-
|
|
126
|
-
export const CustomDestinationButton = styled('div', {
|
|
127
|
-
width: '100%',
|
|
128
|
-
borderRadius: '$sm',
|
|
129
|
-
display: 'flex',
|
|
130
|
-
padding: '$15',
|
|
131
|
-
justifyContent: 'space-between',
|
|
132
|
-
alignItems: 'center',
|
|
133
|
-
$$color: '$colors$neutral100',
|
|
134
|
-
[`.${darkTheme} &`]: {
|
|
135
|
-
$$color: '$colors$neutral300',
|
|
136
|
-
},
|
|
137
|
-
backgroundColor: '$$color',
|
|
138
|
-
borderBottomRightRadius: '0',
|
|
139
|
-
borderBottomLeftRadius: '0',
|
|
140
|
-
'&:focus-visible': {
|
|
141
|
-
$$background: '$colors$secondary100',
|
|
142
|
-
[`.${darkTheme} &`]: {
|
|
143
|
-
$$background: '$colors$info700',
|
|
144
|
-
},
|
|
145
|
-
backgroundColor: '$$background',
|
|
146
|
-
outline: 0,
|
|
147
|
-
},
|
|
148
|
-
});
|
|
@@ -1,30 +1,18 @@
|
|
|
1
1
|
import type { PropTypes } from './ConfirmWalletsModal.types';
|
|
2
2
|
import type { ConnectedWallet } from '../../store/wallets';
|
|
3
3
|
import type { ConfirmSwapWarnings, Wallet } from '../../types';
|
|
4
|
-
import type { MouseEvent } from 'react';
|
|
5
4
|
|
|
6
5
|
import { i18n } from '@lingui/core';
|
|
7
6
|
import {
|
|
8
7
|
Alert,
|
|
9
8
|
BalanceErrors,
|
|
10
9
|
Button,
|
|
11
|
-
ChevronDownIcon,
|
|
12
10
|
ChevronLeftIcon,
|
|
13
|
-
CloseIcon,
|
|
14
11
|
Divider,
|
|
15
|
-
IconButton,
|
|
16
12
|
MessageBox,
|
|
17
|
-
PasteIcon,
|
|
18
13
|
Typography,
|
|
19
|
-
WalletIcon,
|
|
20
14
|
} from '@rango-dev/ui';
|
|
21
|
-
import React, {
|
|
22
|
-
useCallback,
|
|
23
|
-
useEffect,
|
|
24
|
-
useMemo,
|
|
25
|
-
useRef,
|
|
26
|
-
useState,
|
|
27
|
-
} from 'react';
|
|
15
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
28
16
|
import { useNavigate } from 'react-router-dom';
|
|
29
17
|
|
|
30
18
|
import { WIDGET_UI_ID } from '../../constants';
|
|
@@ -33,26 +21,17 @@ import { getQuoteUpdateWarningMessage } from '../../constants/warnings';
|
|
|
33
21
|
import { useAppStore } from '../../store/AppStore';
|
|
34
22
|
import { useQuoteStore } from '../../store/quote';
|
|
35
23
|
import { useWalletsStore } from '../../store/wallets';
|
|
36
|
-
import {
|
|
37
|
-
getBlockchainDisplayNameFor,
|
|
38
|
-
getBlockchainShortNameFor,
|
|
39
|
-
} from '../../utils/meta';
|
|
24
|
+
import { getBlockchainShortNameFor } from '../../utils/meta';
|
|
40
25
|
import { isConfirmSwapDisabled } from '../../utils/swap';
|
|
41
26
|
import { getQuoteWallets } from '../../utils/wallets';
|
|
42
27
|
import { WatermarkedModal } from '../common/WatermarkedModal';
|
|
43
|
-
import {
|
|
44
|
-
import { ExpandedIcon } from '../CustomCollapsible/CustomCollapsible.styles';
|
|
28
|
+
import { CustomDestination } from '../CustomDestination/CustomDestination';
|
|
45
29
|
|
|
46
|
-
import { isValidAddress } from './ConfirmWallets.helpers';
|
|
47
30
|
import {
|
|
48
|
-
alarmsStyles,
|
|
49
31
|
ConfirmButton,
|
|
50
|
-
CustomDestination,
|
|
51
|
-
CustomDestinationButton,
|
|
52
32
|
ListContainer,
|
|
53
33
|
NavigateBack,
|
|
54
34
|
ShowMoreHeader,
|
|
55
|
-
StyledTextField,
|
|
56
35
|
Title,
|
|
57
36
|
Wallets,
|
|
58
37
|
WalletsContainer,
|
|
@@ -66,10 +45,6 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
66
45
|
//TODO: move component's logics to a custom hook
|
|
67
46
|
const { open, onClose, onCancel, onCheckBalance, loading } = props;
|
|
68
47
|
const navigate = useNavigate();
|
|
69
|
-
const config = useAppStore().config;
|
|
70
|
-
|
|
71
|
-
const customDestinationInputRef = useRef<HTMLInputElement | null>(null);
|
|
72
|
-
|
|
73
48
|
const blockchains = useAppStore().blockchains();
|
|
74
49
|
const {
|
|
75
50
|
selectedQuote,
|
|
@@ -80,6 +55,7 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
80
55
|
setCustomDestination,
|
|
81
56
|
} = useQuoteStore();
|
|
82
57
|
const { connectedWallets, selectWallets } = useWalletsStore();
|
|
58
|
+
const { config } = useAppStore();
|
|
83
59
|
|
|
84
60
|
const [showMoreWalletFor, setShowMoreWalletFor] = useState('');
|
|
85
61
|
const [balanceWarnings, setBalanceWarnings] = useState<string[]>([]);
|
|
@@ -87,12 +63,11 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
87
63
|
const [quoteWarning, setQuoteWarning] = useState<
|
|
88
64
|
ConfirmSwapWarnings['quoteUpdate'] | null
|
|
89
65
|
>(null);
|
|
90
|
-
|
|
66
|
+
|
|
67
|
+
const [isCustomDestinationOpen, setCustomDestinationOpen] = useState(
|
|
91
68
|
!!customDestination
|
|
92
69
|
);
|
|
93
70
|
|
|
94
|
-
const isFirefox = navigator?.userAgent.includes('Firefox');
|
|
95
|
-
|
|
96
71
|
const quoteWallets = useMemo(
|
|
97
72
|
() =>
|
|
98
73
|
getQuoteWallets({
|
|
@@ -156,62 +131,50 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
156
131
|
(!isWalletRequiredFor(chain) && !customDestination))
|
|
157
132
|
);
|
|
158
133
|
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
selectableWallet.chain === lastStepToBlockchain?.name
|
|
174
|
-
) {
|
|
175
|
-
anyWalletSelected = true;
|
|
176
|
-
return {
|
|
177
|
-
...selectableWallet,
|
|
178
|
-
selected: true,
|
|
179
|
-
};
|
|
134
|
+
const updateSelectableWallets = (
|
|
135
|
+
wallets: ConnectedWallet[],
|
|
136
|
+
chainName: string,
|
|
137
|
+
shouldSelect: boolean
|
|
138
|
+
) => {
|
|
139
|
+
let isAnyWalletSelected = false;
|
|
140
|
+
return wallets.map((wallet) => {
|
|
141
|
+
if (wallet.chain === chainName) {
|
|
142
|
+
let selected = wallet.selected;
|
|
143
|
+
if (!isAnyWalletSelected && shouldSelect) {
|
|
144
|
+
isAnyWalletSelected = true;
|
|
145
|
+
selected = true;
|
|
146
|
+
} else if (!shouldSelect) {
|
|
147
|
+
selected = false;
|
|
180
148
|
}
|
|
181
|
-
return
|
|
182
|
-
|
|
149
|
+
return {
|
|
150
|
+
...wallet,
|
|
151
|
+
selected,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return wallet;
|
|
183
155
|
});
|
|
184
156
|
};
|
|
185
157
|
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const handleCustomDestinationCollapsibleOpenChange = (checked: boolean) => {
|
|
200
|
-
if (!checked) {
|
|
201
|
-
resetCustomDestination();
|
|
158
|
+
const handleCustomDestinationCollapsibleOpenChange = (open: boolean) => {
|
|
159
|
+
setCustomDestinationOpen(open);
|
|
160
|
+
if (!open) {
|
|
161
|
+
setCustomDestination('');
|
|
162
|
+
setSelectableWallets((selectableWallets) => {
|
|
163
|
+
return updateSelectableWallets(
|
|
164
|
+
selectableWallets,
|
|
165
|
+
lastStepToBlockchain?.name || '',
|
|
166
|
+
true
|
|
167
|
+
);
|
|
168
|
+
});
|
|
202
169
|
} else {
|
|
203
170
|
if (!isWalletRequiredFor(lastStepToBlockchain?.name ?? '')) {
|
|
204
|
-
setSelectableWallets((selectableWallets) =>
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
return selectableWallet;
|
|
213
|
-
})
|
|
214
|
-
);
|
|
171
|
+
setSelectableWallets((selectableWallets) => {
|
|
172
|
+
return updateSelectableWallets(
|
|
173
|
+
selectableWallets,
|
|
174
|
+
lastStepToBlockchain?.name || '',
|
|
175
|
+
false
|
|
176
|
+
);
|
|
177
|
+
});
|
|
215
178
|
}
|
|
216
179
|
}
|
|
217
180
|
};
|
|
@@ -237,10 +200,10 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
237
200
|
onCancel();
|
|
238
201
|
if (
|
|
239
202
|
wallet.chain === lastStepToBlockchain?.name &&
|
|
240
|
-
|
|
203
|
+
isCustomDestinationOpen &&
|
|
241
204
|
!isWalletRequiredFor(lastStepToBlockchain.name)
|
|
242
205
|
) {
|
|
243
|
-
|
|
206
|
+
setCustomDestinationOpen(false);
|
|
244
207
|
setCustomDestination(null);
|
|
245
208
|
}
|
|
246
209
|
setSelectableWallets((selectableWallets) =>
|
|
@@ -287,24 +250,6 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
287
250
|
}
|
|
288
251
|
};
|
|
289
252
|
|
|
290
|
-
const renderCustomDestinationSuffix = () => {
|
|
291
|
-
if (customDestination) {
|
|
292
|
-
return (
|
|
293
|
-
<IconButton onClick={handleClearCustomDestination} variant="ghost">
|
|
294
|
-
<CloseIcon size={12} color="gray" />
|
|
295
|
-
</IconButton>
|
|
296
|
-
);
|
|
297
|
-
} else if (!isFirefox) {
|
|
298
|
-
return (
|
|
299
|
-
<IconButton onClick={handlePasteCustomDestination} variant="ghost">
|
|
300
|
-
<PasteIcon size={16} />
|
|
301
|
-
</IconButton>
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return null;
|
|
306
|
-
};
|
|
307
|
-
|
|
308
253
|
useEffect(() => {
|
|
309
254
|
setSelectableWallets((selectableWallets) => {
|
|
310
255
|
let nextState: typeof selectableWallets = [];
|
|
@@ -382,13 +327,14 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
382
327
|
dismissible={!showMoreWalletFor}
|
|
383
328
|
container={modalContainer}
|
|
384
329
|
{...(!showMoreWalletFor && {
|
|
330
|
+
styles: { container: { height: '100%' } },
|
|
385
331
|
footer: (
|
|
386
332
|
<ConfirmButton>
|
|
387
333
|
<Button
|
|
388
334
|
loading={loading}
|
|
389
335
|
disabled={isConfirmSwapDisabled(
|
|
390
336
|
loading,
|
|
391
|
-
|
|
337
|
+
isCustomDestinationOpen,
|
|
392
338
|
customDestination,
|
|
393
339
|
selectedQuote,
|
|
394
340
|
selectableWallets,
|
|
@@ -405,7 +351,7 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
405
351
|
),
|
|
406
352
|
})}
|
|
407
353
|
{...(showMoreWalletFor && {
|
|
408
|
-
styles: { container: { padding: '$0' } },
|
|
354
|
+
styles: { container: { height: '100%', padding: '$0' } },
|
|
409
355
|
header: (
|
|
410
356
|
<ShowMoreHeader>
|
|
411
357
|
<NavigateBack
|
|
@@ -487,7 +433,10 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
487
433
|
|
|
488
434
|
const key = `wallet-${index}`;
|
|
489
435
|
const isLastWallet = index === quoteWallets.length - 1;
|
|
490
|
-
|
|
436
|
+
const showCustomDestination =
|
|
437
|
+
isLastWallet &&
|
|
438
|
+
lastStepToBlockchain &&
|
|
439
|
+
config?.customDestination !== false;
|
|
491
440
|
return (
|
|
492
441
|
<div key={key}>
|
|
493
442
|
<Title>
|
|
@@ -523,81 +472,14 @@ export function ConfirmWalletsModal(props: PropTypes) {
|
|
|
523
472
|
/>
|
|
524
473
|
</ListContainer>
|
|
525
474
|
{!isLastWallet && <Divider size={32} />}
|
|
526
|
-
{
|
|
527
|
-
<CustomDestination
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
triggerAnchor="top"
|
|
535
|
-
trigger={
|
|
536
|
-
<CustomDestinationButton>
|
|
537
|
-
<div className="button__content">
|
|
538
|
-
<WalletIcon size={18} color="info" />
|
|
539
|
-
<Divider size={4} direction="horizontal" />
|
|
540
|
-
<Typography
|
|
541
|
-
variant="label"
|
|
542
|
-
size="medium"
|
|
543
|
-
color={
|
|
544
|
-
showCustomDestination
|
|
545
|
-
? '$neutral600'
|
|
546
|
-
: undefined
|
|
547
|
-
}>
|
|
548
|
-
{i18n.t('Send to a different address')}
|
|
549
|
-
</Typography>
|
|
550
|
-
</div>
|
|
551
|
-
<ExpandedIcon
|
|
552
|
-
orientation={
|
|
553
|
-
showCustomDestination ? 'up' : 'down'
|
|
554
|
-
}>
|
|
555
|
-
<ChevronDownIcon size={10} color="secondary" />
|
|
556
|
-
</ExpandedIcon>
|
|
557
|
-
</CustomDestinationButton>
|
|
558
|
-
}
|
|
559
|
-
onClickTrigger={() =>
|
|
560
|
-
setShowCustomDestination((prev) => !prev)
|
|
561
|
-
}>
|
|
562
|
-
<StyledTextField
|
|
563
|
-
ref={customDestinationInputRef}
|
|
564
|
-
style={{
|
|
565
|
-
padding: 0,
|
|
566
|
-
paddingRight: customDestination ? '8px' : '5px',
|
|
567
|
-
}}
|
|
568
|
-
autoFocus
|
|
569
|
-
placeholder={i18n.t(
|
|
570
|
-
'Enter {blockchainName} address',
|
|
571
|
-
{
|
|
572
|
-
blockchainName: getBlockchainDisplayNameFor(
|
|
573
|
-
requiredWallet,
|
|
574
|
-
blockchains
|
|
575
|
-
),
|
|
576
|
-
}
|
|
577
|
-
)}
|
|
578
|
-
value={customDestination || ''}
|
|
579
|
-
suffix={renderCustomDestinationSuffix()}
|
|
580
|
-
onChange={(e) => {
|
|
581
|
-
const value = e.target.value;
|
|
582
|
-
setCustomDestination(value);
|
|
583
|
-
}}
|
|
584
|
-
{...(!customDestination && { autoFocus: true })}
|
|
585
|
-
/>
|
|
586
|
-
</CustomCollapsible>
|
|
587
|
-
|
|
588
|
-
{isAddressMatched && (
|
|
589
|
-
<div className={alarmsStyles()}>
|
|
590
|
-
<Alert
|
|
591
|
-
variant="alarm"
|
|
592
|
-
type="error"
|
|
593
|
-
title={i18n.t({
|
|
594
|
-
values: { destination: customDestination },
|
|
595
|
-
id: "Address {destination} doesn't match the blockchain address pattern.",
|
|
596
|
-
})}
|
|
597
|
-
/>
|
|
598
|
-
</div>
|
|
599
|
-
)}
|
|
600
|
-
</CustomDestination>
|
|
475
|
+
{showCustomDestination && (
|
|
476
|
+
<CustomDestination
|
|
477
|
+
blockchain={lastStepToBlockchain}
|
|
478
|
+
open={isCustomDestinationOpen}
|
|
479
|
+
handleOpenChange={
|
|
480
|
+
handleCustomDestinationCollapsibleOpenChange
|
|
481
|
+
}
|
|
482
|
+
/>
|
|
601
483
|
)}
|
|
602
484
|
</div>
|
|
603
485
|
);
|
|
@@ -260,14 +260,26 @@ export function WalletList(props: PropTypes) {
|
|
|
260
260
|
})
|
|
261
261
|
: conciseAddress;
|
|
262
262
|
|
|
263
|
-
const
|
|
263
|
+
const onSelectableWalletClick = async () => {
|
|
264
264
|
if (wallet.state === WalletState.DISCONNECTED) {
|
|
265
|
-
if (!!wallet.namespaces) {
|
|
266
|
-
|
|
265
|
+
if (!!wallet.namespaces?.length) {
|
|
266
|
+
if (wallet.namespaces.length > 1) {
|
|
267
|
+
handleOpenNamespacesModal(wallet);
|
|
268
|
+
} else if (wallet.needsDerivationPath) {
|
|
269
|
+
setDerivationPathModalState({
|
|
270
|
+
open: true,
|
|
271
|
+
providerType: wallet.type,
|
|
272
|
+
providerImage: wallet.image,
|
|
273
|
+
namespace: wallet.namespaces[0],
|
|
274
|
+
});
|
|
275
|
+
} else {
|
|
276
|
+
void handleClick(wallet.type);
|
|
277
|
+
}
|
|
267
278
|
} else {
|
|
268
279
|
void handleClick(wallet.type);
|
|
269
280
|
}
|
|
270
281
|
} else if (!!wallet.namespaces && !conciseAddress) {
|
|
282
|
+
// wallet is connected on a different namespace
|
|
271
283
|
await disconnectWallet(wallet.type);
|
|
272
284
|
handleOpenNamespacesModal(wallet);
|
|
273
285
|
} else if (couldAddExperimentalChain) {
|
|
@@ -409,7 +421,7 @@ export function WalletList(props: PropTypes) {
|
|
|
409
421
|
<SelectableWallet
|
|
410
422
|
key={wallet.type}
|
|
411
423
|
description={connectedWalletDescription}
|
|
412
|
-
onClick={
|
|
424
|
+
onClick={onSelectableWalletClick}
|
|
413
425
|
selected={isSelected(wallet.type, chain)}
|
|
414
426
|
disabled={!isActiveTab}
|
|
415
427
|
{...wallet}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { darkTheme, styled, TextField } from '@rango-dev/ui';
|
|
2
|
+
|
|
3
|
+
export const Container = styled('div', {
|
|
4
|
+
padding: '$10 $0',
|
|
5
|
+
'& .button__content': {
|
|
6
|
+
display: 'flex',
|
|
7
|
+
alignItems: 'center',
|
|
8
|
+
},
|
|
9
|
+
'& .alarms': { paddingTop: '$5' },
|
|
10
|
+
'& .collapsible_content': {
|
|
11
|
+
backgroundColor: '$neutral100',
|
|
12
|
+
},
|
|
13
|
+
'& .collapsible_root': {
|
|
14
|
+
backgroundColor: '$neutral100',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const StyledTextField = styled(TextField, {
|
|
19
|
+
backgroundColor: '$neutral100',
|
|
20
|
+
padding: '$15',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const CustomDestinationButton = styled('div', {
|
|
24
|
+
width: '100%',
|
|
25
|
+
borderRadius: '$sm',
|
|
26
|
+
display: 'flex',
|
|
27
|
+
padding: '$15',
|
|
28
|
+
justifyContent: 'space-between',
|
|
29
|
+
alignItems: 'center',
|
|
30
|
+
$$color: '$colors$neutral100',
|
|
31
|
+
[`.${darkTheme} &`]: {
|
|
32
|
+
$$color: '$colors$neutral300',
|
|
33
|
+
},
|
|
34
|
+
backgroundColor: '$$color',
|
|
35
|
+
borderBottomRightRadius: '0',
|
|
36
|
+
borderBottomLeftRadius: '0',
|
|
37
|
+
'&:focus-visible': {
|
|
38
|
+
$$background: '$colors$secondary100',
|
|
39
|
+
[`.${darkTheme} &`]: {
|
|
40
|
+
$$background: '$colors$info700',
|
|
41
|
+
},
|
|
42
|
+
backgroundColor: '$$background',
|
|
43
|
+
outline: 0,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import type { PropTypes } from './CustomDestination.types';
|
|
2
|
+
import type { MouseEvent } from 'react';
|
|
3
|
+
|
|
4
|
+
import { i18n } from '@lingui/core';
|
|
5
|
+
import {
|
|
6
|
+
Alert,
|
|
7
|
+
ChevronDownIcon,
|
|
8
|
+
CloseIcon,
|
|
9
|
+
Divider,
|
|
10
|
+
IconButton,
|
|
11
|
+
PasteIcon,
|
|
12
|
+
Typography,
|
|
13
|
+
WalletIcon,
|
|
14
|
+
} from '@rango-dev/ui';
|
|
15
|
+
import React, { useEffect, useRef } from 'react';
|
|
16
|
+
|
|
17
|
+
import { useAppStore } from '../../store/AppStore';
|
|
18
|
+
import { useQuoteStore } from '../../store/quote';
|
|
19
|
+
import { getBlockchainDisplayNameFor } from '../../utils/meta';
|
|
20
|
+
import { isValidAddress } from '../ConfirmWalletsModal/ConfirmWallets.helpers';
|
|
21
|
+
import { CustomCollapsible } from '../CustomCollapsible/CustomCollapsible';
|
|
22
|
+
import { ExpandedIcon } from '../CustomCollapsible/CustomCollapsible.styles';
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
Container,
|
|
26
|
+
CustomDestinationButton,
|
|
27
|
+
StyledTextField,
|
|
28
|
+
} from './CustomDestination.styles';
|
|
29
|
+
|
|
30
|
+
export function CustomDestination(props: PropTypes) {
|
|
31
|
+
const { blockchain, handleOpenChange, open } = props;
|
|
32
|
+
|
|
33
|
+
const { customDestination, setCustomDestination } = useQuoteStore();
|
|
34
|
+
const { config } = useAppStore();
|
|
35
|
+
const blockchains = useAppStore().blockchains();
|
|
36
|
+
const blockchainName = getBlockchainDisplayNameFor(
|
|
37
|
+
blockchain.name,
|
|
38
|
+
blockchains
|
|
39
|
+
);
|
|
40
|
+
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
41
|
+
const configDestination =
|
|
42
|
+
config?.defaultCustomDestinations?.[blockchain.name];
|
|
43
|
+
|
|
44
|
+
const isFirefox = navigator?.userAgent.includes('Firefox');
|
|
45
|
+
const isAddressChecked = open && !!customDestination && blockchain;
|
|
46
|
+
const isAddressInvalid =
|
|
47
|
+
isAddressChecked && !isValidAddress(blockchain, customDestination);
|
|
48
|
+
const handleClear = () => {
|
|
49
|
+
setCustomDestination('');
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const handlePaste = async (event: MouseEvent<HTMLButtonElement>) => {
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
if (navigator.clipboard !== undefined) {
|
|
55
|
+
const pastedText = await navigator.clipboard.readText();
|
|
56
|
+
setCustomDestination(pastedText);
|
|
57
|
+
inputRef?.current?.focus();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const renderSuffix = () => {
|
|
62
|
+
if (customDestination) {
|
|
63
|
+
return (
|
|
64
|
+
<IconButton onClick={handleClear} variant="ghost">
|
|
65
|
+
<CloseIcon size={12} color="gray" />
|
|
66
|
+
</IconButton>
|
|
67
|
+
);
|
|
68
|
+
} else if (!isFirefox) {
|
|
69
|
+
return (
|
|
70
|
+
<IconButton onClick={handlePaste} variant="ghost">
|
|
71
|
+
<PasteIcon size={16} />
|
|
72
|
+
</IconButton>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return null;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const shouldUseConfigDestination =
|
|
81
|
+
!!configDestination && customDestination === null;
|
|
82
|
+
|
|
83
|
+
if (shouldUseConfigDestination) {
|
|
84
|
+
setCustomDestination(configDestination);
|
|
85
|
+
handleOpenChange(true);
|
|
86
|
+
}
|
|
87
|
+
}, [configDestination]);
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<Container>
|
|
91
|
+
<CustomCollapsible
|
|
92
|
+
onOpenChange={handleOpenChange}
|
|
93
|
+
hasSelected
|
|
94
|
+
open={open}
|
|
95
|
+
triggerAnchor="top"
|
|
96
|
+
trigger={
|
|
97
|
+
<CustomDestinationButton>
|
|
98
|
+
<div className="button__content">
|
|
99
|
+
<WalletIcon size={18} color="info" />
|
|
100
|
+
<Divider size={4} direction="horizontal" />
|
|
101
|
+
<Typography
|
|
102
|
+
variant="label"
|
|
103
|
+
size="medium"
|
|
104
|
+
color={open ? '$neutral600' : undefined}>
|
|
105
|
+
{i18n.t('Send to a different address')}
|
|
106
|
+
</Typography>
|
|
107
|
+
</div>
|
|
108
|
+
<ExpandedIcon orientation={open ? 'up' : 'down'}>
|
|
109
|
+
<ChevronDownIcon size={10} color="secondary" />
|
|
110
|
+
</ExpandedIcon>
|
|
111
|
+
</CustomDestinationButton>
|
|
112
|
+
}
|
|
113
|
+
onClickTrigger={() => handleOpenChange(!open)}>
|
|
114
|
+
<StyledTextField
|
|
115
|
+
ref={inputRef}
|
|
116
|
+
style={{
|
|
117
|
+
padding: 0,
|
|
118
|
+
paddingRight: customDestination ? '8px' : '5px',
|
|
119
|
+
}}
|
|
120
|
+
autoFocus={!customDestination}
|
|
121
|
+
placeholder={i18n.t('Enter {blockchainName} address', {
|
|
122
|
+
blockchainName,
|
|
123
|
+
})}
|
|
124
|
+
value={customDestination || ''}
|
|
125
|
+
suffix={renderSuffix()}
|
|
126
|
+
onChange={(e) => {
|
|
127
|
+
const customDestination = e.target.value;
|
|
128
|
+
setCustomDestination(customDestination);
|
|
129
|
+
}}
|
|
130
|
+
/>
|
|
131
|
+
</CustomCollapsible>
|
|
132
|
+
|
|
133
|
+
{isAddressInvalid && (
|
|
134
|
+
<>
|
|
135
|
+
<Divider size={4} />
|
|
136
|
+
<Alert
|
|
137
|
+
variant="alarm"
|
|
138
|
+
type="error"
|
|
139
|
+
title={i18n.t({
|
|
140
|
+
values: { destination: customDestination },
|
|
141
|
+
id: "Address {destination} doesn't match the blockchain address pattern.",
|
|
142
|
+
})}
|
|
143
|
+
/>
|
|
144
|
+
</>
|
|
145
|
+
)}
|
|
146
|
+
</Container>
|
|
147
|
+
);
|
|
148
|
+
}
|