@xswap-link/sdk 0.9.4 → 0.9.6

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": "@xswap-link/sdk",
3
- "version": "0.9.4",
3
+ "version": "0.9.6",
4
4
  "description": "JavaScript SDK for XSwap platform",
5
5
  "homepage": "https://github.com/xswap-link/xswap-sdk",
6
6
  "repository": {
@@ -35,11 +35,10 @@ export const Modal: FC<{
35
35
  className || ""
36
36
  }`}
37
37
  onMouseDown={(e) => {
38
- e.stopPropagation();
39
- e.nativeEvent.stopImmediatePropagation();
40
- e.preventDefault();
41
-
42
38
  if (e.target === e.currentTarget && overlay) {
39
+ e.stopPropagation();
40
+ e.nativeEvent.stopImmediatePropagation();
41
+ e.preventDefault();
43
42
  onClose();
44
43
  }
45
44
  }}
@@ -8,7 +8,7 @@ export const Header = ({ onClose }: Props) => {
8
8
  const { tab, bridgeUI } = useSwapContext();
9
9
 
10
10
  return (
11
- <div className="flex justify-between">
11
+ <div className="flex justify-between mt-2 px-4">
12
12
  <div className="text-xl font-sans-bold font-bold">
13
13
  {tab === "Swap" && bridgeUI ? "Bridge" : tab}
14
14
  </div>
@@ -4,7 +4,7 @@ import { Slippage } from "./Slippage";
4
4
 
5
5
  export const SettingsView = () => {
6
6
  return (
7
- <div className="flex flex-col gap-5">
7
+ <div className="flex flex-col gap-5 px-4">
8
8
  <Delivery />
9
9
  <InfiniteApproval />
10
10
  <Slippage />
@@ -1,10 +1,11 @@
1
- import { CloseIcon } from "@src/assets/icons";
1
+ import { CloseIcon, SearchIcon } from "@src/assets/icons";
2
2
  import { useSwapContext } from "@src/context";
3
3
  import { Chain, Web3Environment } from "@src/models";
4
- import { useMemo } from "react";
4
+ import { useMemo, useState, useRef, useEffect } from "react";
5
5
  import { Virtuoso } from "react-virtuoso";
6
6
  import { SwapPanelType } from "../../../../SwapView";
7
7
  import { ChainItem } from "./ChainItem";
8
+ import { TextInput } from "@src/components";
8
9
 
9
10
  type Props = {
10
11
  type: SwapPanelType;
@@ -28,13 +29,34 @@ export const ChainPicker = ({
28
29
  supportedChains,
29
30
  } = useSwapContext();
30
31
 
32
+ const [searchValue, setSearchValue] = useState("");
33
+ const chainSearchRef = useRef<HTMLInputElement | null>(null);
34
+
35
+ useEffect(() => {
36
+ if (chainSearchRef.current) {
37
+ setTimeout(() => {
38
+ chainSearchRef.current?.focus();
39
+ }, 10);
40
+ }
41
+ }, []);
42
+
31
43
  const filteredChains = useMemo(() => {
32
- return supportedChains.filter(
44
+ const baseChains = supportedChains.filter(
33
45
  ({ web3Environment, swapSupported, bridgeSupported }) =>
34
46
  web3Environment === Web3Environment.MAINNET &&
35
47
  ((bridgeUI && bridgeSupported) || (!bridgeUI && swapSupported)),
36
48
  );
37
- }, [bridgeUI, supportedChains]);
49
+
50
+ if (!searchValue) return baseChains;
51
+
52
+ return baseChains.filter((chain) => {
53
+ const searchLower = searchValue.toLowerCase();
54
+ return (
55
+ chain.displayName.toLowerCase().includes(searchLower) ||
56
+ chain.chainId.toLowerCase().includes(searchLower)
57
+ );
58
+ });
59
+ }, [bridgeUI, supportedChains, searchValue]);
38
60
 
39
61
  const select = (selectedChainId: string) => {
40
62
  const chain = supportedChains.find(
@@ -128,9 +150,22 @@ export const ChainPicker = ({
128
150
  <CloseIcon />
129
151
  </div>
130
152
  </div>
131
- <div className="horizontal-separator" />
153
+
154
+ <TextInput
155
+ ref={chainSearchRef}
156
+ inputIcon={
157
+ <div className="fill-t_text_primary">
158
+ <SearchIcon />
159
+ </div>
160
+ }
161
+ placeholder="Search chain name"
162
+ value={searchValue}
163
+ handleChange={setSearchValue}
164
+ />
165
+
166
+ <div className="horizontal-separator mt-4" />
132
167
  <div className="h-full pt-4">
133
- {filteredChains.length ? (
168
+ {sortedChains.length ? (
134
169
  <Virtuoso
135
170
  style={{ height: "100%" }}
136
171
  data={sortedChains}
@@ -144,7 +179,7 @@ export const ChainPicker = ({
144
179
  )}
145
180
  />
146
181
  ) : (
147
- <div className="flex justify-center mt-4">"No chain found."</div>
182
+ <div className="flex justify-center mt-4">No chain found.</div>
148
183
  )}
149
184
  </div>
150
185
  </div>
@@ -77,7 +77,7 @@ export const TokenPanel = ({ chain, token, type, className }: Props) => {
77
77
  return (
78
78
  <>
79
79
  {tokenPickerModalOpen && (
80
- <Modal onClose={() => setTokenPickerModalOpen(false)} className="z-50">
80
+ <Modal onClose={() => setTokenPickerModalOpen(false)} className="z-[3]">
81
81
  <TokenPicker
82
82
  type={type}
83
83
  chain={chain!}
@@ -25,7 +25,7 @@ export const Swap = ({ onClose }: Props) => {
25
25
 
26
26
  return (
27
27
  <div
28
- className={`relative flex flex-col gap-5 p-4 text-t_text_primary bg-t_bg_primary rounded-3xl flex-1`}
28
+ className={`relative flex flex-col gap-4 p-2 text-t_text_primary bg-t_bg_primary rounded-2xl flex-1`}
29
29
  >
30
30
  <Header onClose={onClose} />
31
31
  {view}
@@ -175,13 +175,13 @@ export const TxConfigForm = ({
175
175
  className="top-0 left-0 right-0 bottom-0 bg-[rgba(0,0,0,0.8)] fixed flex flex-col items-center justify-center z-10"
176
176
  onMouseDown={onBackdropClick}
177
177
  >
178
- <div className="relative bg-t_bg_primary rounded-3xl overflow-auto text-t_text_primary border-2 border-solid border-[rgba(255,255,255,0.1)] w-x_modal min-w-x_modal max-w-x_modal min-h-[532px]">
178
+ <div className="relative bg-t_bg_primary rounded-2xl overflow-auto text-t_text_primary border-[1px] border-solid border-[rgba(255,255,255,0.1)] w-x_modal min-w-x_modal max-w-x_modal min-h-[532px]">
179
179
  <Swap onSubmit={onSubmit} onClose={onClose} />
180
180
  <PoweredBy />
181
181
  </div>
182
182
  </div>
183
183
  ) : (
184
- <div className="bg-t_bg_primary rounded-3xl overflow-auto text-t_text_primary border-2 border-solid border-[rgba(255,255,255,0.1)] min-h-[532px] w-x_modal min-w-x_modal max-w-x_modal flex flex-col">
184
+ <div className="bg-t_bg_primary rounded-2xl overflow-auto text-t_text_primary border-[1px] border-solid border-[rgba(255,255,255,0.1)] min-h-[532px] w-x_modal min-w-x_modal max-w-x_modal flex flex-col">
185
185
  <Swap onSubmit={() => {}} onClose={() => {}} />
186
186
  <PoweredBy />
187
187
  </div>
@@ -1,8 +1,8 @@
1
1
  import { WaitingForInit } from "@src/components/WaitingForInit";
2
+ import { isServer } from "@src/utils";
2
3
  import { createRoot, Root } from "react-dom/client";
3
4
  import CSS from "../components/global.css";
4
5
  import { fontDefinitions } from "./fonts";
5
- import { isServer } from "@src/utils";
6
6
 
7
7
  export let xpayRoot: Root | null = null;
8
8
  export let xpayShadowRoot: ShadowRoot | null = null;
@@ -63,7 +63,10 @@ const setupFonts = () => {
63
63
 
64
64
  const createXPayRoot = async () => {
65
65
  const xswapElement = document.createElement("div");
66
- xpayShadowRoot = xswapElement.attachShadow({ mode: "open" });
66
+ xpayShadowRoot = xswapElement.attachShadow({
67
+ mode: "open",
68
+ delegatesFocus: true,
69
+ });
67
70
  xswapElement.setAttribute("id", "xpay-root");
68
71
  document.body.appendChild(xswapElement);
69
72
  xpayRoot = createRoot(xpayShadowRoot);
@@ -257,11 +257,14 @@ export const SwapProvider = ({
257
257
  );
258
258
 
259
259
  const routeAbortController = useRef<AbortController | null>(null);
260
- const getTokenBalancesNonce = useRef(0);
261
260
  const refreshSelectedTokenBalanceNonce = useRef(crypto.randomUUID());
262
261
 
263
262
  const { history } = useHistory();
264
263
 
264
+ const [tokenBalances, setTokenBalances] = useState<
265
+ Record<string, Record<string, string>>
266
+ >({});
267
+
265
268
  useEffect(() => {
266
269
  if (supportedChains.length > 0) {
267
270
  const chainIds = supportedChains.map((chain) => chain.chainId);
@@ -525,7 +528,6 @@ export const SwapProvider = ({
525
528
  );
526
529
 
527
530
  setRoute(route);
528
- setFetchingRoute(false);
529
531
  routeAbortController.current = null;
530
532
  } catch (error) {
531
533
  if (error !== DEFAULT_REQUEST_ABORT_MSG) {
@@ -533,6 +535,8 @@ export const SwapProvider = ({
533
535
  setError("Could not find route!");
534
536
  setRoute(undefined);
535
537
  }
538
+ } finally {
539
+ setFetchingRoute(false);
536
540
  }
537
541
  // eslint-disable-next-line react-hooks/exhaustive-deps
538
542
  }, [
@@ -551,6 +555,14 @@ export const SwapProvider = ({
551
555
  quoteRoute();
552
556
  }, [quoteRoute]);
553
557
 
558
+ useEffect(() => {
559
+ if (address && supportedChains.length > 0) {
560
+ getBalances({ walletAddress: address }).then((balances) => {
561
+ setTokenBalances(balances);
562
+ });
563
+ }
564
+ }, [address, supportedChains.length]);
565
+
554
566
  useEffect(() => {
555
567
  (async () => {
556
568
  // source chain
@@ -617,41 +629,29 @@ export const SwapProvider = ({
617
629
  }
618
630
  setDstChainOtherTokensOptions(dstOtherTokenOptions);
619
631
 
620
- if (address) {
621
- const nonce = Date.now();
622
-
623
- getTokenBalancesNonce.current = nonce;
624
-
625
- const tokenBalancesResponse = await getBalances({
626
- walletAddress: address,
627
- });
632
+ const addBalances = (tokenOptions: TokenOption[]) => {
633
+ return tokenOptions.map((token) => ({
634
+ ...token,
635
+ balance: BigNumber.from(
636
+ tokenBalances[token.chainId]?.[token.address] || 0,
637
+ ),
638
+ }));
639
+ };
628
640
 
629
- const addBalances = (tokenOptions: TokenOption[]) => {
630
- return tokenOptions.map((token) => ({
631
- ...token,
632
- balance: BigNumber.from(
633
- tokenBalancesResponse[token.chainId][token.address] || 0,
634
- ),
635
- }));
636
- };
637
-
638
- if (getTokenBalancesNonce.current === nonce) {
639
- setSrcChainTokensOptions(addBalances(srcTokenOptions));
640
- setDstChainTokensOptions(addBalances(dstTokenOptions));
641
- setSrcChainOtherTokensOptions(addBalances(srcOtherTokenOptions));
642
- setDstChainOtherTokensOptions(addBalances(dstOtherTokenOptions));
643
- }
644
- }
641
+ setSrcChainTokensOptions(addBalances(srcTokenOptions));
642
+ setDstChainTokensOptions(addBalances(dstTokenOptions));
643
+ setSrcChainOtherTokensOptions(addBalances(srcOtherTokenOptions));
644
+ setDstChainOtherTokensOptions(addBalances(dstOtherTokenOptions));
645
645
  })();
646
646
  }, [
647
647
  bridgeUI,
648
648
  srcChain,
649
649
  dstChain,
650
- address,
651
650
  getTokenOptions,
652
651
  supportedChains,
653
652
  srcToken?.symbol,
654
653
  dstToken?.symbol,
654
+ tokenBalances,
655
655
  ]);
656
656
 
657
657
  const refreshBalance = useCallback(async () => {
@@ -83,7 +83,7 @@ export default {
83
83
  x_swap_secondary_active: "#e0e7fa",
84
84
  },
85
85
  minWidth: {
86
- x_modal: "var(--modal-width, 360px)",
86
+ x_modal: "var(--modal-width, 340px)",
87
87
  },
88
88
  width: {
89
89
  x_modal: "var(--modal-width)",