pump-trader 1.1.4 → 1.1.8

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.
Files changed (3) hide show
  1. package/index.js +480 -236
  2. package/index.ts +1311 -247
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  TransactionInstruction,
6
6
  SystemProgram,
7
7
  ComputeBudgetProgram,
8
- Keypair
8
+ Keypair,
9
9
  } from "@solana/web3.js";
10
10
 
11
11
  import {
@@ -17,7 +17,7 @@ import {
17
17
  getTokenMetadata,
18
18
  TOKEN_2022_PROGRAM_ID,
19
19
  TOKEN_PROGRAM_ID,
20
- getMint
20
+ getMint,
21
21
  } from "@solana/spl-token";
22
22
 
23
23
  import BN from "bn.js";
@@ -30,28 +30,30 @@ const PROGRAM_IDS = {
30
30
  PUMP_AMM: new PublicKey("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"),
31
31
  METADATA: new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"),
32
32
  FEE: new PublicKey("pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"),
33
- EVENT_AUTHORITY: new PublicKey("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1")
33
+ EVENT_AUTHORITY: new PublicKey(
34
+ "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1",
35
+ ),
34
36
  };
35
37
 
36
38
  const SOL_MINT = new PublicKey("So11111111111111111111111111111111111111112");
37
39
 
38
40
  const SEEDS = {
39
41
  FEE_CONFIG: new Uint8Array([
40
- 1, 86, 224, 246, 147, 102, 90, 207, 68, 219, 21, 104, 191, 23, 91, 170,
41
- 81, 137, 203, 151, 245, 210, 255, 59, 101, 93, 43, 182, 253, 109, 24, 176
42
+ 1, 86, 224, 246, 147, 102, 90, 207, 68, 219, 21, 104, 191, 23, 91, 170, 81,
43
+ 137, 203, 151, 245, 210, 255, 59, 101, 93, 43, 182, 253, 109, 24, 176,
42
44
  ]),
43
45
  AMM_FEE_CONFIG: Buffer.from([
44
- 12, 20, 222, 252, 130, 94, 198, 118, 148, 37, 8, 24, 187, 101, 64, 101,
45
- 244, 41, 141, 49, 86, 213, 113, 180, 212, 248, 9, 12, 24, 233, 168, 99
46
+ 12, 20, 222, 252, 130, 94, 198, 118, 148, 37, 8, 24, 187, 101, 64, 101, 244,
47
+ 41, 141, 49, 86, 213, 113, 180, 212, 248, 9, 12, 24, 233, 168, 99,
46
48
  ]),
47
49
  GLOBAL: Buffer.from("global"),
48
- BONDING: Buffer.from("bonding-curve")
50
+ BONDING: Buffer.from("bonding-curve"),
49
51
  };
50
52
 
51
53
  const DISCRIMINATORS = {
52
54
  BUY: Buffer.from([102, 6, 61, 18, 1, 218, 235, 234]),
53
55
  SELL: Buffer.from([51, 230, 133, 164, 1, 127, 131, 173]),
54
- TRADE_EVENT: Buffer.from([189, 219, 127, 211, 78, 230, 97, 238])
56
+ TRADE_EVENT: Buffer.from([189, 219, 127, 211, 78, 230, 97, 238]),
55
57
  };
56
58
 
57
59
  const AMM_FEE_BPS = 100n; // 1%
@@ -64,7 +66,7 @@ const PUMP_NEW_FEE_RECIPIENTS = [
64
66
  "5cjcW9wExnJJiqgLjq7DEG75Pm6JBgE1hNv4B2vHXUW6",
65
67
  "EHAAiTxcdDwQ3U4bU6YcMsQGaekdzLS3B5SmYo46kJtL",
66
68
  "5eHhjP8JaYkz83CWwvGU2uMUXefd3AazWGx4gpcuEEYD",
67
- "A7hAgCzFw14fejgCp387JUJRMNyz4j89JKnhtKU8piqW"
69
+ "A7hAgCzFw14fejgCp387JUJRMNyz4j89JKnhtKU8piqW",
68
70
  ].map((value) => new PublicKey(value));
69
71
 
70
72
  /* ================= 工具函数 ================= */
@@ -84,7 +86,9 @@ const readU32 = (buf, offsetObj) => {
84
86
 
85
87
  const readString = (buf, offsetObj) => {
86
88
  const len = readU32(buf, offsetObj);
87
- const str = buf.slice(offsetObj.offset, offsetObj.offset + len).toString("utf8");
89
+ const str = buf
90
+ .slice(offsetObj.offset, offsetObj.offset + len)
91
+ .toString("utf8");
88
92
  offsetObj.offset += len;
89
93
  return str;
90
94
  };
@@ -94,10 +98,14 @@ const readString = (buf, offsetObj) => {
94
98
  function parseMetadataAccount(data) {
95
99
  const offsetObj = { offset: 1 }; // 跳过 key
96
100
 
97
- const updateAuthority = new PublicKey(data.slice(offsetObj.offset, offsetObj.offset + 32));
101
+ const updateAuthority = new PublicKey(
102
+ data.slice(offsetObj.offset, offsetObj.offset + 32),
103
+ );
98
104
  offsetObj.offset += 32;
99
105
 
100
- const mint = new PublicKey(data.slice(offsetObj.offset, offsetObj.offset + 32));
106
+ const mint = new PublicKey(
107
+ data.slice(offsetObj.offset, offsetObj.offset + 32),
108
+ );
101
109
  offsetObj.offset += 32;
102
110
 
103
111
  const name = readString(data, offsetObj);
@@ -109,13 +117,13 @@ function parseMetadataAccount(data) {
109
117
  mint: mint.toBase58(),
110
118
  name,
111
119
  symbol,
112
- uri
120
+ uri,
113
121
  };
114
122
  }
115
123
 
116
124
  function parsePoolKeys(data) {
117
125
  if (!data || data.length < 280) {
118
- throw new Error('Invalid pool account data');
126
+ throw new Error("Invalid pool account data");
119
127
  }
120
128
 
121
129
  let offset = 8; // 跳过 discriminator
@@ -152,7 +160,8 @@ function parsePoolKeys(data) {
152
160
 
153
161
  const isMayhemMode = data.readUInt8(offset) === 1;
154
162
  offset += 1;
155
- const isCashbackCoin = offset < data.length ? data.readUInt8(offset) === 1 : false;
163
+ const isCashbackCoin =
164
+ offset < data.length ? data.readUInt8(offset) === 1 : false;
156
165
 
157
166
  return {
158
167
  creator,
@@ -163,7 +172,7 @@ function parsePoolKeys(data) {
163
172
  poolQuoteTokenAccount,
164
173
  coinCreator,
165
174
  isMayhemMode,
166
- isCashbackCoin
175
+ isCashbackCoin,
167
176
  };
168
177
  }
169
178
 
@@ -173,7 +182,10 @@ export class PumpTrader {
173
182
  constructor(rpc, privateKey) {
174
183
  this.connection = new Connection(rpc, "confirmed");
175
184
  this.wallet = Keypair.fromSecretKey(bs58.decode(privateKey));
176
- this.global = PublicKey.findProgramAddressSync([SEEDS.GLOBAL], PROGRAM_IDS.PUMP)[0];
185
+ this.global = PublicKey.findProgramAddressSync(
186
+ [SEEDS.GLOBAL],
187
+ PROGRAM_IDS.PUMP,
188
+ )[0];
177
189
  this.globalState = null;
178
190
  this.tokenProgramCache = new Map(); // 缓存token program检测结果
179
191
  }
@@ -195,29 +207,59 @@ export class PumpTrader {
195
207
 
196
208
  try {
197
209
  // 首先尝试获取 TOKEN_2022 的代币信息
198
- const mintData = await getMint(this.connection, mint, "confirmed", TOKEN_2022_PROGRAM_ID);
210
+ const mintData = await getMint(
211
+ this.connection,
212
+ mint,
213
+ "confirmed",
214
+ TOKEN_2022_PROGRAM_ID,
215
+ );
199
216
  const result = {
200
217
  type: "TOKEN_2022_PROGRAM_ID",
201
- programId: TOKEN_2022_PROGRAM_ID
218
+ programId: TOKEN_2022_PROGRAM_ID,
202
219
  };
203
220
  this.tokenProgramCache.set(tokenAddr, result);
204
221
  return result;
205
222
  } catch (e) {
206
223
  try {
207
224
  // 如果失败,尝试标准 TOKEN_PROGRAM_ID
208
- const mintData = await getMint(this.connection, mint, "confirmed", TOKEN_PROGRAM_ID);
225
+ const mintData = await getMint(
226
+ this.connection,
227
+ mint,
228
+ "confirmed",
229
+ TOKEN_PROGRAM_ID,
230
+ );
209
231
  const result = {
210
232
  type: "TOKEN_PROGRAM_ID",
211
- programId: TOKEN_PROGRAM_ID
233
+ programId: TOKEN_PROGRAM_ID,
212
234
  };
213
235
  this.tokenProgramCache.set(tokenAddr, result);
214
236
  return result;
215
237
  } catch (error) {
216
- throw new Error(`Failed to detect token program for ${tokenAddr}: ${error}`);
238
+ throw new Error(
239
+ `Failed to detect token program for ${tokenAddr}: ${error}`,
240
+ );
217
241
  }
218
242
  }
219
243
  }
220
244
 
245
+ async detectQuoteTokenProgram(quoteMint) {
246
+ const quoteAddr = quoteMint.toBase58();
247
+ if (this.tokenProgramCache.has(quoteAddr)) {
248
+ return this.tokenProgramCache.get(quoteAddr).programId;
249
+ }
250
+ try {
251
+ await getMint(
252
+ this.connection,
253
+ quoteMint,
254
+ "confirmed",
255
+ TOKEN_2022_PROGRAM_ID,
256
+ );
257
+ return TOKEN_2022_PROGRAM_ID;
258
+ } catch {
259
+ return TOKEN_PROGRAM_ID;
260
+ }
261
+ }
262
+
221
263
  /* ---------- 内盘/外盘检测 ---------- */
222
264
 
223
265
  /**
@@ -282,7 +324,7 @@ export class PumpTrader {
282
324
  initialVirtualSolReserves: readU64(),
283
325
  initialRealTokenReserves: readU64(),
284
326
  tokenTotalSupply: readU64(),
285
- feeBasisPoints: readU64()
327
+ feeBasisPoints: readU64(),
286
328
  };
287
329
 
288
330
  return this.globalState;
@@ -293,14 +335,14 @@ export class PumpTrader {
293
335
  getBondingPda(mint) {
294
336
  return PublicKey.findProgramAddressSync(
295
337
  [SEEDS.BONDING, mint.toBuffer()],
296
- PROGRAM_IDS.PUMP
338
+ PROGRAM_IDS.PUMP,
297
339
  )[0];
298
340
  }
299
341
 
300
342
  deriveBondingCurveV2(mint) {
301
343
  return PublicKey.findProgramAddressSync(
302
344
  [Buffer.from("bonding-curve-v2"), mint.toBuffer()],
303
- PROGRAM_IDS.PUMP
345
+ PROGRAM_IDS.PUMP,
304
346
  )[0];
305
347
  }
306
348
 
@@ -316,7 +358,11 @@ export class PumpTrader {
316
358
  { pubkey: args.globalFeeRecipient, isSigner: false, isWritable: true },
317
359
  { pubkey: args.mint, isSigner: false, isWritable: false },
318
360
  { pubkey: args.bonding, isSigner: false, isWritable: true },
319
- { pubkey: args.associatedBondingCurve, isSigner: false, isWritable: true },
361
+ {
362
+ pubkey: args.associatedBondingCurve,
363
+ isSigner: false,
364
+ isWritable: true,
365
+ },
320
366
  { pubkey: args.userAta, isSigner: false, isWritable: true },
321
367
  { pubkey: args.wallet, isSigner: true, isWritable: true },
322
368
  { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
@@ -324,12 +370,16 @@ export class PumpTrader {
324
370
  { pubkey: args.creatorVault, isSigner: false, isWritable: true },
325
371
  { pubkey: args.eventAuthority, isSigner: false, isWritable: false },
326
372
  { pubkey: args.pumpProgram, isSigner: false, isWritable: false },
327
- { pubkey: args.globalVolumeAccumulator, isSigner: false, isWritable: false },
373
+ {
374
+ pubkey: args.globalVolumeAccumulator,
375
+ isSigner: false,
376
+ isWritable: false,
377
+ },
328
378
  { pubkey: args.userVolumeAccumulator, isSigner: false, isWritable: true },
329
379
  { pubkey: args.feeConfig, isSigner: false, isWritable: false },
330
380
  { pubkey: args.feeProgram, isSigner: false, isWritable: false },
331
381
  { pubkey: args.bondingCurveV2, isSigner: false, isWritable: false },
332
- { pubkey: args.feeRecipient, isSigner: false, isWritable: true }
382
+ { pubkey: args.feeRecipient, isSigner: false, isWritable: true },
333
383
  ];
334
384
  }
335
385
 
@@ -340,7 +390,11 @@ export class PumpTrader {
340
390
  { pubkey: args.globalFeeRecipient, isSigner: false, isWritable: true },
341
391
  { pubkey: args.mint, isSigner: false, isWritable: false },
342
392
  { pubkey: args.bonding, isSigner: false, isWritable: true },
343
- { pubkey: args.associatedBondingCurve, isSigner: false, isWritable: true },
393
+ {
394
+ pubkey: args.associatedBondingCurve,
395
+ isSigner: false,
396
+ isWritable: true,
397
+ },
344
398
  { pubkey: args.userAta, isSigner: false, isWritable: true },
345
399
  { pubkey: args.wallet, isSigner: true, isWritable: true },
346
400
  { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
@@ -349,16 +403,20 @@ export class PumpTrader {
349
403
  { pubkey: args.eventAuthority, isSigner: false, isWritable: false },
350
404
  { pubkey: args.pumpProgram, isSigner: false, isWritable: false },
351
405
  { pubkey: args.feeConfig, isSigner: false, isWritable: false },
352
- { pubkey: args.feeProgram, isSigner: false, isWritable: false }
406
+ { pubkey: args.feeProgram, isSigner: false, isWritable: false },
353
407
  ];
354
408
 
355
409
  if (args.isCashbackCoin) {
356
- keys.push({ pubkey: args.userVolumeAccumulator, isSigner: false, isWritable: true });
410
+ keys.push({
411
+ pubkey: args.userVolumeAccumulator,
412
+ isSigner: false,
413
+ isWritable: true,
414
+ });
357
415
  }
358
416
 
359
417
  keys.push(
360
418
  { pubkey: args.bondingCurveV2, isSigner: false, isWritable: false },
361
- { pubkey: args.feeRecipient, isSigner: false, isWritable: true }
419
+ { pubkey: args.feeRecipient, isSigner: false, isWritable: true },
362
420
  );
363
421
 
364
422
  return keys;
@@ -394,25 +452,29 @@ export class PumpTrader {
394
452
 
395
453
  calcBuy(solIn, state) {
396
454
  const newVirtualSol = state.virtualSolReserves + solIn;
397
- const newVirtualToken = (state.virtualSolReserves * state.virtualTokenReserves) / newVirtualSol;
455
+ const newVirtualToken =
456
+ (state.virtualSolReserves * state.virtualTokenReserves) / newVirtualSol;
398
457
  return state.virtualTokenReserves - newVirtualToken;
399
458
  }
400
459
 
401
460
  calcSell(tokenIn, state) {
402
461
  const newVirtualToken = state.virtualTokenReserves + tokenIn;
403
- const newVirtualSol = (state.virtualSolReserves * state.virtualTokenReserves) / newVirtualToken;
462
+ const newVirtualSol =
463
+ (state.virtualSolReserves * state.virtualTokenReserves) / newVirtualToken;
404
464
  return state.virtualSolReserves - newVirtualSol;
405
465
  }
406
466
 
407
467
  calculateAmmBuyOutput(quoteIn, reserves) {
408
- const quoteInAfterFee = (quoteIn * (BPS_DENOMINATOR - AMM_FEE_BPS)) / BPS_DENOMINATOR;
468
+ const quoteInAfterFee =
469
+ (quoteIn * (BPS_DENOMINATOR - AMM_FEE_BPS)) / BPS_DENOMINATOR;
409
470
  const numerator = reserves.baseAmount * quoteInAfterFee;
410
471
  const denominator = reserves.quoteAmount + quoteInAfterFee;
411
472
  return numerator / denominator;
412
473
  }
413
474
 
414
475
  calculateAmmSellOutput(baseIn, reserves) {
415
- const baseInAfterFee = (baseIn * (BPS_DENOMINATOR - AMM_FEE_BPS)) / BPS_DENOMINATOR;
476
+ const baseInAfterFee =
477
+ (baseIn * (BPS_DENOMINATOR - AMM_FEE_BPS)) / BPS_DENOMINATOR;
416
478
  const numerator = reserves.quoteAmount * baseInAfterFee;
417
479
  const denominator = reserves.baseAmount + baseInAfterFee;
418
480
  return numerator / denominator;
@@ -438,13 +500,19 @@ export class PumpTrader {
438
500
  async getAmmPrice(mint) {
439
501
  const [poolCreator] = PublicKey.findProgramAddressSync(
440
502
  [Buffer.from("pool-authority"), mint.toBuffer()],
441
- PROGRAM_IDS.PUMP
503
+ PROGRAM_IDS.PUMP,
442
504
  );
443
505
 
444
506
  const indexBuffer = new BN(0).toArrayLike(Buffer, "le", 2);
445
507
  const [pool] = PublicKey.findProgramAddressSync(
446
- [Buffer.from("pool"), indexBuffer, poolCreator.toBuffer(), mint.toBuffer(), SOL_MINT.toBuffer()],
447
- PROGRAM_IDS.PUMP_AMM
508
+ [
509
+ Buffer.from("pool"),
510
+ indexBuffer,
511
+ poolCreator.toBuffer(),
512
+ mint.toBuffer(),
513
+ SOL_MINT.toBuffer(),
514
+ ],
515
+ PROGRAM_IDS.PUMP_AMM,
448
516
  );
449
517
 
450
518
  const acc = await this.connection.getAccountInfo(pool);
@@ -453,7 +521,7 @@ export class PumpTrader {
453
521
  const poolKeys = parsePoolKeys(acc.data);
454
522
  const [baseInfo, quoteInfo] = await Promise.all([
455
523
  this.connection.getTokenAccountBalance(poolKeys.poolBaseTokenAccount),
456
- this.connection.getTokenAccountBalance(poolKeys.poolQuoteTokenAccount)
524
+ this.connection.getTokenAccountBalance(poolKeys.poolQuoteTokenAccount),
457
525
  ]);
458
526
 
459
527
  return quoteInfo.value.uiAmount / baseInfo.value.uiAmount;
@@ -472,9 +540,12 @@ export class PumpTrader {
472
540
  const mint = new PublicKey(tokenAddr);
473
541
  const tokenAccounts = await this.connection.getParsedTokenAccountsByOwner(
474
542
  this.wallet.publicKey,
475
- { mint }
543
+ { mint },
544
+ );
545
+ return (
546
+ tokenAccounts.value[0]?.account.data.parsed.info.tokenAmount.uiAmount ||
547
+ 0
476
548
  );
477
- return tokenAccounts.value[0]?.account.data.parsed.info.tokenAmount.uiAmount || 0;
478
549
  } else {
479
550
  // 查询所有代币
480
551
  return this.getAllTokenBalances();
@@ -488,13 +559,13 @@ export class PumpTrader {
488
559
  async getAllTokenBalances() {
489
560
  const tokenAccounts = await this.connection.getParsedTokenAccountsByOwner(
490
561
  this.wallet.publicKey,
491
- { programId: TOKEN_PROGRAM_ID }
562
+ { programId: TOKEN_PROGRAM_ID },
492
563
  );
493
564
 
494
565
  const balances = tokenAccounts.value
495
566
  .map((account) => {
496
567
  const parsed = account.account.data.parsed;
497
- if (parsed.type !== 'account') return null;
568
+ if (parsed.type !== "account") return null;
498
569
 
499
570
  const tokenAmount = parsed.info.tokenAmount;
500
571
  if (Number(tokenAmount.amount) === 0) return null;
@@ -503,21 +574,22 @@ export class PumpTrader {
503
574
  mint: parsed.info.mint,
504
575
  amount: BigInt(tokenAmount.amount),
505
576
  decimals: tokenAmount.decimals,
506
- uiAmount: tokenAmount.uiAmount || 0
577
+ uiAmount: tokenAmount.uiAmount || 0,
507
578
  };
508
579
  })
509
580
  .filter((item) => item !== null);
510
581
 
511
582
  // 同时查询 TOKEN_2022_PROGRAM_ID
512
- const token2022Accounts = await this.connection.getParsedTokenAccountsByOwner(
513
- this.wallet.publicKey,
514
- { programId: TOKEN_2022_PROGRAM_ID }
515
- );
583
+ const token2022Accounts =
584
+ await this.connection.getParsedTokenAccountsByOwner(
585
+ this.wallet.publicKey,
586
+ { programId: TOKEN_2022_PROGRAM_ID },
587
+ );
516
588
 
517
589
  const token2022Balances = token2022Accounts.value
518
590
  .map((account) => {
519
591
  const parsed = account.account.data.parsed;
520
- if (parsed.type !== 'account') return null;
592
+ if (parsed.type !== "account") return null;
521
593
 
522
594
  const tokenAmount = parsed.info.tokenAmount;
523
595
  if (Number(tokenAmount.amount) === 0) return null;
@@ -526,7 +598,7 @@ export class PumpTrader {
526
598
  mint: parsed.info.mint,
527
599
  amount: BigInt(tokenAmount.amount),
528
600
  decimals: tokenAmount.decimals,
529
- uiAmount: tokenAmount.uiAmount || 0
601
+ uiAmount: tokenAmount.uiAmount || 0,
530
602
  };
531
603
  })
532
604
  .filter((item) => item !== null);
@@ -544,7 +616,7 @@ export class PumpTrader {
544
616
  mint: b.mint,
545
617
  amount: Number(b.amount),
546
618
  decimals: b.decimals,
547
- uiAmount: b.uiAmount
619
+ uiAmount: b.uiAmount,
548
620
  }));
549
621
 
550
622
  return uniqueBalances;
@@ -564,7 +636,7 @@ export class PumpTrader {
564
636
  this.wallet.publicKey,
565
637
  false,
566
638
  program,
567
- ASSOCIATED_TOKEN_PROGRAM_ID
639
+ ASSOCIATED_TOKEN_PROGRAM_ID,
568
640
  );
569
641
 
570
642
  const acc = await this.connection.getAccountInfo(ata);
@@ -576,8 +648,8 @@ export class PumpTrader {
576
648
  this.wallet.publicKey,
577
649
  mint,
578
650
  program,
579
- ASSOCIATED_TOKEN_PROGRAM_ID
580
- )
651
+ ASSOCIATED_TOKEN_PROGRAM_ID,
652
+ ),
581
653
  );
582
654
  }
583
655
 
@@ -590,7 +662,7 @@ export class PumpTrader {
590
662
  owner,
591
663
  false,
592
664
  TOKEN_PROGRAM_ID,
593
- ASSOCIATED_TOKEN_PROGRAM_ID
665
+ ASSOCIATED_TOKEN_PROGRAM_ID,
594
666
  );
595
667
 
596
668
  const acc = await this.connection.getAccountInfo(wsolAta);
@@ -603,18 +675,18 @@ export class PumpTrader {
603
675
  owner,
604
676
  SOL_MINT,
605
677
  TOKEN_PROGRAM_ID,
606
- ASSOCIATED_TOKEN_PROGRAM_ID
607
- )
678
+ ASSOCIATED_TOKEN_PROGRAM_ID,
679
+ ),
608
680
  );
609
681
  }
610
682
 
611
- if (mode === 'buy') {
683
+ if (mode === "buy") {
612
684
  tx.add(
613
685
  SystemProgram.transfer({
614
686
  fromPubkey: owner,
615
687
  toPubkey: wsolAta,
616
- lamports: Number(lamports)
617
- })
688
+ lamports: Number(lamports),
689
+ }),
618
690
  );
619
691
  tx.add(createSyncNativeInstruction(wsolAta));
620
692
  }
@@ -628,7 +700,9 @@ export class PumpTrader {
628
700
  if (!priorityOpt?.enableRandom || !priorityOpt.randomRange) {
629
701
  return priorityOpt.base;
630
702
  }
631
- return priorityOpt.base + Math.floor(Math.random() * priorityOpt.randomRange);
703
+ return (
704
+ priorityOpt.base + Math.floor(Math.random() * priorityOpt.randomRange)
705
+ );
632
706
  }
633
707
 
634
708
  calcSlippage({ tradeSize, reserve, slippageOpt }) {
@@ -676,25 +750,47 @@ export class PumpTrader {
676
750
 
677
751
  /**
678
752
  * 统一的自动买入接口,自动判断内盘/外盘
753
+ * @param {boolean} [useV2=false] - use buy_v2 instruction (supports USDC quote)
754
+ * @param {PublicKey} [quoteMint=SOL_MINT] - quote mint (SOL_MINT for SOL-paired, USDC mint for USDC-paired)
679
755
  */
680
- async autoBuy(tokenAddr, totalSolIn, tradeOpt) {
756
+ async autoBuy(
757
+ tokenAddr,
758
+ totalSolIn,
759
+ tradeOpt,
760
+ useV2 = false,
761
+ quoteMint = SOL_MINT,
762
+ ) {
681
763
  const mode = await this.getTradeMode(tokenAddr);
682
764
  if (mode === "bonding") {
765
+ if (useV2) {
766
+ return this.buyV2(tokenAddr, totalSolIn, tradeOpt, quoteMint);
767
+ }
683
768
  return this.buy(tokenAddr, totalSolIn, tradeOpt);
684
769
  } else {
685
- return this.ammBuy(tokenAddr, totalSolIn, tradeOpt);
770
+ return this.ammBuy(tokenAddr, totalSolIn, tradeOpt, quoteMint);
686
771
  }
687
772
  }
688
773
 
689
774
  /**
690
775
  * 统一的自动卖出接口,自动判断内盘/外盘
776
+ * @param {boolean} [useV2=false] - use sell_v2 instruction
777
+ * @param {PublicKey} [quoteMint=SOL_MINT] - quote mint
691
778
  */
692
- async autoSell(tokenAddr, totalTokenIn, tradeOpt) {
779
+ async autoSell(
780
+ tokenAddr,
781
+ totalTokenIn,
782
+ tradeOpt,
783
+ useV2 = false,
784
+ quoteMint = SOL_MINT,
785
+ ) {
693
786
  const mode = await this.getTradeMode(tokenAddr);
694
787
  if (mode === "bonding") {
788
+ if (useV2) {
789
+ return this.sellV2(tokenAddr, totalTokenIn, tradeOpt, quoteMint);
790
+ }
695
791
  return this.sell(tokenAddr, totalTokenIn, tradeOpt);
696
792
  } else {
697
- return this.ammSell(tokenAddr, totalTokenIn, tradeOpt);
793
+ return this.ammSell(tokenAddr, totalTokenIn, tradeOpt, quoteMint);
698
794
  }
699
795
  }
700
796
 
@@ -715,27 +811,30 @@ export class PumpTrader {
715
811
  bonding,
716
812
  true,
717
813
  tokenProgram.programId,
718
- ASSOCIATED_TOKEN_PROGRAM_ID
814
+ ASSOCIATED_TOKEN_PROGRAM_ID,
719
815
  );
720
816
 
721
817
  const [creatorVault] = PublicKey.findProgramAddressSync(
722
818
  [Buffer.from("creator-vault"), creator.toBuffer()],
723
- PROGRAM_IDS.PUMP
819
+ PROGRAM_IDS.PUMP,
724
820
  );
725
821
 
726
822
  const [globalVolumeAccumulator] = PublicKey.findProgramAddressSync(
727
823
  [Buffer.from("global_volume_accumulator")],
728
- PROGRAM_IDS.PUMP
824
+ PROGRAM_IDS.PUMP,
729
825
  );
730
826
 
731
827
  const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
732
- [Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
733
- PROGRAM_IDS.PUMP
828
+ [
829
+ Buffer.from("user_volume_accumulator"),
830
+ this.wallet.publicKey.toBuffer(),
831
+ ],
832
+ PROGRAM_IDS.PUMP,
734
833
  );
735
834
 
736
835
  const [feeConfig] = PublicKey.findProgramAddressSync(
737
836
  [Buffer.from("fee_config"), SEEDS.FEE_CONFIG],
738
- PROGRAM_IDS.FEE
837
+ PROGRAM_IDS.FEE,
739
838
  );
740
839
  const feeRecipient = this.pickFeeRecipient();
741
840
 
@@ -746,14 +845,14 @@ export class PumpTrader {
746
845
  const slippageBps = this.calcSlippage({
747
846
  tradeSize: solIn,
748
847
  reserve: state.virtualSolReserves,
749
- slippageOpt: tradeOpt.slippage
848
+ slippageOpt: tradeOpt.slippage,
750
849
  });
751
850
  const maxSol = (solIn * BigInt(10_000 + slippageBps)) / 10_000n;
752
851
  const priority = this.genPriority(tradeOpt.priority);
753
852
 
754
853
  const tx = new Transaction().add(
755
854
  ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }),
756
- ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority })
855
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority }),
757
856
  );
758
857
 
759
858
  const userAta = await this.ensureAta(tx, mint, tokenProgram.programId);
@@ -778,32 +877,39 @@ export class PumpTrader {
778
877
  feeProgram: PROGRAM_IDS.FEE,
779
878
  bondingCurveV2,
780
879
  feeRecipient,
781
- tokenProgramId: tokenProgram.programId
880
+ tokenProgramId: tokenProgram.programId,
782
881
  }),
783
- data: Buffer.concat([DISCRIMINATORS.BUY, u64(tokenOut), u64(maxSol)])
784
- })
882
+ data: Buffer.concat([
883
+ DISCRIMINATORS.BUY,
884
+ u64(tokenOut),
885
+ u64(maxSol),
886
+ ]),
887
+ }),
785
888
  );
