pump-trader 1.1.3 → 1.1.5

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/index.js CHANGED
@@ -56,6 +56,16 @@ const DISCRIMINATORS = {
56
56
 
57
57
  const AMM_FEE_BPS = 100n; // 1%
58
58
  const BPS_DENOMINATOR = 10000n;
59
+ const PUMP_NEW_FEE_RECIPIENTS = [
60
+ "5YxQFdt3Tr9zJLvkFccqXVUwhdTWJQc1fFg2YPbxvxeD",
61
+ "9M4giFFMxmFGXtc3feFzRai56WbBqehoSeRE5GK7gf7",
62
+ "GXPFM2caqTtQYC2cJ5yJRi9VDkpsYZXzYdwYpGnLmtDL",
63
+ "3BpXnfJaUTiwXnJNe7Ej1rcbzqTTQUvLShZaWazebsVR",
64
+ "5cjcW9wExnJJiqgLjq7DEG75Pm6JBgE1hNv4B2vHXUW6",
65
+ "EHAAiTxcdDwQ3U4bU6YcMsQGaekdzLS3B5SmYo46kJtL",
66
+ "5eHhjP8JaYkz83CWwvGU2uMUXefd3AazWGx4gpcuEEYD",
67
+ "A7hAgCzFw14fejgCp387JUJRMNyz4j89JKnhtKU8piqW"
68
+ ].map((value) => new PublicKey(value));
59
69
 
60
70
  /* ================= 工具函数 ================= */
61
71
 
@@ -294,6 +304,66 @@ export class PumpTrader {
294
304
  )[0];
295
305
  }
296
306
 
