100x-sdk 1.0.1
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/README.md +364 -0
- package/dist/100x-sdk.cjs.js +57601 -0
- package/dist/100x-sdk.cjs.js.map +1 -0
- package/dist/100x-sdk.esm.js +46234 -0
- package/dist/100x-sdk.esm.js.map +1 -0
- package/dist/100x-sdk.js +46245 -0
- package/dist/100x-sdk.js.map +1 -0
- package/dist/index.d.ts +386 -0
- package/package.json +69 -0
- package/src/idl/fun100x_localnet.json +3735 -0
- package/src/idl/fun100x_main.json +3735 -0
- package/src/index.js +50 -0
- package/src/modules/chain.js +1310 -0
- package/src/modules/fast.js +734 -0
- package/src/modules/param.js +171 -0
- package/src/modules/simulator/buy_sell_token.js +326 -0
- package/src/modules/simulator/calcLiq.js +778 -0
- package/src/modules/simulator/calc_sol_liq.js +268 -0
- package/src/modules/simulator/close_indices.js +217 -0
- package/src/modules/simulator/long_shrot_stop.js +1028 -0
- package/src/modules/simulator/stop_loss_utils.js +378 -0
- package/src/modules/simulator/utils.js +63 -0
- package/src/modules/simulator.js +386 -0
- package/src/modules/token.js +455 -0
- package/src/modules/tools.js +370 -0
- package/src/modules/trading.js +848 -0
- package/src/sdk.js +206 -0
- package/src/types/index.d.ts +386 -0
- package/src/utils/constants.js +57 -0
- package/src/utils/curve_amm.js +1215 -0
- package/src/utils/orderUtils.js +17 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
const { ComputeBudgetProgram, PublicKey, Transaction, Keypair, SystemProgram, SYSVAR_RENT_PUBKEY } = require('@solana/web3.js');
|
|
2
|
+
const { TOKEN_PROGRAM_ID, getAssociatedTokenAddress, createAssociatedTokenAccountInstruction, ASSOCIATED_TOKEN_PROGRAM_ID } = require('@solana/spl-token');
|
|
3
|
+
const anchor = require('@coral-xyz/anchor');
|
|
4
|
+
// 统一使用 buffer 包,所有平台一致
|
|
5
|
+
const { Buffer } = require('buffer');
|
|
6
|
+
|
|
7
|
+
// Metaplex Token Metadata 程序ID
|
|
8
|
+
const METADATA_PROGRAM_ID = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Token Module
|
|
12
|
+
* Handles token creation, queries, balance and other operations
|
|
13
|
+
*/
|
|
14
|
+
class TokenModule {
|
|
15
|
+
constructor(sdk) {
|
|
16
|
+
this.sdk = sdk;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 创建新代币
|
|
21
|
+
* @param {Object} params - 创建参数
|
|
22
|
+
* @param {Keypair} params.mint - 代币mint keypair
|
|
23
|
+
* @param {string} params.name - 代币名称
|
|
24
|
+
* @param {string} params.symbol - 代币符号
|
|
25
|
+
* @param {string} params.uri - 元数据URI
|
|
26
|
+
* @param {PublicKey} params.payer - 创建者公钥(付款方)
|
|
27
|
+
*
|
|
28
|
+
* === 第二阶段新增:高级版池子可选参数(5个参数必须全部提供或全部不提供)===
|
|
29
|
+
* @param {anchor.BN} [params.customLpSol] - 自定义流动池SOL数量(lamports,9位精度)
|
|
30
|
+
* - 不传或传null:创建普通版池子,使用默认值30 SOL
|
|
31
|
+
* - 传入值:创建高级版池子,需在 10 SOL ~ 1000 SOL 范围内
|
|
32
|
+
* - ⚠️ 必须与其他4个 custom 参数同时提供
|
|
33
|
+
*
|
|
34
|
+
* @param {anchor.BN} [params.customLpToken] - 自定义流动池Token数量(最小单位,9位精度)
|
|
35
|
+
* - 不传或传null:使用默认值10.73亿 Token
|
|
36
|
+
* - 传入值:需在 1亿 ~ 100亿 Token 范围内
|
|
37
|
+
*
|
|
38
|
+
* @param {number} [params.customBorrowRatio] - 自定义借贷池代币占比(5-30表示5%-30%)
|
|
39
|
+
* - 不传或传null:使用默认值20%
|
|
40
|
+
* - 传入值:需在 5 ~ 30 范围内
|
|
41
|
+
*
|
|
42
|
+
* @param {number} [params.customBorrowDuration] - 自定义借贷时长(秒)
|
|
43
|
+
* - 不传或传null:使用Params账户配置的默认值
|
|
44
|
+
* - 传入值:需在 3天(259200秒) ~ 6个月(15552000秒) 范围内
|
|
45
|
+
*
|
|
46
|
+
* @param {number} [params.customFee] - 自定义手续费率(单位:基点 basis points)
|
|
47
|
+
* - 不传或传null:使用Params账户配置的默认手续费
|
|
48
|
+
* - 传入值:需在 1000 ~ 5000 范围内(表示 1% ~ 5%)
|
|
49
|
+
* - 示例:2000 表示 2%
|
|
50
|
+
* - 借贷手续费会自动上浮20%(如设置2000,则 swap_fee=2000,borrow_fee=2400)
|
|
51
|
+
*
|
|
52
|
+
* @returns {Promise<Object>} 包含transaction、signers和账户信息的对象
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // 创建普通版代币(使用默认参数)
|
|
56
|
+
* const result = await sdk.token.create({
|
|
57
|
+
* mint: mintKeypair,
|
|
58
|
+
* name: "My Token",
|
|
59
|
+
* symbol: "MTK",
|
|
60
|
+
* uri: "https://example.com/metadata.json",
|
|
61
|
+
* payer: wallet.publicKey
|
|
62
|
+
* });
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* // 创建高级版代币(自定义流动池参数,必须提供全部5个参数)
|
|
66
|
+
* const anchor = require('@coral-xyz/anchor');
|
|
67
|
+
* const result = await sdk.token.create({
|
|
68
|
+
* mint: mintKeypair,
|
|
69
|
+
* name: "Advanced Token",
|
|
70
|
+
* symbol: "ADV",
|
|
71
|
+
* uri: "https://example.com/metadata.json",
|
|
72
|
+
* payer: wallet.publicKey,
|
|
73
|
+
* customLpSol: new anchor.BN('60000000000'), // 60 SOL
|
|
74
|
+
* customLpToken: new anchor.BN('1073000000000000000'), // 10.73亿 Token
|
|
75
|
+
* customBorrowRatio: 15, // 15%
|
|
76
|
+
* customBorrowDuration: 7 * 24 * 3600, // 7天
|
|
77
|
+
* customFee: 2000 // 2% (2000 basis points)
|
|
78
|
+
* });
|
|
79
|
+
*/
|
|
80
|
+
async create({
|
|
81
|
+
mint,
|
|
82
|
+
name,
|
|
83
|
+
symbol,
|
|
84
|
+
uri,
|
|
85
|
+
payer,
|
|
86
|
+
// 高级版池子可选参数(5个参数必须全部提供或全部不提供)
|
|
87
|
+
customLpSol = null,
|
|
88
|
+
customLpToken = null,
|
|
89
|
+
customBorrowRatio = null,
|
|
90
|
+
customBorrowDuration = null,
|
|
91
|
+
customFee = null
|
|
92
|
+
}) {
|
|
93
|
+
console.log('Token Module - Create:', {
|
|
94
|
+
mint: mint.publicKey.toString(),
|
|
95
|
+
name,
|
|
96
|
+
symbol,
|
|
97
|
+
uri,
|
|
98
|
+
payer: payer.toString(),
|
|
99
|
+
// 高级版池子参数日志
|
|
100
|
+
poolType: (customLpSol === null && customLpToken === null &&
|
|
101
|
+
customBorrowRatio === null && customBorrowDuration === null &&
|
|
102
|
+
customFee === null)
|
|
103
|
+
? 'Standard (default params)'
|
|
104
|
+
: 'Advanced (custom params)',
|
|
105
|
+
customLpSol: customLpSol?.toString() || 'null',
|
|
106
|
+
customLpToken: customLpToken?.toString() || 'null',
|
|
107
|
+
customBorrowRatio: customBorrowRatio ?? 'null',
|
|
108
|
+
customBorrowDuration: customBorrowDuration ?? 'null',
|
|
109
|
+
customFee: customFee ?? 'null'
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Calculate borrowing liquidity pool account address (borrowing_curve)
|
|
113
|
+
const [curveAccount] = PublicKey.findProgramAddressSync(
|
|
114
|
+
[
|
|
115
|
+
Buffer.from("borrowing_curve"),
|
|
116
|
+
mint.publicKey.toBuffer(),
|
|
117
|
+
],
|
|
118
|
+
this.sdk.programId
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Calculate liquidity pool token account address (pool_token)
|
|
122
|
+
const [poolTokenAccount] = PublicKey.findProgramAddressSync(
|
|
123
|
+
[
|
|
124
|
+
Buffer.from("pool_token"),
|
|
125
|
+
mint.publicKey.toBuffer(),
|
|
126
|
+
],
|
|
127
|
+
this.sdk.programId
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// Calculate liquidity pool SOL account address (pool_sol)
|
|
131
|
+
const [poolSolAccount] = PublicKey.findProgramAddressSync(
|
|
132
|
+
[
|
|
133
|
+
Buffer.from("pool_sol"),
|
|
134
|
+
mint.publicKey.toBuffer(),
|
|
135
|
+
],
|
|
136
|
+
this.sdk.programId
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Calculate order book accounts (new)
|
|
140
|
+
const [upOrderbook] = PublicKey.findProgramAddressSync(
|
|
141
|
+
[
|
|
142
|
+
Buffer.from("up_orderbook"),
|
|
143
|
+
mint.publicKey.toBuffer(),
|
|
144
|
+
],
|
|
145
|
+
this.sdk.programId
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
const [downOrderbook] = PublicKey.findProgramAddressSync(
|
|
149
|
+
[
|
|
150
|
+
Buffer.from("down_orderbook"),
|
|
151
|
+
mint.publicKey.toBuffer(),
|
|
152
|
+
],
|
|
153
|
+
this.sdk.programId
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
// Calculate Metaplex metadata account address
|
|
157
|
+
const [metadataAccount] = PublicKey.findProgramAddressSync(
|
|
158
|
+
[
|
|
159
|
+
Buffer.from("metadata"),
|
|
160
|
+
METADATA_PROGRAM_ID.toBuffer(),
|
|
161
|
+
mint.publicKey.toBuffer(),
|
|
162
|
+
],
|
|
163
|
+
METADATA_PROGRAM_ID
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
console.log('Calculated account addresses:');
|
|
167
|
+
console.log(' Borrowing liquidity pool account:', curveAccount.toString());
|
|
168
|
+
console.log(' Liquidity pool token account:', poolTokenAccount.toString());
|
|
169
|
+
console.log(' Liquidity pool SOL account:', poolSolAccount.toString());
|
|
170
|
+
console.log(' Up orderbook:', upOrderbook.toString());
|
|
171
|
+
console.log(' Down orderbook:', downOrderbook.toString());
|
|
172
|
+
console.log(' Metadata account:', metadataAccount.toString());
|
|
173
|
+
console.log(' Params account:', this.sdk.paramsAccount?.toString() || 'Not set');
|
|
174
|
+
|
|
175
|
+
// Validate required configuration
|
|
176
|
+
if (!this.sdk.paramsAccount) {
|
|
177
|
+
throw new Error('SDK paramsAccount not configured, please provide paramsAccount configuration during initialization');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Create compute budget instruction
|
|
181
|
+
const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({
|
|
182
|
+
units: 400000
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// 构建创建代币指令(传入5个自定义参数)
|
|
186
|
+
const createIx = await this.sdk.program.methods
|
|
187
|
+
.createToken(
|
|
188
|
+
name,
|
|
189
|
+
symbol,
|
|
190
|
+
uri,
|
|
191
|
+
customLpSol, // Option<u64>
|
|
192
|
+
customLpToken, // Option<u64>
|
|
193
|
+
customBorrowRatio, // Option<u8>
|
|
194
|
+
customBorrowDuration, // Option<u32>
|
|
195
|
+
customFee // Option<u16> - 新增参数
|
|
196
|
+
)
|
|
197
|
+
.accounts({
|
|
198
|
+
payer: payer,
|
|
199
|
+
mintAccount: mint.publicKey,
|
|
200
|
+
curveAccount: curveAccount,
|
|
201
|
+
poolTokenAccount: poolTokenAccount,
|
|
202
|
+
poolSolAccount: poolSolAccount,
|
|
203
|
+
upOrderbook: upOrderbook,
|
|
204
|
+
downOrderbook: downOrderbook,
|
|
205
|
+
metadata: metadataAccount,
|
|
206
|
+
metadataProgram: METADATA_PROGRAM_ID,
|
|
207
|
+
params: this.sdk.paramsAccount,
|
|
208
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
209
|
+
systemProgram: SystemProgram.programId,
|
|
210
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
211
|
+
})
|
|
212
|
+
.instruction();
|
|
213
|
+
|
|
214
|
+
// Create transaction and add instructions
|
|
215
|
+
const transaction = new Transaction();
|
|
216
|
+
transaction.add(modifyComputeUnits);
|
|
217
|
+
transaction.add(createIx);
|
|
218
|
+
|
|
219
|
+
console.log('Token creation transaction built, signers required:', [payer.toString(), mint.publicKey.toString()]);
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
transaction,
|
|
223
|
+
signers: [mint], // mint keypair needs to be a signer
|
|
224
|
+
accounts: {
|
|
225
|
+
mint: mint.publicKey,
|
|
226
|
+
curveAccount,
|
|
227
|
+
poolTokenAccount,
|
|
228
|
+
poolSolAccount,
|
|
229
|
+
upOrderbook,
|
|
230
|
+
downOrderbook,
|
|
231
|
+
metadataAccount,
|
|
232
|
+
payer
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Create token and buy in one transaction
|
|
239
|
+
* 将 create 和 buy 两个指令合并到一个交易中,一次签名提交
|
|
240
|
+
*
|
|
241
|
+
* @param {Object} params - Creation and buy parameters
|
|
242
|
+
* @param {Keypair} params.mint - Token mint keypair
|
|
243
|
+
* @param {string} params.name - Token name
|
|
244
|
+
* @param {string} params.symbol - Token symbol
|
|
245
|
+
* @param {string} params.uri - Metadata URI
|
|
246
|
+
* @param {PublicKey} params.payer - Creator public key (payer)
|
|
247
|
+
* @param {anchor.BN} params.buyTokenAmount - Amount of tokens to buy
|
|
248
|
+
* @param {anchor.BN} params.maxSolAmount - Maximum SOL to spend
|
|
249
|
+
*
|
|
250
|
+
* === 第二阶段新增:高级版池子可选参数(5个参数必须全部提供或全部不提供)===
|
|
251
|
+
* @param {anchor.BN} [params.customLpSol] - 自定义流动池SOL数量(lamports,9位精度)
|
|
252
|
+
* @param {anchor.BN} [params.customLpToken] - 自定义流动池Token数量(最小单位,9位精度)
|
|
253
|
+
* @param {number} [params.customBorrowRatio] - 自定义借贷池代币占比(5-30表示5%-30%)
|
|
254
|
+
* @param {number} [params.customBorrowDuration] - 自定义借贷时长(秒)
|
|
255
|
+
* @param {number} [params.customFee] - 自定义手续费率(1000-5000 basis points,表示1%-5%)
|
|
256
|
+
*
|
|
257
|
+
* @param {Object} options - Optional parameters
|
|
258
|
+
* @param {number} options.computeUnits - Compute units limit, default 1800000
|
|
259
|
+
* @returns {Promise<Object>} Object containing transaction, signers and account info
|
|
260
|
+
*/
|
|
261
|
+
async createAndBuy({
|
|
262
|
+
mint,
|
|
263
|
+
name,
|
|
264
|
+
symbol,
|
|
265
|
+
uri,
|
|
266
|
+
payer,
|
|
267
|
+
buyTokenAmount,
|
|
268
|
+
maxSolAmount,
|
|
269
|
+
// 高级版池子可选参数(5个参数必须全部提供或全部不提供)
|
|
270
|
+
customLpSol = null,
|
|
271
|
+
customLpToken = null,
|
|
272
|
+
customBorrowRatio = null,
|
|
273
|
+
customBorrowDuration = null,
|
|
274
|
+
customFee = null
|
|
275
|
+
}, options = {}) {
|
|
276
|
+
const { computeUnits = 1800000 } = options;
|
|
277
|
+
|
|
278
|
+
console.log('Token Module - CreateAndBuy:', {
|
|
279
|
+
mint: mint.publicKey.toString(),
|
|
280
|
+
name,
|
|
281
|
+
symbol,
|
|
282
|
+
uri,
|
|
283
|
+
payer: payer.toString(),
|
|
284
|
+
buyTokenAmount: buyTokenAmount.toString(),
|
|
285
|
+
maxSolAmount: maxSolAmount.toString()
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// 1. 参数验证
|
|
289
|
+
if (!anchor.BN.isBN(buyTokenAmount) || !anchor.BN.isBN(maxSolAmount)) {
|
|
290
|
+
throw new Error('buyTokenAmount and maxSolAmount must be anchor.BN type');
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// 2. 调用 create 方法获取 create 交易(传递所有自定义参数)
|
|
294
|
+
console.log('Step 1: Building create transaction...');
|
|
295
|
+
const createResult = await this.create({
|
|
296
|
+
mint,
|
|
297
|
+
name,
|
|
298
|
+
symbol,
|
|
299
|
+
uri,
|
|
300
|
+
payer,
|
|
301
|
+
// 传递自定义流动池参数(5个参数)
|
|
302
|
+
customLpSol,
|
|
303
|
+
customLpToken,
|
|
304
|
+
customBorrowRatio,
|
|
305
|
+
customBorrowDuration,
|
|
306
|
+
customFee
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
// 3. 从 params 账户读取手续费接收地址
|
|
310
|
+
// 因为此时 curve_account 还未创建,无法从链上读取
|
|
311
|
+
console.log('Step 2: Fetching fee recipient accounts from params...');
|
|
312
|
+
|
|
313
|
+
// 直接从 SDK 配置中获取手续费接收账户(这些在 SDK 初始化时已经设置)
|
|
314
|
+
// 避免使用 program.account.params.fetch() 因为可能有 provider 配置问题
|
|
315
|
+
const feeRecipientAccount = this.sdk.feeRecipient;
|
|
316
|
+
const baseFeeRecipientAccount = this.sdk.baseFeeRecipient;
|
|
317
|
+
|
|
318
|
+
// 验证这些账户已配置
|
|
319
|
+
if (!feeRecipientAccount || !baseFeeRecipientAccount) {
|
|
320
|
+
throw new Error('Fee recipient accounts not configured in SDK options');
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
console.log('Fee recipient accounts:');
|
|
324
|
+
console.log(' Partner fee recipient:', feeRecipientAccount.toString());
|
|
325
|
+
console.log(' Base fee recipient:', baseFeeRecipientAccount.toString());
|
|
326
|
+
|
|
327
|
+
// 4. 准备 buy 所需的额外账户
|
|
328
|
+
console.log('Step 3: Calculating buy-related accounts...');
|
|
329
|
+
const mintPubkey = mint.publicKey;
|
|
330
|
+
|
|
331
|
+
// 计算用户代币账户
|
|
332
|
+
const userTokenAccount = await getAssociatedTokenAddress(
|
|
333
|
+
mintPubkey,
|
|
334
|
+
payer
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
// 计算 cooldown PDA
|
|
338
|
+
const [cooldownPDA] = PublicKey.findProgramAddressSync(
|
|
339
|
+
[
|
|
340
|
+
Buffer.from('trade_cooldown'),
|
|
341
|
+
mintPubkey.toBuffer(),
|
|
342
|
+
payer.toBuffer()
|
|
343
|
+
],
|
|
344
|
+
this.sdk.programId
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
// 计算 orderbook PDAs (复用 create 中计算的值)
|
|
348
|
+
const [upOrderbook] = PublicKey.findProgramAddressSync(
|
|
349
|
+
[Buffer.from('up_orderbook'), mintPubkey.toBuffer()],
|
|
350
|
+
this.sdk.programId
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
const [downOrderbook] = PublicKey.findProgramAddressSync(
|
|
354
|
+
[Buffer.from('down_orderbook'), mintPubkey.toBuffer()],
|
|
355
|
+
this.sdk.programId
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
console.log('Buy-related accounts:');
|
|
359
|
+
console.log(' User token account:', userTokenAccount.toString());
|
|
360
|
+
console.log(' Cooldown PDA:', cooldownPDA.toString());
|
|
361
|
+
|
|
362
|
+
// 5. 检查用户代币账户是否存在,创建 ATA 指令
|
|
363
|
+
console.log('Step 4: Checking if user token account exists...');
|
|
364
|
+
const userTokenAccountInfo = await this.sdk.connection.getAccountInfo(userTokenAccount);
|
|
365
|
+
const createAtaIx = userTokenAccountInfo === null
|
|
366
|
+
? createAssociatedTokenAccountInstruction(
|
|
367
|
+
payer,
|
|
368
|
+
userTokenAccount,
|
|
369
|
+
payer,
|
|
370
|
+
mintPubkey,
|
|
371
|
+
TOKEN_PROGRAM_ID,
|
|
372
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
373
|
+
)
|
|
374
|
+
: null;
|
|
375
|
+
|
|
376
|
+
if (createAtaIx) {
|
|
377
|
+
console.log(' User token account does not exist, will create it');
|
|
378
|
+
} else {
|
|
379
|
+
console.log(' User token account already exists');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// 6. 构建 buy 指令
|
|
383
|
+
console.log('Step 5: Building buy instruction...');
|
|
384
|
+
const buyIx = await this.sdk.program.methods
|
|
385
|
+
.buy(buyTokenAmount, maxSolAmount)
|
|
386
|
+
.accounts({
|
|
387
|
+
payer: payer,
|
|
388
|
+
mintAccount: mintPubkey,
|
|
389
|
+
curveAccount: createResult.accounts.curveAccount,
|
|
390
|
+
poolTokenAccount: createResult.accounts.poolTokenAccount,
|
|
391
|
+
poolSolAccount: createResult.accounts.poolSolAccount,
|
|
392
|
+
upOrderbook: upOrderbook,
|
|
393
|
+
downOrderbook: downOrderbook,
|
|
394
|
+
userTokenAccount: userTokenAccount,
|
|
395
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
396
|
+
systemProgram: SystemProgram.programId,
|
|
397
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
398
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
399
|
+
feeRecipientAccount: feeRecipientAccount,
|
|
400
|
+
baseFeeRecipientAccount: baseFeeRecipientAccount,
|
|
401
|
+
cooldown: cooldownPDA
|
|
402
|
+
})
|
|
403
|
+
.instruction();
|
|
404
|
+
|
|
405
|
+
// 7. 合并交易:create + buy
|
|
406
|
+
console.log('Step 6: Merging create and buy transactions...');
|
|
407
|
+
const transaction = new Transaction();
|
|
408
|
+
|
|
409
|
+
// 设置计算单元限制
|
|
410
|
+
const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({
|
|
411
|
+
units: computeUnits
|
|
412
|
+
});
|
|
413
|
+
transaction.add(modifyComputeUnits);
|
|
414
|
+
|
|
415
|
+
// 添加 create 交易的所有指令(跳过 create 中的计算单元指令)
|
|
416
|
+
createResult.transaction.instructions.forEach(ix => {
|
|
417
|
+
// 跳过 create 交易中的计算单元指令(我们已经添加了)
|
|
418
|
+
if (ix.programId.equals(ComputeBudgetProgram.programId)) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
transaction.add(ix);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// 添加 ATA 创建指令(如果需要)
|
|
425
|
+
if (createAtaIx) {
|
|
426
|
+
transaction.add(createAtaIx);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// 添加 buy 指令
|
|
430
|
+
transaction.add(buyIx);
|
|
431
|
+
|
|
432
|
+
console.log('CreateAndBuy transaction built successfully:');
|
|
433
|
+
console.log(' Total instructions:', transaction.instructions.length);
|
|
434
|
+
console.log(' Compute units:', computeUnits);
|
|
435
|
+
console.log(' Signers required:', [payer.toString(), mint.publicKey.toString()]);
|
|
436
|
+
|
|
437
|
+
// 8. 返回合并后的交易
|
|
438
|
+
return {
|
|
439
|
+
transaction,
|
|
440
|
+
signers: [mint], // mint keypair 需要签名
|
|
441
|
+
accounts: {
|
|
442
|
+
// create 的账户
|
|
443
|
+
...createResult.accounts,
|
|
444
|
+
// buy 的账户
|
|
445
|
+
userTokenAccount,
|
|
446
|
+
cooldown: cooldownPDA,
|
|
447
|
+
feeRecipientAccount,
|
|
448
|
+
baseFeeRecipientAccount
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
module.exports = TokenModule;
|