786
889
 
787
890
  const { blockhash, lastValidBlockHeight } =
788
- await this.connection.getLatestBlockhash('finalized');
891
+ await this.connection.getLatestBlockhash("finalized");
789
892
  tx.recentBlockhash = blockhash;
790
893
  tx.feePayer = this.wallet.publicKey;
791
894
  tx.sign(this.wallet);
792
895
 
793
- const signature = await this.connection.sendRawTransaction(tx.serialize(), {
794
- skipPreflight: false,
795
- maxRetries: 2
796
- });
896
+ const signature = await this.connection.sendRawTransaction(
897
+ tx.serialize(),
898
+ {
899
+ skipPreflight: false,
900
+ maxRetries: 2,
901
+ },
902
+ );
797
903
 
798
904
  pendingTransactions.push({
799
905
  signature,
800
906
  lastValidBlockHeight,
801
- index: i
907
+ index: i,
802
908
  });
803
909
  } catch (e) {
804
910
  failedTransactions.push({
805
911
  index: i,
806
- error: e.message
912
+ error: e.message,
807
913
  });
808
914
  }
809
915
  }
@@ -822,12 +928,15 @@ export class PumpTrader {
822
928
  if (state.complete) throw new Error("Bonding curve already completed");
823
929
 
824
930
  const totalSolOut = this.calcSell(totalTokenIn, state);
825
- const tokenChunks = totalSolOut <= tradeOpt.maxSolPerTx
826
- ? [totalTokenIn]
827
- : this.splitIntoN(
828
- totalTokenIn,
829
- Number((totalSolOut + tradeOpt.maxSolPerTx - 1n) / tradeOpt.maxSolPerTx)
830
- );
931
+ const tokenChunks =
932
+ totalSolOut <= tradeOpt.maxSolPerTx
933
+ ? [totalTokenIn]
934
+ : this.splitIntoN(
935
+ totalTokenIn,
936
+ Number(
937
+ (totalSolOut + tradeOpt.maxSolPerTx - 1n) / tradeOpt.maxSolPerTx,
938
+ ),
939
+ );
831
940
 
832
941
  const pendingTransactions = []; // 待确认的交易
833
942
  const failedTransactions = []; // 发送失败的交易
@@ -837,7 +946,7 @@ export class PumpTrader {
837
946
  bonding,
838
947
  true,
839
948
  tokenProgram.programId,
840
- ASSOCIATED_TOKEN_PROGRAM_ID
949
+ ASSOCIATED_TOKEN_PROGRAM_ID,
841
950
  );
842
951
 
843
952
  const userAta = getAssociatedTokenAddressSync(
@@ -845,21 +954,24 @@ export class PumpTrader {
845
954
  this.wallet.publicKey,
846
955
  false,
847
956
  tokenProgram.programId,
848
- ASSOCIATED_TOKEN_PROGRAM_ID
957
+ ASSOCIATED_TOKEN_PROGRAM_ID,
849
958
  );
850
959
 
851
960
  const [creatorVault] = PublicKey.findProgramAddressSync(
852
961
  [Buffer.from("creator-vault"), creator.toBuffer()],
853
- PROGRAM_IDS.PUMP
962
+ PROGRAM_IDS.PUMP,
854
963
  );
855
964
 
856
965
  const [feeConfig] = PublicKey.findProgramAddressSync(
857
966
  [Buffer.from("fee_config"), SEEDS.FEE_CONFIG],
858
- PROGRAM_IDS.FEE
967
+ PROGRAM_IDS.FEE,
859
968
  );
860
969
  const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
861
- [Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
862
- PROGRAM_IDS.PUMP
970
+ [
971
+ Buffer.from("user_volume_accumulator"),
972
+ this.wallet.publicKey.toBuffer(),
973
+ ],
974
+ PROGRAM_IDS.PUMP,
863
975
  );
864
976
  const feeRecipient = this.pickFeeRecipient();
865
977
 
@@ -870,14 +982,14 @@ export class PumpTrader {
870
982
  const slippageBps = this.calcSlippage({
871
983
  tradeSize: tokenIn,
872
984
  reserve: state.virtualTokenReserves,
873
- slippageOpt: tradeOpt.slippage
985
+ slippageOpt: tradeOpt.slippage,
874
986
  });
875
987
  const minSol = (solOut * BigInt(10_000 - slippageBps)) / 10_000n;
876
988
  const priority = this.genPriority(tradeOpt.priority);
877
989
 
878
990
  const tx = new Transaction().add(
879
991
  ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }),
880
- ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority })
992
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority }),
881
993
  );
