@xswap-link/sdk 0.6.10 → 0.7.0
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 +6 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.global.js +108 -108
- package/dist/index.js +10 -10
- package/dist/index.mjs +10 -10
- package/package.json +1 -1
- package/src/components/Modal/index.tsx +48 -41
- package/src/components/Swap/SwapView/SwapButton/index.tsx +28 -21
- package/src/components/Swap/SwapView/SwapPanel/ChainPanel/ChainPicker/index.tsx +4 -5
- package/src/components/Swap/SwapView/SwapPanel/ChainPanel/index.tsx +16 -14
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/TokenItem/index.tsx +9 -5
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/index.tsx +2 -4
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/index.tsx +19 -18
- package/src/components/Swap/SwapView/WalletPicker/index.tsx +7 -6
- package/src/components/TxConfigForm/index.tsx +15 -18
- package/src/components/TxModal/index.tsx +59 -0
- package/src/components/index.ts +1 -0
- package/src/context/TxUIWrapper.tsx +5 -5
- package/src/hooks/index.ts +0 -1
- package/src/models/payloads/ModalIntegrationPayload.ts +2 -2
- package/src/services/integrations/transactions.ts +20 -17
- package/src/context/ModalProvider.tsx +0 -63
- package/src/hooks/usePortal.ts +0 -79
package/package.json
CHANGED
|
@@ -1,52 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { createPortal } from "react-dom";
|
|
1
|
+
import { useSwapContext } from "@src/context";
|
|
2
|
+
import { FC, ReactNode } from "react";
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
/**
|
|
5
|
+
* This component was created to meet the following requirements:
|
|
6
|
+
* - Modals needs to be inside the shadow root,
|
|
7
|
+
* - Modals needs to be inside all app's main contexts,
|
|
8
|
+
* - Modals' need to rerender on props change.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```
|
|
12
|
+
* const [open, setOpen] = useState(false);
|
|
13
|
+
*
|
|
14
|
+
* return (
|
|
15
|
+
* <>
|
|
16
|
+
* { open && <Modal onClose={() => setOpen(false)}>...</Modal>}
|
|
17
|
+
*
|
|
18
|
+
* <button onClick={() => setOpen(true)}>Open modal</button>
|
|
19
|
+
* </>
|
|
20
|
+
* );
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const Modal: FC<{
|
|
11
24
|
className?: string;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
onCloseClick,
|
|
17
|
-
type = "waiting",
|
|
18
|
-
className,
|
|
19
|
-
}: Props) => {
|
|
20
|
-
const onBackdropClick = (e: MouseEvent<HTMLDivElement>) => {
|
|
21
|
-
e.stopPropagation();
|
|
22
|
-
e.nativeEvent.stopImmediatePropagation();
|
|
23
|
-
if (e.target === e.currentTarget) {
|
|
24
|
-
onCloseClick();
|
|
25
|
-
}
|
|
26
|
-
};
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
onClose: () => void;
|
|
27
|
+
}> = ({ className, children, onClose }) => {
|
|
28
|
+
const { overlay } = useSwapContext();
|
|
27
29
|
|
|
28
|
-
return
|
|
30
|
+
return (
|
|
29
31
|
<div
|
|
30
|
-
className=
|
|
31
|
-
|
|
32
|
+
className={`${
|
|
33
|
+
overlay ? "fixed bg-[rgba(0,0,0,0.8)]" : "absolute"
|
|
34
|
+
} top-0 left-0 right-0 bottom-0 flex items-center justify-center z-10 ${
|
|
35
|
+
className || ""
|
|
36
|
+
}`}
|
|
37
|
+
onMouseDown={(e) => {
|
|
38
|
+
e.stopPropagation();
|
|
39
|
+
e.nativeEvent.stopImmediatePropagation();
|
|
40
|
+
e.preventDefault();
|
|
41
|
+
|
|
42
|
+
if (e.target === e.currentTarget && overlay) {
|
|
43
|
+
onClose();
|
|
44
|
+
}
|
|
45
|
+
}}
|
|
32
46
|
>
|
|
33
47
|
<div
|
|
34
|
-
className=
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
? "border-t_warning_dark"
|
|
41
|
-
: type === "waiting"
|
|
42
|
-
? "border-t_main_accent_dark"
|
|
43
|
-
: "border-t_text_primary border-opacity-10"
|
|
44
|
-
} ${className}`}
|
|
48
|
+
className="flex flex-col bg-t_bg_primary x-border rounded-3xl p-4 w-full min-w-[340px]"
|
|
49
|
+
style={{
|
|
50
|
+
height: overlay ? "600px" : "100%",
|
|
51
|
+
maxWidth: "480px",
|
|
52
|
+
maxHeight: "100%",
|
|
53
|
+
}}
|
|
45
54
|
>
|
|
46
55
|
{children}
|
|
47
56
|
</div>
|
|
48
|
-
</div
|
|
49
|
-
xpayShadowRoot!,
|
|
50
|
-
id,
|
|
57
|
+
</div>
|
|
51
58
|
);
|
|
52
59
|
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
import { Modal } from "@src/components/Modal";
|
|
1
2
|
import { useSwapContext, useTxUIWrapper } from "@src/context";
|
|
2
|
-
import {
|
|
3
|
+
import { ADDRESSES } from "@src/contracts";
|
|
4
|
+
import { specialApprovalTokens } from "@src/contracts/specialApprovalTokens";
|
|
5
|
+
import useNetworks from "@src/hooks/networkManagement/useNetworks";
|
|
6
|
+
import { useERC20Token } from "@src/hooks/useERC20Token";
|
|
3
7
|
import { TxStatus } from "@src/models";
|
|
4
8
|
import { safeBigNumberFrom } from "@src/utils";
|
|
9
|
+
import { BigNumber } from "ethers";
|
|
5
10
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
6
11
|
import { useAccount, useSwitchChain } from "wagmi";
|
|
7
12
|
import { WalletPicker } from "../WalletPicker";
|
|
8
|
-
import { BigNumber } from "ethers";
|
|
9
|
-
import useNetworks from "@src/hooks/networkManagement/useNetworks";
|
|
10
|
-
import { useERC20Token } from "@src/hooks/useERC20Token";
|
|
11
|
-
import { ADDRESSES } from "@src/contracts";
|
|
12
|
-
import { specialApprovalTokens } from "@src/contracts/specialApprovalTokens";
|
|
13
13
|
|
|
14
14
|
type Button = {
|
|
15
15
|
text: string;
|
|
@@ -20,7 +20,7 @@ type Button = {
|
|
|
20
20
|
export const SwapButton = () => {
|
|
21
21
|
const { address, chainId } = useAccount();
|
|
22
22
|
const { switchChainAsync } = useSwitchChain();
|
|
23
|
-
const
|
|
23
|
+
const [connectWalletModalOpen, setConnectWalletModalOpen] = useState(false);
|
|
24
24
|
const { integrationConfig } = useSwapContext();
|
|
25
25
|
|
|
26
26
|
const {
|
|
@@ -113,7 +113,7 @@ export const SwapButton = () => {
|
|
|
113
113
|
? "Connect wallet"
|
|
114
114
|
: "Connect wallet first",
|
|
115
115
|
fn: () => {
|
|
116
|
-
|
|
116
|
+
setConnectWalletModalOpen(true);
|
|
117
117
|
},
|
|
118
118
|
disabled: !integrationConfig.defaultWalletPicker,
|
|
119
119
|
};
|
|
@@ -218,7 +218,6 @@ export const SwapButton = () => {
|
|
|
218
218
|
isFetchingRoute,
|
|
219
219
|
currentTokenAllowance,
|
|
220
220
|
integrationConfig.defaultWalletPicker,
|
|
221
|
-
openModal,
|
|
222
221
|
switchChainAsync,
|
|
223
222
|
enqueueTransaction,
|
|
224
223
|
approve,
|
|
@@ -229,17 +228,25 @@ export const SwapButton = () => {
|
|
|
229
228
|
]);
|
|
230
229
|
|
|
231
230
|
return (
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
231
|
+
<>
|
|
232
|
+
{connectWalletModalOpen && (
|
|
233
|
+
<Modal onClose={() => setConnectWalletModalOpen(false)}>
|
|
234
|
+
<WalletPicker onClose={() => setConnectWalletModalOpen(false)} />
|
|
235
|
+
</Modal>
|
|
236
|
+
)}
|
|
237
|
+
|
|
238
|
+
<button
|
|
239
|
+
type="button"
|
|
240
|
+
disabled={button.disabled}
|
|
241
|
+
onClick={button.fn}
|
|
242
|
+
className={`text-xl w-full py-5 cursor-pointer disabled:cursor-not-allowed rounded-2xl border-none ${
|
|
243
|
+
button.disabled
|
|
244
|
+
? "bg-t_button_pr_off_bg text-t_button_pr_off_text"
|
|
245
|
+
: "bg-gradient-to-r from-t_main_accent_light to-t_main_accent_dark text-t_button_pr_text"
|
|
246
|
+
}`}
|
|
247
|
+
>
|
|
248
|
+
{button.text}
|
|
249
|
+
</button>
|
|
250
|
+
</>
|
|
244
251
|
);
|
|
245
252
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { CloseIcon } from "@src/assets/icons";
|
|
2
|
-
import { useModal } from "@src/context/ModalProvider";
|
|
3
2
|
import { Chain, Web3Environment } from "@src/models";
|
|
4
3
|
import { useMemo } from "react";
|
|
5
4
|
import { Virtuoso } from "react-virtuoso";
|
|
@@ -11,15 +10,15 @@ type Props = {
|
|
|
11
10
|
supportedChains: Chain[];
|
|
12
11
|
setSrcChain: (chain: Chain) => void;
|
|
13
12
|
setDstChain: (chain: Chain) => void;
|
|
13
|
+
onClose: () => void;
|
|
14
14
|
};
|
|
15
15
|
export const ChainPicker = ({
|
|
16
16
|
type,
|
|
17
17
|
supportedChains,
|
|
18
18
|
setSrcChain,
|
|
19
19
|
setDstChain,
|
|
20
|
+
onClose,
|
|
20
21
|
}: Props) => {
|
|
21
|
-
const { closeModal } = useModal();
|
|
22
|
-
|
|
23
22
|
const filteredChains = useMemo(() => {
|
|
24
23
|
return supportedChains.filter(
|
|
25
24
|
({ web3Environment, swapSupported }) =>
|
|
@@ -39,7 +38,7 @@ export const ChainPicker = ({
|
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
type === "source" ? setSrcChain(chain) : setDstChain(chain);
|
|
42
|
-
|
|
41
|
+
onClose();
|
|
43
42
|
};
|
|
44
43
|
|
|
45
44
|
return (
|
|
@@ -48,7 +47,7 @@ export const ChainPicker = ({
|
|
|
48
47
|
<div className="text-base/4 text-t_text_primary mb-4">{`Pick ${type} chain`}</div>
|
|
49
48
|
<div
|
|
50
49
|
className="w-4 h-4 fill-t_text_primary cursor-pointer"
|
|
51
|
-
onClick={
|
|
50
|
+
onClick={onClose}
|
|
52
51
|
>
|
|
53
52
|
<CloseIcon />
|
|
54
53
|
</div>
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { ArrowDownIcon } from "@src/assets/icons";
|
|
2
|
+
import { Modal } from "@src/components/Modal";
|
|
2
3
|
import { useSwapContext } from "@src/context";
|
|
3
|
-
import { useModal } from "@src/context/ModalProvider";
|
|
4
4
|
import { Chain } from "@src/models";
|
|
5
|
-
import { useCallback, useEffect } from "react";
|
|
5
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
6
6
|
import { useAccount } from "wagmi";
|
|
7
7
|
import { SwapPanelType } from "../../../SwapView";
|
|
8
8
|
import { ChainPicker } from "./ChainPicker";
|
|
9
|
-
import { useMemo } from "react";
|
|
10
9
|
|
|
11
10
|
type Props = {
|
|
12
11
|
chain: Chain | undefined;
|
|
@@ -51,7 +50,7 @@ export const ChainPanel = ({ chain, type }: Props) => {
|
|
|
51
50
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
51
|
}, [chainId]);
|
|
53
52
|
|
|
54
|
-
const
|
|
53
|
+
const [chainPickerModalOpen, setChainPickerModalOpen] = useState(false);
|
|
55
54
|
|
|
56
55
|
const handleSrcChainChange = useCallback(
|
|
57
56
|
(chain: Chain) => {
|
|
@@ -77,19 +76,22 @@ export const ChainPanel = ({ chain, type }: Props) => {
|
|
|
77
76
|
|
|
78
77
|
return (
|
|
79
78
|
<>
|
|
79
|
+
{chainPickerModalOpen && (
|
|
80
|
+
<Modal onClose={() => setChainPickerModalOpen(false)}>
|
|
81
|
+
<ChainPicker
|
|
82
|
+
type={type}
|
|
83
|
+
supportedChains={supportedChains}
|
|
84
|
+
setSrcChain={handleSrcChainChange}
|
|
85
|
+
setDstChain={handleDstChainChange}
|
|
86
|
+
onClose={() => setChainPickerModalOpen(false)}
|
|
87
|
+
/>
|
|
88
|
+
</Modal>
|
|
89
|
+
)}
|
|
90
|
+
|
|
80
91
|
<button
|
|
81
92
|
type="button"
|
|
82
93
|
disabled={projectSelectedDestinationChain}
|
|
83
|
-
onClick={() =>
|
|
84
|
-
openModal(
|
|
85
|
-
<ChainPicker
|
|
86
|
-
type={type}
|
|
87
|
-
supportedChains={supportedChains}
|
|
88
|
-
setSrcChain={handleSrcChainChange}
|
|
89
|
-
setDstChain={handleDstChainChange}
|
|
90
|
-
/>,
|
|
91
|
-
)
|
|
92
|
-
}
|
|
94
|
+
onClick={() => setChainPickerModalOpen(true)}
|
|
93
95
|
>
|
|
94
96
|
<div className="flex justify-between items-center p-4 gap-8">
|
|
95
97
|
<div className="flex flex-col font-medium items-start">
|
|
@@ -57,11 +57,15 @@ export const TokenItem = ({ token, selectedTokenAddress, onClick }: Props) => {
|
|
|
57
57
|
})
|
|
58
58
|
: "<0.0001"}
|
|
59
59
|
</div>
|
|
60
|
-
) :
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
) : (
|
|
61
|
+
<>
|
|
62
|
+
{address ? (
|
|
63
|
+
<div>
|
|
64
|
+
<Skeleton className="w-[48px] h-[12px]" />
|
|
65
|
+
</div>
|
|
66
|
+
) : null}
|
|
67
|
+
</>
|
|
68
|
+
)}
|
|
65
69
|
</div>
|
|
66
70
|
</div>
|
|
67
71
|
);
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
} from "@src/components";
|
|
11
11
|
import { SwapPanelType } from "@src/components/Swap/SwapView";
|
|
12
12
|
import { useSwapContext } from "@src/context";
|
|
13
|
-
import { useModal } from "@src/context/ModalProvider";
|
|
14
13
|
import { ERC20Abi } from "@src/contracts";
|
|
15
14
|
import { useEvmContractApi } from "@src/hooks";
|
|
16
15
|
import { Chain, Ecosystem, ImportedTokenData, TokenOption } from "@src/models";
|
|
@@ -52,7 +51,6 @@ export const TokenPicker = ({
|
|
|
52
51
|
|
|
53
52
|
const { supportedChains, findTokenDataByAddressAndChain } = useSwapContext();
|
|
54
53
|
const evmContractApi = useEvmContractApi();
|
|
55
|
-
const { closeModal } = useModal();
|
|
56
54
|
|
|
57
55
|
useEffect(() => {
|
|
58
56
|
setShowImportWarning(false);
|
|
@@ -217,7 +215,7 @@ export const TokenPicker = ({
|
|
|
217
215
|
<div className="text-base/4 mb-4">Import token</div>
|
|
218
216
|
<div
|
|
219
217
|
className="w-4 h-4 fill-t_text_primary cursor-pointer"
|
|
220
|
-
onClick={
|
|
218
|
+
onClick={() => setModalOpen(false)}
|
|
221
219
|
>
|
|
222
220
|
<CloseIcon />
|
|
223
221
|
</div>
|
|
@@ -301,7 +299,7 @@ export const TokenPicker = ({
|
|
|
301
299
|
<div className="text-base/4 text-t_text_primary mb-4">{`Pick ${type} token`}</div>
|
|
302
300
|
<div
|
|
303
301
|
className="w-4 h-4 fill-t_text_primary cursor-pointer"
|
|
304
|
-
onClick={
|
|
302
|
+
onClick={() => setModalOpen(false)}
|
|
305
303
|
>
|
|
306
304
|
<CloseIcon />
|
|
307
305
|
</div>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ArrowDownIcon } from "@src/assets/icons";
|
|
2
|
-
import { TokenLogo } from "@src/components";
|
|
2
|
+
import { Modal, TokenLogo } from "@src/components";
|
|
3
3
|
import { useSwapContext } from "@src/context";
|
|
4
|
-
import { useModal } from "@src/context/ModalProvider";
|
|
5
4
|
import { Chain, Token, TokenOption } from "@src/models";
|
|
6
5
|
import { useMemo, useState } from "react";
|
|
7
6
|
import { SwapPanelType } from "../../index";
|
|
@@ -14,8 +13,6 @@ type Props = {
|
|
|
14
13
|
};
|
|
15
14
|
|
|
16
15
|
export const TokenPanel = ({ chain, token, type }: Props) => {
|
|
17
|
-
const [open, setOpen] = useState(false);
|
|
18
|
-
|
|
19
16
|
const {
|
|
20
17
|
srcChainTokensOptions,
|
|
21
18
|
srcChainOtherTokensOptions,
|
|
@@ -34,7 +31,7 @@ export const TokenPanel = ({ chain, token, type }: Props) => {
|
|
|
34
31
|
[type, dstTokenProvided],
|
|
35
32
|
);
|
|
36
33
|
|
|
37
|
-
const
|
|
34
|
+
const [tokenPickerModalOpen, setTokenPickerModalOpen] = useState(false);
|
|
38
35
|
|
|
39
36
|
const tokensWithBalances = useMemo(
|
|
40
37
|
() => (type === "source" ? srcChainTokensOptions : dstChainTokensOptions),
|
|
@@ -61,27 +58,31 @@ export const TokenPanel = ({ chain, token, type }: Props) => {
|
|
|
61
58
|
setDstToken(token);
|
|
62
59
|
setDstChain(newChain);
|
|
63
60
|
}
|
|
64
|
-
|
|
61
|
+
setTokenPickerModalOpen(false);
|
|
65
62
|
};
|
|
66
63
|
|
|
67
64
|
return (
|
|
68
65
|
<>
|
|
66
|
+
{tokenPickerModalOpen && (
|
|
67
|
+
<Modal onClose={() => setTokenPickerModalOpen(false)}>
|
|
68
|
+
<TokenPicker
|
|
69
|
+
type={type}
|
|
70
|
+
chain={chain!}
|
|
71
|
+
tokens={tokensWithBalances}
|
|
72
|
+
otherTokens={otherTokensWithBalances}
|
|
73
|
+
selectedTokenAddress={token?.address}
|
|
74
|
+
onSelect={onTokenSelect}
|
|
75
|
+
isOpen={tokenPickerModalOpen}
|
|
76
|
+
setModalOpen={setTokenPickerModalOpen}
|
|
77
|
+
/>
|
|
78
|
+
</Modal>
|
|
79
|
+
)}
|
|
80
|
+
|
|
69
81
|
<button
|
|
70
82
|
type="button"
|
|
71
83
|
disabled={projectSelectedDestinationToken}
|
|
72
84
|
onClick={() => {
|
|
73
|
-
|
|
74
|
-
<TokenPicker
|
|
75
|
-
type={type}
|
|
76
|
-
chain={chain!}
|
|
77
|
-
tokens={tokensWithBalances}
|
|
78
|
-
otherTokens={otherTokensWithBalances}
|
|
79
|
-
selectedTokenAddress={token?.address}
|
|
80
|
-
onSelect={onTokenSelect}
|
|
81
|
-
isOpen={open}
|
|
82
|
-
setModalOpen={setOpen}
|
|
83
|
-
/>,
|
|
84
|
-
);
|
|
85
|
+
setTokenPickerModalOpen(true);
|
|
85
86
|
}}
|
|
86
87
|
>
|
|
87
88
|
<div className="flex justify-between items-center p-4 gap-8 border-r border-solid border-t_text_primary border-opacity-10">
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { CloseIcon, WalletConnectIcon } from "@src/assets/icons";
|
|
2
|
-
import { useModal } from "@src/context/ModalProvider";
|
|
3
2
|
import { FC, useCallback, useMemo } from "react";
|
|
4
3
|
import { Connector, useConnect } from "wagmi";
|
|
5
4
|
|
|
@@ -27,8 +26,10 @@ const ConnectorIcon: FC<{ connector: Connector; className?: string }> = ({
|
|
|
27
26
|
}
|
|
28
27
|
};
|
|
29
28
|
|
|
30
|
-
export const WalletPicker: FC<{ className?: string
|
|
31
|
-
|
|
29
|
+
export const WalletPicker: FC<{ className?: string; onClose: () => void }> = ({
|
|
30
|
+
className,
|
|
31
|
+
onClose,
|
|
32
|
+
}) => {
|
|
32
33
|
const { connectors, connectAsync } = useConnect();
|
|
33
34
|
|
|
34
35
|
const allowedConnectors = useMemo(() => {
|
|
@@ -44,9 +45,9 @@ export const WalletPicker: FC<{ className?: string }> = ({ className }) => {
|
|
|
44
45
|
const handleWalletClick = useCallback(
|
|
45
46
|
async (connector: Connector) => {
|
|
46
47
|
await connectAsync({ connector });
|
|
47
|
-
|
|
48
|
+
onClose();
|
|
48
49
|
},
|
|
49
|
-
[connectAsync,
|
|
50
|
+
[connectAsync, onClose],
|
|
50
51
|
);
|
|
51
52
|
|
|
52
53
|
return (
|
|
@@ -55,7 +56,7 @@ export const WalletPicker: FC<{ className?: string }> = ({ className }) => {
|
|
|
55
56
|
<div className="text-base/4 mb-4 text-t_text_primary">Pick wallet</div>
|
|
56
57
|
<div
|
|
57
58
|
className="w-4 h-4 fill-t_text_primary cursor-pointer"
|
|
58
|
-
onClick={
|
|
59
|
+
onClick={onClose}
|
|
59
60
|
>
|
|
60
61
|
<CloseIcon />
|
|
61
62
|
</div>
|
|
@@ -6,13 +6,12 @@ import {
|
|
|
6
6
|
TransactionProvider,
|
|
7
7
|
TxUIWrapper,
|
|
8
8
|
} from "@src/context";
|
|
9
|
-
import { ModalProvider } from "@src/context/ModalProvider";
|
|
10
9
|
import { Chain, ModalIntegrationPayload, Route } from "@src/models";
|
|
11
10
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
12
11
|
import { FC, MouseEvent, useEffect, useMemo } from "react";
|
|
12
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
13
13
|
import { useReconnect, WagmiProvider } from "wagmi";
|
|
14
14
|
import { changeHostVariableColor } from "../../../localTheme";
|
|
15
|
-
import { ErrorBoundary } from "react-error-boundary";
|
|
16
15
|
|
|
17
16
|
export type TxConfigFormPayload = Omit<
|
|
18
17
|
ModalIntegrationPayload,
|
|
@@ -121,24 +120,22 @@ export const TxConfigForm = ({
|
|
|
121
120
|
>
|
|
122
121
|
<TransactionProvider>
|
|
123
122
|
<TxUIWrapper>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
>
|
|
130
|
-
<
|
|
131
|
-
<Swap onSubmit={onSubmit} onClose={onClose} />
|
|
132
|
-
<PoweredBy />
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
135
|
-
) : (
|
|
136
|
-
<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-[432px] w-full">
|
|
137
|
-
<Swap onSubmit={() => {}} onClose={() => {}} />
|
|
123
|
+
{overlay ? (
|
|
124
|
+
<div
|
|
125
|
+
className="top-0 left-0 right-0 bottom-0 bg-[rgba(0,0,0,0.8)] fixed flex items-center justify-center z-10"
|
|
126
|
+
onMouseDown={onBackdropClick}
|
|
127
|
+
>
|
|
128
|
+
<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)] min-w-x_modal max-w-x_modal min-h-[432px] w-full">
|
|
129
|
+
<Swap onSubmit={onSubmit} onClose={onClose} />
|
|
138
130
|
<PoweredBy />
|
|
139
131
|
</div>
|
|
140
|
-
|
|
141
|
-
|
|
132
|
+
</div>
|
|
133
|
+
) : (
|
|
134
|
+
<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-[432px] w-full">
|
|
135
|
+
<Swap onSubmit={() => {}} onClose={() => {}} />
|
|
136
|
+
<PoweredBy />
|
|
137
|
+
</div>
|
|
138
|
+
)}
|
|
142
139
|
</TxUIWrapper>
|
|
143
140
|
</TransactionProvider>
|
|
144
141
|
</SwapProvider>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { xpayShadowRoot } from "@src/config";
|
|
2
|
+
import { MouseEvent, ReactElement } from "react";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
4
|
+
|
|
5
|
+
export type TxModalType =
|
|
6
|
+
| "neutral"
|
|
7
|
+
| "waiting"
|
|
8
|
+
| "warning"
|
|
9
|
+
| "error"
|
|
10
|
+
| "success";
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
id: string;
|
|
14
|
+
children: ReactElement | ReactElement[];
|
|
15
|
+
onCloseClick: () => void;
|
|
16
|
+
type?: TxModalType;
|
|
17
|
+
className?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const TxModal = ({
|
|
21
|
+
id,
|
|
22
|
+
children,
|
|
23
|
+
onCloseClick,
|
|
24
|
+
type = "waiting",
|
|
25
|
+
className,
|
|
26
|
+
}: Props) => {
|
|
27
|
+
const onBackdropClick = (e: MouseEvent<HTMLDivElement>) => {
|
|
28
|
+
e.stopPropagation();
|
|
29
|
+
e.nativeEvent.stopImmediatePropagation();
|
|
30
|
+
if (e.target === e.currentTarget) {
|
|
31
|
+
onCloseClick();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return createPortal(
|
|
36
|
+
<div
|
|
37
|
+
className="fixed box-border inset-0 z-20 flex items-center justify-center bg-black bg-opacity-80"
|
|
38
|
+
onMouseDown={onBackdropClick}
|
|
39
|
+
>
|
|
40
|
+
<div
|
|
41
|
+
className={`relative bg-t_bg_primary rounded-3xl p-4 w-full min-w-[340px] overflow-auto max-w-x_modal border-2 ${
|
|
42
|
+
type === "error"
|
|
43
|
+
? "border-t_error_dark"
|
|
44
|
+
: type === "success"
|
|
45
|
+
? "border-t_success_dark"
|
|
46
|
+
: type === "warning"
|
|
47
|
+
? "border-t_warning_dark"
|
|
48
|
+
: type === "waiting"
|
|
49
|
+
? "border-t_main_accent_dark"
|
|
50
|
+
: "border-t_text_primary border-opacity-10"
|
|
51
|
+
} ${className}`}
|
|
52
|
+
>
|
|
53
|
+
{children}
|
|
54
|
+
</div>
|
|
55
|
+
</div>,
|
|
56
|
+
xpayShadowRoot!,
|
|
57
|
+
id,
|
|
58
|
+
);
|
|
59
|
+
};
|
package/src/components/index.ts
CHANGED
|
@@ -17,6 +17,7 @@ export * from "./TokenLogo/WithChain";
|
|
|
17
17
|
export * from "./Tooltip";
|
|
18
18
|
export * from "./TxConfigForm";
|
|
19
19
|
export * from "./TxDataCard";
|
|
20
|
+
export * from "./TxModal";
|
|
20
21
|
export * from "./TxStatusButton";
|
|
21
22
|
export * from "./TxWidgetWC";
|
|
22
23
|
export * from "./TxWidgetWCWrapped";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CloseIcon } from "@src/assets/icons";
|
|
2
2
|
import {
|
|
3
3
|
Button,
|
|
4
|
-
Modal,
|
|
5
|
-
ModalType,
|
|
6
4
|
SnackMessage,
|
|
7
5
|
Spinner,
|
|
6
|
+
TxModal,
|
|
7
|
+
TxModalType,
|
|
8
8
|
} from "@src/components";
|
|
9
9
|
import { ConfirmationView } from "@src/components/Swap/SwapView/ConfirmationView";
|
|
10
10
|
import { CCIP_EXPLORER } from "@src/constants";
|
|
@@ -319,7 +319,7 @@ export const TxUIWrapper = ({ children }: Props) => {
|
|
|
319
319
|
isTxModalOpenRef.current = flag;
|
|
320
320
|
}, []);
|
|
321
321
|
|
|
322
|
-
const modalType:
|
|
322
|
+
const modalType: TxModalType = useMemo(
|
|
323
323
|
() =>
|
|
324
324
|
txError
|
|
325
325
|
? "error"
|
|
@@ -369,14 +369,14 @@ export const TxUIWrapper = ({ children }: Props) => {
|
|
|
369
369
|
return (
|
|
370
370
|
<TxUIWrapperContext.Provider value={state}>
|
|
371
371
|
{isTxModalOpen && (
|
|
372
|
-
<
|
|
372
|
+
<TxModal
|
|
373
373
|
id="tx_modal"
|
|
374
374
|
className="max-w-x_modal"
|
|
375
375
|
type={modalType}
|
|
376
376
|
onCloseClick={closeTxModal}
|
|
377
377
|
>
|
|
378
378
|
<ConfirmationView onCloseClick={closeTxModal} />
|
|
379
|
-
</
|
|
379
|
+
</TxModal>
|
|
380
380
|
)}
|
|
381
381
|
{children}
|
|
382
382
|
</TxUIWrapperContext.Provider>
|
package/src/hooks/index.ts
CHANGED
|
@@ -38,8 +38,8 @@ export type ModalIntegrationStyles = Pick<
|
|
|
38
38
|
|
|
39
39
|
export type ModalIntegrationPayload = {
|
|
40
40
|
integratorId: string;
|
|
41
|
-
dstChain
|
|
42
|
-
dstToken
|
|
41
|
+
dstChain?: string;
|
|
42
|
+
dstToken?: string;
|
|
43
43
|
srcChain?: string;
|
|
44
44
|
srcToken?: string;
|
|
45
45
|
customContractCalls?: ContractCall[];
|