@rango-dev/widget-embedded 0.43.0 → 0.43.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.
Files changed (173) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +2 -5
  3. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts.map +1 -1
  4. package/dist/components/ConfirmWalletsModal/WalletList.d.ts.map +1 -1
  5. package/dist/components/NoResult/NoResult.d.ts.map +1 -1
  6. package/dist/components/NoResult/NoResult.types.d.ts +1 -0
  7. package/dist/components/NoResult/NoResult.types.d.ts.map +1 -1
  8. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.d.ts.map +1 -1
  9. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.d.ts +5 -3
  10. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.d.ts.map +1 -1
  11. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts +440 -0
  12. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts.map +1 -1
  13. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.d.ts +2 -0
  14. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.d.ts.map +1 -1
  15. package/dist/components/QuoteWarningsAndErrors/SlippageWariningModal.d.ts.map +1 -1
  16. package/dist/components/Slippage/Slippage.d.ts.map +1 -1
  17. package/dist/components/Slippage/Slippage.styles.d.ts +162 -0
  18. package/dist/components/Slippage/Slippage.styles.d.ts.map +1 -1
  19. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.d.ts +4 -0
  20. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.d.ts.map +1 -0
  21. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.helpers.d.ts +8 -0
  22. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.helpers.d.ts.map +1 -0
  23. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.types.d.ts +4 -0
  24. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.types.d.ts.map +1 -0
  25. package/dist/components/StatefulConnectModal/StatefulConnectModal.d.ts.map +1 -1
  26. package/dist/components/StatefulConnectModal/helpers.d.ts +3 -0
  27. package/dist/components/StatefulConnectModal/helpers.d.ts.map +1 -1
  28. package/dist/components/StatefulConnectModal/index.d.ts +1 -1
  29. package/dist/components/StatefulConnectModal/index.d.ts.map +1 -1
  30. package/dist/components/SwapMetrics/SwapMetrics.constants.d.ts +5 -0
  31. package/dist/components/SwapMetrics/SwapMetrics.constants.d.ts.map +1 -0
  32. package/dist/components/SwapMetrics/SwapMetrics.d.ts +4 -0
  33. package/dist/components/SwapMetrics/SwapMetrics.d.ts.map +1 -0
  34. package/dist/components/SwapMetrics/SwapMetrics.helpers.d.ts +11 -0
  35. package/dist/components/SwapMetrics/SwapMetrics.helpers.d.ts.map +1 -0
  36. package/dist/components/SwapMetrics/SwapMetrics.styles.d.ts +482 -0
  37. package/dist/components/SwapMetrics/SwapMetrics.styles.d.ts.map +1 -0
  38. package/dist/components/SwapMetrics/SwapMetrics.types.d.ts +27 -0
  39. package/dist/components/SwapMetrics/SwapMetrics.types.d.ts.map +1 -0
  40. package/dist/components/SwapMetrics/index.d.ts +2 -0
  41. package/dist/components/SwapMetrics/index.d.ts.map +1 -0
  42. package/dist/components/WalletStatefulConnect/Detached.d.ts +4 -0
  43. package/dist/components/WalletStatefulConnect/Detached.d.ts.map +1 -0
  44. package/dist/components/WalletStatefulConnect/Detached.types.d.ts +8 -0
  45. package/dist/components/WalletStatefulConnect/Detached.types.d.ts.map +1 -0
  46. package/dist/components/WalletStatefulConnect/NamespaceDetachedItem.d.ts +4 -0
  47. package/dist/components/WalletStatefulConnect/NamespaceDetachedItem.d.ts.map +1 -0
  48. package/dist/components/WalletStatefulConnect/NamespaceListItem.d.ts.map +1 -1
  49. package/dist/components/WalletStatefulConnect/NamespaceUnsupportedItem.d.ts +4 -0
  50. package/dist/components/WalletStatefulConnect/NamespaceUnsupportedItem.d.ts.map +1 -0
  51. package/dist/components/WalletStatefulConnect/Namespaces.d.ts.map +1 -1
  52. package/dist/components/WalletStatefulConnect/Namespaces.styles.d.ts +805 -3
  53. package/dist/components/WalletStatefulConnect/Namespaces.styles.d.ts.map +1 -1
  54. package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts +11 -8
  55. package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts.map +1 -1
  56. package/dist/components/WalletStatefulConnect/index.d.ts +1 -0
  57. package/dist/components/WalletStatefulConnect/index.d.ts.map +1 -1
  58. package/dist/constants/errors.d.ts.map +1 -1
  59. package/dist/containers/Inputs/Inputs.d.ts.map +1 -1
  60. package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
  61. package/dist/containers/Wallets/Wallets.types.d.ts +5 -3
  62. package/dist/containers/Wallets/Wallets.types.d.ts.map +1 -1
  63. package/dist/containers/Wallets/useUpdates.d.ts +3 -3
  64. package/dist/containers/Wallets/useUpdates.d.ts.map +1 -1
  65. package/dist/hooks/useBootstrap/useBootstrap.d.ts.map +1 -1
  66. package/dist/hooks/useConfirmSwap/useConfirmSwap.helpers.d.ts.map +1 -1
  67. package/dist/hooks/useStatefulConnect/useStatefulConnect.d.ts.map +1 -1
  68. package/dist/hooks/useStatefulConnect/useStatefulConnect.state.d.ts +3 -1
  69. package/dist/hooks/useStatefulConnect/useStatefulConnect.state.d.ts.map +1 -1
  70. package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts +11 -2
  71. package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts.map +1 -1
  72. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.d.ts.map +1 -1
  73. package/dist/hooks/useWalletList.d.ts +2 -2
  74. package/dist/hooks/useWalletList.d.ts.map +1 -1
  75. package/dist/index.d.ts +4 -2
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +2 -2
  78. package/dist/index.js.map +4 -4
  79. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  80. package/dist/pages/Home.d.ts.map +1 -1
  81. package/dist/pages/LiquiditySourcePage.d.ts.map +1 -1
  82. package/dist/pages/WalletsPage.d.ts.map +1 -1
  83. package/dist/store/AppStore.d.ts +2 -0
  84. package/dist/store/AppStore.d.ts.map +1 -1
  85. package/dist/store/app.d.ts +2 -0
  86. package/dist/store/app.d.ts.map +1 -1
  87. package/dist/store/quote.d.ts +2 -0
  88. package/dist/store/quote.d.ts.map +1 -1
  89. package/dist/store/slices/settings.d.ts +3 -0
  90. package/dist/store/slices/settings.d.ts.map +1 -1
  91. package/dist/types/quote.d.ts +1 -0
  92. package/dist/types/quote.d.ts.map +1 -1
  93. package/dist/utils/colors.d.ts.map +1 -1
  94. package/dist/utils/numbers.d.ts +1 -0
  95. package/dist/utils/numbers.d.ts.map +1 -1
  96. package/dist/utils/sanitizers.d.ts +27 -0
  97. package/dist/utils/sanitizers.d.ts.map +1 -0
  98. package/dist/utils/sanitizers.test.d.ts +2 -0
  99. package/dist/utils/sanitizers.test.d.ts.map +1 -0
  100. package/dist/utils/settings.d.ts +2 -1
  101. package/dist/utils/settings.d.ts.map +1 -1
  102. package/dist/utils/validation.d.ts +26 -0
  103. package/dist/utils/validation.d.ts.map +1 -0
  104. package/dist/utils/validation.test.d.ts +2 -0
  105. package/dist/utils/validation.test.d.ts.map +1 -0
  106. package/dist/utils/wallets.d.ts +9 -1
  107. package/dist/utils/wallets.d.ts.map +1 -1
  108. package/dist/widget-embedded.build.json +1 -1
  109. package/package.json +8 -8
  110. package/src/components/ConfirmWalletsModal/ConfirmWallets.styles.ts +4 -47
  111. package/src/components/ConfirmWalletsModal/WalletList.tsx +35 -19
  112. package/src/components/NoResult/NoResult.tsx +4 -1
  113. package/src/components/NoResult/NoResult.types.ts +1 -0
  114. package/src/components/Quote/Quote.tsx +1 -1
  115. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts +29 -4
  116. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.ts +10 -1
  117. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx +38 -7
  118. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.ts +2 -0
  119. package/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx +20 -21
  120. package/src/components/Slippage/Slippage.styles.ts +23 -0
  121. package/src/components/Slippage/Slippage.tsx +28 -22
  122. package/src/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.helpers.ts +33 -0
  123. package/src/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.tsx +48 -0
  124. package/src/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.types.ts +3 -0
  125. package/src/components/StatefulConnectModal/StatefulConnectModal.tsx +19 -1
  126. package/src/components/StatefulConnectModal/helpers.ts +6 -0
  127. package/src/components/StatefulConnectModal/index.ts +1 -1
  128. package/src/components/SwapMetrics/SwapMetrics.constants.ts +4 -0
  129. package/src/components/SwapMetrics/SwapMetrics.helpers.ts +76 -0
  130. package/src/components/SwapMetrics/SwapMetrics.styles.ts +32 -0
  131. package/src/components/SwapMetrics/SwapMetrics.tsx +134 -0
  132. package/src/components/SwapMetrics/SwapMetrics.types.ts +26 -0
  133. package/src/components/SwapMetrics/index.ts +1 -0
  134. package/src/components/WalletStatefulConnect/Detached.tsx +53 -0
  135. package/src/components/WalletStatefulConnect/Detached.types.ts +8 -0
  136. package/src/components/WalletStatefulConnect/NamespaceDetachedItem.tsx +177 -0
  137. package/src/components/WalletStatefulConnect/NamespaceListItem.tsx +14 -33
  138. package/src/components/WalletStatefulConnect/NamespaceUnsupportedItem.tsx +42 -0
  139. package/src/components/WalletStatefulConnect/Namespaces.styles.ts +44 -6
  140. package/src/components/WalletStatefulConnect/Namespaces.tsx +12 -7
  141. package/src/components/WalletStatefulConnect/Namespaces.types.tsx +13 -11
  142. package/src/components/WalletStatefulConnect/index.ts +1 -0
  143. package/src/constants/errors.ts +6 -7
  144. package/src/containers/Inputs/Inputs.tsx +2 -0
  145. package/src/containers/Wallets/Wallets.tsx +6 -5
  146. package/src/containers/Wallets/Wallets.types.ts +5 -3
  147. package/src/containers/Wallets/useUpdates.ts +40 -32
  148. package/src/hooks/useBootstrap/useBootstrap.ts +33 -10
  149. package/src/hooks/useConfirmSwap/useConfirmSwap.helpers.ts +1 -0
  150. package/src/hooks/useConfirmSwap/useConfirmSwap.ts +1 -1
  151. package/src/hooks/useStatefulConnect/useStatefulConnect.state.ts +11 -1
  152. package/src/hooks/useStatefulConnect/useStatefulConnect.ts +33 -4
  153. package/src/hooks/useStatefulConnect/useStatefulConnect.types.ts +13 -1
  154. package/src/hooks/useSwapInput.ts +1 -1
  155. package/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.ts +2 -0
  156. package/src/hooks/useWalletList.ts +3 -3
  157. package/src/index.ts +8 -1
  158. package/src/pages/ConfirmSwapPage.tsx +6 -1
  159. package/src/pages/Home.tsx +61 -12
  160. package/src/pages/LiquiditySourcePage.tsx +5 -3
  161. package/src/pages/WalletsPage.tsx +17 -1
  162. package/src/store/app.ts +1 -0
  163. package/src/store/quote.ts +23 -4
  164. package/src/store/slices/settings.ts +11 -0
  165. package/src/types/quote.ts +4 -1
  166. package/src/utils/colors.ts +3 -10
  167. package/src/utils/numbers.ts +11 -0
  168. package/src/utils/sanitizers.test.ts +122 -0
  169. package/src/utils/sanitizers.ts +41 -0
  170. package/src/utils/settings.ts +11 -4
  171. package/src/utils/validation.test.ts +121 -0
  172. package/src/utils/validation.ts +45 -0
  173. package/src/utils/wallets.ts +59 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.43.0",