882
994
 
883
995
  tx.add(
@@ -900,14 +1012,14 @@ export class PumpTrader {
900
1012
  feeRecipient,
901
1013
  isCashbackCoin: !!state.isCashbackCoin,
902
1014
  userVolumeAccumulator,
903
- tokenProgramId: tokenProgram.programId
1015
+ tokenProgramId: tokenProgram.programId,
904
1016
  }),
905
1017
  data: Buffer.concat([
906
1018
  DISCRIMINATORS.SELL,
907
1019
  u64(tokenIn),
908
- u64(minSol > 0n ? minSol : 1n)
909
- ])
910
- })
1020
+ u64(minSol > 0n ? minSol : 1n),
1021
+ ]),
1022
+ }),
911
1023
  );
912
1024
 
913
1025
  const { blockhash, lastValidBlockHeight } =
@@ -916,16 +1028,18 @@ export class PumpTrader {
916
1028
  tx.feePayer = this.wallet.publicKey;
917
1029
  tx.sign(this.wallet);
918
1030
 
919
- const signature = await this.connection.sendRawTransaction(tx.serialize());
1031
+ const signature = await this.connection.sendRawTransaction(
1032
+ tx.serialize(),
1033
+ );
920
1034
  pendingTransactions.push({
921
1035
  signature,
922
1036
  lastValidBlockHeight,
923
- index: i
1037
+ index: i,
924
1038
  });
925
1039
  } catch (e) {
926
1040
  failedTransactions.push({
927
1041
  index: i,
928
- error: e.message
1042
+ error: e.message,
929
1043
  });
930
1044
  }
