@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.41.2-next.10",
3
+ "version": "0.41.2-next.12",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "source": "./src/index.ts",
@@ -54,4 +54,4 @@
54
54
  "publishConfig": {
55
55
  "access": "public"
56
56
  }
57
- }
57
+ }
@@ -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
- if (customSlippage) {
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={(event) => {
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,
@@ -8,6 +8,6 @@ export const DEFAULT_SLIPPAGE = 1;
8
8
 
9
9
  export const HIGH_SLIPPAGE = 5;
10
10
 
11
- export const MAX_SLIPPAGE = 100;
11
+ export const MAX_SLIPPAGE = 30;
12
12
 
13
- export const MIN_SLIPPGAE = 0;
13
+ export const MIN_SLIPPAGE = 0;
@@ -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
 
@@ -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 = message || i18n.t('Waiting for connecting wallet');
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 =