@rango-dev/widget-embedded 0.41.2-next.10 → 0.41.2-next.12
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/dist/components/Quote/Quote.styles.d.ts +2 -2
- package/dist/components/Slippage/Slippage.d.ts.map +1 -1
- package/dist/constants/swapSettings.d.ts +2 -2
- package/dist/constants/swapSettings.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +4 -4
- package/dist/store/slices/settings.d.ts.map +1 -1
- package/dist/utils/settings.d.ts +4 -0
- package/dist/utils/settings.d.ts.map +1 -1
- package/dist/utils/swap.d.ts +2 -1
- package/dist/utils/swap.d.ts.map +1 -1
- package/dist/widget-embedded.build.json +1 -1
- package/package.json +2 -2
- package/src/components/Slippage/Slippage.tsx +52 -21
- package/src/components/SwapDetails/SwapDetails.tsx +1 -1
- package/src/constants/swapSettings.ts +2 -2
- package/src/store/slices/settings.ts +0 -2
- package/src/utils/settings.ts +28 -0
- package/src/utils/swap.ts +15 -2
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { i18n } from '@lingui/core';
|
|
2
2
|
import {
|
|
3
|
+
Alert,
|
|
3
4
|
Divider,
|
|
4
5
|
InfoIcon,
|
|
5
6
|
SlippageIcon,
|
|
@@ -9,13 +10,10 @@ import {
|
|
|
9
10
|
} from '@rango-dev/ui';
|
|
10
11
|
import React from 'react';
|
|
11
12
|
|
|
12
|
-
import {
|
|
13
|
-
MAX_SLIPPAGE,
|
|
14
|
-
MIN_SLIPPGAE,
|
|
15
|
-
SLIPPAGES,
|
|
16
|
-
} from '../../constants/swapSettings';
|
|
13
|
+
import { MAX_SLIPPAGE, SLIPPAGES } from '../../constants/swapSettings';
|
|
17
14
|
import { useAppStore } from '../../store/AppStore';
|
|
18
15
|
import { getContainer } from '../../utils/common';
|
|
16
|
+
import { getSlippageValidation } from '../../utils/settings';
|
|
19
17
|
|
|
20
18
|
import {
|
|
21
19
|
BaseContainer,
|
|
@@ -29,6 +27,40 @@ export function Slippage() {
|
|
|
29
27
|
const { slippage, setSlippage, customSlippage, setCustomSlippage } =
|
|
30
28
|
useAppStore();
|
|
31
29
|
|
|
30
|
+
const slippageValidation =
|
|
31
|
+
customSlippage !== null ? getSlippageValidation(customSlippage) : null;
|
|
32
|
+
|
|
33
|
+
const onSlippageValueChange = (
|
|
34
|
+
event: React.ChangeEvent<HTMLInputElement>
|
|
35
|
+
) => {
|
|
36
|
+
const value = event.target.value;
|
|
37
|
+
const parsedValue = parseFloat(value);
|
|
38
|
+
if (isNaN(parsedValue)) {
|
|
39
|
+
return setCustomSlippage(null);
|
|
40
|
+
}
|
|
41
|
+
let slippage = parsedValue;
|
|
42
|
+
if (parsedValue > MAX_SLIPPAGE) {
|
|
43
|
+
slippage = MAX_SLIPPAGE;
|
|
44
|
+
}
|
|
45
|
+
setCustomSlippage(slippage);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const onClickSlippageChip = (slippageItem: number) => {
|
|
49
|
+
if (customSlippage !== null) {
|
|
50
|
+
setCustomSlippage(null);
|
|
51
|
+
}
|
|
52
|
+
setSlippage(slippageItem);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const onInput = (event: React.FormEvent<HTMLInputElement>) => {
|
|
56
|
+
const input = event.target as HTMLInputElement;
|
|
57
|
+
const regex = /^(0|[1-9]\d*)(\.\d{1,2})?$/;
|
|
58
|
+
const value = input.value;
|
|
59
|
+
if (!regex.test(value)) {
|
|
60
|
+
input.value = value.slice(0, -1);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
32
64
|
return (
|
|
33
65
|
<BaseContainer>
|
|
34
66
|
<Head>
|
|
@@ -52,13 +84,8 @@ export function Slippage() {
|
|
|
52
84
|
return (
|
|
53
85
|
<SlippageChip
|
|
54
86
|
key={key}
|
|
55
|
-
onClick={() =>
|
|
56
|
-
|
|
57
|
-
setCustomSlippage(null);
|
|
58
|
-
}
|
|
59
|
-
setSlippage(slippageItem);
|
|
60
|
-
}}
|
|
61
|
-
selected={!customSlippage && slippageItem === slippage}
|
|
87
|
+
onClick={() => onClickSlippageChip(slippageItem)}
|
|
88
|
+
selected={customSlippage === null && slippageItem === slippage}
|
|
62
89
|
label={`${slippageItem.toString()}%`}
|
|
63
90
|
/>
|
|
64
91
|
);
|
|
@@ -68,19 +95,12 @@ export function Slippage() {
|
|
|
68
95
|
min="0.01"
|
|
69
96
|
max="30"
|
|
70
97
|
step="0.01"
|
|
98
|
+
onInput={onInput}
|
|
71
99
|
fullWidth
|
|
72
100
|
variant="contained"
|
|
73
101
|
value={customSlippage === null ? '' : customSlippage}
|
|
74
102
|
color="dark"
|
|
75
|
-
onChange={
|
|
76
|
-
const value = event.target.value;
|
|
77
|
-
const parsedValue = parseFloat(value);
|
|
78
|
-
if (parsedValue >= MIN_SLIPPGAE && parsedValue <= MAX_SLIPPAGE) {
|
|
79
|
-
setCustomSlippage(parsedValue);
|
|
80
|
-
} else {
|
|
81
|
-
setCustomSlippage(null);
|
|
82
|
-
}
|
|
83
|
-
}}
|
|
103
|
+
onChange={onSlippageValueChange}
|
|
84
104
|
suffix={
|
|
85
105
|
customSlippage && (
|
|
86
106
|
<Typography variant="body" size="small">
|
|
@@ -91,6 +111,17 @@ export function Slippage() {
|
|
|
91
111
|
placeholder={i18n.t('Custom')}
|
|
92
112
|
/>
|
|
93
113
|
</SlippageChipsContainer>
|
|
114
|
+
|
|
115
|
+
{slippageValidation && (
|
|
116
|
+
<>
|
|
117
|
+
<Divider size={10} />
|
|
118
|
+
<Alert
|
|
119
|
+
variant="alarm"
|
|
120
|
+
type={slippageValidation.type}
|
|
121
|
+
title={slippageValidation.message}
|
|
122
|
+
/>
|
|
123
|
+
</>
|
|
124
|
+
)}
|
|
94
125
|
</BaseContainer>
|
|
95
126
|
);
|
|
96
127
|
}
|
|
@@ -171,7 +171,7 @@ export function SwapDetails(props: SwapDetailsProps) {
|
|
|
171
171
|
])
|
|
172
172
|
: undefined;
|
|
173
173
|
|
|
174
|
-
const stepMessage = getSwapMessages(swap, currentStep);
|
|
174
|
+
const stepMessage = getSwapMessages(swap, currentStep, getWalletInfo);
|
|
175
175
|
const steps = getSteps({
|
|
176
176
|
swap,
|
|
177
177
|
switchNetwork,
|
|
@@ -30,7 +30,6 @@ export interface SettingsSlice {
|
|
|
30
30
|
affiliatePercent: number | null;
|
|
31
31
|
affiliateWallets: { [key: string]: string } | null;
|
|
32
32
|
_customTokens: Token[];
|
|
33
|
-
|
|
34
33
|
setSlippage: (slippage: number) => void;
|
|
35
34
|
setCustomSlippage: (customSlippage: number | null) => void;
|
|
36
35
|
toggleInfiniteApprove: () => void;
|
|
@@ -70,7 +69,6 @@ export const createSettingsSlice: StateCreator<
|
|
|
70
69
|
affiliatePercent: null,
|
|
71
70
|
affiliateWallets: null,
|
|
72
71
|
_customTokens: [],
|
|
73
|
-
|
|
74
72
|
addPreferredBlockchain: (blockchain) => {
|
|
75
73
|
const currentPreferredBlockchains = get().preferredBlockchains;
|
|
76
74
|
|
package/src/utils/settings.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { Features, Routing } from '../types';
|
|
2
2
|
import type { SwapperMeta, SwapperType, Token } from 'rango-sdk';
|
|
3
3
|
|
|
4
|
+
import { i18n } from '@lingui/core';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
HIGH_SLIPPAGE,
|
|
8
|
+
MAX_SLIPPAGE,
|
|
9
|
+
MIN_SLIPPAGE,
|
|
10
|
+
} from '../constants/swapSettings';
|
|
11
|
+
|
|
4
12
|
import { removeDuplicateFrom } from './common';
|
|
5
13
|
|
|
6
14
|
export type UniqueSwappersGroupType = {
|
|
@@ -87,3 +95,23 @@ export const addCustomTokensToSupportedTokens = (
|
|
|
87
95
|
? supportedTokens
|
|
88
96
|
: supportedTokens.concat(customTokens);
|
|
89
97
|
};
|
|
98
|
+
|
|
99
|
+
export function getSlippageValidation(
|
|
100
|
+
slippage: number
|
|
101
|
+
): { type: 'error' | 'warning'; message: string } | null {
|
|
102
|
+
if (slippage == MIN_SLIPPAGE) {
|
|
103
|
+
return {
|
|
104
|
+
type: 'error',
|
|
105
|
+
message: i18n.t('Slippage must be greater than or equal to 0.01'),
|
|
106
|
+
};
|
|
107
|
+
} else if (slippage > HIGH_SLIPPAGE && slippage <= MAX_SLIPPAGE) {
|
|
108
|
+
return {
|
|
109
|
+
type: 'warning',
|
|
110
|
+
message: i18n.t(
|
|
111
|
+
'Your transaction is at risk of being frontrun due to high slippage tolerance.'
|
|
112
|
+
),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return null;
|
|
117
|
+
}
|
package/src/utils/swap.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
SwapButtonState,
|
|
10
10
|
Wallet,
|
|
11
11
|
} from '../types';
|
|
12
|
+
import type { ExtendedWalletInfo } from '@rango-dev/wallets-react';
|
|
12
13
|
import type { WalletType } from '@rango-dev/wallets-shared';
|
|
13
14
|
import type {
|
|
14
15
|
BestRouteRequest,
|
|
@@ -22,6 +23,7 @@ import type { PendingSwap, PendingSwapStep } from 'rango-types';
|
|
|
22
23
|
|
|
23
24
|
import { i18n } from '@lingui/core';
|
|
24
25
|
import {
|
|
26
|
+
getRelatedWalletOrNull,
|
|
25
27
|
type RouteEvent,
|
|
26
28
|
RouteEventType,
|
|
27
29
|
type StepEvent,
|
|
@@ -666,7 +668,8 @@ export function isNetworkStatusInWarningState(
|
|
|
666
668
|
|
|
667
669
|
export function getSwapMessages(
|
|
668
670
|
pendingSwap: PendingSwap,
|
|
669
|
-
currentStep: PendingSwapStep | null
|
|
671
|
+
currentStep: PendingSwapStep | null,
|
|
672
|
+
getWalletInfo?: (type: WalletType) => ExtendedWalletInfo
|
|
670
673
|
): {
|
|
671
674
|
shortMessage: string;
|
|
672
675
|
detailedMessage: { content: string; long: boolean };
|
|
@@ -685,10 +688,20 @@ export function getSwapMessages(
|
|
|
685
688
|
if (networkWarningState) {
|
|
686
689
|
message = pendingSwap.networkStatusExtraMessage || '';
|
|
687
690
|
detailedMessage = pendingSwap.networkStatusExtraMessageDetail || '';
|
|
691
|
+
|
|
692
|
+
const currentStepWallet = currentStep
|
|
693
|
+
? getRelatedWalletOrNull(pendingSwap, currentStep)
|
|
694
|
+
: null;
|
|
695
|
+
const walletType = currentStepWallet?.walletType;
|
|
696
|
+
const walletName = walletType ? getWalletInfo?.(walletType)?.name : null;
|
|
688
697
|
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
689
698
|
switch (currentStep?.networkStatus) {
|
|
690
699
|
case PendingSwapNetworkStatus.WaitingForConnectingWallet:
|
|
691
|
-
message =
|
|
700
|
+
message = walletName
|
|
701
|
+
? i18n.t('Connect {wallet}', {
|
|
702
|
+
wallet: walletName,
|
|
703
|
+
})
|
|
704
|
+
: message;
|
|
692
705
|
break;
|
|
693
706
|
case PendingSwapNetworkStatus.WaitingForQueue:
|
|
694
707
|
message =
|