@xswap-link/sdk 0.14.1 → 0.15.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/index.global.js +99 -93
  3. package/dist/index.js +2061 -1846
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +1901 -1689
  6. package/dist/index.mjs.map +1 -1
  7. package/localTheme.ts +1 -1
  8. package/package.json +2 -1
  9. package/postcss.config.js +2 -0
  10. package/src/assets/icons/ChainlinkMarkIcon.tsx +4 -5
  11. package/src/assets/icons/CheckCircleThinIcon.tsx +22 -0
  12. package/src/assets/icons/ChevronDownThinIcon.tsx +39 -0
  13. package/src/assets/icons/ChevronDownWideThinIcon.tsx +18 -0
  14. package/src/assets/icons/ChevronRightThinIcon.tsx +23 -0
  15. package/src/assets/icons/ChevronsUpDownThinIcon.tsx +21 -0
  16. package/src/assets/icons/CloseIcon.tsx +3 -2
  17. package/src/assets/icons/ErrorCircleThinIcon.tsx +22 -0
  18. package/src/assets/icons/InfoThinIcon.tsx +33 -0
  19. package/src/assets/icons/LinkExternalThinIcon.tsx +19 -0
  20. package/src/assets/icons/LoadingRingIcon.tsx +22 -0
  21. package/src/assets/icons/ProgressRingThinIcon.tsx +29 -0
  22. package/src/assets/icons/RedirectThinIcon.tsx +15 -0
  23. package/src/assets/icons/SearchThinIcon.tsx +15 -0
  24. package/src/assets/icons/SignThinIcon.tsx +15 -0
  25. package/src/assets/icons/WalletCheckThinIcon.tsx +24 -0
  26. package/src/assets/icons/index.ts +14 -0
  27. package/src/components/PoweredBy/index.tsx +1 -1
  28. package/src/components/Swap/Header/index.tsx +5 -5
  29. package/src/components/Swap/HistoryView/ActivityCard/index.tsx +110 -115
  30. package/src/components/Swap/HistoryView/index.tsx +10 -7
  31. package/src/components/Swap/ReorderButton/ReorderButton.tsx +7 -4
  32. package/src/components/Swap/SettingsView/Delivery/index.tsx +20 -18
  33. package/src/components/Swap/SettingsView/InfiniteApproval/index.tsx +20 -18
  34. package/src/components/Swap/SettingsView/Slippage/index.tsx +57 -49
  35. package/src/components/Swap/SwapView/ConfirmationView/TokenTiles/index.tsx +72 -0
  36. package/src/components/Swap/SwapView/ConfirmationView/TxOverview/Header/index.tsx +13 -25
  37. package/src/components/Swap/SwapView/ConfirmationView/TxOverview/Steps/index.tsx +65 -113
  38. package/src/components/Swap/SwapView/ConfirmationView/TxOverview/index.tsx +19 -23
  39. package/src/components/Swap/SwapView/ConfirmationView/TxResult/index.tsx +47 -69
  40. package/src/components/Swap/SwapView/FeesPanel/Fees/index.tsx +1 -1
  41. package/src/components/Swap/SwapView/FeesPanel/index.tsx +6 -4
  42. package/src/components/Swap/SwapView/SwapButton/index.tsx +0 -29
  43. package/src/components/Swap/SwapView/SwapPanel/AmountPanel/index.tsx +11 -2
  44. package/src/components/Swap/SwapView/SwapPanel/TokenPanel/ChainPicker/index.tsx +4 -4
  45. package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/NetworkFilter/index.tsx +62 -51
  46. package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/TokenItem/index.tsx +1 -1
  47. package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/index.tsx +94 -43
  48. package/src/components/Swap/SwapView/SwapPanel/TokenPanel/index.tsx +27 -5
  49. package/src/components/Swap/SwapView/SwapPanel/UsdValue/index.tsx +2 -2
  50. package/src/components/Swap/SwapView/SwapPanel/WalletPanel/index.tsx +23 -18
  51. package/src/components/Swap/SwapView/SwapPanel/index.tsx +17 -5
  52. package/src/components/Swap/SwapView/WalletPicker/index.tsx +131 -139
  53. package/src/components/Swap/SwapView/index.tsx +11 -7
  54. package/src/components/Swap/WalletPickerView/index.tsx +65 -0
  55. package/src/components/Swap/index.tsx +23 -6
  56. package/src/components/ToggleButton/index.tsx +6 -6
  57. package/src/components/TokenLogo/index.tsx +1 -1
  58. package/src/components/TxModal/index.tsx +13 -7
  59. package/src/components/global.css +103 -1
  60. package/src/config/fonts.ts +15 -2
  61. package/src/constants/index.ts +4 -0
  62. package/src/context/SwapProvider.tsx +106 -19
  63. package/src/context/TxUIWrapper.tsx +0 -1
  64. package/src/utils/validation.ts +9 -4
  65. package/tailwind.config.js +3 -9
  66. package/src/components/Swap/SwapView/ConfirmationView/TxOverview/ArrowIcon.tsx +0 -13
  67. package/src/components/Swap/SwapView/ConfirmationView/TxOverview/SwapPanel/index.tsx +0 -72
  68. package/src/components/Swap/SwapView/ConfirmationView/TxResult/TokenItem/index.tsx +0 -25
