@xswap-link/sdk 0.6.8 → 0.6.10

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.6.8",
3
+ "version": "0.6.10",
4
4
  "description": "JavaScript SDK for XSwap platform",
5
5
  "homepage": "https://github.com/xswap-link/xswap-sdk",
6
6
  "repository": {
@@ -58,7 +58,7 @@ export const TxOverview = ({ onCloseClick }: Props) => {
58
58
  const evmContractApi = useEvmContractApi();
59
59
 
60
60
  const trackTransaction = useCallback(
61
- (txReceipt: ContractReceipt) => {
61
+ async (txReceipt: ContractReceipt) => {
62
62
  if (!srcChain || !dstChain || !srcToken || !dstToken || !route) {
63
63
  return;
64
64
  }
@@ -98,18 +98,6 @@ export const TxOverview = ({ onCloseClick }: Props) => {
98
98
  const messageReceivedXSwapCustomRouterEventSignature =
99
99
  "MessageReceived(bytes32,uint64,address,bytes)"; // TODO think of getting this signature in a different way because its easy to forgot about it when we will change event on smartcontract
100
100
 
101
- const messageSentEvent = txReceipt.logs?.find((log) => {
102
- return log.topics[0] === ethers.utils.id(messageSentEventSignature);
103
- });
104
- const messageSentXSwapCustomRouterEvent = txReceipt.logs?.find(
105
- (log) => {
106
- return (
107
- log.topics[0] ===
108
- ethers.utils.id(messageSentXSwapCustomRouterEventSignature)
109
- );
110
- },
111
- );
112
-
113
101
  const destinationChainProvider = ethers.getDefaultProvider(
114
102
  supportedChains.find(
115
103
  (chain) =>
@@ -118,55 +106,68 @@ export const TxOverview = ({ onCloseClick }: Props) => {
118
106
  )?.publicRpcUrls[0],
119
107
  );
120
108
 
121
- if (messageSentEvent) {
122
- // subscription for xswap router event
123
- const messageId = messageSentEvent?.topics[1] as string;
124
- transactionData.messageId = messageId;
109
+ const handleMessageEvent = async (
110
+ contractKey: "XSwapRouter" | "CustomXSwapRouter",
111
+ messageSentEventSignature: string,
112
+ messageReceivedEventSignature: string,
113
+ ) => {
114
+ const messageEvent = txReceipt.logs?.find((log) => {
115
+ return log.topics[0] === ethers.utils.id(messageSentEventSignature);
116
+ });
125
117
 
126
- const xSwapRouterOnDestination = new ethers.Contract(
127
- // @ts-ignore
128
- ADDRESSES[dstChain.chainId].XSwapRouter,
129
- XSwapRouterAbi,
130
- destinationChainProvider,
131
- );
118
+ if (messageEvent) {
119
+ const messageId = messageEvent?.topics[1] as string;
120
+ transactionData.messageId = messageId;
132
121
 
133
- const eventFilter = {
134
- // @ts-ignore
135
- address: ADDRESSES[dstChain.chainId].XSwapRouter,
136
- topics: [ethers.utils.id(messageReceivedEventSignature), messageId],
137
- };
122
+ const xSwapRouterOnDestination = new ethers.Contract(
123
+ // @ts-ignore
124
+ ADDRESSES[dstChain?.chainId]?.[contractKey],
125
+ contractKey === "XSwapRouter"
126
+ ? XSwapRouterAbi
127
+ : CustomXSwapRouterAbi,
128
+ destinationChainProvider,
129
+ );
138
130
 
139
- xSwapRouterOnDestination.once(eventFilter, () => {
140
- transactionData.status = "DONE";
141
- updateTransactionInLocalHistory(transactionData, txReceipt.from);
142
- });
143
- } else if (messageSentXSwapCustomRouterEvent) {
144
- // subscription for custom router event
145
- const messageId = messageSentXSwapCustomRouterEvent
146
- ?.topics[1] as string;
147
- transactionData.messageId = messageId;
131
+ const eventFilter = {
132
+ address: ADDRESSES[dstChain.chainId]?.[contractKey],
133
+ topics: [
134
+ ethers.utils.id(messageReceivedEventSignature),
135
+ messageId,
136
+ ],
137
+ };
148
138
 
149
- const xSwapRouterOnDestination = new ethers.Contract(
150
- // @ts-ignore
151
- ADDRESSES[dstChain.chainId].CustomXSwapRouter,
152
- CustomXSwapRouterAbi,
153
- destinationChainProvider,
154
- );
139
+ const pastEvents = await xSwapRouterOnDestination.queryFilter(
140
+ eventFilter,
141
+ );
155
142
 
156
- const eventFilter = {
157
- address: ADDRESSES[dstChain.chainId]?.CustomXSwapRouter,
158
- topics: [
159
- ethers.utils.id(messageReceivedXSwapCustomRouterEventSignature),
160
- messageId,
161
- ],
162
- };
143
+ if (pastEvents.length > 0) {
144
+ transactionData.status = "DONE";
145
+ updateTransactionInLocalHistory(transactionData, txReceipt.from);
146
+ } else {
147
+ xSwapRouterOnDestination.once(eventFilter, () => {
148
+ transactionData.status = "DONE";
149
+ updateTransactionInLocalHistory(
150
+ transactionData,
151
+ txReceipt.from,
152
+ );
153
+ });
154
+ }
155
+ }
156
+ };
163
157
 
164
- xSwapRouterOnDestination.once(eventFilter, () => {
165
- transactionData.status = "DONE";
166
- updateTransactionInLocalHistory(transactionData, txReceipt.from);
167
- });
168
- }
158
+ await handleMessageEvent(
159
+ "XSwapRouter",
160
+ messageSentEventSignature,
161
+ messageReceivedEventSignature,
162
+ );
163
+
164
+ await handleMessageEvent(
165
+ "CustomXSwapRouter",
166
+ messageSentXSwapCustomRouterEventSignature,
167
+ messageReceivedXSwapCustomRouterEventSignature,
168
+ );
169
169
  }
170
+
170
171
  addTransactionToLocalHistory(transactionData, txReceipt.from);
171
172
  },
172
173
  [
@@ -246,15 +247,19 @@ export const TxOverview = ({ onCloseClick }: Props) => {
246
247
  }
247
248
  }
248
249
  }, [
249
- evmContractApi,
250
- signer,
251
- enqueueTransaction,
252
- refreshBalance,
250
+ srcToken,
253
251
  route,
254
- setTxNeedsApproval,
252
+ enqueueTransaction,
253
+ signer,
254
+ evmContractApi,
255
255
  setTxStatus,
256
- srcToken,
256
+ refreshBalance,
257
257
  trackTransaction,
258
+ srcChain?.chainId,
259
+ dstChain?.chainId,
260
+ dstToken?.address,
261
+ dstValueWei,
262
+ setTxNeedsApproval,
258
263
  ]);
259
264
 
260
265
  return (
@@ -6,6 +6,7 @@ import { useCallback, useEffect } 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";
9
10
 
10
11
  type Props = {
11
12
  chain: Chain | undefined;
@@ -22,13 +23,20 @@ export const ChainPanel = ({ chain, type }: Props) => {
22
23
  setSrcToken,
23
24
  dstToken,
24
25
  setDstToken,
26
+ srcChainProvided,
27
+ dstChainProvided,
25
28
  } = useSwapContext();
26
29
 
27
30
  const { chainId } = useAccount();
28
31
 
32
+ const projectSelectedDestinationChain = useMemo(
33
+ () => type === "destination" && dstChainProvided,
34
+ [type, dstChainProvided],
35
+ );
36
+
29
37
  // select chain from user wallet
30
38
  useEffect(() => {
31
- if (!chainId) return;
39
+ if (!chainId || srcChainProvided) return;
32
40
 
33
41
  const userChainFromWallet = supportedChains.find(
34
42
  (chain) => chain.chainId === String(chainId),
@@ -71,6 +79,7 @@ export const ChainPanel = ({ chain, type }: Props) => {
71
79
  <>
72
80
  <button
73
81
  type="button"
82
+ disabled={projectSelectedDestinationChain}
74
83
  onClick={() =>
75
84
  openModal(
76
85
  <ChainPicker
@@ -91,9 +100,11 @@ export const ChainPanel = ({ chain, type }: Props) => {
91
100
  {chain ? chain.displayName : "Select"}
92
101
  </p>
93
102
  </div>
94
- <div className="w-4 h-2 fill-t_text_primary">
95
- <ArrowDownIcon />
96
- </div>
103
+ {!projectSelectedDestinationChain && (
104
+ <div className="w-4 h-2 fill-t_text_primary">
105
+ <ArrowDownIcon />
106
+ </div>
107
+ )}
97
108
  </div>
98
109
  </button>
99
110
  </>
@@ -26,8 +26,14 @@ export const TokenPanel = ({ chain, token, type }: Props) => {
26
26
  supportedChains,
27
27
  setDstToken,
28
28
  setDstChain,
29
+ dstTokenProvided,
29
30
  } = useSwapContext();
30
31
 
32
+ const projectSelectedDestinationToken = useMemo(
33
+ () => type === "destination" && dstTokenProvided,
34
+ [type, dstTokenProvided],
35
+ );
36
+
31
37
  const { openModal, closeModal } = useModal();
32
38
 
33
39
  const tokensWithBalances = useMemo(
@@ -62,7 +68,8 @@ export const TokenPanel = ({ chain, token, type }: Props) => {
62
68
  <>
63
69
  <button
64
70
  type="button"
65
- onClick={() =>
71
+ disabled={projectSelectedDestinationToken}
72
+ onClick={() => {
66
73
  openModal(
67
74
  <TokenPicker
68
75
  type={type}
@@ -74,8 +81,8 @@ export const TokenPanel = ({ chain, token, type }: Props) => {
74
81
  isOpen={open}
75
82
  setModalOpen={setOpen}
76
83
  />,
77
- )
78
- }
84
+ );
85
+ }}
79
86
  >
80
87
  <div className="flex justify-between items-center p-4 gap-8 border-r border-solid border-t_text_primary border-opacity-10">
81
88
  <div className="flex gap-2 items-center">
@@ -91,9 +98,11 @@ export const TokenPanel = ({ chain, token, type }: Props) => {
91
98
  </p>
92
99
  </div>
93
100
  </div>
94
- <div className="w-4 h-2 fill-t_text_primary">
95
- <ArrowDownIcon />
96
- </div>
101
+ {!projectSelectedDestinationToken && (
102
+ <div className="w-4 h-2 fill-t_text_primary">
103
+ <ArrowDownIcon />
104
+ </div>
105
+ )}
97
106
  </div>
98
107
  </button>
99
108
  </>
@@ -122,10 +122,10 @@ export type TxWidgetWCAttributes = {
122
122
  "dst-token": WidgetIntegrationPayload["dstToken"];
123
123
  "src-chain": WidgetIntegrationPayload["srcChain"];
124
124
  "src-token": WidgetIntegrationPayload["srcToken"];
125
- "custom-contract-calls": WidgetIntegrationPayload["customContractCalls"];
125
+ "custom-contract-calls": string | undefined;
126
126
  desc: WidgetIntegrationPayload["desc"];
127
127
  "dst-display-token": WidgetIntegrationPayload["dstDisplayToken"];
128
128
  "light-theme": WidgetIntegrationPayload["lightTheme"];
129
129
  "default-wallet-picker": WidgetIntegrationPayload["defaultWalletPicker"];
130
- styles: WidgetIntegrationPayload["styles"];
130
+ styles: string | undefined;
131
131
  };
@@ -43,12 +43,12 @@ export const TxWidgetWCWrapped = ({
43
43
  dst-token={dstToken}
44
44
  src-chain={srcChain}
45
45
  src-token={srcToken}
46
- custom-contract-calls={customContractCalls}
46
+ custom-contract-calls={JSON.stringify(customContractCalls)}
47
47
  desc={desc}
48
48
  dst-display-token={dstDisplayToken}
49
49
  light-theme={lightTheme}
50
50
  default-wallet-picker={defaultWalletPicker}
51
- styles={styles}
51
+ styles={typeof styles === "string" ? styles : JSON.stringify(styles)}
52
52
  ></xpay-widget>
53
53
  );
54
54
  };
@@ -53,18 +53,22 @@ type SwapContext = {
53
53
  error: string;
54
54
  setError: Dispatch<SetStateAction<string>>;
55
55
  feeToken: Token | undefined;
56
+ srcChainProvided: boolean;
56
57
  srcChain: Chain | undefined;
57
58
  setSrcChain: Dispatch<SetStateAction<Chain | undefined>>;
58
59
  srcChainTokensOptions: TokenOption[];
59
60
  srcChainOtherTokensOptions: TokenOption[];
60
61
  srcChainTokensPrices: TokenPrices;
61
62
  dstChainTokensPrices: TokenPrices;
63
+ srcTokenProvided: boolean;
62
64
  srcToken: Token | undefined;
63
65
  setSrcToken: Dispatch<SetStateAction<Token | undefined>>;
66
+ dstChainProvided: boolean;
64
67
  dstChain: Chain | undefined;
65
68
  setDstChain: Dispatch<SetStateAction<Chain | undefined>>;
66
69
  dstChainTokensOptions: TokenOption[];
67
70
  dstChainOtherTokensOptions: TokenOption[];
71
+ dstTokenProvided: boolean;
68
72
  dstToken: Token | undefined;
69
73
  setDstToken: Dispatch<SetStateAction<Token | undefined>>;
70
74
  srcValue: string;
@@ -112,15 +116,19 @@ const init: SwapContext = {
112
116
  overlay: false,
113
117
  error: "",
114
118
  feeToken: undefined,
119
+ srcChainProvided: false,
115
120
  srcChain: undefined,
116
121
  srcChainTokensOptions: [],
117
122
  srcChainOtherTokensOptions: [],
118
123
  srcChainTokensPrices: {},
119
124
  dstChainTokensPrices: {},
125
+ dstChainProvided: false,
120
126
  dstChain: undefined,
121
127
  dstChainTokensOptions: [],
122
128
  dstChainOtherTokensOptions: [],
129
+ srcTokenProvided: false,
123
130
  srcToken: undefined,
131
+ dstTokenProvided: false,
124
132
  dstToken: undefined,
125
133
  srcValue: "",
126
134
  srcValueWei: "",
@@ -181,6 +189,22 @@ export const SwapProvider = ({
181
189
  const [infiniteApproval, setInfiniteApproval] = useState(
182
190
  init.infiniteApproval,
183
191
  );
192
+ const srcTokenProvided = useMemo(
193
+ () => !!integrationConfig?.srcTokenAddr,
194
+ [integrationConfig?.srcTokenAddr],
195
+ );
196
+ const dstTokenProvided = useMemo(
197
+ () => !!integrationConfig?.dstTokenAddr,
198
+ [integrationConfig?.dstTokenAddr],
199
+ );
200
+ const srcChainProvided = useMemo(
201
+ () => !!integrationConfig?.srcChainId,
202
+ [integrationConfig?.srcChainId],
203
+ );
204
+ const dstChainProvided = useMemo(
205
+ () => !!integrationConfig?.dstChainId,
206
+ [integrationConfig?.dstChainId],
207
+ );
184
208
  const [slippage, setSlippage] = useState(init.slippage);
185
209
  const [srcChain, setSrcChain] = useState(init.srcChain);
186
210
  const [dstChain, setDstChain] = useState(init.dstChain);
@@ -653,18 +677,22 @@ export const SwapProvider = ({
653
677
  error,
654
678
  setError,
655
679
  feeToken,
680
+ srcChainProvided,
656
681
  srcChain,
657
682
  setSrcChain,
658
683
  srcChainTokensOptions,
659
684
  srcChainOtherTokensOptions,
660
685
  dstChainTokensPrices,
661
686
  srcChainTokensPrices,
687
+ dstChainProvided,
662
688
  dstChain,
663
689
  setDstChain,
664
690
  dstChainTokensOptions,
665
691
  dstChainOtherTokensOptions,
692
+ srcTokenProvided,
666
693
  srcToken,
667
694
  setSrcToken,
695
+ dstTokenProvided,
668
696
  dstToken,
669
697
  setDstToken,
670
698
  srcValue,
@@ -1,4 +1,4 @@
1
- import { ContractCall } from "@src/models";
1
+ import { ContractCall, ModalIntegrationStyles } from "@src/models";
2
2
 
3
3
  export type WidgetIntegrationPayload = {
4
4
  integratorId: string;
@@ -11,5 +11,5 @@ export type WidgetIntegrationPayload = {
11
11
  dstDisplayToken?: string;
12
12
  lightTheme?: boolean;
13
13
  defaultWalletPicker?: boolean;
14
- styles?: string;
14
+ styles?: ModalIntegrationStyles | string;
15
15
  };
package/xswap.config.ts CHANGED
@@ -2,6 +2,7 @@ import { XSwapConfig } from "@src/models";
2
2
 
3
3
  const xSwapConfig: XSwapConfig = {
4
4
  apiUrl: "https://xswap.link/api",
5
+ // apiUrl: "http://127.0.0.1:5001/xswap-app/europe-west1/app/api/beta",
5
6
  localCss: false,
6
7
  };
7
8