931
1045
  }
@@ -935,12 +1049,16 @@ export class PumpTrader {
935
1049
 
936
1050
  /* ---------- 外盘交易 ---------- */
937
1051
 
938
- async ammBuy(tokenAddr, totalSolIn, tradeOpt) {
1052
+ async ammBuy(tokenAddr, totalSolIn, tradeOpt, quoteMint = SOL_MINT) {
939
1053
  const mint = new PublicKey(tokenAddr);
940
- const poolInfo = await this.getAmmPoolInfo(mint);
1054
+ const poolInfo = await this.getAmmPoolInfo(mint, quoteMint);
941
1055
  const reserves = await this.getAmmPoolReserves(poolInfo.poolKeys);
942
1056
  const solChunks = this.splitByMax(totalSolIn, tradeOpt.maxSolPerTx);
943
1057
  const tokenProgram = await this.detectTokenProgram(tokenAddr);
1058
+ const isSolQuote = quoteMint.equals(SOL_MINT);
1059
+ const quoteTokenProgramId = isSolQuote
1060
+ ? TOKEN_PROGRAM_ID
1061
+ : await this.detectQuoteTokenProgram(quoteMint);
944
1062
  const pendingTransactions = [];
945
1063
  const failedTransactions = [];
946
1064
 
@@ -951,23 +1069,29 @@ export class PumpTrader {
951
1069
  const slippageBps = this.calcSlippage({
952
1070
  tradeSize: solIn,
953
1071
  reserve: reserves.quoteAmount,
954
- slippageOpt: tradeOpt.slippage
1072
+ slippageOpt: tradeOpt.slippage,
955
1073
  });
956
1074
  const maxQuoteIn = (solIn * BigInt(10_000 + slippageBps)) / 10_000n;
957
1075
  const priority = this.genPriority(tradeOpt.priority);
958
1076
 
959
1077
  const tx = new Transaction().add(
960
1078
  ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 }),
961
- ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority })
1079
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority }),
962
1080
  );