3
+ "version": "0.43.1-next.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "source": "./src/index.ts",
@@ -25,15 +25,15 @@
25
25
  "@lingui/core": "4.2.1",
26
26
  "@lingui/react": "4.2.1",
27
27
  "@rango-dev/logging-core": "^0.8.0",
28
- "@rango-dev/provider-all": "^0.46.0",
28
+ "@rango-dev/provider-all": "^0.46.1-next.0",
29
29
  "@rango-dev/queue-manager-core": "^0.29.0",
30
- "@rango-dev/queue-manager-rango-preset": "^0.45.1",
30
+ "@rango-dev/queue-manager-rango-preset": "^0.45.2-next.7",
31
31
  "@rango-dev/queue-manager-react": "^0.29.0",
32
- "@rango-dev/signer-solana": "^0.39.0",
33
- "@rango-dev/ui": "^0.46.1",
34
- "@rango-dev/wallets-core": "^0.43.0",
35
- "@rango-dev/wallets-react": "^0.30.1",
36
- "@rango-dev/wallets-shared": "^0.44.1",
32
+ "@rango-dev/signer-solana": "^0.39.1-next.3",
33
+ "@rango-dev/ui": "^0.46.2-next.9",
34
+ "@rango-dev/wallets-core": "^0.43.1-next.6",
35
+ "@rango-dev/wallets-react": "^0.30.2-next.8",
36
+ "@rango-dev/wallets-shared": "^0.44.2-next.7",
37
37
  "bignumber.js": "^9.1.1",
