@xswap-link/sdk 0.1.0 → 0.1.2

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.
Files changed (42) hide show
  1. package/.github/workflows/main.yml +1 -0
  2. package/.github/workflows/publish.yml +1 -0
  3. package/CHANGELOG.md +24 -0
  4. package/dist/index.css +128 -32
  5. package/dist/index.d.mts +22 -19
  6. package/dist/index.d.ts +22 -19
  7. package/dist/index.js +1167 -32978
  8. package/dist/index.mjs +1152 -32988
  9. package/nodemon.json +5 -0
  10. package/package.json +17 -6
  11. package/src/components/TxConfigForm/BalanceComponent.tsx +51 -0
  12. package/src/components/TxConfigForm/ChainListElement.tsx +36 -0
  13. package/src/components/TxConfigForm/Description.tsx +15 -0
  14. package/src/components/TxConfigForm/ErrorField.tsx +17 -0
  15. package/src/components/TxConfigForm/FeesDetails.tsx +105 -0
  16. package/src/components/TxConfigForm/Form.tsx +129 -447
  17. package/src/components/TxConfigForm/History.tsx +67 -122
  18. package/src/components/TxConfigForm/HistoryCard.tsx +3 -2
  19. package/src/components/TxConfigForm/Settings.tsx +137 -0
  20. package/src/components/TxConfigForm/Summary.tsx +57 -0
  21. package/src/components/TxConfigForm/SwapPanel.tsx +191 -0
  22. package/src/components/TxConfigForm/TokenPicker.tsx +76 -67
  23. package/src/components/TxConfigForm/TopBar.tsx +53 -0
  24. package/src/components/TxConfigForm/index.tsx +121 -0
  25. package/src/components/icons/ArrowDownIcon.tsx +16 -0
  26. package/src/components/icons/ChainlinkCCIPIcon.tsx +23 -0
  27. package/src/components/icons/ChevronDownIcon.tsx +2 -2
  28. package/src/components/icons/ChevronUpIcon.tsx +2 -2
  29. package/src/components/icons/CloseIcon.tsx +2 -2
  30. package/src/components/icons/CoinsIcon.tsx +8 -6
  31. package/src/components/icons/HistoryIcon.tsx +8 -5
  32. package/src/components/icons/InfoIcon.tsx +13 -0
  33. package/src/components/icons/SettingsIcon.tsx +16 -0
  34. package/src/components/icons/TimerIcon.tsx +15 -0
  35. package/src/components/icons/XSwapBadgeIcon.tsx +23 -0
  36. package/src/components/icons/index.ts +6 -0
  37. package/src/config/index.ts +1 -0
  38. package/src/config/wagmiConfig.ts +45 -0
  39. package/src/constants/index.ts +6 -3
  40. package/tailwind.config.js +11 -2
  41. package/src/components/TxConfigForm/index.jsx +0 -100
  42. package/src/components/global.d.ts +0 -6
package/nodemon.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "watch": ["src"],
3
+ "ext": "ts,tsx,css,js",
4
+ "exec": "npm run build"
5
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xswap-link/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "JavaScript SDK for XSwap platform",
5
5
  "homepage": "https://github.com/xswap-link/xswap-sdk",
