four-flap-meme-sdk 1.3.89 → 1.3.90
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/clients/blockrazor.js +1 -0
- package/dist/contracts/tm-bundle-merkle/core.js +3 -6
- package/dist/contracts/tm-bundle-merkle/pancake-proxy.js +38 -30
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.d.ts +1 -0
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.js +3 -4
- package/dist/contracts/tm-bundle-merkle/swap.d.ts +3 -0
- package/dist/contracts/tm-bundle-merkle/swap.js +2 -2
- package/dist/flap/portal-bundle-merkle/core.js +6 -2
- package/dist/flap/portal-bundle-merkle/pancake-proxy.js +35 -55
- package/dist/flap/portal-bundle-merkle/swap-buy-first.d.ts +2 -0
- package/dist/flap/portal-bundle-merkle/swap-buy-first.js +11 -6
- package/dist/flap/portal-bundle-merkle/swap.d.ts +2 -0
- package/dist/flap/portal-bundle-merkle/swap.js +22 -10
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/pancake/bundle-buy-first.d.ts +1 -0
- package/dist/pancake/bundle-buy-first.js +9 -4
- package/dist/pancake/bundle-swap.d.ts +4 -0
- package/dist/pancake/bundle-swap.js +14 -7
- package/dist/sol/constants.d.ts +126 -0
- package/dist/sol/constants.js +145 -0
- package/dist/sol/dex/index.d.ts +8 -0
- package/dist/sol/dex/index.js +12 -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 +146 -0
- package/dist/sol/dex/meteora/dlmm.js +593 -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 +10 -0
- package/dist/sol/index.js +16 -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/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 +129 -0
- package/dist/sol/utils/lp-inspect.js +521 -0
- package/dist/sol/utils/transfer.d.ts +125 -0
- package/dist/sol/utils/transfer.js +220 -0
- package/dist/sol/utils/wallet.d.ts +107 -0
- package/dist/sol/utils/wallet.js +210 -0
- package/dist/utils/erc20.d.ts +2 -108
- package/dist/utils/erc20.js +17 -65
- package/package.json +39 -4
- package/dist/flap/portal-bundle-merkle/encryption.d.ts +0 -16
- package/dist/flap/portal-bundle-merkle/encryption.js +0 -146
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pump.fun 批量签名(用于 Jito Bundle)
|
|
3
|
+
* 只构建指令和签名,不发送交易,提交到后端服务器通过 Jito 广播
|
|
4
|
+
* @module sol/dex/pump/pump-bundle
|
|
5
|
+
*/
|
|
6
|
+
import { Keypair, PublicKey, Transaction, } from '@solana/web3.js';
|
|
7
|
+
import BN from 'bn.js';
|
|
8
|
+
import { PUMP_SDK, OnlinePumpSdk, getBuyTokenAmountFromSolAmount, getSellSolAmountFromTokenAmount, } from '@pump-fun/pump-sdk';
|
|
9
|
+
import { getAssociatedTokenAddressSync, createAssociatedTokenAccountIdempotentInstruction, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, } from '@solana/spl-token';
|
|
10
|
+
import { buildTipInstruction, getRandomTipAccount } from '../../jito/tip.js';
|
|
11
|
+
/**
|
|
12
|
+
* 获取代币程序 ID
|
|
13
|
+
* Pump 新代币使用 Token-2022,旧代币使用 Token Program
|
|
14
|
+
*/
|
|
15
|
+
async function getTokenProgramForMint(connection, mint) {
|
|
16
|
+
try {
|
|
17
|
+
const accountInfo = await connection.getAccountInfo(mint);
|
|
18
|
+
if (accountInfo && accountInfo.owner.equals(TOKEN_2022_PROGRAM_ID)) {
|
|
19
|
+
return TOKEN_2022_PROGRAM_ID;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch { }
|
|
23
|
+
return TOKEN_PROGRAM_ID;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 构建批量买入指令(用于 Jito Bundle)
|
|
27
|
+
* 每个钱包一笔交易,最后加 Tip 交易
|
|
28
|
+
*
|
|
29
|
+
* @param connection Solana 连接
|
|
30
|
+
* @param mint 代币 Mint 地址
|
|
31
|
+
* @param buyers 买入列表
|
|
32
|
+
* @param tipPayer Tip 支付者
|
|
33
|
+
* @param tipLamports Tip 金额
|
|
34
|
+
* @param slippageBps 滑点(基点)
|
|
35
|
+
*/
|
|
36
|
+
export async function signPumpBundleBuy(connection, params) {
|
|
37
|
+
try {
|
|
38
|
+
const { mint, buyers, tipPayer, tipLamports = BigInt(10000), slippageBps = 100, } = params;
|
|
39
|
+
if (buyers.length === 0) {
|
|
40
|
+
return { success: false, error: 'No buyers provided' };
|
|
41
|
+
}
|
|
42
|
+
const mintPubkey = new PublicKey(mint);
|
|
43
|
+
const onlineSdk = new OnlinePumpSdk(connection);
|
|
44
|
+
// 获取全局状态和 bonding curve
|
|
45
|
+
const global = await onlineSdk.fetchGlobal();
|
|
46
|
+
const bondingCurve = await onlineSdk.fetchBondingCurve(mintPubkey);
|
|
47
|
+
const tokenProgram = await getTokenProgramForMint(connection, mintPubkey);
|
|
48
|
+
// 获取 blockhash
|
|
49
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
50
|
+
const serializedTransactions = [];
|
|
51
|
+
const allSignatures = [];
|
|
52
|
+
const tipAccount = getRandomTipAccount();
|
|
53
|
+
// 为每个买家构建交易
|
|
54
|
+
for (const { wallet, solAmount } of buyers) {
|
|
55
|
+
const solAmountBN = new BN(solAmount.toString());
|
|
56
|
+
// 计算代币数量
|
|
57
|
+
const tokenAmount = getBuyTokenAmountFromSolAmount({
|
|
58
|
+
global,
|
|
59
|
+
feeConfig: null,
|
|
60
|
+
mintSupply: bondingCurve.tokenTotalSupply,
|
|
61
|
+
bondingCurve,
|
|
62
|
+
amount: solAmountBN,
|
|
63
|
+
});
|
|
64
|
+
// 计算带滑点的最大 SOL
|
|
65
|
+
const maxSolAmount = solAmountBN.add(solAmountBN.mul(new BN(slippageBps)).div(new BN(10000)));
|
|
66
|
+
const instructions = [];
|
|
67
|
+
// 创建 ATA(如果需要)
|
|
68
|
+
const ata = getAssociatedTokenAddressSync(mintPubkey, wallet.publicKey, true, tokenProgram);
|
|
69
|
+
instructions.push(createAssociatedTokenAccountIdempotentInstruction(wallet.publicKey, ata, wallet.publicKey, mintPubkey, tokenProgram));
|
|
70
|
+
// 买入指令
|
|
71
|
+
const buyIx = await PUMP_SDK.getBuyInstructionRaw({
|
|
72
|
+
user: wallet.publicKey,
|
|
73
|
+
mint: mintPubkey,
|
|
74
|
+
creator: bondingCurve.creator,
|
|
75
|
+
amount: tokenAmount,
|
|
76
|
+
solAmount: maxSolAmount,
|
|
77
|
+
feeRecipient: global.feeRecipient,
|
|
78
|
+
tokenProgram,
|
|
79
|
+
});
|
|
80
|
+
instructions.push(buyIx);
|
|
81
|
+
// 构建交易
|
|
82
|
+
const transaction = new Transaction();
|
|
83
|
+
transaction.add(...instructions);
|
|
84
|
+
transaction.recentBlockhash = blockhash;
|
|
85
|
+
transaction.feePayer = wallet.publicKey;
|
|
86
|
+
transaction.sign(wallet);
|
|
87
|
+
const serialized = transaction.serialize();
|
|
88
|
+
serializedTransactions.push({
|
|
89
|
+
data: Buffer.from(serialized).toString('base64'),
|
|
90
|
+
isVersioned: false,
|
|
91
|
+
signature: transaction.signature ? Buffer.from(transaction.signature).toString('base64') : undefined,
|
|
92
|
+
});
|
|
93
|
+
if (transaction.signature) {
|
|
94
|
+
allSignatures.push(Buffer.from(transaction.signature).toString('base64'));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// 添加 Tip 交易
|
|
98
|
+
const tipTx = new Transaction().add(buildTipInstruction(tipPayer.publicKey, tipLamports, tipAccount));
|
|
99
|
+
tipTx.recentBlockhash = blockhash;
|
|
100
|
+
tipTx.feePayer = tipPayer.publicKey;
|
|
101
|
+
tipTx.sign(tipPayer);
|
|
102
|
+
serializedTransactions.push({
|
|
103
|
+
data: Buffer.from(tipTx.serialize()).toString('base64'),
|
|
104
|
+
isVersioned: false,
|
|
105
|
+
signature: tipTx.signature ? Buffer.from(tipTx.signature).toString('base64') : undefined,
|
|
106
|
+
});
|
|
107
|
+
if (tipTx.signature) {
|
|
108
|
+
allSignatures.push(Buffer.from(tipTx.signature).toString('base64'));
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
success: true,
|
|
112
|
+
bundleData: {
|
|
113
|
+
transactions: serializedTransactions,
|
|
114
|
+
signatures: allSignatures,
|
|
115
|
+
tip: {
|
|
116
|
+
account: tipAccount,
|
|
117
|
+
lamports: tipLamports,
|
|
118
|
+
},
|
|
119
|
+
recentBlockhash: blockhash,
|
|
120
|
+
lastValidBlockHeight,
|
|
121
|
+
createdAt: Date.now(),
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
return {
|
|
127
|
+
success: false,
|
|
128
|
+
error: error.message,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 构建批量卖出指令(用于 Jito Bundle)
|
|
134
|
+
*/
|
|
135
|
+
export async function signPumpBundleSell(connection, params) {
|
|
136
|
+
try {
|
|
137
|
+
const { mint, sellers, tipPayer, tipLamports = BigInt(10000), slippageBps = 100, } = params;
|
|
138
|
+
if (sellers.length === 0) {
|
|
139
|
+
return { success: false, error: 'No sellers provided' };
|
|
140
|
+
}
|
|
141
|
+
const mintPubkey = new PublicKey(mint);
|
|
142
|
+
const onlineSdk = new OnlinePumpSdk(connection);
|
|
143
|
+
// 获取全局状态和 bonding curve
|
|
144
|
+
const global = await onlineSdk.fetchGlobal();
|
|
145
|
+
const bondingCurve = await onlineSdk.fetchBondingCurve(mintPubkey);
|
|
146
|
+
const tokenProgram = await getTokenProgramForMint(connection, mintPubkey);
|
|
147
|
+
// 获取 blockhash
|
|
148
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
149
|
+
const serializedTransactions = [];
|
|
150
|
+
const allSignatures = [];
|
|
151
|
+
const tipAccount = getRandomTipAccount();
|
|
152
|
+
// 为每个卖家构建交易
|
|
153
|
+
for (const { wallet, tokenAmount } of sellers) {
|
|
154
|
+
const tokenAmountBN = new BN(tokenAmount.toString());
|
|
155
|
+
// 计算 SOL 数量
|
|
156
|
+
const solAmount = getSellSolAmountFromTokenAmount({
|
|
157
|
+
global,
|
|
158
|
+
feeConfig: null,
|
|
159
|
+
mintSupply: bondingCurve.tokenTotalSupply,
|
|
160
|
+
bondingCurve,
|
|
161
|
+
amount: tokenAmountBN,
|
|
162
|
+
});
|
|
163
|
+
// 计算带滑点的最小 SOL
|
|
164
|
+
const minSolAmount = solAmount.sub(solAmount.mul(new BN(slippageBps)).div(new BN(10000)));
|
|
165
|
+
// 卖出指令
|
|
166
|
+
const sellIx = await PUMP_SDK.getSellInstructionRaw({
|
|
167
|
+
user: wallet.publicKey,
|
|
168
|
+
mint: mintPubkey,
|
|
169
|
+
creator: bondingCurve.creator,
|
|
170
|
+
amount: tokenAmountBN,
|
|
171
|
+
solAmount: minSolAmount,
|
|
172
|
+
feeRecipient: global.feeRecipient,
|
|
173
|
+
tokenProgram,
|
|
174
|
+
});
|
|
175
|
+
// 构建交易
|
|
176
|
+
const transaction = new Transaction();
|
|
177
|
+
transaction.add(sellIx);
|
|
178
|
+
transaction.recentBlockhash = blockhash;
|
|
179
|
+
transaction.feePayer = wallet.publicKey;
|
|
180
|
+
transaction.sign(wallet);
|
|
181
|
+
const serialized = transaction.serialize();
|
|
182
|
+
serializedTransactions.push({
|
|
183
|
+
data: Buffer.from(serialized).toString('base64'),
|
|
184
|
+
isVersioned: false,
|
|
185
|
+
signature: transaction.signature ? Buffer.from(transaction.signature).toString('base64') : undefined,
|
|
186
|
+
});
|
|
187
|
+
if (transaction.signature) {
|
|
188
|
+
allSignatures.push(Buffer.from(transaction.signature).toString('base64'));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// 添加 Tip 交易
|
|
192
|
+
const tipTx = new Transaction().add(buildTipInstruction(tipPayer.publicKey, tipLamports, tipAccount));
|
|
193
|
+
tipTx.recentBlockhash = blockhash;
|
|
194
|
+
tipTx.feePayer = tipPayer.publicKey;
|
|
195
|
+
tipTx.sign(tipPayer);
|
|
196
|
+
serializedTransactions.push({
|
|
197
|
+
data: Buffer.from(tipTx.serialize()).toString('base64'),
|
|
198
|
+
isVersioned: false,
|
|
199
|
+
signature: tipTx.signature ? Buffer.from(tipTx.signature).toString('base64') : undefined,
|
|
200
|
+
});
|
|
201
|
+
if (tipTx.signature) {
|
|
202
|
+
allSignatures.push(Buffer.from(tipTx.signature).toString('base64'));
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
success: true,
|
|
206
|
+
bundleData: {
|
|
207
|
+
transactions: serializedTransactions,
|
|
208
|
+
signatures: allSignatures,
|
|
209
|
+
tip: {
|
|
210
|
+
account: tipAccount,
|
|
211
|
+
lamports: tipLamports,
|
|
212
|
+
},
|
|
213
|
+
recentBlockhash: blockhash,
|
|
214
|
+
lastValidBlockHeight,
|
|
215
|
+
createdAt: Date.now(),
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
return {
|
|
221
|
+
success: false,
|
|
222
|
+
error: error.message,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* 构建创建代币 + 批量买入的 Bundle
|
|
228
|
+
* 第一笔:创建代币 + 创建者购买
|
|
229
|
+
* 后续:其他钱包购买
|
|
230
|
+
* 最后:Tip
|
|
231
|
+
*/
|
|
232
|
+
export async function signPumpBundleCreateAndBuy(connection, params) {
|
|
233
|
+
try {
|
|
234
|
+
const { name, symbol, uri, creator, mintKeypair = Keypair.generate(), creatorBuyAmount = BigInt(0), buyers, tipPayer, tipLamports = BigInt(10000), slippageBps = 100, mayhemMode = false, } = params;
|
|
235
|
+
const onlineSdk = new OnlinePumpSdk(connection);
|
|
236
|
+
const global = await onlineSdk.fetchGlobal();
|
|
237
|
+
// 获取 blockhash
|
|
238
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
239
|
+
const serializedTransactions = [];
|
|
240
|
+
const allSignatures = [];
|
|
241
|
+
const tipAccount = getRandomTipAccount();
|
|
242
|
+
// 第一笔:创建代币(可选:创建者同时购买)
|
|
243
|
+
let createInstructions;
|
|
244
|
+
if (creatorBuyAmount > 0) {
|
|
245
|
+
const solAmount = new BN(creatorBuyAmount.toString());
|
|
246
|
+
const tokenAmount = getBuyTokenAmountFromSolAmount({
|
|
247
|
+
global,
|
|
248
|
+
feeConfig: null,
|
|
249
|
+
mintSupply: null,
|
|
250
|
+
bondingCurve: null,
|
|
251
|
+
amount: solAmount,
|
|
252
|
+
});
|
|
253
|
+
createInstructions = await PUMP_SDK.createV2AndBuyInstructions({
|
|
254
|
+
global,
|
|
255
|
+
mint: mintKeypair.publicKey,
|
|
256
|
+
name,
|
|
257
|
+
symbol,
|
|
258
|
+
uri,
|
|
259
|
+
creator: creator.publicKey,
|
|
260
|
+
user: creator.publicKey,
|
|
261
|
+
amount: tokenAmount,
|
|
262
|
+
solAmount,
|
|
263
|
+
mayhemMode,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const createIx = await PUMP_SDK.createV2Instruction({
|
|
268
|
+
mint: mintKeypair.publicKey,
|
|
269
|
+
name,
|
|
270
|
+
symbol,
|
|
271
|
+
uri,
|
|
272
|
+
creator: creator.publicKey,
|
|
273
|
+
user: creator.publicKey,
|
|
274
|
+
mayhemMode,
|
|
275
|
+
});
|
|
276
|
+
createInstructions = [createIx];
|
|
277
|
+
}
|
|
278
|
+
const createTx = new Transaction();
|
|
279
|
+
createTx.add(...createInstructions);
|
|
280
|
+
createTx.recentBlockhash = blockhash;
|
|
281
|
+
createTx.feePayer = creator.publicKey;
|
|
282
|
+
createTx.sign(creator, mintKeypair);
|
|
283
|
+
serializedTransactions.push({
|
|
284
|
+
data: Buffer.from(createTx.serialize()).toString('base64'),
|
|
285
|
+
isVersioned: false,
|
|
286
|
+
signature: createTx.signature ? Buffer.from(createTx.signature).toString('base64') : undefined,
|
|
287
|
+
});
|
|
288
|
+
if (createTx.signature) {
|
|
289
|
+
allSignatures.push(Buffer.from(createTx.signature).toString('base64'));
|
|
290
|
+
}
|
|
291
|
+
// 后续买家交易
|
|
292
|
+
// 注意:创建后的 bonding curve 状态需要预估
|
|
293
|
+
const tokenProgram = TOKEN_2022_PROGRAM_ID; // 新代币使用 Token-2022
|
|
294
|
+
for (const { wallet, solAmount } of buyers) {
|
|
295
|
+
const solAmountBN = new BN(solAmount.toString());
|
|
296
|
+
// 预估代币数量(使用初始状态)
|
|
297
|
+
const tokenAmount = getBuyTokenAmountFromSolAmount({
|
|
298
|
+
global,
|
|
299
|
+
feeConfig: null,
|
|
300
|
+
mintSupply: null,
|
|
301
|
+
bondingCurve: null,
|
|
302
|
+
amount: solAmountBN,
|
|
303
|
+
});
|
|
304
|
+
const maxSolAmount = solAmountBN.add(solAmountBN.mul(new BN(slippageBps)).div(new BN(10000)));
|
|
305
|
+
const instructions = [];
|
|
306
|
+
// 创建 ATA
|
|
307
|
+
const ata = getAssociatedTokenAddressSync(mintKeypair.publicKey, wallet.publicKey, true, tokenProgram);
|
|
308
|
+
instructions.push(createAssociatedTokenAccountIdempotentInstruction(wallet.publicKey, ata, wallet.publicKey, mintKeypair.publicKey, tokenProgram));
|
|
309
|
+
// 买入指令
|
|
310
|
+
const buyIx = await PUMP_SDK.getBuyInstructionRaw({
|
|
311
|
+
user: wallet.publicKey,
|
|
312
|
+
mint: mintKeypair.publicKey,
|
|
313
|
+
creator: creator.publicKey,
|
|
314
|
+
amount: tokenAmount,
|
|
315
|
+
solAmount: maxSolAmount,
|
|
316
|
+
feeRecipient: global.feeRecipient,
|
|
317
|
+
tokenProgram,
|
|
318
|
+
});
|
|
319
|
+
instructions.push(buyIx);
|
|
320
|
+
const transaction = new Transaction();
|
|
321
|
+
transaction.add(...instructions);
|
|
322
|
+
transaction.recentBlockhash = blockhash;
|
|
323
|
+
transaction.feePayer = wallet.publicKey;
|
|
324
|
+
transaction.sign(wallet);
|
|
325
|
+
serializedTransactions.push({
|
|
326
|
+
data: Buffer.from(transaction.serialize()).toString('base64'),
|
|
327
|
+
isVersioned: false,
|
|
328
|
+
signature: transaction.signature ? Buffer.from(transaction.signature).toString('base64') : undefined,
|
|
329
|
+
});
|
|
330
|
+
if (transaction.signature) {
|
|
331
|
+
allSignatures.push(Buffer.from(transaction.signature).toString('base64'));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// Tip 交易
|
|
335
|
+
const tipTx = new Transaction().add(buildTipInstruction(tipPayer.publicKey, tipLamports, tipAccount));
|
|
336
|
+
tipTx.recentBlockhash = blockhash;
|
|
337
|
+
tipTx.feePayer = tipPayer.publicKey;
|
|
338
|
+
tipTx.sign(tipPayer);
|
|
339
|
+
serializedTransactions.push({
|
|
340
|
+
data: Buffer.from(tipTx.serialize()).toString('base64'),
|
|
341
|
+
isVersioned: false,
|
|
342
|
+
signature: tipTx.signature ? Buffer.from(tipTx.signature).toString('base64') : undefined,
|
|
343
|
+
});
|
|
344
|
+
if (tipTx.signature) {
|
|
345
|
+
allSignatures.push(Buffer.from(tipTx.signature).toString('base64'));
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
success: true,
|
|
349
|
+
mintAddress: mintKeypair.publicKey.toBase58(),
|
|
350
|
+
bundleData: {
|
|
351
|
+
transactions: serializedTransactions,
|
|
352
|
+
signatures: allSignatures,
|
|
353
|
+
tip: {
|
|
354
|
+
account: tipAccount,
|
|
355
|
+
lamports: tipLamports,
|
|
356
|
+
},
|
|
357
|
+
recentBlockhash: blockhash,
|
|
358
|
+
lastValidBlockHeight,
|
|
359
|
+
createdAt: Date.now(),
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
return {
|
|
365
|
+
success: false,
|
|
366
|
+
error: error.message,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* 将 Bundle 数据转换为后端 API 格式
|
|
372
|
+
*/
|
|
373
|
+
export function toBundleApiRequest(bundleData) {
|
|
374
|
+
return {
|
|
375
|
+
transactions: bundleData.transactions.map(tx => tx.data),
|
|
376
|
+
signatures: bundleData.signatures,
|
|
377
|
+
tipAccount: bundleData.tip.account,
|
|
378
|
+
tipLamports: bundleData.tip.lamports.toString(),
|
|
379
|
+
recentBlockhash: bundleData.recentBlockhash,
|
|
380
|
+
lastValidBlockHeight: bundleData.lastValidBlockHeight,
|
|
381
|
+
timestamp: bundleData.createdAt,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pump Swap 批量签名(用于 Jito Bundle)
|
|
3
|
+
* 代币毕业后在 Pump Swap 池子进行交易
|
|
4
|
+
* @module sol/dex/pump/pump-swap-bundle
|
|
5
|
+
*/
|
|
6
|
+
import { Connection, Keypair } from '@solana/web3.js';
|
|
7
|
+
import type { SignedBundleData } from '../../jito/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Pump Swap 批量买入项
|
|
10
|
+
*/
|
|
11
|
+
export interface PumpSwapBundleBuyItem {
|
|
12
|
+
wallet: Keypair;
|
|
13
|
+
/** SOL 数量(lamports) */
|
|
14
|
+
solAmount: bigint;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Pump Swap 批量卖出项
|
|
18
|
+
*/
|
|
19
|
+
export interface PumpSwapBundleSellItem {
|
|
20
|
+
wallet: Keypair;
|
|
21
|
+
/** 代币数量 */
|
|
22
|
+
tokenAmount: bigint;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Pump Swap Bundle 签名结果
|
|
26
|
+
*/
|
|
27
|
+
export interface PumpSwapBundleSignResult {
|
|
28
|
+
success: boolean;
|
|
29
|
+
bundleData?: SignedBundleData;
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 构建 Pump Swap 批量买入(Jito Bundle)
|
|
34
|
+
*
|
|
35
|
+
* @param connection Solana 连接
|
|
36
|
+
* @param params 参数
|
|
37
|
+
*/
|
|
38
|
+
export declare function signPumpSwapBundleBuy(connection: Connection, params: {
|
|
39
|
+
/** 代币 Mint 地址 */
|
|
40
|
+
mint: string;
|
|
41
|
+
/** 买入列表 */
|
|
42
|
+
buyers: PumpSwapBundleBuyItem[];
|
|
43
|
+
/** Tip 支付者 */
|
|
44
|
+
tipPayer: Keypair;
|
|
45
|
+
/** Tip 金额(lamports) */
|
|
46
|
+
tipLamports?: bigint;
|
|
47
|
+
/** 滑点(百分比,如 1 表示 1%) */
|
|
48
|
+
slippagePercent?: number;
|
|
49
|
+
}): Promise<PumpSwapBundleSignResult>;
|
|
50
|
+
/**
|
|
51
|
+
* 构建 Pump Swap 批量卖出(Jito Bundle)
|
|
52
|
+
*/
|
|
53
|
+
export declare function signPumpSwapBundleSell(connection: Connection, params: {
|
|
54
|
+
/** 代币 Mint 地址 */
|
|
55
|
+
mint: string;
|
|
56
|
+
/** 卖出列表 */
|
|
57
|
+
sellers: PumpSwapBundleSellItem[];
|
|
58
|
+
/** Tip 支付者 */
|
|
59
|
+
tipPayer: Keypair;
|
|
60
|
+
/** Tip 金额(lamports) */
|
|
61
|
+
tipLamports?: bigint;
|
|
62
|
+
/** 滑点(百分比) */
|
|
63
|
+
slippagePercent?: number;
|
|
64
|
+
}): Promise<PumpSwapBundleSignResult>;
|
|
65
|
+
/**
|
|
66
|
+
* 构建 Pump Swap 批量买入(按代币数量)
|
|
67
|
+
* 指定想买多少代币,计算需要多少 SOL
|
|
68
|
+
*/
|
|
69
|
+
export declare function signPumpSwapBundleBuyByTokenAmount(connection: Connection, params: {
|
|
70
|
+
mint: string;
|
|
71
|
+
buyers: Array<{
|
|
72
|
+
wallet: Keypair;
|
|
73
|
+
tokenAmount: bigint;
|
|
74
|
+
}>;
|
|
75
|
+
tipPayer: Keypair;
|
|
76
|
+
tipLamports?: bigint;
|
|
77
|
+
slippagePercent?: number;
|
|
78
|
+
}): Promise<PumpSwapBundleSignResult>;
|
|
79
|
+
/**
|
|
80
|
+
* 构建 Pump Swap 批量卖出(按 SOL 数量)
|
|
81
|
+
* 指定想获得多少 SOL,计算需要卖多少代币
|
|
82
|
+
*/
|
|
83
|
+
export declare function signPumpSwapBundleSellBySolAmount(connection: Connection, params: {
|
|
84
|
+
mint: string;
|
|
85
|
+
sellers: Array<{
|
|
86
|
+
wallet: Keypair;
|
|
87
|
+
solAmount: bigint;
|
|
88
|
+
}>;
|
|
89
|
+
tipPayer: Keypair;
|
|
90
|
+
tipLamports?: bigint;
|
|
91
|
+
slippagePercent?: number;
|
|
92
|
+
}): Promise<PumpSwapBundleSignResult>;
|
|
93
|
+
/**
|
|
94
|
+
* 获取 Pump Swap 池子信息
|
|
95
|
+
*/
|
|
96
|
+
export declare function getPumpSwapBundlePoolInfo(connection: Connection, mint: string): Promise<{
|
|
97
|
+
poolAddress: string;
|
|
98
|
+
baseReserve: bigint;
|
|
99
|
+
quoteReserve: bigint;
|
|
100
|
+
lpSupply: bigint;
|
|
101
|
+
baseMint: string;
|
|
102
|
+
quoteMint: string;
|
|
103
|
+
} | null>;
|