963
1081
 
964
- const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint, tokenProgram.programId);
965
- const userQuoteAta = await this.ensureWSOLAta(
1082
+ const userBaseAta = await this.ensureAta(
966
1083
  tx,
967
- this.wallet.publicKey,
968
- "buy",
969
- maxQuoteIn
1084
+ poolInfo.poolKeys.baseMint,
1085
+ tokenProgram.programId,
970
1086
  );
1087
+ const userQuoteAta = isSolQuote
1088
+ ? await this.ensureWSOLAta(
1089
+ tx,
1090
+ this.wallet.publicKey,
1091
+ "buy",
1092
+ maxQuoteIn,
1093
+ )
1094
+ : await this.ensureAta(tx, quoteMint, quoteTokenProgramId);
971
1095
 
972
1096
  const buyIx = this.createAmmBuyInstruction(
973
1097
  poolInfo,
@@ -975,38 +1099,43 @@ export class PumpTrader {
975
1099
  userQuoteAta,
976
1100
  baseAmountOut,
977
1101
  maxQuoteIn,
978
- tokenProgram.programId
1102
+ tokenProgram.programId,
979
1103
  );
980
1104
 
981
1105
  tx.add(buyIx);
982
- tx.add(
983
- createCloseAccountInstruction(
984
- userQuoteAta,
985
- this.wallet.publicKey,
986
- this.wallet.publicKey
987
- )
988
- );
1106
+ if (isSolQuote) {
1107
+ tx.add(
1108
+ createCloseAccountInstruction(
1109
+ userQuoteAta,
1110
+ this.wallet.publicKey,
1111
+ this.wallet.publicKey,
1112
+ ),
1113
+ );
1114
+ }
989
1115
 
990
1116
  const { blockhash, lastValidBlockHeight } =
991
- await this.connection.getLatestBlockhash('finalized');
1117
+ await this.connection.getLatestBlockhash("finalized");
992
1118
  tx.recentBlockhash = blockhash;
993
1119
  tx.feePayer = this.wallet.publicKey;
994
1120
  tx.sign(this.wallet);
995
1121
 
996
- const signature = await this.connection.sendRawTransaction(tx.serialize(), {
997
- skipPreflight: false,
998
- maxRetries: 2
999
- });
1122
+ const signature = await this.connection.sendRawTransaction(
1123
+ tx.serialize(),
1124
+ {
1125
+ skipPreflight: false,
1126
+ maxRetries: 2,
1127
+ },
1128
+ );
1000
1129
 
1001
1130
  pendingTransactions.push({
1002
1131
  signature,
1003
1132
  lastValidBlockHeight,
1004
- index: i
1133
+ index: i,
1005
1134
  });
1006
1135
  } catch (e) {
1007
1136
  failedTransactions.push({
1008
1137
  index: i,
1009
- error: e.message
1138
+ error: e.message,
1010
1139
  });
1011
1140
  }
1012
1141
  }
@@ -1014,19 +1143,26 @@ export class PumpTrader {
1014
1143
  return { pendingTransactions, failedTransactions };
1015
1144
  }
1016
1145
 
1017
- async ammSell(tokenAddr, totalTokenIn, tradeOpt) {
1146
+ async ammSell(tokenAddr, totalTokenIn, tradeOpt, quoteMint = SOL_MINT) {
1018
1147
  const mint = new PublicKey(tokenAddr);
1019
- const poolInfo = await this.getAmmPoolInfo(mint);
1148
+ const poolInfo = await this.getAmmPoolInfo(mint, quoteMint);
1020
1149
  const reserves = await this.getAmmPoolReserves(poolInfo.poolKeys);
1021
1150
  const totalSolOut = this.calculateAmmSellOutput(totalTokenIn, reserves);
1022
1151
  const tokenProgram = await this.detectTokenProgram(tokenAddr);
1023
-
1024
- const tokenChunks = totalSolOut <= tradeOpt.maxSolPerTx
1025
- ? [totalTokenIn]
1026
- : this.splitIntoN(
1027
- totalTokenIn,
1028
- Number((totalSolOut + tradeOpt.maxSolPerTx - 1n) / tradeOpt.maxSolPerTx)
1029
- );
1152
+ const isSolQuote = quoteMint.equals(SOL_MINT);
1153
+ const quoteTokenProgramId = isSolQuote
1154
+ ? TOKEN_PROGRAM_ID
1155
+ : await this.detectQuoteTokenProgram(quoteMint);
1156
+
1157
+ const tokenChunks =
1158
+ totalSolOut <= tradeOpt.maxSolPerTx
1159
+ ? [totalTokenIn]
1160
+ : this.splitIntoN(
1161
+ totalTokenIn,
1162
+ Number(
1163
+ (totalSolOut + tradeOpt.maxSolPerTx - 1n) / tradeOpt.maxSolPerTx,
1164
+ ),
1165
+ );
1030
1166
 
1031
1167
  const pendingTransactions = [];
1032
1168
  const failedTransactions = [];
@@ -1038,18 +1174,24 @@ export class PumpTrader {
1038
1174
  const slippageBps = this.calcSlippage({
1039
1175
  tradeSize: tokenIn,
1040
1176
  reserve: reserves.baseAmount,
1041
- slippageOpt: tradeOpt.slippage
1177
+ slippageOpt: tradeOpt.slippage,
1042
1178
  });
1043
1179
  const minQuoteOut = (solOut * BigInt(10_000 - slippageBps)) / 10_000n;
1044
1180
  const priority = this.genPriority(tradeOpt.priority);
1045
1181
 
1046
1182
  const tx = new Transaction().add(
1047
1183
  ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 }),
1048
- ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority })
1184
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority }),
1049
1185
  );
1050
1186
 
1051
- const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint, tokenProgram.programId);
1052
- const userQuoteAta = await this.ensureWSOLAta(tx, this.wallet.publicKey, "sell");
1187
+ const userBaseAta = await this.ensureAta(
1188
+ tx,
1189
+ poolInfo.poolKeys.baseMint,
1190
+ tokenProgram.programId,
1191
+ );
1192
+ const userQuoteAta = isSolQuote
1193
+ ? await this.ensureWSOLAta(tx, this.wallet.publicKey, "sell")
1194
+ : await this.ensureAta(tx, quoteMint, quoteTokenProgramId);
1053
1195
 
