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,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raydium LaunchLab 代币创建
|
|
3
|
+
* @module sol/dex/raydium/launchlab
|
|
4
|
+
*/
|
|
5
|
+
import { Keypair, PublicKey, } from '@solana/web3.js';
|
|
6
|
+
import { TxVersion } from '@raydium-io/raydium-sdk-v2';
|
|
7
|
+
import BN from 'bn.js';
|
|
8
|
+
import { initRaydium } from './raydium.js';
|
|
9
|
+
/**
|
|
10
|
+
* 获取 LaunchLab 配置列表
|
|
11
|
+
*/
|
|
12
|
+
export async function getLaunchLabConfigs(connection) {
|
|
13
|
+
try {
|
|
14
|
+
const raydium = await initRaydium(connection);
|
|
15
|
+
const configs = await raydium.api.fetchLaunchConfigs();
|
|
16
|
+
return configs.map((config) => ({
|
|
17
|
+
id: config.key.pubKey,
|
|
18
|
+
curveType: config.curveType,
|
|
19
|
+
mintB: config.mintB,
|
|
20
|
+
migrateFee: BigInt(config.migrateFee),
|
|
21
|
+
tradeFeeRate: config.tradeFeeRate,
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.error('Failed to get LaunchLab configs:', error);
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 构建并签名 LaunchLab 创建代币交易
|
|
31
|
+
*/
|
|
32
|
+
export async function signRaydiumLaunchLabCreate(connection, params) {
|
|
33
|
+
try {
|
|
34
|
+
const { name, symbol, uri, decimals = 6, supply, totalSellA, totalFundRaisingB, migrateType = 'cpmm', configId, platformId, buyAmount, minMintAAmount, slippageBps = 100, token2022 = false, wallet, } = params;
|
|
35
|
+
const raydium = await initRaydium(connection, wallet);
|
|
36
|
+
// 生成代币 Mint 地址
|
|
37
|
+
const mintKeypair = Keypair.generate();
|
|
38
|
+
const mintA = mintKeypair.publicKey;
|
|
39
|
+
// 获取配置
|
|
40
|
+
let launchConfigId;
|
|
41
|
+
if (configId) {
|
|
42
|
+
launchConfigId = new PublicKey(configId);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// 使用默认配置
|
|
46
|
+
const configs = await raydium.api.fetchLaunchConfigs();
|
|
47
|
+
if (configs.length === 0) {
|
|
48
|
+
return { success: false, error: 'No LaunchLab configs available' };
|
|
49
|
+
}
|
|
50
|
+
launchConfigId = new PublicKey(configs[0].key.pubKey);
|
|
51
|
+
}
|
|
52
|
+
// 构建创建参数
|
|
53
|
+
const createParams = {
|
|
54
|
+
mintA,
|
|
55
|
+
decimals,
|
|
56
|
+
name,
|
|
57
|
+
symbol,
|
|
58
|
+
uri,
|
|
59
|
+
migrateType,
|
|
60
|
+
configId: launchConfigId,
|
|
61
|
+
txVersion: TxVersion.LEGACY,
|
|
62
|
+
token2022,
|
|
63
|
+
};
|
|
64
|
+
if (platformId) {
|
|
65
|
+
createParams.platformId = new PublicKey(platformId);
|
|
66
|
+
}
|
|
67
|
+
if (supply) {
|
|
68
|
+
createParams.supply = new BN(supply.toString());
|
|
69
|
+
}
|
|
70
|
+
if (totalSellA) {
|
|
71
|
+
createParams.totalSellA = new BN(totalSellA.toString());
|
|
72
|
+
}
|
|
73
|
+
if (totalFundRaisingB) {
|
|
74
|
+
createParams.totalFundRaisingB = new BN(totalFundRaisingB.toString());
|
|
75
|
+
}
|
|
76
|
+
if (buyAmount) {
|
|
77
|
+
createParams.buyAmount = new BN(buyAmount.toString());
|
|
78
|
+
createParams.slippage = new BN(Math.floor(slippageBps));
|
|
79
|
+
}
|
|
80
|
+
if (minMintAAmount) {
|
|
81
|
+
createParams.minMintAAmount = new BN(minMintAAmount.toString());
|
|
82
|
+
}
|
|
83
|
+
// 创建 LaunchLab
|
|
84
|
+
const txData = await raydium.launchpad.createLaunchpad(createParams);
|
|
85
|
+
// 签名交易
|
|
86
|
+
const { blockhash } = await connection.getLatestBlockhash('finalized');
|
|
87
|
+
const signedTransactions = [];
|
|
88
|
+
// 处理多笔交易
|
|
89
|
+
if (txData.transactions && Array.isArray(txData.transactions)) {
|
|
90
|
+
for (const txItem of txData.transactions) {
|
|
91
|
+
// txItem 本身就是 Transaction
|
|
92
|
+
const tx = txItem;
|
|
93
|
+
tx.recentBlockhash = blockhash;
|
|
94
|
+
tx.feePayer = wallet.publicKey;
|
|
95
|
+
// 签名
|
|
96
|
+
tx.sign(wallet, mintKeypair);
|
|
97
|
+
signedTransactions.push(Buffer.from(tx.serialize()).toString('base64'));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
success: true,
|
|
102
|
+
mintAddress: mintA.toBase58(),
|
|
103
|
+
poolId: txData.extInfo?.address?.poolId?.toBase58(),
|
|
104
|
+
signedTransactions,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
return {
|
|
109
|
+
success: false,
|
|
110
|
+
error: error.message,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 构建 LaunchLab 买入交易
|
|
116
|
+
*/
|
|
117
|
+
export async function signRaydiumLaunchLabBuy(connection, params) {
|
|
118
|
+
try {
|
|
119
|
+
const { poolId, mintA, amountIn, minAmountOut, slippageBps = 100, wallet, } = params;
|
|
120
|
+
const raydium = await initRaydium(connection, wallet);
|
|
121
|
+
const txData = await raydium.launchpad.buyToken({
|
|
122
|
+
mintA: new PublicKey(mintA),
|
|
123
|
+
buyAmount: new BN(amountIn.toString()),
|
|
124
|
+
minMintAAmount: minAmountOut ? new BN(minAmountOut.toString()) : undefined,
|
|
125
|
+
slippage: new BN(Math.floor(slippageBps)),
|
|
126
|
+
txVersion: TxVersion.LEGACY,
|
|
127
|
+
});
|
|
128
|
+
const { blockhash } = await connection.getLatestBlockhash('finalized');
|
|
129
|
+
if (txData.transaction) {
|
|
130
|
+
const tx = txData.transaction;
|
|
131
|
+
tx.recentBlockhash = blockhash;
|
|
132
|
+
tx.feePayer = wallet.publicKey;
|
|
133
|
+
tx.sign(wallet);
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
signedTransaction: Buffer.from(tx.serialize()).toString('base64'),
|
|
137
|
+
estimatedAmountOut: txData.extInfo?.decimalOutAmount
|
|
138
|
+
? BigInt(Math.floor(txData.extInfo.decimalOutAmount.toNumber()))
|
|
139
|
+
: undefined,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return { success: false, error: 'Failed to build transaction' };
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
return { success: false, error: error.message };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* 构建 LaunchLab 卖出交易
|
|
150
|
+
*/
|
|
151
|
+
export async function signRaydiumLaunchLabSell(connection, params) {
|
|
152
|
+
try {
|
|
153
|
+
const { poolId, mintA, amountIn, minAmountOut, slippageBps = 100, wallet, } = params;
|
|
154
|
+
const raydium = await initRaydium(connection, wallet);
|
|
155
|
+
const txData = await raydium.launchpad.sellToken({
|
|
156
|
+
mintA: new PublicKey(mintA),
|
|
157
|
+
sellAmount: new BN(amountIn.toString()),
|
|
158
|
+
minAmountB: minAmountOut ? new BN(minAmountOut.toString()) : undefined,
|
|
159
|
+
slippage: new BN(Math.floor(slippageBps)),
|
|
160
|
+
txVersion: TxVersion.LEGACY,
|
|
161
|
+
});
|
|
162
|
+
const { blockhash } = await connection.getLatestBlockhash('finalized');
|
|
163
|
+
if (txData.transaction) {
|
|
164
|
+
const tx = txData.transaction;
|
|
165
|
+
tx.recentBlockhash = blockhash;
|
|
166
|
+
tx.feePayer = wallet.publicKey;
|
|
167
|
+
tx.sign(wallet);
|
|
168
|
+
return {
|
|
169
|
+
success: true,
|
|
170
|
+
signedTransaction: Buffer.from(tx.serialize()).toString('base64'),
|
|
171
|
+
estimatedAmountOut: txData.extInfo?.outAmount
|
|
172
|
+
? BigInt(txData.extInfo.outAmount.toString())
|
|
173
|
+
: undefined,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
return { success: false, error: 'Failed to build transaction' };
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
return { success: false, error: error.message };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* 获取 LaunchLab 池子信息
|
|
184
|
+
*/
|
|
185
|
+
export async function getLaunchLabPoolInfo(connection, poolId) {
|
|
186
|
+
try {
|
|
187
|
+
const raydium = await initRaydium(connection);
|
|
188
|
+
const poolInfo = await raydium.launchpad.getRpcPoolInfo({ poolId: new PublicKey(poolId) });
|
|
189
|
+
if (!poolInfo) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
id: poolId,
|
|
194
|
+
mintA: poolInfo.mintA.toBase58(),
|
|
195
|
+
mintB: poolInfo.mintB.toBase58(),
|
|
196
|
+
status: poolInfo.status,
|
|
197
|
+
virtualA: BigInt(poolInfo.virtualA.toString()),
|
|
198
|
+
virtualB: BigInt(poolInfo.virtualB.toString()),
|
|
199
|
+
realA: BigInt(poolInfo.realA.toString()),
|
|
200
|
+
realB: BigInt(poolInfo.realB.toString()),
|
|
201
|
+
supply: BigInt(poolInfo.supply.toString()),
|
|
202
|
+
totalSellA: BigInt(poolInfo.totalSellA.toString()),
|
|
203
|
+
price: poolInfo.virtualB.toNumber() / poolInfo.virtualA.toNumber(),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
console.error('Failed to get LaunchLab pool info:', error);
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raydium 批量签名(用于 Jito Bundle)
|
|
3
|
+
* @module sol/dex/raydium/raydium-bundle
|
|
4
|
+
*/
|
|
5
|
+
import { Connection, Keypair } from '@solana/web3.js';
|
|
6
|
+
import type { RaydiumBundleBuyItem, RaydiumBundleSellItem, RaydiumBundleSignResult } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* 构建 Raydium CPMM 批量买入(Jito Bundle)
|
|
9
|
+
*/
|
|
10
|
+
export declare function signRaydiumCpmmBundleBuy(connection: Connection, params: {
|
|
11
|
+
/** 池子 ID */
|
|
12
|
+
poolId: string;
|
|
13
|
+
/** 买入列表 */
|
|
14
|
+
buyers: RaydiumBundleBuyItem[];
|
|
15
|
+
/** Tip 支付者 */
|
|
16
|
+
tipPayer: Keypair;
|
|
17
|
+
/** Tip 金额 */
|
|
18
|
+
tipLamports?: bigint;
|
|
19
|
+
/** 滑点(基点) */
|
|
20
|
+
slippageBps?: number;
|
|
21
|
+
}): Promise<RaydiumBundleSignResult>;
|
|
22
|
+
/**
|
|
23
|
+
* 构建 Raydium CPMM 批量卖出(Jito Bundle)
|
|
24
|
+
*/
|
|
25
|
+
export declare function signRaydiumCpmmBundleSell(connection: Connection, params: {
|
|
26
|
+
/** 池子 ID */
|
|
27
|
+
poolId: string;
|
|
28
|
+
/** 卖出列表 */
|
|
29
|
+
sellers: RaydiumBundleSellItem[];
|
|
30
|
+
/** Tip 支付者 */
|
|
31
|
+
tipPayer: Keypair;
|
|
32
|
+
/** Tip 金额 */
|
|
33
|
+
tipLamports?: bigint;
|
|
34
|
+
/** 滑点(基点) */
|
|
35
|
+
slippageBps?: number;
|
|
36
|
+
}): Promise<RaydiumBundleSignResult>;
|
|
37
|
+
/**
|
|
38
|
+
* 构建 Raydium LaunchLab 批量买入(Jito Bundle)
|
|
39
|
+
*/
|
|
40
|
+
export declare function signRaydiumLaunchLabBundleBuy(connection: Connection, params: {
|
|
41
|
+
/** LaunchLab 池子 ID */
|
|
42
|
+
poolId: string;
|
|
43
|
+
/** 代币 Mint */
|
|
44
|
+
mintA: string;
|
|
45
|
+
/** 买入列表 */
|
|
46
|
+
buyers: RaydiumBundleBuyItem[];
|
|
47
|
+
/** Tip 支付者 */
|
|
48
|
+
tipPayer: Keypair;
|
|
49
|
+
/** Tip 金额 */
|
|
50
|
+
tipLamports?: bigint;
|
|
51
|
+
/** 滑点(基点) */
|
|
52
|
+
slippageBps?: number;
|
|
53
|
+
}): Promise<RaydiumBundleSignResult>;
|
|
54
|
+
/**
|
|
55
|
+
* 构建 Raydium LaunchLab 批量卖出(Jito Bundle)
|
|
56
|
+
*/
|
|
57
|
+
export declare function signRaydiumLaunchLabBundleSell(connection: Connection, params: {
|
|
58
|
+
poolId: string;
|
|
59
|
+
mintA: string;
|
|
60
|
+
sellers: RaydiumBundleSellItem[];
|
|
61
|
+
tipPayer: Keypair;
|
|
62
|
+
tipLamports?: bigint;
|
|
63
|
+
slippageBps?: number;
|
|
64
|
+
}): Promise<RaydiumBundleSignResult>;
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raydium 批量签名(用于 Jito Bundle)
|
|
3
|
+
* @module sol/dex/raydium/raydium-bundle
|
|
4
|
+
*/
|
|
5
|
+
import { PublicKey, Transaction, } from '@solana/web3.js';
|
|
6
|
+
import { TxVersion, CurveCalculator } from '@raydium-io/raydium-sdk-v2';
|
|
7
|
+
import BN from 'bn.js';
|
|
8
|
+
import { buildTipInstruction, getRandomTipAccount } from '../../jito/tip.js';
|
|
9
|
+
import { initRaydium } from './raydium.js';
|
|
10
|
+
/**
|
|
11
|
+
* 构建 Raydium CPMM 批量买入(Jito Bundle)
|
|
12
|
+
*/
|
|
13
|
+
export async function signRaydiumCpmmBundleBuy(connection, params) {
|
|
14
|
+
try {
|
|
15
|
+
const { poolId, buyers, tipPayer, tipLamports = BigInt(10000), slippageBps = 100, } = params;
|
|
16
|
+
if (buyers.length === 0) {
|
|
17
|
+
return { success: false, error: 'No buyers provided' };
|
|
18
|
+
}
|
|
19
|
+
// 获取池子信息
|
|
20
|
+
const raydium = await initRaydium(connection);
|
|
21
|
+
const poolData = await raydium.api.fetchPoolById({ ids: poolId });
|
|
22
|
+
if (!poolData || poolData.length === 0) {
|
|
23
|
+
return { success: false, error: 'Pool not found' };
|
|
24
|
+
}
|
|
25
|
+
const pool = poolData[0];
|
|
26
|
+
const poolKeys = await raydium.cpmm.getCpmmPoolKeys(poolId);
|
|
27
|
+
const rpcData = await raydium.cpmm.getRpcPoolInfo(poolId);
|
|
28
|
+
const slippage = slippageBps / 10000;
|
|
29
|
+
// 获取 blockhash
|
|
30
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
31
|
+
const serializedTransactions = [];
|
|
32
|
+
const allSignatures = [];
|
|
33
|
+
const tipAccount = getRandomTipAccount();
|
|
34
|
+
// 为每个买家构建交易
|
|
35
|
+
for (const { wallet, amountIn } of buyers) {
|
|
36
|
+
const userRaydium = await initRaydium(connection, wallet);
|
|
37
|
+
const amountInBN = new BN(amountIn.toString());
|
|
38
|
+
// 计算输出(Quote -> Base = 买入)
|
|
39
|
+
const swapResult = CurveCalculator.swapBaseInput(amountInBN, rpcData.quoteReserve, rpcData.baseReserve, rpcData.configInfo?.tradeFeeRate || new BN(25), new BN(0), new BN(0), new BN(0), false);
|
|
40
|
+
const txData = await userRaydium.cpmm.swap({
|
|
41
|
+
poolInfo: pool,
|
|
42
|
+
poolKeys,
|
|
43
|
+
baseIn: false,
|
|
44
|
+
inputAmount: amountInBN,
|
|
45
|
+
swapResult: {
|
|
46
|
+
inputAmount: swapResult.inputAmount,
|
|
47
|
+
outputAmount: swapResult.outputAmount,
|
|
48
|
+
},
|
|
49
|
+
slippage,
|
|
50
|
+
txVersion: TxVersion.LEGACY,
|
|
51
|
+
});
|
|
52
|
+
if (txData.transaction) {
|
|
53
|
+
const tx = txData.transaction;
|
|
54
|
+
tx.recentBlockhash = blockhash;
|
|
55
|
+
tx.feePayer = wallet.publicKey;
|
|
56
|
+
tx.sign(wallet);
|
|
57
|
+
const serialized = tx.serialize();
|
|
58
|
+
serializedTransactions.push({
|
|
59
|
+
data: Buffer.from(serialized).toString('base64'),
|
|
60
|
+
isVersioned: false,
|
|
61
|
+
signature: tx.signature ? Buffer.from(tx.signature).toString('base64') : undefined,
|
|
62
|
+
});
|
|
63
|
+
if (tx.signature) {
|
|
64
|
+
allSignatures.push(Buffer.from(tx.signature).toString('base64'));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// 添加 Tip 交易
|
|
69
|
+
const tipTx = new Transaction().add(buildTipInstruction(tipPayer.publicKey, tipLamports, tipAccount));
|
|
70
|
+
tipTx.recentBlockhash = blockhash;
|
|
71
|
+
tipTx.feePayer = tipPayer.publicKey;
|
|
72
|
+
tipTx.sign(tipPayer);
|
|
73
|
+
serializedTransactions.push({
|
|
74
|
+
data: Buffer.from(tipTx.serialize()).toString('base64'),
|
|
75
|
+
isVersioned: false,
|
|
76
|
+
signature: tipTx.signature ? Buffer.from(tipTx.signature).toString('base64') : undefined,
|
|
77
|
+
});
|
|
78
|
+
if (tipTx.signature) {
|
|
79
|
+
allSignatures.push(Buffer.from(tipTx.signature).toString('base64'));
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
success: true,
|
|
83
|
+
bundleData: {
|
|
84
|
+
transactions: serializedTransactions,
|
|
85
|
+
signatures: allSignatures,
|
|
86
|
+
tip: {
|
|
87
|
+
account: tipAccount,
|
|
88
|
+
lamports: tipLamports,
|
|
89
|
+
},
|
|
90
|
+
recentBlockhash: blockhash,
|
|
91
|
+
lastValidBlockHeight,
|
|
92
|
+
createdAt: Date.now(),
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
error: error.message,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 构建 Raydium CPMM 批量卖出(Jito Bundle)
|
|
105
|
+
*/
|
|
106
|
+
export async function signRaydiumCpmmBundleSell(connection, params) {
|
|
107
|
+
try {
|
|
108
|
+
const { poolId, sellers, tipPayer, tipLamports = BigInt(10000), slippageBps = 100, } = params;
|
|
109
|
+
if (sellers.length === 0) {
|
|
110
|
+
return { success: false, error: 'No sellers provided' };
|
|
111
|
+
}
|
|
112
|
+
const raydium = await initRaydium(connection);
|
|
113
|
+
const poolData = await raydium.api.fetchPoolById({ ids: poolId });
|
|
114
|
+
if (!poolData || poolData.length === 0) {
|
|
115
|
+
return { success: false, error: 'Pool not found' };
|
|
116
|
+
}
|
|
117
|
+
const pool = poolData[0];
|
|
118
|
+
const poolKeys = await raydium.cpmm.getCpmmPoolKeys(poolId);
|
|
119
|
+
const rpcData = await raydium.cpmm.getRpcPoolInfo(poolId);
|
|
120
|
+
const slippage = slippageBps / 10000;
|
|
121
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
122
|
+
const serializedTransactions = [];
|
|
123
|
+
const allSignatures = [];
|
|
124
|
+
const tipAccount = getRandomTipAccount();
|
|
125
|
+
for (const { wallet, tokenAmount } of sellers) {
|
|
126
|
+
const userRaydium = await initRaydium(connection, wallet);
|
|
127
|
+
const amountInBN = new BN(tokenAmount.toString());
|
|
128
|
+
// 计算输出(Base -> Quote = 卖出)
|
|
129
|
+
const swapResult = CurveCalculator.swapBaseInput(amountInBN, rpcData.baseReserve, rpcData.quoteReserve, rpcData.configInfo?.tradeFeeRate || new BN(25), new BN(0), new BN(0), new BN(0), false);
|
|
130
|
+
const txData = await userRaydium.cpmm.swap({
|
|
131
|
+
poolInfo: pool,
|
|
132
|
+
poolKeys,
|
|
133
|
+
baseIn: true,
|
|
134
|
+
inputAmount: amountInBN,
|
|
135
|
+
swapResult: {
|
|
136
|
+
inputAmount: swapResult.inputAmount,
|
|
137
|
+
outputAmount: swapResult.outputAmount,
|
|
138
|
+
},
|
|
139
|
+
slippage,
|
|
140
|
+
txVersion: TxVersion.LEGACY,
|
|
141
|
+
});
|
|
142
|
+
if (txData.transaction) {
|
|
143
|
+
const tx = txData.transaction;
|
|
144
|
+
tx.recentBlockhash = blockhash;
|
|
145
|
+
tx.feePayer = wallet.publicKey;
|
|
146
|
+
tx.sign(wallet);
|
|
147
|
+
const serialized = tx.serialize();
|
|
148
|
+
serializedTransactions.push({
|
|
149
|
+
data: Buffer.from(serialized).toString('base64'),
|
|
150
|
+
isVersioned: false,
|
|
151
|
+
signature: tx.signature ? Buffer.from(tx.signature).toString('base64') : undefined,
|
|
152
|
+
});
|
|
153
|
+
if (tx.signature) {
|
|
154
|
+
allSignatures.push(Buffer.from(tx.signature).toString('base64'));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Tip
|
|
159
|
+
const tipTx = new Transaction().add(buildTipInstruction(tipPayer.publicKey, tipLamports, tipAccount));
|
|
160
|
+
tipTx.recentBlockhash = blockhash;
|
|
161
|
+
tipTx.feePayer = tipPayer.publicKey;
|
|
162
|
+
tipTx.sign(tipPayer);
|
|
163
|
+
serializedTransactions.push({
|
|
164
|
+
data: Buffer.from(tipTx.serialize()).toString('base64'),
|
|
165
|
+
isVersioned: false,
|
|
166
|
+
signature: tipTx.signature ? Buffer.from(tipTx.signature).toString('base64') : undefined,
|
|
167
|
+
});
|
|
168
|
+
if (tipTx.signature) {
|
|
169
|
+
allSignatures.push(Buffer.from(tipTx.signature).toString('base64'));
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
success: true,
|
|
173
|
+
bundleData: {
|
|
174
|
+
transactions: serializedTransactions,
|
|
175
|
+
signatures: allSignatures,
|
|
176
|
+
tip: {
|
|
177
|
+
account: tipAccount,
|
|
178
|
+
lamports: tipLamports,
|
|
179
|
+
},
|
|
180
|
+
recentBlockhash: blockhash,
|
|
181
|
+
lastValidBlockHeight,
|
|
182
|
+
createdAt: Date.now(),
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
return {
|
|
188
|
+
success: false,
|
|
189
|
+
error: error.message,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* 构建 Raydium LaunchLab 批量买入(Jito Bundle)
|
|
195
|
+
*/
|
|
196
|
+
export async function signRaydiumLaunchLabBundleBuy(connection, params) {
|
|
197
|
+
try {
|
|
198
|
+
const { poolId, mintA, buyers, tipPayer, tipLamports = BigInt(10000), slippageBps = 100, } = params;
|
|
199
|
+
if (buyers.length === 0) {
|
|
200
|
+
return { success: false, error: 'No buyers provided' };
|
|
201
|
+
}
|
|
202
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
203
|
+
const serializedTransactions = [];
|
|
204
|
+
const allSignatures = [];
|
|
205
|
+
const tipAccount = getRandomTipAccount();
|
|
206
|
+
for (const { wallet, amountIn } of buyers) {
|
|
207
|
+
const userRaydium = await initRaydium(connection, wallet);
|
|
208
|
+
const txData = await userRaydium.launchpad.buyToken({
|
|
209
|
+
mintA: new PublicKey(mintA),
|
|
210
|
+
buyAmount: new BN(amountIn.toString()),
|
|
211
|
+
slippage: new BN(Math.floor(slippageBps)),
|
|
212
|
+
txVersion: TxVersion.LEGACY,
|
|
213
|
+
});
|
|
214
|
+
if (txData.transaction) {
|
|
215
|
+
const tx = txData.transaction;
|
|
216
|
+
tx.recentBlockhash = blockhash;
|
|
217
|
+
tx.feePayer = wallet.publicKey;
|
|
218
|
+
tx.sign(wallet);
|
|
219
|
+
const serialized = tx.serialize();
|
|
220
|
+
serializedTransactions.push({
|
|
221
|
+
data: Buffer.from(serialized).toString('base64'),
|
|
222
|
+
isVersioned: false,
|
|
223
|
+
signature: tx.signature ? Buffer.from(tx.signature).toString('base64') : undefined,
|
|
224
|
+
});
|
|
225
|
+
if (tx.signature) {
|
|
226
|
+
allSignatures.push(Buffer.from(tx.signature).toString('base64'));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// Tip
|
|
231
|
+
const tipTx = new Transaction().add(buildTipInstruction(tipPayer.publicKey, tipLamports, tipAccount));
|
|
232
|
+
tipTx.recentBlockhash = blockhash;
|
|
233
|
+
tipTx.feePayer = tipPayer.publicKey;
|
|
234
|
+
tipTx.sign(tipPayer);
|
|
235
|
+
serializedTransactions.push({
|
|
236
|
+
data: Buffer.from(tipTx.serialize()).toString('base64'),
|
|
237
|
+
isVersioned: false,
|
|
238
|
+
signature: tipTx.signature ? Buffer.from(tipTx.signature).toString('base64') : undefined,
|
|
239
|
+
});
|
|
240
|
+
if (tipTx.signature) {
|
|
241
|
+
allSignatures.push(Buffer.from(tipTx.signature).toString('base64'));
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
success: true,
|
|
245
|
+
bundleData: {
|
|
246
|
+
transactions: serializedTransactions,
|
|
247
|
+
signatures: allSignatures,
|
|
248
|
+
tip: { account: tipAccount, lamports: tipLamports },
|
|
249
|
+
recentBlockhash: blockhash,
|
|
250
|
+
lastValidBlockHeight,
|
|
251
|
+
createdAt: Date.now(),
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
return { success: false, error: error.message };
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* 构建 Raydium LaunchLab 批量卖出(Jito Bundle)
|
|
261
|
+
*/
|
|
262
|
+
export async function signRaydiumLaunchLabBundleSell(connection, params) {
|
|
263
|
+
try {
|
|
264
|
+
const { poolId, mintA, sellers, tipPayer, tipLamports = BigInt(10000), slippageBps = 100, } = params;
|
|
265
|
+
if (sellers.length === 0) {
|
|
266
|
+
return { success: false, error: 'No sellers provided' };
|
|
267
|
+
}
|
|
268
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
269
|
+
const serializedTransactions = [];
|
|
270
|
+
const allSignatures = [];
|
|
271
|
+
const tipAccount = getRandomTipAccount();
|
|
272
|
+
for (const { wallet, tokenAmount } of sellers) {
|
|
273
|
+
const userRaydium = await initRaydium(connection, wallet);
|
|
274
|
+
const txData = await userRaydium.launchpad.sellToken({
|
|
275
|
+
mintA: new PublicKey(mintA),
|
|
276
|
+
sellAmount: new BN(tokenAmount.toString()),
|
|
277
|
+
slippage: new BN(Math.floor(slippageBps)),
|
|
278
|
+
txVersion: TxVersion.LEGACY,
|
|
279
|
+
});
|
|
280
|
+
if (txData.transaction) {
|
|
281
|
+
const tx = txData.transaction;
|
|
282
|
+
tx.recentBlockhash = blockhash;
|
|
283
|
+
tx.feePayer = wallet.publicKey;
|
|
284
|
+
tx.sign(wallet);
|
|
285
|
+
const serialized = tx.serialize();
|
|
286
|
+
serializedTransactions.push({
|
|
287
|
+
data: Buffer.from(serialized).toString('base64'),
|
|
288
|
+
isVersioned: false,
|
|
289
|
+
signature: tx.signature ? Buffer.from(tx.signature).toString('base64') : undefined,
|
|
290
|
+
});
|
|
291
|
+
if (tx.signature) {
|
|
292
|
+
allSignatures.push(Buffer.from(tx.signature).toString('base64'));
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// Tip
|
|
297
|
+
const tipTx = new Transaction().add(buildTipInstruction(tipPayer.publicKey, tipLamports, tipAccount));
|
|
298
|
+
tipTx.recentBlockhash = blockhash;
|
|
299
|
+
tipTx.feePayer = tipPayer.publicKey;
|
|
300
|
+
tipTx.sign(tipPayer);
|
|
301
|
+
serializedTransactions.push({
|
|
302
|
+
data: Buffer.from(tipTx.serialize()).toString('base64'),
|
|
303
|
+
isVersioned: false,
|
|
304
|
+
signature: tipTx.signature ? Buffer.from(tipTx.signature).toString('base64') : undefined,
|
|
305
|
+
});
|
|
306
|
+
if (tipTx.signature) {
|
|
307
|
+
allSignatures.push(Buffer.from(tipTx.signature).toString('base64'));
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
success: true,
|
|
311
|
+
bundleData: {
|
|
312
|
+
transactions: serializedTransactions,
|
|
313
|
+
signatures: allSignatures,
|
|
314
|
+
tip: { account: tipAccount, lamports: tipLamports },
|
|
315
|
+
recentBlockhash: blockhash,
|
|
316
|
+
lastValidBlockHeight,
|
|
317
|
+
createdAt: Date.now(),
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
return { success: false, error: error.message };
|
|
323
|
+
}
|
|
324
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raydium DEX 集成
|
|
3
|
+
* 支持 AMM V4/V5、CPMM、CLMM 池子的交易和 LP 管理
|
|
4
|
+
* @module sol/dex/raydium/raydium
|
|
5
|
+
*/
|
|
6
|
+
import { Connection, Keypair } from '@solana/web3.js';
|
|
7
|
+
import { Raydium } from '@raydium-io/raydium-sdk-v2';
|
|
8
|
+
import type { RaydiumSwapParams, RaydiumSwapResult, RaydiumAddLpParams, RaydiumRemoveLpParams, RaydiumLpResult, RaydiumPoolInfo } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* 初始化 Raydium SDK
|
|
11
|
+
*/
|
|
12
|
+
export declare function initRaydium(connection: Connection, owner?: Keypair): Promise<Raydium>;
|
|
13
|
+
/**
|
|
14
|
+
* 获取池子信息
|
|
15
|
+
*/
|
|
16
|
+
export declare function getRaydiumPoolInfo(connection: Connection, poolId: string): Promise<RaydiumPoolInfo | null>;
|
|
17
|
+
/**
|
|
18
|
+
* 构建并签名 Raydium CPMM 交换交易
|
|
19
|
+
*/
|
|
20
|
+
export declare function signRaydiumCpmmSwap(connection: Connection, params: RaydiumSwapParams): Promise<RaydiumSwapResult>;
|
|
21
|
+
/**
|
|
22
|
+
* 构建并签名 Raydium AMM 交换交易
|
|
23
|
+
*/
|
|
24
|
+
export declare function signRaydiumAmmSwap(connection: Connection, params: RaydiumSwapParams): Promise<RaydiumSwapResult>;
|
|
25
|
+
/**
|
|
26
|
+
* 构建并签名 Raydium 交换交易(自动检测池子类型)
|
|
27
|
+
*/
|
|
28
|
+
export declare function signRaydiumSwap(connection: Connection, params: RaydiumSwapParams): Promise<RaydiumSwapResult>;
|
|
29
|
+
/**
|
|
30
|
+
* 构建并签名添加 LP 交易(CPMM)
|
|
31
|
+
*/
|
|
32
|
+
export declare function signRaydiumCpmmAddLp(connection: Connection, params: RaydiumAddLpParams): Promise<RaydiumLpResult>;
|
|
33
|
+
/**
|
|
34
|
+
* 构建并签名移除 LP 交易(CPMM)
|
|
35
|
+
*/
|
|
36
|
+
export declare function signRaydiumCpmmRemoveLp(connection: Connection, params: RaydiumRemoveLpParams): Promise<RaydiumLpResult>;
|
|
37
|
+
/**
|
|
38
|
+
* 通过代币对查找池子
|
|
39
|
+
*/
|
|
40
|
+
export declare function findRaydiumPool(connection: Connection, mintA: string, mintB: string): Promise<RaydiumPoolInfo[]>;
|