@xswap-link/sdk 0.11.3 → 0.12.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xswap-link/sdk",
3
- "version": "0.11.3",
3
+ "version": "0.12.0",
4
4
  "description": "JavaScript SDK for XSwap platform",
5
5
  "homepage": "https://github.com/xswap-link/xswap-sdk",
6
6
  "repository": {
@@ -36,6 +36,8 @@
36
36
  "@fortawesome/free-regular-svg-icons": "^6.4.2",
37
37
  "@fortawesome/free-solid-svg-icons": "^6.4.2",
38
38
  "@fortawesome/react-fontawesome": "^0.2.0",
39
+ "@mysten/dapp-kit": "^0.19.11",
40
+ "@mysten/sui": "^1.45.2",
39
41
  "@r2wc/core": "^1.1.0",
40
42
  "@solana/spl-token": "^0.4.13",
41
43
  "@solana/wallet-adapter-react": "^0.15.38",
@@ -11,6 +11,16 @@ import { SolanaWeb3Network } from "@src/models";
11
11
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
12
12
  import { ReactNode, useMemo } from "react";
13
13
  import { Config, WagmiProvider } from "wagmi";
14
+ import { getFullnodeUrl } from "@mysten/sui/client";
15
+ import {
16
+ createNetworkConfig,
17
+ SuiClientProvider,
18
+ WalletProvider as SuiWalletProvider,
19
+ } from "@mysten/dapp-kit";
20
+
21
+ const { networkConfig } = createNetworkConfig({
22
+ mainnet: { url: getFullnodeUrl("mainnet") },
23
+ });
14
24
 
15
25
  const queryClient = new QueryClient();
16
26
 
@@ -29,11 +39,15 @@ export const AllWalletsConfig = ({
29
39
  return (
30
40
  <WagmiProvider config={wagmiConfig}>
31
41
  <QueryClientProvider client={queryClient}>
32
- <ConnectionProvider endpoint={solanaEndpoint}>
33
- <SolanaWalletProvider wallets={solanaWallets} autoConnect>
34
- {children}
35
- </SolanaWalletProvider>
36
- </ConnectionProvider>
42
+ <SuiClientProvider networks={networkConfig} defaultNetwork="mainnet">
43
+ <SuiWalletProvider autoConnect>
44
+ <ConnectionProvider endpoint={solanaEndpoint}>
45
+ <SolanaWalletProvider wallets={solanaWallets} autoConnect>
46
+ {children}
47
+ </SolanaWalletProvider>
48
+ </ConnectionProvider>
49
+ </SuiWalletProvider>
50
+ </SuiClientProvider>
37
51
  </QueryClientProvider>
38
52
  </WagmiProvider>
39
53
  );
@@ -57,6 +57,8 @@ export const SwapButton = () => {
57
57
  setOpenEVMWalletModal,
58
58
  openSolanaWalletModal,
59
59
  setOpenSolanaWalletModal,
60
+ openSuiWalletModal,
61
+ setOpenSuiWalletModal,
60
62
  solana,
61
63
  } = useWallet();
62
64
 
@@ -309,6 +311,14 @@ export const SwapButton = () => {
309
311
  />
310
312
  </Modal>
311
313
  )}
314
+ {openSuiWalletModal && (
315
+ <Modal onClose={() => setOpenSuiWalletModal(false)}>
316
+ <WalletPicker
317
+ ecosystem={Ecosystem.SUI}
318
+ onClose={() => setOpenSuiWalletModal(false)}
319
+ />
320
+ </Modal>
321
+ )}
312
322
  <button
313
323
  type="button"
314
324
  disabled={button.disabled}
@@ -11,8 +11,14 @@ type Props = {
11
11
  };
12
12
 
13
13
  export const WalletPanel = ({ chain, type, className }: Props) => {
14
- const { setOpenEVMWalletModal, setOpenSolanaWalletModal, evm, solana } =
15
- useWallet();
14
+ const {
15
+ setOpenEVMWalletModal,
16
+ setOpenSolanaWalletModal,
17
+ setOpenSuiWalletModal,
18
+ evm,
19
+ solana,
20
+ sui,
21
+ } = useWallet();
16
22
  const openWalletModal = useCallback(() => {
17
23
  if (!chain) {
18
24
  return;
@@ -23,17 +29,28 @@ export const WalletPanel = ({ chain, type, className }: Props) => {
23
29
  } else if (chain.ecosystem === "solana") {
24
30
  setOpenSolanaWalletModal(true);
25
31
  solana.connectWallet();
32
+ } else if (chain.ecosystem === "sui") {
33
+ setOpenSuiWalletModal(true);
26
34
  }
27
- }, [chain, evm, solana, setOpenEVMWalletModal, setOpenSolanaWalletModal]);
35
+ }, [
36
+ chain,
37
+ evm,
38
+ solana,
39
+ setOpenEVMWalletModal,
40
+ setOpenSolanaWalletModal,
41
+ setOpenSuiWalletModal,
42
+ ]);
28
43
  const renderAddress = useCallback(
29
44
  (chainEcosystem: string) => {
30
45
  if (chainEcosystem === "evm") {
31
46
  return shortAddress(evm.address || "");
32
47
  } else if (chainEcosystem === "solana") {
33
48
  return shortAddress(solana.address || "");
49
+ } else if (chainEcosystem === "sui") {
50
+ return shortAddress(sui.address || "");
34
51
  }
35
52
  },
36
- [evm, solana],
53
+ [evm, solana, sui],
37
54
  );
38
55
  return (
39
56
  <>
@@ -8,6 +8,13 @@ import { FC, useCallback } from "react";
8
8
  import { Connector, useAccount, useConnect, useDisconnect } from "wagmi";
9
9
  import { useWallet as useSolanaWallet } from "@solana/wallet-adapter-react";
10
10
  import { Ecosystem } from "@src/models";
11
+ import {
12
+ useWallets as useSuiWallets,
13
+ useCurrentAccount as useSuiCurrentAccount,
14
+ useCurrentWallet as useSuiCurrentWallet,
15
+ useConnectWallet as useSuiConnectWallet,
16
+ useDisconnectWallet as useSuiDisconnectWallet,
17
+ } from "@mysten/dapp-kit";
11
18
 
12
19
  const ConnectorIcon: FC<{ connector: Connector; className?: string }> = ({
13
20
  connector,
@@ -77,6 +84,36 @@ export const WalletPicker: FC<{
77
84
  [connect, select, onClose],
78
85
  );
79
86
 
87
+ // ---- SUI ----
88
+ const suiWallets = useSuiWallets();
89
+ const suiAccount = useSuiCurrentAccount();
90
+ const suiCurrentWallet = useSuiCurrentWallet();
91
+ const { mutateAsync: connectSuiWalletMut } = useSuiConnectWallet();
92
+ const { mutateAsync: disconnectSuiWalletMut } = useSuiDisconnectWallet();
93
+
94
+ const handleConnectSui = useCallback(
95
+ async (wallet: (typeof suiWallets)[number]) => {
96
+ try {
97
+ await connectSuiWalletMut({ wallet });
98
+ } catch (error) {
99
+ console.error("Failed to connect Sui wallet:", error);
100
+ } finally {
101
+ onClose();
102
+ }
103
+ },
104
+ [connectSuiWalletMut, onClose],
105
+ );
106
+
107
+ const handleDisconnectSui = useCallback(async () => {
108
+ try {
109
+ await disconnectSuiWalletMut();
110
+ } catch (error) {
111
+ console.error("Failed to disconnect Sui wallet:", error);
112
+ } finally {
113
+ onClose();
114
+ }
115
+ }, [disconnectSuiWalletMut, onClose]);
116
+
80
117
  return (
81
118
  <div className={`flex flex-col h-full ${className || ""}`}>
82
119
  <div className="flex justify-between">
@@ -179,6 +216,60 @@ export const WalletPicker: FC<{
179
216
  })}
180
217
  </>
181
218
  )}
219
+ {ecosystem === Ecosystem.SUI && (
220
+ <>
221
+ {suiWallets.map((wallet) => {
222
+ const isConnected =
223
+ !!suiAccount?.address &&
224
+ suiCurrentWallet?.currentWallet?.name === wallet.name;
225
+
226
+ const icon = wallet.icon;
227
+
228
+ return (
229
+ <button
230
+ key={wallet.name}
231
+ onClick={async () => {
232
+ isConnected
233
+ ? await handleDisconnectSui()
234
+ : await handleConnectSui(wallet);
235
+ }}
236
+ className="group flex items-center w-full gap-3 mt-2 mb-2 cursor-pointer p-4 border border-solid border-white border-opacity-0 hover:selected-wallet-item"
237
+ >
238
+ {icon ? (
239
+ <img
240
+ src={icon}
241
+ alt={wallet.name}
242
+ className={`w-[34px] h-[34px] rounded-md ${
243
+ className || ""
244
+ }`}
245
+ />
246
+ ) : (
247
+ <div className="w-[34px] h-[34px] rounded-md bg-white/10" />
248
+ )}
249
+
250
+ <div className="text-t_text_primary">{wallet.name}</div>
251
+
252
+ {isConnected && (
253
+ <div className="flex w-full justify-end items-baseline gap-1">
254
+ <div className="group-hover:hidden">
255
+ <DotGreenIcon />
256
+ </div>
257
+ <div className="hidden group-hover:block">
258
+ <DotRedIcon />
259
+ </div>
260
+ <div className="text-t_text_green group-hover:hidden">
261
+ connected
262
+ </div>
263
+ <div className="text-t_text_red hidden group-hover:block">
264
+ disconnect
265
+ </div>
266
+ </div>
267
+ )}
268
+ </button>
269
+ );
270
+ })}
271
+ </>
272
+ )}
182
273
  </div>
183
274
  </div>
184
275
  );
@@ -36,6 +36,7 @@ export const SOLANA_MAINNET_RPC_URL =
36
36
  export const JUPITER_V6_PROGRAM_ID = new PublicKey(
37
37
  "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
38
38
  );
39
+ export const DEPLOYER_ADDRESS = "0x8ebD04b2fbA00418Be00329146837dcE51F02c00";
39
40
  export const DEFAULT_ECOSYSTEM = Ecosystem.EVM;
40
41
  export const NUMBER_INPUT_REGEX = /^[0-9]*[.,]?[0-9]*$/;
41
42
  export const SLIPPAGE_PRESETS: number[] = [0.5, 1.5, 3.0];
@@ -3,6 +3,7 @@ import {
3
3
  DEFAULT_DESTINATION_CHAIN_ID,
4
4
  DEFAULT_REQUEST_ABORT_MSG,
5
5
  DEFAULT_SOURCE_CHAIN_ID,
6
+ DEPLOYER_ADDRESS,
6
7
  SOLANA_NATIVE_TOKEN_ADDRESS,
7
8
  SOLANA_TOKEN_2022_PROGRAM_ID,
8
9
  SOLANA_TOKEN_PROGRAM_ID,
@@ -600,13 +601,17 @@ export const SwapProvider = ({
600
601
  fromChain: srcChain.chainId,
601
602
  toChain: dstChain.chainId,
602
603
  fromAddress:
603
- evmAddress || ADDRESSES[srcChain.chainId]?.FeeCollector || "",
604
+ evmAddress ||
605
+ ADDRESSES[srcChain.chainId]?.FeeCollector ||
606
+ DEPLOYER_ADDRESS,
604
607
  toAddress:
605
608
  dstChain.ecosystem === Ecosystem.SOLANA
606
609
  ? solanaAddress ||
607
610
  ADDRESSES[dstChain.chainId]?.FeeCollector ||
608
611
  ""
609
- : evmAddress || ADDRESSES[dstChain.chainId]?.FeeCollector || "",
612
+ : evmAddress ||
613
+ ADDRESSES[dstChain.chainId]?.FeeCollector ||
614
+ DEPLOYER_ADDRESS,
610
615
  fromToken: srcToken.address,
611
616
  toToken: dstToken.address,
612
617
  fromAmount: srcValueWei,
@@ -11,6 +11,8 @@ import { useAccount, useConnect, useDisconnect } from "wagmi";
11
11
  import { useWallet as useSolanaWallet } from "@solana/wallet-adapter-react";
12
12
  import { SolanaWeb3Network } from "@src/models";
13
13
 
14
+ import { useCurrentAccount, useDisconnectWallet } from "@mysten/dapp-kit";
15
+
14
16
  interface WalletInfo {
15
17
  address: string | undefined;
16
18
  isConnected: boolean;
@@ -18,13 +20,17 @@ interface WalletInfo {
18
20
  connectWallet: () => Promise<void>;
19
21
  disconnectWallet: () => Promise<void>;
20
22
  }
23
+
21
24
  export interface WalletState {
22
25
  openEVMWalletModal: boolean;
23
26
  setOpenEVMWalletModal: Dispatch<React.SetStateAction<boolean>>;
24
27
  openSolanaWalletModal: boolean;
25
28
  setOpenSolanaWalletModal: Dispatch<React.SetStateAction<boolean>>;
29
+ openSuiWalletModal: boolean;
30
+ setOpenSuiWalletModal: Dispatch<React.SetStateAction<boolean>>;
26
31
  evm: WalletInfo;
27
32
  solana: WalletInfo;
33
+ sui: WalletInfo;
28
34
  }
29
35
 
30
36
  // Wallet Context
@@ -32,10 +38,12 @@ const WalletContext: Context<WalletState> = createContext<WalletState>(
32
38
  {} as WalletState,
33
39
  );
34
40
 
35
- export const WalletProvider = ({ children }) => {
41
+ export const WalletProvider = ({ children }: { children: React.ReactNode }) => {
36
42
  const [openEVMWalletModal, setOpenEVMWalletModal] = useState(false);
37
43
  const [openSolanaWalletModal, setOpenSolanaWalletModal] = useState(false);
44
+ const [openSuiWalletModal, setOpenSuiWalletModal] = useState(false);
38
45
 
46
+ // -------- EVM --------
39
47
  const {
40
48
  address: evmAddress,
41
49
  isConnected: isEvmConnected,
@@ -44,24 +52,39 @@ export const WalletProvider = ({ children }) => {
44
52
  const { connect, connectors } = useConnect();
45
53
  const { disconnect: evmDisconnect } = useDisconnect();
46
54
 
47
- const solanaWallet = useSolanaWallet();
48
-
49
55
  const connectEvmWallet = useCallback(async () => {
50
- connect({ connector: connectors[0]! }); // Default to MetaMask
56
+ connect({ connector: connectors[0]! }); // Default connector
51
57
  }, [connect, connectors]);
52
58
 
53
- const connectSolanaWallet = useCallback(async () => {
54
- await solanaWallet.connect();
55
- }, [solanaWallet]);
56
-
57
59
  const disconnectEvmWallet = useCallback(
58
60
  () => new Promise<void>((resolve) => resolve(evmDisconnect())),
59
61
  [evmDisconnect],
60
62
  );
63
+
64
+ // -------- SOLANA --------
65
+ const solanaWallet = useSolanaWallet();
66
+
67
+ const connectSolanaWallet = useCallback(async () => {
68
+ await solanaWallet.connect();
69
+ }, [solanaWallet]);
70
+
61
71
  const disconnectSolanaWallet = useCallback(
62
72
  () => solanaWallet.disconnect(),
63
73
  [solanaWallet],
64
74
  );
75
+
76
+ // -------- SUI --------
77
+ const suiAccount = useCurrentAccount();
78
+ const { mutateAsync: disconnectSui } = useDisconnectWallet();
79
+
80
+ const connectSuiWallet = useCallback(async () => {
81
+ setOpenSuiWalletModal(true);
82
+ }, []);
83
+
84
+ const disconnectSuiWallet = useCallback(async () => {
85
+ await disconnectSui();
86
+ }, [disconnectSui]);
87
+
65
88
  const state = useMemo(() => {
66
89
  return {
67
90
  evm: {
@@ -78,17 +101,31 @@ export const WalletProvider = ({ children }) => {
78
101
  connectWallet: connectSolanaWallet,
79
102
  disconnectWallet: disconnectSolanaWallet,
80
103
  },
104
+ sui: {
105
+ address: suiAccount?.address,
106
+ isConnected: !!suiAccount?.address,
107
+ chainId: "sui-mainnet",
108
+ connectWallet: connectSuiWallet,
109
+ disconnectWallet: disconnectSuiWallet,
110
+ },
81
111
  };
82
112
  }, [
113
+ // evm
83
114
  evmAddress,
84
115
  isEvmConnected,
85
116
  evmChainId,
86
117
  connectEvmWallet,
87
118
  disconnectEvmWallet,
119
+ // sol
88
120
  solanaWallet.publicKey,
89
121
  connectSolanaWallet,
90
122
  disconnectSolanaWallet,
123
+ // sui
124
+ suiAccount?.address,
125
+ connectSuiWallet,
126
+ disconnectSuiWallet,
91
127
  ]);
128
+
92
129
  return (
93
130
  <WalletContext.Provider
94
131
  value={{
@@ -96,6 +133,8 @@ export const WalletProvider = ({ children }) => {
96
133
  setOpenEVMWalletModal,
97
134
  openSolanaWalletModal,
98
135
  setOpenSolanaWalletModal,
136
+ openSuiWalletModal,
137
+ setOpenSuiWalletModal,
99
138
  ...state,
100
139
  }}
101
140
  >
@@ -1,4 +1,5 @@
1
1
  export enum Ecosystem {
2
2
  EVM = "evm",
3
3
  SOLANA = "solana",
4
+ SUI = "sui",
4
5
  }