@xswap-link/sdk 0.3.3 → 0.3.4

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.
@@ -10,17 +10,19 @@ import {
10
10
  import { ethers } from "ethers";
11
11
  import { Config, useAccount, useSendTransaction, useSwitchChain } from "wagmi";
12
12
  import { Chain, Route, Token, TokenBalances, TokenPrices } from "@src/models";
13
- import { getCustomTokenData, getPrices, getRoute } from "@src/services";
14
13
  import {
15
- getAllowanceOf,
16
- getBalances,
17
- parseWeb3Error,
18
- safeBigNumberFrom,
19
- weiToHumanReadable,
20
- } from "@src/utils";
21
- import { CCIP_EXPLORER, ROUTE_TIMEOUT_MS } from "@src/constants";
14
+ getCustomTokenData,
15
+ getPrices,
16
+ getRoute,
17
+ renderTxStatus,
18
+ } from "@src/services";
19
+ import { getBalances, safeBigNumberFrom } from "@src/utils";
20
+ import {
21
+ DEFAULT_REQUEST_ABORT_MSG,
22
+ DEFAULT_SOURCE_CHAIN_ID,
23
+ ROUTE_TIMEOUT_MS,
24
+ } from "@src/constants";
22
25
  import { TxConfigFormProps } from "@src/components";
23
- import { useDebounce } from "@src/hooks";
24
26
  import { ADDRESSES } from "@src/contracts";
25
27
  import { History } from "./History";
26
28
  import { TopBar } from "./TopBar";
@@ -30,23 +32,10 @@ import { Summary } from "./Summary";
30
32
  import { SwapPanel } from "./SwapPanel";
31
33
  import { ErrorField } from "./ErrorField";
32
34
  import { Description } from "./Description";
33
- import { DEFAULT_SOURCE_CHAIN_ID } from "@src/constants";
34
35
  import { Button } from "./Button";
35
36
  import { getChainId, waitForTransactionReceipt } from "wagmi/actions";
36
- import { renderTxStatus } from "@src/services";
37
- import { ConfirmationAmount } from "./ConfirmationAmount";
38
- import {
39
- ArrowDownIcon,
40
- ArrowRightIcon,
41
- ArrowUpRightIcon,
42
- CheckIcon,
43
- CloseIcon,
44
- ErrorIcon,
45
- SignIcon,
46
- SuccessIcon,
47
- } from "../icons";
48
- import { Spinner } from "../Spinner";
49
- import { UnknownTokenLogo } from "../UnknownTokenLogo/UnknownTokenLogo";
37
+ import { ConfirmationView } from "./ConfirmationView";
38
+ import { ConnectWalletPrompt } from "./ConnectWalletPrompt";
50
39
 