6
6
  "repository": {
@@ -20,32 +20,43 @@
20
20
  "types": "dist/index.d.ts",
21
21
  "dependencies": {
22
22
  "@ethersproject/providers": "^5.7.2",
23
+ "@tanstack/react-query": "^5.35.5",
24
+ "@types/react": "18.2.0",
25
+ "@types/react-dom": "18.2.0",
23
26
  "bignumber.js": "4.0.4",
24
27
  "date-fns": "^3.6.0",
25
- "ethers": "^5.7.2"
28
+ "ethers": "^5.7.2",
29
+ "react": "18.2.0",
30
+ "react-dom": "18.2.0",
31
+ "viem": "2.x",
32
+ "wagmi": "^2.8.5"
26
33
  },
27
34
  "devDependencies": {
28
35
  "@changesets/cli": "^2.27.1",
29
36
  "@types/jest": "^29.5.12",
30
37
  "@types/node": "^20.11.17",
31
- "@types/react": "^18.2.79",
32
- "@types/react-dom": "^18.2.25",
33
38
  "@typescript-eslint/eslint-plugin": "^7.1.0",
34
39
  "@typescript-eslint/parser": "^7.1.0",
35
40
  "eslint": "^8.57.0",
36
41
  "jest": "^29.7.0",
37
42
  "jest-fetch": "^1.1.1",
38
43
  "jest-fetch-mock": "^3.0.3",
39
- "react": "^18.2.0",
40
- "react-dom": "^18.2.0",
44
+ "nodemon": "^3.1.0",
41
45
  "tailwindcss": "^3.4.3",
42
46
  "ts-jest": "^29.1.2",
43
47
  "ts-node": "^10.9.2",
44
48
  "tsup": "^8.0.2",
45
49
  "typescript": "^5.3.3"
46
50
  },
51
+ "peerDependencies": {
52
+ "@types/react": ">=16 || <=18",
53
+ "@types/react-dom": ">=16 || <=18",
54
+ "react": ">=16 || <=18",
55
+ "react-dom": ">=16 || <=18"
56
+ },
47
57
  "scripts": {
48
58
  "build": "tsup src/index.ts --format cjs,esm --dts",
59
+ "watch": "nodemon",
49
60
  "release": "pnpm run build && changeset publish",
50
61
  "lint": "tsc && eslint . --ext .ts",
51
62
  "test": "jest"
@@ -0,0 +1,51 @@
1
+ import { FC, useMemo } from "react";
2
+ import { Token, TokenBalances } from "@src/models";
3
+ import { weiToHumanReadable } from "@src/utils";
4
+ import BigNumber from "bignumber.js";
5
+ import { MINIMUM_DISPLAYED_TOKEN_AMOUNT } from "@src/constants";
6
+
7
+ interface Props {
8
+ srcToken: Token | undefined;
9
+ balances: TokenBalances | undefined;
10
+ }
11
+
12
+ export const BalanceComponent: FC<Props> = ({ srcToken, balances }) => {
13
+ const balanceText = useMemo(() => {
14
+ if (!balances || !srcToken) return "0";
15
+ if (balances[srcToken.address]?.toString() === "0") return "0";
16
+ const fullHumanReadable = weiToHumanReadable({
17
+ amount: balances[srcToken.address]?.toString() || "0",
18
+ decimals: srcToken.decimals,
19
+ precisionFractionalPlaces: srcToken.decimals,
20
+ });
21
+
22
+ if (
23
+ new BigNumber(fullHumanReadable).lt(
24
+ MINIMUM_DISPLAYED_TOKEN_AMOUNT.toString(),
25
+ )
26
+ )
27
+ return `<${MINIMUM_DISPLAYED_TOKEN_AMOUNT}`;
28
+
29
+ return weiToHumanReadable({
30
+ amount: balances[srcToken.address]?.toString() || "0",
31
+ decimals: srcToken.decimals,
32
+ precisionFractionalPlaces: 5,
33
+ });
34
+ }, [srcToken, balances]);
35
+
36
+ return (
37
+ <>
38
+ Balance:{" "}
39
+ {srcToken && balances
40
+ ? weiToHumanReadable({
41
+ amount: balances[srcToken.address]?.toString() || "0",
42
+ decimals: srcToken.decimals,
43
+ precisionFractionalPlaces: 4,
44
+ })
45
+ : 0}
46
+ <span className="bg-gradient-to-r from-x_blue_light to-x_blue_dark bg-clip-text text-transparent">
47
+ Max
48
+ </span>
49
+ </>
50
+ );
51
+ };
@@ -0,0 +1,36 @@
1
+ import { FC } from "react";
2
+ import { Chain } from "@src/models";
3
+
4
+ interface Props {
5
+ chain: Chain;
6
+ index: number;
7
+ length: number;
8
+ setSrcChain: (chain: Chain) => void;
9
+ setChainListShown: (x: boolean) => void;
10
+ }
11
+
12
+ export const ChainListElement: FC<Props> = ({
13
+ chain,
14
+ setSrcChain,
15
+ setChainListShown,
16
+ index,
17
+ length,
18
+ }) => {
19
+ return (
20
+ <div key={`${chain.ecosystem}-${chain.chainId}`}>
21
+ <li
22
+ className="bg-transparent border-none flex gap-1 items-center cursor-pointer py-2 w-full"
23
+ onClick={() => {
24
+ setSrcChain(chain);
25
+ setChainListShown(false);
26
+ }}
27
+ >
28
+ <img width={12} height={12} src={chain.image} alt={chain.displayName} />
29
+ {chain.displayName}
30
+ </li>
31
+ {index !== length - 1 && (
32
+ <div className="h-px mx-2 bg-[rgba(255,255,255,0.15)]"></div>
33
+ )}
34
+ </div>
35
+ );
36
+ };
@@ -0,0 +1,15 @@
1
+ import React, { FC } from "react";
2
+
3
+ interface Props {
4
+ description: string;
5
+ }
6
+
7
+ export const Description: FC<Props> = ({ description }) => {
8
+ return (
9
+ <div className="flex flex-col items-start rounded-lg px-4 py-2">
10
+ <div className="w-full flex gap-4 items-start justify-between text-xl">
11
+ {description}
12
+ </div>
13
+ </div>
14
+ );
15
+ };
@@ -0,0 +1,17 @@
1
+ import React, { FC } from "react";
2
+
3
+ interface Props {
4
+ error: string;
5
+ }
6
+
7
+ export const ErrorField: FC<Props> = ({ error }) => {
8
+ return (
9
+ <div
10
+ className={`flex justify-center mb-1 items-center w-full rounded-2xl bg-x_error_background border border-solid ${
11
+ error.length > 0 ? "border-x_error_border" : "border-transparent"
12
+ }`}
13
+ >
14
+ {error}
15
+ </div>
16
+ );
17
+ };
@@ -0,0 +1,105 @@
1
+ import { FC } from "react";
2
+ import { CoinsIcon, TimerIcon, ChevronUpIcon, ChevronDownIcon } from "../icons";
3
+ import { safeBigNumberFrom, weiToHumanReadable } from "@src/utils";
4
+ import { Route, Token } from "@src/models";
5
+
6
+ interface Props {
7
+ route: Route | undefined;
8
+ isGettingRoute: boolean;
9
+ paymentToken: Token | undefined;
10
+ dstToken: Token | undefined;
11
+ expressChecked: boolean;
12
+ slippage: string | undefined;
13
+ feesDetailsShown: boolean;
14
+ setFeesDetailsShown: React.Dispatch<React.SetStateAction<boolean>>;
15
+ }
16
+
17
+ export const FeesDetails: FC<Props> = ({
18
+ isGettingRoute,
19
+ route,
20
+ paymentToken,
21
+ dstToken,
22
+ expressChecked,
23
+ slippage,
24
+ feesDetailsShown,
25
+ setFeesDetailsShown,
26
+ }) => {
27
+ return (
28
+ <div className="flex flex-col gap-3 globalBorder rounded-lg bg-[rgba(15,15,15,1)] p-4 mb-1">
29
+ <div className="flex w-full items-center justify-between">
30
+ <div className="flex items-center gap-1 text-sm font-medium text-white opacity-60">
31
+ <CoinsIcon />
32
+ <div className="mr-1">Fees:</div>
33
+ {isGettingRoute ? (
34
+ <div className="bg-current rounded animate-pulse w-20 h-4" />
35
+ ) : (
36
+ ` ${weiToHumanReadable({
37
+ amount: safeBigNumberFrom(
38
+ route?.xSwapFees.xSwapFee.nativeFee || "0",
39
+ )
40
+ .add(safeBigNumberFrom(route?.xSwapFees.ccipFee || "0"))
41
+ .add(
42
+ safeBigNumberFrom(route?.xSwapFees.expressDeliveryFee || "0"),
43
+ )
44
+ .toString(),
45
+ decimals: 18,
46
+ precisionFractionalPlaces: 5,
47
+ })} ${paymentToken?.symbol}`
48
+ )}
49
+ </div>
50
+ <div className="flex gap-1">
51
+ <div
52
+ className={`flex gap-1 text-xs font-medium ${
53
+ expressChecked ? "text-x_green" : "text-white opacity-60"
54
+ }`}
55
+ >
56
+ <TimerIcon />
57
+ {expressChecked ? "Fast ~ 30sec " : "Normal ~ 30min"}
58
+ </div>
59
+ <div
60
+ onClick={() => setFeesDetailsShown((x) => !x)}
61
+ className="text-xs font-medium text-white opacity-60 cursor-pointer flex items-center"
62
+ >
63
+ {feesDetailsShown ? <ChevronUpIcon /> : <ChevronDownIcon />}
64
+ </div>
65
+ </div>
66
+ </div>
67
+ {feesDetailsShown && (
68
+ <div className="flex w-full items-center justify-between ">
69
+ <div className="flex flex-col text-[10px] gap-1">
70
+ <div className="font-medium text-white opacity-60">
71
+ CCIP Fee:
72
+ {` ${weiToHumanReadable({
73
+ amount: route?.xSwapFees.ccipFee || "0",
74
+ decimals: 18,
75
+ precisionFractionalPlaces: 5,
76
+ })} ${paymentToken?.symbol}`}
77
+ </div>
78
+ <div className="font-medium text-white opacity-60">
79
+ Native Fee:
80
+ {` ${weiToHumanReadable({
81
+ amount: route?.xSwapFees.xSwapFee.nativeFee || "0",
82
+ decimals: 18,
83
+ precisionFractionalPlaces: 5,
84
+ })} ${paymentToken?.symbol}`}
85
+ </div>
86
+ </div>
87
+ <div className="flex flex-col text-[10px] gap-1">
88
+ <div className="font-medium text-white opacity-60">
89
+ Slippage: {`${slippage}%`}
90
+ </div>
91
+ <div className="font-medium text-white opacity-60">
92
+ Min amount out:{" "}
93
+ {weiToHumanReadable({
94
+ amount: route?.minAmountOut || "0",
95
+ decimals: dstToken?.decimals || 18,
96
+ precisionFractionalPlaces: 5,
97
+ })}{" "}
98
+ {dstToken?.symbol}
99
+ </div>
100
+ </div>
101
+ </div>
102
+ )}
103
+ </div>
104
+ );
105
+ };