@xswap-link/sdk 0.2.4 → 0.2.6
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 +14 -0
- package/dist/index.css +244 -267
- package/dist/index.d.mts +19 -12
- package/dist/index.d.ts +19 -12
- package/dist/index.js +588 -432
- package/dist/index.mjs +539 -383
- package/package.json +1 -1
- package/src/components/Alert/index.tsx +1 -1
- package/src/components/Skeleton/index.tsx +3 -1
- package/src/components/TxConfigForm/BalanceComponent.tsx +1 -1
- package/src/components/TxConfigForm/Button.tsx +1 -1
- package/src/components/TxConfigForm/ChainListElement.tsx +2 -2
- package/src/components/TxConfigForm/Description.tsx +2 -2
- package/src/components/TxConfigForm/ErrorField.tsx +4 -2
- package/src/components/TxConfigForm/FeesDetails.tsx +35 -31
- package/src/components/TxConfigForm/Form.tsx +23 -7
- package/src/components/TxConfigForm/History.tsx +36 -9
- package/src/components/TxConfigForm/HistoryCard.tsx +33 -40
- package/src/components/TxConfigForm/PoweredBy.tsx +2 -2
- package/src/components/TxConfigForm/Settings.tsx +33 -27
- package/src/components/TxConfigForm/Summary.tsx +33 -20
- package/src/components/TxConfigForm/SwapPanel.tsx +12 -12
- package/src/components/TxConfigForm/TokenPicker.tsx +36 -34
- package/src/components/TxConfigForm/TopBar.tsx +8 -8
- package/src/components/TxConfigForm/UsdPrice.tsx +2 -2
- package/src/components/TxConfigForm/index.tsx +11 -6
- package/src/components/TxStatusButton/index.tsx +47 -35
- package/src/components/UnknownTokenLogo/UnknownTokenLogo.tsx +14 -0
- package/src/components/global.css +7 -5
- package/src/components/icons/CircularProgressIcon.tsx +1 -1
- package/src/config/init.tsx +19 -18
- package/src/index.ts +9 -1
- package/src/models/TokenData.ts +1 -1
- package/src/models/TransactionHistory.ts +12 -8
- package/src/models/payloads/GetRoutePayload.ts +1 -0
- package/src/models/payloads/GetSwapTxPayload.ts +1 -0
- package/src/services/api.ts +9 -0
- package/src/services/blockchain.ts +49 -0
- package/src/services/index.ts +1 -0
- package/src/services/integrations/monitoring.ts +34 -14
- package/src/services/integrations/transactions.ts +8 -3
- package/src/utils/strings.ts +4 -0
- package/tailwind.config.js +1 -0
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
XSwapLogo,
|
|
9
9
|
} from "../icons";
|
|
10
10
|
import { MonitoredTransaction } from "@src/models";
|
|
11
|
-
import {
|
|
11
|
+
import { xpayTxStatusRoot } from "@src/config";
|
|
12
|
+
import { UnknownTokenLogo } from "../UnknownTokenLogo/UnknownTokenLogo";
|
|
12
13
|
|
|
13
14
|
interface Props {
|
|
14
15
|
transaction: MonitoredTransaction;
|
|
@@ -16,15 +17,14 @@ interface Props {
|
|
|
16
17
|
|
|
17
18
|
export const TxStatusButton: FC<Props> = ({ transaction }) => {
|
|
18
19
|
const {
|
|
19
|
-
fromChain,
|
|
20
|
-
fromChainImage,
|
|
21
|
-
fromToken,
|
|
22
|
-
fromTokenImage,
|
|
23
|
-
fromAmount,
|
|
24
|
-
toChain,
|
|
25
|
-
toChainImage,
|
|
20
|
+
srcChain: fromChain,
|
|
21
|
+
srcChainImage: fromChainImage,
|
|
22
|
+
srcToken: fromToken,
|
|
23
|
+
srcTokenImage: fromTokenImage,
|
|
24
|
+
srcAmount: fromAmount,
|
|
25
|
+
dstChain: toChain,
|
|
26
|
+
dstChainImage: toChainImage,
|
|
26
27
|
isDone,
|
|
27
|
-
txHash,
|
|
28
28
|
explorer,
|
|
29
29
|
} = transaction;
|
|
30
30
|
const [isWide, setIsWide] = useState(false);
|
|
@@ -32,80 +32,92 @@ export const TxStatusButton: FC<Props> = ({ transaction }) => {
|
|
|
32
32
|
const background = useMemo(
|
|
33
33
|
() =>
|
|
34
34
|
isDone
|
|
35
|
-
? "bg-[rgba(2,2,2,1)] bg-gradient-to-r from-[rgba(76,175,80,0.2)] to-[rgba(46,125,50,0.2)]"
|
|
36
|
-
: "bg-[rgba(2,2,2,1)] bg-gradient-to-r from-[rgba(54,129,198,0.2)] to-[rgba(43,74,157,0.2)]",
|
|
35
|
+
? "xpay-bg-[rgba(2,2,2,1)] xpay-bg-gradient-to-r xpay-from-[rgba(76,175,80,0.2)] xpay-to-[rgba(46,125,50,0.2)]"
|
|
36
|
+
: "xpay-bg-[rgba(2,2,2,1)] xpay-bg-gradient-to-r xpay-from-[rgba(54,129,198,0.2)] xpay-to-[rgba(43,74,157,0.2)]",
|
|
37
37
|
[isDone],
|
|
38
38
|
);
|
|
39
39
|
|
|
40
40
|
const border = useMemo(
|
|
41
41
|
() =>
|
|
42
42
|
isDone
|
|
43
|
-
? "border border-solid border-x_green_dark"
|
|
44
|
-
: "border border-solid border-x_blue_dark",
|
|
43
|
+
? "xpay-border xpay-border-solid xpay-border-x_green_dark"
|
|
44
|
+
: "xpay-border xpay-border-solid xpay-border-x_blue_dark",
|
|
45
45
|
[isDone],
|
|
46
46
|
);
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
|
-
<div
|
|
49
|
+
<div
|
|
50
|
+
className="xpay-flex xpay-gap-2"
|
|
51
|
+
onClick={() => setIsWide((x: boolean) => !x)}
|
|
52
|
+
>
|
|
50
53
|
{isWide && (
|
|
51
54
|
<div
|
|
52
|
-
className={`flex items-center min-w-60 sm:w-[520px] text-white h-14 px-4 text-sm gap-3 rounded-xl ${background} ${border}`}
|
|
55
|
+
className={`xpay-flex xpay-items-center xpay-min-w-60 sm:xpay-w-[520px] xpay-text-white xpay-h-14 xpay-px-4 xpay-text-sm xpay-gap-3 xpay-rounded-xl ${background} ${border}`}
|
|
53
56
|
>
|
|
54
|
-
<div className="flex justify-between flex-col gap-2 sm:gap-5 sm:flex-row w-full">
|
|
55
|
-
<div className="flex items-center gap-2">
|
|
57
|
+
<div className="xpay-flex xpay-justify-between xpay-flex-col xpay-gap-2 sm:xpay-gap-5 sm:xpay-flex-row xpay-w-full">
|
|
58
|
+
<div className="xpay-flex xpay-items-center xpay-gap-2">
|
|
56
59
|
<img
|
|
57
|
-
className="w-5 h-5"
|
|
60
|
+
className="xpay-w-5 xpay-h-5"
|
|
58
61
|
src={fromChainImage}
|
|
59
62
|
alt="source chain"
|
|
60
63
|
/>
|
|
61
64
|
<div>{fromChain}</div>
|
|
62
|
-
<div className="w-3.5 h-3.5">
|
|
65
|
+
<div className="xpay-w-3.5 xpay-h-3.5">
|
|
63
66
|
<ArrowRightIcon />
|
|
64
67
|
</div>
|
|
65
|
-
<img
|
|
68
|
+
<img
|
|
69
|
+
className="xpay-w-5 xpay-h-5"
|
|
70
|
+
src={toChainImage}
|
|
71
|
+
alt="to chain"
|
|
72
|
+
/>
|
|
66
73
|
<div>{toChain}</div>
|
|
67
74
|
</div>
|
|
68
75
|
|
|
69
|
-
<div className="flex items-center gap-2">
|
|
76
|
+
<div className="xpay-flex xpay-items-center xpay-gap-2">
|
|
70
77
|
<div>Sent</div>
|
|
71
78
|
<div>{fromAmount}</div>
|
|
72
79
|
<div>{fromToken}</div>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
|
|
81
|
+
{fromTokenImage ? (
|
|
82
|
+
<img
|
|
83
|
+
className="xpay-w-5 xpay-h-5"
|
|
84
|
+
src={fromTokenImage}
|
|
85
|
+
alt="source token"
|
|
86
|
+
/>
|
|
87
|
+
) : (
|
|
88
|
+
<UnknownTokenLogo tokenName={"?"} />
|
|
89
|
+
)}
|
|
78
90
|
</div>
|
|
79
91
|
</div>
|
|
80
92
|
<a
|
|
81
93
|
href={explorer}
|
|
82
94
|
target="_blank"
|
|
83
95
|
rel="noreferrer"
|
|
84
|
-
className="no-underline cursor-pointer"
|
|
96
|
+
className="xpay-no-underline xpay-cursor-pointer"
|
|
85
97
|
aria-label="Show the transaction in the chain explorer"
|
|
86
98
|
>
|
|
87
|
-
<div className="w-3.5 h-3.5">
|
|
99
|
+
<div className="xpay-w-3.5 xpay-h-3.5">
|
|
88
100
|
<ArrowUpRightIcon />
|
|
89
101
|
</div>
|
|
90
102
|
</a>
|
|
91
103
|
</div>
|
|
92
104
|
)}
|
|
93
105
|
<div
|
|
94
|
-
className={`text-white rounded-xl cursor-pointer ${background} ${border}`}
|
|
106
|
+
className={`xpay-text-white xpay-rounded-xl xpay-cursor-pointer ${background} ${border}`}
|
|
95
107
|
>
|
|
96
|
-
<div className="flex gap-2 items-center h-14 w-20 justify-center">
|
|
108
|
+
<div className="xpay-flex xpay-gap-2 xpay-items-center xpay-h-14 xpay-w-20 xpay-justify-center">
|
|
97
109
|
<ArrowLeftIcon />
|
|
98
|
-
<div className="relative flex items-center justify-center w-9 h-9">
|
|
110
|
+
<div className="xpay-relative xpay-flex xpay-items-center xpay-justify-center xpay-w-9 xpay-h-9">
|
|
99
111
|
{isDone ? (
|
|
100
|
-
<div className="text-x_green w-5 h-5">
|
|
112
|
+
<div className="xpay-text-x_green xpay-w-5 xpay-h-5">
|
|
101
113
|
<CheckIcon />
|
|
102
114
|
</div>
|
|
103
115
|
) : (
|
|
104
116
|
<>
|
|
105
|
-
<div className="w-5 h-5">
|
|
117
|
+
<div className="xpay-w-5 xpay-h-5">
|
|
106
118
|
<XSwapLogo />
|
|
107
119
|
</div>
|
|
108
|
-
<div className="absolute flex items-center justify-center top-0 left-0 right-0 bottom-0 text-white">
|
|
120
|
+
<div className="xpay-absolute xpay-flex xpay-items-center xpay-justify-center xpay-top-0 xpay-left-0 xpay-right-0 xpay-bottom-0 xpay-text-white">
|
|
109
121
|
<CircularProgressIcon />
|
|
110
122
|
</div>
|
|
111
123
|
</>
|
|
@@ -146,5 +158,5 @@ export const renderTxStatusButtons = () => {
|
|
|
146
158
|
const buttons = renderedTransactions.map((item) => (
|
|
147
159
|
<TxStatusButton key={item.txHash} transaction={item} />
|
|
148
160
|
));
|
|
149
|
-
|
|
161
|
+
xpayTxStatusRoot.render(buttons);
|
|
150
162
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
tokenName: string;
|
|
3
|
+
className?: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export const UnknownTokenLogo = ({ tokenName, className }: Props) => {
|
|
7
|
+
return (
|
|
8
|
+
<div
|
|
9
|
+
className={`xpay-w-5 xpay-h-5 xpay-rounded-full xpay-bg-white xpay-shadow-sm xpay-flex xpay-items-center xpay-justify-center xpay-text-black ${className}`}
|
|
10
|
+
>
|
|
11
|
+
{tokenName.substring(0, 1)}
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
@tailwind components;
|
|
3
3
|
@tailwind utilities;
|
|
4
4
|
|
|
5
|
-
.
|
|
5
|
+
.xpay {
|
|
6
6
|
/* Works on Firefox */
|
|
7
7
|
* {
|
|
8
8
|
scrollbar-width: thin;
|
|
@@ -23,12 +23,14 @@
|
|
|
23
23
|
background-color: #252525;
|
|
24
24
|
border-radius: 4px;
|
|
25
25
|
}
|
|
26
|
+
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
@layer components {
|
|
29
|
+
.xpay-global-border {
|
|
28
30
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
29
31
|
}
|
|
30
|
-
}
|
|
31
32
|
|
|
32
|
-
.
|
|
33
|
-
|
|
33
|
+
.xpay-tx-status {
|
|
34
|
+
@apply xpay-fixed xpay-bottom-5 xpay-right-2 xpay-flex xpay-flex-col xpay-gap-3 xpay-pl-9 xpay-items-end xpay-w-full xpay-z-50;
|
|
35
|
+
}
|
|
34
36
|
}
|
package/src/config/init.tsx
CHANGED
|
@@ -3,9 +3,9 @@ import xswapConfig from "../../xswap.config";
|
|
|
3
3
|
import { version } from "../../package.json";
|
|
4
4
|
import { WaitingForInit } from "@src/components/WaitingForInit";
|
|
5
5
|
|
|
6
|
-
export let
|
|
7
|
-
export let
|
|
8
|
-
export let
|
|
6
|
+
export let xpayRoot: Root;
|
|
7
|
+
export let xpayInitIndicatorRoot: Root;
|
|
8
|
+
export let xpayTxStatusRoot: Root;
|
|
9
9
|
|
|
10
10
|
let initCompleted = false;
|
|
11
11
|
|
|
@@ -13,12 +13,12 @@ export const initDocument = () => {
|
|
|
13
13
|
if (typeof document === "undefined") {
|
|
14
14
|
throw new Error("Can't render XPay components from server side.");
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
createXPayInitIndicatorRoot();
|
|
17
17
|
|
|
18
18
|
Promise.all([
|
|
19
19
|
createStyleElement(),
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
createXPayRoot(),
|
|
21
|
+
createXPayTxStatusRoot(),
|
|
22
22
|
]).then(() => {
|
|
23
23
|
initCompleted = true;
|
|
24
24
|
});
|
|
@@ -46,30 +46,31 @@ const createStyleElement = async () => {
|
|
|
46
46
|
document.body.appendChild(style);
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
const
|
|
49
|
+
const createXPayRoot = async () => {
|
|
50
50
|
const xswapElement = document.createElement("div");
|
|
51
|
-
xswapElement.setAttribute("id", "
|
|
51
|
+
xswapElement.setAttribute("id", "xpay-root");
|
|
52
|
+
xswapElement.setAttribute("class", "xpay");
|
|
52
53
|
document.body.appendChild(xswapElement);
|
|
53
|
-
|
|
54
|
+
xpayRoot = createRoot(xswapElement);
|
|
54
55
|
};
|
|
55
56
|
|
|
56
|
-
const
|
|
57
|
+
const createXPayTxStatusRoot = async () => {
|
|
57
58
|
const txStatusElement = document.createElement("div");
|
|
58
|
-
txStatusElement.setAttribute("id", "
|
|
59
|
-
txStatusElement.setAttribute("class", "
|
|
59
|
+
txStatusElement.setAttribute("id", "xpay-tx-status");
|
|
60
|
+
txStatusElement.setAttribute("class", "xpay-tx-status");
|
|
60
61
|
document.body.appendChild(txStatusElement);
|
|
61
|
-
|
|
62
|
+
xpayTxStatusRoot = createRoot(txStatusElement);
|
|
62
63
|
};
|
|
63
64
|
|
|
64
|
-
const
|
|
65
|
+
const createXPayInitIndicatorRoot = () => {
|
|
65
66
|
const initIndicatorElement = document.createElement("div");
|
|
66
|
-
initIndicatorElement.setAttribute("id", "
|
|
67
|
+
initIndicatorElement.setAttribute("id", "xpay-init-indicator");
|
|
67
68
|
document.body.appendChild(initIndicatorElement);
|
|
68
|
-
|
|
69
|
+
xpayInitIndicatorRoot = createRoot(initIndicatorElement);
|
|
69
70
|
};
|
|
70
71
|
|
|
71
72
|
const displayInitIndicator = (display: boolean) => {
|
|
72
73
|
display
|
|
73
|
-
?
|
|
74
|
-
:
|
|
74
|
+
? xpayInitIndicatorRoot.render(<WaitingForInit />)
|
|
75
|
+
: xpayInitIndicatorRoot.render("");
|
|
75
76
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { initDocument } from "@src/config/init";
|
|
2
|
+
import { openTransactionModal, renderTxStatus } from "@src/services";
|
|
2
3
|
|
|
3
4
|
initDocument();
|
|
4
5
|
|
|
5
6
|
export * from "@src/models";
|
|
6
|
-
export {
|
|
7
|
+
export { openTransactionModal, renderTxStatus } from "@src/services";
|
|
8
|
+
|
|
9
|
+
const XPay = {
|
|
10
|
+
openTransactionModal,
|
|
11
|
+
renderTxStatus,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default XPay;
|
package/src/models/TokenData.ts
CHANGED
|
@@ -34,7 +34,11 @@ export type HistoryTransaction = {
|
|
|
34
34
|
} | null;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
export type TransactionStatus =
|
|
37
|
+
export type TransactionStatus =
|
|
38
|
+
| "IN_PROGRESS"
|
|
39
|
+
| "DONE"
|
|
40
|
+
| "REVERTED"
|
|
41
|
+
| "NOT_FOUND";
|
|
38
42
|
|
|
39
43
|
export type Transaction = {
|
|
40
44
|
hash: string;
|
|
@@ -50,13 +54,13 @@ export type Transaction = {
|
|
|
50
54
|
};
|
|
51
55
|
|
|
52
56
|
export type MonitoredTransaction = {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
srcChain: string | undefined;
|
|
58
|
+
srcChainImage: string | undefined;
|
|
59
|
+
srcToken: string | undefined;
|
|
60
|
+
srcTokenImage: string | undefined;
|
|
61
|
+
srcAmount: string | undefined;
|
|
62
|
+
dstChain: string | undefined;
|
|
63
|
+
dstChainImage: string | undefined;
|
|
60
64
|
isDone: boolean;
|
|
61
65
|
txHash: string;
|
|
62
66
|
explorer: string | undefined;
|
package/src/services/api.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
Token,
|
|
10
10
|
TokenPrices,
|
|
11
11
|
TransactionHistory,
|
|
12
|
+
TransactionStatus,
|
|
12
13
|
} from "@src/models";
|
|
13
14
|
|
|
14
15
|
async function _sendRequest<T>(
|
|
@@ -110,3 +111,11 @@ export async function getPrices(payload: GetPricesPayload) {
|
|
|
110
111
|
})}`,
|
|
111
112
|
);
|
|
112
113
|
}
|
|
114
|
+
|
|
115
|
+
export async function getTxStatus(payload: { transferId: string }) {
|
|
116
|
+
return await _sendRequest<{ status: TransactionStatus }>(
|
|
117
|
+
`/getTxStatus?${new URLSearchParams({
|
|
118
|
+
data: JSON.stringify(payload), // todo remove once gcp starts working
|
|
119
|
+
})}`,
|
|
120
|
+
);
|
|
121
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ERC20Abi } from "@src/contracts";
|
|
2
|
+
import { ethers } from "ethers";
|
|
3
|
+
import { Chain, Token } from "@src/models";
|
|
4
|
+
|
|
5
|
+
export const getCustomTokenData = async (
|
|
6
|
+
chain: Chain,
|
|
7
|
+
tokenAddress: string,
|
|
8
|
+
): Promise<Token> => {
|
|
9
|
+
const rpcUrl = chain.publicRpcUrls[0];
|
|
10
|
+
|
|
11
|
+
const customTokenContract = new ethers.Contract(
|
|
12
|
+
tokenAddress.toLowerCase(),
|
|
13
|
+
ERC20Abi,
|
|
14
|
+
ethers.getDefaultProvider(rpcUrl),
|
|
15
|
+
);
|
|
16
|
+
try {
|
|
17
|
+
const query = async (
|
|
18
|
+
contract: ethers.Contract | null,
|
|
19
|
+
method: string,
|
|
20
|
+
args: unknown[] = [],
|
|
21
|
+
) => {
|
|
22
|
+
if (contract?.provider) {
|
|
23
|
+
const response = await contract[method](...args);
|
|
24
|
+
return response;
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
28
|
+
const responses = await Promise.all([
|
|
29
|
+
query(customTokenContract, "decimals"),
|
|
30
|
+
query(customTokenContract, "name"),
|
|
31
|
+
query(customTokenContract, "symbol"),
|
|
32
|
+
]);
|
|
33
|
+
const [decimals, name, symbol] = responses;
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
address: tokenAddress,
|
|
37
|
+
symbol: symbol,
|
|
38
|
+
name: name,
|
|
39
|
+
decimals: decimals,
|
|
40
|
+
quickPick: false,
|
|
41
|
+
supported: true,
|
|
42
|
+
priority: 0,
|
|
43
|
+
};
|
|
44
|
+
} catch (_) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`Provided token ${tokenAddress} does not exists on chain ${chain.displayName}`,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
};
|
package/src/services/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Chain, MonitoredTransaction, Web3Environment } from "@src/models";
|
|
2
|
-
import { getChains } from "@src/services";
|
|
2
|
+
import { getChains, getTxStatus } from "@src/services";
|
|
3
3
|
import { ethers } from "ethers";
|
|
4
4
|
import { weiToHumanReadable } from "@src/utils";
|
|
5
5
|
import {
|
|
@@ -18,8 +18,9 @@ import {
|
|
|
18
18
|
} from "@src/components";
|
|
19
19
|
import { ADDRESSES } from "@src/contracts";
|
|
20
20
|
import retry from "async-retry";
|
|
21
|
+
import { getCustomTokenData } from "../blockchain";
|
|
21
22
|
|
|
22
|
-
export const
|
|
23
|
+
export const renderTxStatus = async (
|
|
23
24
|
txChainId: string,
|
|
24
25
|
txHash: string,
|
|
25
26
|
): Promise<void> => {
|
|
@@ -52,11 +53,20 @@ export const monitorTransactionStatus = async (
|
|
|
52
53
|
const srcChain = supportedChains.find(
|
|
53
54
|
(chain) => chain.chainId === txChainId.toString(),
|
|
54
55
|
);
|
|
56
|
+
if (!srcChain) {
|
|
57
|
+
throw new Error(`Unknown src chain ${txChainId}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const tokenAddress = decodedMessageSentEvent.args?.token.toString();
|
|
55
61
|
|
|
56
|
-
|
|
62
|
+
let srcToken = srcChain.tokens.find(
|
|
57
63
|
(token) => token.address === decodedMessageSentEvent.args?.token.toString(),
|
|
58
64
|
);
|
|
59
65
|
|
|
66
|
+
if (!srcToken) {
|
|
67
|
+
srcToken = await getCustomTokenData(srcChain, tokenAddress);
|
|
68
|
+
}
|
|
69
|
+
|
|
60
70
|
const dstChain = supportedChains.find(
|
|
61
71
|
(chain) =>
|
|
62
72
|
chain.ccipChainId ===
|
|
@@ -69,19 +79,21 @@ export const monitorTransactionStatus = async (
|
|
|
69
79
|
throw new Error(`Unknown destination chain!`);
|
|
70
80
|
}
|
|
71
81
|
|
|
82
|
+
const tokenAmount = weiToHumanReadable({
|
|
83
|
+
amount: decodedMessageSentEvent.args?.tokenAmount.toString(),
|
|
84
|
+
decimals: srcToken?.decimals || 18,
|
|
85
|
+
precisionFractionalPlaces: 4,
|
|
86
|
+
});
|
|
87
|
+
|
|
72
88
|
const transaction: MonitoredTransaction = {
|
|
73
89
|
txHash: txHash,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
amount: decodedMessageSentEvent.args?.tokenAmount.toString(),
|
|
82
|
-
decimals: srcToken?.decimals || 18,
|
|
83
|
-
precisionFractionalPlaces: 4,
|
|
84
|
-
}),
|
|
90
|
+
srcChain: srcChain.displayName,
|
|
91
|
+
srcChainImage: srcChain.image,
|
|
92
|
+
dstChain: dstChain.displayName,
|
|
93
|
+
dstChainImage: dstChain.image,
|
|
94
|
+
srcToken: srcToken?.symbol,
|
|
95
|
+
srcTokenImage: srcToken?.image,
|
|
96
|
+
srcAmount: tokenAmount === "0" ? "<0.0001" : tokenAmount,
|
|
85
97
|
isDone: false,
|
|
86
98
|
explorer: `${CCIP_EXPLORER}/tx/${txHash}`,
|
|
87
99
|
};
|
|
@@ -120,6 +132,14 @@ export const monitorTransactionStatus = async (
|
|
|
120
132
|
removeTransactionFromRenderedTransactions(txHash);
|
|
121
133
|
renderTxStatusButtons();
|
|
122
134
|
};
|
|
135
|
+
|
|
136
|
+
// check tx status on backend
|
|
137
|
+
getTxStatus({ transferId: messageId }).then((response) => {
|
|
138
|
+
if (response.status === "DONE") {
|
|
139
|
+
onSuccess();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
123
143
|
xSwapRouterOnDestination.once(msgReceivedEventFilter, () => onSuccess());
|
|
124
144
|
};
|
|
125
145
|
|
|
@@ -6,8 +6,10 @@ import {
|
|
|
6
6
|
} from "@src/models";
|
|
7
7
|
import { getChains } from "@src/services";
|
|
8
8
|
import { openTxConfigForm } from "@src/components";
|
|
9
|
+
import { isETHAddressValid } from "@src/utils";
|
|
9
10
|
|
|
10
|
-
export const
|
|
11
|
+
export const openTransactionModal = async ({
|
|
12
|
+
integratorId,
|
|
11
13
|
dstChain,
|
|
12
14
|
dstToken,
|
|
13
15
|
customContractCalls = [],
|
|
@@ -21,6 +23,7 @@ export const getSwapTx = async ({
|
|
|
21
23
|
validateSwapTxData(supportedChains, dstChain, dstToken);
|
|
22
24
|
|
|
23
25
|
const route = await openTxConfigForm({
|
|
26
|
+
integratorId: integratorId,
|
|
24
27
|
dstChainId: dstChain,
|
|
25
28
|
dstTokenAddr: dstToken,
|
|
26
29
|
customContractCalls,
|
|
@@ -43,7 +46,9 @@ const validateSwapTxData = (
|
|
|
43
46
|
throw new Error(`Provided chain '${dstChain}' is not supported`);
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
if (!
|
|
47
|
-
throw new Error(
|
|
49
|
+
if (!isETHAddressValid(dstToken)) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Provided token address ${dstToken} on chain ${dstChain} is not correct`,
|
|
52
|
+
);
|
|
48
53
|
}
|
|
49
54
|
};
|
package/src/utils/strings.ts
CHANGED