@xswap-link/sdk 0.14.0 → 0.15.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 +21 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.global.js +92 -92
- package/dist/index.js +3208 -2862
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3083 -2740
- package/dist/index.mjs.map +1 -1
- package/localTheme.ts +6 -4
- package/package.json +1 -1
- package/src/assets/icons/AdjustmentsIcon.tsx +5 -7
- package/src/assets/icons/ChainlinkMarkIcon.tsx +4 -5
- package/src/assets/icons/CheckCircleThinIcon.tsx +22 -0
- package/src/assets/icons/ChevronDownThinIcon.tsx +39 -0
- package/src/assets/icons/ChevronDownWideThinIcon.tsx +18 -0
- package/src/assets/icons/ChevronsUpDownThinIcon.tsx +21 -0
- package/src/assets/icons/ClockIcon.tsx +3 -7
- package/src/assets/icons/CloseIcon.tsx +9 -4
- package/src/assets/icons/ErrorCircleThinIcon.tsx +22 -0
- package/src/assets/icons/LinkExternalThinIcon.tsx +19 -0
- package/src/assets/icons/LoadingRingIcon.tsx +22 -0
- package/src/assets/icons/ProgressRingThinIcon.tsx +29 -0
- package/src/assets/icons/SearchThinIcon.tsx +15 -0
- package/src/assets/icons/SignThinIcon.tsx +15 -0
- package/src/assets/icons/WalletCheckThinIcon.tsx +24 -0
- package/src/assets/icons/WarningIcon.tsx +8 -5
- package/src/assets/icons/index.ts +11 -0
- package/src/components/Modal/index.tsx +14 -9
- package/src/components/PoweredBy/index.tsx +6 -8
- package/src/components/Swap/Header/index.tsx +2 -4
- package/src/components/Swap/HistoryView/ActivityCard/index.tsx +110 -115
- package/src/components/Swap/HistoryView/index.tsx +10 -7
- package/src/components/Swap/PickerView/index.tsx +151 -0
- package/src/components/Swap/ReorderButton/ReorderButton.tsx +4 -4
- package/src/components/Swap/SettingsView/Delivery/index.tsx +19 -17
- package/src/components/Swap/SettingsView/InfiniteApproval/index.tsx +19 -17
- package/src/components/Swap/SettingsView/Slippage/index.tsx +55 -49
- package/src/components/Swap/SwapView/ConfirmationView/TokenTiles/index.tsx +69 -0
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/Header/index.tsx +13 -25
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/Steps/index.tsx +65 -113
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/index.tsx +68 -26
- package/src/components/Swap/SwapView/ConfirmationView/TxResult/index.tsx +51 -74
- package/src/components/Swap/SwapView/FeesPanel/DeliveryInfo/index.tsx +1 -1
- package/src/components/Swap/SwapView/FeesPanel/index.tsx +5 -5
- package/src/components/Swap/SwapView/SwapButton/index.tsx +2 -31
- package/src/components/Swap/SwapView/SwapPanel/AmountPanel/Balance/index.tsx +2 -2
- package/src/components/Swap/SwapView/SwapPanel/AmountPanel/index.tsx +2 -2
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/ChainPicker/index.tsx +143 -0
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/NetworkFilter/index.tsx +19 -16
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/TokenItem/index.tsx +11 -4
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/index.tsx +185 -105
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/index.tsx +54 -120
- package/src/components/Swap/SwapView/SwapPanel/UsdValue/index.tsx +2 -2
- package/src/components/Swap/SwapView/SwapPanel/WalletPanel/index.tsx +10 -16
- package/src/components/Swap/SwapView/SwapPanel/index.tsx +4 -4
- package/src/components/Swap/SwapView/WalletPicker/index.tsx +131 -139
- package/src/components/Swap/SwapView/index.tsx +11 -7
- package/src/components/Swap/WalletPickerView/index.tsx +65 -0
- package/src/components/Swap/index.tsx +39 -8
- package/src/components/ToggleButton/index.tsx +5 -7
- package/src/components/TokenLogo/index.tsx +1 -1
- package/src/components/TxConfigForm/index.tsx +2 -2
- package/src/components/TxModal/index.tsx +14 -4
- package/src/components/global.css +18 -1
- package/src/constants/index.ts +4 -0
- package/src/context/HistoryProvider.tsx +1 -1
- package/src/context/SwapProvider.tsx +193 -81
- package/src/context/TxUIWrapper.tsx +3 -3
- package/src/hooks/useEvmContractApi.ts +28 -4
- package/src/models/payloads/GetBalancesPayload.ts +1 -0
- package/src/services/api.ts +37 -0
- package/src/utils/index.ts +27 -1
- package/src/utils/tokens.ts +20 -1
- package/src/utils/validation.ts +9 -4
- package/tailwind.config.js +4 -1
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/ArrowIcon.tsx +0 -13
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/SwapPanel/index.tsx +0 -72
- package/src/components/Swap/SwapView/ConfirmationView/TxResult/TokenItem/index.tsx +0 -25
|
@@ -7,14 +7,18 @@ export type SwapPanelType = "source" | "destination";
|
|
|
7
7
|
|
|
8
8
|
export const SwapView = () => {
|
|
9
9
|
return (
|
|
10
|
-
<div className="flex flex-col gap-
|
|
11
|
-
<div className="flex flex-col gap-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<
|
|
10
|
+
<div className="flex flex-col gap-8 fill-t_text_primary">
|
|
11
|
+
<div className="flex flex-col gap-6">
|
|
12
|
+
{/* ReorderButton is a zero-height anchor between the panels, so the
|
|
13
|
+
flex gap applies twice — 6px above and below it, 12px total. */}
|
|
14
|
+
<div className="flex flex-col gap-1.5">
|
|
15
|
+
<SwapPanel type="source" />
|
|
16
|
+
<ReorderButton />
|
|
17
|
+
<SwapPanel type="destination" />
|
|
18
|
+
</div>
|
|
19
|
+
<div className="h-px w-full gradient-sections-separator-container" />
|
|
20
|
+
<FeesPanel />
|
|
15
21
|
</div>
|
|
16
|
-
<div className="h-px w-full gradient-sections-separator-container" />
|
|
17
|
-
<FeesPanel />
|
|
18
22
|
<SwapButton />
|
|
19
23
|
</div>
|
|
20
24
|
);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Ecosystem } from "@src/models";
|
|
2
|
+
import { useWallet } from "@src/context/WalletProvider";
|
|
3
|
+
import { WalletPicker } from "../SwapView/WalletPicker";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Wallet picker rendered while one of the wallet modals is open, presented
|
|
7
|
+
* exactly like PickerView:
|
|
8
|
+
* - sm and up it replaces the swap view inside the widget container, so it
|
|
9
|
+
* sits on the exact same glass background,
|
|
10
|
+
* - below sm the same element becomes a bottom sheet pinned to the viewport.
|
|
11
|
+
*/
|
|
12
|
+
export const WalletPickerView = () => {
|
|
13
|
+
const {
|
|
14
|
+
openEVMWalletModal,
|
|
15
|
+
setOpenEVMWalletModal,
|
|
16
|
+
openSolanaWalletModal,
|
|
17
|
+
setOpenSolanaWalletModal,
|
|
18
|
+
openSuiWalletModal,
|
|
19
|
+
setOpenSuiWalletModal,
|
|
20
|
+
} = useWallet();
|
|
21
|
+
|
|
22
|
+
const ecosystem = openEVMWalletModal
|
|
23
|
+
? Ecosystem.EVM
|
|
24
|
+
: openSolanaWalletModal
|
|
25
|
+
? Ecosystem.SOLANA
|
|
26
|
+
: openSuiWalletModal
|
|
27
|
+
? Ecosystem.SUI
|
|
28
|
+
: null;
|
|
29
|
+
|
|
30
|
+
const close = () => {
|
|
31
|
+
setOpenEVMWalletModal(false);
|
|
32
|
+
setOpenSolanaWalletModal(false);
|
|
33
|
+
setOpenSuiWalletModal(false);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
if (!ecosystem) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div
|
|
42
|
+
className="fixed top-0 left-0 right-0 bottom-0 z-10 flex flex-col justify-end bg-[rgba(2,2,2,0.8)] sm:absolute sm:z-[2] sm:justify-start sm:bg-transparent"
|
|
43
|
+
onMouseDown={(e) => {
|
|
44
|
+
if (e.target === e.currentTarget) {
|
|
45
|
+
e.stopPropagation();
|
|
46
|
+
e.nativeEvent.stopImmediatePropagation();
|
|
47
|
+
e.preventDefault();
|
|
48
|
+
close();
|
|
49
|
+
}
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
<div className="flex flex-col w-full h-[85vh] max-h-full overflow-hidden p-4 pt-2.5 rounded-t-[24px] border-t border-solid border-t_text_primary border-opacity-10 bg-gradient-to-r from-t_bg_secondary/50 to-t_bg_secondary/50 bg-t_bg_primary sm:h-full sm:p-0 sm:rounded-none sm:border-0 sm:bg-none sm:bg-transparent">
|
|
53
|
+
<div className="sm:hidden mx-auto mb-4 h-1 w-8 rounded-full bg-t_bg_tertiary bg-opacity-10 shrink-0" />
|
|
54
|
+
<WalletPicker ecosystem={ecosystem} onClose={close} />
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/** True while any of the wallet picker modals is requested open. */
|
|
61
|
+
export const useWalletPickerOpen = () => {
|
|
62
|
+
const { openEVMWalletModal, openSolanaWalletModal, openSuiWalletModal } =
|
|
63
|
+
useWallet();
|
|
64
|
+
return openEVMWalletModal || openSolanaWalletModal || openSuiWalletModal;
|
|
65
|
+
};
|
|
@@ -3,8 +3,10 @@ import { useSwapContext } from "@src/context";
|
|
|
3
3
|
import { useMemo } from "react";
|
|
4
4
|
import { Header } from "./Header";
|
|
5
5
|
import { HistoryView } from "./HistoryView";
|
|
6
|
+
import { PickerView } from "./PickerView";
|
|
6
7
|
import { SettingsView } from "./SettingsView";
|
|
7
8
|
import { SwapView } from "./SwapView";
|
|
9
|
+
import { WalletPickerView, useWalletPickerOpen } from "./WalletPickerView";
|
|
8
10
|
import { UnifiedRoute } from "@src/models";
|
|
9
11
|
|
|
10
12
|
type Props = {
|
|
@@ -12,24 +14,53 @@ type Props = {
|
|
|
12
14
|
onClose: () => void;
|
|
13
15
|
};
|
|
14
16
|
export const Swap = ({ onClose }: Props) => {
|
|
15
|
-
const { tab } = useSwapContext();
|
|
17
|
+
const { tab, activePicker } = useSwapContext();
|
|
18
|
+
const walletPickerOpen = useWalletPickerOpen();
|
|
16
19
|
|
|
17
|
-
const
|
|
20
|
+
const overlayView = useMemo(() => {
|
|
18
21
|
return tab === "Settings" ? (
|
|
19
22
|
<SettingsView />
|
|
20
23
|
) : tab === "History" ? (
|
|
21
24
|
<HistoryView />
|
|
22
|
-
) :
|
|
23
|
-
<SwapView />
|
|
24
|
-
);
|
|
25
|
+
) : null;
|
|
25
26
|
}, [tab]);
|
|
26
27
|
|
|
27
28
|
return (
|
|
28
29
|
<div
|
|
29
|
-
className={`relative flex flex-col gap-6 p-
|
|
30
|
+
className={`relative flex flex-col gap-6 p-4 sm:p-8 text-t_text_primary bg-gradient-to-r from-t_bg_tertiary/[0.01] to-t_bg_tertiary/[0.01] bg-t_bg_secondary bg-opacity-50 backdrop-blur-[48px] rounded-[32px] border border-solid border-t_text_primary border-opacity-10 flex-1`}
|
|
30
31
|
>
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
{/* On sm+ the picker replaces the header and the current view in
|
|
33
|
+
place; below sm it renders as a bottom sheet over them. The
|
|
34
|
+
replaced content stays in the layout (visibility only), so it keeps
|
|
35
|
+
defining the widget height for the picker to fill. */}
|
|
36
|
+
<div className="relative flex flex-col flex-1 min-h-0">
|
|
37
|
+
{activePicker && <PickerView />}
|
|
38
|
+
<WalletPickerView />
|
|
39
|
+
<div
|
|
40
|
+
className={`flex flex-col gap-6 flex-1 min-h-0 ${
|
|
41
|
+
activePicker || walletPickerOpen ? "sm:invisible" : ""
|
|
42
|
+
}`}
|
|
43
|
+
>
|
|
44
|
+
<Header onClose={onClose} />
|
|
45
|
+
{/* SwapView stays in the layout on every tab (visibility only), so
|
|
46
|
+
it keeps defining one shared widget height; Settings/History
|
|
47
|
+
render as an overlay filling that height. */}
|
|
48
|
+
<div className="relative flex flex-col flex-1 min-h-0">
|
|
49
|
+
<div
|
|
50
|
+
className={`flex flex-col flex-1 min-h-0 ${
|
|
51
|
+
overlayView ? "invisible" : ""
|
|
52
|
+
}`}
|
|
53
|
+
>
|
|
54
|
+
<SwapView />
|
|
55
|
+
</div>
|
|
56
|
+
{overlayView && (
|
|
57
|
+
<div className="absolute inset-0 flex flex-col min-h-0">
|
|
58
|
+
{overlayView}
|
|
59
|
+
</div>
|
|
60
|
+
)}
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
33
64
|
<PoweredBy />
|
|
34
65
|
</div>
|
|
35
66
|
);
|
|
@@ -10,17 +10,15 @@ const ToggleButton = ({ checked, onClick }: Props) => {
|
|
|
10
10
|
role="switch"
|
|
11
11
|
aria-checked={checked}
|
|
12
12
|
onClick={onClick}
|
|
13
|
-
className={`relative inline-flex items-center w-
|
|
13
|
+
className={`relative inline-flex items-center w-10 h-5 p-0.5 rounded-full cursor-pointer transition-opacity border-none bg-gradient-to-r ${
|
|
14
14
|
checked
|
|
15
|
-
? "
|
|
16
|
-
: "
|
|
15
|
+
? "from-t_main_accent_light/25 to-t_main_accent_dark/25"
|
|
16
|
+
: "from-t_main_accent_light/20 to-t_main_accent_dark/20 opacity-50"
|
|
17
17
|
}`}
|
|
18
18
|
>
|
|
19
19
|
<span
|
|
20
|
-
className={`w-
|
|
21
|
-
checked
|
|
22
|
-
? "translate-x-6 bg-t_main_accent_light"
|
|
23
|
-
: "translate-x-0 bg-t_text_primary opacity-40"
|
|
20
|
+
className={`w-4 h-4 rounded-full transition-transform bg-gradient-to-r from-t_main_accent_light to-t_main_accent_dark ${
|
|
21
|
+
checked ? "translate-x-5" : "translate-x-0"
|
|
24
22
|
}`}
|
|
25
23
|
></span>
|
|
26
24
|
</button>
|
|
@@ -32,7 +32,7 @@ export const TokenLogo = ({
|
|
|
32
32
|
<img
|
|
33
33
|
src={token.image}
|
|
34
34
|
alt={token.name}
|
|
35
|
-
className={`
|
|
35
|
+
className={`rounded-full ${className}`}
|
|
36
36
|
onError={() => setErrorOccured(true)}
|
|
37
37
|
/>
|
|
38
38
|
) : (
|
|
@@ -189,12 +189,12 @@ export const TxConfigForm = (props: TxConfigFormProps) => {
|
|
|
189
189
|
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"
|
|
190
190
|
onMouseDown={onBackdropClick}
|
|
191
191
|
>
|
|
192
|
-
<div className="relative rounded-[
|
|
192
|
+
<div className="relative rounded-[32px] overflow-auto text-t_text_primary w-x_modal min-w-x_modal max-w-x_modal min-h-[532px] flex flex-col">
|
|
193
193
|
<Swap onSubmit={onSubmit} onClose={onClose} />
|
|
194
194
|
</div>
|
|
195
195
|
</div>
|
|
196
196
|
) : (
|
|
197
|
-
<div className="rounded-[
|
|
197
|
+
<div className="rounded-[32px] overflow-auto text-t_text_primary min-h-[532px] w-x_modal min-w-x_modal max-w-x_modal flex flex-col">
|
|
198
198
|
<Swap onSubmit={() => {}} onClose={() => {}} />
|
|
199
199
|
</div>
|
|
200
200
|
)}
|
|
@@ -38,11 +38,11 @@ export const TxModal = ({
|
|
|
38
38
|
onMouseDown={onBackdropClick}
|
|
39
39
|
>
|
|
40
40
|
<div
|
|
41
|
-
className={`relative
|
|
41
|
+
className={`relative rounded-[32px] p-6 sm:p-8 w-full min-w-[340px] overflow-auto max-w-x_modal backdrop-blur-[32px] bg-t_bg_secondary bg-opacity-75 border border-solid ${
|
|
42
42
|
type === "error"
|
|
43
|
-
? "border-
|
|
43
|
+
? "border-[#F44336]"
|
|
44
44
|
: type === "success"
|
|
45
|
-
? "border-
|
|
45
|
+
? "border-[#6AE89B]"
|
|
46
46
|
: type === "warning"
|
|
47
47
|
? "border-t_warning_dark"
|
|
48
48
|
: type === "waiting"
|
|
@@ -50,7 +50,17 @@ export const TxModal = ({
|
|
|
50
50
|
: "border-t_text_primary border-opacity-10"
|
|
51
51
|
} ${className}`}
|
|
52
52
|
>
|
|
53
|
-
{
|
|
53
|
+
{(type === "error" || type === "success") && (
|
|
54
|
+
<div
|
|
55
|
+
aria-hidden
|
|
56
|
+
className={`absolute inset-0 rounded-[inherit] pointer-events-none ${
|
|
57
|
+
type === "error"
|
|
58
|
+
? "tx-modal-glow-error"
|
|
59
|
+
: "tx-modal-glow-success"
|
|
60
|
+
}`}
|
|
61
|
+
/>
|
|
62
|
+
)}
|
|
63
|
+
<div className="relative">{children}</div>
|
|
54
64
|
</div>
|
|
55
65
|
</div>,
|
|
56
66
|
xpayShadowRoot!,
|
|
@@ -36,13 +36,30 @@
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
.gradient-sections-separator-container {
|
|
39
|
-
@apply bg-gradient-to-r from-transparent via-t_bg_tertiary/
|
|
39
|
+
@apply bg-gradient-to-r from-transparent via-t_bg_tertiary/10 to-transparent;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
.x-border {
|
|
43
43
|
@apply border border-solid border-t_text_primary border-opacity-10;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/* Corner glow of the transaction result modal, fading towards the center */
|
|
47
|
+
.tx-modal-glow-success {
|
|
48
|
+
background: radial-gradient(
|
|
49
|
+
120% 60% at 0% 0%,
|
|
50
|
+
rgba(76, 175, 80, 0.25) 0%,
|
|
51
|
+
transparent 45%
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.tx-modal-glow-error {
|
|
56
|
+
background: radial-gradient(
|
|
57
|
+
120% 60% at 0% 0%,
|
|
58
|
+
rgba(244, 67, 54, 0.25) 0%,
|
|
59
|
+
transparent 45%
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
46
63
|
.xpay-tx-status {
|
|
47
64
|
@apply fixed bottom-5 right-2 flex flex-col gap-3 pl-9 items-end w-full z-50;
|
|
48
65
|
}
|
package/src/constants/index.ts
CHANGED
|
@@ -49,6 +49,10 @@ export const MINIMUM_DISPLAYED_TOKEN_AMOUNT = 0.0001;
|
|
|
49
49
|
export const DEFAULT_SOURCE_CHAIN_ID = "1";
|
|
50
50
|
export const DEFAULT_SOURCE_TOKEN_ADDR = constants.AddressZero;
|
|
51
51
|
export const DEFAULT_DESTINATION_CHAIN_ID = "1";
|
|
52
|
+
// Default bridge route: Ethereum -> Base; the token defaults to XSWAP via
|
|
53
|
+
// getDefaultBridgeTokenForChain.
|
|
54
|
+
export const DEFAULT_BRIDGE_SOURCE_CHAIN_ID = "1";
|
|
55
|
+
export const DEFAULT_BRIDGE_DESTINATION_CHAIN_ID = "8453";
|
|
52
56
|
export const DEFAULT_DESTINATION_TOKEN_ADDR =
|
|
53
57
|
"0x8fe815417913a93ea99049fc0718ee1647a2a07c"; // XSWAP token
|
|
54
58
|
export const CCIP_EXPLORER = "https://ccip.chain.link/";
|
|
@@ -360,7 +360,7 @@ export const HistoryProvider = ({ children }: HistoryProviderProps) => {
|
|
|
360
360
|
</Button>
|
|
361
361
|
|
|
362
362
|
<div
|
|
363
|
-
className="transaction-provider__close fill-white leading-[0px]"
|
|
363
|
+
className="transaction-provider__close fill-white text-white leading-[0px]"
|
|
364
364
|
onClick={() => closeSnackbar(messageId)}
|
|
365
365
|
>
|
|
366
366
|
<CloseIcon />
|