@imtbl/checkout-widgets 2.4.13 → 2.4.14-alpha.1
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/browser/{AddTokensWidget-Dw62MGE7.js → AddTokensWidget-ShqEH0bA.js} +4 -4
- package/dist/browser/{BridgeWidget-pB9NQr0j.js → BridgeWidget-DJLZDZAJ.js} +6 -6
- package/dist/browser/{CommerceWidget-CmGjTT5f.js → CommerceWidget-nbdP_6Ip.js} +13 -13
- package/dist/browser/{FeesBreakdown-D42F89mf.js → FeesBreakdown-DvFl9V2q.js} +1 -1
- package/dist/browser/{OnRampWidget-C11vbDpE.js → OnRampWidget-cqzl_-aK.js} +3 -3
- package/dist/browser/{SaleWidget-C-kIuH_x.js → SaleWidget-iKKGkvvk.js} +10 -10
- package/dist/browser/{SpendingCapHero-DxECFPhZ.js → SpendingCapHero-Daz_5xcg.js} +1 -1
- package/dist/browser/{SwapWidget-CaimjlZx.js → SwapWidget-Y6Xo5WSo.js} +43 -54
- package/dist/browser/{TokenImage-CJcf0BVb.js → TokenImage-DW2XzMbU.js} +1 -1
- package/dist/browser/{TopUpView-DIAfMQDk.js → TopUpView-BORiBYNf.js} +1 -1
- package/dist/browser/{WalletApproveHero-2qnl25R9.js → WalletApproveHero-4jx0GgAA.js} +2 -2
- package/dist/browser/{WalletWidget-EUpKwouL.js → WalletWidget-BwFVpnAI.js} +3 -3
- package/dist/browser/{auto-track-BLHegHT2.js → auto-track-DZymc0UC.js} +1 -1
- package/dist/browser/{index-Co43S-f8.js → index-B6p10_zD.js} +256 -241
- package/dist/browser/{index-BZQairfY.js → index-BQ53A9R_.js} +2 -2
- package/dist/browser/{index-C52OgfPn.js → index-Bhny47VI.js} +1 -1
- package/dist/browser/{index-C7zLn4CO.js → index-BjxyO_sP.js} +1 -1
- package/dist/browser/{index-iCexzEAZ.js → index-CGpeUDFk.js} +1 -1
- package/dist/browser/{index-COIl8mga.js → index-CZhAFfYE.js} +1 -1
- package/dist/browser/{index-B1kcsGhP.js → index-DQSmVvsC.js} +1 -1
- package/dist/browser/{index-B6adB8ks.js → index-bhVqRauZ.js} +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/{index.umd-ENtuIC6R.js → index.umd-DQuNDZ-6.js} +1 -1
- package/dist/browser/{useInterval-BaXQ-Cl5.js → useInterval-BPf23nxq.js} +1 -1
- package/dist/types/lib/squid/functions/execute.d.ts +8 -0
- package/dist/types/lib/squid/functions/routeCalculation.d.ts +22 -0
- package/dist/types/lib/squid/functions/slippage.d.ts +1 -0
- package/dist/types/lib/squid/hooks/useExecute.d.ts +1 -2
- package/dist/types/lib/squid/hooks/useRoutes.d.ts +1 -5
- package/dist/types/widgets/swap/context/SwapContext.d.ts +3 -9
- package/package.json +7 -7
- package/src/lib/squid/functions/execute.ts +88 -0
- package/src/lib/squid/functions/routeCalculation.ts +162 -0
- package/src/lib/squid/functions/slippage.ts +36 -0
- package/src/lib/squid/hooks/useExecute.ts +3 -85
- package/src/lib/squid/hooks/useRoutes.ts +5 -115
- package/src/widgets/add-tokens/views/Review.tsx +2 -1
- package/src/widgets/purchase/views/Purchase.tsx +8 -2
- package/src/widgets/swap/SwapWidget.tsx +0 -23
- package/src/widgets/swap/components/SwapForm.tsx +45 -21
- package/src/widgets/swap/context/SwapContext.ts +1 -16
- package/dist/types/lib/squid/hooks/useRouteCalculation.d.ts +0 -9
- package/dist/types/lib/squid/hooks/useSlippage.d.ts +0 -7
- package/src/lib/squid/hooks/useRouteCalculation.ts +0 -60
- package/src/lib/squid/hooks/useSlippage.ts +0 -45
|
@@ -3,7 +3,6 @@ import { RouteResponse, ActionType } from '@0xsquid/squid-types';
|
|
|
3
3
|
import { Squid } from '@0xsquid/sdk';
|
|
4
4
|
import { useRef } from 'react';
|
|
5
5
|
import { formatUnits } from 'ethers';
|
|
6
|
-
import { WrappedBrowserProvider } from '@imtbl/checkout-sdk';
|
|
7
6
|
import { delay } from '../../../functions/delay';
|
|
8
7
|
import { sortRoutesByFastestTime } from '../functions/sortRoutesByFastestTime';
|
|
9
8
|
import { retry } from '../../retry';
|
|
@@ -14,12 +13,13 @@ import {
|
|
|
14
13
|
} from '../types';
|
|
15
14
|
import { SquidPostHook } from '../../primary-sales';
|
|
16
15
|
import { SQUID_NATIVE_TOKEN } from '../config';
|
|
17
|
-
import { findToken } from '../functions/findToken';
|
|
18
16
|
import { isRouteToAmountGreaterThanToAmount } from '../functions/isRouteToAmountGreaterThanToAmount';
|
|
19
|
-
import { useRouteCalculation } from './useRouteCalculation';
|
|
20
17
|
import { RouteError } from '../RouteError';
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
import {
|
|
19
|
+
calculateFromAmountFromRoute,
|
|
20
|
+
convertToFormattedFromAmount,
|
|
21
|
+
getSufficientFromAmounts,
|
|
22
|
+
} from '../functions/routeCalculation';
|
|
23
23
|
|
|
24
24
|
export const useRoutes = () => {
|
|
25
25
|
const latestRequestIdRef = useRef<number>(0);
|
|
@@ -30,71 +30,6 @@ export const useRoutes = () => {
|
|
|
30
30
|
},
|
|
31
31
|
} = useProvidersContext();
|
|
32
32
|
|
|
33
|
-
const { calculateFromAmount, calculateFromAmountFromRoute, convertToFormattedFromAmount } = useRouteCalculation();
|
|
34
|
-
|
|
35
|
-
const getFromAmountData = (
|
|
36
|
-
tokens: Token[],
|
|
37
|
-
balance: TokenBalance,
|
|
38
|
-
toAmount: string,
|
|
39
|
-
toChainId: string,
|
|
40
|
-
toTokenAddress: string,
|
|
41
|
-
additionalBuffer: number = 0,
|
|
42
|
-
): FromAmountData | undefined => {
|
|
43
|
-
const fromToken = findToken(
|
|
44
|
-
tokens,
|
|
45
|
-
balance.address,
|
|
46
|
-
balance.chainId.toString(),
|
|
47
|
-
);
|
|
48
|
-
const toToken = findToken(tokens, toTokenAddress, toChainId);
|
|
49
|
-
|
|
50
|
-
if (!fromToken || !toToken) {
|
|
51
|
-
return undefined;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
fromToken,
|
|
56
|
-
fromAmount: calculateFromAmount(
|
|
57
|
-
fromToken,
|
|
58
|
-
toToken,
|
|
59
|
-
toAmount,
|
|
60
|
-
additionalBuffer,
|
|
61
|
-
),
|
|
62
|
-
toToken,
|
|
63
|
-
toAmount,
|
|
64
|
-
balance,
|
|
65
|
-
additionalBuffer,
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const getSufficientFromAmounts = (
|
|
70
|
-
tokens: Token[],
|
|
71
|
-
balances: TokenBalance[],
|
|
72
|
-
toChainId: string,
|
|
73
|
-
toTokenAddress: string,
|
|
74
|
-
toAmount: string,
|
|
75
|
-
): FromAmountData[] => {
|
|
76
|
-
const filteredBalances = balances.filter(
|
|
77
|
-
(balance) => !(
|
|
78
|
-
balance.address.toLowerCase() === toTokenAddress.toLowerCase()
|
|
79
|
-
&& balance.chainId === toChainId
|
|
80
|
-
),
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
const fromAmountDataArray: FromAmountData[] = filteredBalances
|
|
84
|
-
.map((balance) => getFromAmountData(tokens, balance, toAmount, toChainId, toTokenAddress))
|
|
85
|
-
.filter((value) => value !== undefined);
|
|
86
|
-
|
|
87
|
-
return fromAmountDataArray.filter((data: FromAmountData) => {
|
|
88
|
-
const formattedBalance = formatUnits(
|
|
89
|
-
data.balance.balance,
|
|
90
|
-
data.balance.decimals,
|
|
91
|
-
);
|
|
92
|
-
return (
|
|
93
|
-
parseFloat(formattedBalance.toString()) > parseFloat(data.fromAmount)
|
|
94
|
-
);
|
|
95
|
-
});
|
|
96
|
-
};
|
|
97
|
-
|
|
98
33
|
const getRouteWithRetry = async (
|
|
99
34
|
squid: Squid,
|
|
100
35
|
fromToken: Token,
|
|
@@ -357,53 +292,8 @@ export const useRoutes = () => {
|
|
|
357
292
|
}
|
|
358
293
|
};
|
|
359
294
|
|
|
360
|
-
const hasSufficientBalance = (
|
|
361
|
-
balances: TokenBalance[],
|
|
362
|
-
toTokenAddress: string,
|
|
363
|
-
toChainId: string,
|
|
364
|
-
toAmount: string,
|
|
365
|
-
): boolean => {
|
|
366
|
-
const matchingTokens = balances.filter(
|
|
367
|
-
(balance) => balance.address.toLowerCase() === toTokenAddress.toLowerCase()
|
|
368
|
-
&& balance.chainId.toString() === toChainId.toString(),
|
|
369
|
-
);
|
|
370
|
-
|
|
371
|
-
if (matchingTokens.length > 0) {
|
|
372
|
-
return matchingTokens.some((balance) => {
|
|
373
|
-
const tokenAmount = parseFloat(formatUnits(balance.balance, balance.decimals));
|
|
374
|
-
return tokenAmount >= parseFloat(toAmount);
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
return false;
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
const hasSufficientGas = (
|
|
382
|
-
balances: TokenBalance[],
|
|
383
|
-
selectedChainId: string | number,
|
|
384
|
-
provider: WrappedBrowserProvider | undefined,
|
|
385
|
-
): boolean => {
|
|
386
|
-
if (!provider) return false;
|
|
387
|
-
if (isPassportProvider(provider)) return true;
|
|
388
|
-
|
|
389
|
-
const nativeCurrencyBalance = balances.find(
|
|
390
|
-
(balance) => balance.address.toLowerCase() === SQUID_NATIVE_TOKEN.toLowerCase()
|
|
391
|
-
&& balance.chainId.toString() === selectedChainId.toString(),
|
|
392
|
-
);
|
|
393
|
-
if (!nativeCurrencyBalance) return false;
|
|
394
|
-
|
|
395
|
-
const nativeCurrencyBalanceAmount = parseFloat(
|
|
396
|
-
formatUnits(nativeCurrencyBalance.balance, nativeCurrencyBalance.decimals),
|
|
397
|
-
);
|
|
398
|
-
if (nativeCurrencyBalanceAmount < INSUFFICIENT_GAS_THRESHOLD) return false;
|
|
399
|
-
return true;
|
|
400
|
-
};
|
|
401
|
-
|
|
402
295
|
return {
|
|
403
|
-
hasSufficientBalance,
|
|
404
|
-
hasSufficientGas,
|
|
405
296
|
fetchRoutes,
|
|
406
|
-
getFromAmountData,
|
|
407
297
|
getRoute,
|
|
408
298
|
};
|
|
409
299
|
};
|
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
} from '../AddTokensWidgetEvents';
|
|
67
67
|
import { useErrorHandler } from '../hooks/useErrorHandler';
|
|
68
68
|
import { AddTokensHandoverStep, useHandoverConfig } from '../hooks/useHandoverConfig';
|
|
69
|
+
import { getFromAmountData } from '../../../lib/squid/functions/routeCalculation';
|
|
69
70
|
|
|
70
71
|
interface ReviewProps {
|
|
71
72
|
data: AddTokensReviewData;
|
|
@@ -116,7 +117,7 @@ export function Review({
|
|
|
116
117
|
const [showFeeBreakdown, setShowFeeBreakdown] = useState(false);
|
|
117
118
|
const [showSecuringQuote, setShowSecuringQuote] = useState(false);
|
|
118
119
|
const [showAddressMissmatchDrawer, setShowAddressMissmatchDrawer] = useState(false);
|
|
119
|
-
const {
|
|
120
|
+
const { getRoute } = useRoutes();
|
|
120
121
|
const { showHandover } = useHandoverConfig(checkout.config.environment);
|
|
121
122
|
|
|
122
123
|
const { onTransactionError } = useErrorHandler();
|
|
@@ -46,6 +46,12 @@ import {
|
|
|
46
46
|
} from '../types';
|
|
47
47
|
import { ViewActions, ViewContext } from '../../../context/view-context/ViewContext';
|
|
48
48
|
import { PurchaseWidgetViews } from '../../../context/view-context/PurchaseViewContextTypes';
|
|
49
|
+
import {
|
|
50
|
+
getFromAmountData,
|
|
51
|
+
hasSufficientBalance,
|
|
52
|
+
hasSufficientGas,
|
|
53
|
+
} from '../../../lib/squid/functions/routeCalculation';
|
|
54
|
+
import { waitForReceipt } from '../../../lib/squid/functions/execute';
|
|
49
55
|
|
|
50
56
|
interface PurchaseProps {
|
|
51
57
|
checkout: Checkout;
|
|
@@ -109,12 +115,12 @@ export function Purchase({
|
|
|
109
115
|
} = useProvidersContext();
|
|
110
116
|
|
|
111
117
|
const {
|
|
112
|
-
fetchRoutes, getRoute,
|
|
118
|
+
fetchRoutes, getRoute,
|
|
113
119
|
} = useRoutes();
|
|
114
120
|
const { providers } = useInjectedProviders({ checkout });
|
|
115
121
|
|
|
116
122
|
const {
|
|
117
|
-
getAllowance, approve, execute, getStatus,
|
|
123
|
+
getAllowance, approve, execute, getStatus,
|
|
118
124
|
} = useExecute(UserJourney.PURCHASE, (err) => {
|
|
119
125
|
// eslint-disable-next-line no-console
|
|
120
126
|
console.log('useExecute err', err);
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
TokenFilterTypes, IMTBLWidgetEvents, SwapWidgetParams,
|
|
11
11
|
SwapDirection,
|
|
12
|
-
fetchRiskAssessment,
|
|
13
12
|
WalletProviderName,
|
|
14
13
|
} from '@imtbl/checkout-sdk';
|
|
15
14
|
import { useTranslation } from 'react-i18next';
|
|
@@ -193,28 +192,6 @@ export default function SwapWidget({
|
|
|
193
192
|
})();
|
|
194
193
|
}, [checkout, provider]);
|
|
195
194
|
|
|
196
|
-
useEffect(() => {
|
|
197
|
-
if (!checkout || swapState.riskAssessment) {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
(async () => {
|
|
202
|
-
const address = await (await provider?.getSigner())?.getAddress();
|
|
203
|
-
|
|
204
|
-
if (!address) {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const assessment = await fetchRiskAssessment([address], checkout.config);
|
|
209
|
-
swapDispatch({
|
|
210
|
-
payload: {
|
|
211
|
-
type: SwapActions.SET_RISK_ASSESSMENT,
|
|
212
|
-
riskAssessment: assessment,
|
|
213
|
-
},
|
|
214
|
-
});
|
|
215
|
-
})();
|
|
216
|
-
}, [checkout, provider]);
|
|
217
|
-
|
|
218
195
|
useEffect(() => {
|
|
219
196
|
swapDispatch({
|
|
220
197
|
payload: {
|
|
@@ -5,8 +5,12 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
Box, ButtCon, Heading, Icon, OptionKey, Tooltip, Body,
|
|
7
7
|
} from '@biom3/react';
|
|
8
|
-
import {
|
|
9
|
-
|
|
8
|
+
import {
|
|
9
|
+
fetchRiskAssessmentV2,
|
|
10
|
+
isSingleAddressSanctioned,
|
|
11
|
+
TokenInfo,
|
|
12
|
+
WidgetTheme,
|
|
13
|
+
} from '@imtbl/checkout-sdk';
|
|
10
14
|
import { TransactionResponse } from '@imtbl/dex-sdk';
|
|
11
15
|
import { useTranslation } from 'react-i18next';
|
|
12
16
|
import { Environment } from '@imtbl/config';
|
|
@@ -92,7 +96,6 @@ export function SwapForm({ data, theme, cancelAutoProceed }: SwapFromProps) {
|
|
|
92
96
|
tokenBalances,
|
|
93
97
|
network,
|
|
94
98
|
autoProceed,
|
|
95
|
-
riskAssessment,
|
|
96
99
|
},
|
|
97
100
|
} = useContext(SwapContext);
|
|
98
101
|
|
|
@@ -815,18 +818,7 @@ export function SwapForm({ data, theme, cancelAutoProceed }: SwapFromProps) {
|
|
|
815
818
|
|
|
816
819
|
const sendTransaction = async () => {
|
|
817
820
|
if (!quote) return;
|
|
818
|
-
if (riskAssessment && isAddressSanctioned(riskAssessment)) {
|
|
819
|
-
viewDispatch({
|
|
820
|
-
payload: {
|
|
821
|
-
type: ViewActions.UPDATE_VIEW,
|
|
822
|
-
view: {
|
|
823
|
-
type: SwapWidgetViews.SERVICE_UNAVAILABLE,
|
|
824
|
-
},
|
|
825
|
-
},
|
|
826
|
-
});
|
|
827
821
|
|
|
828
|
-
return;
|
|
829
|
-
}
|
|
830
822
|
const transaction = quote;
|
|
831
823
|
const isValid = SwapFormValidator();
|
|
832
824
|
// Tracking swap from data here and is valid or not to understand behaviour
|
|
@@ -836,12 +828,12 @@ export function SwapForm({ data, theme, cancelAutoProceed }: SwapFromProps) {
|
|
|
836
828
|
control: 'Swap',
|
|
837
829
|
controlType: 'Button',
|
|
838
830
|
extras: {
|
|
839
|
-
swapFromAddress:
|
|
840
|
-
swapFromAmount:
|
|
841
|
-
swapFromTokenSymbol:
|
|
842
|
-
swapToAddress:
|
|
843
|
-
swapToAmount:
|
|
844
|
-
swapToTokenSymbol:
|
|
831
|
+
swapFromAddress: fromToken?.address,
|
|
832
|
+
swapFromAmount: fromAmount,
|
|
833
|
+
swapFromTokenSymbol: fromToken?.symbol,
|
|
834
|
+
swapToAddress: toToken?.address,
|
|
835
|
+
swapToAmount: toAmount,
|
|
836
|
+
swapToTokenSymbol: toToken?.symbol,
|
|
845
837
|
isSwapFormValid: isValid,
|
|
846
838
|
hasFundsForGas: !insufficientFundsForGas,
|
|
847
839
|
autoProceed,
|
|
@@ -855,6 +847,38 @@ export function SwapForm({ data, theme, cancelAutoProceed }: SwapFromProps) {
|
|
|
855
847
|
return;
|
|
856
848
|
}
|
|
857
849
|
|
|
850
|
+
// Perform sanctions check once we have valid asset and amount data
|
|
851
|
+
const address = await (await provider?.getSigner())?.getAddress();
|
|
852
|
+
|
|
853
|
+
if (!address) {
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
if (!fromToken?.address || !fromAmount) {
|
|
858
|
+
throw new Error('Invalid form data: fromToken.Address or fromAmount is missing');
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
const riskAssessmentData = [{
|
|
862
|
+
address,
|
|
863
|
+
tokenAddr: fromToken.address,
|
|
864
|
+
amount: parseUnits(fromAmount, fromToken.decimals),
|
|
865
|
+
}];
|
|
866
|
+
|
|
867
|
+
const riskAssessment = await fetchRiskAssessmentV2(riskAssessmentData, checkout.config);
|
|
868
|
+
|
|
869
|
+
if (riskAssessment && isSingleAddressSanctioned(riskAssessment, address)) {
|
|
870
|
+
viewDispatch({
|
|
871
|
+
payload: {
|
|
872
|
+
type: ViewActions.UPDATE_VIEW,
|
|
873
|
+
view: {
|
|
874
|
+
type: SwapWidgetViews.SERVICE_UNAVAILABLE,
|
|
875
|
+
},
|
|
876
|
+
},
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
|
|
858
882
|
try {
|
|
859
883
|
// check for switch network here
|
|
860
884
|
const currentChainId = await (provider.provider as any).send('eth_chainId', []);
|
|
@@ -959,7 +983,7 @@ export function SwapForm({ data, theme, cancelAutoProceed }: SwapFromProps) {
|
|
|
959
983
|
testInputMode="decimal"
|
|
960
984
|
textInputValue={fromAmount}
|
|
961
985
|
textInputPlaceholder={t('views.SWAP.swapForm.from.inputPlaceholder')}
|
|
962
|
-
textInputSubtext={`${t('views.SWAP.content.fiatPricePrefix')}
|
|
986
|
+
textInputSubtext={`${t('views.SWAP.content.fiatPricePrefix')}
|
|
963
987
|
$${formatZeroAmount(
|
|
964
988
|
fromFiatValue,
|
|
965
989
|
true,
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
NetworkInfo,
|
|
5
5
|
TokenInfo,
|
|
6
6
|
SwapDirection,
|
|
7
|
-
AssessmentResult,
|
|
8
7
|
} from '@imtbl/checkout-sdk';
|
|
9
8
|
import { Exchange } from '@imtbl/dex-sdk';
|
|
10
9
|
import { createContext } from 'react';
|
|
@@ -17,7 +16,6 @@ export interface SwapState {
|
|
|
17
16
|
supportedTopUps: TopUpFeature | null;
|
|
18
17
|
allowedTokens: TokenInfo[];
|
|
19
18
|
autoProceed: boolean;
|
|
20
|
-
riskAssessment: AssessmentResult | undefined;
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
export interface TopUpFeature {
|
|
@@ -34,7 +32,6 @@ export const initialSwapState: SwapState = {
|
|
|
34
32
|
supportedTopUps: null,
|
|
35
33
|
allowedTokens: [],
|
|
36
34
|
autoProceed: false,
|
|
37
|
-
riskAssessment: undefined,
|
|
38
35
|
};
|
|
39
36
|
|
|
40
37
|
export interface SwapContextState {
|
|
@@ -53,8 +50,7 @@ type ActionPayload =
|
|
|
53
50
|
| SetSupportedTopUpPayload
|
|
54
51
|
| SetTokenBalancesPayload
|
|
55
52
|
| SetAllowedTokensPayload
|
|
56
|
-
| SetAutoProceedPayload
|
|
57
|
-
| SetRiskAssessmentPayload;
|
|
53
|
+
| SetAutoProceedPayload;
|
|
58
54
|
|
|
59
55
|
export enum SwapActions {
|
|
60
56
|
SET_EXCHANGE = 'SET_EXCHANGE',
|
|
@@ -64,7 +60,6 @@ export enum SwapActions {
|
|
|
64
60
|
SET_TOKEN_BALANCES = 'SET_TOKEN_BALANCES',
|
|
65
61
|
SET_ALLOWED_TOKENS = 'SET_ALLOWED_TOKENS',
|
|
66
62
|
SET_AUTO_PROCEED = 'SET_AUTO_PROCEED',
|
|
67
|
-
SET_RISK_ASSESSMENT = 'SET_RISK_ASSESSMENT',
|
|
68
63
|
}
|
|
69
64
|
|
|
70
65
|
export interface SetExchangePayload {
|
|
@@ -103,11 +98,6 @@ export interface SetAutoProceedPayload {
|
|
|
103
98
|
direction: SwapDirection;
|
|
104
99
|
}
|
|
105
100
|
|
|
106
|
-
export interface SetRiskAssessmentPayload {
|
|
107
|
-
type: SwapActions.SET_RISK_ASSESSMENT;
|
|
108
|
-
riskAssessment: AssessmentResult;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
101
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
112
102
|
export const SwapContext = createContext<SwapContextState>({
|
|
113
103
|
swapState: initialSwapState,
|
|
@@ -165,11 +155,6 @@ export const swapReducer: Reducer<SwapState, SwapAction> = (
|
|
|
165
155
|
autoProceed: action.payload.autoProceed,
|
|
166
156
|
direction: action.payload.direction,
|
|
167
157
|
};
|
|
168
|
-
case SwapActions.SET_RISK_ASSESSMENT:
|
|
169
|
-
return {
|
|
170
|
-
...state,
|
|
171
|
-
riskAssessment: action.payload.riskAssessment,
|
|
172
|
-
};
|
|
173
158
|
default:
|
|
174
159
|
return state;
|
|
175
160
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Token } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Hook to handle route amount calculations.
|
|
4
|
-
*/
|
|
5
|
-
export declare const useRouteCalculation: () => {
|
|
6
|
-
calculateFromAmount: (fromToken: Token, toToken: Token, toAmount: string, additionalBuffer?: number) => string;
|
|
7
|
-
calculateFromAmountFromRoute: (exchangeRate: string, toAmount: string, toAmountUSD?: string) => string;
|
|
8
|
-
convertToFormattedFromAmount: (amount: string, decimals: number) => string;
|
|
9
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { parseUnits } from 'ethers';
|
|
3
|
-
import { useSlippage } from './useSlippage';
|
|
4
|
-
import { Token } from '../types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Hook to handle route amount calculations.
|
|
8
|
-
*/
|
|
9
|
-
export const useRouteCalculation = () => {
|
|
10
|
-
const { calculateAdjustedAmount } = useSlippage();
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Calculate the fromAmount based on USD prices and slippage.
|
|
14
|
-
*/
|
|
15
|
-
const calculateFromAmount = (
|
|
16
|
-
fromToken: Token,
|
|
17
|
-
toToken: Token,
|
|
18
|
-
toAmount: string,
|
|
19
|
-
additionalBuffer: number = 0,
|
|
20
|
-
) => {
|
|
21
|
-
const toAmountNumber = parseFloat(toAmount);
|
|
22
|
-
// Calculate the USD value of the toAmount
|
|
23
|
-
const toAmountInUsd = toAmountNumber * toToken.usdPrice;
|
|
24
|
-
// Calculate the amount of fromToken needed to match this USD value
|
|
25
|
-
const baseFromAmount = toAmountInUsd / fromToken.usdPrice;
|
|
26
|
-
// Add a buffer for price fluctuations and fees
|
|
27
|
-
const fromAmountWithBuffer = calculateAdjustedAmount(baseFromAmount, toAmountInUsd, additionalBuffer);
|
|
28
|
-
|
|
29
|
-
return fromAmountWithBuffer.toString();
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Calculate the fromAmount using exchange rate returned from the route.
|
|
34
|
-
*/
|
|
35
|
-
const calculateFromAmountFromRoute = (
|
|
36
|
-
exchangeRate: string,
|
|
37
|
-
toAmount: string,
|
|
38
|
-
toAmountUSD?: string,
|
|
39
|
-
) => {
|
|
40
|
-
const toAmountUSDNumber = toAmountUSD ? parseFloat(toAmountUSD) : 0;
|
|
41
|
-
const fromAmount = parseFloat(toAmount) / parseFloat(exchangeRate);
|
|
42
|
-
const fromAmountWithBuffer = calculateAdjustedAmount(fromAmount, toAmountUSDNumber);
|
|
43
|
-
return fromAmountWithBuffer.toString();
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Convert a string amount to a formatted amount with the specified number of decimals.
|
|
48
|
-
*/
|
|
49
|
-
const convertToFormattedFromAmount = (amount: string, decimals: number) => {
|
|
50
|
-
const parsedFromAmount = parseFloat(amount).toFixed(decimals);
|
|
51
|
-
const formattedFromAmount = parseUnits(parsedFromAmount, decimals);
|
|
52
|
-
return formattedFromAmount.toString();
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return useMemo(() => ({
|
|
56
|
-
calculateFromAmount,
|
|
57
|
-
calculateFromAmountFromRoute,
|
|
58
|
-
convertToFormattedFromAmount,
|
|
59
|
-
}), []);
|
|
60
|
-
};
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
|
|
3
|
-
const BASE_SLIPPAGE_HIGH_TIER = 0.005;
|
|
4
|
-
const BASE_SLIPPAGE_MEDIUM_TIER = 0.01;
|
|
5
|
-
const BASE_SLIPPAGE_LOW_TIER = 0.015;
|
|
6
|
-
|
|
7
|
-
const SLIPPAGE_TIERS = {
|
|
8
|
-
high: {
|
|
9
|
-
threshold: 999,
|
|
10
|
-
value: BASE_SLIPPAGE_HIGH_TIER,
|
|
11
|
-
},
|
|
12
|
-
medium: {
|
|
13
|
-
threshold: 99,
|
|
14
|
-
value: BASE_SLIPPAGE_MEDIUM_TIER,
|
|
15
|
-
},
|
|
16
|
-
low: {
|
|
17
|
-
threshold: 0,
|
|
18
|
-
value: BASE_SLIPPAGE_LOW_TIER,
|
|
19
|
-
},
|
|
20
|
-
} as const;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Hook to calculate slippage based on thresholds
|
|
24
|
-
*/
|
|
25
|
-
export const useSlippage = () => {
|
|
26
|
-
const getSlippageTier = (usdAmount: number): number => {
|
|
27
|
-
if (usdAmount >= SLIPPAGE_TIERS.high.threshold) return SLIPPAGE_TIERS.high.value;
|
|
28
|
-
if (usdAmount >= SLIPPAGE_TIERS.medium.threshold) return SLIPPAGE_TIERS.medium.value;
|
|
29
|
-
return SLIPPAGE_TIERS.low.value;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const calculateAdjustedAmount = (
|
|
33
|
-
baseAmount: number,
|
|
34
|
-
usdAmount: number,
|
|
35
|
-
additionalBuffer: number = 0,
|
|
36
|
-
): number => {
|
|
37
|
-
const slippage = getSlippageTier(usdAmount);
|
|
38
|
-
return baseAmount * (1 + slippage + additionalBuffer);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
return useMemo(() => ({
|
|
42
|
-
getSlippageTier,
|
|
43
|
-
calculateAdjustedAmount,
|
|
44
|
-
}), []);
|
|
45
|
-
};
|