307
+ pickFeeRecipient(index = 0) {
308
+ return PUMP_NEW_FEE_RECIPIENTS[index % PUMP_NEW_FEE_RECIPIENTS.length];
309
+ }
310
+
311
+ buildBondingBuyKeys(args) {
312
+ const tokenProgramId = args.tokenProgramId ?? TOKEN_PROGRAM_ID;
313
+
314
+ return [
315
+ { pubkey: args.global, isSigner: false, isWritable: false },
316
+ { pubkey: args.globalFeeRecipient, isSigner: false, isWritable: true },
317
+ { pubkey: args.mint, isSigner: false, isWritable: false },
318
+ { pubkey: args.bonding, isSigner: false, isWritable: true },
319
+ { pubkey: args.associatedBondingCurve, isSigner: false, isWritable: true },
320
+ { pubkey: args.userAta, isSigner: false, isWritable: true },
321
+ { pubkey: args.wallet, isSigner: true, isWritable: true },
322
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
323
+ { pubkey: tokenProgramId, isSigner: false, isWritable: false },
324
+ { pubkey: args.creatorVault, isSigner: false, isWritable: true },
325
+ { pubkey: args.eventAuthority, isSigner: false, isWritable: false },
326
+ { pubkey: args.pumpProgram, isSigner: false, isWritable: false },
327
+ { pubkey: args.globalVolumeAccumulator, isSigner: false, isWritable: false },
328
+ { pubkey: args.userVolumeAccumulator, isSigner: false, isWritable: true },
329
+ { pubkey: args.feeConfig, isSigner: false, isWritable: false },
330
+ { pubkey: args.feeProgram, isSigner: false, isWritable: false },
331
+ { pubkey: args.bondingCurveV2, isSigner: false, isWritable: false },
332
+ { pubkey: args.feeRecipient, isSigner: false, isWritable: true }
333
+ ];
334
+ }
335
+
336
+ buildBondingSellKeys(args) {
337
+ const tokenProgramId = args.tokenProgramId ?? TOKEN_PROGRAM_ID;
338
+ const keys = [
339
+ { pubkey: args.global, isSigner: false, isWritable: false },
340
+ { pubkey: args.globalFeeRecipient, isSigner: false, isWritable: true },
341
+ { pubkey: args.mint, isSigner: false, isWritable: false },
342
+ { pubkey: args.bonding, isSigner: false, isWritable: true },
343
+ { pubkey: args.associatedBondingCurve, isSigner: false, isWritable: true },
344
+ { pubkey: args.userAta, isSigner: false, isWritable: true },
345
+ { pubkey: args.wallet, isSigner: true, isWritable: true },
346
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
347
+ { pubkey: args.creatorVault, isSigner: false, isWritable: true },
348
+ { pubkey: tokenProgramId, isSigner: false, isWritable: false },
349
+ { pubkey: args.eventAuthority, isSigner: false, isWritable: false },
350
+ { pubkey: args.pumpProgram, isSigner: false, isWritable: false },
351
+ { pubkey: args.feeConfig, isSigner: false, isWritable: false },
352
+ { pubkey: args.feeProgram, isSigner: false, isWritable: false }
353
+ ];
354
+
355
+ if (args.isCashbackCoin) {
356
+ keys.push({ pubkey: args.userVolumeAccumulator, isSigner: false, isWritable: true });
357
+ }
358
+
359
+ keys.push(
360
+ { pubkey: args.bondingCurveV2, isSigner: false, isWritable: false },
361
+ { pubkey: args.feeRecipient, isSigner: false, isWritable: true }
362
+ );
363
+
364
+ return keys;
365
+ }
366
+
297
367
  async loadBonding(mint) {
298
368
  const bonding = this.getBondingPda(mint);
299
369
  const acc = await this.connection.getAccountInfo(bonding);
@@ -313,6 +383,12 @@ export class PumpTrader {
313
383
 
314
384
  const creator = new PublicKey(data.slice(offset, offset + 32));
315
385
  offset += 32;
386
+
387
+ if (offset + 32 <= data.length - 2) {
388
+ state.quoteMint = new PublicKey(data.slice(offset, offset + 32));
389
+ offset += 32;
390
+ }
391
+
316
392
  state.isMayhemMode = offset < data.length ? data[offset] === 1 : false;
317
393
  offset += 1;
318
394
  state.isCashbackCoin = offset < data.length ? data[offset] === 1 : false;
@@ -353,19 +429,21 @@ export class PumpTrader {
353
429
  async getPriceAndStatus(tokenAddr) {
354
430
  const mint = new PublicKey(tokenAddr);
355
431
  const { state } = await this.loadBonding(mint);
432
+ const quoteMint = this.getEffectiveQuoteMint(state.quoteMint);
356
433
 
357
434
  if (state.complete) {
358
- const price = await this.getAmmPrice(mint);
435
+ const price = await this.getAmmPrice(mint, quoteMint);
359
436
  return { price, completed: true };
360
437
  }
361
438
 
362
439
  const oneToken = BigInt(1_000_000);
363
- const solOut = this.calcSell(oneToken, state);
364
- const price = Number(solOut) / 1e9;
440
+ const quoteOut = this.calcSell(oneToken, state);
441
+ const quoteDecimals = await this.getMintDecimals(quoteMint);
442
+ const price = Number(quoteOut) / 10 ** quoteDecimals;
365
443
  return { price, completed: false };
366
444
  }
367
445
 
368
- async getAmmPrice(mint) {
446
+ async getAmmPrice(mint, quoteMint = SOL_MINT) {
369
447
  const [poolCreator] = PublicKey.findProgramAddressSync(
370
448
  [Buffer.from("pool-authority"), mint.toBuffer()],
371
449
  PROGRAM_IDS.PUMP
@@ -373,7 +451,7 @@ export class PumpTrader {
373
451
 
374
452
  const indexBuffer = new BN(0).toArrayLike(Buffer, "le", 2);
375
453
  const [pool] = PublicKey.findProgramAddressSync(
376
- [Buffer.from("pool"), indexBuffer, poolCreator.toBuffer(), mint.toBuffer(), SOL_MINT.toBuffer()],
454
+ [Buffer.from("pool"), indexBuffer, poolCreator.toBuffer(), mint.toBuffer(), quoteMint.toBuffer()],
377
455
  PROGRAM_IDS.PUMP_AMM
378
456
  );
379
457
 
@@ -389,6 +467,28 @@ export class PumpTrader {
389
467
  return quoteInfo.value.uiAmount / baseInfo.value.uiAmount;
390
468
  }
391
469
 
470
+ getEffectiveQuoteMint(quoteMint) {
471
+ if (!quoteMint || quoteMint.equals(PublicKey.default)) {
472
+ return SOL_MINT;
473
+ }
474
+ return quoteMint;
475
+ }
476
+
477
+ async getMintDecimals(mint) {
478
+ if (mint.equals(SOL_MINT)) {
479
+ return 9;
480
+ }
481
+
482
+ const mintInfo = await this.connection.getParsedAccountInfo(mint);
483
+ const parsedData = mintInfo.value?.data;
484
+
485
+ if (parsedData && "parsed" in parsedData) {
486
+ return parsedData.parsed.info.decimals;
487
+ }
488
+
489
+ throw new Error(`Unable to determine mint decimals for ${mint.toBase58()}`);
490
+ }
491
+
392
492
  /* ---------- 余额查询 ---------- */
393
493
 
394
494
  /**
@@ -667,17 +767,7 @@ export class PumpTrader {
667
767
  [Buffer.from("fee_config"), SEEDS.FEE_CONFIG],
668
768
  PROGRAM_IDS.FEE
669
769
  );
670
-
671
- const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
672
- [Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
673
- PROGRAM_IDS.PUMP
674
- );
675
-
676
- const sellRemainingKeys = [];
677
- if (state.isCashbackCoin) {
678
- sellRemainingKeys.push({ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true });
679
- }
680
- sellRemainingKeys.push({ pubkey: bondingCurveV2, isSigner: false, isWritable: false });
770
+ const feeRecipient = this.pickFeeRecipient();
681
771
 
682
772
  for (let i = 0; i < solChunks.length; i++) {
683
773
  try {
@@ -701,25 +791,25 @@ export class PumpTrader {
701
791
  tx.add(
702
792
  new TransactionInstruction({
703
793
  programId: PROGRAM_IDS.PUMP,
704
- keys: [
705
- { pubkey: this.global, isSigner: false, isWritable: false },
706
- { pubkey: this.globalState.feeRecipient, isSigner: false, isWritable: true },
707
- { pubkey: mint, isSigner: false, isWritable: false },
708
- { pubkey: bonding, isSigner: false, isWritable: true },
709
- { pubkey: associatedBondingCurve, isSigner: false, isWritable: true },
710
- { pubkey: userAta, isSigner: false, isWritable: true },
711
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: true },
712
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
713
- { pubkey: tokenProgram.programId, isSigner: false, isWritable: false },
714
- { pubkey: creatorVault, isSigner: false, isWritable: true },
715
- { pubkey: PROGRAM_IDS.EVENT_AUTHORITY, isSigner: false, isWritable: false },
716
- { pubkey: PROGRAM_IDS.PUMP, isSigner: false, isWritable: false },
717
- { pubkey: globalVolumeAccumulator, isSigner: false, isWritable: false },
718
- { pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
719
- { pubkey: feeConfig, isSigner: false, isWritable: false },
720
- { pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
721
- { pubkey: bondingCurveV2, isSigner: false, isWritable: false }
722
- ],
794
+ keys: this.buildBondingBuyKeys({
795
+ global: this.global,
796
+ globalFeeRecipient: this.globalState.feeRecipient,
797
+ mint,
798
+ bonding,
799
+ associatedBondingCurve,
800
+ userAta,
801
+ wallet: this.wallet.publicKey,
802
+ creatorVault,
803
+ eventAuthority: PROGRAM_IDS.EVENT_AUTHORITY,
804
+ pumpProgram: PROGRAM_IDS.PUMP,
805
+ globalVolumeAccumulator,
806
+ userVolumeAccumulator,
807
+ feeConfig,
808
+ feeProgram: PROGRAM_IDS.FEE,
809
+ bondingCurveV2,
810
+ feeRecipient,
811
+ tokenProgramId: tokenProgram.programId
812
+ }),
723
813
  data: Buffer.concat([DISCRIMINATORS.BUY, u64(tokenOut), u64(maxSol)])
724
814
  })
725
815
  );
@@ -797,6 +887,11 @@ export class PumpTrader {
797
887
  [Buffer.from("fee_config"), SEEDS.FEE_CONFIG],
798
888
  PROGRAM_IDS.FEE
799
889
  );
890
+ const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
891
+ [Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
892
+ PROGRAM_IDS.PUMP
893
+ );
894
+ const feeRecipient = this.pickFeeRecipient();
800
895
 
801
896
  for (let i = 0; i < tokenChunks.length; i++) {
802
897
  try {
@@ -818,23 +913,25 @@ export class PumpTrader {
818
913
  tx.add(
819
914
  new TransactionInstruction({
820
915
  programId: PROGRAM_IDS.PUMP,
821
- keys: [
822
- { pubkey: this.global, isSigner: false, isWritable: false },
823
- { pubkey: this.globalState.feeRecipient, isSigner: false, isWritable: true },
824
- { pubkey: mint, isSigner: false, isWritable: false },
825
- { pubkey: bonding, isSigner: false, isWritable: true },
826
- { pubkey: associatedBondingCurve, isSigner: false, isWritable: true },
827
- { pubkey: userAta, isSigner: false, isWritable: true },
828
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: true },
829
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
830
- { pubkey: creatorVault, isSigner: false, isWritable: true },
831
- { pubkey: tokenProgram.programId, isSigner: false, isWritable: false },
832
- { pubkey: PROGRAM_IDS.EVENT_AUTHORITY, isSigner: false, isWritable: false },
833
- { pubkey: PROGRAM_IDS.PUMP, isSigner: false, isWritable: false },
834
- { pubkey: feeConfig, isSigner: false, isWritable: false },
835
- { pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
836
- ...sellRemainingKeys
837
- ],
916
+ keys: this.buildBondingSellKeys({
917
+ global: this.global,
918
+ globalFeeRecipient: this.globalState.feeRecipient,
919
+ mint,
920
+ bonding,
921
+ associatedBondingCurve,
922
+ userAta,
923
+ wallet: this.wallet.publicKey,
924
+ creatorVault,
925
+ eventAuthority: PROGRAM_IDS.EVENT_AUTHORITY,
926
+ pumpProgram: PROGRAM_IDS.PUMP,
927
+ feeConfig,
928
+ feeProgram: PROGRAM_IDS.FEE,
929
+ bondingCurveV2,
930
+ feeRecipient,
931
+ isCashbackCoin: !!state.isCashbackCoin,
932
+ userVolumeAccumulator,
933
+ tokenProgramId: tokenProgram.programId
934
+ }),
838
935
  data: Buffer.concat([
839
936
  DISCRIMINATORS.SELL,
840
937
  u64(tokenIn),
@@ -1153,6 +1250,14 @@ export class PumpTrader {
1153
1250
  TOKEN_PROGRAM_ID,
1154
1251
  ASSOCIATED_TOKEN_PROGRAM_ID
1155
1252
  );
1253
+ const newFeeRecipient = this.pickFeeRecipient();
1254
+ const newFeeRecipientTokenAccount = getAssociatedTokenAddressSync(
1255
+ poolKeys.quoteMint,
1256
+ newFeeRecipient,
1257
+ true,
1258
+ TOKEN_PROGRAM_ID,
1259
+ ASSOCIATED_TOKEN_PROGRAM_ID
1260
+ );
1156
1261
 
1157
1262
  const remainingKeys = [];
1158
1263
  if (poolKeys.isCashbackCoin) {
@@ -1166,6 +1271,10 @@ export class PumpTrader {
1166
1271
  remainingKeys.push({ pubkey: userVolumeAccumulatorWsolAta, isSigner: false, isWritable: true });
1167
1272
  }
1168
1273
  remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1274
+ remainingKeys.push(
1275
+ { pubkey: newFeeRecipient, isSigner: false, isWritable: false },
1276
+ { pubkey: newFeeRecipientTokenAccount, isSigner: false, isWritable: true }
1277
+ );
1169
1278
 
1170
1279
  return new TransactionInstruction({
1171
1280
  programId: PROGRAM_IDS.PUMP_AMM,
@@ -1239,6 +1348,14 @@ export class PumpTrader {
1239
1348
  TOKEN_PROGRAM_ID,
1240
1349
  ASSOCIATED_TOKEN_PROGRAM_ID
1241
1350
  );
1351
+ const newFeeRecipient = this.pickFeeRecipient();
1352
+ const newFeeRecipientTokenAccount = getAssociatedTokenAddressSync(
1353
+ poolKeys.quoteMint,
1354
+ newFeeRecipient,
1355
+ true,
1356
+ TOKEN_PROGRAM_ID,
1357
+ ASSOCIATED_TOKEN_PROGRAM_ID
1358
+ );
1242
1359
 
1243
1360
  const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
1244
1361
  [Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
@@ -1261,6 +1378,10 @@ export class PumpTrader {
1261
1378
  );
1262
1379
  }
1263
1380
  remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1381
+ remainingKeys.push(
1382
+ { pubkey: newFeeRecipient, isSigner: false, isWritable: false },
1383
+ { pubkey: newFeeRecipientTokenAccount, isSigner: false, isWritable: true }
1384
+ );
1264
1385
 
1265
1386
  return new TransactionInstruction({
1266
1387
  programId: PROGRAM_IDS.PUMP_AMM,