@xswap-link/sdk 0.1.4 → 0.2.1
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/.github/workflows/publish.yml +21 -2
- package/CHANGELOG.md +12 -0
- package/dist/index.css +11 -8
- package/dist/index.d.mts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +125 -99
- package/dist/index.mjs +122 -102
- package/package.json +5 -3
- package/src/components/TxConfigForm/index.tsx +40 -32
- package/src/components/TxHistoryButton/index.tsx +20 -12
- package/src/constants/index.ts +14 -0
- package/src/services/integrations/index.ts +1 -0
- package/src/services/integrations/monitoring.ts +148 -0
- package/src/services/integrations/transactions.ts +1 -147
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
2
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
3
|
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined")
|
|
5
|
-
return require.apply(this, arguments);
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
5
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
6
|
});
|
|
8
7
|
|
|
@@ -572,6 +571,15 @@ var ROUTE_TIMEOUT_MS = 5e3;
|
|
|
572
571
|
var MINIMUM_DISPLAYED_TOKEN_AMOUNT = 1e-4;
|
|
573
572
|
var DEFAULT_SOURCE_CHAIN_ID = "1";
|
|
574
573
|
var CCIP_EXPLORER = "https://ccip.chain.link/";
|
|
574
|
+
var TX_RECEIPT_STATUS_LIFETIME = 1e4;
|
|
575
|
+
var MSG_SENT_EVENT_SIG = "MessageSent(bytes32,uint64,address,bytes,address,uint256,uint256,address,uint256)";
|
|
576
|
+
var MSG_SENT_EVENT_ABI = [
|
|
577
|
+
"event MessageSent(bytes32 indexed messageId, uint64 indexed destinationChainSelector, address indexed sender, bytes data, address token, uint256 tokenAmount, uint256 valueForInstantCcipRecieve, address transferedToken, uint256 transferedTokenAmount)"
|
|
578
|
+
];
|
|
579
|
+
var MSG_RECEIVED_EVENT_SIG = "MessageReceived(bytes32,uint64,address,bytes,address,uint256)";
|
|
580
|
+
var MSG_RECEIVED_EVENT_ABI = [
|
|
581
|
+
"event MessageReceived(bytes32 indexed messageId, uint64 indexed sourceChainSelector, address indexed sender, bytes data, address token, uint256 tokenAmount)"
|
|
582
|
+
];
|
|
575
583
|
|
|
576
584
|
// src/utils/contracts.ts
|
|
577
585
|
var IERC20 = new ethers.utils.Interface(ERC20Abi);
|
|
@@ -778,91 +786,49 @@ var generateStakingCalls = ({
|
|
|
778
786
|
return [stakingApproveCall, stakingCall];
|
|
779
787
|
};
|
|
780
788
|
|
|
781
|
-
// src/services/integrations/
|
|
789
|
+
// src/services/integrations/monitoring.ts
|
|
782
790
|
import { ethers as ethers3 } from "ethers";
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
customContractCalls = [],
|
|
787
|
-
desc
|
|
788
|
-
}) => {
|
|
789
|
-
const supportedChains = (await getChains()).filter(
|
|
790
|
-
({ web3Environment, swapSupported }) => web3Environment === "mainnet" /* MAINNET */ && swapSupported
|
|
791
|
-
);
|
|
792
|
-
validateSwapTxData(supportedChains, dstChain, dstToken);
|
|
793
|
-
const route = await openTxConfigForm({
|
|
794
|
-
dstChainId: dstChain,
|
|
795
|
-
dstTokenAddr: dstToken,
|
|
796
|
-
customContractCalls,
|
|
797
|
-
desc,
|
|
798
|
-
supportedChains
|
|
799
|
-
});
|
|
800
|
-
return route.transactions;
|
|
801
|
-
};
|
|
802
|
-
var validateSwapTxData = (supportedChains, dstChain, dstToken) => {
|
|
803
|
-
const supportedDstChain = supportedChains.find(
|
|
804
|
-
({ chainId }) => chainId === dstChain
|
|
805
|
-
);
|
|
806
|
-
if (!supportedDstChain) {
|
|
807
|
-
throw new Error(`Provided chain '${dstChain}' is not supported`);
|
|
808
|
-
}
|
|
809
|
-
if (!supportedDstChain.tokens.some(({ address }) => address === dstToken)) {
|
|
810
|
-
throw new Error(`Provided token '${dstToken}' is not supported`);
|
|
811
|
-
}
|
|
812
|
-
};
|
|
813
|
-
var monitorTransactionStatus = async (srcChainId, txHash) => {
|
|
814
|
-
const txReceipt = await getTxReceipt(srcChainId, txHash);
|
|
815
|
-
if (!txReceipt) {
|
|
816
|
-
throw new Error(
|
|
817
|
-
`No transaction found for chain ${srcChainId} tx ${txHash}`
|
|
818
|
-
);
|
|
819
|
-
}
|
|
791
|
+
import retry from "async-retry";
|
|
792
|
+
var monitorTransactionStatus = async (txChainId, txHash) => {
|
|
793
|
+
const txReceipt = await getTxReceipt(txChainId, txHash);
|
|
820
794
|
const supportedChains = (await getChains()).filter(
|
|
821
795
|
({ web3Environment, swapSupported }) => web3Environment === "mainnet" /* MAINNET */ && swapSupported
|
|
822
796
|
);
|
|
823
|
-
const messageSentEventSignature = "MessageSent(bytes32,uint64,address,bytes,address,uint256,uint256,address,uint256)";
|
|
824
|
-
const messageSentEventAbi = [
|
|
825
|
-
"event MessageSent(bytes32 indexed messageId, uint64 indexed destinationChainSelector, address indexed sender, bytes data, address token, uint256 tokenAmount, uint256 valueForInstantCcipRecieve, address transferedToken, uint256 transferedTokenAmount)"
|
|
826
|
-
];
|
|
827
|
-
const messageReceivedEventSignature = "MessageReceived(bytes32,uint64,address,bytes,address,uint256)";
|
|
828
|
-
const messageReceivedEventAbi = [
|
|
829
|
-
"event MessageReceived(bytes32 indexed messageId, uint64 indexed sourceChainSelector, address indexed sender, bytes data, address token, uint256 tokenAmount)"
|
|
830
|
-
];
|
|
831
797
|
const messageSentEvent = txReceipt.logs?.find((log) => {
|
|
832
|
-
return log.topics[0] === ethers3.utils.id(
|
|
798
|
+
return log.topics[0] === ethers3.utils.id(MSG_SENT_EVENT_SIG);
|
|
833
799
|
});
|
|
834
800
|
if (!messageSentEvent) {
|
|
835
801
|
throw new Error(
|
|
836
|
-
`No transaction event found for chain ${
|
|
802
|
+
`No transaction event found for chain ${txChainId} tx ${txHash}`
|
|
837
803
|
);
|
|
838
804
|
}
|
|
839
805
|
const messageId = messageSentEvent?.topics[1];
|
|
840
|
-
const iface = new ethers3.utils.Interface(
|
|
806
|
+
const iface = new ethers3.utils.Interface(MSG_SENT_EVENT_ABI);
|
|
841
807
|
const decodedMessageSentEvent = iface.parseLog(messageSentEvent);
|
|
842
808
|
if (!decodedMessageSentEvent) {
|
|
843
809
|
throw new Error(
|
|
844
|
-
`No transaction event arguments found for chain ${
|
|
810
|
+
`No transaction event arguments found for chain ${txChainId} tx ${txHash}`
|
|
845
811
|
);
|
|
846
812
|
}
|
|
847
813
|
const srcChain = supportedChains.find(
|
|
848
|
-
(chain) => chain.chainId ===
|
|
814
|
+
(chain) => chain.chainId === txChainId.toString()
|
|
849
815
|
);
|
|
850
816
|
const srcToken = srcChain?.tokens.find(
|
|
851
817
|
(token) => token.address === decodedMessageSentEvent.args?.token.toString()
|
|
852
818
|
);
|
|
853
|
-
const
|
|
819
|
+
const dstChain = supportedChains.find(
|
|
854
820
|
(chain) => chain.ccipChainId === decodedMessageSentEvent.args?.destinationChainSelector?.toString()
|
|
855
821
|
);
|
|
856
|
-
const
|
|
857
|
-
if (!
|
|
822
|
+
const dstChainId = dstChain?.chainId;
|
|
823
|
+
if (!dstChainId) {
|
|
858
824
|
throw new Error(`Unknown destination chain!`);
|
|
859
825
|
}
|
|
860
826
|
const transaction = {
|
|
861
827
|
txHash,
|
|
862
828
|
fromChain: srcChain?.displayName,
|
|
863
829
|
fromChainImage: srcChain?.image,
|
|
864
|
-
toChain:
|
|
865
|
-
toChainImage:
|
|
830
|
+
toChain: dstChain.displayName,
|
|
831
|
+
toChainImage: dstChain.image,
|
|
866
832
|
fromToken: srcToken?.symbol,
|
|
867
833
|
fromTokenImage: srcToken?.image,
|
|
868
834
|
fromAmount: weiToHumanReadable({
|
|
@@ -875,41 +841,83 @@ var monitorTransactionStatus = async (srcChainId, txHash) => {
|
|
|
875
841
|
};
|
|
876
842
|
addTransactionToRenderedTransactions(transaction);
|
|
877
843
|
renderTxHistoryButtons();
|
|
878
|
-
const xSwapRouterOnDestinationAddress = ADDRESSES[
|
|
844
|
+
const xSwapRouterOnDestinationAddress = ADDRESSES[dstChainId]?.XSwapRouter;
|
|
879
845
|
if (!xSwapRouterOnDestinationAddress) {
|
|
880
846
|
throw new Error(`Unknown destination XSwapRouter!`);
|
|
881
847
|
}
|
|
882
848
|
const xSwapRouterOnDestination = new ethers3.Contract(
|
|
883
849
|
xSwapRouterOnDestinationAddress,
|
|
884
|
-
|
|
850
|
+
MSG_RECEIVED_EVENT_ABI,
|
|
885
851
|
ethers3.getDefaultProvider(
|
|
886
|
-
supportedChains.find((chain) => chain.chainId ===
|
|
852
|
+
supportedChains.find((chain) => chain.chainId === dstChainId)?.publicRpcUrls[0]
|
|
887
853
|
)
|
|
888
854
|
);
|
|
889
|
-
const
|
|
855
|
+
const msgReceivedEventFilter = {
|
|
890
856
|
address: xSwapRouterOnDestinationAddress,
|
|
891
|
-
topics: [ethers3.utils.id(
|
|
857
|
+
topics: [ethers3.utils.id(MSG_RECEIVED_EVENT_SIG), messageId]
|
|
892
858
|
};
|
|
893
859
|
const onSuccess = async () => {
|
|
894
860
|
updateTransactionDoneInRenderedTransactions(txHash);
|
|
895
861
|
renderTxHistoryButtons();
|
|
896
|
-
await new Promise(
|
|
862
|
+
await new Promise(
|
|
863
|
+
(resolve) => setTimeout(() => resolve(true), TX_RECEIPT_STATUS_LIFETIME)
|
|
864
|
+
);
|
|
897
865
|
removeTransactionFromRenderedTransactions(txHash);
|
|
898
866
|
renderTxHistoryButtons();
|
|
899
867
|
};
|
|
900
|
-
xSwapRouterOnDestination.once(
|
|
868
|
+
xSwapRouterOnDestination.once(msgReceivedEventFilter, () => onSuccess());
|
|
901
869
|
};
|
|
902
870
|
var getTxReceipt = async (txChainId, txHash) => {
|
|
903
|
-
const chains = await getChains();
|
|
904
|
-
const chain = chains.find((chain2) => chain2.chainId === txChainId.toString());
|
|
905
|
-
const provider = new ethers3.providers.JsonRpcProvider(
|
|
906
|
-
chain?.publicRpcUrls[0]
|
|
907
|
-
);
|
|
908
871
|
try {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
872
|
+
const chain = (await getChains()).find(
|
|
873
|
+
(chain2) => chain2.chainId === txChainId
|
|
874
|
+
);
|
|
875
|
+
const provider = new ethers3.providers.JsonRpcProvider(
|
|
876
|
+
chain?.publicRpcUrls[0]
|
|
877
|
+
);
|
|
878
|
+
return await retry(async () => {
|
|
879
|
+
const txReceipt = await provider.getTransactionReceipt(txHash);
|
|
880
|
+
if (!txReceipt) {
|
|
881
|
+
throw new Error(`Couldn't fetch tx receipt`);
|
|
882
|
+
}
|
|
883
|
+
return txReceipt;
|
|
884
|
+
});
|
|
885
|
+
} catch (e) {
|
|
886
|
+
throw new Error(
|
|
887
|
+
`Couldn't fetch tx ${txHash} receipt on chain ${txChainId}`
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
// src/services/integrations/transactions.ts
|
|
893
|
+
var getSwapTx = async ({
|
|
894
|
+
dstChain,
|
|
895
|
+
dstToken,
|
|
896
|
+
customContractCalls = [],
|
|
897
|
+
desc
|
|
898
|
+
}) => {
|
|
899
|
+
const supportedChains = (await getChains()).filter(
|
|
900
|
+
({ web3Environment, swapSupported }) => web3Environment === "mainnet" /* MAINNET */ && swapSupported
|
|
901
|
+
);
|
|
902
|
+
validateSwapTxData(supportedChains, dstChain, dstToken);
|
|
903
|
+
const route = await openTxConfigForm({
|
|
904
|
+
dstChainId: dstChain,
|
|
905
|
+
dstTokenAddr: dstToken,
|
|
906
|
+
customContractCalls,
|
|
907
|
+
desc,
|
|
908
|
+
supportedChains
|
|
909
|
+
});
|
|
910
|
+
return route.transactions;
|
|
911
|
+
};
|
|
912
|
+
var validateSwapTxData = (supportedChains, dstChain, dstToken) => {
|
|
913
|
+
const supportedDstChain = supportedChains.find(
|
|
914
|
+
({ chainId }) => chainId === dstChain
|
|
915
|
+
);
|
|
916
|
+
if (!supportedDstChain) {
|
|
917
|
+
throw new Error(`Provided chain '${dstChain}' is not supported`);
|
|
918
|
+
}
|
|
919
|
+
if (!supportedDstChain.tokens.some(({ address }) => address === dstToken)) {
|
|
920
|
+
throw new Error(`Provided token '${dstToken}' is not supported`);
|
|
913
921
|
}
|
|
914
922
|
};
|
|
915
923
|
|
|
@@ -918,14 +926,12 @@ import { useEffect, useRef, useState } from "react";
|
|
|
918
926
|
var useDebounce = (value, delay) => {
|
|
919
927
|
const timeoutRef = useRef(null);
|
|
920
928
|
useEffect(() => {
|
|
921
|
-
if (timeoutRef.current)
|
|
922
|
-
clearTimeout(timeoutRef.current);
|
|
929
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
923
930
|
timeoutRef.current = setTimeout(() => {
|
|
924
931
|
setValue(value);
|
|
925
932
|
}, delay);
|
|
926
933
|
return () => {
|
|
927
|
-
if (timeoutRef.current)
|
|
928
|
-
clearTimeout(timeoutRef.current);
|
|
934
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
929
935
|
};
|
|
930
936
|
}, [value, delay]);
|
|
931
937
|
const [debouncedValue, setValue] = useState(value);
|
|
@@ -1498,8 +1504,7 @@ var History = ({ signer, supportedChains }) => {
|
|
|
1498
1504
|
continue;
|
|
1499
1505
|
}
|
|
1500
1506
|
let status;
|
|
1501
|
-
if (entry.failed)
|
|
1502
|
-
status = "REVERTED";
|
|
1507
|
+
if (entry.failed) status = "REVERTED";
|
|
1503
1508
|
if (!!entry.target) {
|
|
1504
1509
|
status = "DONE";
|
|
1505
1510
|
} else {
|
|
@@ -1530,8 +1535,7 @@ var History = ({ signer, supportedChains }) => {
|
|
|
1530
1535
|
}
|
|
1531
1536
|
}, [signer, getHistory]);
|
|
1532
1537
|
useEffect2(() => {
|
|
1533
|
-
if (!historyLoadedOnce)
|
|
1534
|
-
fetchHistory();
|
|
1538
|
+
if (!historyLoadedOnce) fetchHistory();
|
|
1535
1539
|
const timer = setInterval(() => {
|
|
1536
1540
|
fetchHistory();
|
|
1537
1541
|
}, 6e4);
|
|
@@ -2015,10 +2019,8 @@ import BigNumber3 from "bignumber.js";
|
|
|
2015
2019
|
import { Fragment as Fragment5, jsx as jsx32, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2016
2020
|
var BalanceComponent = ({ srcToken, balances }) => {
|
|
2017
2021
|
const balanceText = useMemo5(() => {
|
|
2018
|
-
if (!balances || !srcToken)
|
|
2019
|
-
|
|
2020
|
-
if (balances[srcToken.address]?.toString() === "0")
|
|
2021
|
-
return "0";
|
|
2022
|
+
if (!balances || !srcToken) return "0";
|
|
2023
|
+
if (balances[srcToken.address]?.toString() === "0") return "0";
|
|
2022
2024
|
const fullHumanReadable = weiToHumanReadable({
|
|
2023
2025
|
amount: balances[srcToken.address]?.toString() || "0",
|
|
2024
2026
|
decimals: srcToken.decimals,
|
|
@@ -2102,8 +2104,7 @@ var SwapPanel = ({
|
|
|
2102
2104
|
className: "p-0 border-none outline-none bg-transparent text-2xl overflow-ellipsis",
|
|
2103
2105
|
value: amount,
|
|
2104
2106
|
onChange: (e) => {
|
|
2105
|
-
if (e.target.value === ".")
|
|
2106
|
-
return;
|
|
2107
|
+
if (e.target.value === ".") return;
|
|
2107
2108
|
if (NUMBER_INPUT_REGEX.test(e.target.value)) {
|
|
2108
2109
|
setAmount(e.target.value.replace(/,/g, "."));
|
|
2109
2110
|
}
|
|
@@ -2369,8 +2370,7 @@ var Form = ({
|
|
|
2369
2370
|
}, [srcChain, signer]);
|
|
2370
2371
|
const handleSubmit = (event) => {
|
|
2371
2372
|
event.preventDefault();
|
|
2372
|
-
if (route)
|
|
2373
|
-
onSubmit(route);
|
|
2373
|
+
if (route) onSubmit(route);
|
|
2374
2374
|
};
|
|
2375
2375
|
const handleSwitchChain = async () => {
|
|
2376
2376
|
await switchChainAsync({ chainId: Number(srcChain?.chainId) });
|
|
@@ -2454,6 +2454,9 @@ var Form = ({
|
|
|
2454
2454
|
);
|
|
2455
2455
|
};
|
|
2456
2456
|
|
|
2457
|
+
// package.json
|
|
2458
|
+
var version = "0.2.1";
|
|
2459
|
+
|
|
2457
2460
|
// src/components/TxConfigForm/index.tsx
|
|
2458
2461
|
import { jsx as jsx38, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2459
2462
|
var TxConfigForm = ({
|
|
@@ -2521,7 +2524,7 @@ var openTxConfigForm = async ({
|
|
|
2521
2524
|
}) => {
|
|
2522
2525
|
try {
|
|
2523
2526
|
return await new Promise((resolve) => {
|
|
2524
|
-
|
|
2527
|
+
xswapRoot.render(
|
|
2525
2528
|
/* @__PURE__ */ jsx38(
|
|
2526
2529
|
TxConfigForm,
|
|
2527
2530
|
{
|
|
@@ -2532,10 +2535,10 @@ var openTxConfigForm = async ({
|
|
|
2532
2535
|
supportedChains,
|
|
2533
2536
|
onSubmit: (route) => {
|
|
2534
2537
|
resolve(route);
|
|
2535
|
-
|
|
2538
|
+
xswapRoot.render("");
|
|
2536
2539
|
},
|
|
2537
2540
|
onClose: () => {
|
|
2538
|
-
|
|
2541
|
+
xswapRoot.render("");
|
|
2539
2542
|
}
|
|
2540
2543
|
}
|
|
2541
2544
|
)
|
|
@@ -2545,16 +2548,21 @@ var openTxConfigForm = async ({
|
|
|
2545
2548
|
throw new Error(`XSwap component error, ${err}`);
|
|
2546
2549
|
}
|
|
2547
2550
|
};
|
|
2548
|
-
var
|
|
2551
|
+
var xswapRoot;
|
|
2549
2552
|
if (typeof document !== "undefined") {
|
|
2550
|
-
const
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2553
|
+
const xswapStyleElement = document.createElement("link");
|
|
2554
|
+
xswapStyleElement.rel = "stylesheet";
|
|
2555
|
+
xswapStyleElement.type = "text/css";
|
|
2556
|
+
xswapStyleElement.href = `${xswap_config_default.apiUrl}/sdk/css?data={"version": "${version}"}`;
|
|
2557
|
+
document.head.appendChild(xswapStyleElement);
|
|
2558
|
+
const xswapModalElement = document.createElement("div");
|
|
2559
|
+
xswapModalElement.setAttribute("id", "xswap-modal");
|
|
2560
|
+
document.body.appendChild(xswapModalElement);
|
|
2561
|
+
xswapRoot = createRoot(xswapModalElement);
|
|
2554
2562
|
}
|
|
2555
2563
|
|
|
2556
2564
|
// src/components/TxHistoryButton/index.tsx
|
|
2557
|
-
import { useState as useState9 } from "react";
|
|
2565
|
+
import { useMemo as useMemo8, useState as useState9 } from "react";
|
|
2558
2566
|
import { createRoot as createRoot2 } from "react-dom/client";
|
|
2559
2567
|
import { Fragment as Fragment6, jsx as jsx39, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2560
2568
|
var TxHistoryButton = ({ transaction }) => {
|
|
@@ -2571,11 +2579,19 @@ var TxHistoryButton = ({ transaction }) => {
|
|
|
2571
2579
|
explorer
|
|
2572
2580
|
} = transaction;
|
|
2573
2581
|
const [isWide, setIsWide] = useState9(false);
|
|
2582
|
+
const background = useMemo8(
|
|
2583
|
+
() => isDone ? "bg-[rgba(2,2,2,1)] bg-gradient-to-r from-[rgba(76,175,80,0.2)] to-[rgba(46,125,50,0.2)]" : "bg-[rgba(2,2,2,1)] bg-gradient-to-r from-[rgba(54,129,198,0.2)] to-[rgba(43,74,157,0.2)]",
|
|
2584
|
+
[isDone]
|
|
2585
|
+
);
|
|
2586
|
+
const border = useMemo8(
|
|
2587
|
+
() => isDone ? "border border-solid border-x_green_dark" : "border border-solid border-x_blue_dark",
|
|
2588
|
+
[isDone]
|
|
2589
|
+
);
|
|
2574
2590
|
return /* @__PURE__ */ jsxs18("div", { className: "flex gap-2", onClick: () => setIsWide((x) => !x), children: [
|
|
2575
2591
|
isWide && /* @__PURE__ */ jsxs18(
|
|
2576
2592
|
"div",
|
|
2577
2593
|
{
|
|
2578
|
-
className: `flex items-center min-w-60 sm:w-[520px] text-white h-14 px-4 text-sm gap-3 rounded-xl
|
|
2594
|
+
className: `flex items-center min-w-60 sm:w-[520px] text-white h-14 px-4 text-sm gap-3 rounded-xl ${background} ${border}`,
|
|
2579
2595
|
children: [
|
|
2580
2596
|
/* @__PURE__ */ jsxs18("div", { className: "flex justify-between flex-col gap-2 sm:gap-5 sm:flex-row w-full", children: [
|
|
2581
2597
|
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", children: [
|
|
@@ -2623,8 +2639,7 @@ var TxHistoryButton = ({ transaction }) => {
|
|
|
2623
2639
|
/* @__PURE__ */ jsx39(
|
|
2624
2640
|
"div",
|
|
2625
2641
|
{
|
|
2626
|
-
className: `text-white rounded-xl cursor-pointer
|
|
2627
|
-
${isDone ? "from-[rgba(76,175,80,0.1)] to-[rgba(46,125,50,0.1)] border border-solid border-x_green_dark" : "from-[rgba(54,129,198,0.1)] to-[rgba(43,74,157,0.1)] border border-solid border-x_blue_dark"}`,
|
|
2642
|
+
className: `text-white rounded-xl cursor-pointer ${background} ${border}`,
|
|
2628
2643
|
children: /* @__PURE__ */ jsxs18("div", { className: "flex gap-2 items-center h-14 w-20 justify-center", children: [
|
|
2629
2644
|
/* @__PURE__ */ jsx39(ArrowLeftIcon, {}),
|
|
2630
2645
|
/* @__PURE__ */ jsx39("div", { className: "relative flex items-center justify-center w-9 h-9", children: isDone ? /* @__PURE__ */ jsx39("div", { className: "text-x_green w-5 h-5", children: /* @__PURE__ */ jsx39(CheckIcon, {}) }) : /* @__PURE__ */ jsxs18(Fragment6, { children: [
|
|
@@ -2689,10 +2704,15 @@ export {
|
|
|
2689
2704
|
Environment,
|
|
2690
2705
|
IERC20,
|
|
2691
2706
|
MINIMUM_DISPLAYED_TOKEN_AMOUNT,
|
|
2707
|
+
MSG_RECEIVED_EVENT_ABI,
|
|
2708
|
+
MSG_RECEIVED_EVENT_SIG,
|
|
2709
|
+
MSG_SENT_EVENT_ABI,
|
|
2710
|
+
MSG_SENT_EVENT_SIG,
|
|
2692
2711
|
NUMBER_INPUT_REGEX,
|
|
2693
2712
|
ROUTE_TIMEOUT_MS,
|
|
2694
2713
|
SLIPPAGE_PRESETS,
|
|
2695
2714
|
Skeleton,
|
|
2715
|
+
TX_RECEIPT_STATUS_LIFETIME,
|
|
2696
2716
|
TxHistoryButton,
|
|
2697
2717
|
Web3Environment,
|
|
2698
2718
|
XSwapCallType,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xswap-link/sdk",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "JavaScript SDK for XSwap platform",
|
|
5
5
|
"homepage": "https://github.com/xswap-link/xswap-sdk",
|
|
6
6
|
"repository": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"@tanstack/react-query": "^5.35.5",
|
|
24
24
|
"@types/react": "18.2.0",
|
|
25
25
|
"@types/react-dom": "18.2.0",
|
|
26
|
+
"async-retry": "^1.3.3",
|
|
26
27
|
"bignumber.js": "4.0.4",
|
|
27
28
|
"date-fns": "^3.6.0",
|
|
28
29
|
"ethers": "^5.7.2",
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@changesets/cli": "^2.27.1",
|
|
37
|
+
"@types/async-retry": "^1.4.8",
|
|
36
38
|
"@types/jest": "^29.5.12",
|
|
37
39
|
"@types/node": "^20.11.17",
|
|
38
40
|
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
|
@@ -56,8 +58,8 @@
|
|
|
56
58
|
},
|
|
57
59
|
"scripts": {
|
|
58
60
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
59
|
-
"watch": "nodemon",
|
|
60
|
-
"release": "pnpm
|
|
61
|
+
"watch": "pnpm build && nodemon",
|
|
62
|
+
"release": "pnpm build && changeset publish",
|
|
61
63
|
"lint": "tsc && eslint . --ext .ts",
|
|
62
64
|
"test": "jest"
|
|
63
65
|
}
|
|
@@ -8,6 +8,8 @@ import { Chain, ContractCall, Route } from "@src/models";
|
|
|
8
8
|
import { CloseIcon } from "@src/components/icons/CloseIcon";
|
|
9
9
|
import { Form } from "./Form";
|
|
10
10
|
import { ChainlinkCCIPIcon, XSwapBadgeIcon } from "../icons";
|
|
11
|
+
import { version } from "../../../package.json";
|
|
12
|
+
import xswapConfig from "../../../xswap.config";
|
|
11
13
|
|
|
12
14
|
export type TxConfigFormProps = {
|
|
13
15
|
dstChainId: string;
|
|
@@ -46,34 +48,34 @@ const TxConfigForm = ({
|
|
|
46
48
|
return (
|
|
47
49
|
<WagmiProvider config={wagmiConfig}>
|
|
48
50
|
<QueryClientProvider client={queryClient}>
|
|
49
|
-
<div
|
|
50
|
-
className="top-0 left-0 right-0 bottom-0 bg-[rgba(0,0,0,0.8)] fixed flex items-center justify-center z-10"
|
|
51
|
-
onClick={onBackdropClick}
|
|
52
|
-
>
|
|
53
|
-
<div className="relative bg-black rounded-3xl w-lg overflow-auto text-white border-2 border-solid border-[rgba(255,255,255,0.1)]">
|
|
54
|
-
<Form
|
|
55
|
-
dstChainId={dstChainId}
|
|
56
|
-
dstTokenAddr={dstTokenAddr}
|
|
57
|
-
customContractCalls={customContractCalls}
|
|
58
|
-
desc={desc}
|
|
59
|
-
supportedChains={supportedChains}
|
|
60
|
-
onSubmit={onSubmit}
|
|
61
|
-
/>
|
|
62
51
|
<div
|
|
63
|
-
className="
|
|
64
|
-
onClick={
|
|
52
|
+
className="top-0 left-0 right-0 bottom-0 bg-[rgba(0,0,0,0.8)] fixed flex items-center justify-center z-10"
|
|
53
|
+
onClick={onBackdropClick}
|
|
65
54
|
>
|
|
66
|
-
<
|
|
67
|
-
|
|
55
|
+
<div className="relative bg-black rounded-3xl w-lg overflow-auto text-white border-2 border-solid border-[rgba(255,255,255,0.1)]">
|
|
56
|
+
<Form
|
|
57
|
+
dstChainId={dstChainId}
|
|
58
|
+
dstTokenAddr={dstTokenAddr}
|
|
59
|
+
customContractCalls={customContractCalls}
|
|
60
|
+
desc={desc}
|
|
61
|
+
supportedChains={supportedChains}
|
|
62
|
+
onSubmit={onSubmit}
|
|
63
|
+
/>
|
|
64
|
+
<div
|
|
65
|
+
className="absolute top-7 right-4 cursor-pointer text-white"
|
|
66
|
+
onClick={onClose}
|
|
67
|
+
>
|
|
68
|
+
<CloseIcon />
|
|
69
|
+
</div>
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
<div className="swappage__poweredby">
|
|
72
|
+
<span>Powered by</span>
|
|
73
|
+
<XSwapBadgeIcon />
|
|
74
|
+
<span>✕</span>
|
|
75
|
+
<ChainlinkCCIPIcon />
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
74
78
|
</div>
|
|
75
|
-
</div>
|
|
76
|
-
</div>
|
|
77
79
|
</QueryClientProvider>
|
|
78
80
|
</WagmiProvider>
|
|
79
81
|
);
|
|
@@ -88,7 +90,7 @@ export const openTxConfigForm = async ({
|
|
|
88
90
|
}: TxConfigFormProps): Promise<Route> => {
|
|
89
91
|
try {
|
|
90
92
|
return await new Promise((resolve) => {
|
|
91
|
-
|
|
93
|
+
xswapRoot.render(
|
|
92
94
|
<TxConfigForm
|
|
93
95
|
dstChainId={dstChainId}
|
|
94
96
|
dstTokenAddr={dstTokenAddr}
|
|
@@ -97,10 +99,10 @@ export const openTxConfigForm = async ({
|
|
|
97
99
|
supportedChains={supportedChains}
|
|
98
100
|
onSubmit={(route) => {
|
|
99
101
|
resolve(route);
|
|
100
|
-
|
|
102
|
+
xswapRoot.render("");
|
|
101
103
|
}}
|
|
102
104
|
onClose={() => {
|
|
103
|
-
|
|
105
|
+
xswapRoot.render("");
|
|
104
106
|
}}
|
|
105
107
|
/>,
|
|
106
108
|
);
|
|
@@ -111,10 +113,16 @@ export const openTxConfigForm = async ({
|
|
|
111
113
|
};
|
|
112
114
|
|
|
113
115
|
// skip on server-side integrations
|
|
114
|
-
let
|
|
116
|
+
let xswapRoot: Root;
|
|
115
117
|
if (typeof document !== "undefined") {
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
const xswapStyleElement = document.createElement("link");
|
|
119
|
+
xswapStyleElement.rel = "stylesheet";
|
|
120
|
+
xswapStyleElement.type = "text/css";
|
|
121
|
+
xswapStyleElement.href = `${xswapConfig.apiUrl}/sdk/css?data={"version": "${version}"}`;
|
|
122
|
+
document.head.appendChild(xswapStyleElement);
|
|
123
|
+
|
|
124
|
+
const xswapModalElement = document.createElement("div");
|
|
125
|
+
xswapModalElement.setAttribute("id", "xswap-modal");
|
|
126
|
+
document.body.appendChild(xswapModalElement);
|
|
127
|
+
xswapRoot = createRoot(xswapModalElement);
|
|
120
128
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FC, useState } from "react";
|
|
1
|
+
import { FC, useMemo, useState } from "react";
|
|
2
2
|
import { createRoot } from "react-dom/client";
|
|
3
3
|
import {
|
|
4
4
|
ArrowLeftIcon,
|
|
@@ -27,15 +27,28 @@ export const TxHistoryButton: FC<Props> = ({ transaction }) => {
|
|
|
27
27
|
explorer,
|
|
28
28
|
} = transaction;
|
|
29
29
|
const [isWide, setIsWide] = useState(false);
|
|
30
|
+
|
|
31
|
+
const background = useMemo(
|
|
32
|
+
() =>
|
|
33
|
+
isDone
|
|
34
|
+
? "bg-[rgba(2,2,2,1)] bg-gradient-to-r from-[rgba(76,175,80,0.2)] to-[rgba(46,125,50,0.2)]"
|
|
35
|
+
: "bg-[rgba(2,2,2,1)] bg-gradient-to-r from-[rgba(54,129,198,0.2)] to-[rgba(43,74,157,0.2)]",
|
|
36
|
+
[isDone],
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const border = useMemo(
|
|
40
|
+
() =>
|
|
41
|
+
isDone
|
|
42
|
+
? "border border-solid border-x_green_dark"
|
|
43
|
+
: "border border-solid border-x_blue_dark",
|
|
44
|
+
[isDone],
|
|
45
|
+
);
|
|
46
|
+
|
|
30
47
|
return (
|
|
31
48
|
<div className="flex gap-2" onClick={() => setIsWide((x: boolean) => !x)}>
|
|
32
49
|
{isWide && (
|
|
33
50
|
<div
|
|
34
|
-
className={`flex items-center min-w-60 sm:w-[520px] text-white h-14 px-4 text-sm gap-3 rounded-xl
|
|
35
|
-
isDone
|
|
36
|
-
? "from-[rgba(76,175,80,0.1)] to-[rgba(46,125,50,0.1)] border border-solid border-x_green_dark"
|
|
37
|
-
: "from-[rgba(54,129,198,0.1)] to-[rgba(43,74,157,0.1)] border border-solid border-x_blue_dark"
|
|
38
|
-
}`}
|
|
51
|
+
className={`flex items-center min-w-60 sm:w-[520px] text-white h-14 px-4 text-sm gap-3 rounded-xl ${background} ${border}`}
|
|
39
52
|
>
|
|
40
53
|
<div className="flex justify-between flex-col gap-2 sm:gap-5 sm:flex-row w-full">
|
|
41
54
|
<div className="flex items-center gap-2">
|
|
@@ -77,12 +90,7 @@ export const TxHistoryButton: FC<Props> = ({ transaction }) => {
|
|
|
77
90
|
</div>
|
|
78
91
|
)}
|
|
79
92
|
<div
|
|
80
|
-
className={`text-white rounded-xl cursor-pointer
|
|
81
|
-
${
|
|
82
|
-
isDone
|
|
83
|
-
? "from-[rgba(76,175,80,0.1)] to-[rgba(46,125,50,0.1)] border border-solid border-x_green_dark"
|
|
84
|
-
: "from-[rgba(54,129,198,0.1)] to-[rgba(43,74,157,0.1)] border border-solid border-x_blue_dark"
|
|
85
|
-
}`}
|
|
93
|
+
className={`text-white rounded-xl cursor-pointer ${background} ${border}`}
|
|
86
94
|
>
|
|
87
95
|
<div className="flex gap-2 items-center h-14 w-20 justify-center">
|
|
88
96
|
<ArrowLeftIcon />
|
package/src/constants/index.ts
CHANGED
|
@@ -10,3 +10,17 @@ export const ROUTE_TIMEOUT_MS = 5000;
|
|
|
10
10
|
export const MINIMUM_DISPLAYED_TOKEN_AMOUNT = 0.0001;
|
|
11
11
|
export const DEFAULT_SOURCE_CHAIN_ID = "1";
|
|
12
12
|
export const CCIP_EXPLORER = "https://ccip.chain.link/";
|
|
13
|
+
export const TX_RECEIPT_STATUS_LIFETIME = 10000;
|
|
14
|
+
|
|
15
|
+
export const MSG_SENT_EVENT_SIG =
|
|
16
|
+
"MessageSent(bytes32,uint64,address,bytes,address,uint256,uint256,address,uint256)";
|
|
17
|
+
|
|
18
|
+
export const MSG_SENT_EVENT_ABI = [
|
|
19
|
+
"event MessageSent(bytes32 indexed messageId, uint64 indexed destinationChainSelector, address indexed sender, bytes data, address token, uint256 tokenAmount, uint256 valueForInstantCcipRecieve, address transferedToken, uint256 transferedTokenAmount)",
|
|
20
|
+
];
|
|
21
|
+
export const MSG_RECEIVED_EVENT_SIG =
|
|
22
|
+
"MessageReceived(bytes32,uint64,address,bytes,address,uint256)";
|
|
23
|
+
|
|
24
|
+
export const MSG_RECEIVED_EVENT_ABI = [
|
|
25
|
+
"event MessageReceived(bytes32 indexed messageId, uint64 indexed sourceChainSelector, address indexed sender, bytes data, address token, uint256 tokenAmount)",
|
|
26
|
+
];
|