@@ -1,37 +1,25 @@
1
- import { CloseIcon, HelpIcon } from "@src/assets/icons";
2
- import { Tooltip } from "@src/components/Tooltip/index";
3
- import { useRef } from "react";
1
+ import { CloseIcon } from "@src/assets/icons";
4
2
 
5
3
  type Props = {
6
4
  onCloseClick: () => void;
7
5
  };
8
6
 
9
7
  export const Header = ({ onCloseClick }: Props) => {
10
- const tooltipTriggerRef = useRef<SVGSVGElement>(null);
11
-
12
8
  return (
13
- <div className="flex justify-between items-center text-base font-medium">
14
- <div className="text-t_text_primary">Confirmation</div>
15
- <div className="flex gap-4 items-center">
16
- <Tooltip
17
- text="To sign the transaction open the wallet you have used to connect with XSwap."
18
- position="BOTTOM"
19
- triggerRef={tooltipTriggerRef}
20
- id="connect-wallet-to-sign-tx-tooltip"
21
- />
22
-
23
- <HelpIcon
24
- ref={tooltipTriggerRef}
25
- className="cursor-help fill-t_main_accent_light w-[18px] h-[18px]"
26
- />
27
-
28
- <div
29
- className="w-4 h-4 fill-t_text_primary cursor-pointer"
30
- onClick={onCloseClick}
31
- >
9
+ <div className="flex justify-between items-center gap-6">
10
+ <div className="text-2xl font-medium leading-8 tracking-[0.01em] text-t_text_primary">
11
+ Confirmation
12
+ </div>
13
+ <button
14
+ type="button"
15
+ onClick={onCloseClick}
16
+ aria-label="Close"
17
+ className="flex items-center justify-center shrink-0 w-8 h-8 rounded-md bg-t_bg_tertiary bg-opacity-5 text-t_text_primary hover:bg-opacity-10 transition-colors"
18
+ >
19
+ <div className="w-4 h-4 opacity-50 fill-t_text_primary flex items-center justify-center">
32
20
  <CloseIcon />
33
21
  </div>
34
- </div>
22
+ </button>
35
23
  </div>
36
24
  );
37
25
  };
@@ -1,101 +1,57 @@
1
1
  import {
2
- CheckIcon,
3
- SignIcon,
4
- ThumbUpRoundedIcon,
5
- WaitingIcon,
2
+ CheckCircleThinIcon,
3
+ ProgressRingThinIcon,
4
+ SignThinIcon,
5
+ WalletCheckThinIcon,
6
6
  } from "@src/assets/icons";
7
7
  import { useTxUIWrapper } from "@src/context";
8
8
  import { TxStatus } from "@src/models";
9
9
  import { ReactElement, useMemo } from "react";
10
10
 
