@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/CHANGELOG.md +12 -0
- package/dist/index.global.js +83 -83
- package/dist/index.js +11 -11
- package/dist/index.mjs +11 -11
- package/package.json +1 -1
- package/src/components/Modal/index.tsx +3 -4
- package/src/components/Swap/Header/index.tsx +1 -1
- package/src/components/Swap/SettingsView/index.tsx +1 -1
- package/src/components/Swap/SwapView/SwapPanel/ChainPanel/ChainPicker/index.tsx +42 -7
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/index.tsx +1 -1
- package/src/components/Swap/index.tsx +1 -1
- package/src/components/TxConfigForm/index.tsx +2 -2
- package/src/config/init.tsx +5 -2
- package/src/context/SwapProvider.tsx +27 -27
- package/tailwind.config.js +1 -1
package/package.json
CHANGED
|
@@ -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>
|
|
@@ -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
|
-
|
|
44
|
+
const baseChains = supportedChains.filter(
|
|
33
45
|
({ web3Environment, swapSupported, bridgeSupported }) =>
|
|
34
46
|
web3Environment === Web3Environment.MAINNET &&
|
|
35
47
|
((bridgeUI && bridgeSupported) || (!bridgeUI && swapSupported)),
|
|
36
48
|
);
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
{
|
|
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">
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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>
|
package/src/config/init.tsx
CHANGED
|
@@ -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({
|
|
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
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
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
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
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 () => {
|