51
40
  export const Form = ({
52
41
  integratorId,
@@ -55,7 +44,7 @@ export const Form = ({
55
44
  customContractCalls,
56
45
  desc,
57
46
  supportedChains,
58
- retrunTransactions,
47
+ returnTransactions,
59
48
  dstDisplayTokenAddr,
60
49
  wagmiConfig,
61
50
  onSubmit,
@@ -63,7 +52,7 @@ export const Form = ({
63
52
  setBackdropClickDisabled,
64
53
  }: TxConfigFormProps & {
65
54
  wagmiConfig: Config;
66
- retrunTransactions: boolean;
55
+ returnTransactions: boolean;
67
56
  onSubmit: (route: Route) => void;
68
57
  onClose: () => void;
69
58
  setBackdropClickDisabled: (disabled: boolean) => void;
@@ -74,7 +63,7 @@ export const Form = ({
74
63
  const [dstDisplayToken, setDstDisplayToken] = useState<Token>();
75
64
  const [srcChain, setSrcChain] = useState<Chain>();
76
65
  const [srcToken, setSrcToken] = useState<Token>();
77
- const [amount, setAmount] = useState<string>("");
66
+ const [amount, setAmount] = useState("");
78
67
  const [paymentToken, setPaymentToken] = useState<Token>();
79
68
  const [route, setRoute] = useState<Route>();
80
69
  const [expressChecked, setExpressChecked] = useState(true);
@@ -84,7 +73,7 @@ export const Form = ({
84
73
  const [balances, setBalances] = useState<TokenBalances>();
85
74
  const [settingsShown, setSettingsShown] = useState(false);
86
75
  const [formError, setFormError] = useState("");
87
- const [slippage, setSlippage] = useState<string>("1.5");
76
+ const [slippage, setSlippage] = useState("1.5");
88
77
  const [feesDetailsShown, setFeesDetailsShown] = useState(false);
89
78
  const [executingTransactions, setExecutingTransactions] = useState(false);
90
79
  const [transactionSuccessHash, setTransactionSuccessHash] = useState<
@@ -95,25 +84,12 @@ export const Form = ({
95
84
  const [approveTxLoading, setApproveTxLoading] = useState(false);
96
85
  const [approveTxDone, setApproveTxDone] = useState(false);
97
86
  const [transactionError, setTransactionError] = useState<string | null>(null);
98
- const currentRouteRequestNonce = useRef<number>(0);
99
-
100
- // Allowance section
101
- const prevAllowanceValuesRef = useRef({
102
- srcChainId: srcChain?.chainId,
103
- srcTokenAddress: srcToken?.address,
104
- routeTo: ethers.constants.AddressZero,
105
- });
106
-
107
- const currentAllowanceRequestNonce = useRef<number>(0);
108
87
 
109
- const [isAllowanceLoading, setIsAllowanceLoading] = useState(false);
110
- const [srcTokenAllowance, setSrcTokenAllowance] = useState("0");
111
- // End of Allowance section
88
+ const routeAbortController = useRef<AbortController | null>(null);
112
89
 
113
90
  // Wagmi hook to execute transactions
114
91
  const { sendTransaction } = useSendTransaction({ config: wagmiConfig });
115
92
 
116
- const debouncedAmount = useDebounce(amount, 1000);
117
93
  const account = useAccount();
118
94
  const { switchChainAsync } = useSwitchChain();
119
95
 
@@ -186,7 +162,7 @@ export const Form = ({
186
162
  srcChain &&
187
163
  srcToken &&
188
164
  dstChain &&
189
- debouncedAmount &&
165
+ amount &&
190
166
  paymentToken &&
191
167
  signer &&
192
168
  slippage
@@ -206,99 +182,54 @@ export const Form = ({
206
182
  `Configuration error: selected token ($${srcToken.symbol} ${srcToken.name}) has unknown decimals param.`,
207
183
  );
208
184
 
209
- const nonce = Date.now();
210
- currentRouteRequestNonce.current = nonce;
211
- getRoute({
212
- integratorId,
213
- fromAmount: ethers.utils
214
- .parseUnits(debouncedAmount, srcToken.decimals)
215
- .toString(),
216
- fromAddress: signer || ADDRESSES[srcChain.chainId]!.FeeCollector,
217
- fromChain: srcChain.chainId,
218
- fromToken: srcToken.address,
219
- toAddress: signer || ADDRESSES[dstChain.chainId]!.FeeCollector,
220
- toChain: dstChainId,
221
- toToken: dstTokenAddr,
222
- paymentToken: paymentToken.address,
223
- slippage: Number(slippage),
224
- expressDelivery: expressChecked,
225
- customContractCalls,
226
- })
185
+ if (routeAbortController.current) {
186
+ routeAbortController.current.abort(DEFAULT_REQUEST_ABORT_MSG);
187
+ }
188
+ routeAbortController.current = new AbortController();
189
+
190
+ getRoute(
191
+ {
192
+ integratorId,
193
+ fromAmount: ethers.utils
194
+ .parseUnits(amount, srcToken.decimals)
195
+ .toString(),
196
+ fromAddress: signer || ADDRESSES[srcChain.chainId]!.FeeCollector,
197
+ fromChain: srcChain.chainId,
198
+ fromToken: srcToken.address,
199
+ toAddress: signer || ADDRESSES[dstChain.chainId]!.FeeCollector,
200
+ toChain: dstChainId,
201
+ toToken: dstTokenAddr,
202
+ paymentToken: paymentToken.address,
203
+ slippage: Number(slippage),
204
+ expressDelivery: expressChecked,
205
+ customContractCalls,
206
+ },
207
+ routeAbortController.current.signal,
208
+ )
227
209
  .then((response) => {
228
- if (nonce !== currentRouteRequestNonce.current) {
229
- return;
230
- }
231
210
  setRoute(response);
232
211
  setFormError("");
212
+ setIsGettingRoute(false);
213
+ routeAbortController.current = null;
233
214
  })
234
215
  .catch((err) => {
235
- setFormError(err.message);
216
+ if (err !== DEFAULT_REQUEST_ABORT_MSG) {
217
+ setFormError(err.message);
218
+ }
236
219
  })
237
220
  .finally(() => {
238
- setIsGettingRoute(false);
239
221
  clearTimeout(timeout);
240
222
  });
241
223
  }, [
224
+ amount,
242
225
  signer,
243
226
  srcChain,
244
227
  srcToken,
245
- debouncedAmount,
246
228
  paymentToken,
247
229
  slippage,
248
230
  expressChecked,
249
231
  ]);
250
232
 
251
- // Handle fetching allowance
252
- useEffect(() => {
253
- (async () => {
254
- if (
255
- !signer ||
256
- !srcToken?.address ||
257
- !srcChain?.publicRpcUrls[0] ||
258
- srcToken?.address === ethers.constants.AddressZero
259
- ) {
260
- return;
261
- }
262
- if (route && route.transactions.swap?.to) {
263
- const {
264
- srcChainId: prevFromChainId,
265
- srcTokenAddress: prevFromTokenAddress,
266
- routeTo: prevRouteTo,
267
- } = prevAllowanceValuesRef.current;
268
-
269
- const hasChanges =
270
- srcChain?.chainId !== prevFromChainId ||
271
- srcToken?.address !== prevFromTokenAddress ||
272
- route.transactions.swap?.to !== prevRouteTo;
273
-
274
- if (!hasChanges) {
275
- return;
276
- }
277
-
278
- prevAllowanceValuesRef.current = {
279
- srcChainId: srcChain?.chainId,
280
- srcTokenAddress: srcToken?.address,
281
- routeTo: route.transactions.swap?.to,
282
- };
283
-
284
- const nonce = Date.now();
285
- currentAllowanceRequestNonce.current = nonce;
286
- setIsAllowanceLoading(true);
287
- const allowanceResponse = await getAllowanceOf(
288
- srcToken?.address,
289
- signer,
290
- route.transactions.swap.to,
291
- srcChain?.publicRpcUrls[0],
292
- );
293
- if (nonce !== currentAllowanceRequestNonce.current) {
294
- return;
295
- }
296
- setSrcTokenAllowance(allowanceResponse);
297
- setIsAllowanceLoading(false);
298
- }
299
- })();
300
- }, [srcChain, srcToken?.address, signer, setSrcTokenAllowance, route]);
301
-
302
233
  // Set fee payment token
303
234
  useEffect(() => {
304
235
  if (srcChain) {
@@ -318,8 +249,6 @@ export const Form = ({
318
249
  setFormError("");
319
250
  setIsGettingRoute(false);
320
251
  setRoute(undefined);
321
- const nonce = Date.now();
322
- currentRouteRequestNonce.current = nonce;
323
252
  }, [srcToken]);
324
253
 
325
254
  // Clear state on source chain change
@@ -328,8 +257,6 @@ export const Form = ({
328
257
  setAmount("");
329
258
  setIsGettingRoute(false);
330
259
  setRoute(undefined);
331
- const nonce = Date.now();
332
- currentRouteRequestNonce.current = nonce;
333
260
  }, [srcChain]);
334
261
 
335
262
  // Fetch token prices on source chain
@@ -353,15 +280,7 @@ export const Form = ({
353
280
  setBackdropClickDisabled(executingTransactions);
354
281
  }, [executingTransactions]);
355
282
 
356
- // Check if the allowance needs to be adjusted
357
- const isAllowanceOk = useMemo(() => {
358
- return (
359
- srcToken?.address === ethers.constants.AddressZero ||
360
- Number(srcTokenAllowance) >= Number(amount)
361
- );
362
- }, [srcToken, amount, srcTokenAllowance]);
363
-
364
- // Execute the transactions recieved from the xPay.
283
+ // Execute the transactions received from the xPay.
365
284
  const triggerTx = useCallback(async () => {
366
285
  if (!route) {
367
286
  return;
@@ -371,11 +290,11 @@ export const Form = ({
371
290
  setTransactionError(null);
372
291
 
373
292
  // Optional approve for ERC20 tokens.
374
- if (route.transactions.approve && !isAllowanceOk) {
293
+ if (route.transactions.approve) {
375
294
  setApproveTxDone(false);
376
295
 
377
296
  const { to, data } = route.transactions.approve;
378
- await sendTransaction(
297
+ sendTransaction(
379
298
  {
380
299
  to,
381
300
  data,
@@ -391,7 +310,7 @@ export const Form = ({
391
310
  });
392
311
  setApproveTxLoading(false);
393
312
  setApproveTxDone(true);
394
- swap(route);
313
+ await swap(route);
395
314
  },
396
315
  onError: (error) => {
397
316
  setTransactionError(`Approval failed: ${error.message}`);
@@ -408,19 +327,17 @@ export const Form = ({
408
327
  signer,
409
328
  srcChain,
410
329
  srcToken,
411
- debouncedAmount,
412
330
  paymentToken,
413
331
  slippage,
414
332
  expressChecked,
415
333
  amount,
416
- srcTokenAllowance,
417
334
  ]);
418
335
 
419
336
  // Sign and send the swap transaction
420
337
  const swap = useCallback(
421
338
  async (route: Route) => {
422
339
  const { to, value, data } = route.transactions.swap;
423
- await sendTransaction(
340
+ sendTransaction(
424
341
  {
425
342
  to,
426
343
  value: BigInt(value),
@@ -441,7 +358,6 @@ export const Form = ({
441
358
  renderTxStatus(chainId.toString(), hash);
442
359
  }
443
360
  setTransactionSuccessHash(hash);
444
- // onSubmit(route);
445
361
  },
446
362
  onError: (error) => {
447
363
  setBackdropClickDisabled(false);
@@ -450,16 +366,7 @@ export const Form = ({
450
366
  },
451
367
  );
452
368
  },
453
- [
454
- route,
455
- signer,
456
- srcChain,
457
- srcToken,
458
- debouncedAmount,
459
- paymentToken,
460
- slippage,
461
- expressChecked,
462
- ],
369
+ [route, signer, srcChain, srcToken, paymentToken, slippage, expressChecked],
463
370
  );
464
371
 
465
372
  // Handle form submit
@@ -469,7 +376,7 @@ export const Form = ({
469
376
  return;
470
377
  }
471
378
 
472
- if (retrunTransactions) {
379
+ if (returnTransactions) {
473
380
  onSubmit(route);
474
381
  return;
475
382
  }
@@ -484,8 +391,6 @@ export const Form = ({
484
391
  // provides data for the main button
485
392
  const swapButton: { text: string; fn: () => void; disabled: boolean } =
486
393
  useMemo(() => {
487
- let disabled = false;
488
-
489
394
  if (transactionError) {
490
395
  return {
491
396
  text: transactionError,
@@ -498,7 +403,7 @@ export const Form = ({
498
403
  return {
499
404
  text: "Connect wallet",
500
405
  fn: () => {},
501
- disabled,
406
+ disabled: false,
502
407
  };
503
408
  }
504
409
 
@@ -510,7 +415,8 @@ export const Form = ({
510
415
  return {
511
416
  text: "Switch chain",
512
417
  fn: handleSwitchChain,
513
- disabled,
418
+
419
+ disabled: false,
514
420
  };
515
421
  }
516
422
 
@@ -547,308 +453,53 @@ export const Form = ({
547
453
  };
548
454
  }
549
455
 
550
- if (isAllowanceLoading) {
551
- return {
552
- text: `Checking allowance`,
553
- fn: () => {},
554
- disabled: true,
555
- };
556
- }
557
-
558
456
  return {
559
457
  text: "Submit",
560
458
  fn: () => {},
561
- disabled,
459
+ disabled: false,
562
460
  };
563
461
  }, [
564
462
  account,
565
463
  srcToken,
566
464
  srcChain,
567
- isAllowanceOk,
568
465
  amount,
569
466
  balances,
570
467
  signer,
571
468
  transactionError,
572
469
  route,
573
- isAllowanceLoading,
574
470
  ]);
575
471
 
576
472
  // check if the express delivery will be executed
577
473
  const isExpressDelivery = useMemo(() => {
578
- let expressDeliveryFee;
579
- if (!route?.xSwapFees || !route?.xSwapFees.expressDeliveryFee) {
580
- expressDeliveryFee = safeBigNumberFrom("0");
581
- } else {
582
- expressDeliveryFee = safeBigNumberFrom(
583
- route?.xSwapFees.expressDeliveryFee,
584
- );
585
- }
586
-
587
- if (expressDeliveryFee.gt("0")) {
588
- return true;
589
- }
590
- return false;
474
+ const expressDeliveryFee =
475
+ !route?.xSwapFees || !route?.xSwapFees.expressDeliveryFee
476
+ ? safeBigNumberFrom("0")
477
+ : safeBigNumberFrom(route?.xSwapFees.expressDeliveryFee);
478
+ return expressDeliveryFee.gt("0");
591
479
  }, [route]);
592
480
 
593
481
  return (
594
482
  <>
595
483
  {!signer ? (
596
- // Connect wallet modal
597
- <div className="xpay-flex xpay-flex-col xpay-gap-2 xpay-z-10 xpay-my-0 xpay-p-2 md:xpay-p-4 xpay-rounded-3xl xpay-overflow-hidden xpay-font-light sm:xpay-w-x_desktop xpay-w-screen">
598
- <div className="xpay-flex xpay-w-full xpay-justify-end xpay-items-center xpay-mx-auto xpay-p-2">
599
- <div
600
- className="xpay-cursor-pointer xpay-text-white"
601
- onClick={onClose}
602
- >
603
- <CloseIcon />
604
- </div>
605
- </div>{" "}
606
- <p className="xpay-text-xl xpay-font-bold xpay-leading-8 xpay-text-center xpay-text-white">
607
- Please connect the wallet first.
608
- </p>
609
- </div>
484
+ <ConnectWalletPrompt onClose={onClose} />
610
485
  ) : executingTransactions ? (
611
- <div className="xpay-flex xpay-flex-col xpay-gap-2 xpay-z-10 xpay-my-0 xpay-p-2 md:xpay-p-4 xpay-rounded-3xl xpay-overflow-hidden xpay-font-light sm:xpay-w-x_desktop xpay-w-screen">
612
- {transactionError ? (
613
- // Tx Error modal
614
- <div>
615
- <div className="xpay-flex xpay-w-full xpay-justify-end xpay-items-center xpay-mx-auto xpay-p-2">
616
- <div
617
- className="xpay-cursor-pointer xpay-text-white"
618
- onClick={onClose}
619
- >
620
- <CloseIcon />
621
- </div>
622
- </div>
623
-
624
- <div className="xpay-flex xpay-flex-col xpay-w-full xpay-justify-center xpay-items-center xpay-mx-auto xpay-p-2 xpay-gap-4">
625
- <div>
626
- <ErrorIcon />
627
- </div>
628
-
629
- <div className="xpay-flex xpay-flex-col">
630
- <div>
631
- <p className="xpay-text-2xl xpay-font-bold xpay-leading-8 xpay-text-center xpay-text-white">
632
- Transaction error!
633
- </p>
634
- </div>
635
- <div>
636
- <p className="xpay-text-sm xpay-text-center xpay-text-white xpay-opacity-50">
637
- {parseWeb3Error(transactionError)}
638
- </p>
639
- </div>
640
- </div>
641
- </div>
642
- </div>
643
- ) : transactionSuccessHash ? (
644
- // Tx Success modal
645
- <div>
646
- <div className="xpay-flex xpay-w-full xpay-justify-end xpay-items-center xpay-mx-auto xpay-p-2">
647
- <div
648
- className="xpay-cursor-pointer xpay-text-white"
649
- onClick={onClose}
650
- >
651
- <CloseIcon />
652
- </div>
653
- </div>
654
-
655
- <div className="xpay-flex xpay-flex-col xpay-w-full xpay-justify-center xpay-items-center xpay-mx-auto xpay-p-2 xpay-gap-4">
656
- <div>
657
- <SuccessIcon />
658
- </div>
659
- <div className="xpay-flex xpay-flex-col">
660
- <div>
661
- <p className="xpay-text-2xl xpay-font-bold xpay-leading-8 xpay-text-center xpay-text-white">
662
- Transaction success!
663
- </p>
664
- </div>
665
- {srcChain?.chainId !== dstChain?.chainId ? (
666
- <div>
667
- <p className="xpay-text-sm xpay-text-center xpay-text-white xpay-opacity-50">
668
- Approximated time of delivery:{" "}
669
- {isExpressDelivery ? "30 seconds" : "30 minutes"}
670
- </p>
671
- </div>
672
- ) : (
673
- <></>
674
- )}
675
- </div>
676
-
677
- <div className="xpay-flex xpay-gap-4 xpay-items-center">
678
- <div className="xpay-flex xpay-gap-2">
679
- <div className="xpay-w-10 xpay-h-10">
680
- {srcToken?.image ? (
681
- <img
682
- className="xpay-w-10 xpay-h-10"
683
- src={srcToken?.image}
684
- alt={srcToken?.name}
685
- />
686
- ) : (
687
- <UnknownTokenLogo
688
- tokenName={"?"}
689
- className="xpay-w-10 xpay-h-10"
690
- />
691
- )}
692
- </div>
693
- <div className="xpay-flex xpay-flex-col xpay-items-start">
694
- <div className="xpay-flex">
695
- {`${debouncedAmount} ${srcToken?.symbol}`}
696
- </div>
697
- <div className="xpay-text-sm xpay-text-center xpay-text-white xpay-opacity-50">
698
- {srcChain?.displayName}
699
- </div>
700
- </div>
701
- </div>
702
-
703
- <div className="xpay-w-3.5 xpay-h-3.5">
704
- <ArrowRightIcon />
705
- </div>
706
-
707
- <div className="xpay-flex xpay-gap-2">
708
- <div className="xpay-w-10 xpay-h-10">
709
- {(dstDisplayToken ? dstDisplayToken : dstToken)?.image ? (
710
- <img
711
- className="xpay-w-10 xpay-h-10"
712
- src={
713
- (dstDisplayToken ? dstDisplayToken : dstToken)
714
- ?.image
715
- }
716
- alt={
717
- (dstDisplayToken ? dstDisplayToken : dstToken)?.name
718
- }
719
- />
720
- ) : (
721
- <UnknownTokenLogo
722
- tokenName={"?"}
723
- className="xpay-w-10 xpay-h-10"
724
- />
725
- )}
726
- </div>
727
- <div className="xpay-flex xpay-flex-col xpay-items-start">
728
- <div className="xpay-flex">
729
- {weiToHumanReadable({
730
- amount: route?.estAmountOut || "0",
731
- decimals:
732
- (dstDisplayToken ? dstDisplayToken : dstToken)
733
- ?.decimals || 18,
734
- precisionFractionalPlaces: 4,
735
- })}{" "}
736
- {(dstDisplayToken ? dstDisplayToken : dstToken)?.symbol}
737
- </div>
738
- <div className="xpay-text-sm xpay-text-center xpay-text-white xpay-opacity-50">
739
- {dstChain?.displayName}
740
- </div>
741
- </div>
742
- </div>
743
- </div>
744
-
745
- <div>
746
- <a
747
- href={
748
- srcChain?.chainId !== dstChain?.chainId
749
- ? `${CCIP_EXPLORER}/tx/${transactionSuccessHash}`
750
- : `${
751
- supportedChains.find(
752
- (chain) => chain.chainId === srcChain?.chainId,
753
- )?.transactionExplorer
754
- }/${transactionSuccessHash}`
755
- }
756
- target="_blank"
757
- rel="noreferrer"
758
- className="xpay-flex xpay-items-center xpay-gap-2 xpay-font-bold xpay-no-underline xpay-cursor-pointer xpay-text-center"
759
- aria-label="Show the transaction in the chain explorer"
760
- >
761
- <p className="xpay-bg-gradient-to-r xpay-from-x_blue_light xpay-to-x_blue_dark xpay-bg-clip-text xpay-text-transparent xpay-underline">
762
- View details on Explorer
763
- </p>
764
- <div className="xpay-w-3.5 xpay-h-3.5 xpay-bg-gradient-to-r xpay-text-x_blue_dark">
765
- <ArrowUpRightIcon />
766
- </div>
767
- </a>
768
- </div>
769
- </div>
770
- </div>
771
- ) : (
772
- // Tx Confirmation modal
773
- <>
774
- <div className="xpay-flex xpay-w-full xpay-justify-between xpay-items-center xpay-mx-auto xpay-p-2 xpay-font-light ">
775
- <p className="xpay-text-white xpay-text-xl">Confirmation</p>
776
- <div className="xpay-flex xpay-w-full xpay-justify-end xpay-items-center xpay-mx-auto xpay-p-2">
777
- <div
778
- className="xpay-cursor-pointer xpay-text-white"
779
- onClick={onClose}
780
- >
781
- <CloseIcon />
782
- </div>
783
- </div>
784
- </div>
785
-
786
- <div className="xpay-flex xpay-flex-col xpay-gap-2">
787
- <ConfirmationAmount
788
- amount={ethers.utils
789
- .parseUnits(debouncedAmount, srcToken?.decimals)
790
- .toString()}
791
- chain={srcChain}
792
- token={srcToken}
793
- type="src"
794
- />
795
- </div>
796
-
797
- <div className="xpay-flex xpay-justify-center xpay-globalBorder xpay-rounded-xl xpay-p-[5px] xpay--mt-7 xpay--mb-6 ">
798
- <div className="xpay-flex xpay-items-center xpay-justify-center xpay-rounded-lg xpay-w-8 xpay-h-8 xpay-bg-gradient-to-l xpay-from-[rgba(54,129,198,1)] xpay-to-[rgba(43,74,157,1)] ">
799
- <ArrowDownIcon />
800
- </div>
801
- </div>
802
-
803
- <div className="xpay-flex xpay-flex-col xpay-gap-2">
804
- <ConfirmationAmount
805
- amount={route?.estAmountOut || "0"}
806
- chain={dstChain}
807
- token={dstDisplayToken ? dstDisplayToken : dstToken}
808
- type="dst"
809
- />
810
- </div>
811
- <div className="xpay-flex xpay-flex-col xpay-globalBorder xpay-p-4 xpay-justify-center xpay-rounded-xl xpay-bg-[rgba(15,15,15,1)] xpay-relative">
812
- {route?.transactions.approve && !isAllowanceOk && (
813
- <>
814
- <div className="xpay-flex xpay-justify-between xpay-items-center">
815
- <div className="xpay-flex xpay-items-center xpay-gap-2">
816
- <SignIcon />
817
- <p className="xpay-opacity-50">
818
- {approveTxLoading
819
- ? "Wait for approval confirmation"
820
- : "Approve token spending"}
821
- </p>
822
- </div>
823
- <div className="xpay-flex xpay-items-center">
824
- {approveTxLoading && <Spinner width="5" height="5" />}
825
- {approveTxDone && (
826
- <div className="xpay-text-x_green xpay-w-5 xpay-h-5">
827
- <CheckIcon />
828
- </div>
829
- )}
830
- </div>
831
- </div>
832
- <div className="xpay-w-px xpay-h-6 xpay-mt-1 xpay-mb-1 xpay-ml-2.5 xpay-bg-white xpay-opacity-50"></div>
833
- </>
834
- )}
835
- <div className="xpay-flex xpay-justify-between xpay-items-center">
836
- <div className="xpay-flex xpay-items-center xpay-gap-2">
837
- <SignIcon />
838
- <p className="xpay-opacity-50">
839
- {txLoading
840
- ? "Wait for transaction confirmation"
841
- : "Confirm transaction"}
842
- </p>
843
- </div>
844
- <div className="xpay-flex xpay-items-center">
845
- {txLoading && <Spinner width="5" height="5" />}
846
- </div>
847
- </div>
848
- </div>
849
- </>
850
- )}
851
- </div>
486
+ <ConfirmationView
487
+ txError={transactionError}
488
+ onClose={onClose}
489
+ txSuccessHash={transactionSuccessHash}
490
+ srcChain={srcChain}
491
+ dstChain={dstChain}
492
+ isExpressDelivery={isExpressDelivery}
493
+ srcToken={srcToken}
494
+ amount={amount}
495
+ dstDisplayToken={dstDisplayToken}
496
+ dstToken={dstToken}
497
+ route={route}
498
+ supportedChains={supportedChains}
499
+ approveTxLoading={approveTxLoading}
500
+ approveTxDone={approveTxDone}
501
+ txLoading={txLoading}
502
+ />
852
503
  ) : (
853
504
  // XPay form
854
505
  <form