11
+ type StepState = "pending" | "active" | "completed";
12
+
11
13
  type Step = {
12
- icon: (className: string) => ReactElement;
14
+ icon: ReactElement;
13
15
  title: string;
14
- state: "none" | "triggered" | "completed";
16
+ state: StepState;
15
17
  show: boolean;
16
18
  };
17
19
 
18
- // TODO item's 'show' logic is a bit complicated/weird. Think about an improvement...
19
20
  export const Steps = () => {
20
21
  const { txStatus, txNeedsApproval, txMsg } = useTxUIWrapper();
21
22
 
22
- const items: Step[] = useMemo(
23
- () => [
24
- {
25
- icon: (className) => (
26
- <div className={`${className}`}>
27
- <SignIcon />
28
- </div>
29
- ),
30
- title: "sign approval transaction",
31
- state:
32
- txStatus === TxStatus.SIGNING_APPROVAL
33
- ? "triggered"
34
- : txStatus > TxStatus.SIGNING_APPROVAL
35
- ? "completed"
36
- : "none",
37
- show: txMsg
38
- ? txStatus === TxStatus.SIGNING_APPROVAL ||
39
- txStatus === TxStatus.CONFIRMING_APPROVAL
40
- : txNeedsApproval,
41
- },
42
- {
43
- icon: (className) => (
44
- <div className={`${className}`}>
45
- <ThumbUpRoundedIcon />
46
- </div>
47
- ),
48
- title: "confirming approval transaction...",
49
- state:
50
- txStatus === TxStatus.CONFIRMING_APPROVAL
51
- ? "triggered"
52
- : txStatus > TxStatus.CONFIRMING_APPROVAL
53
- ? "completed"
54
- : "none",
55
- show: txMsg
56
- ? txStatus === TxStatus.SIGNING_APPROVAL ||
57
- txStatus === TxStatus.CONFIRMING_APPROVAL
58
- : txNeedsApproval,
59
- },
23
+ const items: Step[] = useMemo(() => {
24
+ const approvalActive =
25
+ txStatus === TxStatus.SIGNING_APPROVAL ||
26
+ txStatus === TxStatus.CONFIRMING_APPROVAL;
27
+ const txActive =
28
+ txStatus === TxStatus.SIGNING_TX || txStatus === TxStatus.CONFIRMING_TX;
29
+
30
+ return [
60
31
  {
61
- icon: (className) => (
62
- <div className={`${className}`}>
63
- <SignIcon />
64
- </div>
65
- ),
66
- title: "sign transaction",
67
- state:
68
- txStatus === TxStatus.SIGNING_TX
69
- ? "triggered"
70
- : txStatus > TxStatus.SIGNING_TX
71
- ? "completed"
72
- : "none",
73
- show: txMsg
74
- ? txStatus === TxStatus.SIGNING_TX ||
75
- txStatus === TxStatus.CONFIRMING_TX
76
- : true,
32
+ icon: <SignThinIcon className="w-6 h-6" />,
33
+ title: "Please, approve spending first.",
34
+ state: approvalActive
35
+ ? "active"
36
+ : txStatus > TxStatus.CONFIRMING_APPROVAL
37
+ ? "completed"
38
+ : "pending",
39
+ // With a custom tx message (e.g. approval reset) the modal only runs
40
+ // that single transaction, so show just the step it is on.
41
+ show: txMsg ? approvalActive : txNeedsApproval,
77
42
  },
78
43
  {
79
- icon: (className) => (
80
- <div className={`${className}`}>
81
- <ThumbUpRoundedIcon />
82
- </div>
83
- ),
84
- title: "confirming transaction...",
85
- state:
86
- txStatus === TxStatus.CONFIRMING_TX
87
- ? "triggered"
88
- : txStatus > TxStatus.CONFIRMING_TX
89
- ? "completed"
90
- : "none",
91
- show: txMsg
92
- ? txStatus === TxStatus.SIGNING_TX ||
93
- txStatus === TxStatus.CONFIRMING_TX
94
- : true,
44
+ icon: <WalletCheckThinIcon className="w-6 h-6" />,
45
+ title: "Confirm transaction in your wallet.",
46
+ state: txActive
47
+ ? "active"
48
+ : txStatus > TxStatus.CONFIRMING_TX
49
+ ? "completed"
50
+ : "pending",
51
+ show: txMsg ? txActive : true,
95
52
  },
96
- ],
97
- [txMsg, txNeedsApproval, txStatus],
98
- );
53
+ ];
54
+ }, [txMsg, txNeedsApproval, txStatus]);
99
55
 
100
56
  const filteredItems = useMemo(
101
57
  () => items.filter(({ show }) => show),
@@ -103,42 +59,38 @@ export const Steps = () => {
103
59
  );
104
60
 
105
61
  return (
106
- <div className="flex flex-col gap-1">
107
- {filteredItems.map(({ icon, title, state }, index) => (
108
- <div key={title} className="flex flex-col px-4 gap-1">
109
- <div className="flex justify-between items-center">
110
- <div className="flex items-center gap-2">
111
- {icon(
112
- `${
113
- state === "triggered"
114
- ? "fill-t_main_accent_light"
115
- : "fill-t_text_primary opacity-50"
116
- }`,
117
- )}
118
- <div
119
- className={`${
120
- state !== "triggered"
121
- ? "opacity-50"
122
- : state === "triggered" && "text-t_text_secondary"
123
- }`}
124
- >
125
- {title}
126
- </div>
62
+ <div className="flex flex-col rounded-xl bg-t_bg_tertiary bg-opacity-[0.02]">
63
+ {filteredItems.map(({ icon, title, state }) => (
64
+ <div
65
+ key={title}
66
+ className={`flex items-center justify-between gap-4 px-4 sm:px-6 py-4 rounded-lg ${
67
+ state === "active"
68
+ ? "bg-gradient-to-r from-transparent via-t_bg_tertiary/5 to-transparent"
69
+ : ""
70
+ }`}
71
+ >
72
+ <div className="flex items-center gap-4">
73
+ <div
74
+ className={`text-t_text_primary ${
75
+ state === "active" ? "opacity-50" : "opacity-25"
76
+ }`}
77
+ >
78
+ {icon}
127
79
  </div>
128
- <div>
129
- {state === "completed" ? (
130
- <div className="fill-t_success_dark">
131
- <CheckIcon />
132
- </div>
133
- ) : state === "triggered" ? (
134
- <div className="animate-spin-slow fill-t_main_accent_light">
135
- <WaitingIcon />
136
- </div>
137
- ) : null}
80
+ <div
81
+ className={`text-sm leading-5 tracking-[0.01em] text-t_text_primary ${
82
+ state === "active" ? "text-opacity-75" : "text-opacity-50"
83
+ }`}
84
+ >
85
+ {title}
138
86
  </div>
139
87
  </div>
140
- {index !== filteredItems.length - 1 && (
141
- <div className="vertical-separator py-3 ml-2" />
88
+ {state === "completed" ? (
89
+ <CheckCircleThinIcon className="w-6 h-6 shrink-0 text-[#6AE89B]" />
90
+ ) : state === "active" ? (
91
+ <ProgressRingThinIcon className="w-6 h-6 shrink-0 animate-spin-slow text-t_text_primary" />
92
+ ) : (
93
+ <div className="w-6 h-6 shrink-0 rounded-full border border-solid border-t_text_primary border-opacity-20" />
142
94
  )}
143
95
  </div>
144
96
  ))}
@@ -1,4 +1,3 @@
1
- import { Button } from "@src/components";
2
1
  import {
3
2
  CCIP_ROUTER_PROGRAM_ID,
4
3
  FALLBACK_CROSSCHAIN_ESTIMATION_TIME,
@@ -24,10 +23,9 @@ import { renderTxStatus } from "@src/services";
24
23
  import { ContractReceipt, constants, ethers } from "ethers";
25
24
  import { useCallback } from "react";
26
25
  import { FeesPanel } from "../../FeesPanel";
27
- import { ArrowIcon } from "./ArrowIcon";
26
+ import { TokenTiles } from "../TokenTiles";
28
27
  import { Header } from "./Header";
29
28
  import { Steps } from "./Steps";
30
- import { SwapPanel } from "./SwapPanel";
31
29
  import { useWallet } from "@solana/wallet-adapter-react";
32
30
 
33
31
  import {
@@ -443,31 +441,29 @@ export const TxOverview = ({ onCloseClick }: Props) => {
443
441
  ]);
444
442
 
445
443
  return (
446
- <div className="flex flex-col text-t_text_primary gap-5">
444
+ <div className="flex flex-col text-t_text_primary gap-8">
447
445
  <Header onCloseClick={onCloseClick} />
448
446
  {txMsg ? (
449
- <div>{txMsg}</div>
447
+ <div className="text-sm leading-5 tracking-[0.01em] text-t_text_primary text-opacity-75">
448
+ {txMsg}
449
+ </div>
450
450
  ) : (
451
- <>
452
- <div className="relative flex flex-col gap-5 fill-white">
453
- <SwapPanel type="source" />
454
- <ArrowIcon />
455
- <SwapPanel type="destination" />
456
- </div>
457
- <FeesPanel />
458
- </>
451
+ <TokenTiles />
459
452
  )}
453
+ <div className="h-px w-full gradient-sections-separator-container" />
460
454
  {txStatus === TxStatus.SWAP_INIT ? (
461
- <Button
462
- variant="filled-squared"
463
- onClick={() => {
464
- enqueueSwapTx();
465
- }}
466
- type="button"
467
- className="text-t_button_pr_text border-none h-14 text-sm font-bold w-full py-5 cursor-pointer bg-gradient-to-r from-t_main_accent_light to-t_main_accent_dark rounded-lg"
468
- >
469
- Sign and swap
470
- </Button>
455
+ <>
456
+ {!txMsg && <FeesPanel />}
457
+ <button
458
+ type="button"
459
+ onClick={() => {
460
+ enqueueSwapTx();
461
+ }}
462
+ className="text-base font-medium leading-6 tracking-[0.01em] w-full px-6 py-3 cursor-pointer rounded-lg border-none transition-[filter] bg-gradient-to-b from-t_main_accent_light from-50% to-t_main_accent_dark text-t_button_pr_text hover:brightness-105"
463
+ >
464
+ Sign and swap
465
+ </button>
466
+ </>
471
467
  ) : (
472
468
  <Steps />
473
469
  )}
@@ -1,14 +1,10 @@
1
1
  import {
2
- ArrowDownLongIcon,
3
- CloseIcon,
4
- ErrorModalStatusIcon,
5
- LinkExternalIcon,
6
- SuccessModalStatusIcon,
2
+ CheckCircleThinIcon,
3
+ ErrorCircleThinIcon,
4
+ RedirectThinIcon,
7
5
  } from "@src/assets/icons";
8
6
  import { useSwapContext, useTxUIWrapper } from "@src/context";
9
- import { TokenItem } from "./TokenItem";
10
- import { useMemo } from "react";
11
- import { Ecosystem } from "@src/models";
7
+ import { TokenTiles } from "../TokenTiles";
12
8
 
13
9
  type Props = {
14
10
  onCloseClick: () => void;
@@ -16,78 +12,60 @@ type Props = {
16
12
 
17
13
  export const TxResult = ({ onCloseClick }: Props) => {
18
14
  const { txError, txExplorerUrl, txMsg } = useTxUIWrapper();
19
- const {
20
- isExpressDeliveryActive,
21
- srcChain,
22
- srcToken,
23
- dstChain,
24
- dstToken,
25
- srcValue,
26
- dstValue,
27
- bridgeUI,
28
- } = useSwapContext();
29
-
30
- const value = useMemo(() => {
31
- if (bridgeUI && srcChain?.ecosystem === Ecosystem.SOLANA) {
32
- return srcValue;
33
- }
34
- return dstValue;
35
- }, [bridgeUI, srcChain?.ecosystem, srcValue, dstValue]);
15
+ const { isExpressDeliveryActive, srcChain, dstChain } = useSwapContext();
36
16
 
37
17
  return (
38
- <div className="flex flex-col gap-5 text-t_text_primary justify-center items-center">
39
- {txError ? (
40
- <>
41
- <div
42
- className="flex justify-end fill-t_text_primary cursor-pointer w-full"
43
- onClick={onCloseClick}
44
- >
45
- <CloseIcon className="w-3.5 h-3.5" />
46
- </div>
47
- <ErrorModalStatusIcon />
48
- <div className="text-2xl font-bold">Transaction failed</div>
49
- <div className="text-center">{txError}</div>
50
- </>
51
- ) : (
52
- <>
53
- <div
54
- className="flex justify-end fill-t_text_primary cursor-pointer w-full"
55
- onClick={onCloseClick}
56
- >
57
- <CloseIcon className="w-3.5 h-3.5" />
18
+ <div className="flex flex-col gap-8 text-t_text_primary">
19
+ <div className="flex flex-col gap-2">
20
+ <div className="flex items-center gap-3">
21
+ <div className="text-2xl font-medium leading-8 tracking-[0.01em]">
22
+ {txError ? "Transaction Error" : "Transaction Success"}
58
23
  </div>
59
- <SuccessModalStatusIcon />
60
- <div className="flex flex-col items-center">
61
- <div className="text-2xl font-bold">Transaction success!</div>
62
- {!txMsg && srcChain !== dstChain && (
63
- <div className="text-sm font-normal opacity-60">
64
- {`Approximated time of delivery: ${
65
- isExpressDeliveryActive ? "30 sec" : "30 min"
66
- }`}
67
- </div>
68
- )}
24
+ {txError ? (
25
+ <ErrorCircleThinIcon className="w-6 h-6 shrink-0 text-[#F44336]" />
26
+ ) : (
27
+ <CheckCircleThinIcon className="w-6 h-6 shrink-0 text-[#6AE89B]" />
28
+ )}
29
+ </div>
30
+ {txError ? (
31
+ <div className="text-sm leading-5 tracking-[0.01em] text-t_text_primary text-opacity-50">
32
+ {txError}
69
33
  </div>
70
- {!txMsg && (
71
- <div className="flex items-center gap-2">
72
- <TokenItem chain={srcChain} token={srcToken} value={srcValue} />
73
- <div className="-rotate-90 flex justify-center w-8 fill-t_text_primary opacity-50">
74
- <ArrowDownLongIcon />
75
- </div>
76
- <TokenItem chain={dstChain} token={dstToken} value={value} />
34
+ ) : (
35
+ !txMsg &&
36
+ srcChain !== dstChain && (
37
+ <div className="text-sm leading-5 tracking-[0.01em] text-t_text_primary text-opacity-50">
38
+ {`Approximated time of delivery: ${
39
+ isExpressDeliveryActive ? "30 sec" : "30 min"
40
+ }`}
77
41
  </div>
78
- )}
42
+ )
43
+ )}
44
+ </div>
45
+ {!txMsg && <TokenTiles />}
46
+ <div className="h-px w-full gradient-sections-separator-container" />
47
+ <button
48
+ type="button"
49
+ onClick={onCloseClick}
50
+ className="w-full px-6 py-3 rounded-lg border-none cursor-pointer bg-t_bg_tertiary bg-opacity-5 text-sm font-medium leading-6 tracking-[0.01em] text-t_text_primary text-opacity-80 hover:bg-opacity-10 transition-colors"
51
+ >
52
+ Continue
53
+ </button>
54
+ {!txMsg && !txError && (
55
+ <div className="w-full flex gap-3 items-center">
79
56
  <a
80
57
  href={txExplorerUrl}
81
58
  target="_blank"
82
59
  rel="noreferrer"
83
- className="flex gap-4 items-center mb-2 fill-t_main_accent_light"
60
+ className="flex items-center gap-1.5 text-sm text-t_text_primary text-opacity-25 hover:text-opacity-50 transition-colors"
84
61
  >
85
- <p className="text-t_text_secondary underline">
86
- View details on Explorer
87
- </p>
88
- <LinkExternalIcon />
62
+ View On Explorer{" "}
63
+ <div className="w-6 h-6 bg-t_bg_tertiary bg-opacity-5 rounded-[4px] flex items-center justify-center">
64
+ <RedirectThinIcon className="w-3 h-3" />
65
+ </div>
89
66
  </a>
90
- </>
67
+ <div className="flex-1 h-px bg-t_text_primary bg-opacity-10" />
68
+ </div>
91
69
  )}
92
70
  </div>
93
71
  );
@@ -47,7 +47,7 @@ export const Fees = ({
47
47
  },
48
48
  ]
49
49
  : []),
50
- { name: "Price Tolerance: ", value: `${slippage}%` },
50
+ { name: "Slippage: ", value: `${slippage}%` },
51
51
  {
52
52
  name: "Min. Received: ",
53
53
  value: `${
@@ -1,4 +1,4 @@
1
- import { CaretDownIcon } from "@src/assets/icons";
1
+ import { ChevronDownThinIcon } from "@src/assets/icons";
2
2
  import { Skeleton } from "@src/components";
3
3
  import { useSwapContext } from "@src/context";
4
4
  import { safeBigNumberFrom, weiToHumanReadable } from "@src/utils";
@@ -176,7 +176,7 @@ export const FeesPanel = () => {
176
176
  isFetchingSolanaFee);
177
177
 
178
178
  return (
179
- <div className="flex flex-col rounded-xl py-2 px-4 sm:px-6 bg-gradient-to-r from-t_bg_tertiary/[0.02] to-t_bg_tertiary/0">
179
+ <div className="flex flex-col rounded-xl py-3 px-4 sm:px-6 bg-gradient-to-r from-t_bg_tertiary/[0.02] to-t_bg_tertiary/0">
180
180
  <button
181
181
  aria-label={`${expanded ? "Collapse" : "Expand"} fees panel`}
182
182
  type="button"
@@ -200,12 +200,14 @@ export const FeesPanel = () => {
200
200
  </>
201
201
  )}
202
202
  </div>
203
+ {/* The 24px glyph has 8px of built-in whitespace on each side; pull the
204
+ right side back so the chevron sits flush with the panel padding. */}
203
205
  <div
204
- className={`flex items-center justify-center w-6 h-6 fill-t_text_primary opacity-75 transition-transform [&_svg]:w-2.5 [&_svg]:h-[5px] ${
206
+ className={`flex items-center justify-center w-6 h-6 -mr-2 text-t_text_primary opacity-50 transition-transform ${
205
207
  expanded ? "rotate-180" : ""
206
208
  }`}
207
209
  >
208
- <CaretDownIcon />
210
+ <ChevronDownThinIcon />
209
211
  </div>
210
212
  </div>
211
213
  {expanded && <Fees solanaBridgeFee={solanaBridgeFee} />}
@@ -1,4 +1,3 @@
1
- import { Modal } from "@src/components/Modal";
2
1
  import { useSwapContext, useTxUIWrapper } from "@src/context";
3
2
  import { useWallet } from "@src/context/WalletProvider";
4
3
  import { ADDRESSES } from "@src/contracts";
@@ -10,7 +9,6 @@ import { safeBigNumberFrom } from "@src/utils";
10
9
  import { BigNumber } from "ethers";
11
10
  import { useCallback, useEffect, useMemo, useState } from "react";
12
11
  import { useAccount, useSwitchChain } from "wagmi";
13
- import { WalletPicker } from "../WalletPicker";
14
12
 
15
13
  type Button = {
16
14
  text: string;
@@ -53,11 +51,8 @@ export const SwapButton = () => {
53
51
  } = useNetworks();
54
52
 
55
53
  const {
56
- openEVMWalletModal,
57
54
  setOpenEVMWalletModal,
58
- openSolanaWalletModal,
59
55
  setOpenSolanaWalletModal,
60
- openSuiWalletModal,
61
56
  setOpenSuiWalletModal,
62
57
  solana,
63
58
  sui,
@@ -314,30 +309,6 @@ export const SwapButton = () => {
314
309
 
315
310
  return (
316
311
  <>
317
- {openEVMWalletModal && (
318
- <Modal onClose={() => setOpenEVMWalletModal(false)}>
319
- <WalletPicker
320
- ecosystem={Ecosystem.EVM}
321
- onClose={() => setOpenEVMWalletModal(false)}
322
- />
323
- </Modal>
324
- )}
325
- {openSolanaWalletModal && (
326
- <Modal onClose={() => setOpenSolanaWalletModal(false)}>
327
- <WalletPicker
328
- ecosystem={Ecosystem.SOLANA}
329
- onClose={() => setOpenSolanaWalletModal(false)}
330
- />
331
- </Modal>
332
- )}
333
- {openSuiWalletModal && (
334
- <Modal onClose={() => setOpenSuiWalletModal(false)}>
335
- <WalletPicker
336
- ecosystem={Ecosystem.SUI}
337
- onClose={() => setOpenSuiWalletModal(false)}
338
- />
339
- </Modal>
340
- )}
341
312
  <button
342
313
  type="button"
343
314
  disabled={button.disabled}
@@ -22,10 +22,11 @@ export const AmountPanel = ({ type }: Props) => {
22
22
  setSrcValue,
23
23
  isFetchingRoute,
24
24
  bridgeUI,
25
+ isAsyncDataLoaded,
25
26
  } = useSwapContext();
26
27
 
27
28
  const onMaxClick = () => {
28
- if (!srcTokenBalanceWei) {
29
+ if (!srcToken || !srcTokenBalanceWei) {
29
30
  return;
30
31
  }
31
32
  setSrcValue(
@@ -58,6 +59,14 @@ export const AmountPanel = ({ type }: Props) => {
58
59
  dstChain,
59
60
  ]);
60
61
 
62
+ if (!isAsyncDataLoaded) {
63
+ return (
64
+ <div className="flex items-center flex-1 min-w-0">
65
+ <Skeleton className="w-[100px] h-8" />
66
+ </div>
67
+ );
68
+ }
69
+
61
70
  return (
62
71
  <div className="flex items-center gap-3 flex-1 min-w-0 overflow-hidden text-left">
63
72
  {type === "source" ? (
@@ -69,7 +78,7 @@ export const AmountPanel = ({ type }: Props) => {
69
78
  value={srcValue}
70
79
  onChange={(value) => setSrcValue(value)}
71
80
  />
72
- {!!srcTokenBalanceWei && (
81
+ {!!srcToken && !!srcTokenBalanceWei && (
73
82
  <button
74
83
  type="button"
75
84
  onClick={onMaxClick}
@@ -1,4 +1,4 @@
1
- import { CloseIcon, SearchIcon, WarningIcon } from "@src/assets/icons";
1
+ import { CloseIcon, SearchThinIcon, WarningIcon } from "@src/assets/icons";
2
2
  import { Chain } from "@src/models";
3
3
  import { useEffect, useMemo, useRef, useState } from "react";
4
4
  import { Virtuoso } from "react-virtuoso";
@@ -56,7 +56,7 @@ export const ChainPicker = ({
56
56
  return (
57
57
  <>
58
58
  <div className="flex justify-between items-center mb-6">
59
- <div className="text-2xl leading-8 tracking-[0.01em] text-t_text_primary">
59
+ <div className="text-2xl font-medium leading-8 tracking-[0.01em] text-t_text_primary">
60
60
  Select Network
61
61
  </div>
62
62
  <button
@@ -72,8 +72,8 @@ export const ChainPicker = ({
72
72
  </div>
73
73
 
74
74
  <div className="flex items-center gap-2 h-14 px-4 rounded-xl bg-t_bg_tertiary bg-opacity-[0.03] border border-solid border-t_text_primary border-opacity-5 mb-6">
75
- <div className="fill-t_text_primary opacity-50 [&_svg]:w-4 [&_svg]:h-4 flex items-center shrink-0">
76
- <SearchIcon />
75
+ <div className="text-t_text_primary opacity-60 flex items-center shrink-0">
76
+ <SearchThinIcon />
77
77
  </div>
78
78
  <input
79
79
  ref={chainSearchRef}