├── .eslintrc.json
├── .gitignore
├── README.md
├── components
├── common
│ ├── Loading.tsx
│ └── Notify.tsx
├── layout
│ ├── Header.tsx
│ └── index.tsx
└── raydium
│ ├── SwapOperateContainer.tsx
│ ├── TokenList.tsx
│ ├── TokenSelect.tsx
│ └── index.tsx
├── hooks
└── useDapp.ts
├── next-env.d.ts
├── next.config.js
├── package-lock.json
├── package.json
├── pages
├── _app.tsx
├── exchange.tsx
├── index.tsx
└── my_spl.tsx
├── public
├── bg.jpeg
└── image
│ └── dappio-logo.png
├── styles
├── color.module.sass
├── common.module.sass
├── globals.css
├── header.module.sass
├── layout.module.sass
├── mySpl.module.sass
└── swap.module.sass
├── tsconfig.json
├── types.d.ts
└── utils
├── ids.ts
├── layouts.ts
├── liquidity.ts
├── pools.ts
├── safe-math.ts
├── swap.ts
├── tokenList.ts
├── tokens.ts
├── types.d.ts
└── web3.ts
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
36 | # typescript
37 | *.tsbuildinfo
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Getting started
3 |
4 | This boilerplate aim to help solana devloper to start building a frontend dapp quickly.
5 |
6 | The project is bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with Solana web3 wallet.
7 |
8 | ## prerequisites
9 |
10 | Below are some key dependencies of this project
11 | 1. Chakra UI framewark
12 | 2. Solana wallet adaptor (Including adaptor-ui) to make use of sollana wallet
13 | 3. Solana web3 to interact with solana chain programs
14 |
15 | Simply implement all neccessory packages by npm install
16 | ```
17 | npm install
18 | ```
19 |
20 | ## Runing demo dapp
21 |
22 | You can run test server on localhost:3000 with the boilerplate basic template by runing " npm run dev"
23 | ```
24 | npm run dev
25 | ```
26 |
27 | ## Build UI component on top of boilerplate
28 |
29 | You can make your own react component by
30 | 1. Adding/Editing layout components into ./components/Layout/ such as Header, footer, sider ..etc
31 |
32 | 2. Changing the style of common components by editing Loading.tsx or Notify.tsx under ./components/Common/
33 |
34 |
35 | ## Default Context provider
36 |
37 | This boilerplate by default contains two built in context providers in ./pages/_app.tsx:
38 | 1. WalletProvier is to take advantage of solana wallet adaptor
39 | 2. ChakraProvider is to equip the project with [Chakra UI components](https://chakra-ui.com/docs/getting-started)
40 |
41 |
42 | # TODO
43 |
44 | 1. Build in Anchor framework
45 | 2. Dynamic adjusting exchange pool data
46 |
--------------------------------------------------------------------------------
/components/common/Loading.tsx:
--------------------------------------------------------------------------------
1 | import { Spinner } from "@chakra-ui/react"
2 | import style from "../../styles/common.module.sass";
3 |
4 | function Loading(props: LoadingProps): JSX.Element {
5 | const {size, msg, thickness, speed, emptyColor, color} = props.data
6 | return <>
7 |
17 |
18 | >
19 | }
20 | export default Loading
--------------------------------------------------------------------------------
/components/common/Notify.tsx:
--------------------------------------------------------------------------------
1 | import { FunctionComponent } from "react";
2 | import {
3 | Alert,
4 | AlertIcon,
5 | AlertTitle,
6 | AlertDescription
7 | } from "@chakra-ui/react";
8 | import style from "../../styles/common.module.sass";
9 |
10 | const Notify: FunctionComponent = props => {
11 | return (
12 |
13 |
14 |
15 |
{props.message.title}
16 |
17 |
18 | {props.message.description}
19 |
20 | {props.message.link ? (
21 |
25 | Check Explorer
26 |
27 | ) : (
28 | ""
29 | )}
30 |
31 | );
32 | };
33 |
34 | export default Notify;
35 |
--------------------------------------------------------------------------------
/components/layout/Header.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | WalletModalProvider,
3 | WalletDisconnectButton,
4 | WalletMultiButton
5 | } from "@solana/wallet-adapter-react-ui";
6 | import { useWallet} from "@solana/wallet-adapter-react";
7 | import Link from "next/link";
8 | import style from "../../styles/header.module.sass"
9 | import Image from "next/image";
10 |
11 |
12 | export default function Header() {
13 | const wallet = useWallet()
14 |
15 | return <>
16 |
17 |
18 | My SPL Tokens
19 | Home
20 | Exchange
21 |
22 | {wallet.connected ? : }
23 |
24 |
25 | >
26 | }
--------------------------------------------------------------------------------
/components/layout/index.tsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import Header from "./Header"
3 | import { useWallet } from "@solana/wallet-adapter-react"
4 | import { Connection } from "@solana/web3.js"
5 | import { getSPLTokenData } from "../../utils/web3"
6 | import { useEffect, useState } from "react"
7 | import { DappContext } from "../../hooks/useDapp"
8 | // import { Liquidity, LiquidityPoolKeysV4 } from '@raydium-io/raydium-sdk'
9 | import Loading from '../common/Loading'
10 | import Notify from '../common/Notify'
11 | import style from '../../styles/layout.module.sass'
12 |
13 | function Layout({...props}): JSX.Element {
14 |
15 | const connection = new Connection("https://rpc-mainnet-fork.dappio.xyz", {
16 | wsEndpoint: "wss://rpc-mainnet-fork.dappio.xyz/ws",
17 | commitment: "processed"
18 | });
19 | // --> // 3rd party Hooks
20 | const wallet = useWallet();
21 |
22 | // --> // React Hooks
23 | const [splTokenData, setSplTokenData] = useState([]);
24 | // const [poolKeys, setPoolKeys] = useState([])
25 | const [notify, setNotify] = useState(null);
26 | const [loading, setLoading] = useState(null);
27 |
28 | useEffect(()=>{ // Show notify component for 5s if there is any
29 | if (notify) {
30 | setTimeout(()=>setNotify(null), 5000)
31 | }
32 | }, [notify])
33 |
34 | // useEffect(()=>{
35 | // Liquidity.fetchAllPoolKeys(connection).then((pools: LiquidityPoolKeysV4[])=>{
36 | // setPoolKeys(pools)
37 | // })
38 | // }, [wallet.connected])
39 |
40 | useEffect(() => {
41 | if (wallet.connected) {
42 | setLoading({
43 | msg: "Loading spl tokens"
44 | })
45 | getSPLTokenData(wallet, connection).then((tokenList: ISplToken[]) => {
46 | if (tokenList) {
47 | setSplTokenData(() => tokenList.filter(t => t !== undefined));
48 | }
49 | setLoading(null)
50 | });
51 | } else {
52 | setSplTokenData([])
53 | }
54 | }, [wallet.connected]);
55 |
56 | return <>
57 |
58 |
59 | {/* fontawesome */}
60 |
61 | Solana DAPP Boilerplate
62 |
63 |
64 |
65 |
66 | {notify && }
67 | {loading && }
68 |
77 | {props.children}
78 |
79 |
80 | >
81 | }
82 |
83 |
84 | export default Layout
85 |
--------------------------------------------------------------------------------
/components/raydium/SwapOperateContainer.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 | import { ArrowUpDownIcon, QuestionOutlineIcon } from "@chakra-ui/icons";
3 | import { Tooltip } from "@chakra-ui/react";
4 | import { useWallet } from "@solana/wallet-adapter-react";
5 | import {
6 | WalletModalProvider,
7 | WalletMultiButton
8 | } from "@solana/wallet-adapter-react-ui";
9 | import TokenSelect from "./TokenSelect";
10 | import style from "../../styles/swap.module.sass";
11 |
12 | const SwapOperateContainer: FC = props => {
13 | let wallet = useWallet();
14 | const SwapBtn = (swapProps: any) => {
15 | if (wallet.connected) {
16 | if (
17 | !swapProps.props.fromData.tokenInfo?.symbol ||
18 | !swapProps.props.toData.tokenInfo?.symbol
19 | ) {
20 | return (
21 |
27 | );
28 | }
29 | if (
30 | swapProps.props.fromData.tokenInfo?.symbol &&
31 | swapProps.props.toData.tokenInfo?.symbol
32 | ) {
33 | if (
34 | !swapProps.props.fromData.amount ||
35 | !swapProps.props.toData.amount
36 | ) {
37 | return (
38 |
44 | );
45 | }
46 | }
47 |
48 | return (
49 |
55 | );
56 | } else {
57 | return (
58 |
59 |
60 |
61 |
62 |
63 | );
64 | }
65 | };
66 |
67 | const SwapDetailPreview: FC = props => {
68 | return (
69 |
70 |
71 |
{props.title}
72 |
79 |
84 |
85 |
86 |
{props.value}
87 |
88 | );
89 | };
90 |
91 | const SwapDetailPreviewList = (): JSX.Element => {
92 | return (
93 | <>
94 | ${props.toData.tokenInfo.symbol}`}
98 | />
99 | >
100 | );
101 | };
102 |
103 | return (
104 |
105 |
106 |
114 |
120 |
128 |
129 |
130 |
Slippage Tolerance
131 |
138 |
143 |
144 |
145 |
{props.slippageValue}%
146 |
147 | {props.fromData.amount! > 0 &&
148 | props.fromData.tokenInfo.symbol &&
149 | props.toData.amount! > 0 &&
150 | props.toData.tokenInfo.symbol ? (
151 |
152 | ) : (
153 | ""
154 | )}
155 |
156 |
157 |
158 | );
159 | };
160 |
161 | export default SwapOperateContainer;
162 |
--------------------------------------------------------------------------------
/components/raydium/TokenList.tsx:
--------------------------------------------------------------------------------
1 | import { FunctionComponent, useEffect, useRef, useState } from "react";
2 | import { CloseIcon } from "@chakra-ui/icons";
3 | import SPLTokenRegistrySource from "../../utils/tokenList";
4 | import { TOKENS } from "../../utils/tokens";
5 | import style from "../../styles/swap.module.sass";
6 |
7 | const TokenList: FunctionComponent = props => {
8 |
9 | const [initialList, setList] = useState([]);
10 | const [searchedList, setSearchList] = useState([]);
11 | const searchRef = useRef();
12 |
13 | useEffect(() => { // Fetch all tokens data
14 | SPLTokenRegistrySource().then((res) => {
15 | let list: ITokenInfo[] = [];
16 | res.forEach((item: any) => {
17 | let token = {} as ITokenInfo;
18 | if (
19 | TOKENS[item.symbol] &&
20 | !list.find(
21 | (t: ITokenInfo) => t.mintAddress === TOKENS[item.symbol].mintAddress
22 | )
23 | ) {
24 | token = TOKENS[item.symbol];
25 | token["logoURI"] = item.logoURI;
26 | list.push(token);
27 | }
28 | });
29 | setList(() => list); // Put tokens into list
30 |
31 | props.getTokenInfo( // Select SOL as default
32 | list.find((item: ITokenInfo) => item.symbol === "SOL")
33 | )
34 | })
35 | }, []);
36 |
37 | useEffect(() => {
38 | setSearchList(() => initialList);
39 | }, [initialList]);
40 |
41 | const setTokenInfo = (item: ITokenInfo) => {
42 | props.getTokenInfo(item);
43 | props.toggleTokenList("From");
44 | };
45 |
46 | const listItems = (data: ITokenInfo[]) => {
47 | return data.map((item: ITokenInfo) => {
48 | return (
49 | setTokenInfo(item)}
53 | >
54 |

55 |
{item.symbol}
56 |
57 | );
58 | });
59 | };
60 |
61 | const searchToken = (e: any) => {
62 | let key = e.target.value.toUpperCase();
63 | let newList: ITokenInfo[] = [];
64 | initialList.map((item: ITokenInfo) => {
65 | if (item.symbol.includes(key)) {
66 | newList.push(item);
67 | }
68 | });
69 | setSearchList(newList);
70 | };
71 |
72 | let tokeListComponentStyle;
73 | if (!props.showTokenList) {
74 | tokeListComponentStyle = {
75 | display: "none"
76 | };
77 | } else {
78 | tokeListComponentStyle = {
79 | display: "block"
80 | };
81 | }
82 |
83 | return (
84 |
85 |
86 |
87 |
Select a token
88 |
props.toggleTokenList(undefined)}>
89 |
90 |
91 |
92 |
104 |
{listItems(searchedList)}
105 |
View Token List
106 |
107 |
108 | );
109 | };
110 |
111 | export default TokenList;
112 |
--------------------------------------------------------------------------------
/components/raydium/TokenSelect.tsx:
--------------------------------------------------------------------------------
1 | import { FunctionComponent, useEffect, useState } from "react";
2 | import { ArrowDownIcon } from "@chakra-ui/icons";
3 | import { useWallet } from "@solana/wallet-adapter-react";
4 | import style from "../../styles/swap.module.sass";
5 |
6 | const TokenSelect: FunctionComponent = props => {
7 | let wallet = useWallet();
8 | const [tokenBalance, setTokenBalance] = useState(null);
9 |
10 | const updateAmount = (e: any) => {
11 | e.preventDefault();
12 |
13 | const amountData: IUpdateAmountData = {
14 | amount: e.target.value,
15 | type: props.type
16 | };
17 | props.updateAmount(amountData);
18 | };
19 |
20 | const selectToken = () => {
21 | props.toggleTokenList(props.type);
22 | };
23 |
24 | useEffect(() => {
25 | const updateSelectedTokenBalance = () => {
26 | console.log(props.tokenData.tokenInfo?.mintAddress)
27 | let data: ISplToken | undefined = props.splTokenData.find(
28 | (t: ISplToken) =>
29 | t.parsedInfo.mint === props.tokenData.tokenInfo?.mintAddress
30 | );
31 | console.log(props.splTokenData)
32 | if (data) {
33 | setTokenBalance(data.amount);
34 | } else {
35 | setTokenBalance(0);
36 | }
37 | };
38 | updateSelectedTokenBalance();
39 | }, [props.tokenData, props.splTokenData]);
40 |
41 | const DropDownTokenListBtn: FunctionComponent = selectTokenProps => {
42 | if (selectTokenProps.tokenData.tokenInfo?.symbol) {
43 | return (
44 | <>
45 |
50 |
51 |
52 | {selectTokenProps.tokenData.tokenInfo?.symbol}
53 |
54 |
55 |
56 | >
57 | );
58 | }
59 | return (
60 | <>
61 | Select a token
62 |
63 | >
64 | );
65 | };
66 |
67 | return (
68 |
69 |
70 |
71 | {props.type === "To" ? `${props.type} (Estimate)` : props.type}
72 |
73 |
74 | {wallet.connected && tokenBalance
75 | ? `Balance: ${tokenBalance.toFixed(4)}`
76 | : ""}
77 |
78 |
79 |
80 | {props.type !== "From" ? (
81 |
82 | {props.tokenData.amount ? props.tokenData.amount : "-"}
83 |
84 | ) : (
85 |
92 | )}
93 |
94 |
95 |
96 |
97 |
98 |
99 | );
100 | };
101 |
102 | export default TokenSelect;
103 |
--------------------------------------------------------------------------------
/components/raydium/index.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect, FunctionComponent } from "react";
2 | import { useWallet } from "@solana/wallet-adapter-react";
3 | import { getPoolByTokenMintAddresses } from "../../utils/pools";
4 | import { swap, getSwapOutAmount, setupPools } from "../../utils/swap";
5 | import { getSPLTokenData } from "../../utils/web3";
6 | import useDapp from "../../hooks/useDapp";
7 | import TokenList from "./TokenList";
8 | import SwapOperateContainer from "./SwapOperateContainer";
9 |
10 | const SwapPage: FunctionComponent = () => {
11 | // React Hooks
12 | const [showTokenList, setShowTokenList] = useState(false);
13 | const [showSlippageSetting, setShowSlippageSetting] = useState(false);
14 | const [selectType, setSelectType] = useState<"From" | "To" | undefined>("From");
15 | const [fromData, setFromData] = useState({} as TokenData);
16 | const [toData, setToData] = useState({} as TokenData);
17 | const [slippageValue, setSlippageValue] = useState(1);
18 | const [splTokenData, setSplTokenData] = useState([]);
19 | const [liquidityPools, setLiquidityPools] = useState("");
20 | // Other Hooks
21 | let wallet = useWallet();
22 | let { connection, splTokens, setNotify, setLoading } = useDapp()
23 |
24 | useEffect(()=>{
25 | splTokens && setSplTokenData(splTokens)
26 | }, [splTokens])
27 |
28 | useEffect(() => { // Setup Liquidity Pools
29 | setLoading!({
30 | msg: "Loading Liquidity Pools"
31 | });
32 | setupPools(connection).then(data => {
33 | setLiquidityPools(data);
34 | setLoading!(null)
35 | });
36 | return () => {
37 | setLiquidityPools("");
38 | };
39 | }, []);
40 |
41 | const updateAmount = (e: IUpdateAmountData) => {
42 | if (e.type === "From") {
43 | setFromData((old: TokenData) => ({
44 | ...old,
45 | amount: e.amount
46 | }));
47 |
48 | if (!e.amount) {
49 | setToData((old: TokenData) => ({
50 | ...old,
51 | amount: 0
52 | }));
53 | }
54 | }
55 | };
56 |
57 | const updateSwapOutAmount = () => {
58 | if (
59 | fromData.amount! > 0 &&
60 | fromData.tokenInfo?.symbol &&
61 | toData.tokenInfo?.symbol
62 | ) {
63 | // Get LP info
64 | let poolInfo = getPoolByTokenMintAddresses(
65 | fromData.tokenInfo.mintAddress,
66 | toData.tokenInfo.mintAddress
67 | );
68 |
69 | if (!poolInfo) { // If get no LP then trigger notification
70 | setNotify!(() => ({ /** @TODO Manual update pool?? how to get the Liquidity pool in util auto update? */
71 | status: "error",
72 | title: "AMM error",
73 | description: "Current token pair pool not found"
74 | }));
75 | return;
76 | }
77 |
78 | let parsedPoolsData = liquidityPools;
79 | let parsedPoolInfo = parsedPoolsData[poolInfo?.lp.mintAddress];
80 |
81 | // //@ts-ignore
82 | const { amountOutWithSlippage } = getSwapOutAmount(
83 | parsedPoolInfo,
84 | fromData.tokenInfo.mintAddress,
85 | toData.tokenInfo.mintAddress,
86 | fromData.amount!.toString(),
87 | slippageValue
88 | );
89 |
90 | setToData((old: TokenData) => ({
91 | ...old,
92 | amount: parseFloat(amountOutWithSlippage.fixed())
93 | }));
94 | }
95 | };
96 |
97 | useEffect(() => { // Update SwapOut Amount when there is change of src or dist coins or slippage
98 | updateSwapOutAmount();
99 | }, [fromData, toData.tokenInfo?.symbol, slippageValue]);
100 |
101 | const toggleTokenList = (type: "From"|"To" | undefined) => { /**@Param e: selected type */
102 | setShowTokenList(() => !showTokenList);
103 | setSelectType(type)
104 | };
105 |
106 | const toggleSlippageSetting = () => { // pop-up slippage selection
107 | setShowSlippageSetting(() => !showSlippageSetting);
108 | };
109 |
110 | const getSlippageValue = (e: number) => {
111 | if (!e) {
112 | setSlippageValue(() => e);
113 | } else {
114 | setSlippageValue(() => e);
115 | }
116 | };
117 |
118 | const switchFromAndTo = () => {
119 | const fromToken = fromData.tokenInfo;
120 | const toToken = toData.tokenInfo;
121 | setFromData((old: TokenData) => ({
122 | ...old,
123 | tokenInfo: toToken,
124 | amount: null
125 | }));
126 |
127 | setToData((old: TokenData) => ({
128 | ...old,
129 | tokenInfo: fromToken,
130 | amount: null
131 | }));
132 | };
133 |
134 | const getTokenInfo = (e: ITokenInfo) => { // Set src and dist coin when user select
135 | if (selectType === "From") { // When user selects src token which is the same as current dist coin
136 | if (toData.tokenInfo?.symbol === e?.symbol) {
137 | setToData((old: TokenData) => ({
138 | ...old,
139 | tokenInfo: {
140 | symbol: "",
141 | mintAddress: "",
142 | logoURI: ""
143 | }
144 | }));
145 | }
146 |
147 | setFromData((old: TokenData) => ({
148 | ...old,
149 | tokenInfo: e
150 | }));
151 | } else { // Else when user selects dist token which is the same as current src coin
152 | if (fromData.tokenInfo?.symbol === e.symbol) {
153 | setFromData((old: TokenData) => ({
154 | ...old,
155 | tokenInfo: {
156 | symbol: "",
157 | mintAddress: "",
158 | logoURI: ""
159 | }
160 | }));
161 | }
162 |
163 | setToData((old: TokenData) => ({
164 | ...old,
165 | tokenInfo: e
166 | }));
167 | }
168 | };
169 |
170 | const sendSwapTransaction = async () => {
171 | let poolInfo = getPoolByTokenMintAddresses(
172 | fromData.tokenInfo.mintAddress,
173 | toData.tokenInfo.mintAddress
174 | );
175 |
176 | let fromTokenAccount: ISplToken | undefined | string = splTokenData.find(
177 | (token: ISplToken) =>
178 | token.parsedInfo.mint === fromData.tokenInfo.mintAddress
179 | );
180 | if (fromTokenAccount) {
181 | fromTokenAccount = fromTokenAccount.pubkey;
182 | } else {
183 | fromTokenAccount = "";
184 | }
185 |
186 | let toTokenAccount: ISplToken | undefined | string = splTokenData.find(
187 | (token: ISplToken) =>
188 | token.parsedInfo.mint === toData.tokenInfo.mintAddress
189 | );
190 | if (toTokenAccount) {
191 | toTokenAccount = toTokenAccount.pubkey;
192 | } else {
193 | toTokenAccount = "";
194 | }
195 |
196 | let wsol: ISplToken | undefined = splTokenData.find(
197 | (token: ISplToken) =>
198 | token.parsedInfo.mint === "So11111111111111111111111111111111111111112"
199 | );
200 | let wsolMint: string = "";
201 | if (wsol) {
202 | wsolMint = wsol.parsedInfo.mint;
203 | }
204 |
205 | if (poolInfo === undefined) {
206 | alert("Pool not exist");
207 | return;
208 | }
209 |
210 | swap(
211 | connection,
212 | wallet,
213 | poolInfo,
214 | fromData.tokenInfo.mintAddress,
215 | toData.tokenInfo.mintAddress,
216 | fromTokenAccount,
217 | toTokenAccount,
218 | fromData.amount!.toString(),
219 | toData.amount!.toString(),
220 | wsolMint
221 | ).then(async res => {
222 | setNotify!(() => ({
223 | status: "error",
224 | title: "AMM error",
225 | description: "Current token pair pool not found"
226 | }));
227 |
228 | let result = await connection.confirmTransaction(res);
229 |
230 | if (!result.value.err) {
231 | setNotify!({
232 | status: "success",
233 | title: "Transaction Success",
234 | description: "",
235 | });
236 | } else {
237 | setNotify!({
238 | status: "success",
239 | title: "Fail",
240 | description: "Transaction fail, please check below link",
241 | link: `https://explorer.solana.com/address/${res}`
242 | });
243 | }
244 |
245 | getSPLTokenData(wallet, connection).then((tokenList: ISplToken[]) => {
246 | if (tokenList) {
247 | setSplTokenData(() =>
248 | tokenList.filter((t: ISplToken) => t !== undefined)
249 | );
250 | }
251 | });
252 | });
253 | };
254 |
255 | useEffect(() => {
256 | if (wallet.connected) {
257 | setNotify!({
258 | status: "success",
259 | title: "Wallet connected",
260 | description: wallet.publicKey?.toBase58() as string
261 | });
262 | } else {
263 | let description = wallet.publicKey?.toBase58();
264 | if (!description) {
265 | description = "Please try again";
266 | }
267 | setNotify!({
268 | status: "error",
269 | title: "Wallet disconnected",
270 | description: description as string
271 | });
272 | }
273 |
274 | }, [wallet.connected]);
275 |
276 | return (
277 |
278 | toggleTokenList(undefined)}
281 | getTokenInfo={getTokenInfo}
282 | />
283 |
293 |
294 |
295 | );
296 | };
297 |
298 | export default SwapPage;
299 |
--------------------------------------------------------------------------------
/hooks/useDapp.ts:
--------------------------------------------------------------------------------
1 | import { Connection } from "@solana/web3.js";
2 | import { useContext, createContext } from "react";
3 |
4 | const DappContext = createContext({
5 | splTokens: undefined,
6 | connection: new Connection("https://rpc-mainnet-fork.dappio.xyz", {
7 | wsEndpoint: "wss://rpc-mainnet-fork.dappio.xyz/ws",
8 | commitment: "processed",
9 | }),
10 | setNotify: null,
11 | setLoading: null,
12 | })
13 |
14 | export default function useDapp() {
15 | return useContext(DappContext)
16 | }
17 |
18 | export {DappContext}
19 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const withPlugins = require("next-compose-plugins");
3 |
4 | /** eslint-disable @typescript-eslint/no-var-requires */
5 | const withTM = require("next-transpile-modules")([
6 | "@solana/wallet-adapter-base",
7 | // Uncomment wallets you want to use
8 | // "@solana/wallet-adapter-bitpie",
9 | // "@solana/wallet-adapter-coin98",
10 | // "@solana/wallet-adapter-ledger",
11 | // "@solana/wallet-adapter-mathwallet",
12 | "@solana/wallet-adapter-phantom",
13 | "@solana/wallet-adapter-react",
14 | "@solana/wallet-adapter-solflare",
15 | "@solana/wallet-adapter-sollet",
16 | // "@solana/wallet-adapter-solong",
17 | // "@solana/wallet-adapter-torus",
18 | "@solana/wallet-adapter-wallets",
19 | // "@project-serum/sol-wallet-adapter",
20 | // "@solana/wallet-adapter-ant-design",
21 | ]);
22 |
23 | const plugins = [
24 | [
25 | withTM,
26 | {
27 | webpack5: true,
28 | reactStrictMode: true,
29 | },
30 | ],
31 | ];
32 |
33 | const nextConfig = {
34 | swcMinify: false,
35 | webpack: (config, {
36 | isServer
37 | }) => {
38 | if (!isServer) {
39 | config.resolve.fallback.fs = false;
40 | }
41 | return config;
42 | },
43 | };
44 |
45 | module.exports = withPlugins(plugins, nextConfig);
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "project60_solana_dapp",
3 | "private": true,
4 | "scripts": {
5 | "dev": "next dev",
6 | "build": "next build",
7 | "start": "next start",
8 | "lint": "next lint"
9 | },
10 | "dependencies": {
11 | "@chakra-ui/icons": "^1.1.1",
12 | "@chakra-ui/react": "^1.7.4",
13 | "@emotion/react": "^11",
14 | "@emotion/styled": "^11",
15 | "@jup-ag/react-hook": "^1.0.0-beta.2",
16 | "@project-serum/borsh": "^0.2.3",
17 | "@project-serum/serum": "^0.13.61",
18 | "@solana/spl-token-registry": "^0.2.1733",
19 | "@solana/wallet-adapter-base": "^0.9.2",
20 | "@solana/wallet-adapter-react": "^0.15.2",
21 | "@solana/wallet-adapter-react-ui": "^0.9.4",
22 | "@solana/wallet-adapter-wallets": "^0.14.2",
23 | "@solana/web3.js": "^1.32.0",
24 | "framer-motion": "^5",
25 | "lodash-es": "^4.17.21",
26 | "next": "12.0.8",
27 | "next-compose-plugins": "^2.2.1",
28 | "next-transpile-modules": "^9.0.0",
29 | "react": "17.0.2",
30 | "react-dom": "17.0.2",
31 | "sass": "^1.49.0"
32 | },
33 | "devDependencies": {
34 | "@types/lodash-es": "^4.17.5",
35 | "@types/node": "17.0.10",
36 | "@types/react": "17.0.38",
37 | "eslint": "8.7.0",
38 | "eslint-config-next": "12.0.8",
39 | "typescript": "4.5.5"
40 | },
41 | "resolutions": {
42 | "@solana/buffer-layout": "^3.0.0"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 | import type { AppProps } from 'next/app'
3 | // import { Wallet } from '../components/common/WalletProvider'
4 | import { ChakraProvider } from '@chakra-ui/react'
5 | import Layout from '../components/layout'
6 |
7 | import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
8 | import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
9 | import {
10 | LedgerWalletAdapter,
11 | PhantomWalletAdapter,
12 | SlopeWalletAdapter,
13 | SolflareWalletAdapter,
14 | SolletExtensionWalletAdapter,
15 | SolletWalletAdapter,
16 | TorusWalletAdapter
17 | } from "@solana/wallet-adapter-wallets";
18 | import { useMemo } from 'react'
19 | // import { clusterApiUrl } from "@solana/web3.js";
20 |
21 | // Default styles that can be overridden by your app
22 | require("@solana/wallet-adapter-react-ui/styles.css");
23 |
24 | function MyApp({ Component, pageProps }: AppProps) {
25 | // // The network can be set to 'devnet', 'testnet', or 'mainnet-beta'.
26 | const network = WalletAdapterNetwork.Mainnet;
27 |
28 | // // You can also provide a custom RPC endpoint.
29 | const endpoint = "https://rpc-mainnet-fork.dappio.xyz";
30 |
31 | // @solana/wallet-adapter-wallets includes all the adapters but supports tree shaking and lazy loading --
32 | // Only the wallets you configure here will be compiled into your application, and only the dependencies
33 | // of wallets that your users connect to will be loaded.
34 | const wallets = useMemo(
35 | () => [
36 | new PhantomWalletAdapter(),
37 | new SlopeWalletAdapter(),
38 | new SolflareWalletAdapter(),
39 | new TorusWalletAdapter(),
40 | new LedgerWalletAdapter(),
41 | new SolletWalletAdapter({ network }),
42 | new SolletExtensionWalletAdapter({ network })
43 | ],
44 | [network]
45 | );
46 |
47 | return
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | }
57 |
58 | export default MyApp
59 |
--------------------------------------------------------------------------------
/pages/exchange.tsx:
--------------------------------------------------------------------------------
1 |
2 | import SwapPage from "../components/raydium"
3 | import useDapp from "../hooks/useDapp"
4 |
5 |
6 | export default function ExchangePage() {
7 | const {splTokens} = useDapp()
8 | return <>
9 |
10 |
11 |
12 |
13 | >
14 | }
--------------------------------------------------------------------------------
/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import type { NextPage } from 'next'
2 |
3 |
4 |
5 | const Home: NextPage = () => {
6 |
7 | return <>
8 | >
9 | }
10 |
11 | export default Home
12 |
--------------------------------------------------------------------------------
/pages/my_spl.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useMemo, useState } from "react";
2 | import useDapp from "../hooks/useDapp"
3 | import { TOKENS } from "../utils/tokens";
4 | import style from "../styles/mySpl.module.sass"
5 | import { useWallet } from "@solana/wallet-adapter-react";
6 |
7 |
8 | export default function MySplPage() {
9 |
10 | const {splTokens, setNotify} = useDapp()
11 |
12 | const wallet = useWallet()
13 |
14 | const [tokenList, setTokenList] = useState([]);
15 |
16 | useEffect(()=>{ // Show error notify if there !wallet.connected
17 | setTokenList(updateTokenList())
18 | if (!wallet.connected) {
19 | setNotify!({
20 | status: "error",
21 | title: "Wallet not connected",
22 | description: "Please login with your wallet",
23 | })
24 | return
25 | }
26 | setNotify!(null)
27 | }, [])
28 |
29 | function updateTokenList(): SplTokenDisplayData[] {
30 | let tokenList = [];
31 | for (const [_, value] of Object.entries(TOKENS)) {
32 | let spl: ISplToken | undefined = splTokens?.find(
33 | (t: ISplToken) => t.parsedInfo.mint === value.mintAddress
34 | );
35 |
36 | if (spl) {
37 | let token = {} as SplTokenDisplayData;
38 | token["symbol"] = value.symbol;
39 | token["mint"] = spl?.parsedInfo.mint;
40 | token["pubkey"] = spl?.pubkey;
41 | token["amount"] = spl?.amount;
42 | tokenList.push(token);
43 | }
44 | }
45 | return tokenList
46 | }
47 |
48 | return <>
49 |
50 | {tokenList.map((item ) => {
51 | return (
52 |
53 |
54 |
55 | {item.symbol}
56 |
57 | - {item.amount}
58 |
59 |
60 |
Mint: {item.mint}
61 |
Pubkey: {item.pubkey}
62 |
63 |
64 | );
65 | })}
66 |
67 | >
68 | }
--------------------------------------------------------------------------------
/public/bg.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DappioLab/swap-ui-example/9b2b71217ab2be5f92ea07e3a50cca4afd59eaaf/public/bg.jpeg
--------------------------------------------------------------------------------
/public/image/dappio-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DappioLab/swap-ui-example/9b2b71217ab2be5f92ea07e3a50cca4afd59eaaf/public/image/dappio-logo.png
--------------------------------------------------------------------------------
/styles/color.module.sass:
--------------------------------------------------------------------------------
1 | $white: #eee
2 | $main_blue: rgb(19, 27, 51)
3 | $swap_card_bgc: #131a35
4 | $coin_select_block_bgc: #000829
5 | $placeholder_grey: #f1f1f2
6 | $swap_btn_border_color: #5ac4be
7 | $token_list_bgc: #1c274f
8 | $slippage_setting_warning_red: #f5222d
9 |
--------------------------------------------------------------------------------
/styles/common.module.sass:
--------------------------------------------------------------------------------
1 | @import './color.module'
2 | .notifyContainer
3 | position: fixed !important
4 | bottom: 3rem
5 | left: 2rem
6 | width: auto !important
7 | background-color: $token_list_bgc !important
8 | border-radius: .5rem
9 | padding: 2rem !important
10 | font-size: 1.4rem
11 | display: flex !important
12 | flex-direction: column !important
13 | align-items: center !important
14 | color: $white
15 | .notifyTitleRow
16 | display: flex
17 | align-items: center
18 | justify-content: center
19 | .notifyDescription
20 | margin-top: 2rem
21 |
22 | .loadingContainer
23 | position: fixed
24 | top: 100px
25 | right: 50px
26 | width: auto
27 | background-color: $token_list_bgc
28 | border-radius: .5rem
29 | padding: 2rem
30 | font-size: 1.4rem
31 | display: flex
32 | flex-direction: column
33 | align-items: center
34 | color: $white
--------------------------------------------------------------------------------
/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | }
8 |
9 | a {
10 | color: inherit;
11 | text-decoration: none;
12 | }
13 |
14 | * {
15 | box-sizing: border-box;
16 | }
17 |
18 |
19 | .wallet-adapter-button {
20 |
21 | }
22 |
23 | .wallet-adapter-button-trigger {
24 | background-color: #fbae21 !important;
25 | color: black !important;
26 | padding: 10px 5px;
27 | border-radius: 5px;
28 | font-weight: bold;
29 | }
30 |
31 | .btn {
32 | margin: 30px
33 | }
34 |
35 |
36 | .wallet-adapter-modal-wrapper {
37 | display: flex;
38 | flex-direction: column;
39 | width: 50%;
40 | margin: auto;
41 | justify-content: center;
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/styles/header.module.sass:
--------------------------------------------------------------------------------
1 | @import './color.module'
2 |
3 | .header
4 | padding: 10px
5 | display: flex
6 | color: $white
7 | justify-content: space-around
8 | background-color: black
9 | align-items: center
10 | font-weight: bold
11 |
--------------------------------------------------------------------------------
/styles/layout.module.sass:
--------------------------------------------------------------------------------
1 | .layoutContainer
2 | background-image: url("../public/bg.jpeg")
3 | background-repeat: no-repeat
4 | background-size: cover
5 | min-height: 100vh
--------------------------------------------------------------------------------
/styles/mySpl.module.sass:
--------------------------------------------------------------------------------
1 | @import './color.module'
2 | .splTokenList
3 | display: flex
4 | flex-direction: column
5 | align-items: center
6 | padding: 50px
7 | .item
8 | border: 1px solid $swap_card_bgc
9 | margin-top: 30px
10 | padding: 20px
11 | border-radius: 5px
12 | opacity: 0.7
13 | background-color: $white
14 |
--------------------------------------------------------------------------------
/styles/swap.module.sass:
--------------------------------------------------------------------------------
1 | @import './color.module'
2 |
3 | // .swapPage
4 | // position: relative
5 | // height: calc( 100vh - 7rem )
6 | // color: $white
7 | // background-color: $main_blue
8 | // .container
9 | // position: absolute
10 | // top: 5rem
11 | // left: 50%
12 | // transform: translateX(-50%)
13 | // .titleContainer
14 | // display: flex
15 | // align-items: center
16 | // justify-content: center
17 | // margin-bottom: 1rem
18 | // .title
19 | // flex: 1
20 | // font-weight: 600
21 | // font-size: 2.4rem
22 | // .iconContainer
23 | // display: flex
24 | // flex: 2
25 | // justify-content: flex-end
26 | // .icon
27 | // cursor: pointer
28 | // padding: .5rem
29 | // border-radius: .5rem
30 | // margin-left: 1rem
31 | // &:hover
32 | // background-color: $coin_select_block_bgc
33 | // .percentageCircle
34 | // width: 3rem
35 | // height: 3rem
36 | // .circleBg
37 | // stroke: $white
38 | // fill: none
39 | // stroke-width: 4
40 | // .popover
41 | // box-shadow: none !important
42 | // outline: none !important
43 | // .selectTokenAddressTitle
44 | // font-size: 1.2rem
45 | // font-weight: 600
46 | // color: $placeholder_grey
47 | // margin: .5rem 0 1rem 0
48 | // .selectTokenAddress
49 | // opacity: .7
50 | // display: flex
51 | // align-items: center
52 | // margin-top: .5rem
53 | // .symbol
54 | // width: 5rem
55 | // flex-shrink: 0
56 | // .address
57 | // background-color: $swap_card_bgc
58 | // padding: .5rem
59 | // border-radius: .5rem
60 | // font-weight: 600
61 | .swapCard
62 | margin: auto
63 | width: 36rem
64 | background: linear-gradient(245.22deg,#da2eef 7.97%,#2b6aff 49.17%,#39d0d8 92.1%)
65 | display: flex
66 | align-items: center
67 | justify-content: center
68 | border-radius: .5rem
69 | padding: .1rem
70 | .cardBody
71 | background-color: $swap_card_bgc
72 | border-radius: .5rem
73 | width: 100%
74 | height: 100%
75 | opacity: .9
76 | padding: 3.2rem 1.8rem 3.2rem 1.8rem
77 | display: flex
78 | flex-direction: column
79 | align-items: center
80 | .switchIcon
81 | margin: 1rem 0
82 | width: 3.2rem
83 | height: 3.2rem
84 | background-color: #000829
85 | border-radius: 50%
86 | display: flex
87 | align-items: center
88 | justify-content: center
89 | .icon
90 | cursor: pointer
91 | .lowSOLWarning
92 | font-size: 1.4rem
93 | color: $white
94 | display: flex
95 | align-items: center
96 | justify-content: center
97 | font-weight: 600
98 | padding-top: 1.5rem
99 | .txt
100 | margin-right: 1rem
101 | .coinSelect
102 | color: $white
103 | background-color: $coin_select_block_bgc
104 | border-radius: .4rem
105 | box-sizing: border-box
106 | padding: 1rem
107 | width: 100%
108 | .noteText
109 | font-size: 1.2rem
110 | color: #85858d
111 | display: flex
112 | justify-content: space-between
113 | .coinAmountRow
114 | display: flex
115 | align-items: center
116 | justify-content: space-between
117 | margin: 2rem 0 1rem 0
118 | .input
119 | background-color: transparent
120 | flex: 6
121 | border: none
122 | font-weight: 600
123 | font-size: 1.6rem
124 | color: $placeholder_grey
125 | white-space: nowrap
126 | overflow: hidden
127 | text-overflow: ellipsis
128 | letter-spacing: .1rem
129 | outline: none
130 | .selectTokenBtn
131 | flex: 4
132 | display: flex
133 | align-items: center
134 | justify-content: center
135 | padding: .5rem
136 | border-radius: .5rem
137 | font-weight: 500
138 | height: 4rem
139 | &:hover
140 | background-color: $token_list_bgc
141 | cursor: pointer
142 | .img
143 | width: 2.4rem
144 | height: 2.4rem
145 | border-radius: 50%
146 | margin-right: 1rem
147 | .coinNameBlock
148 | border: none
149 | font-weight: 600
150 | font-size: 1.4rem
151 | border-radius: .4rem
152 | white-space: nowrap
153 | cursor: pointer
154 | font-family: Bakbak One
155 | letter-spacing: 1px
156 | .coinName
157 | margin-right: .5rem
158 | .slippageRow
159 | color: $white
160 | display: flex
161 | align-items: center
162 | justify-content: space-between
163 | width: 100%
164 | padding: 1rem 1.2rem 0 1.2rem
165 | font-size: 1.2rem
166 | opacity: .75
167 | font-weight: 600
168 | .slippageTooltipBlock
169 | display: flex
170 | align-items: center
171 | .icon
172 | margin-left: 1rem
173 |
174 | .operateBtn
175 | width: 100%
176 | height: 4rem
177 | border: solid .1rem $swap_btn_border_color
178 | color: $white
179 | background-color: transparent
180 | border-radius: .4rem
181 | margin-top: 2rem
182 | font-size: 1.6rem
183 | font-weight: 600
184 | &:hover
185 | transition: .5s
186 | color: $swap_btn_border_color
187 | // .selectWallet
188 | // margin-top: 2.5rem
189 | .disabledBtn
190 | border-color: $placeholder_grey
191 | opacity: .7
192 | cursor: unset
193 | &:hover
194 | color: $placeholder_grey
195 |
196 | .tokeListComponent
197 | transition: .3s
198 | width: 100vw
199 | height: 100vh
200 | background-color: rgba(0,0,0,.5)
201 | color: $white
202 | position: fixed
203 | top: 0
204 | left: 0
205 | z-index: 99
206 | .tokeListContainer
207 | max-width: 45rem
208 | width: calc(100vw - 1.6rem)
209 | height: calc( 100vh - 14rem)
210 | overflow: hidden
211 | background-color: $token_list_bgc
212 | position: absolute
213 | top: 10rem
214 | left: 50%
215 | transform: translateX(-50%)
216 | border-radius: .5rem
217 | .header
218 | height: 6rem
219 | padding: 2.4rem
220 | display: flex
221 | align-items: center
222 | justify-content: space-between
223 | font-size: 1.6rem
224 | font-weight: 600
225 | letter-spacing: 1px
226 | border-bottom: solid .1rem $white
227 | .list
228 | height: calc(100% - 10rem)
229 | overflow: scroll
230 | padding: 0 1.5rem 2rem 1.5rem
231 | .tokenRow
232 | display: flex
233 | align-items: center
234 | padding: .8rem 1.2rem
235 | font-size: 1.2rem
236 | cursor: pointer
237 | &:hover
238 | background-color: $coin_select_block_bgc
239 | opacity: .7
240 | .tokenLogo
241 | width: 2rem
242 | height: 2rem
243 | border-radius: 50%
244 | overflow: hidden
245 | margin-right: 1.2rem
246 | .tokenListSetting
247 | border-top: solid .1rem $white
248 | height: 5.5rem
249 | flex-shrink: 0
250 | display: flex
251 | align-items: center
252 | justify-content: center
253 | font-size: 1.4rem
254 | letter-spacing: 1px
255 | position: absolute
256 | bottom: 0
257 | background-color: $token_list_bgc
258 | width: 100%
259 | .closeIcon
260 | cursor: pointer
261 | .inputBlock
262 | padding: 0.2rem 2.5rem 0 2.5rem
263 | .tokenListTitleRow
264 | font-size: 1.4rem
265 | font-weight: 600
266 | height: 5rem
267 | display: flex
268 | justify-content: space-between
269 | align-items: center
270 | .searchTokenInput
271 | // padding: 0.5rem
272 | border: solid .1rem $swap_btn_border_color
273 | outline: none
274 | width: 100%
275 | background-color: $token_list_bgc
276 | font-size: 1.8rem
277 | border-radius: .5rem
278 | margin-top: 2rem
279 |
280 | // .slippageSettingComponent
281 | // width: 100vw
282 | // height: 100vh
283 | // background-color: rgba(0,0,0,.5)
284 | // position: fixed
285 | // z-index: 999
286 | // top: 0
287 | // left: 0
288 | // .slippageSettingContainer
289 | // width: 50rem
290 | // height: 20rem
291 | // background-color: $token_list_bgc
292 | // top: 50%
293 | // left: 50%
294 | // transform: translate(-50%, -50%)
295 | // position: fixed
296 | // z-index: 9999999
297 | // border-radius: .5rem
298 | // .header
299 | // padding: 0 2rem
300 | // font-size: 1.6rem
301 | // height: 5rem
302 | // display: flex
303 | // align-items: center
304 | // justify-content: space-between
305 | // border-bottom: solid .1rem $white
306 | // font-weight: 500
307 | // .closeIcon
308 | // cursor: pointer
309 | // .settingSelectBlock
310 | // padding: 2.4rem
311 | // .title
312 | // font-weight: 700
313 | // font-size: 1.6rem
314 | // color: $placeholder_grey
315 | // .optionsBlock
316 | // display: flex
317 | // align-items: center
318 | // margin-top: 1rem
319 | // .optionBtn
320 | // display: flex
321 | // align-items: center
322 | // justify-content: center
323 | // width: 100%
324 | // background-color: $swap_card_bgc
325 | // color: $placeholder_grey
326 | // padding: 1rem 1.2rem
327 | // border: 0
328 | // border-radius: 4px
329 | // font-size: 1.4rem
330 | // font-weight: 600
331 | // cursor: pointer
332 | // flex: 1
333 | // margin-right: 1.5rem
334 | // .warning
335 | // margin: 1rem
336 | // color: $slippage_setting_warning_red
337 | // font-size: 1.4rem
338 | // .input
339 | // width: 100%
340 | // background-color: transparent
341 | // outline: none
342 | // text-align: center
343 | // .optionBtn.selectedSlippageRateBtn
344 | // background-color: $swap_btn_border_color
345 | // .inputBtn
346 | // border: solid .1rem $swap_btn_border_color
347 | // .splTokenContainer
348 | // padding: 3rem 2rem 3rem 3rem
349 | // margin-top: 5rem
350 | // border-radius: 0 1rem 1rem 0
351 | // height: 80%
352 | // overflow: scroll
353 | // background-color: $token_list_bgc
354 | // display: inline-block
355 | // .splTokenListTitle
356 | // font-size: 2.2rem
357 | // margin-bottom: 4rem
358 | // font-weight: 600
359 | // .splTokenItem
360 | // margin-top: 1rem
361 | // font-size: 1.5rem
362 | // .loading
363 | // font-size: 2rem
364 | // position: absolute
365 | // left: 50%
366 | // transform: translateX(-50%)
367 | // margin-top: 3rem
368 |
369 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true
17 | },
18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
19 | "exclude": ["node_modules"]
20 | }
21 |
--------------------------------------------------------------------------------
/types.d.ts:
--------------------------------------------------------------------------------
1 | import { WalletContextState } from "@solana/wallet-adapter-react"
2 | import { Connection } from "@solana/web3.js"
3 | import { AlertStatus } from "@chakra-ui/react";
4 | import { SetStateAction, Dispatch} from "react"
5 |
6 | declare global {
7 |
8 | // Common Components
9 | interface INotify {
10 | status: AlertStatus;
11 | title: string;
12 | description: string;
13 | link?: string;
14 | }
15 |
16 | type LoadingType = {
17 | msg: string,
18 | size?: "xl" | "xs" | "sm" | "md" | "lg",
19 | thickness?: number, // uint ex: 3 (in pixel)
20 | speed?: number, // floating point ex: 0.65s (in second)
21 | emptyColor?: string, // ex: gray.200 (see chakra doc)
22 | color?: string, // ex: blue.500 (see chakra doc)
23 | }
24 |
25 | // Raydium Components
26 | interface IUpdateAmountData {
27 | type: string;
28 | amount: number;
29 | }
30 |
31 | interface ITokenInfo {
32 | symbol: string;
33 | mintAddress: string;
34 | logoURI: string;
35 | }
36 | interface TokenData {
37 | amount: number | null;
38 | tokenInfo: ITokenInfo;
39 | }
40 |
41 | interface IUpdateAmountData {
42 | type: string;
43 | amount: number;
44 | }
45 |
46 |
47 | // SPL token
48 |
49 | interface SplTokenDisplayData {
50 | symbol: string;
51 | mint: string;
52 | pubkey: string;
53 | amount: number;
54 | }
55 |
56 | interface ISplToken {
57 | pubkey: string;
58 | parsedInfo: any;
59 | amount: number;
60 | }
61 |
62 | // Components props
63 |
64 | type LoadingProps = {
65 | data: LoadingType
66 | }
67 |
68 | interface NotifyProps {
69 | message: INotify;
70 | }
71 |
72 | interface ISplTokenProps {
73 | splTokenData: ISplToken[];
74 | }
75 |
76 | interface TokenListProps {
77 | showTokenList: boolean;
78 | toggleTokenList: (type: "From" | "To" | undefined) => void;
79 | getTokenInfo: Function;
80 | }
81 |
82 | interface TokenSelectProps {
83 | type: string;
84 | toggleTokenList: Function;
85 | tokenData: TokenData;
86 | updateAmount: Function;
87 | wallet: Object;
88 | splTokenData: ISplToken[];
89 | }
90 |
91 | interface dropDownTokenListBtnProps {
92 | tokenData: TokenData;
93 | }
94 |
95 | interface SwapOperateContainerProps {
96 | toggleTokenList: Function;
97 | fromData: TokenData;
98 | toData: TokenData;
99 | updateAmount: Function;
100 | switchFromAndTo: (event?: React.MouseEvent) => void;
101 | slippageValue: number;
102 | sendSwapTransaction: (event?: React.MouseEvent) => void;
103 | splTokenData: ISplToken[];
104 | }
105 |
106 | interface SwapDetailProps {
107 | title: string;
108 | tooltipContent: string;
109 | value: string;
110 | }
111 |
112 |
113 | // Context Types
114 |
115 | type DappContextType = {
116 | splTokens: ISplToken[] | undefined,
117 | connection: Connection,
118 | setNotify: Dispatch>| null,
119 | setLoading: Dispatch>| null
120 | }
121 | }
122 | export {}
--------------------------------------------------------------------------------
/utils/ids.ts:
--------------------------------------------------------------------------------
1 | import { PublicKey } from '@solana/web3.js'
2 |
3 | export const SYSTEM_PROGRAM_ID = new PublicKey('11111111111111111111111111111111')
4 | export const TOKEN_PROGRAM_ID = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA')
5 | export const MEMO_PROGRAM_ID = new PublicKey('Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo')
6 | export const RENT_PROGRAM_ID = new PublicKey('SysvarRent111111111111111111111111111111111')
7 | export const CLOCK_PROGRAM_ID = new PublicKey('SysvarC1ock11111111111111111111111111111111')
8 | export const ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL')
9 |
10 | export const SERUM_PROGRAM_ID_V2 = 'EUqojwWA2rd19FZrzeBncJsm38Jm1hEhE3zsmX3bRc2o'
11 | export const SERUM_PROGRAM_ID_V3 = '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'
12 |
13 | export const LIQUIDITY_POOL_PROGRAM_ID_V2 = 'RVKd61ztZW9GUwhRbbLoYVRE5Xf1B2tVscKqwZqXgEr'
14 | export const LIQUIDITY_POOL_PROGRAM_ID_V3 = '27haf8L6oxUeXrHrgEgsexjSY5hbVUWEmvv9Nyxg8vQv'
15 | export const LIQUIDITY_POOL_PROGRAM_ID_V4 = '675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'
16 |
17 | export const STABLE_POOL_PROGRAM_ID = '5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h'
18 |
19 | export const ROUTE_SWAP_PROGRAM_ID = '93BgeoLHo5AdNbpqy9bD12dtfxtA5M2fh3rj72bE35Y3'
20 |
21 | export const STAKE_PROGRAM_ID = 'EhhTKczWMGQt46ynNeRX1WfeagwwJd7ufHvCDjRxjo5Q'
22 | export const STAKE_PROGRAM_ID_V4 = 'CBuCnLe26faBpcBP2fktp4rp8abpcAnTWft6ZrP5Q4T'
23 | export const STAKE_PROGRAM_ID_V5 = '9KEPoZmtHUrBbhWN1v1KWLMkkvwY6WLtAVUCPRtRjP4z'
24 |
25 | export const IDO_PROGRAM_ID = '6FJon3QE27qgPVggARueB22hLvoh22VzJpXv4rBEoSLF'
26 | export const IDO_PROGRAM_ID_V2 = 'CC12se5To1CdEuw7fDS27B7Geo5jJyL7t5UK2B44NgiH'
27 | export const IDO_PROGRAM_ID_V3 = '9HzJyW1qZsEiSfMUf6L2jo3CcTKAyBmSyKdwQeYisHrC'
28 |
29 | export const AUTHORITY_AMM = 'amm authority'
30 | export const AMM_ASSOCIATED_SEED = 'amm_associated_seed'
31 | export const TARGET_ASSOCIATED_SEED = 'target_associated_seed'
32 | export const WITHDRAW_ASSOCIATED_SEED = 'withdraw_associated_seed'
33 | export const OPEN_ORDER_ASSOCIATED_SEED = 'open_order_associated_seed'
34 | export const COIN_VAULT_ASSOCIATED_SEED = 'coin_vault_associated_seed'
35 | export const PC_VAULT_ASSOCIATED_SEED = 'pc_vault_associated_seed'
36 | export const LP_MINT_ASSOCIATED_SEED = 'lp_mint_associated_seed'
37 | export const TEMP_LP_TOKEN_ASSOCIATED_SEED = 'temp_lp_token_associated_seed'
38 |
--------------------------------------------------------------------------------
/utils/layouts.ts:
--------------------------------------------------------------------------------
1 | import { bool, publicKey, struct, u32, u64, u8 } from '@project-serum/borsh'
2 |
3 | // https://github.com/solana-labs/solana-program-library/blob/master/token/js/client/token.js#L210
4 | export const ACCOUNT_LAYOUT = struct([
5 | publicKey('mint'),
6 | publicKey('owner'),
7 | u64('amount'),
8 | u32('delegateOption'),
9 | publicKey('delegate'),
10 | u8('state'),
11 | u32('isNativeOption'),
12 | u64('isNative'),
13 | u64('delegatedAmount'),
14 | u32('closeAuthorityOption'),
15 | publicKey('closeAuthority')
16 | ])
17 |
18 | export const MINT_LAYOUT = struct([
19 | u32('mintAuthorityOption'),
20 | publicKey('mintAuthority'),
21 | u64('supply'),
22 | u8('decimals'),
23 | bool('initialized'),
24 | u32('freezeAuthorityOption'),
25 | publicKey('freezeAuthority')
26 | ])
27 |
28 | export function getBigNumber(num: any) {
29 | return num === undefined || num === null ? 0 : parseFloat(num.toString())
30 | }
31 |
--------------------------------------------------------------------------------
/utils/liquidity.ts:
--------------------------------------------------------------------------------
1 | //@ts-ignore
2 | import { struct } from "buffer-layout";
3 | import { publicKey, u128, u64 } from "@project-serum/borsh";
4 | import { PublicKey } from "@solana/web3.js";
5 | import { LP_TOKENS } from "./tokens";
6 | import { commitment, getMultipleAccounts } from "./web3";
7 | import { MINT_LAYOUT } from "./layouts";
8 |
9 | export const AMM_INFO_LAYOUT = struct([
10 | u64("status"),
11 | u64("nonce"),
12 | u64("orderNum"),
13 | u64("depth"),
14 | u64("coinDecimals"),
15 | u64("pcDecimals"),
16 | u64("state"),
17 | u64("resetFlag"),
18 | u64("fee"),
19 | u64("minSize"),
20 | u64("volMaxCutRatio"),
21 | u64("pnlRatio"),
22 | u64("amountWaveRatio"),
23 | u64("coinLotSize"),
24 | u64("pcLotSize"),
25 | u64("minPriceMultiplier"),
26 | u64("maxPriceMultiplier"),
27 | u64("needTakePnlCoin"),
28 | u64("needTakePnlPc"),
29 | u64("totalPnlX"),
30 | u64("totalPnlY"),
31 | u64("systemDecimalsValue"),
32 | publicKey("poolCoinTokenAccount"),
33 | publicKey("poolPcTokenAccount"),
34 | publicKey("coinMintAddress"),
35 | publicKey("pcMintAddress"),
36 | publicKey("lpMintAddress"),
37 | publicKey("ammOpenOrders"),
38 | publicKey("serumMarket"),
39 | publicKey("serumProgramId"),
40 | publicKey("ammTargetOrders"),
41 | publicKey("ammQuantities"),
42 | publicKey("poolWithdrawQueue"),
43 | publicKey("poolTempLpTokenAccount"),
44 | publicKey("ammOwner"),
45 | publicKey("pnlOwner")
46 | ]);
47 |
48 | export const AMM_INFO_LAYOUT_V3 = struct([
49 | u64("status"),
50 | u64("nonce"),
51 | u64("orderNum"),
52 | u64("depth"),
53 | u64("coinDecimals"),
54 | u64("pcDecimals"),
55 | u64("state"),
56 | u64("resetFlag"),
57 | u64("fee"),
58 | u64("min_separate"),
59 | u64("minSize"),
60 | u64("volMaxCutRatio"),
61 | u64("pnlRatio"),
62 | u64("amountWaveRatio"),
63 | u64("coinLotSize"),
64 | u64("pcLotSize"),
65 | u64("minPriceMultiplier"),
66 | u64("maxPriceMultiplier"),
67 | u64("needTakePnlCoin"),
68 | u64("needTakePnlPc"),
69 | u64("totalPnlX"),
70 | u64("totalPnlY"),
71 | u64("poolTotalDepositPc"),
72 | u64("poolTotalDepositCoin"),
73 | u64("systemDecimalsValue"),
74 | publicKey("poolCoinTokenAccount"),
75 | publicKey("poolPcTokenAccount"),
76 | publicKey("coinMintAddress"),
77 | publicKey("pcMintAddress"),
78 | publicKey("lpMintAddress"),
79 | publicKey("ammOpenOrders"),
80 | publicKey("serumMarket"),
81 | publicKey("serumProgramId"),
82 | publicKey("ammTargetOrders"),
83 | publicKey("ammQuantities"),
84 | publicKey("poolWithdrawQueue"),
85 | publicKey("poolTempLpTokenAccount"),
86 | publicKey("ammOwner"),
87 | publicKey("pnlOwner"),
88 | publicKey("srmTokenAccount")
89 | ]);
90 |
91 | export const AMM_INFO_LAYOUT_V4 = struct([
92 | u64("status"),
93 | u64("nonce"),
94 | u64("orderNum"),
95 | u64("depth"),
96 | u64("coinDecimals"),
97 | u64("pcDecimals"),
98 | u64("state"),
99 | u64("resetFlag"),
100 | u64("minSize"),
101 | u64("volMaxCutRatio"),
102 | u64("amountWaveRatio"),
103 | u64("coinLotSize"),
104 | u64("pcLotSize"),
105 | u64("minPriceMultiplier"),
106 | u64("maxPriceMultiplier"),
107 | u64("systemDecimalsValue"),
108 | // Fees
109 | u64("minSeparateNumerator"),
110 | u64("minSeparateDenominator"),
111 | u64("tradeFeeNumerator"),
112 | u64("tradeFeeDenominator"),
113 | u64("pnlNumerator"),
114 | u64("pnlDenominator"),
115 | u64("swapFeeNumerator"),
116 | u64("swapFeeDenominator"),
117 | // OutPutData
118 | u64("needTakePnlCoin"),
119 | u64("needTakePnlPc"),
120 | u64("totalPnlPc"),
121 | u64("totalPnlCoin"),
122 |
123 | u64("poolOpenTime"),
124 | u64("punishPcAmount"),
125 | u64("punishCoinAmount"),
126 | u64("orderbookToInitTime"),
127 |
128 | u128("swapCoinInAmount"),
129 | u128("swapPcOutAmount"),
130 | u64("swapCoin2PcFee"),
131 | u128("swapPcInAmount"),
132 | u128("swapCoinOutAmount"),
133 | u64("swapPc2CoinFee"),
134 |
135 | publicKey("poolCoinTokenAccount"),
136 | publicKey("poolPcTokenAccount"),
137 | publicKey("coinMintAddress"),
138 | publicKey("pcMintAddress"),
139 | publicKey("lpMintAddress"),
140 | publicKey("ammOpenOrders"),
141 | publicKey("serumMarket"),
142 | publicKey("serumProgramId"),
143 | publicKey("ammTargetOrders"),
144 | publicKey("poolWithdrawQueue"),
145 | publicKey("poolTempLpTokenAccount"),
146 | publicKey("ammOwner"),
147 | publicKey("pnlOwner")
148 | ]);
149 |
150 | export const AMM_INFO_LAYOUT_STABLE = struct([
151 | u64("status"),
152 | publicKey("own_address"),
153 | u64("nonce"),
154 | u64("orderNum"),
155 | u64("depth"),
156 | u64("coinDecimals"),
157 | u64("pcDecimals"),
158 | u64("state"),
159 | u64("resetFlag"),
160 | u64("minSize"),
161 | u64("volMaxCutRatio"),
162 | u64("amountWaveRatio"),
163 | u64("coinLotSize"),
164 | u64("pcLotSize"),
165 | u64("minPriceMultiplier"),
166 | u64("maxPriceMultiplier"),
167 | u64("systemDecimalsValue"),
168 |
169 | u64("ammMaxPrice"),
170 | u64("ammMiddlePrice"),
171 | u64("ammPriceMultiplier"),
172 |
173 | // Fees
174 | u64("minSeparateNumerator"),
175 | u64("minSeparateDenominator"),
176 | u64("tradeFeeNumerator"),
177 | u64("tradeFeeDenominator"),
178 | u64("pnlNumerator"),
179 | u64("pnlDenominator"),
180 | u64("swapFeeNumerator"),
181 | u64("swapFeeDenominator"),
182 | // OutPutData
183 | u64("needTakePnlCoin"),
184 | u64("needTakePnlPc"),
185 | u64("totalPnlPc"),
186 | u64("totalPnlCoin"),
187 | u128("poolTotalDepositPc"),
188 | u128("poolTotalDepositCoin"),
189 | u128("swapCoinInAmount"),
190 | u128("swapPcOutAmount"),
191 | u128("swapPcInAmount"),
192 | u128("swapCoinOutAmount"),
193 | u64("swapPcFee"),
194 | u64("swapCoinFee"),
195 |
196 | publicKey("poolCoinTokenAccount"),
197 | publicKey("poolPcTokenAccount"),
198 | publicKey("coinMintAddress"),
199 | publicKey("pcMintAddress"),
200 | publicKey("lpMintAddress"),
201 | publicKey("ammOpenOrders"),
202 | publicKey("serumMarket"),
203 | publicKey("serumProgramId"),
204 | publicKey("ammTargetOrders"),
205 | publicKey("poolWithdrawQueue"),
206 | publicKey("poolTempLpTokenAccount"),
207 | publicKey("ammOwner"),
208 | publicKey("pnlOwner"),
209 |
210 | u128("currentK"),
211 | u128("padding1"),
212 | publicKey("padding2")
213 | ]);
214 |
215 | export async function getLpMintListDecimals(
216 | conn: any,
217 | mintAddressInfos: string[]
218 | ): Promise<{ [name: string]: number }> {
219 | const reLpInfoDict: { [name: string]: number } = {};
220 | const mintList = [] as PublicKey[];
221 | mintAddressInfos.forEach(item => {
222 | let lpInfo = Object.values(LP_TOKENS).find(
223 | itemLpToken => itemLpToken.mintAddress === item
224 | );
225 | if (!lpInfo) {
226 | mintList.push(new PublicKey(item));
227 | lpInfo = {
228 | decimals: null
229 | };
230 | }
231 | reLpInfoDict[item] = lpInfo.decimals;
232 | });
233 | const mintAll = await getMultipleAccounts(conn, mintList, commitment);
234 | for (let mintIndex = 0; mintIndex < mintAll.length; mintIndex += 1) {
235 | const itemMint = mintAll[mintIndex];
236 | if (itemMint) {
237 | const mintLayoutData = MINT_LAYOUT.decode(
238 | Buffer.from(itemMint.account.data)
239 | );
240 | reLpInfoDict[mintList[mintIndex].toString()] = mintLayoutData.decimals;
241 | }
242 | }
243 | const reInfo: { [name: string]: number } = {};
244 | for (const key of Object.keys(reLpInfoDict)) {
245 | if (reLpInfoDict[key] !== null) {
246 | reInfo[key] = reLpInfoDict[key];
247 | }
248 | }
249 | return reInfo;
250 | }
251 |
--------------------------------------------------------------------------------
/utils/safe-math.ts:
--------------------------------------------------------------------------------
1 | import BigNumber from "bignumber.js";
2 |
3 | // https://github.com/MikeMcl/bignumber.js
4 | // https://blog.csdn.net/shenxianhui1995/article/details/103985434
5 | export class TokenAmount {
6 | public wei: BigNumber;
7 |
8 | public decimals: number;
9 | public _decimals: BigNumber;
10 |
11 | constructor(
12 | wei: number | string | BigNumber,
13 | decimals: number = 0,
14 | isWei = true
15 | ) {
16 | this.decimals = decimals;
17 | this._decimals = new BigNumber(10).exponentiatedBy(decimals);
18 |
19 | if (isWei) {
20 | this.wei = new BigNumber(wei);
21 | } else {
22 | this.wei = new BigNumber(wei).multipliedBy(this._decimals);
23 | }
24 | }
25 |
26 | toWei() {
27 | return this.wei;
28 | }
29 |
30 | fixed() {
31 | return this.wei.dividedBy(this._decimals).toFixed(this.decimals);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/utils/swap.ts:
--------------------------------------------------------------------------------
1 | import { Buffer } from "buffer";
2 | import { closeAccount } from "@project-serum/serum/lib/token-instructions";
3 | import { OpenOrders } from "@project-serum/serum";
4 | // import { _OPEN_ORDERS_LAYOUT_V2} from '@project-serum/serum/lib/market';
5 | import {
6 | Connection,
7 | PublicKey,
8 | Transaction,
9 | TransactionInstruction,
10 | AccountInfo,
11 | Keypair
12 | } from "@solana/web3.js";
13 | // @ts-ignore
14 | import { nu64, struct, u8 } from "buffer-layout";
15 |
16 | // eslint-disable-next-line
17 | import { TokenAmount } from "./safe-math";
18 | import {
19 | createAssociatedTokenAccountIfNotExist,
20 | createTokenAccountIfNotExist,
21 | sendTransaction,
22 | getMultipleAccounts,
23 | getFilteredProgramAccountsAmmOrMarketCache,
24 | createAmmAuthority
25 | } from "./web3";
26 | import { TOKEN_PROGRAM_ID } from "./ids";
27 | import { getBigNumber, ACCOUNT_LAYOUT, MINT_LAYOUT } from "./layouts";
28 |
29 | // eslint-disable-next-line
30 | import {
31 | getTokenByMintAddress,
32 | NATIVE_SOL,
33 | TOKENS,
34 | // TokenInfo,
35 | LP_TOKENS
36 | } from "./tokens";
37 | // import { getAddressForWhat, LIQUIDITY_POOLS, LiquidityPoolInfo } from "./pools";
38 | import { getAddressForWhat, LIQUIDITY_POOLS} from "./pools";
39 | import {
40 | AMM_INFO_LAYOUT,
41 | AMM_INFO_LAYOUT_STABLE,
42 | AMM_INFO_LAYOUT_V3,
43 | AMM_INFO_LAYOUT_V4,
44 | getLpMintListDecimals
45 | } from "./liquidity";
46 | import { LIQUIDITY_POOL_PROGRAM_ID_V4, SERUM_PROGRAM_ID_V3 } from "./ids";
47 | import { MARKET_STATE_LAYOUT_V2 } from "@project-serum/serum/lib/market";
48 |
49 | export function swapInstruction(
50 | programId: PublicKey,
51 | // tokenProgramId: PublicKey,
52 | // amm
53 | ammId: PublicKey,
54 | ammAuthority: PublicKey,
55 | ammOpenOrders: PublicKey,
56 | ammTargetOrders: PublicKey,
57 | poolCoinTokenAccount: PublicKey,
58 | poolPcTokenAccount: PublicKey,
59 | // serum
60 | serumProgramId: PublicKey,
61 | serumMarket: PublicKey,
62 | serumBids: PublicKey,
63 | serumAsks: PublicKey,
64 | serumEventQueue: PublicKey,
65 | serumCoinVaultAccount: PublicKey,
66 | serumPcVaultAccount: PublicKey,
67 | serumVaultSigner: PublicKey,
68 | // user
69 | userSourceTokenAccount: PublicKey,
70 | userDestTokenAccount: PublicKey,
71 | userOwner: PublicKey,
72 |
73 | amountIn: number,
74 | minAmountOut: number
75 | ): TransactionInstruction {
76 | const dataLayout = struct([
77 | u8("instruction"),
78 | nu64("amountIn"),
79 | nu64("minAmountOut")
80 | ]);
81 |
82 | const keys = [
83 | // spl token
84 | { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
85 | // amm
86 | { pubkey: ammId, isSigner: false, isWritable: true },
87 | { pubkey: ammAuthority, isSigner: false, isWritable: false },
88 | { pubkey: ammOpenOrders, isSigner: false, isWritable: true },
89 | { pubkey: ammTargetOrders, isSigner: false, isWritable: true },
90 | { pubkey: poolCoinTokenAccount, isSigner: false, isWritable: true },
91 | { pubkey: poolPcTokenAccount, isSigner: false, isWritable: true },
92 | // serum
93 | { pubkey: serumProgramId, isSigner: false, isWritable: false },
94 | { pubkey: serumMarket, isSigner: false, isWritable: true },
95 | { pubkey: serumBids, isSigner: false, isWritable: true },
96 | { pubkey: serumAsks, isSigner: false, isWritable: true },
97 | { pubkey: serumEventQueue, isSigner: false, isWritable: true },
98 | { pubkey: serumCoinVaultAccount, isSigner: false, isWritable: true },
99 | { pubkey: serumPcVaultAccount, isSigner: false, isWritable: true },
100 | { pubkey: serumVaultSigner, isSigner: false, isWritable: false },
101 | { pubkey: userSourceTokenAccount, isSigner: false, isWritable: true },
102 | { pubkey: userDestTokenAccount, isSigner: false, isWritable: true },
103 | { pubkey: userOwner, isSigner: true, isWritable: false }
104 | ];
105 |
106 | const data = Buffer.alloc(dataLayout.span);
107 | dataLayout.encode(
108 | {
109 | instruction: 9,
110 | amountIn,
111 | minAmountOut
112 | },
113 | data
114 | );
115 |
116 | return new TransactionInstruction({
117 | keys,
118 | programId,
119 | data
120 | });
121 | }
122 |
123 | export async function swap(
124 | connection: Connection,
125 | wallet: any,
126 | poolInfo: any,
127 | fromCoinMint: string,
128 | toCoinMint: string,
129 | fromTokenAccount: string,
130 | toTokenAccount: string,
131 | aIn: string,
132 | aOut: string,
133 | wsolAddress: string
134 | ) {
135 | const transaction = new Transaction();
136 | const signers: Keypair[] = [];
137 |
138 | const owner = wallet.publicKey;
139 |
140 | const from = getTokenByMintAddress(fromCoinMint);
141 | const to = getTokenByMintAddress(toCoinMint);
142 | if (!from || !to) {
143 | throw new Error("Miss token info");
144 | }
145 |
146 | const amountIn = new TokenAmount(aIn, from.decimals, false);
147 | const amountOut = new TokenAmount(aOut, to.decimals, false);
148 |
149 | if (fromCoinMint === NATIVE_SOL.mintAddress && wsolAddress) {
150 | transaction.add(
151 | closeAccount({
152 | source: new PublicKey(wsolAddress),
153 | destination: owner,
154 | owner
155 | })
156 | );
157 | }
158 |
159 | let fromMint = fromCoinMint;
160 | let toMint = toCoinMint;
161 |
162 | if (fromMint === NATIVE_SOL.mintAddress) {
163 | fromMint = TOKENS.WSOL.mintAddress;
164 | }
165 | if (toMint === NATIVE_SOL.mintAddress) {
166 | toMint = TOKENS.WSOL.mintAddress;
167 | }
168 |
169 | let wrappedSolAccount: PublicKey | null = null;
170 | let wrappedSolAccount2: PublicKey | null = null;
171 | let newFromTokenAccount = PublicKey.default;
172 | let newToTokenAccount = PublicKey.default;
173 |
174 | if (fromCoinMint === NATIVE_SOL.mintAddress) {
175 | wrappedSolAccount = await createTokenAccountIfNotExist(
176 | connection,
177 | wrappedSolAccount,
178 | owner,
179 | TOKENS.WSOL.mintAddress,
180 | getBigNumber(amountIn.wei) + 1e7,
181 | transaction,
182 | signers
183 | );
184 | } else {
185 | newFromTokenAccount = await createAssociatedTokenAccountIfNotExist(
186 | fromTokenAccount,
187 | owner,
188 | fromMint,
189 | transaction
190 | );
191 | }
192 |
193 | if (toCoinMint === NATIVE_SOL.mintAddress) {
194 | wrappedSolAccount2 = await createTokenAccountIfNotExist(
195 | connection,
196 | wrappedSolAccount2,
197 | owner,
198 | TOKENS.WSOL.mintAddress,
199 | 1e7,
200 | transaction,
201 | signers
202 | );
203 | } else {
204 | newToTokenAccount = await createAssociatedTokenAccountIfNotExist(
205 | toTokenAccount,
206 | owner,
207 | toMint,
208 | transaction
209 | );
210 | }
211 |
212 | transaction.add(
213 | swapInstruction(
214 | new PublicKey(poolInfo.programId),
215 | new PublicKey(poolInfo.ammId),
216 | new PublicKey(poolInfo.ammAuthority),
217 | new PublicKey(poolInfo.ammOpenOrders),
218 | new PublicKey(poolInfo.ammTargetOrders),
219 | new PublicKey(poolInfo.poolCoinTokenAccount),
220 | new PublicKey(poolInfo.poolPcTokenAccount),
221 | new PublicKey(poolInfo.serumProgramId),
222 | new PublicKey(poolInfo.serumMarket),
223 | new PublicKey(poolInfo.serumBids),
224 | new PublicKey(poolInfo.serumAsks),
225 | new PublicKey(poolInfo.serumEventQueue),
226 | new PublicKey(poolInfo.serumCoinVaultAccount),
227 | new PublicKey(poolInfo.serumPcVaultAccount),
228 | new PublicKey(poolInfo.serumVaultSigner),
229 | wrappedSolAccount ?? newFromTokenAccount,
230 | wrappedSolAccount2 ?? newToTokenAccount,
231 | owner,
232 | Math.floor(getBigNumber(amountIn.toWei())),
233 | Math.floor(getBigNumber(amountOut.toWei()))
234 | )
235 | );
236 |
237 | if (wrappedSolAccount) {
238 | transaction.add(
239 | closeAccount({
240 | source: wrappedSolAccount,
241 | destination: owner,
242 | owner
243 | })
244 | );
245 | }
246 | if (wrappedSolAccount2) {
247 | transaction.add(
248 | closeAccount({
249 | source: wrappedSolAccount2,
250 | destination: owner,
251 | owner
252 | })
253 | );
254 | }
255 |
256 | return await sendTransaction(connection, wallet, transaction, signers);
257 | }
258 |
259 | export function getSwapOutAmount(
260 | poolInfo: any,
261 | fromCoinMint: string,
262 | toCoinMint: string,
263 | amount: string,
264 | slippage: number
265 | ) {
266 | const { coin, pc, fees } = poolInfo;
267 | const { swapFeeNumerator, swapFeeDenominator } = fees;
268 |
269 | if (fromCoinMint === TOKENS.WSOL.mintAddress)
270 | fromCoinMint = NATIVE_SOL.mintAddress;
271 | if (toCoinMint === TOKENS.WSOL.mintAddress)
272 | toCoinMint = NATIVE_SOL.mintAddress;
273 |
274 | if (fromCoinMint === coin.mintAddress && toCoinMint === pc.mintAddress) {
275 | // coin2pc
276 | const fromAmount = new TokenAmount(amount, coin.decimals, false);
277 | const fromAmountWithFee = fromAmount.wei
278 | .multipliedBy(swapFeeDenominator - swapFeeNumerator)
279 | .dividedBy(swapFeeDenominator);
280 | const denominator = coin.balance.wei.plus(fromAmountWithFee);
281 | const amountOut = pc.balance.wei
282 | .multipliedBy(fromAmountWithFee)
283 | .dividedBy(denominator);
284 | const amountOutWithSlippage = amountOut.dividedBy(1 + slippage / 100);
285 |
286 | const outBalance = pc.balance.wei.minus(amountOut);
287 | const beforePrice = new TokenAmount(
288 | parseFloat(new TokenAmount(pc.balance.wei, pc.decimals).fixed()) /
289 | parseFloat(new TokenAmount(coin.balance.wei, coin.decimals).fixed()),
290 | pc.decimals,
291 | false
292 | );
293 | const afterPrice = new TokenAmount(
294 | parseFloat(new TokenAmount(outBalance, pc.decimals).fixed()) /
295 | parseFloat(new TokenAmount(denominator, coin.decimals).fixed()),
296 | pc.decimals,
297 | false
298 | );
299 | const priceImpact =
300 | Math.abs(
301 | (parseFloat(beforePrice.fixed()) - parseFloat(afterPrice.fixed())) /
302 | parseFloat(beforePrice.fixed())
303 | ) * 100;
304 |
305 | return {
306 | amountIn: fromAmount,
307 | amountOut: new TokenAmount(amountOut, pc.decimals),
308 | amountOutWithSlippage: new TokenAmount(
309 | amountOutWithSlippage,
310 | pc.decimals
311 | ),
312 | priceImpact
313 | };
314 | } else {
315 | // pc2coin
316 | const fromAmount = new TokenAmount(amount, pc.decimals, false);
317 | const fromAmountWithFee = fromAmount.wei
318 | .multipliedBy(swapFeeDenominator - swapFeeNumerator)
319 | .dividedBy(swapFeeDenominator);
320 |
321 | const denominator = pc.balance.wei.plus(fromAmountWithFee);
322 | const amountOut = coin.balance.wei
323 | .multipliedBy(fromAmountWithFee)
324 | .dividedBy(denominator);
325 | const amountOutWithSlippage = amountOut.dividedBy(1 + slippage / 100);
326 |
327 | const outBalance = coin.balance.wei.minus(amountOut);
328 |
329 | const beforePrice = new TokenAmount(
330 | parseFloat(new TokenAmount(pc.balance.wei, pc.decimals).fixed()) /
331 | parseFloat(new TokenAmount(coin.balance.wei, coin.decimals).fixed()),
332 | pc.decimals,
333 | false
334 | );
335 | const afterPrice = new TokenAmount(
336 | parseFloat(new TokenAmount(denominator, pc.decimals).fixed()) /
337 | parseFloat(new TokenAmount(outBalance, coin.decimals).fixed()),
338 | pc.decimals,
339 | false
340 | );
341 | const priceImpact =
342 | Math.abs(
343 | (parseFloat(afterPrice.fixed()) - parseFloat(beforePrice.fixed())) /
344 | parseFloat(beforePrice.fixed())
345 | ) * 100;
346 | return {
347 | amountIn: fromAmount,
348 | amountOut: new TokenAmount(amountOut, coin.decimals),
349 | amountOutWithSlippage: new TokenAmount(
350 | amountOutWithSlippage,
351 | coin.decimals
352 | ),
353 | priceImpact
354 | };
355 | }
356 | }
357 |
358 | export async function setupPools(conn: Connection) {
359 | let ammAll: {
360 | publicKey: PublicKey;
361 | accountInfo: AccountInfo;
362 | }[] = [];
363 | let marketAll: {
364 | publicKey: PublicKey;
365 | accountInfo: AccountInfo;
366 | }[] = [];
367 |
368 | await Promise.all([
369 | await (async () => {
370 | ammAll = await getFilteredProgramAccountsAmmOrMarketCache(
371 | "amm",
372 | conn,
373 | new PublicKey(LIQUIDITY_POOL_PROGRAM_ID_V4),
374 | [
375 | {
376 | dataSize: AMM_INFO_LAYOUT_V4.span
377 | }
378 | ]
379 | );
380 | })(),
381 | await (async () => {
382 | marketAll = await getFilteredProgramAccountsAmmOrMarketCache(
383 | "market",
384 | conn,
385 | new PublicKey(SERUM_PROGRAM_ID_V3),
386 | [
387 | {
388 | dataSize: MARKET_STATE_LAYOUT_V2.span
389 | }
390 | ]
391 | );
392 | })()
393 | ]);
394 | const marketToLayout: { [name: string]: any } = {};
395 | marketAll.forEach(item => {
396 | marketToLayout[item.publicKey.toString()] = MARKET_STATE_LAYOUT_V2.decode(
397 | item.accountInfo.data
398 | );
399 | });
400 | const lpMintAddressList: string[] = [];
401 | ammAll.forEach(item => {
402 | const ammLayout = AMM_INFO_LAYOUT_V4.decode(
403 | Buffer.from(item.accountInfo.data)
404 | );
405 | console.log("\n",ammLayout.serumMarket.toString()) // Serum Dex Program v3
406 | console.log(ammLayout.coinMintAddress.toString()) // coin Mint Address
407 | console.log(ammLayout.pcMintAddress.toString()) // Pair Coin Mint Address
408 | console.log(ammLayout.lpMintAddress.toString(), "\n") // LP Coin Mint Address
409 |
410 | if (
411 | ammLayout.pcMintAddress.toString() === ammLayout.serumMarket.toString() || /** How could the pair coin mint be = serum dex program?? */
412 | ammLayout.lpMintAddress.toString() === "11111111111111111111111111111111" /** How could the lp coin mint be = system program?? */
413 | ) {
414 | return;
415 | }
416 | lpMintAddressList.push(ammLayout.lpMintAddress.toString());
417 | });
418 | const lpMintListDecimls = await getLpMintListDecimals(
419 | conn,
420 | lpMintAddressList
421 | );
422 | const tokenMintData: { [mintAddress: string]: TokenInfo } = {};
423 | for (const itemToken of Object.values(TOKENS)) {
424 | tokenMintData[itemToken.mintAddress] = itemToken;
425 | }
426 | /**@TODO combine with prev ammAll.forEach section */
427 | for (let indexAmmInfo = 0; indexAmmInfo < ammAll.length; indexAmmInfo += 1) {
428 | const ammInfo = AMM_INFO_LAYOUT_V4.decode(
429 | Buffer.from(ammAll[indexAmmInfo].accountInfo.data)
430 | );
431 | if (
432 | !Object.keys(lpMintListDecimls).includes(
433 | ammInfo.lpMintAddress.toString()
434 | ) ||
435 | ammInfo.pcMintAddress.toString() === ammInfo.serumMarket.toString() ||
436 | ammInfo.lpMintAddress.toString() === "11111111111111111111111111111111" ||
437 | !Object.keys(marketToLayout).includes(ammInfo.serumMarket.toString())
438 | ) {
439 | continue;
440 | }
441 | const fromCoin =
442 | ammInfo.coinMintAddress.toString() === TOKENS.WSOL.mintAddress
443 | ? NATIVE_SOL.mintAddress
444 | : ammInfo.coinMintAddress.toString();
445 | const toCoin =
446 | ammInfo.pcMintAddress.toString() === TOKENS.WSOL.mintAddress
447 | ? NATIVE_SOL.mintAddress
448 | : ammInfo.pcMintAddress.toString();
449 | let coin = tokenMintData[fromCoin];
450 | if (!coin && fromCoin !== NATIVE_SOL.mintAddress) {
451 | TOKENS[`unknow-${ammInfo.coinMintAddress.toString()}`] = {
452 | symbol: "unknown",
453 | name: "unknown",
454 | mintAddress: ammInfo.coinMintAddress.toString(),
455 | decimals: getBigNumber(ammInfo.coinDecimals),
456 | cache: true,
457 | tags: []
458 | };
459 | coin = TOKENS[`unknow-${ammInfo.coinMintAddress.toString()}`];
460 | tokenMintData[ammInfo.coinMintAddress.toString()] = coin;
461 | } else if (fromCoin === NATIVE_SOL.mintAddress) {
462 | coin = NATIVE_SOL;
463 | }
464 | if (!coin.tags.includes("unofficial")) {
465 | coin.tags.push("unofficial");
466 | }
467 |
468 | let pc = tokenMintData[toCoin];
469 | if (!pc && toCoin !== NATIVE_SOL.mintAddress) {
470 | TOKENS[`unknow-${ammInfo.pcMintAddress.toString()}`] = {
471 | symbol: "unknown",
472 | name: "unknown",
473 | mintAddress: ammInfo.pcMintAddress.toString(),
474 | decimals: getBigNumber(ammInfo.pcDecimals),
475 | cache: true,
476 | tags: []
477 | };
478 | pc = TOKENS[`unknow-${ammInfo.pcMintAddress.toString()}`];
479 | tokenMintData[ammInfo.pcMintAddress.toString()] = pc;
480 | } else if (toCoin === NATIVE_SOL.mintAddress) {
481 | pc = NATIVE_SOL;
482 | }
483 | if (!pc.tags.includes("unofficial")) {
484 | pc.tags.push("unofficial");
485 | }
486 |
487 | if (coin.mintAddress === TOKENS.WSOL.mintAddress) {
488 | coin.symbol = "SOL";
489 | coin.name = "SOL";
490 | coin.mintAddress = "11111111111111111111111111111111";
491 | }
492 | if (pc.mintAddress === TOKENS.WSOL.mintAddress) {
493 | pc.symbol = "SOL";
494 | pc.name = "SOL";
495 | pc.mintAddress = "11111111111111111111111111111111";
496 | }
497 | const lp = Object.values(LP_TOKENS).find(
498 | item => item.mintAddress === ammInfo.lpMintAddress
499 | ) ?? {
500 | symbol: `${coin.symbol}-${pc.symbol}`,
501 | name: `${coin.symbol}-${pc.symbol}`,
502 | coin,
503 | pc,
504 | mintAddress: ammInfo.lpMintAddress.toString(),
505 | decimals: lpMintListDecimls[ammInfo.lpMintAddress]
506 | };
507 |
508 | const { publicKey } = await createAmmAuthority(
509 | new PublicKey(LIQUIDITY_POOL_PROGRAM_ID_V4)
510 | );
511 |
512 | const market = marketToLayout[ammInfo.serumMarket];
513 |
514 | const serumVaultSigner = await PublicKey.createProgramAddress(
515 | [
516 | ammInfo.serumMarket.toBuffer(),
517 | market.vaultSignerNonce.toArrayLike(Buffer, "le", 8)
518 | ],
519 | new PublicKey(SERUM_PROGRAM_ID_V3)
520 | );
521 |
522 | const itemLiquidity: LiquidityPoolInfo = {
523 | name: `${coin.symbol}-${pc.symbol}`,
524 | coin,
525 | pc,
526 | lp,
527 | version: 4,
528 | programId: LIQUIDITY_POOL_PROGRAM_ID_V4,
529 | ammId: ammAll[indexAmmInfo].publicKey.toString(),
530 | ammAuthority: publicKey.toString(),
531 | ammOpenOrders: ammInfo.ammOpenOrders.toString(),
532 | ammTargetOrders: ammInfo.ammTargetOrders.toString(),
533 | ammQuantities: NATIVE_SOL.mintAddress,
534 | poolCoinTokenAccount: ammInfo.poolCoinTokenAccount.toString(),
535 | poolPcTokenAccount: ammInfo.poolPcTokenAccount.toString(),
536 | poolWithdrawQueue: ammInfo.poolWithdrawQueue.toString(),
537 | poolTempLpTokenAccount: ammInfo.poolTempLpTokenAccount.toString(),
538 | serumProgramId: SERUM_PROGRAM_ID_V3,
539 | serumMarket: ammInfo.serumMarket.toString(),
540 | serumBids: market.bids.toString(),
541 | serumAsks: market.asks.toString(),
542 | serumEventQueue: market.eventQueue.toString(),
543 | serumCoinVaultAccount: market.baseVault.toString(),
544 | serumPcVaultAccount: market.quoteVault.toString(),
545 | serumVaultSigner: serumVaultSigner.toString(),
546 | official: false
547 | };
548 | if (!LIQUIDITY_POOLS.find(item => item.ammId === itemLiquidity.ammId)) {
549 | LIQUIDITY_POOLS.push(itemLiquidity);
550 | } else {
551 | for (
552 | let itemIndex = 0;
553 | itemIndex < LIQUIDITY_POOLS.length;
554 | itemIndex += 1
555 | ) {
556 | if (
557 | LIQUIDITY_POOLS[itemIndex].ammId === itemLiquidity.ammId &&
558 | LIQUIDITY_POOLS[itemIndex].name !== itemLiquidity.name &&
559 | !LIQUIDITY_POOLS[itemIndex].official
560 | ) {
561 | LIQUIDITY_POOLS[itemIndex] = itemLiquidity;
562 | }
563 | }
564 | }
565 | }
566 |
567 | const liquidityPools = {} as any;
568 | const publicKeys = [] as any;
569 |
570 | LIQUIDITY_POOLS.forEach(pool => {
571 | const {
572 | poolCoinTokenAccount,
573 | poolPcTokenAccount,
574 | ammOpenOrders,
575 | ammId,
576 | coin,
577 | pc,
578 | lp
579 | } = pool;
580 |
581 | publicKeys.push(
582 | new PublicKey(poolCoinTokenAccount),
583 | new PublicKey(poolPcTokenAccount),
584 | new PublicKey(ammOpenOrders),
585 | new PublicKey(ammId),
586 | new PublicKey(lp.mintAddress)
587 | );
588 |
589 | const poolInfo = JSON.parse(JSON.stringify(pool));
590 | poolInfo.coin.balance = new TokenAmount(0, coin.decimals);
591 | poolInfo.pc.balance = new TokenAmount(0, pc.decimals);
592 |
593 | liquidityPools[lp.mintAddress] = poolInfo;
594 | });
595 |
596 | const multipleInfo = await getMultipleAccounts(conn, publicKeys, "confirmed");
597 | multipleInfo.forEach(info => {
598 | if (info) {
599 | const address = info.publicKey.toBase58();
600 | const data = Buffer.from(info.account.data);
601 |
602 | const { key, lpMintAddress, version } = getAddressForWhat(address);
603 |
604 | if (key && lpMintAddress) {
605 | const poolInfo = liquidityPools[lpMintAddress];
606 |
607 | switch (key) {
608 | case "poolCoinTokenAccount": {
609 | const parsed = ACCOUNT_LAYOUT.decode(data);
610 | // quick fix: Number can only safely store up to 53 bits
611 | poolInfo.coin.balance.wei = poolInfo.coin.balance.wei.plus(
612 | getBigNumber(parsed.amount)
613 | );
614 |
615 | break;
616 | }
617 | case "poolPcTokenAccount": {
618 | const parsed = ACCOUNT_LAYOUT.decode(data);
619 |
620 | poolInfo.pc.balance.wei = poolInfo.pc.balance.wei.plus(
621 | getBigNumber(parsed.amount)
622 | );
623 |
624 | break;
625 | }
626 | case "ammOpenOrders": {
627 | const OPEN_ORDERS_LAYOUT = OpenOrders.getLayout(
628 | new PublicKey(poolInfo.serumProgramId)
629 | );
630 | const parsed = OPEN_ORDERS_LAYOUT.decode(data);
631 |
632 | const { baseTokenTotal, quoteTokenTotal } = parsed;
633 | poolInfo.coin.balance.wei = poolInfo.coin.balance.wei.plus(
634 | getBigNumber(baseTokenTotal)
635 | );
636 | poolInfo.pc.balance.wei = poolInfo.pc.balance.wei.plus(
637 | getBigNumber(quoteTokenTotal)
638 | );
639 |
640 | break;
641 | }
642 | case "ammId": {
643 | let parsed;
644 | if (version === 2) {
645 | parsed = AMM_INFO_LAYOUT.decode(data);
646 | } else if (version === 3) {
647 | parsed = AMM_INFO_LAYOUT_V3.decode(data);
648 | } else {
649 | if (version === 5) {
650 | parsed = AMM_INFO_LAYOUT_STABLE.decode(data);
651 | poolInfo.currentK = getBigNumber(parsed.currentK);
652 | } else {
653 | parsed = AMM_INFO_LAYOUT_V4.decode(data);
654 | if (getBigNumber(parsed.status) === 7) {
655 | poolInfo.poolOpenTime = getBigNumber(parsed.poolOpenTime);
656 | }
657 | }
658 |
659 | const { swapFeeNumerator, swapFeeDenominator } = parsed;
660 | poolInfo.fees = {
661 | swapFeeNumerator: getBigNumber(swapFeeNumerator),
662 | swapFeeDenominator: getBigNumber(swapFeeDenominator)
663 | };
664 | }
665 |
666 | const { status, needTakePnlCoin, needTakePnlPc } = parsed;
667 | poolInfo.status = getBigNumber(status);
668 | poolInfo.coin.balance.wei = poolInfo.coin.balance.wei.minus(
669 | getBigNumber(needTakePnlCoin)
670 | );
671 | poolInfo.pc.balance.wei = poolInfo.pc.balance.wei.minus(
672 | getBigNumber(needTakePnlPc)
673 | );
674 |
675 | break;
676 | }
677 | // getLpSupply
678 | case "lpMintAddress": {
679 | const parsed = MINT_LAYOUT.decode(data);
680 |
681 | poolInfo.lp.totalSupply = new TokenAmount(
682 | getBigNumber(parsed.supply),
683 | poolInfo.lp.decimals
684 | );
685 |
686 | break;
687 | }
688 | }
689 | }
690 | }
691 | });
692 | return liquidityPools;
693 | }
694 |
--------------------------------------------------------------------------------
/utils/tokenList.ts:
--------------------------------------------------------------------------------
1 | import { TokenListProvider } from "@solana/spl-token-registry";
2 |
3 | const SPLTokenRegistrySource = async () => {
4 | let tokens = await new TokenListProvider().resolve()
5 | let tokenList = tokens.filterByClusterSlug("mainnet-beta").getList()
6 | return tokenList.sort((a: any, b: any) =>
7 | a.symbol < b.symbol ? -1 : a.symbol > b.symbol ? 1 : 0
8 | )
9 | };
10 |
11 | export default SPLTokenRegistrySource;
12 |
--------------------------------------------------------------------------------
/utils/tokens.ts:
--------------------------------------------------------------------------------
1 | import { cloneDeep } from 'lodash-es';
2 |
3 | /**
4 | * Get token use symbol
5 |
6 | * @param {string} symbol
7 |
8 | * @returns {TokenInfo | null} tokenInfo
9 | */
10 |
11 | export function getTokenBySymbol(symbol: string): TokenInfo | null {
12 | if (symbol === 'SOL') {
13 | return cloneDeep(NATIVE_SOL)
14 | }
15 |
16 | let token = cloneDeep(TOKENS[symbol])
17 |
18 | if (!token) {
19 | token = null
20 | }
21 |
22 | return token
23 | }
24 |
25 | /**
26 | * Get token use mint addresses
27 |
28 | * @param {string} mintAddress
29 |
30 | * @returns {TokenInfo | null} tokenInfo
31 | */
32 | export function getTokenByMintAddress(mintAddress: string): TokenInfo | null {
33 | if (mintAddress === NATIVE_SOL.mintAddress) {
34 | return cloneDeep(NATIVE_SOL)
35 | }
36 | const token = Object.values(TOKENS).find((item) => item.mintAddress === mintAddress)
37 | return token ? cloneDeep(token) : null
38 | }
39 |
40 | export function getTokenSymbolByMint(mint: string) {
41 | if (mint === NATIVE_SOL.mintAddress) {
42 | return NATIVE_SOL.symbol
43 | }
44 |
45 | const token = Object.values({ ...TOKENS, ...LP_TOKENS }).find((item) => item.mintAddress === mint)
46 |
47 | if (token) {
48 | return token.symbol
49 | }
50 | return 'UNKNOWN'
51 | }
52 |
53 | export interface Tokens {
54 | [key: string]: any
55 | [index: number]: any
56 | }
57 |
58 | export const TOKENS_TAGS: { [key: string]: { mustShow: boolean; show: boolean; outName: string } } = {
59 | raydium: { mustShow: true, show: true, outName: 'Raydium Default List' },
60 | userAdd: { mustShow: true, show: true, outName: 'User Added Tokens' },
61 | solana: { mustShow: false, show: false, outName: 'Solana Token List' },
62 | unofficial: { mustShow: false, show: false, outName: 'Permissionless Pool Tokens' }
63 | }
64 |
65 | export const NATIVE_SOL: TokenInfo = {
66 | symbol: 'SOL',
67 | name: 'Native Solana',
68 | mintAddress: '11111111111111111111111111111111',
69 | decimals: 9,
70 | tags: ['raydium']
71 | }
72 |
73 | export const TOKENS: Tokens = {
74 | SOL: {
75 | symbol: 'SOL',
76 | name: 'Native Solana',
77 | mintAddress: '11111111111111111111111111111111',
78 | address: '11111111111111111111111111111111',
79 | decimals: 9,
80 | tags: ['raydium']
81 | },
82 | WSOL: {
83 | symbol: 'WSOL',
84 | name: 'Wrapped Solana',
85 | mintAddress: 'So11111111111111111111111111111111111111112',
86 | decimals: 9,
87 | referrer: 'HTcarLHe7WRxBQCWvhVB8AP56pnEtJUV2jDGvcpY3xo5',
88 | tags: ['raydium']
89 | },
90 | BTC: {
91 | symbol: 'BTC',
92 | name: 'Wrapped Bitcoin',
93 | mintAddress: '9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E',
94 | decimals: 6,
95 | referrer: 'GZpS8cY8Nt8HuqxzJh6PXTdSxc38vFUjBmi7eEUkkQtG',
96 | tags: ['raydium']
97 | },
98 | ETH: {
99 | symbol: 'ETH',
100 | name: 'Wrapped Ethereum',
101 | mintAddress: '2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk',
102 | decimals: 6,
103 | referrer: 'CXPTcSxxh4AT38gtv3SPbLS7oZVgXzLbMb83o4ziXjjN',
104 | tags: ['raydium']
105 | },
106 | USDT: {
107 | symbol: 'USDT',
108 | name: 'USDT',
109 | mintAddress: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
110 | decimals: 6,
111 | referrer: '8DwwDNagph8SdwMUdcXS5L9YAyutTyDJmK6cTKrmNFk3',
112 | tags: ['raydium']
113 | },
114 | WUSDT: {
115 | symbol: 'WUSDT',
116 | name: 'Wrapped USDT',
117 | mintAddress: 'BQcdHdAQW1hczDbBi9hiegXAR7A98Q9jx3X3iBBBDiq4',
118 | decimals: 6,
119 | referrer: 'CA98hYunCLKgBuD6N8MJSgq1GbW9CXdksLf5mw736tS3',
120 | tags: ['raydium']
121 | },
122 | USDC: {
123 | symbol: 'USDC',
124 | name: 'USDC',
125 | mintAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
126 | decimals: 6,
127 | referrer: '92vdtNjEg6Zth3UU1MgPgTVFjSEzTHx66aCdqWdcRkrg',
128 | tags: ['raydium']
129 | },
130 | WUSDC: {
131 | symbol: 'WUSDC',
132 | name: 'Wrapped USDC',
133 | mintAddress: 'BXXkv6z8ykpG1yuvUDPgh732wzVHB69RnB9YgSYh3itW',
134 | decimals: 6,
135 | tags: ['raydium']
136 | },
137 | YFI: {
138 | symbol: 'YFI',
139 | name: 'Wrapped YFI',
140 | mintAddress: '3JSf5tPeuscJGtaCp5giEiDhv51gQ4v3zWg8DGgyLfAB',
141 | decimals: 6,
142 | referrer: 'DZjgzKfYzZBBSTo5vytMYvGdNF933DvuX8TftDMrThrb',
143 | tags: ['raydium']
144 | },
145 | LINK: {
146 | symbol: 'LINK',
147 | name: 'Wrapped Chainlink',
148 | mintAddress: 'CWE8jPTUYhdCTZYWPTe1o5DFqfdjzWKc9WKz6rSjQUdG',
149 | decimals: 6,
150 | referrer: 'DRSKKsYZaPEFkRgGywo7KWBGZikf71R9aDr8tjtpr41V',
151 | tags: ['raydium']
152 | },
153 | XRP: {
154 | symbol: 'XRP',
155 | name: 'Wrapped XRP',
156 | mintAddress: 'Ga2AXHpfAF6mv2ekZwcsJFqu7wB4NV331qNH7fW9Nst8',
157 | decimals: 6,
158 | referrer: '6NeHPXG142tAE2Ej3gHgT2N66i1KH6PFR6PBZw6RyrwH',
159 | tags: ['raydium']
160 | },
161 | SUSHI: {
162 | symbol: 'SUSHI',
163 | name: 'Wrapped SUSHI',
164 | mintAddress: 'AR1Mtgh7zAtxuxGd2XPovXPVjcSdY3i4rQYisNadjfKy',
165 | decimals: 6,
166 | referrer: '59QxHeHgb28tDc3gStnrW8FNKC9qWuRmRZHBaAqCerJX',
167 | tags: ['raydium']
168 | },
169 | ALEPH: {
170 | symbol: 'ALEPH',
171 | name: 'Wrapped ALEPH',
172 | mintAddress: 'CsZ5LZkDS7h9TDKjrbL7VAwQZ9nsRu8vJLhRYfmGaN8K',
173 | decimals: 6,
174 | referrer: '8FKAKrenJMDd7V6cxnM5BsymHTjqxgodtHbLwZReMnWW',
175 | tags: ['raydium']
176 | },
177 | SXP: {
178 | symbol: 'SXP',
179 | name: 'Wrapped SXP',
180 | mintAddress: 'SF3oTvfWzEP3DTwGSvUXRrGTvr75pdZNnBLAH9bzMuX',
181 | decimals: 6,
182 | referrer: '97Vyotr284UM2Fyq9gbfQ3azMYtgf7cjnsf8pN1PFfY9',
183 | tags: ['raydium']
184 | },
185 | HGET: {
186 | symbol: 'HGET',
187 | name: 'Wrapped HGET',
188 | mintAddress: 'BtZQfWqDGbk9Wf2rXEiWyQBdBY1etnUUn6zEphvVS7yN',
189 | decimals: 6,
190 | referrer: 'AGY2wy1ANzLM2jJLSkVxPUYAY5iAYXYsLMQkoQsAhucj',
191 | tags: ['raydium']
192 | },
193 | CREAM: {
194 | symbol: 'CREAM',
195 | name: 'Wrapped CREAM',
196 | mintAddress: '5Fu5UUgbjpUvdBveb3a1JTNirL8rXtiYeSMWvKjtUNQv',
197 | decimals: 6,
198 | referrer: '7WPzEiozJ69MQe8bfbss1t2unR6bHR4S7FimiUVRgu7P',
199 | tags: ['raydium']
200 | },
201 | UNI: {
202 | symbol: 'UNI',
203 | name: 'Wrapped UNI',
204 | mintAddress: 'DEhAasscXF4kEGxFgJ3bq4PpVGp5wyUxMRvn6TzGVHaw',
205 | decimals: 6,
206 | referrer: '4ntxDv95ajBbXfZyGy3UhcQDx8xmH1yJ6eKvuNNH466x',
207 | tags: ['raydium']
208 | },
209 | SRM: {
210 | symbol: 'SRM',
211 | name: 'Serum',
212 | mintAddress: 'SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt',
213 | decimals: 6,
214 | referrer: 'HYxa4Ea1dz7ya17Cx18rEGUA1WbCvKjXjFKrnu8CwugH',
215 | tags: ['raydium']
216 | },
217 | FTT: {
218 | symbol: 'FTT',
219 | name: 'Wrapped FTT',
220 | mintAddress: 'AGFEad2et2ZJif9jaGpdMixQqvW5i81aBdvKe7PHNfz3',
221 | decimals: 6,
222 | referrer: 'CafpgSh8KGL2GPTjdXfctD3vXngNZDJ3Q92FTfV71Hmt',
223 | tags: ['raydium']
224 | },
225 | MSRM: {
226 | symbol: 'MSRM',
227 | name: 'MegaSerum',
228 | mintAddress: 'MSRMcoVyrFxnSgo5uXwone5SKcGhT1KEJMFEkMEWf9L',
229 | decimals: 0,
230 | referrer: 'Ge5q9x8gDUNYqqLA1MdnCzWNJGsbj3M15Yxse2cDbw9z',
231 | tags: ['raydium']
232 | },
233 | TOMO: {
234 | symbol: 'TOMO',
235 | name: 'Wrapped TOMO',
236 | mintAddress: 'GXMvfY2jpQctDqZ9RoU3oWPhufKiCcFEfchvYumtX7jd',
237 | decimals: 6,
238 | referrer: '9fexfN3eZomF5gfenG5L9ydbKRQkPhq6x74rb5iLrvXP',
239 | tags: ['raydium']
240 | },
241 | KARMA: {
242 | symbol: 'KARMA',
243 | name: 'Wrapped KARMA',
244 | mintAddress: 'EcqExpGNFBve2i1cMJUTR4bPXj4ZoqmDD2rTkeCcaTFX',
245 | decimals: 4,
246 | tags: ['raydium']
247 | },
248 | LUA: {
249 | symbol: 'LUA',
250 | name: 'Wrapped LUA',
251 | mintAddress: 'EqWCKXfs3x47uVosDpTRgFniThL9Y8iCztJaapxbEaVX',
252 | decimals: 6,
253 | referrer: 'HuZwNApjVFuFSDgrwZA8GP2JD7WMby4qt6rkWDnaMo7j',
254 | tags: ['raydium']
255 | },
256 | MATH: {
257 | symbol: 'MATH',
258 | name: 'Wrapped MATH',
259 | mintAddress: 'GeDS162t9yGJuLEHPWXXGrb1zwkzinCgRwnT8vHYjKza',
260 | decimals: 6,
261 | referrer: 'C9K1M8sJX8WMdsnFT7DuzdiHHunEj79EsLuz4DixQYGm',
262 | tags: ['raydium']
263 | },
264 | KEEP: {
265 | symbol: 'KEEP',
266 | name: 'Wrapped KEEP',
267 | mintAddress: 'GUohe4DJUA5FKPWo3joiPgsB7yzer7LpDmt1Vhzy3Zht',
268 | decimals: 6,
269 | tags: ['raydium']
270 | },
271 | SWAG: {
272 | symbol: 'SWAG',
273 | name: 'Wrapped SWAG',
274 | mintAddress: '9F9fNTT6qwjsu4X4yWYKZpsbw5qT7o6yR2i57JF2jagy',
275 | decimals: 6,
276 | tags: ['raydium']
277 | },
278 | FIDA: {
279 | symbol: 'FIDA',
280 | name: 'Bonfida',
281 | mintAddress: 'EchesyfXePKdLtoiZSL8pBe8Myagyy8ZRqsACNCFGnvp',
282 | decimals: 6,
283 | referrer: 'AeAsG75UmyPDB271c6NHonHxXAPXfkvhcf2xjfJhReS8',
284 | tags: ['raydium']
285 | },
286 | KIN: {
287 | symbol: 'KIN',
288 | name: 'KIN',
289 | mintAddress: 'kinXdEcpDQeHPEuQnqmUgtYykqKGVFq6CeVX5iAHJq6',
290 | decimals: 5,
291 | referrer: 'AevFXmApVxN2yk1iemSxXc6Wy7Z1udUEfST11kuYKmr9',
292 | tags: ['raydium']
293 | },
294 | MAPS: {
295 | symbol: 'MAPS',
296 | name: 'MAPS',
297 | mintAddress: 'MAPS41MDahZ9QdKXhVa4dWB9RuyfV4XqhyAZ8XcYepb',
298 | decimals: 6,
299 | tags: ['raydium']
300 | },
301 | OXY: {
302 | symbol: 'OXY',
303 | name: 'OXY',
304 | mintAddress: 'z3dn17yLaGMKffVogeFHQ9zWVcXgqgf3PQnDsNs2g6M',
305 | decimals: 6,
306 | tags: ['raydium']
307 | },
308 | RAY: {
309 | symbol: 'RAY',
310 | name: 'Raydium',
311 | mintAddress: '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R',
312 | decimals: 6,
313 | referrer: '33XpMmMQRf6tSPpmYyzpwU4uXpZHkFwCZsusD9dMYkjy',
314 | tags: ['raydium']
315 | },
316 | xCOPE: {
317 | symbol: 'xCOPE',
318 | name: 'xCOPE',
319 | mintAddress: '3K6rftdAaQYMPunrtNRHgnK2UAtjm2JwyT2oCiTDouYE',
320 | decimals: 0,
321 | referrer: '8DTehuES4tfnd2SrqcjN52XofxWXGjiLZRgM12U9pB6f',
322 | tags: ['raydium']
323 | },
324 | COPE: {
325 | symbol: 'COPE',
326 | name: 'COPE',
327 | mintAddress: '8HGyAAB1yoM1ttS7pXjHMa3dukTFGQggnFFH3hJZgzQh',
328 | decimals: 6,
329 | referrer: 'G7UYwWhkmgeL57SUKFF45K663V9TdXZw6Ho6ZLQ7p4p',
330 | tags: ['raydium']
331 | },
332 | STEP: {
333 | symbol: 'STEP',
334 | name: 'STEP',
335 | mintAddress: 'StepAscQoEioFxxWGnh2sLBDFp9d8rvKz2Yp39iDpyT',
336 | decimals: 9,
337 | referrer: 'EFQVX1S6dFroDDhJDAnMTX4fCfjt4fJXHdk1eEtJ2uRY',
338 | tags: ['raydium']
339 | },
340 | MEDIA: {
341 | symbol: 'MEDIA',
342 | name: 'MEDIA',
343 | mintAddress: 'ETAtLmCmsoiEEKfNrHKJ2kYy3MoABhU6NQvpSfij5tDs',
344 | decimals: 6,
345 | referrer: 'AYnaG3AidNWFzjq9U3BJSsQ9DShE8g7FszriBDtRFvsx',
346 |
347 | details:
348 | 'Media Network is a new protocol that bypasses traditional CDN providers’ centralized approach for a self-governed and open source solution where everyone can participate. Media Network creates a distributed bandwidth market that enables service providers such as media platforms to hire resources from the network and dynamically come and go as the demand for last-mile data delivery shifts. It allows anyone to organically serve content without introducing any trust assumptions or pre-authentication requirements. Participants earn MEDIA rewards for their bandwidth contributions, a fixed supply SPL token minted on Solana’s Blockchain.',
349 | docs: {
350 | website: 'https://media.network/',
351 | whitepaper: 'https://media.network/whitepaper.pdf'
352 | },
353 | socials: {
354 | Twitter: 'https://twitter.com/Media_FDN',
355 | Telegram: 'https://t.me/Media_FDN',
356 | Medium: 'https://mediafoundation.medium.com/'
357 | },
358 | tags: ['raydium']
359 | },
360 | ROPE: {
361 | symbol: 'ROPE',
362 | name: 'ROPE',
363 | mintAddress: '8PMHT4swUMtBzgHnh5U564N5sjPSiUz2cjEQzFnnP1Fo',
364 | decimals: 9,
365 | referrer: '5sGVVniBSPLTwRHDETShovq7STRH2rJwbvdvvH3NcVTF',
366 | tags: ['raydium']
367 | },
368 | MER: {
369 | symbol: 'MER',
370 | name: 'Mercurial',
371 | mintAddress: 'MERt85fc5boKw3BW1eYdxonEuJNvXbiMbs6hvheau5K',
372 | decimals: 6,
373 | referrer: '36F4ryvqaNW2yKQsAry4ZHCZ3j7tz3gtEz7NEwv7pSRu',
374 |
375 | details:
376 | 'Mercurial Finance\nMercurial is building DeFi’s first dynamic vaults for stable assets on Solana, providing the technical tools for users to easily deposit, swap and mint stable assets.\n\nInnovations\nMercurial will be introducing several key new technical innovations, including on-chain algorithms to regulate the flow of assets and dynamic fees that tap on the market and price data to assist LPs in optimizing performance. We will also be developing a unique pricing curve that will be the first to combine high efficiency, multi-token support, and generalizability for all types of token sets.\n\nMaximizing Capital Utlilization\nMercurial vaults will dynamically utilize assets for a wide range of use cases, like low slippage swaps, lending, flash loans, and external third-party decentralized protocols. To increase pegged assets availability on Solana, we will allow the creation of synthetics, like mUSD or mBTC, which can be added to our vaults to improve liquidity for other stables and facilitate interaction with other third-party decentralized protocols.\n\nStarting with a vault for the most common stables, for example, USDC, USDT, wUSDC, and wDAI, we will be facilitating low slippage swaps with dynamic fees. Features will be added as key technical and ecosystem pieces become available on Solana, i.e. inter-program composability, price oracles, etc.\n\nMER\nThe MER token will be used to accrue value for the holder via fees from swaps, commission from yield farms, and as collateral for synthetic stables like mUSD. MER will also be intrinsically linked to the governance and growth of Mercurial, playing a crucial role in regulating the system across governance, insurance, and bootstrapping.',
377 | docs: {
378 | website: 'https://www.mercurial.finance/',
379 | whitepaper: 'https://www.mercurial.finance/Mercurial-Lite-Paper-v1.pdf'
380 | },
381 | socials: {
382 | Twitter: 'https://twitter.com/MercurialFi',
383 | Telegram: 'https://t.me/MercurialFi',
384 | Medium: 'https://mercurialfi.medium.com/'
385 | },
386 | tags: ['raydium']
387 | },
388 | TULIP: {
389 | symbol: 'TULIP',
390 | name: 'TULIP',
391 | mintAddress: 'TuLipcqtGVXP9XR62wM8WWCm6a9vhLs7T1uoWBk6FDs',
392 | decimals: 6,
393 | referrer: 'Bcw1TvX8jUj6CtY2a7GU2THeYVAudvmT8yzRypVMVsSH',
394 | tags: ['raydium']
395 | },
396 | SNY: {
397 | symbol: 'SNY',
398 | name: 'SNY',
399 | mintAddress: '4dmKkXNHdgYsXqBHCuMikNQWwVomZURhYvkkX5c4pQ7y',
400 | decimals: 6,
401 | referrer: 'G7gyaTNn2hgjF67SWs4Ee9PEaFU2xadhtXL8HmkJ2cNL',
402 |
403 | detailLink: 'https://raydium.medium.com/synthetify-launching-on-acceleraytor-3755b4903f88',
404 | details:
405 | 'Synthetify is a decentralized protocol that allows for the creation and exchange of synthetic assets that closely track the price of underlying assets. Synthetify’s synthetics adhere to the SPL token standard, allowing them to be easily integrated with DeFi applications across the Solana ecosystem.\n\nSynthetify leverages Solana to enable a fast, cheap and intuitive trading experience for users of the platform while staying fully decentralized thanks to an infrastructure that relies on smart contracts and blockchain oracles.\n\nThe Synthetify Token (SNY) gives the ability to participate in the protocol through staking. Stakers receive a pro rata share of fees generated by the exchange as well as additional rewards. SNY acts as a collateral token for all synthetic assets created on the platform and each token will have voting power on future governance proposals.',
406 | docs: {
407 | website: 'https://synthetify.io/',
408 | whitepaper: 'https://resources.synthetify.io/synthetify-whitepaper.pdf'
409 | },
410 | socials: {
411 | Twitter: 'https://twitter.com/synthetify',
412 | Telegram: 'https://t.me/synthetify',
413 | Medium: 'https://synthetify.medium.com/'
414 | },
415 | tags: ['raydium']
416 | },
417 | SLRS: {
418 | symbol: 'SLRS',
419 | name: 'SLRS',
420 | mintAddress: 'SLRSSpSLUTP7okbCUBYStWCo1vUgyt775faPqz8HUMr',
421 | decimals: 6,
422 | referrer: 'AmqeHgTdm6kBzy5ewZFKuMAfbynZmhve1GQxbJzQFLbP',
423 |
424 | detailLink: 'https://raydium.medium.com/solrise-is-launching-on-acceleraytor-c2c980362037',
425 | details:
426 | 'Solrise Finance is a fully decentralized and non-custodial protocol for investment funds on Solana. What this means in practice is that anyone can open a fund, and anyone can invest in it.\n\nSolrise’s platform allows fund managers from all across the globe — weWether they are well-established and looking for a new channel, or ambitious rookies with something to prove — to open a fund, with performance kept completely transparent.\n\nExisting decentralized fund management platforms on Ethereum are suffering from brutally high transaction fees. With Solrise, you can create, enter, and exit funds all for under $0.01.',
427 | docs: {
428 | website: 'https://solrise.finance/',
429 | docs: 'https://docs.solrise.finance/'
430 | },
431 | socials: {
432 | Twitter: 'https://twitter.com/SolriseFinance',
433 | Telegram: 'https://t.me/solrisefinance',
434 | Medium: 'https://blog.solrise.finance/'
435 | },
436 | tags: ['raydium']
437 | },
438 | WOO: {
439 | symbol: 'WOO',
440 | name: 'Wootrade Network',
441 | mintAddress: 'E5rk3nmgLUuKUiS94gg4bpWwWwyjCMtddsAXkTFLtHEy',
442 | decimals: 6,
443 | referrer: '7UbeAZxpza5zN3QawQ5KsUo88zXvohUncYB9Zk5QCiim',
444 | tags: ['raydium']
445 | },
446 | BOP: {
447 | symbol: 'BOP',
448 | name: 'Boring Protocol',
449 | mintAddress: 'BLwTnYKqf7u4qjgZrrsKeNs2EzWkMLqVCu6j8iHyrNA3',
450 | decimals: 8,
451 | referrer: 'FWxBZmNsvNckx8DnaL2NuyMtiQmT1x529WwV4e1UWiGk',
452 | tags: ['raydium']
453 | },
454 | SAMO: {
455 | symbol: 'SAMO',
456 | name: 'Samoyed Coin',
457 | mintAddress: '7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU',
458 | decimals: 9,
459 | referrer: 'FnMDNFL9t8EpbADSU3hLWBtx7SuwRBB6NM84U3PzSkUu',
460 | tags: ['raydium']
461 | },
462 | renBTC: {
463 | symbol: 'renBTC',
464 | name: 'renBTC',
465 | mintAddress: 'CDJWUqTcYTVAKXAVXoQZFes5JUFc7owSeq7eMQcDSbo5',
466 | decimals: 8,
467 | referrer: '7rr64uygy3o5RKVeNv12JGDUFMXVdr2YHvA3NTxzbZT6',
468 | tags: ['raydium']
469 | },
470 | renDOGE: {
471 | symbol: 'renDOGE',
472 | name: 'renDOGE',
473 | mintAddress: 'ArUkYE2XDKzqy77PRRGjo4wREWwqk6RXTfM9NeqzPvjU',
474 | decimals: 8,
475 | referrer: 'J5g7uvJRGnpRyLnRQjFs1MqMkiTVgjxVJCXocu4B4BcZ',
476 | tags: ['raydium']
477 | },
478 | LIKE: {
479 | symbol: 'LIKE',
480 | name: 'LIKE',
481 | mintAddress: '3bRTivrVsitbmCTGtqwp7hxXPsybkjn4XLNtPsHqa3zR',
482 | decimals: 9,
483 | referrer: '2rnVeVGfM88XqyNyBzGWEb7JViYKqncFzjWq5h1ujS9A',
484 |
485 | detailLink: 'https://raydium.medium.com/only1-is-launching-on-acceleraytor-41ecb89dcc4e',
486 | details:
487 | 'Only1 is the first NFT-powered social platform built on the Solana blockchain. Mixing social media, an NFT marketplace, a scalable blockchain, and the native token — $LIKE, Only1 offers fans a unique way of connecting with the creators they love.\n\nBy using the Only1 platform, fans will have the ability to invest, access, and earn from the limited edition contents created by the world’s largest influencers/celebrities, all powered by NFTs.',
488 | docs: {
489 | website: 'https://only1.io/',
490 | whitepaper: 'https://only1.io/pitch-deck.pdf'
491 | },
492 | socials: {
493 | Twitter: 'https://twitter.com/only1nft',
494 | Telegram: 'https://t.me/only1nft',
495 | Medium: 'https://medium.com/@only1nft',
496 | Discord: 'https://discord.gg/sUu7KZwNCB'
497 | },
498 | tags: ['raydium']
499 | },
500 | DXL: {
501 | symbol: 'DXL',
502 | name: 'DXL',
503 | mintAddress: 'GsNzxJfFn6zQdJGeYsupJWzUAm57Ba7335mfhWvFiE9Z',
504 | decimals: 6,
505 | referrer: 'HF7mhT9YgD5CULAFDYQmhnUMi1FnNbKeBFCy9SZDh2XE',
506 | tags: ['raydium']
507 | },
508 | mSOL: {
509 | symbol: 'mSOL',
510 | name: 'Marinade staked SOL (mSOL)',
511 | mintAddress: 'mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So',
512 | decimals: 9,
513 | referrer: '7h5bckf8P29RdviNoKjDyH3Ky3uwdrBiPgYuSCD4asV5',
514 | tags: ['raydium']
515 | },
516 | PAI: {
517 | symbol: 'PAI',
518 | name: 'PAI (Parrot)',
519 | mintAddress: 'Ea5SjE2Y6yvCeW5dYTn7PYMuW5ikXkvbGdcmSnXeaLjS',
520 | decimals: 6,
521 | referrer: '54X98LAxRR2j1KMBBXkbYyUaAWi1iKW9G1Y4TnTJVY2e',
522 | tags: ['raydium']
523 | },
524 | PORT: {
525 | symbol: 'PORT',
526 | name: 'PORT',
527 | mintAddress: 'PoRTjZMPXb9T7dyU7tpLEZRQj7e6ssfAE62j2oQuc6y',
528 | decimals: 6,
529 | referrer: '5Ve8q9fb7R2DhdqGV4o1RVy7xxo4D6ifQfbxGiASdxEH',
530 | tags: ['raydium']
531 | },
532 | MNGO: {
533 | symbol: 'MNGO',
534 | name: 'Mango',
535 | mintAddress: 'MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac',
536 | decimals: 6,
537 | referrer: 'CijuvE6qDpxZ5WqdEQEe7mS11fXEKiiHc7RR8wRiGzjY',
538 | tags: ['raydium']
539 | },
540 | CRP: {
541 | symbol: 'CRP',
542 | name: 'CRP',
543 | mintAddress: 'DubwWZNWiNGMMeeQHPnMATNj77YZPZSAz2WVR5WjLJqz',
544 | decimals: 9,
545 | referrer: 'FKocyVJptELTbnkUkDRmT7y6hUem2JYrqHoph9uyvQXt',
546 | tags: ['raydium']
547 | },
548 | ATLAS: {
549 | symbol: 'ATLAS',
550 | name: 'ATLAS',
551 | mintAddress: 'ATLASXmbPQxBUYbxPsV97usA3fPQYEqzQBUHgiFCUsXx',
552 | decimals: 8,
553 | referrer: '9t9mzbkMtLdazj1D9JycS15Geb1KVtcDt4XyAkpM72Ee',
554 |
555 | detailLink: 'https://raydium.medium.com/star-atlas-is-launching-on-acceleraytor-fa35cfe3291f',
556 | details:
557 | 'POLIS is the primary governance token of Star Atlas.\n\nStar Atlas is a grand strategy game that combines space exploration, territorial conquest, and political domination. In the distant future, players can join one of three galactic factions to directly influence the course of the metaverse and earn real-world income for their contributions.\n\nThe Star Atlas offers a unique gaming experience by combining block chain mechanics with traditional game mechanics. All assets in the metaverse are directly owned by players, and can be traded on the marketplace or exchanged on other cryptocurrency networks.',
558 | docs: {
559 | website: 'https://staratlas.com/',
560 | whitepaper: 'https://staratlas.com/files/star-atlas-white-paper.pdf'
561 | },
562 | socials: {
563 | Twitter: 'https://twitter.com/staratlas',
564 | Telegram: 'https://t.me/staratlasgame',
565 | Medium: 'https://medium.com/star-atlas',
566 | Discord: 'https://discord.gg/staratlas',
567 | Twitch: 'https://www.twitch.tv/staratlasgame',
568 | Youtube: 'https://www.youtube.com/channel/UCt-y8Npwje5KDG5MSZ0a9Jw/videos'
569 | },
570 | tags: ['raydium']
571 | },
572 | POLIS: {
573 | symbol: 'POLIS',
574 | name: 'POLIS',
575 | mintAddress: 'poLisWXnNRwC6oBu1vHiuKQzFjGL4XDSu4g9qjz9qVk',
576 | decimals: 8,
577 | referrer: 'CQ7HWCeSSp3tAfWzqH7ZEzgnTBr5Tvz1No3Y1xbiWzBm',
578 |
579 | detailLink: 'https://raydium.medium.com/star-atlas-is-launching-on-acceleraytor-fa35cfe3291f',
580 | details:
581 | 'POLIS is the primary governance token of Star Atlas.\n\nStar Atlas is a grand strategy game that combines space exploration, territorial conquest, and political domination. In the distant future, players can join one of three galactic factions to directly influence the course of the metaverse and earn real-world income for their contributions.\n\nThe Star Atlas offers a unique gaming experience by combining block chain mechanics with traditional game mechanics. All assets in the metaverse are directly owned by players, and can be traded on the marketplace or exchanged on other cryptocurrency networks.',
582 | docs: {
583 | website: 'https://staratlas.com/',
584 | whitepaper: 'https://staratlas.com/files/star-atlas-white-paper.pdf'
585 | },
586 | socials: {
587 | Twitter: 'https://twitter.com/staratlas',
588 | Telegram: 'https://t.me/staratlasgame',
589 | Medium: 'https://medium.com/star-atlas',
590 | Discord: 'https://discord.gg/staratlas',
591 | Twitch: 'https://www.twitch.tv/staratlasgame',
592 | Youtube: 'https://www.youtube.com/channel/UCt-y8Npwje5KDG5MSZ0a9Jw/videos'
593 | },
594 | tags: ['raydium']
595 | },
596 | GRAPE: {
597 | symbol: 'GRAPE',
598 | name: 'GRAPE',
599 | mintAddress: '8upjSpvjcdpuzhfR1zriwg5NXkwDruejqNE9WNbPRtyA',
600 | decimals: 6,
601 | referrer: 'M4nDMB9krXbaNFPVu1DjrBTfqPUHbKEQLZSSDNH2JrL',
602 |
603 | detailLink: 'https://raydium.medium.com/grape-protocol-launching-on-acceleraytor-547f58c12937',
604 | details:
605 | 'The GRAPE “Great Ape” community is a token-based membership community focused on accelerating the growth and adoption of Solana. GRAPE token holders at different tiers are rewarded with exclusive benefits and monthly emissions of GRAPE. You can find more details on the GRAPE membership tiers and benefits here.\n\nThe GRAPE toolset creates a framework for decentralized and tokenized communities to better organize and coordinate their activities, unlocking a whole new world of possibility for these dynamic groups. The GRAPE roadmap includes modules for DAO Management, non-custodial tipping, escrow, and event planning to be deployed in the next 6 months.\n\nGRAPE protocol’s first tool, Grape Access, creates a Dynamic Balance-Based Membership solution by connecting members’ social accounts to cryptographic keys. All Solana tokens are supported by Multi-Coin configurations, which grants users permission and access rights based on SPL tokens, token pairs, and LP tokens in their wallet.',
606 | docs: {
607 | website: 'https://grapes.network/'
608 | // whitepaper: '' // TODO
609 | },
610 | socials: {
611 | Discord: 'https://discord.com/invite/greatape',
612 | Medium: 'https://medium.com/great-ape',
613 | Twitter: 'https://twitter.com/grapeprotocol',
614 | Twitch: 'https://www.twitch.tv/whalesfriend'
615 | },
616 | tags: ['raydium']
617 | },
618 | GENE: {
619 | symbol: 'GENE',
620 | name: 'Genopets',
621 | mintAddress: 'GENEtH5amGSi8kHAtQoezp1XEXwZJ8vcuePYnXdKrMYz',
622 | decimals: 9,
623 |
624 | detailLink: 'https://raydium.medium.com/genopets-is-launching-on-acceleraytor-a4cba0b9f78b',
625 | details:
626 | 'Genopets is the world’s first Free-to-Play, Move-to-Earn NFT game that makes it fun and rewarding to live an active lifestyle. Build on Solana, Genopets integrates your daily activity in real life with blockchain Play-to-Earn economics so you can turn your real-life actions into expansive gameplay and earn crypto while doing it.',
627 | docs: {
628 | website: 'https://www.genopets.me/'
629 | // whitepaper: ''
630 | },
631 | socials: {
632 | Discord: 'https://discord.gg/genopets',
633 | Medium: 'https://medium.com/@genopets',
634 | Twitter: 'https://twitter.com/genopets'
635 | },
636 | tags: ['raydium']
637 | },
638 | DFL: {
639 | symbol: 'DFL',
640 | name: 'DeFi Land',
641 | mintAddress: 'DFL1zNkaGPWm1BqAVqRjCZvHmwTFrEaJtbzJWgseoNJh',
642 | decimals: 9,
643 |
644 | detailLink: 'https://raydium.medium.com/defi-land-is-launching-on-acceleraytor-8aa06caecc3c',
645 | details:
646 | 'DeFi Land is a multi-chain agriculture simulation web game created to gamify decentralized finance. The game will have all the features that traditional platforms have, but it will be gathered all in one place. DeFi Land gamifies decentralized finance by turning investment activities into games.',
647 | docs: {
648 | website: 'https://defiland.app/'
649 | // whitepaper: ''
650 | },
651 | socials: {
652 | Discord: 'https://discord.gg/defiland',
653 | Medium: 'https://defiland.medium.com/',
654 | Twitter: 'https://twitter.com/DeFi_Land',
655 | Telegram: 'https://t.me/defiland_official'
656 | },
657 | tags: ['raydium']
658 | },
659 | CHEEMS: {
660 | symbol: 'CHEEMS',
661 | name: 'CHEEMS',
662 | mintAddress: '3FoUAsGDbvTD6YZ4wVKJgTB76onJUKz7GPEBNiR5b8wc',
663 | decimals: 4,
664 | referrer: '',
665 | tags: ['raydium']
666 | },
667 | stSOL: {
668 | symbol: 'stSOL',
669 | name: 'stSOL',
670 | mintAddress: '7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj',
671 | decimals: 9,
672 | referrer: '8Mq4Tugv1fcT4gb1wf5ChdEFmdqNGKxFVCnM9TVe44vD',
673 | tags: ['raydium']
674 | },
675 | LARIX: {
676 | symbol: 'LARIX',
677 | name: 'LARIX',
678 | mintAddress: 'Lrxqnh6ZHKbGy3dcrCED43nsoLkM1LTzU2jRfWe8qUC',
679 | decimals: 6,
680 | referrer: 'DReKowvoxxEDdi5jnxBWJLTV73D9oHSt9uNMuSCk9cLk',
681 | tags: ['raydium']
682 | },
683 | RIN: {
684 | symbol: 'RIN',
685 | name: 'RIN',
686 | mintAddress: 'E5ndSkaB17Dm7CsD22dvcjfrYSDLCxFcMd6z8ddCk5wp',
687 | decimals: 9,
688 | tags: ['raydium']
689 | },
690 | APEX: {
691 | symbol: 'APEX',
692 | name: 'APEX',
693 | mintAddress: '51tMb3zBKDiQhNwGqpgwbavaGH54mk8fXFzxTc1xnasg',
694 | decimals: 9,
695 | tags: ['raydium']
696 | },
697 | MNDE: {
698 | symbol: 'MNDE',
699 | name: 'MNDE',
700 | mintAddress: 'MNDEFzGvMt87ueuHvVU9VcTqsAP5b3fTGPsHuuPA5ey',
701 | decimals: 9,
702 | tags: ['raydium']
703 | },
704 | LIQ: {
705 | symbol: 'LIQ',
706 | name: 'LIQ',
707 | mintAddress: '4wjPQJ6PrkC4dHhYghwJzGBVP78DkBzA2U3kHoFNBuhj',
708 | decimals: 6,
709 | tags: ['raydium']
710 | },
711 | WAG: {
712 | symbol: 'WAG',
713 | name: 'WAG',
714 | mintAddress: '5tN42n9vMi6ubp67Uy4NnmM5DMZYN8aS8GeB3bEDHr6E',
715 | decimals: 9,
716 | tags: ['raydium']
717 | },
718 | wLDO: {
719 | symbol: 'wLDO',
720 | name: 'wLDO',
721 | mintAddress: 'HZRCwxP2Vq9PCpPXooayhJ2bxTpo5xfpQrwB1svh332p',
722 | decimals: 8,
723 | tags: ['raydium']
724 | },
725 | SLIM: {
726 | symbol: 'SLIM',
727 | name: 'SLIM',
728 | mintAddress: 'xxxxa1sKNGwFtw2kFn8XauW9xq8hBZ5kVtcSesTT9fW',
729 | decimals: 6,
730 | tags: ['raydium']
731 | },
732 | PRT: {
733 | symbol: 'PRT',
734 | name: 'PRT',
735 | mintAddress: 'PRT88RkA4Kg5z7pKnezeNH4mafTvtQdfFgpQTGRjz44',
736 | decimals: 6,
737 | tags: ['raydium']
738 | },
739 | SBR: {
740 | symbol: 'SBR',
741 | name: 'SBR',
742 | mintAddress: 'Saber2gLauYim4Mvftnrasomsv6NvAuncvMEZwcLpD1',
743 | decimals: 6,
744 | tags: ['raydium']
745 | },
746 | FAB: {
747 | symbol: 'FAB',
748 | name: 'FAB',
749 | mintAddress: 'EdAhkbj5nF9sRM7XN7ewuW8C9XEUMs8P7cnoQ57SYE96',
750 | decimals: 9,
751 | tags: ['raydium']
752 | },
753 | ABR: {
754 | symbol: 'ABR',
755 | name: 'ABR',
756 | mintAddress: 'a11bdAAuV8iB2fu7X6AxAvDTo1QZ8FXB3kk5eecdasp',
757 | decimals: 9,
758 | tags: ['raydium']
759 | },
760 | IVN: {
761 | symbol: 'IVN',
762 | name: 'IVN',
763 | mintAddress: 'iVNcrNE9BRZBC9Aqf753iZiZfbszeAVUoikgT9yvr2a',
764 | decimals: 6,
765 | tags: ['raydium']
766 | },
767 | CYS: {
768 | symbol: 'CYS',
769 | name: 'CYS',
770 | mintAddress: 'BRLsMczKuaR5w9vSubF4j8HwEGGprVAyyVgS4EX7DKEg',
771 | decimals: 6,
772 | tags: ['raydium']
773 | },
774 | FRKT: {
775 | symbol: 'FRKT',
776 | name: 'FRKT',
777 | mintAddress: 'ErGB9xa24Szxbk1M28u2Tx8rKPqzL6BroNkkzk5rG4zj',
778 | decimals: 8,
779 | tags: ['raydium']
780 | },
781 | AURY: {
782 | symbol: 'AURY',
783 | name: 'AURY',
784 | mintAddress: 'AURYydfxJib1ZkTir1Jn1J9ECYUtjb6rKQVmtYaixWPP',
785 | decimals: 9,
786 | tags: ['raydium']
787 | },
788 | SYP: {
789 | symbol: 'SYP',
790 | name: 'SYP',
791 | mintAddress: 'FnKE9n6aGjQoNWRBZXy4RW6LZVao7qwBonUbiD7edUmZ',
792 | decimals: 9,
793 | tags: ['raydium']
794 | },
795 | WOOF: {
796 | symbol: 'WOOF',
797 | name: 'WOOF',
798 | mintAddress: '9nEqaUcb16sQ3Tn1psbkWqyhPdLmfHWjKGymREjsAgTE',
799 | decimals: 6,
800 | tags: ['raydium']
801 | },
802 | ORCA: {
803 | symbol: 'ORCA',
804 | name: 'ORCA',
805 | mintAddress: 'orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE',
806 | decimals: 6,
807 | tags: ['raydium']
808 | },
809 | SLND: {
810 | symbol: 'SLND',
811 | name: 'SLND',
812 | mintAddress: 'SLNDpmoWTVADgEdndyvWzroNL7zSi1dF9PC3xHGtPwp',
813 | decimals: 6,
814 | tags: ['raydium']
815 | },
816 | weWETH: {
817 | symbol: 'weWETH',
818 | name: 'weWETH',
819 | mintAddress: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs',
820 | decimals: 8,
821 | tags: ['raydium']
822 | },
823 | weUNI: {
824 | symbol: 'weUNI',
825 | name: 'weUNI',
826 | mintAddress: '8FU95xFJhUUkyyCLU13HSzDLs7oC4QZdXQHL6SCeab36',
827 | decimals: 8,
828 | tags: ['raydium']
829 | },
830 | weSUSHI: {
831 | symbol: 'weSUSHI',
832 | name: 'weSUSHI',
833 | mintAddress: 'ChVzxWRmrTeSgwd3Ui3UumcN8KX7VK3WaD4KGeSKpypj',
834 | decimals: 8,
835 | tags: ['raydium']
836 | },
837 | GOFX: {
838 | symbol: 'GOFX',
839 | name: 'GOFX',
840 | mintAddress: 'GFX1ZjR2P15tmrSwow6FjyDYcEkoFb4p4gJCpLBjaxHD',
841 | decimals: 9,
842 | tags: ['raydium']
843 | },
844 | IN: {
845 | symbol: 'IN',
846 | name: 'IN',
847 | mintAddress: 'inL8PMVd6iiW3RCBJnr5AsrRN6nqr4BTrcNuQWQSkvY',
848 | decimals: 9,
849 | tags: ['raydium']
850 | },
851 | weDYDX: {
852 | symbol: 'weDYDX',
853 | name: 'weDYDX',
854 | mintAddress: '4Hx6Bj56eGyw8EJrrheM6LBQAvVYRikYCWsALeTrwyRU',
855 | decimals: 8,
856 | tags: ['raydium']
857 | },
858 | STARS: {
859 | symbol: 'STARS',
860 | name: 'STARS',
861 | mintAddress: 'HCgybxq5Upy8Mccihrp7EsmwwFqYZtrHrsmsKwtGXLgW',
862 | decimals: 6,
863 | tags: ['raydium']
864 | },
865 | weAXS: {
866 | symbol: 'weAXS',
867 | name: 'weAXS',
868 | mintAddress: 'HysWcbHiYY9888pHbaqhwLYZQeZrcQMXKQWRqS7zcPK5',
869 | decimals: 8,
870 | tags: ['raydium']
871 | },
872 | weSHIB: {
873 | symbol: 'weSHIB',
874 | name: 'weSHIB',
875 | mintAddress: 'CiKu4eHsVrc1eueVQeHn7qhXTcVu95gSQmBpX4utjL9z',
876 | decimals: 8,
877 | tags: ['raydium']
878 | },
879 | OXS: {
880 | symbol: 'OXS',
881 | name: 'OXS',
882 | mintAddress: '4TGxgCSJQx2GQk9oHZ8dC5m3JNXTYZHjXumKAW3vLnNx',
883 | decimals: 9,
884 | tags: ['raydium']
885 | },
886 | CWAR: {
887 | symbol: 'CWAR',
888 | name: 'CWAR',
889 | mintAddress: 'HfYFjMKNZygfMC8LsQ8LtpPsPxEJoXJx4M6tqi75Hajo',
890 | decimals: 9,
891 | tags: ['raydium']
892 | },
893 | UPS: {
894 | symbol: 'UPS',
895 | name: 'UPS',
896 | mintAddress: 'EwJN2GqUGXXzYmoAciwuABtorHczTA5LqbukKXV1viH7',
897 | decimals: 6,
898 | tags: ['raydium']
899 | },
900 | weSAND: {
901 | symbol: 'weSAND',
902 | name: 'weSAND',
903 | mintAddress: '49c7WuCZkQgc3M4qH8WuEUNXfgwupZf1xqWkDQ7gjRGt',
904 | decimals: 8,
905 | tags: ['raydium']
906 | },
907 | weMANA: {
908 | symbol: 'weMANA',
909 | name: 'weMANA',
910 | mintAddress: '7dgHoN8wBZCc5wbnQ2C47TDnBMAxG4Q5L3KjP67z8kNi',
911 | decimals: 8,
912 | tags: ['raydium']
913 | },
914 | CAVE: {
915 | symbol: 'CAVE',
916 | name: 'CAVE',
917 | mintAddress: '4SZjjNABoqhbd4hnapbvoEPEqT8mnNkfbEoAwALf1V8t',
918 | decimals: 6,
919 | tags: ['raydium']
920 | },
921 | JSOL: {
922 | symbol: 'JSOL',
923 | name: 'JSOL',
924 | mintAddress: '7Q2afV64in6N6SeZsAAB81TJzwDoD6zpqmHkzi9Dcavn',
925 | decimals: 9,
926 | tags: ['raydium']
927 | },
928 | APT: {
929 | symbol: 'APT',
930 | name: 'APT',
931 | mintAddress: 'APTtJyaRX5yGTsJU522N4VYWg3vCvSb65eam5GrPT5Rt',
932 | decimals: 6,
933 | tags: ['raydium']
934 | },
935 | SONAR: {
936 | symbol: 'SONAR',
937 | name: 'SONAR',
938 | mintAddress: 'sonarX4VtVkQemriJeLm6CKeW3GDMyiBnnAEMw1MRAE',
939 | decimals: 9,
940 | tags: ['raydium']
941 | },
942 | SHILL: {
943 | symbol: 'SHILL',
944 | name: 'SHILL',
945 | mintAddress: '6cVgJUqo4nmvQpbgrDZwyfd6RwWw5bfnCamS3M9N1fd',
946 | decimals: 6,
947 | tags: ['raydium']
948 | },
949 | TTT: {
950 | symbol: 'TTT',
951 | name: 'TabTrader',
952 | mintAddress: 'FNFKRV3V8DtA3gVJN6UshMiLGYA8izxFwkNWmJbFjmRj',
953 | decimals: 6,
954 |
955 | detailLink: 'https://raydium.medium.com/tabtrader-is-launching-on-acceleraytor-bc570b6a9628',
956 | details:
957 | 'TabTrader is a trading terminal that supports 34 exchanges with over 12,000 instruments, a variety of analytical tools, and a convenient interface. It’s a quick-access application allowing you to track your exchange accounts, trade, analyze charts, and get instantly notified on price changes, all within one unified interface. The app has a rating of 4.7 on the Apple App Store (with over 52,000 ratings) and a rating of 4.5 on the Google Play Store (with over 55,000 ratings).',
958 | docs: {
959 | website: 'https://tab-trader.com/'
960 | // whitepaper: ''
961 | },
962 | socials: {
963 | Twitter: 'https://twitter.com/tabtraderpro',
964 | Telegram: 'https://t.me/tabtrader_en'
965 | },
966 | tags: ['raydium']
967 | },
968 | BOKU: {
969 | symbol: 'BOKU',
970 | name: 'BOKU',
971 | mintAddress: 'CN7qFa5iYkHz99PTctvT4xXUHnxwjQ5MHxCuTJtPN5uS',
972 | decimals: 9,
973 | tags: ['raydium']
974 | },
975 | MIMO: {
976 | symbol: 'MIMO',
977 | name: 'MIMO',
978 | mintAddress: '9TE7ebz1dsFo1uQ2T4oYAKSm39Y6fWuHrd6Uk6XaiD16',
979 | decimals: 9,
980 | tags: ['raydium']
981 | },
982 | wbWBNB: {
983 | symbol: 'wbWBNB',
984 | name: 'wbWBNB',
985 | mintAddress: '9gP2kCy3wA1ctvYWQk75guqXuHfrEomqydHLtcTCqiLa',
986 | decimals: 8,
987 | tags: ['raydium']
988 | },
989 | wePEOPLE: {
990 | symbol: 'wePEOPLE',
991 | name: 'wePEOPLE',
992 | mintAddress: 'CobcsUrt3p91FwvULYKorQejgsm5HoQdv5T8RUZ6PnLA',
993 | decimals: 8,
994 | tags: ['raydium']
995 | },
996 | XTAG: {
997 | symbol: 'XTAG',
998 | name: 'XTAG',
999 | mintAddress: '5gs8nf4wojB5EXgDUWNLwXpknzgV2YWDhveAeBZpVLbp',
1000 | decimals: 6,
1001 | tags: ['raydium']
1002 | },
1003 | KKO: {
1004 | symbol: 'KKO',
1005 | name: 'KKO',
1006 | mintAddress: 'kiNeKo77w1WBEzFFCXrTDRWGRWGP8yHvKC9rX6dqjQh',
1007 | decimals: 9,
1008 | tags: ['raydium']
1009 | },
1010 | VI: {
1011 | symbol: 'VI',
1012 | name: 'VI',
1013 | mintAddress: '7zBWymxbZt7PVHQzfi3i85frc1YRiQc23K7bh3gos8ZC',
1014 | decimals: 9,
1015 | tags: ['raydium']
1016 | },
1017 | SOLC: {
1018 | symbol: 'SOLC',
1019 | name: 'SOLC',
1020 | mintAddress: 'Bx1fDtvTN6NvE4kjdPHQXtmGSg582bZx9fGy4DQNMmAT',
1021 | decimals: 9,
1022 | tags: ['raydium']
1023 | },
1024 | STR: {
1025 | symbol: 'STR',
1026 | name: 'STR',
1027 | mintAddress: '9zoqdwEBKWEi9G5Ze8BSkdmppxGgVv1Kw4LuigDiNr9m',
1028 | decimals: 9,
1029 | tags: ['raydium']
1030 | },
1031 | SPWN: {
1032 | symbol: 'SPWN',
1033 | name: 'SPWN',
1034 | mintAddress: '5U9QqCPhqXAJcEv9uyzFJd5zhN93vuPk1aNNkXnUfPnt',
1035 | decimals: 9,
1036 | tags: ['raydium']
1037 | },
1038 | ISOLA: {
1039 | symbol: 'ISOLA',
1040 | name: 'ISOLA',
1041 | mintAddress: '333iHoRM2Awhf9uVZtSyTfU8AekdGrgQePZsKMFPgKmS',
1042 | decimals: 6,
1043 | tags: ['raydium']
1044 | },
1045 | RUN: {
1046 | symbol: 'RUN',
1047 | name: 'RUN',
1048 | mintAddress: '6F9XriABHfWhit6zmMUYAQBSy6XK5VF1cHXuW5LDpRtC',
1049 | decimals: 9,
1050 |
1051 | detailLink: 'https://raydium.medium.com/runnode-is-launching-on-acceleraytor-3ff7326864b0',
1052 | details:
1053 | 'RunNode is a bridge from web 2.0 to 3.0 and powers the infrastructure of Solana through its RPC protocol. With a quick onboarding application to get an RPC endpoint in under 30 seconds, any project can launch, build and scale its Solana dApp — now.',
1054 | docs: {
1055 | website: 'https://runnode.com/'
1056 | // whitepaper: ''
1057 | },
1058 | socials: {
1059 | Twitter: 'https://twitter.com/RunNode',
1060 | Telegram: 'https://t.me/runnode',
1061 | Discord: 'https://discord.gg/V2f74X8Zrt'
1062 | },
1063 |
1064 | tags: ['raydium']
1065 | },
1066 | REAL: {
1067 | symbol: 'REAL',
1068 | name: 'REAL',
1069 | mintAddress: 'AD27ov5fVU2XzwsbvnFvb1JpCBaCB5dRXrczV9CqSVGb',
1070 | decimals: 9,
1071 |
1072 | detailLink: 'https://raydium.medium.com/realy-is-launching-on-acceleraytor-b6d6a63d69d8',
1073 | details:
1074 | 'Realy Metaverse will be the 1st Live-to-Earn metaverse on Solana. Developed via Unreal Engine, Realy is a virtual city with AAA graphics that seamlessly integrates virtual and reality.',
1075 | docs: {
1076 | website: 'https://realy.pro/'
1077 | // whitepaper: ''
1078 | },
1079 | socials: {
1080 | Twitter: 'https://twitter.com/RealyOfficial',
1081 | Telegram: 'https://t.me/realyofficial',
1082 | Discord: 'https://discord.gg/realy'
1083 | },
1084 |
1085 | tags: ['raydium']
1086 | },
1087 | CRWNY: {
1088 | symbol: 'CRWNY',
1089 | name: 'CRWNY',
1090 | mintAddress: 'CRWNYkqdgvhGGae9CKfNka58j6QQkaD5bLhKXvUYqnc1',
1091 | decimals: 6,
1092 | tags: ['raydium']
1093 | },
1094 | BLOCK: {
1095 | symbol: 'BLOCK',
1096 | name: 'BLOCK',
1097 | mintAddress: 'NFTUkR4u7wKxy9QLaX2TGvd9oZSWoMo4jqSJqdMb7Nk',
1098 | decimals: 6,
1099 | tags: ['raydium']
1100 | },
1101 | SOLAR: {
1102 | symbol: 'SOLAR',
1103 | name: 'SOLAR',
1104 | mintAddress: '2wmKXX1xsxLfrvjEPrt2UHiqj8Gbzwxvffr9qmNjsw8g',
1105 | decimals: 9,
1106 | tags: ['raydium']
1107 | },
1108 | BASIS: {
1109 | symbol: 'BASIS',
1110 | name: 'BASIS',
1111 | mintAddress: 'Basis9oJw9j8cw53oMV7iqsgo6ihi9ALw4QR31rcjUJa',
1112 | decimals: 6,
1113 | tags: ['raydium']
1114 | },
1115 | SOLX: {
1116 | symbol: 'SOLX',
1117 | name: 'SOLX',
1118 | mintAddress: 'CH74tuRLTYcxG7qNJCsV9rghfLXJCQJbsu7i52a8F1Gn',
1119 | decimals: 9,
1120 | tags: ['raydium']
1121 | },
1122 | CHICKS: {
1123 | symbol: 'CHICKS',
1124 | name: 'CHICKS',
1125 | mintAddress: 'cxxShYRVcepDudXhe7U62QHvw8uBJoKFifmzggGKVC2',
1126 | decimals: 9,
1127 | tags: ['raydium']
1128 | }
1129 | }
1130 |
1131 | export const LP_TOKENS: Tokens = {
1132 | 'RAY-WUSDT': {
1133 | symbol: 'RAY-WUSDT',
1134 | name: 'RAY-WUSDT V2 LP',
1135 | coin: { ...TOKENS.RAY },
1136 | pc: { ...TOKENS.WUSDT },
1137 |
1138 | mintAddress: 'CzPDyvotTcxNqtPne32yUiEVQ6jk42HZi1Y3hUu7qf7f',
1139 | decimals: TOKENS.RAY.decimals
1140 | },
1141 | 'RAY-SOL': {
1142 | symbol: 'RAY-SOL',
1143 | name: 'RAY-SOL LP',
1144 | coin: { ...TOKENS.RAY },
1145 | pc: { ...NATIVE_SOL },
1146 |
1147 | mintAddress: '134Cct3CSdRCbYgq5SkwmHgfwjJ7EM5cG9PzqffWqECx',
1148 | decimals: TOKENS.RAY.decimals
1149 | },
1150 | 'LINK-WUSDT': {
1151 | symbol: 'LINK-WUSDT',
1152 | name: 'LINK-WUSDT LP',
1153 | coin: { ...TOKENS.LINK },
1154 | pc: { ...TOKENS.WUSDT },
1155 |
1156 | mintAddress: 'EVDmwajM5U73PD34bYPugwiA4Eqqbrej4mLXXv15Z5qR',
1157 | decimals: TOKENS.LINK.decimals
1158 | },
1159 | 'ETH-WUSDT': {
1160 | symbol: 'ETH-WUSDT',
1161 | name: 'ETH-WUSDT LP',
1162 | coin: { ...TOKENS.ETH },
1163 | pc: { ...TOKENS.WUSDT },
1164 |
1165 | mintAddress: 'KY4XvwHy7JPzbWYAbk23jQvEb4qWJ8aCqYWREmk1Q7K',
1166 | decimals: TOKENS.ETH.decimals
1167 | },
1168 | 'RAY-USDC': {
1169 | symbol: 'RAY-USDC',
1170 | name: 'RAY-USDC V2 LP',
1171 | coin: { ...TOKENS.RAY },
1172 | pc: { ...TOKENS.USDC },
1173 |
1174 | mintAddress: 'FgmBnsF5Qrnv8X9bomQfEtQTQjNNiBCWRKGpzPnE5BDg',
1175 | decimals: TOKENS.RAY.decimals
1176 | },
1177 | 'RAY-SRM': {
1178 | symbol: 'RAY-SRM',
1179 | name: 'RAY-SRM V2 LP',
1180 | coin: { ...TOKENS.RAY },
1181 | pc: { ...TOKENS.SRM },
1182 |
1183 | mintAddress: '5QXBMXuCL7zfAk39jEVVEvcrz1AvBGgT9wAhLLHLyyUJ',
1184 | decimals: TOKENS.RAY.decimals
1185 | },
1186 | // v3
1187 | 'RAY-WUSDT-V3': {
1188 | symbol: 'RAY-WUSDT',
1189 | name: 'RAY-WUSDT V3 LP',
1190 | coin: { ...TOKENS.RAY },
1191 | pc: { ...TOKENS.WUSDT },
1192 |
1193 | mintAddress: 'FdhKXYjCou2jQfgKWcNY7jb8F2DPLU1teTTTRfLBD2v1',
1194 | decimals: TOKENS.RAY.decimals
1195 | },
1196 | 'RAY-USDC-V3': {
1197 | symbol: 'RAY-USDC',
1198 | name: 'RAY-USDC V3 LP',
1199 | coin: { ...TOKENS.RAY },
1200 | pc: { ...TOKENS.USDC },
1201 |
1202 | mintAddress: 'BZFGfXMrjG2sS7QT2eiCDEevPFnkYYF7kzJpWfYxPbcx',
1203 | decimals: TOKENS.RAY.decimals
1204 | },
1205 | 'RAY-SRM-V3': {
1206 | symbol: 'RAY-SRM',
1207 | name: 'RAY-SRM V3 LP',
1208 | coin: { ...TOKENS.RAY },
1209 | pc: { ...TOKENS.SRM },
1210 |
1211 | mintAddress: 'DSX5E21RE9FB9hM8Nh8xcXQfPK6SzRaJiywemHBSsfup',
1212 | decimals: TOKENS.RAY.decimals
1213 | },
1214 | 'RAY-SOL-V3': {
1215 | symbol: 'RAY-SOL',
1216 | name: 'RAY-SOL V3 LP',
1217 | coin: { ...TOKENS.RAY },
1218 | pc: { ...NATIVE_SOL },
1219 |
1220 | mintAddress: 'F5PPQHGcznZ2FxD9JaxJMXaf7XkaFFJ6zzTBcW8osQjw',
1221 | decimals: TOKENS.RAY.decimals
1222 | },
1223 | 'RAY-ETH-V3': {
1224 | symbol: 'RAY-ETH',
1225 | name: 'RAY-ETH V3 LP',
1226 | coin: { ...TOKENS.RAY },
1227 | pc: { ...TOKENS.ETH },
1228 |
1229 | mintAddress: '8Q6MKy5Yxb9vG1mWzppMtMb2nrhNuCRNUkJTeiE3fuwD',
1230 | decimals: TOKENS.RAY.decimals
1231 | },
1232 | // v4
1233 | 'FIDA-RAY-V4': {
1234 | symbol: 'FIDA-RAY',
1235 | name: 'FIDA-RAY LP',
1236 | coin: { ...TOKENS.FIDA },
1237 | pc: { ...TOKENS.RAY },
1238 |
1239 | mintAddress: 'DsBuznXRTmzvEdb36Dx3aVLVo1XmH7r1PRZUFugLPTFv',
1240 | decimals: TOKENS.FIDA.decimals
1241 | },
1242 | 'OXY-RAY-V4': {
1243 | symbol: 'OXY-RAY',
1244 | name: 'OXY-RAY LP',
1245 | coin: { ...TOKENS.OXY },
1246 | pc: { ...TOKENS.RAY },
1247 |
1248 | mintAddress: 'FwaX9W7iThTZH5MFeasxdLpxTVxRcM7ZHieTCnYog8Yb',
1249 | decimals: TOKENS.OXY.decimals
1250 | },
1251 | 'MAPS-RAY-V4': {
1252 | symbol: 'MAPS-RAY',
1253 | name: 'MAPS-RAY LP',
1254 | coin: { ...TOKENS.MAPS },
1255 | pc: { ...TOKENS.RAY },
1256 |
1257 | mintAddress: 'CcKK8srfVdTSsFGV3VLBb2YDbzF4T4NM2C3UEjC39RLP',
1258 | decimals: TOKENS.MAPS.decimals
1259 | },
1260 | 'KIN-RAY-V4': {
1261 | symbol: 'KIN-RAY',
1262 | name: 'KIN-RAY LP',
1263 | coin: { ...TOKENS.KIN },
1264 | pc: { ...TOKENS.RAY },
1265 |
1266 | mintAddress: 'CHT8sft3h3gpLYbCcZ9o27mT5s3Z6VifBVbUiDvprHPW',
1267 | decimals: 6
1268 | },
1269 | 'RAY-USDT-V4': {
1270 | symbol: 'RAY-USDT',
1271 | name: 'RAY-USDT LP',
1272 | coin: { ...TOKENS.RAY },
1273 | pc: { ...TOKENS.USDT },
1274 |
1275 | mintAddress: 'C3sT1R3nsw4AVdepvLTLKr5Gvszr7jufyBWUCvy4TUvT',
1276 | decimals: TOKENS.RAY.decimals
1277 | },
1278 | 'SOL-USDC-V4': {
1279 | symbol: 'SOL-USDC',
1280 | name: 'SOL-USDC LP',
1281 | coin: { ...NATIVE_SOL },
1282 | pc: { ...TOKENS.USDC },
1283 |
1284 | mintAddress: '8HoQnePLqPj4M7PUDzfw8e3Ymdwgc7NLGnaTUapubyvu',
1285 | decimals: NATIVE_SOL.decimals
1286 | },
1287 | 'YFI-USDC-V4': {
1288 | symbol: 'YFI-USDC',
1289 | name: 'YFI-USDC LP',
1290 | coin: { ...TOKENS.YFI },
1291 | pc: { ...TOKENS.USDC },
1292 |
1293 | mintAddress: '865j7iMmRRycSYUXzJ33ZcvLiX9JHvaLidasCyUyKaRE',
1294 | decimals: TOKENS.YFI.decimals
1295 | },
1296 | 'SRM-USDC-V4': {
1297 | symbol: 'SRM-USDC',
1298 | name: 'SRM-USDC LP',
1299 | coin: { ...TOKENS.SRM },
1300 | pc: { ...TOKENS.USDC },
1301 |
1302 | mintAddress: '9XnZd82j34KxNLgQfz29jGbYdxsYznTWRpvZE3SRE7JG',
1303 | decimals: TOKENS.SRM.decimals
1304 | },
1305 | 'FTT-USDC-V4': {
1306 | symbol: 'FTT-USDC',
1307 | name: 'FTT-USDC LP',
1308 | coin: { ...TOKENS.FTT },
1309 | pc: { ...TOKENS.USDC },
1310 |
1311 | mintAddress: '75dCoKfUHLUuZ4qEh46ovsxfgWhB4icc3SintzWRedT9',
1312 | decimals: TOKENS.FTT.decimals
1313 | },
1314 | 'BTC-USDC-V4': {
1315 | symbol: 'BTC-USDC',
1316 | name: 'BTC-USDC LP',
1317 | coin: { ...TOKENS.BTC },
1318 | pc: { ...TOKENS.USDC },
1319 |
1320 | mintAddress: '2hMdRdVWZqetQsaHG8kQjdZinEMBz75vsoWTCob1ijXu',
1321 | decimals: TOKENS.BTC.decimals
1322 | },
1323 | 'SUSHI-USDC-V4': {
1324 | symbol: 'SUSHI-USDC',
1325 | name: 'SUSHI-USDC LP',
1326 | coin: { ...TOKENS.SUSHI },
1327 | pc: { ...TOKENS.USDC },
1328 |
1329 | mintAddress: '2QVjeR9d2PbSf8em8NE8zWd8RYHjFtucDUdDgdbDD2h2',
1330 | decimals: TOKENS.SUSHI.decimals
1331 | },
1332 | 'TOMO-USDC-V4': {
1333 | symbol: 'TOMO-USDC',
1334 | name: 'TOMO-USDC LP',
1335 | coin: { ...TOKENS.TOMO },
1336 | pc: { ...TOKENS.USDC },
1337 |
1338 | mintAddress: 'CHyUpQFeW456zcr5XEh4RZiibH8Dzocs6Wbgz9aWpXnQ',
1339 | decimals: TOKENS.TOMO.decimals
1340 | },
1341 | 'LINK-USDC-V4': {
1342 | symbol: 'LINK-USDC',
1343 | name: 'LINK-USDC LP',
1344 | coin: { ...TOKENS.LINK },
1345 | pc: { ...TOKENS.USDC },
1346 |
1347 | mintAddress: 'BqjoYjqKrXtfBKXeaWeAT5sYCy7wsAYf3XjgDWsHSBRs',
1348 | decimals: TOKENS.LINK.decimals
1349 | },
1350 | 'ETH-USDC-V4': {
1351 | symbol: 'ETH-USDC',
1352 | name: 'ETH-USDC LP',
1353 | coin: { ...TOKENS.ETH },
1354 | pc: { ...TOKENS.USDC },
1355 |
1356 | mintAddress: '13PoKid6cZop4sj2GfoBeujnGfthUbTERdE5tpLCDLEY',
1357 | decimals: TOKENS.ETH.decimals
1358 | },
1359 | 'xCOPE-USDC-V4': {
1360 | symbol: 'xCOPE-USDC',
1361 | name: 'xCOPE-USDC LP',
1362 | coin: { ...TOKENS.xCOPE },
1363 | pc: { ...TOKENS.USDC },
1364 |
1365 | mintAddress: '2Vyyeuyd15Gp8aH6uKE72c4hxc8TVSLibxDP9vzspQWG',
1366 | decimals: TOKENS.xCOPE.decimals
1367 | },
1368 | 'SOL-USDT-V4': {
1369 | symbol: 'SOL-USDT',
1370 | name: 'SOL-USDT LP',
1371 | coin: { ...NATIVE_SOL },
1372 | pc: { ...TOKENS.USDT },
1373 |
1374 | mintAddress: 'Epm4KfTj4DMrvqn6Bwg2Tr2N8vhQuNbuK8bESFp4k33K',
1375 | decimals: NATIVE_SOL.decimals
1376 | },
1377 | 'YFI-USDT-V4': {
1378 | symbol: 'YFI-USDT',
1379 | name: 'YFI-USDT LP',
1380 | coin: { ...TOKENS.YFI },
1381 | pc: { ...TOKENS.USDT },
1382 |
1383 | mintAddress: 'FA1i7fej1pAbQbnY8NbyYUsTrWcasTyipKreDgy1Mgku',
1384 | decimals: TOKENS.YFI.decimals
1385 | },
1386 | 'SRM-USDT-V4': {
1387 | symbol: 'SRM-USDT',
1388 | name: 'SRM-USDT LP',
1389 | coin: { ...TOKENS.SRM },
1390 | pc: { ...TOKENS.USDT },
1391 |
1392 | mintAddress: 'HYSAu42BFejBS77jZAZdNAWa3iVcbSRJSzp3wtqCbWwv',
1393 | decimals: TOKENS.SRM.decimals
1394 | },
1395 | 'FTT-USDT-V4': {
1396 | symbol: 'FTT-USDT',
1397 | name: 'FTT-USDT LP',
1398 | coin: { ...TOKENS.FTT },
1399 | pc: { ...TOKENS.USDT },
1400 |
1401 | mintAddress: '2cTCiUnect5Lap2sk19xLby7aajNDYseFhC9Pigou11z',
1402 | decimals: TOKENS.FTT.decimals
1403 | },
1404 | 'BTC-USDT-V4': {
1405 | symbol: 'BTC-USDT',
1406 | name: 'BTC-USDT LP',
1407 | coin: { ...TOKENS.BTC },
1408 | pc: { ...TOKENS.USDT },
1409 |
1410 | mintAddress: 'DgGuvR9GSHimopo3Gc7gfkbKamLKrdyzWkq5yqA6LqYS',
1411 | decimals: TOKENS.BTC.decimals
1412 | },
1413 | 'SUSHI-USDT-V4': {
1414 | symbol: 'SUSHI-USDT',
1415 | name: 'SUSHI-USDT LP',
1416 | coin: { ...TOKENS.SUSHI },
1417 | pc: { ...TOKENS.USDT },
1418 |
1419 | mintAddress: 'Ba26poEYDy6P2o95AJUsewXgZ8DM9BCsmnU9hmC9i4Ki',
1420 | decimals: TOKENS.SUSHI.decimals
1421 | },
1422 | 'TOMO-USDT-V4': {
1423 | symbol: 'TOMO-USDT',
1424 | name: 'TOMO-USDT LP',
1425 | coin: { ...TOKENS.TOMO },
1426 | pc: { ...TOKENS.USDT },
1427 |
1428 | mintAddress: 'D3iGro1vn6PWJXo9QAPj3dfta6dKkHHnmiiym2EfsAmi',
1429 | decimals: TOKENS.TOMO.decimals
1430 | },
1431 | 'LINK-USDT-V4': {
1432 | symbol: 'LINK-USDT',
1433 | name: 'LINK-USDT LP',
1434 | coin: { ...TOKENS.LINK },
1435 | pc: { ...TOKENS.USDT },
1436 |
1437 | mintAddress: 'Dr12Sgt9gkY8WU5tRkgZf1TkVWJbvjYuPAhR3aDCwiiX',
1438 | decimals: TOKENS.LINK.decimals
1439 | },
1440 | 'ETH-USDT-V4': {
1441 | symbol: 'ETH-USDT',
1442 | name: 'ETH-USDT LP',
1443 | coin: { ...TOKENS.ETH },
1444 | pc: { ...TOKENS.USDT },
1445 |
1446 | mintAddress: 'nPrB78ETY8661fUgohpuVusNCZnedYCgghzRJzxWnVb',
1447 | decimals: TOKENS.ETH.decimals
1448 | },
1449 | 'YFI-SRM-V4': {
1450 | symbol: 'YFI-SRM',
1451 | name: 'YFI-SRM LP',
1452 | coin: { ...TOKENS.YFI },
1453 | pc: { ...TOKENS.SRM },
1454 |
1455 | mintAddress: 'EGJht91R7dKpCj8wzALkjmNdUUUcQgodqWCYweyKcRcV',
1456 | decimals: TOKENS.YFI.decimals
1457 | },
1458 | 'FTT-SRM-V4': {
1459 | symbol: 'FTT-SRM',
1460 | name: 'FTT-SRM LP',
1461 | coin: { ...TOKENS.FTT },
1462 | pc: { ...TOKENS.SRM },
1463 |
1464 | mintAddress: 'AsDuPg9MgPtt3jfoyctUCUgsvwqAN6RZPftqoeiPDefM',
1465 | decimals: TOKENS.FTT.decimals
1466 | },
1467 | 'BTC-SRM-V4': {
1468 | symbol: 'BTC-SRM',
1469 | name: 'BTC-SRM LP',
1470 | coin: { ...TOKENS.BTC },
1471 | pc: { ...TOKENS.SRM },
1472 |
1473 | mintAddress: 'AGHQxXb3GSzeiLTcLtXMS2D5GGDZxsB2fZYZxSB5weqB',
1474 | decimals: TOKENS.BTC.decimals
1475 | },
1476 | 'SUSHI-SRM-V4': {
1477 | symbol: 'SUSHI-SRM',
1478 | name: 'SUSHI-SRM LP',
1479 | coin: { ...TOKENS.SUSHI },
1480 | pc: { ...TOKENS.SRM },
1481 |
1482 | mintAddress: '3HYhUnUdV67j1vn8fu7ExuVGy5dJozHEyWvqEstDbWwE',
1483 | decimals: TOKENS.SUSHI.decimals
1484 | },
1485 | 'TOMO-SRM-V4': {
1486 | symbol: 'TOMO-SRM',
1487 | name: 'TOMO-SRM LP',
1488 | coin: { ...TOKENS.TOMO },
1489 | pc: { ...TOKENS.SRM },
1490 |
1491 | mintAddress: 'GgH9RnKrQpaMQeqmdbMvs5oo1A24hERQ9wuY2pSkeG7x',
1492 | decimals: TOKENS.TOMO.decimals
1493 | },
1494 | 'LINK-SRM-V4': {
1495 | symbol: 'LINK-SRM',
1496 | name: 'LINK-SRM LP',
1497 | coin: { ...TOKENS.LINK },
1498 | pc: { ...TOKENS.SRM },
1499 |
1500 | mintAddress: 'GXN6yJv12o18skTmJXaeFXZVY1iqR18CHsmCT8VVCmDD',
1501 | decimals: TOKENS.LINK.decimals
1502 | },
1503 | 'ETH-SRM-V4': {
1504 | symbol: 'ETH-SRM',
1505 | name: 'ETH-SRM LP',
1506 | coin: { ...TOKENS.ETH },
1507 | pc: { ...TOKENS.SRM },
1508 |
1509 | mintAddress: '9VoY3VERETuc2FoadMSYYizF26mJinY514ZpEzkHMtwG',
1510 | decimals: TOKENS.ETH.decimals
1511 | },
1512 | 'SRM-SOL-V4': {
1513 | symbol: 'SRM-SOL',
1514 | name: 'SRM-SOL LP',
1515 | coin: { ...TOKENS.SRM },
1516 | pc: { ...NATIVE_SOL },
1517 |
1518 | mintAddress: 'AKJHspCwDhABucCxNLXUSfEzb7Ny62RqFtC9uNjJi4fq',
1519 | decimals: TOKENS.SRM.decimals
1520 | },
1521 | 'STEP-USDC-V4': {
1522 | symbol: 'STEP-USDC',
1523 | name: 'STEP-USDC LP',
1524 | coin: { ...TOKENS.STEP },
1525 | pc: { ...TOKENS.USDC },
1526 |
1527 | mintAddress: '3k8BDobgihmk72jVmXYLE168bxxQUhqqyESW4dQVktqC',
1528 | decimals: TOKENS.STEP.decimals
1529 | },
1530 | 'MEDIA-USDC-V4': {
1531 | symbol: 'MEDIA-USDC',
1532 | name: 'MEDIA-USDC LP',
1533 | coin: { ...TOKENS.MEDIA },
1534 | pc: { ...TOKENS.USDC },
1535 |
1536 | mintAddress: 'A5zanvgtioZGiJMdEyaKN4XQmJsp1p7uVxaq2696REvQ',
1537 | decimals: TOKENS.MEDIA.decimals
1538 | },
1539 | 'ROPE-USDC-V4': {
1540 | symbol: 'ROPE-USDC',
1541 | name: 'ROPE-USDC LP',
1542 | coin: { ...TOKENS.ROPE },
1543 | pc: { ...TOKENS.USDC },
1544 |
1545 | mintAddress: 'Cq4HyW5xia37tKejPF2XfZeXQoPYW6KfbPvxvw5eRoUE',
1546 | decimals: TOKENS.ROPE.decimals
1547 | },
1548 | 'MER-USDC-V4': {
1549 | symbol: 'MER-USDC',
1550 | name: 'MER-USDC LP',
1551 | coin: { ...TOKENS.MER },
1552 | pc: { ...TOKENS.USDC },
1553 |
1554 | mintAddress: '3H9NxvaZoxMZZDZcbBDdWMKbrfNj7PCF5sbRwDr7SdDW',
1555 | decimals: TOKENS.MER.decimals
1556 | },
1557 | 'COPE-USDC-V4': {
1558 | symbol: 'COPE-USDC',
1559 | name: 'COPE-USDC LP',
1560 | coin: { ...TOKENS.COPE },
1561 | pc: { ...TOKENS.USDC },
1562 |
1563 | mintAddress: 'Cz1kUvHw98imKkrqqu95GQB9h1frY8RikxPojMwWKGXf',
1564 | decimals: TOKENS.COPE.decimals
1565 | },
1566 | 'ALEPH-USDC-V4': {
1567 | symbol: 'ALEPH-USDC',
1568 | name: 'ALEPH-USDC LP',
1569 | coin: { ...TOKENS.ALEPH },
1570 | pc: { ...TOKENS.USDC },
1571 |
1572 | mintAddress: 'iUDasAP2nXm5wvTukAHEKSdSXn8vQkRtaiShs9ceGB7',
1573 | decimals: TOKENS.ALEPH.decimals
1574 | },
1575 | 'TULIP-USDC-V4': {
1576 | symbol: 'TULIP-USDC',
1577 | name: 'TULIP-USDC LP',
1578 | coin: { ...TOKENS.TULIP },
1579 | pc: { ...TOKENS.USDC },
1580 |
1581 | mintAddress: '2doeZGLJyACtaG9DCUyqMLtswesfje1hjNA11hMdj6YU',
1582 | decimals: TOKENS.TULIP.decimals
1583 | },
1584 | 'WOO-USDC-V4': {
1585 | symbol: 'WOO-USDC',
1586 | name: 'WOO-USDC LP',
1587 | coin: { ...TOKENS.WOO },
1588 | pc: { ...TOKENS.USDC },
1589 |
1590 | mintAddress: '7cu42ao8Jgrd5A3y3bNQsCxq5poyGZNmTydkGfJYQfzh',
1591 | decimals: TOKENS.WOO.decimals
1592 | },
1593 | 'SNY-USDC-V4': {
1594 | symbol: 'SNY-USDC',
1595 | name: 'SNY-USDC LP',
1596 | coin: { ...TOKENS.SNY },
1597 | pc: { ...TOKENS.USDC },
1598 |
1599 | mintAddress: 'G8qcfeFqxwbCqpxv5LpLWxUCd1PyMB5nWb5e5YyxLMKg',
1600 | decimals: TOKENS.SNY.decimals
1601 | },
1602 | 'BOP-RAY-V4': {
1603 | symbol: 'BOP-RAY',
1604 | name: 'BOP-RAY LP',
1605 | coin: { ...TOKENS.BOP },
1606 | pc: { ...TOKENS.RAY },
1607 |
1608 | mintAddress: '9nQPYJvysyfnXhQ6nkK5V7sZG26hmDgusfdNQijRk5LD',
1609 | decimals: TOKENS.BOP.decimals
1610 | },
1611 | 'SLRS-USDC-V4': {
1612 | symbol: 'SLRS-USDC',
1613 | name: 'SLRS-USDC LP',
1614 | coin: { ...TOKENS.SLRS },
1615 | pc: { ...TOKENS.USDC },
1616 |
1617 | mintAddress: '2Xxbm1hdv5wPeen5ponDSMT3VqhGMTQ7mH9stNXm9shU',
1618 | decimals: TOKENS.SLRS.decimals
1619 | },
1620 | 'SAMO-RAY-V4': {
1621 | symbol: 'SAMO-RAY',
1622 | name: 'SAMO-RAY LP',
1623 | coin: { ...TOKENS.SAMO },
1624 | pc: { ...TOKENS.RAY },
1625 |
1626 | mintAddress: 'HwzkXyX8B45LsaHXwY8su92NoRBS5GQC32HzjQRDqPnr',
1627 | decimals: TOKENS.SAMO.decimals
1628 | },
1629 | 'renBTC-USDC-V4': {
1630 | symbol: 'renBTC-USDC',
1631 | name: 'renBTC-USDC LP',
1632 | coin: { ...TOKENS.renBTC },
1633 | pc: { ...TOKENS.USDC },
1634 |
1635 | mintAddress: 'CTEpsih91ZLo5gunvryLpJ3pzMjmt5jbS6AnSQrzYw7V',
1636 | decimals: TOKENS.renBTC.decimals
1637 | },
1638 | 'renDOGE-USDC-V4': {
1639 | symbol: 'renDOGE-USDC',
1640 | name: 'renDOGE-USDC LP',
1641 | coin: { ...TOKENS.renDOGE },
1642 | pc: { ...TOKENS.USDC },
1643 |
1644 | mintAddress: 'Hb8KnZNKvRxu7pgMRWJgoMSMcepfvNiBFFDDrdf9o3wA',
1645 | decimals: TOKENS.renDOGE.decimals
1646 | },
1647 | 'RAY-USDC-V4': {
1648 | symbol: 'RAY-USDC',
1649 | name: 'RAY-USDC LP',
1650 | coin: { ...TOKENS.RAY },
1651 | pc: { ...TOKENS.USDC },
1652 |
1653 | mintAddress: 'FbC6K13MzHvN42bXrtGaWsvZY9fxrackRSZcBGfjPc7m',
1654 | decimals: TOKENS.RAY.decimals
1655 | },
1656 | 'RAY-SRM-V4': {
1657 | symbol: 'RAY-SRM',
1658 | name: 'RAY-SRM LP',
1659 | coin: { ...TOKENS.RAY },
1660 | pc: { ...TOKENS.SRM },
1661 |
1662 | mintAddress: '7P5Thr9Egi2rvMmEuQkLn8x8e8Qro7u2U7yLD2tU2Hbe',
1663 | decimals: TOKENS.RAY.decimals
1664 | },
1665 | 'RAY-ETH-V4': {
1666 | symbol: 'RAY-ETH',
1667 | name: 'RAY-ETH LP',
1668 | coin: { ...TOKENS.RAY },
1669 | pc: { ...TOKENS.ETH },
1670 |
1671 | mintAddress: 'mjQH33MqZv5aKAbKHi8dG3g3qXeRQqq1GFcXceZkNSr',
1672 | decimals: TOKENS.RAY.decimals
1673 | },
1674 | 'RAY-SOL-V4': {
1675 | symbol: 'RAY-SOL',
1676 | name: 'RAY-SOL LP',
1677 | coin: { ...TOKENS.RAY },
1678 | pc: { ...NATIVE_SOL },
1679 |
1680 | mintAddress: '89ZKE4aoyfLBe2RuV6jM3JGNhaV18Nxh8eNtjRcndBip',
1681 | decimals: TOKENS.RAY.decimals
1682 | },
1683 | 'DXL-USDC-V4': {
1684 | symbol: 'DXL-USDC',
1685 | name: 'DXL-USDC LP',
1686 | coin: { ...TOKENS.DXL },
1687 | pc: { ...TOKENS.USDC },
1688 |
1689 | mintAddress: '4HFaSvfgskipvrzT1exoVKsUZ174JyExEsA8bDfsAdY5',
1690 | decimals: TOKENS.DXL.decimals
1691 | },
1692 | 'LIKE-USDC-V4': {
1693 | symbol: 'LIKE-USDC',
1694 | name: 'LIKE-USDC LP',
1695 | coin: { ...TOKENS.LIKE },
1696 | pc: { ...TOKENS.USDC },
1697 |
1698 | mintAddress: 'cjZmbt8sJgaoyWYUttomAu5LJYU44ZrcKTbzTSEPDVw',
1699 | decimals: TOKENS.LIKE.decimals
1700 | },
1701 | 'mSOL-USDC-V4': {
1702 | symbol: 'mSOL-USDC',
1703 | name: 'mSOL-USDC LP',
1704 | coin: { ...TOKENS.mSOL },
1705 | pc: { ...TOKENS.USDC },
1706 |
1707 | mintAddress: '4xTpJ4p76bAeggXoYywpCCNKfJspbuRzZ79R7pRhbqSf',
1708 | decimals: TOKENS.mSOL.decimals
1709 | },
1710 | 'mSOL-SOL-V4': {
1711 | symbol: 'mSOL-SOL',
1712 | name: 'mSOL-SOL LP',
1713 | coin: { ...TOKENS.mSOL },
1714 | pc: { ...NATIVE_SOL },
1715 |
1716 | mintAddress: '5ijRoAHVgd5T5CNtK5KDRUBZ7Bffb69nktMj5n6ks6m4',
1717 | decimals: TOKENS.mSOL.decimals
1718 | },
1719 | 'MER-PAI-V4': {
1720 | symbol: 'MER-PAI',
1721 | name: 'MER-PAI LP',
1722 | coin: { ...TOKENS.MER },
1723 | pc: { ...TOKENS.PAI },
1724 |
1725 | mintAddress: 'DU5RT2D9EviaSmX6Ta8MZwMm85HwSEqGMRdqUiuCGfmD',
1726 | decimals: TOKENS.MER.decimals
1727 | },
1728 | 'PORT-USDC-V4': {
1729 | symbol: 'PORT-USDC',
1730 | name: 'PORT-USDC LP',
1731 | coin: { ...TOKENS.PORT },
1732 | pc: { ...TOKENS.USDC },
1733 |
1734 | mintAddress: '9tmNtbUCrLS15qC4tEfr5NNeqcqpZ4uiGgi2vS5CLQBS',
1735 | decimals: TOKENS.PORT.decimals
1736 | },
1737 | 'MNGO-USDC-V4': {
1738 | symbol: 'MNGO-USDC',
1739 | name: 'MNGO-USDC LP',
1740 | coin: { ...TOKENS.MNGO },
1741 | pc: { ...TOKENS.USDC },
1742 |
1743 | mintAddress: 'DkiqCQ792n743xjWQVCbBUaVtkdiuvQeYndM53ReWnCC',
1744 | decimals: TOKENS.MNGO.decimals
1745 | },
1746 | 'ATLAS-USDC-V4': {
1747 | symbol: 'ATLAS-USDC',
1748 | name: 'ATLAS-USDC LP',
1749 | coin: { ...TOKENS.ATLAS },
1750 | pc: { ...TOKENS.USDC },
1751 |
1752 | mintAddress: '9shGU9f1EsxAbiR567MYZ78WUiS6ZNCYbHe53WUULQ7n',
1753 | decimals: TOKENS.ATLAS.decimals
1754 | },
1755 | 'POLIS-USDC-V4': {
1756 | symbol: 'POLIS-USDC',
1757 | name: 'POLIS-USDC LP',
1758 | coin: { ...TOKENS.POLIS },
1759 | pc: { ...TOKENS.USDC },
1760 |
1761 | mintAddress: '8MbKSBpyXs8fVneKgt71jfHrn5SWtX8n4wMLpiVfF9So',
1762 | decimals: TOKENS.POLIS.decimals
1763 | },
1764 | 'ATLAS-RAY-V4': {
1765 | symbol: 'ATLAS-RAY',
1766 | name: 'ATLAS-RAY LP',
1767 | coin: { ...TOKENS.ATLAS },
1768 | pc: { ...TOKENS.RAY },
1769 |
1770 | mintAddress: '418MFhkaYQtbn529wmjLLqL6uKxDz7j4eZBaV1cobkyd',
1771 | decimals: TOKENS.ATLAS.decimals
1772 | },
1773 | 'POLIS-RAY-V4': {
1774 | symbol: 'POLIS-RAY',
1775 | name: 'POLIS-RAY LP',
1776 | coin: { ...TOKENS.POLIS },
1777 | pc: { ...TOKENS.RAY },
1778 |
1779 | mintAddress: '9ysGKUH6WqzjQEUT4dxqYCUaFNVK9QFEa24pGzjFq8xg',
1780 | decimals: TOKENS.POLIS.decimals
1781 | },
1782 | 'ALEPH-RAY-V4': {
1783 | symbol: 'ALEPH-RAY',
1784 | name: 'ALEPH-RAY LP',
1785 | coin: { ...TOKENS.ALEPH },
1786 | pc: { ...TOKENS.RAY },
1787 |
1788 | mintAddress: 'n76skjqv4LirhdLok2zJELXNLdRpYDgVJQuQFbamscy',
1789 | decimals: TOKENS.ALEPH.decimals
1790 | },
1791 | 'TULIP-RAY-V4': {
1792 | symbol: 'TULIP-RAY',
1793 | name: 'TULIP-RAY LP',
1794 | coin: { ...TOKENS.TULIP },
1795 | pc: { ...TOKENS.RAY },
1796 |
1797 | mintAddress: '3AZTviji5qduMG2s4FfWGR3SSQmNUCyx8ao6UKCPg3oJ',
1798 | decimals: TOKENS.TULIP.decimals
1799 | },
1800 | 'SLRS-RAY-V4': {
1801 | symbol: 'SLRS-RAY',
1802 | name: 'SLRS-RAY LP',
1803 | coin: { ...TOKENS.SLRS },
1804 | pc: { ...TOKENS.RAY },
1805 |
1806 | mintAddress: '2pk78vsKT3jfJAcN2zbpMUnrR57SZrxHqaZYyFgp92mM',
1807 | decimals: TOKENS.SLRS.decimals
1808 | },
1809 | 'MER-RAY-V4': {
1810 | symbol: 'MER-RAY',
1811 | name: 'MER-RAY LP',
1812 | coin: { ...TOKENS.MER },
1813 | pc: { ...TOKENS.RAY },
1814 |
1815 | mintAddress: '214hxy3AbKoaEKgqcg2aC1cP5R67cGGAyDEg5GDwC7Ub',
1816 | decimals: TOKENS.MER.decimals
1817 | },
1818 | 'MEDIA-RAY-V4': {
1819 | symbol: 'MEDIA-RAY',
1820 | name: 'MEDIA-RAY LP',
1821 | coin: { ...TOKENS.MEDIA },
1822 | pc: { ...TOKENS.RAY },
1823 |
1824 | mintAddress: '9Aseg5A1JD1yCiFFdDaNNxCiJ7XzrpZFmcEmLjXFdPaH',
1825 | decimals: TOKENS.MEDIA.decimals
1826 | },
1827 | 'SNY-RAY-V4': {
1828 | symbol: 'SNY-RAY',
1829 | name: 'SNY-RAY LP',
1830 | coin: { ...TOKENS.SNY },
1831 | pc: { ...TOKENS.RAY },
1832 |
1833 | mintAddress: '2k4quTuuLUxrSEhFH99qcoZzvgvVEc3b5sz3xz3qstfS',
1834 | decimals: TOKENS.SNY.decimals
1835 | },
1836 | 'LIKE-RAY-V4': {
1837 | symbol: 'LIKE-RAY',
1838 | name: 'LIKE-RAY LP',
1839 | coin: { ...TOKENS.LIKE },
1840 | pc: { ...TOKENS.RAY },
1841 |
1842 | mintAddress: '7xqDycbFSCpUpzkYapFeyPJWPwEpV7zdWbYf2MVHTNjv',
1843 | decimals: TOKENS.LIKE.decimals
1844 | },
1845 | 'COPE-RAY-V4': {
1846 | symbol: 'COPE-RAY',
1847 | name: 'COPE-RAY LP',
1848 | coin: { ...TOKENS.COPE },
1849 | pc: { ...TOKENS.RAY },
1850 |
1851 | mintAddress: 'A7GCVHA8NSsbdFscHdoNU41tL1TRKNmCH4K94CgcLK9F',
1852 | decimals: TOKENS.COPE.decimals
1853 | },
1854 | 'ETH-SOL-V4': {
1855 | symbol: 'ETH-SOL',
1856 | name: 'ETH-SOL LP',
1857 | coin: { ...TOKENS.ETH },
1858 | pc: { ...NATIVE_SOL },
1859 |
1860 | mintAddress: 'GKfgC86iJoMjwAtcyiLu6nWnjggqUXsDQihXkP14fDez',
1861 | decimals: TOKENS.ETH.decimals
1862 | },
1863 | 'stSOL-USDC-V4': {
1864 | symbol: 'stSOL-USDC',
1865 | name: 'stSOL-USDC LP',
1866 | coin: { ...TOKENS.stSOL },
1867 | pc: { ...TOKENS.USDC },
1868 |
1869 | mintAddress: 'HDUJMwYZkjUZre63xUeDhdCi8c6LgUDiBqxmP3QC3VPX',
1870 | decimals: TOKENS.stSOL.decimals
1871 | },
1872 | 'GRAPE-USDC-V4': {
1873 | symbol: 'GRAPE-USDC',
1874 | name: 'GRAPE-USDC LP',
1875 | coin: { ...TOKENS.GRAPE },
1876 | pc: { ...TOKENS.USDC },
1877 |
1878 | mintAddress: 'A8ZYmnZ1vwxUa4wpJVUaJgegsuTEz5TKy5CiJXffvmpt',
1879 | decimals: TOKENS.GRAPE.decimals
1880 | },
1881 | 'LARIX-USDC-V4': {
1882 | symbol: 'LARIX-USDC',
1883 | name: 'LARIX-USDC LP',
1884 | coin: { ...TOKENS.LARIX },
1885 | pc: { ...TOKENS.USDC },
1886 |
1887 | mintAddress: '7yieit4YsNsZ9CAK8H5ZEMvvk35kPEHHeXwp6naoWU9V',
1888 | decimals: TOKENS.LARIX.decimals
1889 | },
1890 | 'RIN-USDC-V4': {
1891 | symbol: 'RIN-USDC',
1892 | name: 'RIN-USDC LP',
1893 | coin: { ...TOKENS.RIN },
1894 | pc: { ...TOKENS.USDC },
1895 |
1896 | mintAddress: 'GfCWfrZez7BDmCSEeMERVDVUaaM2TEreyYUgb2cpuS3w',
1897 | decimals: TOKENS.RIN.decimals
1898 | },
1899 | 'APEX-USDC-V4': {
1900 | symbol: 'APEX-USDC',
1901 | name: 'APEX-USDC LP',
1902 | coin: { ...TOKENS.APEX },
1903 | pc: { ...TOKENS.USDC },
1904 |
1905 | mintAddress: '444cVqYyDxJNo6FqiMb9qQWFUd7tYzFRdDuJRFrSAGnU',
1906 | decimals: TOKENS.APEX.decimals
1907 | },
1908 | 'mSOL-RAY-V4': {
1909 | symbol: 'mSOL-RAY',
1910 | name: 'mSOL-RAY LP',
1911 | coin: { ...TOKENS.mSOL },
1912 | pc: { ...TOKENS.RAY },
1913 |
1914 | mintAddress: 'De2EHBAdkgfc72DpShqDGG42cV3iDWh8wvvZdPsiEcqP',
1915 | decimals: TOKENS.mSOL.decimals
1916 | },
1917 | 'MNDE-mSOL-V4': {
1918 | symbol: 'MNDE-mSOL',
1919 | name: 'MNDE-mSOL LP',
1920 | coin: { ...TOKENS.MNDE },
1921 | pc: { ...TOKENS.mSOL },
1922 |
1923 | mintAddress: '4bh8XCzTHSbqbWN8o1Jn4ueBdz1LvJFoEasN6K6CQ8Ny',
1924 | decimals: TOKENS.MNDE.decimals
1925 | },
1926 | 'LARIX-RAY-V4': {
1927 | symbol: 'LARIX-RAY',
1928 | name: 'LARIX-RAY LP',
1929 | coin: { ...TOKENS.LARIX },
1930 | pc: { ...TOKENS.RAY },
1931 |
1932 | mintAddress: 'ZRDfSLgWGeaYSmhdPvFNKQQhDcYdZQaue2N8YDmHX4q',
1933 | decimals: TOKENS.LARIX.decimals
1934 | },
1935 | 'LIQ-USDC-V4': {
1936 | symbol: 'LIQ-USDC',
1937 | name: 'LIQ-USDC LP',
1938 | coin: { ...TOKENS.LIQ },
1939 | pc: { ...TOKENS.USDC },
1940 |
1941 | mintAddress: 'GWpD3eTfhJB5KDCcnE85dBQrjAk2CsrgDF9b52R9CrjV',
1942 | decimals: TOKENS.LIQ.decimals
1943 | },
1944 | 'WAG-USDC-V4': {
1945 | symbol: 'WAG-USDC',
1946 | name: 'WAG-USDC LP',
1947 | coin: { ...TOKENS.WAG },
1948 | pc: { ...TOKENS.USDC },
1949 |
1950 | mintAddress: '4yykyPugitUVRewNPXXCviRvxGfsfsRMoP32z3b6FmUC',
1951 | decimals: TOKENS.WAG.decimals
1952 | },
1953 | 'ETH-mSOL-V4': {
1954 | symbol: 'ETH-mSOL',
1955 | name: 'ETH-mSOL LP',
1956 | coin: { ...TOKENS.ETH },
1957 | pc: { ...TOKENS.mSOL },
1958 |
1959 | mintAddress: 'HYv3grQfi8QbV7nG7EFgNK1aJSrsJ7HynXJKJVPLL2Uh',
1960 | decimals: TOKENS.ETH.decimals
1961 | },
1962 | 'mSOL-USDT-V4': {
1963 | symbol: 'mSOL-USDT',
1964 | name: 'mSOL-USDT LP',
1965 | coin: { ...TOKENS.mSOL },
1966 | pc: { ...TOKENS.USDT },
1967 |
1968 | mintAddress: '69NCmEW9mGpiWLjAcAWHq51k4ionJZmzgRfRT3wQaCCf',
1969 | decimals: TOKENS.mSOL.decimals
1970 | },
1971 | 'BTC-mSOL-V4': {
1972 | symbol: 'BTC-mSOL',
1973 | name: 'BTC-mSOL LP',
1974 | coin: { ...TOKENS.BTC },
1975 | pc: { ...TOKENS.mSOL },
1976 |
1977 | mintAddress: '92bcERNtUmuaJ6mwLSxYHZYSph37jdKxRdoYNxpcYNPp',
1978 | decimals: TOKENS.BTC.decimals
1979 | },
1980 | 'SLIM-SOL-V4': {
1981 | symbol: 'SLIM-SOL',
1982 | name: 'SLIM-SOL LP',
1983 | coin: { ...TOKENS.SLIM },
1984 | pc: { ...NATIVE_SOL },
1985 |
1986 | mintAddress: '9X4EK8E59VAVi6ChnNvvd39m6Yg9RtkBbAPq1mDVJT57',
1987 | decimals: TOKENS.SLIM.decimals
1988 | },
1989 | 'AURY-USDC-V4': {
1990 | symbol: 'AURY-USDC',
1991 | name: 'AURY-USDC LP',
1992 | coin: { ...TOKENS.AURY },
1993 | pc: { ...TOKENS.USDC },
1994 |
1995 | mintAddress: 'Gub5dvTy4nzP82qpmpNkBxmRqjtqRddBTBqHSdNcf2oS',
1996 | decimals: TOKENS.AURY.decimals
1997 | },
1998 | 'PRT-SOL-V4': {
1999 | symbol: 'PRT-SOL',
2000 | name: 'PRT-SOL LP',
2001 | coin: { ...TOKENS.PRT },
2002 | pc: { ...NATIVE_SOL },
2003 |
2004 | mintAddress: 'EcJ8Wgwt1AzSPiDpVr6aaSur8TKAsNTPmmzRACeqT68Z',
2005 | decimals: TOKENS.PRT.decimals
2006 | },
2007 | 'LIQ-RAY-V4': {
2008 | symbol: 'LIQ-RAY',
2009 | name: 'LIQ-RAY LP',
2010 | coin: { ...TOKENS.LIQ },
2011 | pc: { ...TOKENS.RAY },
2012 |
2013 | mintAddress: '49YUsDrThJosHSagCn1F59Uc9NRxbr9thVrZikUnQDXy',
2014 | decimals: TOKENS.LIQ.decimals
2015 | },
2016 | 'SYP-SOL-V4': {
2017 | symbol: 'SYP-SOL',
2018 | name: 'SYP-SOL LP',
2019 | coin: { ...TOKENS.SYP },
2020 | pc: { ...NATIVE_SOL },
2021 |
2022 | mintAddress: 'KHV6dfj2bDntzJ9z1S26cDfqWfUZdJRFmteLR6LxHwW',
2023 | decimals: TOKENS.SYP.decimals
2024 | },
2025 | 'SYP-RAY-V4': {
2026 | symbol: 'SYP-RAY',
2027 | name: 'SYP-RAY LP',
2028 | coin: { ...TOKENS.SYP },
2029 | pc: { ...TOKENS.RAY },
2030 |
2031 | mintAddress: 'FT2KZqxxM8F2h9pZtTF4PyjK88bM4YbuBzd7ZPwQ5wMB',
2032 | decimals: TOKENS.SYP.decimals
2033 | },
2034 | 'SYP-USDC-V4': {
2035 | symbol: 'SYP-USDC',
2036 | name: 'SYP-USDC LP',
2037 | coin: { ...TOKENS.SYP },
2038 | pc: { ...TOKENS.USDC },
2039 |
2040 | mintAddress: '2xJGuLAivAR1WkARRA6zP1v4jaA9jV2Qis8JfMNvrVyZ',
2041 | decimals: TOKENS.SYP.decimals
2042 | },
2043 | 'FAB-USDC-V4': {
2044 | symbol: 'FAB-USDC',
2045 | name: 'FAB-USDC LP',
2046 | coin: { ...TOKENS.FAB },
2047 | pc: { ...TOKENS.USDC },
2048 |
2049 | mintAddress: '5rTCvZq6BcApsC3VV1EEUuTJfaVd8uYhcGjwTy1By6P8',
2050 | decimals: TOKENS.FAB.decimals
2051 | },
2052 | 'WOOF-RAY-V4': {
2053 | symbol: 'WOOF-RAY',
2054 | name: 'WOOF-RAY LP',
2055 | coin: { ...TOKENS.WOOF },
2056 | pc: { ...TOKENS.RAY },
2057 |
2058 | mintAddress: 'H2FAnazDaGFutcmnrwDxhmdncR1Bd7GG4mhPCSUiamDX',
2059 | decimals: TOKENS.WOOF.decimals
2060 | },
2061 | 'WOOF-USDC-V4': {
2062 | symbol: 'WOOF-USDC',
2063 | name: 'WOOF-USDC LP',
2064 | coin: { ...TOKENS.WOOF },
2065 | pc: { ...TOKENS.USDC },
2066 |
2067 | mintAddress: 'EFSu5TMc1ijRevaYCxUkS7uGvbhsymDHEaTK3UVdNE3q',
2068 | decimals: TOKENS.WOOF.decimals
2069 | },
2070 | 'SLND-USDC-V4': {
2071 | symbol: 'SLND-USDC',
2072 | name: 'SLND-USDC LP',
2073 | coin: { ...TOKENS.SLND },
2074 | pc: { ...TOKENS.USDC },
2075 |
2076 | mintAddress: 'EunE9uDh2cGsyJcsGuGKc6wte7kBn8iye2gzC4w2ePHn',
2077 | decimals: TOKENS.SLND.decimals
2078 | },
2079 | 'FRKT-SOL-V4': {
2080 | symbol: 'FRKT-SOL',
2081 | name: 'FRKT-SOL LP',
2082 | coin: { ...TOKENS.FRKT },
2083 | pc: { ...NATIVE_SOL },
2084 |
2085 | mintAddress: 'HYUKXgpjaxMXHttyrFYtv3z2rdhZ1U9QDH8zEc8BooQC',
2086 | decimals: TOKENS.FRKT.decimals
2087 | },
2088 | 'weWETH-SOL-V4': {
2089 | symbol: 'weWETH-SOL',
2090 | name: 'weWETH-SOL LP',
2091 | coin: { ...TOKENS.weWETH },
2092 | pc: { ...NATIVE_SOL },
2093 |
2094 | mintAddress: '3hbozt2Por7bcrGod8N7kEeJNMocFFjCJrQR16TQGBrE',
2095 | decimals: TOKENS.weWETH.decimals
2096 | },
2097 | 'weWETH-USDC-V4': {
2098 | symbol: 'weWETH-USDC',
2099 | name: 'weWETH-USDC LP',
2100 | coin: { ...TOKENS.weWETH },
2101 | pc: { ...TOKENS.USDC },
2102 |
2103 | mintAddress: '3529SBnMCDW3S3xQ52aABbRHo7PcHvpQA4no8J12L5eK',
2104 | decimals: TOKENS.weWETH.decimals
2105 | },
2106 | 'weUNI-USDC-V4': {
2107 | symbol: 'weUNI-USDC',
2108 | name: 'weUNI-USDC LP',
2109 | coin: { ...TOKENS.weUNI },
2110 | pc: { ...TOKENS.USDC },
2111 |
2112 | mintAddress: 'EEC4QnT41py39QaYnzQnoYQEtDUDNa6Se8SBDgfPSN2a',
2113 | decimals: TOKENS.weUNI.decimals
2114 | },
2115 | 'weSUSHI-USDC-V4': {
2116 | symbol: 'weSUSHI-USDC',
2117 | name: 'weSUSHI-USDC LP',
2118 | coin: { ...TOKENS.weSUSHI },
2119 | pc: { ...TOKENS.USDC },
2120 |
2121 | mintAddress: '3wVrtQZsiDNp5yTPyfEzQHPU6iuJoMmpnWg6CTt4V8sR',
2122 | decimals: TOKENS.weSUSHI.decimals
2123 | },
2124 | 'CYS-USDC-V4': {
2125 | symbol: 'CYS-USDC',
2126 | name: 'CYS-USDC LP',
2127 | coin: { ...TOKENS.CYS },
2128 | pc: { ...TOKENS.USDC },
2129 |
2130 | mintAddress: 'GfV3QDzzdVUwCNSdfn6PjhmyJvjw18tn51RingWZYwk3',
2131 | decimals: TOKENS.CYS.decimals
2132 | },
2133 | 'SAMO-USDC-V4': {
2134 | symbol: 'SAMO-USDC',
2135 | name: 'SAMO-USDC LP',
2136 | coin: { ...TOKENS.SAMO },
2137 | pc: { ...TOKENS.USDC },
2138 |
2139 | mintAddress: 'B2PjGEP3vPf1999fUD14pYdxvSDRVBk43hxB2rgthwEY',
2140 | decimals: TOKENS.SAMO.decimals
2141 | },
2142 | 'ABR-USDC-V4': {
2143 | symbol: 'ABR-USDC',
2144 | name: 'ABR-USDC LP',
2145 | coin: { ...TOKENS.ABR },
2146 | pc: { ...TOKENS.USDC },
2147 |
2148 | mintAddress: 'ECHfxkf5zjjZFTX95QfFahNyzG7feyEKcfTdjsdrMSGU',
2149 | decimals: TOKENS.ABR.decimals
2150 | },
2151 | 'IN-USDC-V4': {
2152 | symbol: 'IN-USDC',
2153 | name: 'IN-USDC LP',
2154 | coin: { ...TOKENS.IN },
2155 | pc: { ...TOKENS.USDC },
2156 |
2157 | mintAddress: 'GbmJtVgg9fRmmmjKUYGMZeSt8wZ47cDDXasg5Y3iF4kz',
2158 | decimals: TOKENS.IN.decimals
2159 | },
2160 | 'weDYDX-USDC-V4': {
2161 | symbol: 'weDYDX-USDC',
2162 | name: 'weDYDX-USDC LP',
2163 | coin: { ...TOKENS.weDYDX },
2164 | pc: { ...TOKENS.USDC },
2165 |
2166 | mintAddress: 'BjkkMZnnzmgLqzGErzDbkk15ozv48iVKQuunpeM2Hqnk',
2167 | decimals: TOKENS.weDYDX.decimals
2168 | },
2169 | 'STARS-USDC-V4': {
2170 | symbol: 'STARS-USDC',
2171 | name: 'STARS-USDC LP',
2172 | coin: { ...TOKENS.STARS },
2173 | pc: { ...TOKENS.USDC },
2174 |
2175 | mintAddress: 'FJ68q7NChhETcGVdinMbM2FF1Cy79dpmUi6HC83K55Hv',
2176 | decimals: TOKENS.STARS.decimals
2177 | },
2178 | 'weAXS-USDC-V4': {
2179 | symbol: 'weAXS-USDC',
2180 | name: 'weAXS-USDC LP',
2181 | coin: { ...TOKENS.weAXS },
2182 | pc: { ...TOKENS.USDC },
2183 |
2184 | mintAddress: '6PSoJQ7myQ1BJtbQC6oiWR8HSecQGyoWsPYTZRJo2ci3',
2185 | decimals: TOKENS.weAXS.decimals
2186 | },
2187 | 'weSHIB-USDC-V4': {
2188 | symbol: 'weSHIB-USDC',
2189 | name: 'weSHIB-USDC LP',
2190 | coin: { ...TOKENS.weSHIB },
2191 | pc: { ...TOKENS.USDC },
2192 |
2193 | mintAddress: 'AcjX5pmTMGSgxkdxc3r82r6WMKBvS6eQXXFz5ck5KKUa',
2194 | decimals: TOKENS.weSHIB.decimals
2195 | },
2196 | 'SBR-USDC-V4': {
2197 | symbol: 'SBR-USDC',
2198 | name: 'SBR-USDC LP',
2199 | coin: { ...TOKENS.SBR },
2200 | pc: { ...TOKENS.USDC },
2201 |
2202 | mintAddress: '9FC8xTFRbgTpuZZYAYnZLxgnQ8r7FwfSBM1SWvGwgF7s',
2203 | decimals: TOKENS.SBR.decimals
2204 | },
2205 | 'OXS-USDC-V4': {
2206 | symbol: 'OXS-USDC',
2207 | name: 'OXS-USDC LP',
2208 | coin: { ...TOKENS.OXS },
2209 | pc: { ...TOKENS.USDC },
2210 |
2211 | mintAddress: 'et9pdjWm97rbmsJoN183GkFV5qzTGru79GE1Zhe7NTU',
2212 | decimals: TOKENS.OXS.decimals
2213 | },
2214 | 'CWAR-USDC-V4': {
2215 | symbol: 'CWAR-USDC',
2216 | name: 'CWAR-USDC LP',
2217 | coin: { ...TOKENS.CWAR },
2218 | pc: { ...TOKENS.USDC },
2219 |
2220 | mintAddress: 'HjR23bxn2gtRDB2P1Tm3DLepAPPZgazsWJpLG9wqjnYR',
2221 | decimals: TOKENS.CWAR.decimals
2222 | },
2223 | 'UPS-USDC-V4': {
2224 | symbol: 'UPS-USDC',
2225 | name: 'UPS-USDC LP',
2226 | coin: { ...TOKENS.UPS },
2227 | pc: { ...TOKENS.USDC },
2228 |
2229 | mintAddress: '9hSUZdREEsbaYaKY4FouvXr7xyAqtpdHRDoYCb6Mb28a',
2230 | decimals: TOKENS.UPS.decimals
2231 | },
2232 | 'weSAND-USDC-V4': {
2233 | symbol: 'weSAND-USDC',
2234 | name: 'weSAND-USDC LP',
2235 | coin: { ...TOKENS.weSAND },
2236 | pc: { ...TOKENS.USDC },
2237 |
2238 | mintAddress: '3dADrQa7utyiCsaFeVk9r7oebW1WheowhKo5soBYKBVT',
2239 | decimals: TOKENS.weSAND.decimals
2240 | },
2241 | 'weMANA-USDC-V4': {
2242 | symbol: 'weMANA-USDC',
2243 | name: 'weMANA-USDC LP',
2244 | coin: { ...TOKENS.weMANA },
2245 | pc: { ...TOKENS.USDC },
2246 |
2247 | mintAddress: 'HpUkVAPRJ5zNRuJ1ZwMXEhbMHL3gSuPb2QuSER9YUd3a',
2248 | decimals: TOKENS.weMANA.decimals
2249 | },
2250 | 'CAVE-USDC-V4': {
2251 | symbol: 'CAVE-USDC',
2252 | name: 'CAVE-USDC LP',
2253 | coin: { ...TOKENS.CAVE },
2254 | pc: { ...TOKENS.USDC },
2255 |
2256 | mintAddress: '5Gba1k3fU7Vh7UtAiBmie9vhQNNq1JfEwgn1DPGZ7NKQ',
2257 | decimals: TOKENS.CAVE.decimals
2258 | },
2259 | 'GENE-USDC-V4': {
2260 | symbol: 'GENE-USDC',
2261 | name: 'GENE-USDC LP',
2262 | coin: { ...TOKENS.GENE },
2263 | pc: { ...TOKENS.USDC },
2264 |
2265 | mintAddress: '7GKvfHEXenNiWYbJBKae89mdaMPr5gGMYwZmyC8gBNVG',
2266 | decimals: TOKENS.GENE.decimals
2267 | },
2268 | 'GENE-RAY-V4': {
2269 | symbol: 'GENE-RAY',
2270 | name: 'GENE-RAY LP',
2271 | coin: { ...TOKENS.GENE },
2272 | pc: { ...TOKENS.RAY },
2273 |
2274 | mintAddress: '3HzXnc1qZ8mGqun18Ck3KA616XnZNqF1RWbgYE2nGRMA',
2275 | decimals: TOKENS.GENE.decimals
2276 | },
2277 | 'APT-USDC-V4': {
2278 | symbol: 'APT-USDC',
2279 | name: 'APT-USDC LP',
2280 | coin: { ...TOKENS.APT },
2281 | pc: { ...TOKENS.USDC },
2282 |
2283 | mintAddress: 'Hk8mDAJFq4E9kF3DtNgPFwzbo5kbeiusNFJgWmo3LoQ5',
2284 | decimals: TOKENS.APT.decimals
2285 | },
2286 | 'GOFX-USDC-V4': {
2287 | symbol: 'GOFX-USDC',
2288 | name: 'GOFX-USDC LP',
2289 | coin: { ...TOKENS.GOFX },
2290 | pc: { ...TOKENS.USDC },
2291 |
2292 | mintAddress: '4svqAwrLPGRDCQuuieYTmtLXF75wiahjeK2rEN9tY1YL',
2293 | decimals: TOKENS.GOFX.decimals
2294 | },
2295 | 'SONAR-USDC-V4': {
2296 | symbol: 'SONAR-USDC',
2297 | name: 'SONAR-USDC LP',
2298 | coin: { ...TOKENS.SONAR },
2299 | pc: { ...TOKENS.USDC },
2300 |
2301 | mintAddress: '2tAcfqJ1YYjpGLqwh76kyNt9VaNFDd4fJySfH6SmWfKt',
2302 | decimals: TOKENS.SONAR.decimals
2303 | },
2304 | 'JSOL-SOL-V4': {
2305 | symbol: 'JSOL-SOL',
2306 | name: 'JSOL-SOL LP',
2307 | coin: { ...TOKENS.JSOL },
2308 | pc: { ...NATIVE_SOL },
2309 |
2310 | mintAddress: '61z37rpHsU6d3Fq5sUjJ85K6tXGzkoYKDAG3kPJQNDRo',
2311 | decimals: TOKENS.JSOL.decimals
2312 | },
2313 | 'JSOL-USDC-V4': {
2314 | symbol: 'JSOL-USDC',
2315 | name: 'JSOL-USDC LP',
2316 | coin: { ...TOKENS.JSOL },
2317 | pc: { ...TOKENS.USDC },
2318 |
2319 | mintAddress: '3JZqf2VPNxj1kDZQsfzC7myM6spsGQbGuFv1gVfdYosN',
2320 | decimals: TOKENS.JSOL.decimals
2321 | },
2322 | 'SHILL-USDC-V4': {
2323 | symbol: 'SHILL-USDC',
2324 | name: 'SHILL-USDC LP',
2325 | coin: { ...TOKENS.SHILL },
2326 | pc: { ...TOKENS.USDC },
2327 |
2328 | mintAddress: 'CnUhYBtQEbSBZ76bgxAouVCTCb8rofZzwerVF5z5LREJ',
2329 | decimals: TOKENS.SHILL.decimals
2330 | },
2331 | 'DFL-USDC-V4': {
2332 | symbol: 'DFL-USDC',
2333 | name: 'DFL-USDC LP',
2334 | coin: { ...TOKENS.DFL },
2335 | pc: { ...TOKENS.USDC },
2336 |
2337 | mintAddress: 'Fffijd6UVJdQeLVXhenS8YcsnMUdWJqpbBeH42LFkXgS',
2338 | decimals: TOKENS.DFL.decimals
2339 | },
2340 | 'BOKU-USDC-V4': {
2341 | symbol: 'BOKU-USDC',
2342 | name: 'BOKU-USDC LP',
2343 | coin: { ...TOKENS.BOKU },
2344 | pc: { ...TOKENS.USDC },
2345 |
2346 | mintAddress: '8jjQn5Yagb6Nm2WGAxPW1bcGqrTWpg5adf6QukXEarcP',
2347 | decimals: TOKENS.BOKU.decimals
2348 | },
2349 | 'MIMO-SOL-V4': {
2350 | symbol: 'MIMO-SOL',
2351 | name: 'MIMO-SOL LP',
2352 | coin: { ...TOKENS.MIMO },
2353 | pc: { ...NATIVE_SOL },
2354 |
2355 | mintAddress: 'HUJ1opSk8AiPfDT47r7n4hTiK2EXgrR3Msy7T8q1BywS',
2356 | decimals: TOKENS.MIMO.decimals
2357 | },
2358 | 'wbWBNB-USDC-V4': {
2359 | symbol: 'wbWBNB-USDC',
2360 | name: 'wbWBNB-USDC LP',
2361 | coin: { ...TOKENS.wbWBNB },
2362 | pc: { ...TOKENS.USDC },
2363 |
2364 | mintAddress: 'FEsEfEJJSfiMQcshUgZ5UigfytfGRQ3z5puyF6DXDp9C',
2365 | decimals: TOKENS.wbWBNB.decimals
2366 | },
2367 | 'wePEOPLE-USDC-V4': {
2368 | symbol: 'wePEOPLE-USDC',
2369 | name: 'wePEOPLE-USDC LP',
2370 | coin: { ...TOKENS.wePEOPLE },
2371 | pc: { ...TOKENS.USDC },
2372 |
2373 | mintAddress: '3e5ZCKi4etorpV4pv1fSckP5iJD67xcUkx3RtFCZhbzD',
2374 | decimals: TOKENS.wePEOPLE.decimals
2375 | },
2376 | 'ISOLA-USDT-V4': {
2377 | symbol: 'ISOLA-USDT',
2378 | name: 'ISOLA-USDT LP',
2379 | coin: { ...TOKENS.ISOLA },
2380 | pc: { ...TOKENS.USDT },
2381 |
2382 | mintAddress: 'H8s1wQsZpRK61pyLF3XwyQc6E8vNUnwRDhy3TBDCDENQ',
2383 | decimals: TOKENS.ISOLA.decimals
2384 | },
2385 | 'SPWN-USDC-V4': {
2386 | symbol: 'SPWN-USDC',
2387 | name: 'SPWN-USDC LP',
2388 | coin: { ...TOKENS.SPWN },
2389 | pc: { ...TOKENS.USDC },
2390 |
2391 | mintAddress: 'B5uyCAQcX6nAjZypLgiivbEKabSptgUb8JK9tkaSnqdW',
2392 | decimals: TOKENS.SPWN.decimals
2393 | },
2394 | 'STR-USDC-V4': {
2395 | symbol: 'STR-USDC',
2396 | name: 'STR-USDC LP',
2397 | coin: { ...TOKENS.STR },
2398 | pc: { ...TOKENS.USDC },
2399 |
2400 | mintAddress: '8uDVKmVwNmbXHDB7rNKqtpcT9VAsFHTJ5pPYxjyoBbNg',
2401 | decimals: TOKENS.STR.decimals
2402 | },
2403 | 'SOLC-USDT-V4': {
2404 | symbol: 'SOLC-USDT',
2405 | name: 'SOLC-USDT LP',
2406 | coin: { ...TOKENS.SOLC },
2407 | pc: { ...TOKENS.USDT },
2408 |
2409 | mintAddress: '2g9JzTWycLzK4KEBBHsponAtZRee2ii63bRrJ8tefEyt',
2410 | decimals: TOKENS.SOLC.decimals
2411 | },
2412 | 'VI-USDC-V4': {
2413 | symbol: 'VI-USDC',
2414 | name: 'VI-USDC LP',
2415 | coin: { ...TOKENS.VI },
2416 | pc: { ...TOKENS.USDC },
2417 |
2418 | mintAddress: '3MwHyHCRfVqtH3ABFtdKXdY9dwemr9GGxQFaBkeq6NjY',
2419 | decimals: TOKENS.VI.decimals
2420 | },
2421 | 'KKO-USDC-V4': {
2422 | symbol: 'KKO-USDC',
2423 | name: 'KKO-USDC LP',
2424 | coin: { ...TOKENS.KKO },
2425 | pc: { ...TOKENS.USDC },
2426 |
2427 | mintAddress: '7xr1Doc1NiMWbUg99YVFqQSLfYXNzo6YvacXUsSgBMNW',
2428 | decimals: TOKENS.KKO.decimals
2429 | },
2430 | 'XTAG-USDC-V4': {
2431 | symbol: 'XTAG-USDC',
2432 | name: 'XTAG-USDC LP',
2433 | coin: { ...TOKENS.XTAG },
2434 | pc: { ...TOKENS.USDC },
2435 |
2436 | mintAddress: 'GCEQbLg4ik5YJ4CMcbtuVqEc4sjLdSGy34rFk1CtGjdg',
2437 | decimals: TOKENS.XTAG.decimals
2438 | },
2439 | 'TTT-USDC-V4': {
2440 | symbol: 'TTT-USDC',
2441 | name: 'TTT-USDC LP',
2442 | coin: { ...TOKENS.TTT },
2443 | pc: { ...TOKENS.USDC },
2444 |
2445 | mintAddress: '84fmrerHGohoRf4iLPDQ1KG4CjSjCRksYWGzjWfCRM8a',
2446 | decimals: TOKENS.TTT.decimals
2447 | },
2448 | 'RUN-USDC-V4': {
2449 | symbol: 'RUN-USDC',
2450 | name: 'RUN-USDC LP',
2451 | coin: { ...TOKENS.RUN },
2452 | pc: { ...TOKENS.USDC },
2453 |
2454 | mintAddress: 'CjTLvvKSQdEujcSzeZRYgk4w1DpuXBbMppLHaxZyz11Y',
2455 | decimals: TOKENS.RUN.decimals
2456 | },
2457 | 'CRWNY-USDC-V4': {
2458 | symbol: 'CRWNY-USDC',
2459 | name: 'CRWNY-USDC LP',
2460 | coin: { ...TOKENS.CRWNY },
2461 | pc: { ...TOKENS.USDC },
2462 |
2463 | mintAddress: 'H3D9Gyi4frRLW6bS9vBthDVDJyzyRJ6XhhpP6PJGWaDC',
2464 | decimals: TOKENS.CRWNY.decimals
2465 | },
2466 | 'CRWNY-RAY-V4': {
2467 | symbol: 'CRWNY-RAY',
2468 | name: 'CRWNY-RAY LP',
2469 | coin: { ...TOKENS.CRWNY },
2470 | pc: { ...TOKENS.RAY },
2471 |
2472 | mintAddress: '5Cz9wGStNjiUg81q8t6sJJeckuT2C14CYSfyQbtYirSX',
2473 | decimals: TOKENS.CRWNY.decimals
2474 | },
2475 | 'BLOCK-USDC-V4': {
2476 | symbol: 'BLOCK-USDC',
2477 | name: 'BLOCK-USDC LP',
2478 | coin: { ...TOKENS.BLOCK },
2479 | pc: { ...TOKENS.USDC },
2480 |
2481 | mintAddress: '8i44Y23GkkwDYZ5iSkVEqmrXUfwNmwo9grguTDWKM8wg',
2482 | decimals: TOKENS.BLOCK.decimals
2483 | },
2484 | 'REAL-USDC-V4': {
2485 | symbol: 'REAL-USDC',
2486 | name: 'REAL-USDC LP',
2487 | coin: { ...TOKENS.REAL },
2488 | pc: { ...TOKENS.USDC },
2489 |
2490 | mintAddress: 'EN43tp8xdkcM8RYSJ4msFHMPTJRXKhUteVYBDJLwTvr3',
2491 | decimals: TOKENS.REAL.decimals
2492 | }
2493 | }
2494 |
2495 | function addUserLocalCoinMint() {
2496 | const localMintStr = window.localStorage.user_add_coin_mint
2497 | const localMintList = (localMintStr ?? '').split('---')
2498 | if (localMintList.length % 3 !== 0) {
2499 | window.localStorage.removeItem('user_add_coin_mint')
2500 | } else {
2501 | for (let index = 0; index < Math.floor(localMintList.length / 3); index += 1) {
2502 | const name = localMintList[index * 3 + 0]
2503 | const mintAddress = localMintList[index * 3 + 1]
2504 | const decimals = localMintList[index * 3 + 2]
2505 | if (!Object.values(TOKENS).find((item) => item.mintAddress === mintAddress)) {
2506 | TOKENS[name + mintAddress + 'unofficialUserAdd'] = {
2507 | name,
2508 | symbol: name,
2509 | decimals: parseInt(decimals),
2510 | mintAddress,
2511 | tags: ['userAdd']
2512 | }
2513 | } else if (
2514 | !Object.values(TOKENS)
2515 | .find((item) => item.mintAddress === mintAddress)
2516 | .tags.includes('userAdd')
2517 | ) {
2518 | Object.values(TOKENS)
2519 | .find((item) => item.mintAddress === mintAddress)
2520 | .tags.push('userAdd')
2521 | }
2522 | }
2523 | }
2524 | }
2525 |
2526 | // fake
2527 | const BLACK_LIST = ['3pX59cis3ZXnX6ZExPoUQjpvJVspmj4YavtUmpTpkB33']
2528 |
2529 | function blockBlackList(tokens: { address: string }[]) {
2530 | return tokens.filter((item) => !BLACK_LIST.includes(item.address))
2531 | }
2532 |
2533 | function addTokensSolana() {
2534 | fetch('https://api.raydium.io/cache/solana-token-list')
2535 | .then(async (response) => {
2536 | addTokensSolanaFunc(blockBlackList((await response.json()).tokens))
2537 | })
2538 | .catch(() => {
2539 | fetch('https://raw.githubusercontent.com/solana-labs/token-list/main/src/tokens/solana.tokenlist.json')
2540 | .then(function (response) {
2541 | return response.json()
2542 | })
2543 | .then(function (myJson) {
2544 | addTokensSolanaFunc(blockBlackList(myJson.tokens))
2545 | })
2546 | })
2547 | }
2548 |
2549 | const notUseSolanaPicMint: string[] = [TOKENS.TTT.mintAddress]
2550 |
2551 | function addTokensSolanaFunc(tokens: any[]) {
2552 | tokens.forEach((itemToken: any) => {
2553 | if (itemToken.tags && itemToken.tags.includes('lp-token')) {
2554 | return
2555 | }
2556 | if (!Object.values(TOKENS).find((item) => item.mintAddress === itemToken.address)) {
2557 | TOKENS[itemToken.symbol + itemToken.address + 'solana'] = {
2558 | symbol: itemToken.symbol,
2559 | name: itemToken.name,
2560 | mintAddress: itemToken.address,
2561 | decimals: itemToken.decimals,
2562 | picUrl: itemToken.logoURI,
2563 | tags: ['solana']
2564 | }
2565 | } else {
2566 | const token = Object.values(TOKENS).find((item) => item.mintAddress === itemToken.address)
2567 | if (token.symbol !== itemToken.symbol && !token.tags.includes('raydium')) {
2568 | token.symbol = itemToken.symbol
2569 | token.name = itemToken.name
2570 | token.decimals = itemToken.decimals
2571 | token.tags.push('solana')
2572 | }
2573 | const picToken = Object.values(TOKENS).find((item) => item.mintAddress === itemToken.address)
2574 | if (picToken && !notUseSolanaPicMint.includes(itemToken.address)) {
2575 | picToken.picUrl = itemToken.logoURI
2576 | }
2577 | }
2578 | })
2579 |
2580 | if (window.localStorage.addSolanaCoin) {
2581 | window.localStorage.addSolanaCoin.split('---').forEach((itemMint: string) => {
2582 | if (itemMint === NATIVE_SOL.mintAddress) NATIVE_SOL.tags.push('userAdd')
2583 | else
2584 | Object.keys(TOKENS).forEach((item) => {
2585 | if (TOKENS[item].mintAddress === itemMint) {
2586 | TOKENS[item].tags.push('userAdd')
2587 | }
2588 | })
2589 | })
2590 | }
2591 | }
2592 |
2593 | function updateTokenTagsChange() {
2594 | const userSelectSource = window.localStorage.userSelectSource ?? ''
2595 | const userSelectSourceList: string[] = userSelectSource.split('---')
2596 | for (const itemSource of userSelectSourceList) {
2597 | if (TOKENS_TAGS[itemSource] && !TOKENS_TAGS[itemSource].mustShow) {
2598 | TOKENS_TAGS[itemSource].show = true
2599 | }
2600 | }
2601 | }
2602 |
2603 | addUserLocalCoinMint()
2604 | addTokensSolana()
2605 | updateTokenTagsChange()
2606 |
--------------------------------------------------------------------------------
/utils/types.d.ts:
--------------------------------------------------------------------------------
1 |
2 | declare global {
3 |
4 | // tokens.ts
5 | interface TokenInfo {
6 | symbol: string
7 | name: string
8 |
9 | mintAddress: string
10 | decimals: number
11 | totalSupply?: TokenAmount
12 |
13 | referrer?: string
14 |
15 | details?: string
16 | docs?: object
17 | socials?: object
18 |
19 | tokenAccountAddress?: string
20 | balance?: TokenAmount
21 | tags: string[]
22 | }
23 |
24 | // pools.ts
25 |
26 | interface LiquidityPoolInfo {
27 | name: string;
28 | coin: TokenInfo;
29 | pc: TokenInfo;
30 | lp: TokenInfo;
31 |
32 | version: number;
33 | programId: string;
34 |
35 | ammId: string;
36 | ammAuthority: string;
37 | ammOpenOrders: string;
38 | ammTargetOrders: string;
39 | ammQuantities: string;
40 |
41 | poolCoinTokenAccount: string;
42 | poolPcTokenAccount: string;
43 | poolWithdrawQueue: string;
44 | poolTempLpTokenAccount: string;
45 |
46 | serumProgramId: string;
47 | serumMarket: string;
48 | serumBids?: string;
49 | serumAsks?: string;
50 | serumEventQueue?: string;
51 | serumCoinVaultAccount: string;
52 | serumPcVaultAccount: string;
53 | serumVaultSigner: string;
54 |
55 | official: boolean;
56 |
57 | status?: number;
58 | currentK?: number;
59 | }
60 | }
61 | export {}
--------------------------------------------------------------------------------
/utils/web3.ts:
--------------------------------------------------------------------------------
1 | import { initializeAccount } from "@project-serum/serum/lib/token-instructions";
2 | import { WalletContextState } from "@solana/wallet-adapter-react";
3 |
4 | // @ts-ignore without ts ignore, yarn build will failed
5 | import { Token } from "@solana/spl-token";
6 | import {
7 | Keypair, // Account is deprecated, using Keypair instead
8 | Commitment,
9 | Connection,
10 | PublicKey,
11 | TransactionSignature,
12 | Transaction,
13 | SystemProgram,
14 | AccountInfo,
15 | LAMPORTS_PER_SOL
16 | } from "@solana/web3.js";
17 |
18 | import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from "./ids";
19 | import { ACCOUNT_LAYOUT } from "./layouts";
20 |
21 | export const commitment: Commitment = "confirmed";
22 | export async function createTokenAccountIfNotExist( // returns Token Account
23 | connection: Connection,
24 | account: string | undefined | null,
25 | owner: PublicKey,
26 | mintAddress: string,
27 | lamports: number | null,
28 |
29 | transaction: Transaction,
30 | signer: Array
31 | ) : Promise {
32 | let publicKey;
33 |
34 | if (account) {
35 | publicKey = new PublicKey(account);
36 | } else {
37 | publicKey = await createProgramAccountIfNotExist(
38 | connection,
39 | account,
40 | owner,
41 | TOKEN_PROGRAM_ID,
42 | lamports,
43 | ACCOUNT_LAYOUT,
44 | transaction,
45 | signer
46 | );
47 |
48 | transaction.add(
49 | initializeAccount({
50 | account: publicKey,
51 | mint: new PublicKey(mintAddress),
52 | owner
53 | })
54 | );
55 | }
56 | return publicKey;
57 | }
58 |
59 | export async function createAssociatedTokenAccountIfNotExist(
60 | account: string | undefined | null,
61 | owner: PublicKey,
62 | mintAddress: string,
63 |
64 | transaction: Transaction,
65 | atas: string[] = []
66 | ) {
67 | let publicKey;
68 | if (account) {
69 | publicKey = new PublicKey(account);
70 | }
71 |
72 | const mint = new PublicKey(mintAddress);
73 | // @ts-ignore without ts ignore, yarn build will failed
74 | const ata = await Token.getAssociatedTokenAddress(
75 | ASSOCIATED_TOKEN_PROGRAM_ID,
76 | TOKEN_PROGRAM_ID,
77 | mint,
78 | owner,
79 | true
80 | );
81 |
82 | if (
83 | (!publicKey || !ata.equals(publicKey)) &&
84 | !atas.includes(ata.toBase58())
85 | ) {
86 | transaction.add(
87 | Token.createAssociatedTokenAccountInstruction(
88 | ASSOCIATED_TOKEN_PROGRAM_ID,
89 | TOKEN_PROGRAM_ID,
90 | mint,
91 | ata,
92 | owner,
93 | owner
94 | )
95 | );
96 | atas.push(ata.toBase58());
97 | }
98 |
99 | return ata;
100 | }
101 |
102 | export async function sendTransaction(
103 | connection: Connection,
104 | wallet: any,
105 | transaction: Transaction,
106 | signers: Array = []
107 | ) {
108 | const txid: TransactionSignature = await wallet.sendTransaction(
109 | transaction,
110 | connection,
111 | {
112 | signers,
113 | skipPreflight: true,
114 | preflightCommitment: commitment
115 | }
116 | );
117 |
118 | return txid;
119 | }
120 |
121 | export async function createProgramAccountIfNotExist(
122 | connection: Connection,
123 | account: string | undefined | null,
124 | owner: PublicKey,
125 | programId: PublicKey,
126 | lamports: number | null,
127 | layout: any,
128 |
129 | transaction: Transaction,
130 | signer: Array
131 | ) {
132 | let publicKey;
133 |
134 | if (account) {
135 | publicKey = new PublicKey(account);
136 | } else {
137 | const newAccount = new Keypair();
138 | publicKey = newAccount.publicKey;
139 |
140 | transaction.add(
141 | SystemProgram.createAccount({
142 | fromPubkey: owner,
143 | newAccountPubkey: publicKey,
144 | lamports:
145 | lamports ??
146 | (await connection.getMinimumBalanceForRentExemption(layout.span)),
147 | space: layout.span,
148 | programId
149 | })
150 | );
151 |
152 | signer.push(newAccount);
153 | }
154 |
155 | return publicKey;
156 | }
157 |
158 | export async function findAssociatedTokenAddress(
159 | walletAddress: PublicKey,
160 | tokenMintAddress: PublicKey
161 | ) {
162 | const { publicKey } = await findProgramAddress(
163 | [
164 | walletAddress.toBuffer(),
165 | TOKEN_PROGRAM_ID.toBuffer(),
166 | tokenMintAddress.toBuffer()
167 | ],
168 | ASSOCIATED_TOKEN_PROGRAM_ID
169 | );
170 | return publicKey;
171 | }
172 |
173 | export async function findProgramAddress(
174 | seeds: Array,
175 | programId: PublicKey
176 | ) {
177 | const [publicKey, nonce] = await PublicKey.findProgramAddress(
178 | seeds,
179 | programId
180 | );
181 | return { publicKey, nonce };
182 | }
183 |
184 | export async function getMultipleAccounts(
185 | connection: Connection,
186 | publicKeys: PublicKey[],
187 | commitment?: Commitment
188 | ): Promise }>> {
189 | const keys: PublicKey[][] = [];
190 | let tempKeys: PublicKey[] = [];
191 |
192 | publicKeys.forEach(k => {
193 | if (tempKeys.length >= 100) {
194 | keys.push(tempKeys);
195 | tempKeys = [];
196 | }
197 | tempKeys.push(k);
198 | });
199 | if (tempKeys.length > 0) {
200 | keys.push(tempKeys);
201 | }
202 |
203 | const accounts: Array = [];
209 | const resArray: { [key: number]: any } = {};
210 |
211 | await Promise.all(
212 | keys.map(async (key, index) => {
213 | const res = await connection.getMultipleAccountsInfo(key, commitment);
214 | resArray[index] = res;
215 | })
216 | );
217 |
218 | Object.keys(resArray)
219 | .sort((a, b) => parseInt(a) - parseInt(b))
220 | .forEach(itemIndex => {
221 | const res = resArray[parseInt(itemIndex)];
222 | for (const account of res) {
223 | accounts.push(account);
224 | }
225 | });
226 |
227 | return accounts.map((account, idx) => {
228 | if (account === null) {
229 | return null;
230 | }
231 | return {
232 | publicKey: publicKeys[idx],
233 | account
234 | };
235 | });
236 | }
237 |
238 | export async function getFilteredProgramAccountsAmmOrMarketCache(
239 | cacheName: String,
240 | connection: Connection,
241 | programId: PublicKey,
242 | filters: any
243 | ): Promise<{ publicKey: PublicKey; accountInfo: AccountInfo }[]> {
244 | try {
245 | if (!cacheName) {
246 | throw new Error("cacheName error");
247 | }
248 |
249 | const resp = await (
250 | await fetch("https://api.raydium.io/cache/rpc/" + cacheName)
251 | ).json();
252 | if (resp.error) {
253 | throw new Error(resp.error.message);
254 | }
255 | // @ts-ignore
256 | return resp.result.map(
257 | // @ts-ignore
258 | ({ pubkey, account: { data, executable, owner, lamports } }) => ({
259 | publicKey: new PublicKey(pubkey),
260 | accountInfo: {
261 | data: Buffer.from(data[0], "base64"),
262 | executable,
263 | owner: new PublicKey(owner),
264 | lamports
265 | }
266 | })
267 | );
268 | } catch (e) {
269 | return getFilteredProgramAccounts(connection, programId, filters);
270 | }
271 | }
272 |
273 | export async function getFilteredProgramAccounts(
274 | connection: Connection,
275 | programId: PublicKey,
276 | filters: any
277 | ): Promise<{ publicKey: PublicKey; accountInfo: AccountInfo }[]> {
278 | // @ts-ignore
279 | const resp = await connection._rpcRequest("getProgramAccounts", [
280 | programId.toBase58(),
281 | {
282 | commitment: connection.commitment,
283 | filters,
284 | encoding: "base64"
285 | }
286 | ]);
287 | if (resp.error) {
288 | throw new Error(resp.error.message);
289 | }
290 | return resp.result.map(
291 | // @ts-ignore
292 | ({ pubkey, account: { data, executable, owner, lamports } }) => ({
293 | publicKey: new PublicKey(pubkey),
294 | accountInfo: {
295 | data: Buffer.from(data[0], "base64"),
296 | executable,
297 | owner: new PublicKey(owner),
298 | lamports
299 | }
300 | })
301 | );
302 | }
303 |
304 | export async function createAmmAuthority(programId: PublicKey) {
305 | return await findProgramAddress(
306 | [
307 | new Uint8Array(
308 | Buffer.from("amm authority".replace("\u00A0", " "), "utf-8")
309 | )
310 | ],
311 | programId
312 | );
313 | }
314 | // export interface ISplToken {
315 | // pubkey: string;
316 | // parsedInfo: any;
317 | // amount: number;
318 | // }
319 |
320 | export const getSPLTokenData = async (
321 | wallet: WalletContextState,
322 | connection: Connection
323 | ): Promise => {
324 | if (!wallet.connected) {
325 | return [];
326 | }
327 | const res = await connection.getParsedTokenAccountsByOwner(
328 | wallet.publicKey!,
329 | {
330 | programId: new PublicKey(TOKEN_PROGRAM_ID)
331 | },
332 | "confirmed"
333 | );
334 | // Get all SPL tokens owned by connected wallet
335 | let data = await connection.getAccountInfo(wallet.publicKey!);
336 |
337 | let list = res.value.map(item => {
338 | let token = {
339 | pubkey: item.pubkey.toBase58(),
340 | parsedInfo: item.account.data.parsed.info,
341 | amount:
342 | item.account.data.parsed.info.tokenAmount.amount /
343 | 10 ** item.account.data.parsed.info.tokenAmount.decimals
344 | };
345 | // Filter out empty account
346 | if (item.account.data.parsed.info.tokenAmount.decimals === 0) {
347 | return undefined;
348 | } else {
349 | return token;
350 | }
351 | });
352 | // Add SOL into list
353 | list.push({
354 | //@ts-ignore
355 | pubkey: wallet.publicKey?.toBase58(),
356 | parsedInfo: {
357 | mint: data?.owner.toBase58()
358 | },
359 | //@ts-ignore
360 | amount: data?.lamports / LAMPORTS_PER_SOL
361 | });
362 | return list as ISplToken[];
363 | };
364 |
--------------------------------------------------------------------------------