1054
1196
  const sellIx = this.createAmmSellInstruction(
1055
1197
  poolInfo,
@@ -1057,38 +1199,43 @@ export class PumpTrader {
1057
1199
  userQuoteAta,
1058
1200
  tokenIn,
1059
1201
  minQuoteOut,
1060
- tokenProgram.programId
1202
+ tokenProgram.programId,
1061
1203
  );
1062
1204
 
1063
1205
  tx.add(sellIx);
1064
- tx.add(
1065
- createCloseAccountInstruction(
1066
- userQuoteAta,
1067
- this.wallet.publicKey,
1068
- this.wallet.publicKey
1069
- )
1070
- );
1206
+ if (isSolQuote) {
1207
+ tx.add(
1208
+ createCloseAccountInstruction(
1209
+ userQuoteAta,
1210
+ this.wallet.publicKey,
1211
+ this.wallet.publicKey,
1212
+ ),
1213
+ );
1214
+ }
1071
1215
 
1072
1216
  const { blockhash, lastValidBlockHeight } =
1073
- await this.connection.getLatestBlockhash('finalized');
1217
+ await this.connection.getLatestBlockhash("finalized");
1074
1218
  tx.recentBlockhash = blockhash;
1075
1219
  tx.feePayer = this.wallet.publicKey;
1076
1220
  tx.sign(this.wallet);
1077
1221
 
1078
- const signature = await this.connection.sendRawTransaction(tx.serialize(), {
1079
- skipPreflight: false,
1080
- maxRetries: 2
1081
- });
1222
+ const signature = await this.connection.sendRawTransaction(
1223
+ tx.serialize(),
1224
+ {
1225
+ skipPreflight: false,
1226
+ maxRetries: 2,
1227
+ },
1228
+ );
1082
1229
 
1083
1230
  pendingTransactions.push({
1084
1231
  signature,
1085
1232
  lastValidBlockHeight,
1086
- index: i
1233
+ index: i,
1087
1234
  });
1088
1235
  } catch (e) {
1089
1236
  failedTransactions.push({
1090
1237
  index: i,
1091
- error: e.message
1238
+ error: e.message,
1092
1239
  });
1093
1240
  }
1094
1241
  }
