four-flap-meme-sdk 1.5.55 → 1.5.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/sol/constants.d.ts +150 -0
- package/dist/sol/constants.js +188 -0
- package/dist/sol/dex/blockrazor/client.d.ts +51 -0
- package/dist/sol/dex/blockrazor/client.js +96 -0
- package/dist/sol/dex/blockrazor/constants.d.ts +34 -0
- package/dist/sol/dex/blockrazor/constants.js +55 -0
- package/dist/sol/dex/blockrazor/geyser.d.ts +128 -0
- package/dist/sol/dex/blockrazor/geyser.js +530 -0
- package/dist/sol/dex/blockrazor/index.d.ts +18 -0
- package/dist/sol/dex/blockrazor/index.js +23 -0
- package/dist/sol/dex/blockrazor/send.d.ts +135 -0
- package/dist/sol/dex/blockrazor/send.js +254 -0
- package/dist/sol/dex/blockrazor/types.d.ts +191 -0
- package/dist/sol/dex/blockrazor/types.js +5 -0
- package/dist/sol/dex/index.d.ts +10 -0
- package/dist/sol/dex/index.js +16 -0
- package/dist/sol/dex/jup/client.d.ts +33 -0
- package/dist/sol/dex/jup/client.js +110 -0
- package/dist/sol/dex/jup/index.d.ts +16 -0
- package/dist/sol/dex/jup/index.js +148 -0
- package/dist/sol/dex/jup/legacy.d.ts +623 -0
- package/dist/sol/dex/jup/legacy.js +416 -0
- package/dist/sol/dex/jup/lend.d.ts +640 -0
- package/dist/sol/dex/jup/lend.js +603 -0
- package/dist/sol/dex/jup/portfolio.d.ts +362 -0
- package/dist/sol/dex/jup/portfolio.js +367 -0
- package/dist/sol/dex/jup/price.d.ts +173 -0
- package/dist/sol/dex/jup/price.js +220 -0
- package/dist/sol/dex/jup/recurring.d.ts +437 -0
- package/dist/sol/dex/jup/recurring.js +320 -0
- package/dist/sol/dex/jup/send.d.ts +282 -0
- package/dist/sol/dex/jup/send.js +295 -0
- package/dist/sol/dex/jup/studio.d.ts +457 -0
- package/dist/sol/dex/jup/studio.js +488 -0
- package/dist/sol/dex/jup/tokens.d.ts +767 -0
- package/dist/sol/dex/jup/tokens.js +697 -0
- package/dist/sol/dex/jup/trigger.d.ts +511 -0
- package/dist/sol/dex/jup/trigger.js +397 -0
- package/dist/sol/dex/jup/types.d.ts +433 -0
- package/dist/sol/dex/jup/types.js +5 -0
- package/dist/sol/dex/jup/ultra.d.ts +646 -0
- package/dist/sol/dex/jup/ultra.js +853 -0
- package/dist/sol/dex/meteora/client.d.ts +76 -0
- package/dist/sol/dex/meteora/client.js +219 -0
- package/dist/sol/dex/meteora/damm-v1-bundle.d.ts +61 -0
- package/dist/sol/dex/meteora/damm-v1-bundle.js +112 -0
- package/dist/sol/dex/meteora/damm-v1.d.ts +118 -0
- package/dist/sol/dex/meteora/damm-v1.js +315 -0
- package/dist/sol/dex/meteora/damm-v2-bundle.d.ts +82 -0
- package/dist/sol/dex/meteora/damm-v2-bundle.js +242 -0
- package/dist/sol/dex/meteora/damm-v2.d.ts +172 -0
- package/dist/sol/dex/meteora/damm-v2.js +632 -0
- package/dist/sol/dex/meteora/dbc-bundle.d.ts +123 -0
- package/dist/sol/dex/meteora/dbc-bundle.js +304 -0
- package/dist/sol/dex/meteora/dbc.d.ts +192 -0
- package/dist/sol/dex/meteora/dbc.js +619 -0
- package/dist/sol/dex/meteora/dlmm-bundle.d.ts +39 -0
- package/dist/sol/dex/meteora/dlmm-bundle.js +189 -0
- package/dist/sol/dex/meteora/dlmm.d.ts +157 -0
- package/dist/sol/dex/meteora/dlmm.js +671 -0
- package/dist/sol/dex/meteora/index.d.ts +25 -0
- package/dist/sol/dex/meteora/index.js +65 -0
- package/dist/sol/dex/meteora/types.d.ts +787 -0
- package/dist/sol/dex/meteora/types.js +110 -0
- package/dist/sol/dex/orca/index.d.ts +10 -0
- package/dist/sol/dex/orca/index.js +16 -0
- package/dist/sol/dex/orca/orca-bundle.d.ts +41 -0
- package/dist/sol/dex/orca/orca-bundle.js +173 -0
- package/dist/sol/dex/orca/orca.d.ts +65 -0
- package/dist/sol/dex/orca/orca.js +474 -0
- package/dist/sol/dex/orca/types.d.ts +263 -0
- package/dist/sol/dex/orca/types.js +38 -0
- package/dist/sol/dex/orca/wavebreak-bundle.d.ts +34 -0
- package/dist/sol/dex/orca/wavebreak-bundle.js +198 -0
- package/dist/sol/dex/orca/wavebreak-types.d.ts +227 -0
- package/dist/sol/dex/orca/wavebreak-types.js +23 -0
- package/dist/sol/dex/orca/wavebreak.d.ts +78 -0
- package/dist/sol/dex/orca/wavebreak.js +497 -0
- package/dist/sol/dex/pump/index.d.ts +9 -0
- package/dist/sol/dex/pump/index.js +14 -0
- package/dist/sol/dex/pump/pump-bundle.d.ts +92 -0
- package/dist/sol/dex/pump/pump-bundle.js +383 -0
- package/dist/sol/dex/pump/pump-swap-bundle.d.ts +103 -0
- package/dist/sol/dex/pump/pump-swap-bundle.js +380 -0
- package/dist/sol/dex/pump/pump-swap.d.ts +46 -0
- package/dist/sol/dex/pump/pump-swap.js +199 -0
- package/dist/sol/dex/pump/pump.d.ts +35 -0
- package/dist/sol/dex/pump/pump.js +352 -0
- package/dist/sol/dex/pump/types.d.ts +215 -0
- package/dist/sol/dex/pump/types.js +5 -0
- package/dist/sol/dex/raydium/index.d.ts +8 -0
- package/dist/sol/dex/raydium/index.js +12 -0
- package/dist/sol/dex/raydium/launchlab.d.ts +68 -0
- package/dist/sol/dex/raydium/launchlab.js +210 -0
- package/dist/sol/dex/raydium/raydium-bundle.d.ts +64 -0
- package/dist/sol/dex/raydium/raydium-bundle.js +324 -0
- package/dist/sol/dex/raydium/raydium.d.ts +40 -0
- package/dist/sol/dex/raydium/raydium.js +366 -0
- package/dist/sol/dex/raydium/types.d.ts +240 -0
- package/dist/sol/dex/raydium/types.js +5 -0
- package/dist/sol/index.d.ts +11 -0
- package/dist/sol/index.js +18 -0
- package/dist/sol/jito/bundle.d.ts +90 -0
- package/dist/sol/jito/bundle.js +263 -0
- package/dist/sol/jito/index.d.ts +7 -0
- package/dist/sol/jito/index.js +7 -0
- package/dist/sol/jito/tip.d.ts +51 -0
- package/dist/sol/jito/tip.js +83 -0
- package/dist/sol/jito/types.d.ts +100 -0
- package/dist/sol/jito/types.js +5 -0
- package/dist/sol/nozomi/client.d.ts +63 -0
- package/dist/sol/nozomi/client.js +222 -0
- package/dist/sol/nozomi/index.d.ts +8 -0
- package/dist/sol/nozomi/index.js +8 -0
- package/dist/sol/nozomi/tip.d.ts +50 -0
- package/dist/sol/nozomi/tip.js +80 -0
- package/dist/sol/nozomi/types.d.ts +96 -0
- package/dist/sol/nozomi/types.js +5 -0
- package/dist/sol/token/create-complete.d.ts +115 -0
- package/dist/sol/token/create-complete.js +235 -0
- package/dist/sol/token/create-token.d.ts +57 -0
- package/dist/sol/token/create-token.js +230 -0
- package/dist/sol/token/index.d.ts +9 -0
- package/dist/sol/token/index.js +14 -0
- package/dist/sol/token/metadata-upload.d.ts +86 -0
- package/dist/sol/token/metadata-upload.js +173 -0
- package/dist/sol/token/metadata.d.ts +92 -0
- package/dist/sol/token/metadata.js +274 -0
- package/dist/sol/token/types.d.ts +153 -0
- package/dist/sol/token/types.js +5 -0
- package/dist/sol/types.d.ts +176 -0
- package/dist/sol/types.js +7 -0
- package/dist/sol/utils/balance.d.ts +160 -0
- package/dist/sol/utils/balance.js +638 -0
- package/dist/sol/utils/connection.d.ts +78 -0
- package/dist/sol/utils/connection.js +168 -0
- package/dist/sol/utils/index.d.ts +9 -0
- package/dist/sol/utils/index.js +9 -0
- package/dist/sol/utils/lp-inspect.d.ts +75 -0
- package/dist/sol/utils/lp-inspect.js +235 -0
- package/dist/sol/utils/transfer.d.ts +196 -0
- package/dist/sol/utils/transfer.js +307 -0
- package/dist/sol/utils/wallet.d.ts +107 -0
- package/dist/sol/utils/wallet.js +210 -0
- package/package.json +44 -5
- package/README.zh-CN.pdf +0 -0
- package/dist/flap/portal-bundle-merkle/encryption.d.ts +0 -16
- package/dist/flap/portal-bundle-merkle/encryption.js +0 -146
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solana RPC 连接管理
|
|
3
|
+
* @module sol/utils/connection
|
|
4
|
+
*/
|
|
5
|
+
import { Connection, Commitment } from '@solana/web3.js';
|
|
6
|
+
/**
|
|
7
|
+
* 创建 Solana 连接
|
|
8
|
+
*
|
|
9
|
+
* 重要:必须传入用户选择的 RPC URL,SDK 不提供默认 RPC
|
|
10
|
+
* 前端应从 RPC 设置中获取用户配置的节点
|
|
11
|
+
*
|
|
12
|
+
* @param rpcUrl RPC URL(必填)
|
|
13
|
+
* @param commitment Commitment 级别(可选,默认 confirmed)
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const connection = createConnection('https://user-selected-rpc.com')
|
|
17
|
+
*
|
|
18
|
+
* @throws Error 如果没有传入 rpcUrl
|
|
19
|
+
*/
|
|
20
|
+
export declare function createConnection(rpcUrl: string, commitment?: Commitment): Connection;
|
|
21
|
+
/**
|
|
22
|
+
* 获取账户 SOL 余额
|
|
23
|
+
* @param connection Solana 连接
|
|
24
|
+
* @param address 账户地址
|
|
25
|
+
* @returns 余额(lamports)
|
|
26
|
+
*/
|
|
27
|
+
export declare function getBalance(connection: Connection, address: string): Promise<bigint>;
|
|
28
|
+
/**
|
|
29
|
+
* 获取账户 SOL 余额(格式化)
|
|
30
|
+
* @param connection Solana 连接
|
|
31
|
+
* @param address 账户地址
|
|
32
|
+
* @returns 余额(SOL)
|
|
33
|
+
*/
|
|
34
|
+
export declare function getBalanceInSol(connection: Connection, address: string): Promise<number>;
|
|
35
|
+
/**
|
|
36
|
+
* 获取最新 blockhash
|
|
37
|
+
* @param connection Solana 连接
|
|
38
|
+
*/
|
|
39
|
+
export declare function getLatestBlockhash(connection: Connection): Promise<{
|
|
40
|
+
blockhash: string;
|
|
41
|
+
lastValidBlockHeight: number;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* 获取当前 slot
|
|
45
|
+
* @param connection Solana 连接
|
|
46
|
+
*/
|
|
47
|
+
export declare function getCurrentSlot(connection: Connection): Promise<number>;
|
|
48
|
+
/**
|
|
49
|
+
* 检查账户是否存在
|
|
50
|
+
* @param connection Solana 连接
|
|
51
|
+
* @param address 账户地址
|
|
52
|
+
*/
|
|
53
|
+
export declare function accountExists(connection: Connection, address: string): Promise<boolean>;
|
|
54
|
+
/**
|
|
55
|
+
* 获取账户信息
|
|
56
|
+
* @param connection Solana 连接
|
|
57
|
+
* @param address 账户地址
|
|
58
|
+
*/
|
|
59
|
+
export declare function getAccountInfo(connection: Connection, address: string): Promise<import("@solana/web3.js").AccountInfo<Buffer<ArrayBufferLike>> | null>;
|
|
60
|
+
/**
|
|
61
|
+
* 获取最小租金豁免余额
|
|
62
|
+
* @param connection Solana 连接
|
|
63
|
+
* @param dataSize 账户数据大小
|
|
64
|
+
*/
|
|
65
|
+
export declare function getMinimumBalanceForRentExemption(connection: Connection, dataSize: number): Promise<bigint>;
|
|
66
|
+
/**
|
|
67
|
+
* 等待交易确认
|
|
68
|
+
* @param connection Solana 连接
|
|
69
|
+
* @param signature 交易签名
|
|
70
|
+
* @param timeout 超时时间(毫秒)
|
|
71
|
+
*/
|
|
72
|
+
export declare function waitForConfirmation(connection: Connection, signature: string, timeout?: number): Promise<boolean>;
|
|
73
|
+
/**
|
|
74
|
+
* 获取交易状态
|
|
75
|
+
* @param connection Solana 连接
|
|
76
|
+
* @param signature 交易签名
|
|
77
|
+
*/
|
|
78
|
+
export declare function getTransactionStatus(connection: Connection, signature: string): Promise<'pending' | 'confirmed' | 'failed'>;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solana RPC 连接管理
|
|
3
|
+
* @module sol/utils/connection
|
|
4
|
+
*/
|
|
5
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
6
|
+
import { TX_CONFIG, lamportsToSol } from '../constants.js';
|
|
7
|
+
/**
|
|
8
|
+
* 创建 Solana 连接
|
|
9
|
+
*
|
|
10
|
+
* 重要:必须传入用户选择的 RPC URL,SDK 不提供默认 RPC
|
|
11
|
+
* 前端应从 RPC 设置中获取用户配置的节点
|
|
12
|
+
*
|
|
13
|
+
* @param rpcUrl RPC URL(必填)
|
|
14
|
+
* @param commitment Commitment 级别(可选,默认 confirmed)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const connection = createConnection('https://user-selected-rpc.com')
|
|
18
|
+
*
|
|
19
|
+
* @throws Error 如果没有传入 rpcUrl
|
|
20
|
+
*/
|
|
21
|
+
export function createConnection(rpcUrl, commitment = TX_CONFIG.DEFAULT_COMMITMENT) {
|
|
22
|
+
if (!rpcUrl) {
|
|
23
|
+
throw new Error('RPC URL is required. Please pass the user-configured RPC URL from frontend settings.');
|
|
24
|
+
}
|
|
25
|
+
return new Connection(rpcUrl, {
|
|
26
|
+
commitment,
|
|
27
|
+
confirmTransactionInitialTimeout: TX_CONFIG.CONFIRMATION_TIMEOUT,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 获取账户 SOL 余额
|
|
32
|
+
* @param connection Solana 连接
|
|
33
|
+
* @param address 账户地址
|
|
34
|
+
* @returns 余额(lamports)
|
|
35
|
+
*/
|
|
36
|
+
export async function getBalance(connection, address) {
|
|
37
|
+
try {
|
|
38
|
+
const publicKey = new PublicKey(address);
|
|
39
|
+
const balance = await connection.getBalance(publicKey);
|
|
40
|
+
return BigInt(balance);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
throw new Error(`Failed to get balance: ${error.message}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 获取账户 SOL 余额(格式化)
|
|
48
|
+
* @param connection Solana 连接
|
|
49
|
+
* @param address 账户地址
|
|
50
|
+
* @returns 余额(SOL)
|
|
51
|
+
*/
|
|
52
|
+
export async function getBalanceInSol(connection, address) {
|
|
53
|
+
const lamports = await getBalance(connection, address);
|
|
54
|
+
return lamportsToSol(lamports);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 获取最新 blockhash
|
|
58
|
+
* @param connection Solana 连接
|
|
59
|
+
*/
|
|
60
|
+
export async function getLatestBlockhash(connection) {
|
|
61
|
+
try {
|
|
62
|
+
const result = await connection.getLatestBlockhash('finalized');
|
|
63
|
+
return {
|
|
64
|
+
blockhash: result.blockhash,
|
|
65
|
+
lastValidBlockHeight: result.lastValidBlockHeight,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw new Error(`Failed to get blockhash: ${error.message}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 获取当前 slot
|
|
74
|
+
* @param connection Solana 连接
|
|
75
|
+
*/
|
|
76
|
+
export async function getCurrentSlot(connection) {
|
|
77
|
+
try {
|
|
78
|
+
return await connection.getSlot();
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
throw new Error(`Failed to get slot: ${error.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 检查账户是否存在
|
|
86
|
+
* @param connection Solana 连接
|
|
87
|
+
* @param address 账户地址
|
|
88
|
+
*/
|
|
89
|
+
export async function accountExists(connection, address) {
|
|
90
|
+
try {
|
|
91
|
+
const publicKey = new PublicKey(address);
|
|
92
|
+
const accountInfo = await connection.getAccountInfo(publicKey);
|
|
93
|
+
return accountInfo !== null;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 获取账户信息
|
|
101
|
+
* @param connection Solana 连接
|
|
102
|
+
* @param address 账户地址
|
|
103
|
+
*/
|
|
104
|
+
export async function getAccountInfo(connection, address) {
|
|
105
|
+
try {
|
|
106
|
+
const publicKey = new PublicKey(address);
|
|
107
|
+
return await connection.getAccountInfo(publicKey);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
throw new Error(`Failed to get account info: ${error.message}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 获取最小租金豁免余额
|
|
115
|
+
* @param connection Solana 连接
|
|
116
|
+
* @param dataSize 账户数据大小
|
|
117
|
+
*/
|
|
118
|
+
export async function getMinimumBalanceForRentExemption(connection, dataSize) {
|
|
119
|
+
try {
|
|
120
|
+
const lamports = await connection.getMinimumBalanceForRentExemption(dataSize);
|
|
121
|
+
return BigInt(lamports);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
throw new Error(`Failed to get rent exemption: ${error.message}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 等待交易确认
|
|
129
|
+
* @param connection Solana 连接
|
|
130
|
+
* @param signature 交易签名
|
|
131
|
+
* @param timeout 超时时间(毫秒)
|
|
132
|
+
*/
|
|
133
|
+
export async function waitForConfirmation(connection, signature, timeout = TX_CONFIG.CONFIRMATION_TIMEOUT) {
|
|
134
|
+
try {
|
|
135
|
+
const result = await connection.confirmTransaction({
|
|
136
|
+
signature,
|
|
137
|
+
blockhash: (await getLatestBlockhash(connection)).blockhash,
|
|
138
|
+
lastValidBlockHeight: (await getLatestBlockhash(connection)).lastValidBlockHeight,
|
|
139
|
+
}, 'confirmed');
|
|
140
|
+
return !result.value.err;
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
console.error(`Transaction confirmation failed: ${error.message}`);
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 获取交易状态
|
|
149
|
+
* @param connection Solana 连接
|
|
150
|
+
* @param signature 交易签名
|
|
151
|
+
*/
|
|
152
|
+
export async function getTransactionStatus(connection, signature) {
|
|
153
|
+
try {
|
|
154
|
+
const status = await connection.getSignatureStatus(signature);
|
|
155
|
+
if (!status.value)
|
|
156
|
+
return 'pending';
|
|
157
|
+
if (status.value.err)
|
|
158
|
+
return 'failed';
|
|
159
|
+
if (status.value.confirmationStatus === 'confirmed' ||
|
|
160
|
+
status.value.confirmationStatus === 'finalized') {
|
|
161
|
+
return 'confirmed';
|
|
162
|
+
}
|
|
163
|
+
return 'pending';
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return 'pending';
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solana LP 检测工具
|
|
3
|
+
* 自动判断代币在哪个平台(内盘/外盘)
|
|
4
|
+
* @module sol/utils/lp-inspect
|
|
5
|
+
*/
|
|
6
|
+
import { Connection } from '@solana/web3.js';
|
|
7
|
+
/** Solana LP 平台类型 */
|
|
8
|
+
export type SolanaLPPlatform = 'PUMP_BONDING_CURVE' | 'METEORA_DBC' | 'RAYDIUM_LAUNCHLAB' | 'JUPITER_AGGREGATED' | 'PUMP_SWAP' | 'MULTI_POOL' | 'UNKNOWN';
|
|
9
|
+
/** 内盘(Bonding Curve)信息 */
|
|
10
|
+
export interface SolanaBondingCurveInfo {
|
|
11
|
+
type: 'pump' | 'meteora_dbc' | 'raydium_launchlab';
|
|
12
|
+
address: string;
|
|
13
|
+
complete: boolean;
|
|
14
|
+
reserveQuote: string;
|
|
15
|
+
reserveQuoteRaw: bigint;
|
|
16
|
+
reserveToken: string;
|
|
17
|
+
reserveTokenRaw: bigint;
|
|
18
|
+
price?: number;
|
|
19
|
+
progress?: number;
|
|
20
|
+
creator?: string;
|
|
21
|
+
}
|
|
22
|
+
/** 外盘池子信息 (整合 Jupiter 数据) */
|
|
23
|
+
export interface SolanaPoolInfo {
|
|
24
|
+
platform: SolanaLPPlatform;
|
|
25
|
+
poolAddress: string;
|
|
26
|
+
quoteToken: string;
|
|
27
|
+
quoteSymbol: string;
|
|
28
|
+
quoteDecimals: number;
|
|
29
|
+
baseToken: string;
|
|
30
|
+
reserveQuote: string;
|
|
31
|
+
reserveQuoteRaw: bigint;
|
|
32
|
+
price?: number;
|
|
33
|
+
mcap?: number;
|
|
34
|
+
liquidity?: number;
|
|
35
|
+
fdv?: number;
|
|
36
|
+
isVerified?: boolean;
|
|
37
|
+
extra?: Record<string, any>;
|
|
38
|
+
}
|
|
39
|
+
/** Solana LP 检测结果 */
|
|
40
|
+
export interface SolanaLPInfo {
|
|
41
|
+
mint: string;
|
|
42
|
+
platform: SolanaLPPlatform;
|
|
43
|
+
decimals?: number;
|
|
44
|
+
totalSupply?: string;
|
|
45
|
+
totalSupplyRaw?: bigint;
|
|
46
|
+
bondingCurve?: SolanaBondingCurveInfo;
|
|
47
|
+
bestPool?: SolanaPoolInfo;
|
|
48
|
+
pools: SolanaPoolInfo[];
|
|
49
|
+
elapsed?: number;
|
|
50
|
+
}
|
|
51
|
+
/** 检测选项 */
|
|
52
|
+
export interface SolanaInspectOptions {
|
|
53
|
+
rpcUrl?: string;
|
|
54
|
+
connection?: Connection;
|
|
55
|
+
skipBondingCurve?: boolean;
|
|
56
|
+
skipPools?: boolean;
|
|
57
|
+
debug?: boolean;
|
|
58
|
+
timeout?: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 检测 Solana 代币的 LP 信息
|
|
62
|
+
*/
|
|
63
|
+
export declare function inspectSolanaTokenLP(mint: string, options?: SolanaInspectOptions): Promise<SolanaLPInfo>;
|
|
64
|
+
/**
|
|
65
|
+
* 快速检测代币是否在内盘
|
|
66
|
+
*/
|
|
67
|
+
export declare function detectBondingCurve(mint: string, options?: SolanaInspectOptions): Promise<SolanaBondingCurveInfo | null>;
|
|
68
|
+
/**
|
|
69
|
+
* 获取代币流动性 (USD)
|
|
70
|
+
*/
|
|
71
|
+
export declare function getTokenLiquidity(mint: string, options?: SolanaInspectOptions): Promise<number>;
|
|
72
|
+
/**
|
|
73
|
+
* 判断代币是否已毕业
|
|
74
|
+
*/
|
|
75
|
+
export declare function isTokenGraduated(mint: string, options?: SolanaInspectOptions): Promise<boolean>;
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solana LP 检测工具
|
|
3
|
+
* 自动判断代币在哪个平台(内盘/外盘)
|
|
4
|
+
* @module sol/utils/lp-inspect
|
|
5
|
+
*/
|
|
6
|
+
import { PublicKey } from '@solana/web3.js';
|
|
7
|
+
import { createConnection } from './connection.js';
|
|
8
|
+
import { getTokenInfoV2 } from '../dex/jup/tokens.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// 常量
|
|
11
|
+
// ============================================================================
|
|
12
|
+
const WSOL = 'So11111111111111111111111111111111111111112';
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// 内盘检测
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* 检测 Pump.fun Bonding Curve
|
|
18
|
+
*/
|
|
19
|
+
async function detectPumpBondingCurve(mint, connection, debug) {
|
|
20
|
+
try {
|
|
21
|
+
const { getBondingCurveInfo } = await import('../dex/pump/pump.js');
|
|
22
|
+
const info = await getBondingCurveInfo(connection, mint);
|
|
23
|
+
if (!info)
|
|
24
|
+
return null;
|
|
25
|
+
const price = Number(info.virtualSolReserves) / Number(info.virtualTokenReserves);
|
|
26
|
+
const GRADUATION_THRESHOLD = 85000000000n;
|
|
27
|
+
const progress = Math.min(100, Number(info.realSolReserves * 100n / GRADUATION_THRESHOLD));
|
|
28
|
+
return {
|
|
29
|
+
type: 'pump',
|
|
30
|
+
address: info.bondingCurve,
|
|
31
|
+
complete: info.complete,
|
|
32
|
+
reserveQuote: (Number(info.virtualSolReserves) / 1e9).toFixed(4),
|
|
33
|
+
reserveQuoteRaw: info.virtualSolReserves,
|
|
34
|
+
reserveToken: (Number(info.virtualTokenReserves) / 1e6).toFixed(0),
|
|
35
|
+
reserveTokenRaw: info.virtualTokenReserves,
|
|
36
|
+
price,
|
|
37
|
+
progress,
|
|
38
|
+
creator: info.creator,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
if (debug)
|
|
43
|
+
console.log('[LP Inspect] Pump bonding curve check failed:', err);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 检测 Meteora DBC
|
|
49
|
+
*/
|
|
50
|
+
async function detectMeteoraDbc(mint, connection, debug) {
|
|
51
|
+
try {
|
|
52
|
+
const { findDbcPoolByBaseMint, getDbcPoolInfo } = await import('../dex/meteora/dbc.js');
|
|
53
|
+
const poolAddress = await findDbcPoolByBaseMint(mint, connection);
|
|
54
|
+
if (!poolAddress)
|
|
55
|
+
return null;
|
|
56
|
+
const poolInfo = await getDbcPoolInfo(poolAddress, connection);
|
|
57
|
+
return {
|
|
58
|
+
type: 'meteora_dbc',
|
|
59
|
+
address: poolAddress,
|
|
60
|
+
complete: poolInfo.isMigrated,
|
|
61
|
+
reserveQuote: poolInfo.quoteReserve,
|
|
62
|
+
reserveQuoteRaw: BigInt(poolInfo.quoteReserve),
|
|
63
|
+
reserveToken: poolInfo.baseReserve,
|
|
64
|
+
reserveTokenRaw: BigInt(poolInfo.baseReserve),
|
|
65
|
+
price: poolInfo.currentPrice,
|
|
66
|
+
progress: poolInfo.progressPercent,
|
|
67
|
+
creator: poolInfo.creator,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
if (debug)
|
|
72
|
+
console.log('[LP Inspect] Meteora DBC check failed:', err);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 检测 Raydium LaunchLab
|
|
78
|
+
*/
|
|
79
|
+
async function detectRaydiumLaunchLab(mint, connection, debug) {
|
|
80
|
+
try {
|
|
81
|
+
const { LaunchpadPool, LaunchpadConfig, getPdaLaunchpadPoolId, LAUNCHPAD_PROGRAM, Curve, } = await import('@raydium-io/raydium-sdk-v2');
|
|
82
|
+
const { NATIVE_MINT } = await import('@solana/spl-token');
|
|
83
|
+
const poolId = getPdaLaunchpadPoolId(LAUNCHPAD_PROGRAM, new PublicKey(mint), NATIVE_MINT).publicKey;
|
|
84
|
+
const poolAccountInfo = await connection.getAccountInfo(poolId);
|
|
85
|
+
if (!poolAccountInfo)
|
|
86
|
+
return null;
|
|
87
|
+
const poolInfo = LaunchpadPool.decode(poolAccountInfo.data);
|
|
88
|
+
const configAccountInfo = await connection.getAccountInfo(poolInfo.configId);
|
|
89
|
+
if (!configAccountInfo)
|
|
90
|
+
return null;
|
|
91
|
+
const configInfo = LaunchpadConfig.decode(configAccountInfo.data);
|
|
92
|
+
const currentPrice = Curve.getPrice({
|
|
93
|
+
poolInfo,
|
|
94
|
+
curveType: configInfo.curveType,
|
|
95
|
+
decimalA: poolInfo.mintDecimalsA,
|
|
96
|
+
decimalB: poolInfo.mintDecimalsB,
|
|
97
|
+
}).toNumber();
|
|
98
|
+
const isMigrated = poolInfo.status !== undefined && poolInfo.status >= 2;
|
|
99
|
+
return {
|
|
100
|
+
type: 'raydium_launchlab',
|
|
101
|
+
address: poolId.toBase58(),
|
|
102
|
+
complete: isMigrated,
|
|
103
|
+
reserveQuote: (Number(poolInfo.totalFundRaisingB || 0) / 1e9).toFixed(4),
|
|
104
|
+
reserveQuoteRaw: BigInt(poolInfo.totalFundRaisingB?.toString() || '0'),
|
|
105
|
+
reserveToken: "0", // Simplified
|
|
106
|
+
reserveTokenRaw: 0n,
|
|
107
|
+
price: currentPrice,
|
|
108
|
+
creator: poolInfo.creator?.toBase58(),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
if (debug)
|
|
113
|
+
console.log('[LP Inspect] Raydium LaunchLab check failed:', err);
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// 外盘检测 (Jupiter API)
|
|
119
|
+
// ============================================================================
|
|
120
|
+
/**
|
|
121
|
+
* 使用 Jupiter API 检测外盘信息
|
|
122
|
+
*/
|
|
123
|
+
async function detectWithJupiter(mint, debug) {
|
|
124
|
+
try {
|
|
125
|
+
const info = await getTokenInfoV2(mint);
|
|
126
|
+
if (!info || !info.liquidity || info.liquidity < 100) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
platform: 'JUPITER_AGGREGATED',
|
|
131
|
+
poolAddress: info.graduatedPool || '',
|
|
132
|
+
quoteToken: WSOL,
|
|
133
|
+
quoteSymbol: 'SOL',
|
|
134
|
+
quoteDecimals: 9,
|
|
135
|
+
baseToken: mint,
|
|
136
|
+
reserveQuote: info.liquidity.toFixed(2),
|
|
137
|
+
reserveQuoteRaw: BigInt(Math.floor(info.liquidity)),
|
|
138
|
+
price: info.usdPrice ?? undefined,
|
|
139
|
+
mcap: info.mcap ?? undefined,
|
|
140
|
+
liquidity: info.liquidity,
|
|
141
|
+
fdv: info.fdv ?? undefined,
|
|
142
|
+
isVerified: info.isVerified ?? false,
|
|
143
|
+
extra: {
|
|
144
|
+
launchpad: info.launchpad,
|
|
145
|
+
organicScore: info.organicScore,
|
|
146
|
+
stats24h: info.stats24h,
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
if (debug)
|
|
152
|
+
console.log('[LP Inspect] Jupiter check failed:', err);
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// ============================================================================
|
|
157
|
+
// 主函数
|
|
158
|
+
// ============================================================================
|
|
159
|
+
/**
|
|
160
|
+
* 检测 Solana 代币的 LP 信息
|
|
161
|
+
*/
|
|
162
|
+
export async function inspectSolanaTokenLP(mint, options = {}) {
|
|
163
|
+
const startTime = Date.now();
|
|
164
|
+
const connection = options.connection || createConnection(options.rpcUrl);
|
|
165
|
+
const debug = options.debug;
|
|
166
|
+
const result = {
|
|
167
|
+
mint,
|
|
168
|
+
platform: 'UNKNOWN',
|
|
169
|
+
pools: [],
|
|
170
|
+
};
|
|
171
|
+
// 0. 获取代币基本信息
|
|
172
|
+
try {
|
|
173
|
+
const mintInfo = await connection.getParsedAccountInfo(new PublicKey(mint));
|
|
174
|
+
if (mintInfo.value?.data && 'parsed' in mintInfo.value.data) {
|
|
175
|
+
const parsed = mintInfo.value.data.parsed;
|
|
176
|
+
result.decimals = parsed.info.decimals;
|
|
177
|
+
result.totalSupplyRaw = BigInt(parsed.info.supply);
|
|
178
|
+
result.totalSupply = (Number(result.totalSupplyRaw) / Math.pow(10, result.decimals)).toString();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch { }
|
|
182
|
+
// 1. 内盘检测
|
|
183
|
+
if (!options.skipBondingCurve) {
|
|
184
|
+
const [pump, meteora, raydium] = await Promise.all([
|
|
185
|
+
detectPumpBondingCurve(mint, connection, debug),
|
|
186
|
+
detectMeteoraDbc(mint, connection, debug),
|
|
187
|
+
detectRaydiumLaunchLab(mint, connection, debug),
|
|
188
|
+
]);
|
|
189
|
+
const bc = pump || meteora || raydium;
|
|
190
|
+
if (bc && !bc.complete) {
|
|
191
|
+
result.bondingCurve = bc;
|
|
192
|
+
result.platform = bc.type === 'pump' ? 'PUMP_BONDING_CURVE' :
|
|
193
|
+
bc.type === 'meteora_dbc' ? 'METEORA_DBC' : 'RAYDIUM_LAUNCHLAB';
|
|
194
|
+
result.elapsed = Date.now() - startTime;
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// 2. 外盘检测 (Jupiter)
|
|
199
|
+
if (!options.skipPools) {
|
|
200
|
+
const jupPool = await detectWithJupiter(mint, debug);
|
|
201
|
+
if (jupPool) {
|
|
202
|
+
result.bestPool = jupPool;
|
|
203
|
+
result.pools = [jupPool];
|
|
204
|
+
result.platform = jupPool.platform;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
result.elapsed = Date.now() - startTime;
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* 快速检测代币是否在内盘
|
|
212
|
+
*/
|
|
213
|
+
export async function detectBondingCurve(mint, options = {}) {
|
|
214
|
+
const connection = options.connection || createConnection(options.rpcUrl);
|
|
215
|
+
const results = await Promise.all([
|
|
216
|
+
detectPumpBondingCurve(mint, connection, options.debug),
|
|
217
|
+
detectMeteoraDbc(mint, connection, options.debug),
|
|
218
|
+
detectRaydiumLaunchLab(mint, connection, options.debug),
|
|
219
|
+
]);
|
|
220
|
+
return results.find(r => r && !r.complete) || null;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* 获取代币流动性 (USD)
|
|
224
|
+
*/
|
|
225
|
+
export async function getTokenLiquidity(mint, options = {}) {
|
|
226
|
+
const info = await inspectSolanaTokenLP(mint, options);
|
|
227
|
+
return info.bestPool?.liquidity || 0;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* 判断代币是否已毕业
|
|
231
|
+
*/
|
|
232
|
+
export async function isTokenGraduated(mint, options = {}) {
|
|
233
|
+
const bc = await detectBondingCurve(mint, options);
|
|
234
|
+
return bc === null;
|
|
235
|
+
}
|