38
38
  "copy-to-clipboard": "^3.3.3",
39
39
  "dayjs": "^1.11.7",
@@ -1,4 +1,4 @@
1
- import { css, darkTheme, IconButton, styled } from '@rango-dev/ui';
1
+ import { css, IconButton, SelectableWalletButton, styled } from '@rango-dev/ui';
2
2
 
3
3
  export const Title = styled('div', {
4
4
  display: 'flex',
@@ -11,58 +11,15 @@ export const ListContainer = styled('div', {
11
11
  display: 'flex',
12
12
  justifyContent: 'space-evenly',
13
13
  alignItems: 'center',
14
- gap: '$10',
14
+ columnGap: '$5',
15
+ rowGap: '$10',
15
16
  flexWrap: 'wrap',
16
17
  paddingTop: '$5',
17
18
  height: '100%',
18
19
  });
19
20
 
20
- export const WalletButton = styled('button', {
21
- borderRadius: '$xm',
22
- padding: '$10',
23
- border: '0',
24
- display: 'flex',
21
+ export const ShowMoreWallets = styled(SelectableWalletButton, {
25
22
  justifyContent: 'center',
26
- $$color: '$colors$neutral100',
27
- [`.${darkTheme} &`]: {
28
- $$color: '$colors$neutral300',
29
- },
30
- backgroundColor: '$$color',
31
- alignItems: 'center',
32
- cursor: 'pointer',
33
- width: 110,
34
- position: 'relative',
35
-
36
- '&:hover': {
37
- $$color: '$colors$secondary100',
38
- [`.${darkTheme} &`]: {
39
- $$color: '$colors$neutral100',
40
- },
41
- backgroundColor: '$$color',
42
- },
43
-
44
- '&:focus-visible': {
45
- $$color: '$colors$secondary100',
46
- [`.${darkTheme} &`]: {
47
- $$color: '$colors$info700',
48
- },
49
- backgroundColor: '$$color',
50
- outline: 0,
51
- },
52
- variants: {
53
- selected: {
54
- true: {
55
- outlineWidth: 1,
56
- outlineColor: '$secondary',
57
- outlineStyle: 'solid',
58
- },
59
- },
60
- },
61
- });
62
-
63
- export const ShowMoreWallets = styled(WalletButton, {
64
- alignSelf: 'stretch',
65
- minHeight: '93px',
66
23
  });
67
24
  export const ShowMoreHeader = styled('div', {
68
25
  padding: '$20 $20 $15 $20',
@@ -6,6 +6,7 @@ import { i18n } from '@lingui/core';
6
6
  import { warn } from '@rango-dev/logging-core';
7
7
  import {
8
8
  Divider,
9
+ makeInfo,
9
10
  SelectableWallet,
10
11
  Typography,
11
12
  WalletState,
@@ -14,7 +15,6 @@ import React, { useEffect, useState } from 'react';
14
15
 
15
16
  import { useWallets } from '../..';
16
17
  import { WIDGET_UI_ID } from '../../constants';
17
- import { useStatefulConnect } from '../../hooks/useStatefulConnect';
18
18
  import { useWalletList } from '../../hooks/useWalletList';
19
19
  import { useAppStore } from '../../store/AppStore';
20
20
  import { useUiStore } from '../../store/ui';
@@ -49,7 +49,6 @@ export function WalletList(props: PropTypes) {
49
49
  const [addingExperimentalChainStatus, setAddingExperimentalChainStatus] =
50
50
  useState<'in-progress' | 'completed' | 'rejected' | null>(null);
51
51
  const { suggestAndConnect } = useWallets();
52
- const { handleDisconnect } = useStatefulConnect();
53
52
  const { list } = useWalletList({
54
53
  chain,
55
54
  });
@@ -119,9 +118,14 @@ export function WalletList(props: PropTypes) {
119
118
  walletType: wallet.type,
120
119
  chain,
121
120
  });
121
+ const isConnected = wallet.state === WalletState.CONNECTED;
122
122
  const conciseAddress = address
123
123
  ? getConciseAddress(address, ACCOUNT_ADDRESS_MAX_CHARACTERS)
124
124
  : '';
125
+ const isConnectedButDifferentThanTargetNamespace =
126
+ isConnected && wallet.isHub
127
+ ? !conciseAddress
128
+ : !!wallet.needsNamespace && !conciseAddress;
125
129
 
126
130
  const experimentalChain = isExperimentalChain(blockchains(), chain);
127
131
 
@@ -136,25 +140,10 @@ export function WalletList(props: PropTypes) {
136
140
  experimentalChainNotAdded &&
137
141
  wallet.state === WalletState.CONNECTED;
138
142
 
139
- const connectedWalletDescription = couldAddExperimentalChain
140
- ? i18n.t({
141
- id: 'Add {chain} chain',
142
- values: { chain },
143
- })
144
- : conciseAddress;
145
-
146
143
  const onSelectableWalletClick = async () => {
147
144
  const isDisconnected = wallet.state === WalletState.DISCONNECTED;
148
- const isConnectedButDifferentThanTargetNamespace = wallet.isHub
149
- ? !conciseAddress
150
- : !!wallet.needsNamespace && !conciseAddress;
151
-
152
- if (isDisconnected) {
153
- setSelectedWalletToConnect(wallet);
154
- } else if (isConnectedButDifferentThanTargetNamespace) {
155
- // wallet is connected on a different namespace
156
- await handleDisconnect(wallet.type);
157
145
 
146
+ if (isDisconnected || isConnectedButDifferentThanTargetNamespace) {
158
147
  setSelectedWalletToConnect(wallet);
159
148
  } else if (couldAddExperimentalChain) {
160
149
  setExperimentalChainWallet({
@@ -172,6 +161,32 @@ export function WalletList(props: PropTypes) {
172
161
  }
173
162
  };
174
163
 
164
+ const info = makeInfo(wallet.state);
165
+
166
+ const getWalletDescription = () => {
167
+ if (couldAddExperimentalChain) {
168
+ return i18n.t({
169
+ id: 'Add {chain} chain',
170
+ values: { chain },
171
+ });
172
+ } else if (isConnectedButDifferentThanTargetNamespace) {
173
+ return i18n.t('Chain not connected');
174
+ } else if (conciseAddress) {
175
+ return conciseAddress;
176
+ }
177
+ return info.description;
178
+ };
179
+
180
+ const getWalletDescriptionColor = () => {
181
+ if (wallet.state === WalletState.CONNECTED) {
182
+ if (isConnectedButDifferentThanTargetNamespace) {
183
+ return 'neutral600';
184
+ }
185
+ return 'neutral700';
186
+ }
187
+ return info.color;
188
+ };
189
+
175
190
  const blockchainDisplayName: string | undefined =
176
191
  experimentalChainWallet?.chain
177
192
  ? getBlockchainDisplayNameFor(
@@ -211,7 +226,8 @@ export function WalletList(props: PropTypes) {
211
226
  )}
212
227
  <SelectableWallet
213
228
  key={wallet.type}
214
- description={connectedWalletDescription}
229
+ description={getWalletDescription()}
230
+ descriptionColor={getWalletDescriptionColor()}
215
231
  onClick={onSelectableWalletClick}
216
232
  selected={isSelected(wallet.type, chain)}
217
233
  disabled={!isActiveTab}
@@ -26,7 +26,7 @@ import {
26
26
  } from './NoResult.styles';
27
27
 
28
28
  export function NoResult(props: PropTypes) {
29
- const { fetch, error, size = 'small' } = props;
29
+ const { fetch, error, size = 'small', skipAlerts } = props;
30
30
  const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources();
31
31
  const toggleAllLiquiditySources = useAppStore().toggleAllLiquiditySources;
32
32
 
@@ -37,6 +37,9 @@ export function NoResult(props: PropTypes) {
37
37
  () => toggleAllLiquiditySources(swappers, true),
38
38
  fetch
39
39
  );
40
+ if (skipAlerts) {
41
+ info.alert = null;
42
+ }
40
43
 
41
44
  return (
42
45
  <Container>
@@ -4,6 +4,7 @@ export interface PropTypes {
4
4
  fetch: () => void;
5
5
  error: NoResultError | QuoteRequestFailed | null;
6
6
  size?: 'small' | 'large';
7
+ skipAlerts?: boolean;
7
8
  }
8
9
 
9
10
  type AlertAction = {
@@ -263,7 +263,7 @@ export function Quote(props: QuoteProps) {
263
263
  variant="body"
264
264
  color="neutral900">
265
265
  {i18n.t({
266
- id: 'Minimum required slippage: {minRequiredSlippage}',
266
+ id: 'Minimum suggested slippage: {minRequiredSlippage}',
267
267
  values: {
268
268
  ...(error?.type ===
269
269
  QuoteErrorType.INSUFFICIENT_SLIPPAGE && {
@@ -10,10 +10,17 @@ import { errorMessages } from '../../constants/errors';
10
10
  import { QuoteErrorType, QuoteWarningType } from '../../types';
11
11
  import { getPriceImpactLevel } from '../../utils/quote';
12
12
 
13
- type AlertInfo = {
13
+ export type ActionType =
14
+ | 'show-info'
15
+ | 'change-settings'
16
+ | 'change-slippage'
17
+ | null;
18
+
19
+ export type AlertInfo = {
14
20
  alertType: 'error' | 'warning';
15
21
  title: string;
16
- action: 'show-info' | 'change-settings' | null;
22
+ action: ActionType;
23
+ actionButtonTitle: string | null;
17
24
  };
18
25
 
19
26
  export function makeAlerts(
@@ -24,7 +31,9 @@ export function makeAlerts(
24
31
  alertType: 'warning',
25
32
  title: '',
26
33
  action: null,
34
+ actionButtonTitle: null,
27
35
  };
36
+
28
37
  if (error) {
29
38
  alertInfo.alertType = 'error';
30
39
  if (error.type === QuoteErrorType.BRIDGE_LIMIT) {
@@ -38,7 +47,8 @@ export function makeAlerts(
38
47
  minRequiredSlippage: error.minRequiredSlippage,
39
48
  },
40
49
  });
41
- alertInfo.action = 'change-settings';
50
+ alertInfo.action = 'change-slippage';
51
+ alertInfo.actionButtonTitle = i18n.t('Increase');
42
52
  }
43
53
 
44
54
  return alertInfo;
@@ -75,7 +85,9 @@ export function makeAlerts(
75
85
  minRequiredSlippage: warning.minRequiredSlippage,
76
86
  },
77
87
  });
78
- alertInfo.action = 'change-settings';
88
+ alertInfo.action = 'change-slippage';
89
+ alertInfo.actionButtonTitle = i18n.t('Increase');
90
+
79
91
  break;
80
92
  }
81
93
  case QuoteWarningType.HIGH_SLIPPAGE: {
@@ -92,3 +104,16 @@ export function makeAlerts(
92
104
  }
93
105
  return null;
94
106
  }
107
+
108
+ export function getRequiredSlippage(
109
+ warning: QuoteWarning | null,
110
+ error: BridgeLimitError | InsufficientSlippageError | null
111
+ ) {
112
+ if (error?.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE) {
113
+ return Number(error.minRequiredSlippage);
114
+ }
115
+ if (warning?.type === QuoteWarningType.INSUFFICIENT_SLIPPAGE) {
116
+ return Number(warning.minRequiredSlippage);
117
+ }
118
+ return null;
119
+ }
@@ -1,4 +1,4 @@
1
- import { darkTheme, styled } from '@rango-dev/ui';
1
+ import { Button, darkTheme, styled } from '@rango-dev/ui';
2
2
 
3
3
  export const Alerts = styled('div', {
4
4
  width: '100%',
@@ -32,3 +32,12 @@ export const Action = styled('div', {
32
32
  alignSelf: 'flex-start',
33
33
  cursor: 'pointer',
34
34
  });
35
+
36
+ export const SwapButton = styled(Button, {
37
+ '& ._text': {
38
+ gap: '$5',
39
+ display: 'flex',
40
+ alignItems: 'center',
41
+ justifyContent: 'center',
42
+ },
43
+ });
@@ -1,14 +1,18 @@
1
+ import type { ActionType } from './QuoteWarningsAndErrors.helpers';
1
2
  import type { PropTypes } from './QuoteWarningsAndErrors.types';
2
3
 
3
4
  import { i18n } from '@lingui/core';
4
- import { Alert, Button, InfoIcon } from '@rango-dev/ui';
5
+ import { Alert, Button, Divider, InfoIcon } from '@rango-dev/ui';
5
6
  import React from 'react';
6
7
 
7
8
  import { QuoteErrorType, QuoteWarningType } from '../../types';
8
9
  import { NoResult } from '../NoResult';
9
10
 
10
11
  import { HighValueLossWarningModal } from './HighValueLossWarningModal';
11
- import { makeAlerts } from './QuoteWarningsAndErrors.helpers';
12
+ import {
13
+ getRequiredSlippage,
14
+ makeAlerts,
15
+ } from './QuoteWarningsAndErrors.helpers';
12
16
  import { Action, Alerts } from './QuoteWarningsAndErrors.styles';
13
17
  import { SlippageWarningModal } from './SlippageWariningModal';
14
18
  import { UnknownPriceWarningModal } from './UnknownPriceWarningModal';
@@ -20,11 +24,13 @@ export function QuoteWarningsAndErrors(props: PropTypes) {
20
24
  couldChangeSettings,
21
25
  showWarningModal,
22
26
  confirmationDisabled,
27
+ skipAlerts,
23
28
  refetchQuote,
24
29
  onOpenWarningModal,
25
30
  onCloseWarningModal,
26
31
  onConfirmWarningModal,
27
32
  onChangeSettings,
33
+ onChangeSlippage,
28
34
  } = props;
29
35
 
30
36
  const warningModalHandlers = {
@@ -49,14 +55,38 @@ export function QuoteWarningsAndErrors(props: PropTypes) {
49
55
  alertInfo.action = null;
50
56
  }
51
57
 
52
- const showAlerts = !!alertInfo;
58
+ const showAlerts = !!alertInfo && !skipAlerts;
59
+
60
+ const onclickActionButton = (action: ActionType) => {
61
+ if (action === 'change-slippage') {
62
+ const quoteError =
63
+ error?.type === QuoteErrorType.BRIDGE_LIMIT ||
64
+ error?.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE
65
+ ? error
66
+ : null;
67
+ const requestedSlippage = getRequiredSlippage(warning, quoteError);
68
+ onChangeSlippage?.(requestedSlippage);
69
+ } else if (action === 'change-settings') {
70
+ onChangeSettings();
71
+ }
72
+ };
53
73
 
54
74
  return (
55
75
  <>
56
- {showNoResultMessage && <NoResult error={error} fetch={refetchQuote} />}
76
+ {showNoResultMessage && (
77
+ <>
78
+ <Divider size={10} />
79
+ <NoResult
80
+ skipAlerts={skipAlerts}
81
+ error={error}
82
+ fetch={refetchQuote}
83
+ />
84
+ </>
85
+ )}
57
86
 
58
87
  {showAlerts && (
59
88
  <Alerts>
89
+ <Divider size={10} />
60
90
  <Alert
61
91
  title={alertInfo.title}
62
92
  type={alertInfo.alertType}
@@ -68,14 +98,15 @@ export function QuoteWarningsAndErrors(props: PropTypes) {
68
98
  </Action>
69
99
  ),
70
100
  })}
71
- {...(alertInfo.action === 'change-settings' && {
101
+ {...((alertInfo.action === 'change-settings' ||
102
+ alertInfo.action === 'change-slippage') && {
72
103
  action: (
73
104
  <Button
74
105
  id="widget-quote-warning-error-change-settings-btn"
75
106
  size="xxsmall"
76
107
  type={alertInfo.alertType}
77
- onClick={onChangeSettings}>
78
- {i18n.t('Change')}
108
+ onClick={() => onclickActionButton(alertInfo.action)}>
109
+ {alertInfo.actionButtonTitle || i18n.t('Change')}
79
110
  </Button>
80
111
  ),
81
112
  })}
@@ -6,11 +6,13 @@ export interface PropTypes {
6
6
  showWarningModal: boolean;
7
7
  confirmationDisabled: boolean;
8
8
  couldChangeSettings: boolean;
9
+ skipAlerts?: boolean;
9
10
  refetchQuote: () => void;
10
11
  onOpenWarningModal: () => void;
11
12
  onCloseWarningModal: () => void;
12
13
  onConfirmWarningModal: () => void;
13
14
  onChangeSettings: () => void;
15
+ onChangeSlippage?: (slippage: number | null) => void;
14
16
  }
15
17
 
16
18
  type ModalPropTypesKeys = keyof Omit<PropTypes, 'extraSpace' | 'loading'>;
@@ -4,16 +4,17 @@ import type {
4
4
  } from '../../types';
5
5
 
6
6
  import { i18n } from '@lingui/core';
7
- import { Button, Divider, MessageBox, Typography } from '@rango-dev/ui';
7
+ import { Button, Divider, MessageBox, WarningIcon } from '@rango-dev/ui';
8
8
  import React from 'react';
9
9
  import { useNavigate } from 'react-router-dom';
10
10
 
11
11
  import { navigationRoutes } from '../../constants/navigationRoutes';
12
- import { useAppStore } from '../../store/AppStore';
13
12
  import { QuoteWarningType } from '../../types';
14
13
  import { getContainer } from '../../utils/common';
15
14
  import { WatermarkedModal } from '../common/WatermarkedModal';
16
15
 
16
+ import { SwapButton } from './QuoteWarningsAndErrors.styles';
17
+
17
18
  type PropsTypes = {
18
19
  open: boolean;
19
20
  confirmationDisabled: boolean;
@@ -23,26 +24,13 @@ type PropsTypes = {
23
24
  };
24
25
 
25
26
  export function SlippageWarningModal(props: PropsTypes) {
26
- const { customSlippage, slippage } = useAppStore();
27
27
  const { open, onClose, onConfirm, warning, confirmationDisabled } = props;
28
28
  const navigate = useNavigate();
29
- const userSlippage = customSlippage ?? slippage;
30
29
 
31
30
  return (
32
31
  <WatermarkedModal
33
32
  anchor="bottom"
34
33
  open={open}
35
- prefix={
36
- <Button
37
- size="small"
38
- id="widget-slippage-warning-modal-change-settings-btn"
39
- variant="ghost"
40
- onClick={() => navigate('../' + navigationRoutes.settings)}>
41
- <Typography variant="label" size="medium" color="$neutral900">
42
- {i18n.t('Change settings')}
43
- </Typography>
44
- </Button>
45
- }
46
34
  container={getContainer()}
47
35
  onClose={onClose}>
48
36
  <MessageBox
@@ -54,10 +42,9 @@ export function SlippageWarningModal(props: PropsTypes) {
54
42
  }
55
43
  description={
56
44
  warning.type === QuoteWarningType.HIGH_SLIPPAGE
57
- ? i18n.t({
58
- id: ' Caution, your slippage is high (={userSlippage}). Your trade may be front run.',
59
- values: { userSlippage },
60
- })
45
+ ? i18n.t(
46
+ 'Caution, your slippage is high. Your trade may be front run.'
47
+ )
61
48
  : i18n.t({
62
49
  id: 'We recommend you to increase slippage to at least {minRequiredSlippage} for this route.',
63
50
  values: {
@@ -67,7 +54,7 @@ export function SlippageWarningModal(props: PropsTypes) {
67
54
  }>
68
55
  <Divider size={18} />
69
56
  <Divider size={32} />
70
- <Button
57
+ <SwapButton
71
58
  id="widget-slippage-warning-modal-confirm-anyway-btn"
72
59
  size="large"
73
60
  type="primary"
@@ -75,7 +62,19 @@ export function SlippageWarningModal(props: PropsTypes) {
75
62
  fullWidth
76
63
  disabled={confirmationDisabled}
77
64
  onClick={onConfirm}>
78
- {i18n.t('Confirm anyway')}
65
+ <WarningIcon color="white" size={16} />
66
+ {i18n.t('Swap anyway')}
67
+ </SwapButton>
68
+ <Divider size={10} />
69
+ <Button
70
+ id="widget-slippage-warning-modal-change-slippage-btn"
71
+ size="large"
72
+ type="primary"
73
+ variant="outlined"
74
+ fullWidth
75
+ disabled={confirmationDisabled}
76
+ onClick={() => navigate('../' + navigationRoutes.settings)}>
77
+ {i18n.t('Change Slippage')}
79
78
  </Button>
80
79
  </MessageBox>
81
80
  </WatermarkedModal>
@@ -32,3 +32,26 @@ export const SlippageChip = styled(Chip, {
32
32
  width: '61px',
33
33
  flexShrink: 0,
34
34
  });
35
+
36
+ export const SlippageTextFieldContainer = styled('div', {
37
+ borderWidth: 1,
38
+ borderStyle: 'solid',
39
+ borderRadius: '$xs',
40
+ flex: 1,
41
+ variants: {
42
+ status: {
43
+ safe: {
44
+ borderColor: '$secondary500',
45
+ },
46
+ error: {
47
+ borderColor: '$error500',
48
+ },
49
+ warning: {
50
+ borderColor: '$warning500',
51
+ },
52
+ empty: {
53
+ borderWidth: 0,
54
+ },
55
+ },
56
+ },
57
+ });
@@ -14,12 +14,14 @@ import { MAX_SLIPPAGE, SLIPPAGES } from '../../constants/swapSettings';
14
14
  import { useAppStore } from '../../store/AppStore';
15
15
  import { getContainer } from '../../utils/common';
16
16
  import { getSlippageValidation } from '../../utils/settings';
17
+ import { isValidCurrencyFormat } from '../../utils/validation';
17
18
 
18
19
  import {
19
20
  BaseContainer,
20
21
  Head,
21
22
  SlippageChip,
22
23
  SlippageChipsContainer,
24
+ SlippageTextFieldContainer,
23
25
  } from './Slippage.styles';
24
26
  import { SlippageTooltipContent } from './SlippageTooltipContent';
25
27
 
@@ -54,9 +56,8 @@ export function Slippage() {
54
56
 
55
57
  const onInput = (event: React.FormEvent<HTMLInputElement>) => {
56
58
  const input = event.target as HTMLInputElement;
57
- const regex = /^(0|[1-9]\d*)(\.\d{1,2})?$/;
58
59
  const value = input.value;
59
- if (!regex.test(value)) {
60
+ if (!isValidCurrencyFormat(value)) {
60
61
  input.value = value.slice(0, -1);
61
62
  }
62
63
  };
@@ -90,26 +91,31 @@ export function Slippage() {
90
91
  />
91
92
  );
92
93
  })}
93
- <TextField
94
- type="number"
95
- min="0.01"
96
- max="30"
97
- step="0.01"
98
- onInput={onInput}
99
- fullWidth
100
- variant="contained"
101
- value={customSlippage === null ? '' : customSlippage}
102
- color="dark"
103
- onChange={onSlippageValueChange}
104
- suffix={
105
- customSlippage && (
106
- <Typography variant="body" size="small">
107
- %
108
- </Typography>
109
- )
110
- }
111
- placeholder={i18n.t('Custom')}
112
- />
94
+ <SlippageTextFieldContainer
95
+ status={
96
+ slippageValidation?.type || (customSlippage ? 'safe' : 'empty')
97
+ }>
98
+ <TextField
99
+ type="number"
100
+ min="0.01"
101
+ max="30"
102
+ step="0.01"
103
+ onInput={onInput}
104
+ fullWidth
105
+ variant="contained"
106
+ value={customSlippage === null ? '' : customSlippage}
107
+ color="dark"
108
+ onChange={onSlippageValueChange}
109
+ suffix={
110
+ customSlippage && (
111
+ <Typography variant="body" size="small">
112
+ %
113
+ </Typography>
114
+ )
115
+ }
116
+ placeholder={i18n.t('Custom')}
117
+ />
118
+ </SlippageTextFieldContainer>
113
119
  </SlippageChipsContainer>
114
120
 
115
121
  {slippageValidation && (
@@ -0,0 +1,33 @@
1
+ import type { AlertInfo } from '../QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers';
2
+
3
+ import { i18n } from '@lingui/core';
4
+
5
+ import { HIGH_SLIPPAGE, MIN_SLIPPAGE } from '../../constants/swapSettings';
6
+
7
+ export type ActionType = AlertInfo['action'] | 'reset-slippage';
8
+
9
+ type Alert = Omit<AlertInfo, 'action'> & {
10
+ action: ActionType;
11
+ };
12
+
13
+ export function makeAlerts(slippage: number): Alert | null {
14
+ let alertInfo: Alert | null = null;
15
+ if (slippage === MIN_SLIPPAGE) {
16
+ alertInfo = {
17
+ alertType: 'error',
18
+ action: 'reset-slippage',
19
+ actionButtonTitle: i18n.t('Reset'),
20
+ title: i18n.t('Slippage cannot be set lower than 0.01%.'),
21
+ };
22
+ return alertInfo;
23
+ } else if (slippage > HIGH_SLIPPAGE) {
24
+ alertInfo = {
25
+ alertType: 'warning',
26
+ action: 'change-settings',
27
+ actionButtonTitle: i18n.t('Change'),
28
+ title: i18n.t('Caution, your slippage is high!'),
29
+ };
30
+ return alertInfo;
31
+ }
32
+ return null;
33
+ }