@@ -1098,10 +1245,10 @@ export class PumpTrader {
1098
1245
 
1099
1246
  /* ---------- AMM 池信息 ---------- */
1100
1247
 
1101
- async getAmmPoolInfo(mint) {
1248
+ async getAmmPoolInfo(mint, quoteMint = SOL_MINT) {
1102
1249
  const [poolAuthority] = PublicKey.findProgramAddressSync(
1103
1250
  [Buffer.from("pool-authority"), mint.toBuffer()],
1104
- PROGRAM_IDS.PUMP
1251
+ PROGRAM_IDS.PUMP,
1105
1252
  );
1106
1253
 
1107
1254
  const [pool] = PublicKey.findProgramAddressSync(
@@ -1110,9 +1257,9 @@ export class PumpTrader {
1110
1257
  new BN(0).toArrayLike(Buffer, "le", 2),
1111
1258
  poolAuthority.toBuffer(),
1112
1259
  mint.toBuffer(),
1113
- SOL_MINT.toBuffer()
1260
+ quoteMint.toBuffer(),
1114
1261
  ],
1115
- PROGRAM_IDS.PUMP_AMM
1262
+ PROGRAM_IDS.PUMP_AMM,
1116
1263
  );
1117
1264
 
1118
1265
  const acc = await this.connection.getAccountInfo(pool);
@@ -1122,13 +1269,17 @@ export class PumpTrader {
1122
1269
 
1123
1270
  const [globalConfigPda] = PublicKey.findProgramAddressSync(
1124
1271
  [Buffer.from("global_config")],
1125
- PROGRAM_IDS.PUMP_AMM
1272
+ PROGRAM_IDS.PUMP_AMM,
1126
1273
  );
1127
1274
 
1128
- const globalConfigAcc = await this.connection.getAccountInfo(globalConfigPda);
1275
+ const globalConfigAcc =
1276
+ await this.connection.getAccountInfo(globalConfigPda);
1129
1277
  if (!globalConfigAcc) throw new Error("Global config not found");
1130
1278
 
1131
- const globalConfig = this.parseAmmGlobalConfig(globalConfigAcc.data, globalConfigPda);
1279
+ const globalConfig = this.parseAmmGlobalConfig(
1280
+ globalConfigAcc.data,
1281
+ globalConfigPda,
1282
+ );
1132
1283
 
1133
1284
  return { pool, poolAuthority, poolKeys, globalConfig };
1134
1285
  }
@@ -1145,7 +1296,9 @@ export class PumpTrader {
1145
1296
 
1146
1297
  const protocolFeeRecipients = [];
1147
1298
  for (let i = 0; i < 8; i++) {
1148
- protocolFeeRecipients.push(new PublicKey(data.slice(offset, offset + 32)));
1299
+ protocolFeeRecipients.push(
1300
+ new PublicKey(data.slice(offset, offset + 32)),
1301
+ );
1149
1302
  offset += 32;
1150
1303
  }
1151
1304
 
@@ -1155,38 +1308,45 @@ export class PumpTrader {
1155
1308
  async getAmmPoolReserves(poolKeys) {
1156
1309
  const [baseInfo, quoteInfo] = await Promise.all([
1157
1310
  this.connection.getTokenAccountBalance(poolKeys.poolBaseTokenAccount),
1158
- this.connection.getTokenAccountBalance(poolKeys.poolQuoteTokenAccount)
1311
+ this.connection.getTokenAccountBalance(poolKeys.poolQuoteTokenAccount),
1159
1312
  ]);
1160
1313
 
1161
1314
  return {
1162
1315
  baseAmount: BigInt(baseInfo.value.amount),
1163
1316
  quoteAmount: BigInt(quoteInfo.value.amount),
1164
1317
  baseDecimals: baseInfo.value.decimals,
1165
- quoteDecimals: quoteInfo.value.decimals
1318
+ quoteDecimals: quoteInfo.value.decimals,
1166
1319
  };
1167
1320
  }
1168
1321
 
1169
1322
  deriveAmmPoolV2(baseMint) {
1170
1323
  return PublicKey.findProgramAddressSync(
1171
1324
  [Buffer.from("pool-v2"), baseMint.toBuffer()],
1172
- PROGRAM_IDS.PUMP_AMM
1325
+ PROGRAM_IDS.PUMP_AMM,
1173
1326
  )[0];
1174
1327
  }
1175
1328
 
1176
1329
  /* ---------- AMM 指令构建 ---------- */
1177
1330
 
1178
- createAmmBuyInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountOut, maxQuoteAmountIn, tokenProgramId) {
1331
+ createAmmBuyInstruction(
1332
+ poolInfo,
1333
+ userBaseAta,
1334
+ userQuoteAta,
1335
+ baseAmountOut,
1336
+ maxQuoteAmountIn,
1337
+ tokenProgramId,
1338
+ ) {
1179
1339
  const { pool, poolKeys, globalConfig } = poolInfo;
1180
1340
  const poolV2 = this.deriveAmmPoolV2(poolKeys.baseMint);
1181
1341
 
1182
1342
  const [eventAuthority] = PublicKey.findProgramAddressSync(
1183
1343
  [Buffer.from("__event_authority")],
1184
- PROGRAM_IDS.PUMP_AMM
1344
+ PROGRAM_IDS.PUMP_AMM,
1185
1345
  );
1186
1346
 
1187
1347
  const [coinCreatorVaultAuthority] = PublicKey.findProgramAddressSync(
1188
1348
  [Buffer.from("creator_vault"), poolKeys.coinCreator.toBuffer()],
1189
- PROGRAM_IDS.PUMP_AMM
1349
+ PROGRAM_IDS.PUMP_AMM,
1190
1350
  );
1191
1351
 
1192
1352
  const coinCreatorVaultAta = getAssociatedTokenAddressSync(
@@ -1194,22 +1354,25 @@ export class PumpTrader {
1194
1354
  coinCreatorVaultAuthority,
1195
1355
  true,
1196
1356
  TOKEN_PROGRAM_ID,
1197
- ASSOCIATED_TOKEN_PROGRAM_ID
1357
+ ASSOCIATED_TOKEN_PROGRAM_ID,
1198
1358
  );
1199
1359
 
1200
1360
  const [globalVolumeAccumulator] = PublicKey.findProgramAddressSync(
1201
1361
  [Buffer.from("global_volume_accumulator")],
1202
- PROGRAM_IDS.PUMP_AMM
1362
+ PROGRAM_IDS.PUMP_AMM,
1203
1363
  );
1204
1364
 
1205
1365
  const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
1206
- [Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
1207
- PROGRAM_IDS.PUMP_AMM
1366
+ [
1367
+ Buffer.from("user_volume_accumulator"),
1368
+ this.wallet.publicKey.toBuffer(),
1369
+ ],
1370
+ PROGRAM_IDS.PUMP_AMM,
1208
1371
  );
1209
1372
 
1210
1373
  const [feeConfig] = PublicKey.findProgramAddressSync(
1211
1374
  [Buffer.from("fee_config"), SEEDS.AMM_FEE_CONFIG],
1212
- PROGRAM_IDS.FEE
1375
+ PROGRAM_IDS.FEE,
1213
1376
  );
1214
1377
 
1215
1378
  const protocolFeeRecipient = globalConfig.protocolFeeRecipients[0];
@@ -1218,7 +1381,7 @@ export class PumpTrader {
1218
1381
  protocolFeeRecipient,
1219
1382
  true,
1220
1383
  TOKEN_PROGRAM_ID,
1221
- ASSOCIATED_TOKEN_PROGRAM_ID
1384
+ ASSOCIATED_TOKEN_PROGRAM_ID,
1222
1385
  );
1223
1386
  const newFeeRecipient = this.pickFeeRecipient();
1224
1387
  const newFeeRecipientTokenAccount = getAssociatedTokenAddressSync(
@@ -1226,7 +1389,7 @@ export class PumpTrader {
1226
1389
  newFeeRecipient,
1227
1390
  true,
1228
1391
  TOKEN_PROGRAM_ID,
1229
- ASSOCIATED_TOKEN_PROGRAM_ID
1392
+ ASSOCIATED_TOKEN_PROGRAM_ID,
1230
1393
  );
1231
1394
 
1232
1395
  const remainingKeys = [];
@@ -1236,14 +1399,22 @@ export class PumpTrader {
1236
1399
  userVolumeAccumulator,
1237
1400
  true,
1238
1401
  TOKEN_PROGRAM_ID,
1239
- ASSOCIATED_TOKEN_PROGRAM_ID
1402
+ ASSOCIATED_TOKEN_PROGRAM_ID,
1240
1403
  );
1241
- remainingKeys.push({ pubkey: userVolumeAccumulatorWsolAta, isSigner: false, isWritable: true });
1404
+ remainingKeys.push({
1405
+ pubkey: userVolumeAccumulatorWsolAta,
1406
+ isSigner: false,
1407
+ isWritable: true,
1408
+ });
1242
1409
  }
1243
1410
  remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1244
1411
  remainingKeys.push(
1245
1412
  { pubkey: newFeeRecipient, isSigner: false, isWritable: false },
1246
- { pubkey: newFeeRecipientTokenAccount, isSigner: false, isWritable: true }
1413
+ {
1414
+ pubkey: newFeeRecipientTokenAccount,
1415
+ isSigner: false,
1416
+ isWritable: true,
1417
+ },
1247
1418
  );
1248
1419
 
1249
1420
  return new TransactionInstruction({
@@ -1256,45 +1427,72 @@ export class PumpTrader {
1256
1427
  { pubkey: poolKeys.quoteMint, isSigner: false, isWritable: false },
1257
1428
  { pubkey: userBaseAta, isSigner: false, isWritable: true },
1258
1429
  { pubkey: userQuoteAta, isSigner: false, isWritable: true },
1259
- { pubkey: poolKeys.poolBaseTokenAccount, isSigner: false, isWritable: true },
1260
- { pubkey: poolKeys.poolQuoteTokenAccount, isSigner: false, isWritable: true },
1430
+ {
1431
+ pubkey: poolKeys.poolBaseTokenAccount,
1432
+ isSigner: false,
1433
+ isWritable: true,
1434
+ },
1435
+ {
1436
+ pubkey: poolKeys.poolQuoteTokenAccount,
1437
+ isSigner: false,
1438
+ isWritable: true,
1439
+ },
1261
1440
  { pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
1262
- { pubkey: protocolFeeRecipientTokenAccount, isSigner: false, isWritable: true },
1441
+ {
1442
+ pubkey: protocolFeeRecipientTokenAccount,
1443
+ isSigner: false,
1444
+ isWritable: true,
1445
+ },
1263
1446
  { pubkey: tokenProgramId, isSigner: false, isWritable: false },
1264
1447
  { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
1265
1448
  { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
1266
- { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
1449
+ {
1450
+ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,
1451
+ isSigner: false,
1452
+ isWritable: false,
1453
+ },
1267
1454
  { pubkey: eventAuthority, isSigner: false, isWritable: false },
1268
1455
  { pubkey: PROGRAM_IDS.PUMP_AMM, isSigner: false, isWritable: false },
1269
1456
  { pubkey: coinCreatorVaultAta, isSigner: false, isWritable: true },
1270
- { pubkey: coinCreatorVaultAuthority, isSigner: false, isWritable: false },
1457
+ {
1458
+ pubkey: coinCreatorVaultAuthority,
1459
+ isSigner: false,
1460
+ isWritable: false,
1461
+ },
1271
1462
  { pubkey: globalVolumeAccumulator, isSigner: false, isWritable: false },
1272
1463
  { pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
1273
1464
  { pubkey: feeConfig, isSigner: false, isWritable: false },
1274
1465
  { pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
1275
- ...remainingKeys
1466
+ ...remainingKeys,
1276
1467
  ],
1277
1468
  data: Buffer.concat([
1278
1469
  DISCRIMINATORS.BUY,
1279
1470
  u64(baseAmountOut),
1280
1471
  u64(maxQuoteAmountIn),
1281
- Buffer.from([1, 1])
1282
- ])
1472
+ Buffer.from([1, 1]),
1473
+ ]),
1283
1474
  });
1284
1475
  }
1285
1476
 
1286
- createAmmSellInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountIn, minQuoteAmountOut, tokenProgramId) {
1477
+ createAmmSellInstruction(
1478
+ poolInfo,
1479
+ userBaseAta,
1480
+ userQuoteAta,
1481
+ baseAmountIn,
1482
+ minQuoteAmountOut,
1483
+ tokenProgramId,
1484
+ ) {
1287
1485
  const { pool, poolKeys, globalConfig } = poolInfo;
1288
1486
  const poolV2 = this.deriveAmmPoolV2(poolKeys.baseMint);
1289
1487
 
1290
1488
  const [eventAuthority] = PublicKey.findProgramAddressSync(
1291
1489
  [Buffer.from("__event_authority")],
1292
- PROGRAM_IDS.PUMP_AMM
1490
+ PROGRAM_IDS.PUMP_AMM,
1293
1491
  );
1294
1492
 
1295
1493
  const [coinCreatorVaultAuthority] = PublicKey.findProgramAddressSync(
1296
1494
  [Buffer.from("creator_vault"), poolKeys.coinCreator.toBuffer()],
1297
- PROGRAM_IDS.PUMP_AMM
1495
+ PROGRAM_IDS.PUMP_AMM,
1298
1496
  );
1299
1497
 
1300
1498
  const coinCreatorVaultAta = getAssociatedTokenAddressSync(
@@ -1302,12 +1500,12 @@ export class PumpTrader {
1302
1500
  coinCreatorVaultAuthority,
1303
1501
  true,
1304
1502
  TOKEN_PROGRAM_ID,
1305
- ASSOCIATED_TOKEN_PROGRAM_ID
1503
+ ASSOCIATED_TOKEN_PROGRAM_ID,
1306
1504
  );
1307
1505
 
1308
1506
  const [feeConfig] = PublicKey.findProgramAddressSync(
1309
1507
  [Buffer.from("fee_config"), SEEDS.AMM_FEE_CONFIG],
1310
- PROGRAM_IDS.FEE
1508
+ PROGRAM_IDS.FEE,
1311
1509
  );
1312
1510
 
1313
1511
  const protocolFeeRecipient = globalConfig.protocolFeeRecipients[0];
@@ -1316,7 +1514,7 @@ export class PumpTrader {
1316
1514
  protocolFeeRecipient,
1317
1515
  true,
1318
1516
  TOKEN_PROGRAM_ID,
1319
- ASSOCIATED_TOKEN_PROGRAM_ID
1517
+ ASSOCIATED_TOKEN_PROGRAM_ID,
1320
1518
  );
1321
1519
  const newFeeRecipient = this.pickFeeRecipient();
1322
1520
  const newFeeRecipientTokenAccount = getAssociatedTokenAddressSync(
@@ -1324,12 +1522,15 @@ export class PumpTrader {
1324
1522
  newFeeRecipient,
1325
1523
  true,
1326
1524
  TOKEN_PROGRAM_ID,
1327
- ASSOCIATED_TOKEN_PROGRAM_ID
1525
+ ASSOCIATED_TOKEN_PROGRAM_ID,
1328
1526
  );
1329
1527
 
1330
1528
  const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
1331
- [Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
1332
- PROGRAM_IDS.PUMP_AMM
1529
+ [
1530
+ Buffer.from("user_volume_accumulator"),
1531
+ this.wallet.publicKey.toBuffer(),
1532
+ ],
1533
+ PROGRAM_IDS.PUMP_AMM,
1333
1534
  );
1334
1535
 
1335
1536
  const userVolumeAccumulatorWsolAta = getAssociatedTokenAddressSync(
@@ -1337,20 +1538,28 @@ export class PumpTrader {
1337
1538
  userVolumeAccumulator,
1338
1539
  true,
1339
1540
  TOKEN_PROGRAM_ID,
1340
- ASSOCIATED_TOKEN_PROGRAM_ID
1541
+ ASSOCIATED_TOKEN_PROGRAM_ID,
1341
1542
  );
1342
1543
 
1343
1544
  const remainingKeys = [];
1344
1545
  if (poolKeys.isCashbackCoin) {
1345
1546
  remainingKeys.push(
1346
- { pubkey: userVolumeAccumulatorWsolAta, isSigner: false, isWritable: true },
1347
- { pubkey: userVolumeAccumulator, isSigner: false, isWritable: true }
1547
+ {
1548
+ pubkey: userVolumeAccumulatorWsolAta,
1549
+ isSigner: false,
1550
+ isWritable: true,
1551
+ },
1552
+ { pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
1348
1553
  );
1349
1554
  }
1350
1555
  remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1351
1556
  remainingKeys.push(
1352
1557
  { pubkey: newFeeRecipient, isSigner: false, isWritable: false },
1353
- { pubkey: newFeeRecipientTokenAccount, isSigner: false, isWritable: true }
1558
+ {
1559
+ pubkey: newFeeRecipientTokenAccount,
1560
+ isSigner: false,
1561
+ isWritable: true,
1562
+ },
1354
1563
  );
1355
1564
 
1356
1565
  return new TransactionInstruction({
@@ -1363,65 +1572,93 @@ export class PumpTrader {
1363
1572
  { pubkey: poolKeys.quoteMint, isSigner: false, isWritable: false },
1364
1573
  { pubkey: userBaseAta, isSigner: false, isWritable: true },
1365
1574
  { pubkey: userQuoteAta, isSigner: false, isWritable: true },
1366
- { pubkey: poolKeys.poolBaseTokenAccount, isSigner: false, isWritable: true },
1367
- { pubkey: poolKeys.poolQuoteTokenAccount, isSigner: false, isWritable: true },
1575
+ {
1576
+ pubkey: poolKeys.poolBaseTokenAccount,
1577
+ isSigner: false,
1578
+ isWritable: true,
1579
+ },
1580
+ {
1581
+ pubkey: poolKeys.poolQuoteTokenAccount,
1582
+ isSigner: false,
1583
+ isWritable: true,
1584
+ },
1368
1585
  { pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
1369
- { pubkey: protocolFeeRecipientTokenAccount, isSigner: false, isWritable: true },
1586
+ {
1587
+ pubkey: protocolFeeRecipientTokenAccount,
1588
+ isSigner: false,
1589
+ isWritable: true,
1590
+ },
1370
1591
  { pubkey: tokenProgramId, isSigner: false, isWritable: false },
1371
1592
  { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
1372
1593
  { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
1373
- { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
1594
+ {
1595
+ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,
1596
+ isSigner: false,
1597
+ isWritable: false,
1598
+ },
1374
1599
  { pubkey: eventAuthority, isSigner: false, isWritable: false },
1375
1600
  { pubkey: PROGRAM_IDS.PUMP_AMM, isSigner: false, isWritable: false },
1376
1601
  { pubkey: coinCreatorVaultAta, isSigner: false, isWritable: true },
1377
- { pubkey: coinCreatorVaultAuthority, isSigner: false, isWritable: false },
1602
+ {
1603
+ pubkey: coinCreatorVaultAuthority,
1604
+ isSigner: false,
1605
+ isWritable: false,
1606
+ },
1378
1607
  { pubkey: feeConfig, isSigner: false, isWritable: false },
1379
1608
  { pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
1380
- ...remainingKeys
1609
+ ...remainingKeys,
1381
1610
  ],
1382
1611
  data: Buffer.concat([
1383
1612
  DISCRIMINATORS.SELL,
1384
1613
  u64(baseAmountIn),
1385
- u64(minQuoteAmountOut > 0n ? minQuoteAmountOut : 1n)
1386
- ])
1614
+ u64(minQuoteAmountOut > 0n ? minQuoteAmountOut : 1n),
1615
+ ]),
1387
1616
  });
1388
1617
  }
1389
1618
 
1390
1619
  /* ---------- 交易确认 ---------- */
1391
1620
 
1392
- async confirmTransactionWithPolling(signature, lastValidBlockHeight, maxAttempts = 5, delayMs = 2000) {
1393
- console.log('✅ 交易已发送:', signature);
1394
- console.log('🔗 查看交易: https://solscan.io/tx/' + signature);
1621
+ async confirmTransactionWithPolling(
1622
+ signature,
1623
+ lastValidBlockHeight,
1624
+ maxAttempts = 5,
1625
+ delayMs = 2000,
1626
+ ) {
1627
+ console.log("✅ 交易已发送:", signature);
1628
+ console.log("🔗 查看交易: https://solscan.io/tx/" + signature);
1395
1629
 
1396
1630
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
1397
- await new Promise(resolve => setTimeout(resolve, delayMs));
1631
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
1398
1632
 
1399
1633
  try {
1400
1634
  console.log(`🔍 检查交易状态 (${attempt}/${maxAttempts})...`);
1401
1635
 
1402
1636
  const txInfo = await this.connection.getTransaction(signature, {
1403
- commitment: 'confirmed',
1404
- maxSupportedTransactionVersion: 0
1637
+ commitment: "confirmed",
1638
+ maxSupportedTransactionVersion: 0,
1405
1639
  });
1406
1640
 
1407
1641
  if (txInfo) {
1408
1642
  if (txInfo.meta?.err) {
1409
- console.error('❌ 交易失败:', txInfo.meta.err);
1410
- throw new Error('交易失败: ' + JSON.stringify(txInfo.meta.err));
1643
+ console.error("❌ 交易失败:", txInfo.meta.err);
1644
+ throw new Error("交易失败: " + JSON.stringify(txInfo.meta.err));
1411
1645
  }
1412
1646
 
1413
- console.log('✅ 交易已确认!');
1647
+ console.log("✅ 交易已确认!");
1414
1648
  return signature;
1415
1649
  }
1416
1650
 
1417
- const currentBlockHeight = await this.connection.getBlockHeight('finalized');
1651
+ const currentBlockHeight =
1652
+ await this.connection.getBlockHeight("finalized");
1418
1653
  if (currentBlockHeight > lastValidBlockHeight) {
1419
- console.log('⚠️ 交易已过期(超过有效区块高度)');
1420
- throw new Error('交易过期:未在有效区块高度内确认');
1654
+ console.log("⚠️ 交易已过期(超过有效区块高度)");
1655
+ throw new Error("交易过期:未在有效区块高度内确认");
1421
1656
  }
1422
-
1423
1657
  } catch (error) {
1424
- if (error.message?.includes('交易失败') || error.message?.includes('交易过期')) {
1658
+ if (
1659
+ error.message?.includes("交易失败") ||
1660
+ error.message?.includes("交易过期")
1661
+ ) {
1425
1662
  throw error;
1426
1663
  }
1427
1664
  console.log(`⚠️ 查询出错,继续重试: ${error.message}`);
@@ -1429,7 +1666,7 @@ export class PumpTrader {
1429
1666
  }
1430
1667
 
1431
1668
  throw new Error(
1432
- `交易确认超时(已尝试 ${maxAttempts} 次),签名: ${signature}。请手动检查交易状态。`
1669
+ `交易确认超时(已尝试 ${maxAttempts} 次),签名: ${signature}。请手动检查交易状态。`,
1433
1670
  );
1434
1671
  }
1435
1672
 
@@ -1442,7 +1679,10 @@ export class PumpTrader {
1442
1679
  for (const logLine of log.logs) {
1443
1680
  if (!logLine.startsWith("Program data: ")) continue;
1444
1681
 
1445
- const buf = Buffer.from(logLine.replace("Program data: ", ""), "base64");
1682
+ const buf = Buffer.from(
1683
+ logLine.replace("Program data: ", ""),
1684
+ "base64",
1685
+ );
1446
1686
 
1447
1687
  if (!buf.subarray(0, 8).equals(DISCRIMINATORS.TRADE_EVENT)) continue;
1448
1688
 
@@ -1468,11 +1708,11 @@ export class PumpTrader {
1468
1708
  isBuy,
1469
1709
  user: user.toBase58(),
1470
1710
  timestamp,
1471
- signature: log.signature
1711
+ signature: log.signature,
1472
1712
  });
1473
1713
  }
1474
1714
  },
1475
- "confirmed"
1715
+ "confirmed",
1476
1716
  );
1477
1717
  }
1478
1718
 
@@ -1485,18 +1725,22 @@ export class PumpTrader {
1485
1725
  const metadata = await getTokenMetadata(
1486
1726
  this.connection,
1487
1727
  mint,
1488
- TOKEN_2022_PROGRAM_ID
1728
+ TOKEN_2022_PROGRAM_ID,
1489
1729
  );
1490
1730
 
1491
1731
  return {
1492
1732
  name: metadata?.name || "",
1493
1733
  symbol: metadata?.symbol || "",
1494
- uri: metadata?.uri || ""
1734
+ uri: metadata?.uri || "",
1495
1735
  };
1496
1736
  } catch (e) {
1497
1737
  const metadataPda = PublicKey.findProgramAddressSync(
1498
- [Buffer.from("metadata"), PROGRAM_IDS.METADATA.toBuffer(), mint.toBuffer()],
1499
- PROGRAM_IDS.METADATA
1738
+ [
1739
+ Buffer.from("metadata"),
1740
+ PROGRAM_IDS.METADATA.toBuffer(),
1741
+ mint.toBuffer(),
1742
+ ],
1743
+ PROGRAM_IDS.METADATA,
1500
1744
  )[0];
1501
1745
 
1502
1746
  const acc = await this.connection.getAccountInfo(metadataPda);
@@ -1505,9 +1749,9 @@ export class PumpTrader {
1505
1749
  const meta = parseMetadataAccount(acc.data);
1506
1750
 
1507
1751
  return {
1508
- name: meta?.name?.replace(/\u0000/g, '') || "",
1509
- symbol: meta?.symbol?.replace(/\u0000/g, '') || "",
1510
- uri: meta?.uri?.replace(/\u0000/g, '') || ""
1752
+ name: meta?.name?.replace(/\u0000/g, "") || "",
1753
+ symbol: meta?.symbol?.replace(/\u0000/g, "") || "",
1754
+ uri: meta?.uri?.replace(/\u0000/g, "") || "",
1511
1755
  };
1512
1756
  }
1513
1757
  }