pump-trader 1.1.9 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -126,11 +126,13 @@ export declare class PumpTrader {
126
126
  calcSell(tokenIn: bigint, state: BondingCurveState): bigint;
127
127
  calculateAmmBuyOutput(quoteIn: bigint, reserves: PoolReserves): bigint;
128
128
  calculateAmmSellOutput(baseIn: bigint, reserves: PoolReserves): bigint;
129
- getPriceAndStatus(tokenAddr: string): Promise<{
129
+ private solPriceCache;
130
+ getSolPriceInUsdc(): Promise<number>;
131
+ getPriceAndStatus(tokenAddr: string, quoteMint?: PublicKey): Promise<{
130
132
  price: number;
131
133
  completed: boolean;
132
134
  }>;
133
- getAmmPrice(mint: PublicKey): Promise<number>;
135
+ getAmmPrice(mint: PublicKey, quoteMint?: PublicKey): Promise<number>;
134
136
  /**
135
137
  * 查询代币余额
136
138
  * @param tokenAddr - 代币地址(可选),如果不传则返回所有代币
package/dist/index.js CHANGED
@@ -153,15 +153,11 @@ function parsePoolKeys(data) {
153
153
  /* ================= PumpTrader 类 ================= */
154
154
  class PumpTrader {
155
155
  constructor(rpc, wallet) {
156
+ /* ---------- 价格查询 ---------- */
157
+ this.solPriceCache = null;
156
158
  this.connection = new web3_js_1.Connection(rpc, "confirmed");
157
- if (wallet instanceof web3_js_1.Keypair) {
158
- this._wallet = wallet;
159
- this.publicKey = wallet.publicKey;
160
- }
161
- else {
162
- this._wallet = wallet;
163
- this.publicKey = wallet.publicKey;
164
- }
159
+ this._wallet = wallet;
160
+ this.publicKey = wallet.publicKey;
165
161
  this.global = web3_js_1.PublicKey.findProgramAddressSync([SEEDS.GLOBAL], PROGRAM_IDS.PUMP)[0];
166
162
  this.globalState = null;
167
163
  this.tokenProgramCache = new Map();
@@ -169,9 +165,12 @@ class PumpTrader {
169
165
  async signTx(tx) {
170
166
  if (this._wallet instanceof web3_js_1.Keypair) {
171
167
  tx.sign(this._wallet);
172
- return tx;
173
168
  }
174
- return this._wallet.signTransaction(tx);
169
+ else {
170
+ const signed = await this._wallet.signTransaction(tx);
171
+ // Copy signatures back to the original tx (adapter returns a new tx)
172
+ tx.signatures = signed.signatures;
173
+ }
175
174
  }
176
175
  /* ---------- Token Program 检测 ---------- */
177
176
  /**
@@ -422,20 +421,77 @@ class PumpTrader {
422
421
  const denominator = reserves.baseAmount + baseInAfterFee;
423
422
  return numerator / denominator;
424
423
  }
425
- /* ---------- 价格查询 ---------- */
426
- async getPriceAndStatus(tokenAddr) {
424
+ async getSolPriceInUsdc() {
425
+ if (this.solPriceCache && Date.now() - this.solPriceCache.timestamp < 60000) {
426
+ return this.solPriceCache.price;
427
+ }
428
+ try {
429
+ // Use Orca USDC/SOL whirlpool (7qbRF6YsyGuLUVs6Y1q64bdVrfe4ZcUUz1JRdoVNUJnm)
430
+ // Read token vault balances directly to compute price
431
+ const poolAddr = new web3_js_1.PublicKey("7qbRF6YsyGuLUVs6Y1q64bdVrfe4ZcUUz1JRdoVNUJnm");
432
+ const acc = await this.connection.getAccountInfo(poolAddr);
433
+ if (!acc || acc.data.length < 304)
434
+ throw new Error("Invalid pool data");
435
+ // Whirlpool: tokenMintA at offset 40, tokenMintB at offset 72, vaultA at 104, vaultB at 136
436
+ const tokenMintA = new web3_js_1.PublicKey(acc.data.slice(40, 72));
437
+ const tokenVaultA = new web3_js_1.PublicKey(acc.data.slice(104, 136));
438
+ const tokenVaultB = new web3_js_1.PublicKey(acc.data.slice(136, 168));
439
+ const [balanceA, balanceB] = await Promise.all([
440
+ this.connection.getTokenAccountBalance(tokenVaultA),
441
+ this.connection.getTokenAccountBalance(tokenVaultB),
442
+ ]);
443
+ // Determine which vault holds SOL by checking tokenMintA
444
+ const SOL_ADDR = "So11111111111111111111111111111111111111112";
445
+ const solBalance = tokenMintA.toBase58() === SOL_ADDR
446
+ ? Number(balanceA.value.amount)
447
+ : Number(balanceB.value.amount);
448
+ const usdcBalance = tokenMintA.toBase58() === SOL_ADDR
449
+ ? Number(balanceB.value.amount)
450
+ : Number(balanceA.value.amount);
451
+ if (solBalance === 0)
452
+ throw new Error("Zero balance");
453
+ const price = usdcBalance / solBalance;
454
+ this.solPriceCache = { price, timestamp: Date.now() };
455
+ return price;
456
+ }
457
+ catch {
458
+ return 175;
459
+ }
460
+ }
461
+ async getPriceAndStatus(tokenAddr, quoteMint) {
427
462
  const mint = new web3_js_1.PublicKey(tokenAddr);
428
463
  const { state } = await this.loadBonding(mint);
429
464
  if (state.complete) {
430
- const price = await this.getAmmPrice(mint);
465
+ const qm = quoteMint || (state.quoteMint && !state.quoteMint.equals(SOL_MINT) ? state.quoteMint : SOL_MINT);
466
+ const price = await this.getAmmPrice(mint, qm);
431
467
  return { price, completed: true };
432
468
  }
469
+ const qm = quoteMint || state.quoteMint || SOL_MINT;
470
+ const isSolQuote = qm.equals(SOL_MINT);
433
471
  const oneToken = BigInt(1_000_000);
434
- const solOut = this.calcSell(oneToken, state);
435
- const price = Number(solOut) / 1e9;
472
+ if (isSolQuote) {
473
+ const solOut = this.calcSell(oneToken, state);
474
+ const price = Number(solOut) / 1e9;
475
+ return { price, completed: false };
476
+ }
477
+ // USDC-paired bonding curve: pump stores USDC raw amount (6 decimals) in the
478
+ // virtualSolReserves field. calcSell returns USDC raw, divide by 1e6 for USDC price.
479
+ // Then convert to SOL using Orca USDC/SOL pool.
480
+ let quotePrice;
481
+ if (state.virtualQuoteReserves !== undefined) {
482
+ const newVirtualToken = state.virtualTokenReserves + oneToken;
483
+ const quoteOut = state.virtualQuoteReserves - (state.virtualQuoteReserves * state.virtualTokenReserves) / newVirtualToken;
484
+ quotePrice = Number(quoteOut) / 1e6;
485
+ }
486
+ else {
487
+ const rawOut = this.calcSell(oneToken, state);
488
+ quotePrice = Number(rawOut) / 1e6;
489
+ }
490
+ const solPrice = await this.getSolPriceInUsdc();
491
+ const price = quotePrice / solPrice;
436
492
  return { price, completed: false };
437
493
  }
438
- async getAmmPrice(mint) {
494
+ async getAmmPrice(mint, quoteMint = SOL_MINT) {
439
495
  const [poolCreator] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("pool-authority"), mint.toBuffer()], PROGRAM_IDS.PUMP);
440
496
  const indexBuffer = new bn_js_1.default(0).toArrayLike(Buffer, "le", 2);
441
497
  const [pool] = web3_js_1.PublicKey.findProgramAddressSync([
@@ -443,7 +499,7 @@ class PumpTrader {
443
499
  indexBuffer,
444
500
  poolCreator.toBuffer(),
445
501
  mint.toBuffer(),
446
- SOL_MINT.toBuffer(),
502
+ quoteMint.toBuffer(),
447
503
  ], PROGRAM_IDS.PUMP_AMM);
448
504
  const acc = await this.connection.getAccountInfo(pool);
449
505
  if (!acc)
@@ -453,7 +509,13 @@ class PumpTrader {
453
509
  this.connection.getTokenAccountBalance(poolKeys.poolBaseTokenAccount),
454
510
  this.connection.getTokenAccountBalance(poolKeys.poolQuoteTokenAccount),
455
511
  ]);
456
- return quoteInfo.value.uiAmount / baseInfo.value.uiAmount;
512
+ let price = quoteInfo.value.uiAmount / baseInfo.value.uiAmount;
513
+ // If pool is not SOL-quoted, convert to SOL price
514
+ if (!quoteMint.equals(SOL_MINT)) {
515
+ const solPrice = await this.getSolPriceInUsdc();
516
+ price = price / solPrice;
517
+ }
518
+ return price;
457
519
  }
458
520
  /* ---------- 余额查询 ---------- */
459
521
  /**
@@ -997,7 +1059,17 @@ class PumpTrader {
997
1059
  isWritable: true,
998
1060
  });
999
1061
  }
1000
- remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1062
+ const POOL_DEFAULT_COIN_CREATOR = new web3_js_1.PublicKey("11111111111111111111111111111111");
1063
+ if (poolKeys.coinCreator && !poolKeys.coinCreator.equals(POOL_DEFAULT_COIN_CREATOR)) {
1064
+ remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1065
+ }
1066
+ else {
1067
+ remainingKeys.push({
1068
+ pubkey: PUMP_BUYBACK_FEE_RECIPIENTS[0],
1069
+ isSigner: false,
1070
+ isWritable: true,
1071
+ });
1072
+ }
1001
1073
  remainingKeys.push({ pubkey: newFeeRecipient, isSigner: false, isWritable: false }, {
1002
1074
  pubkey: newFeeRecipientTokenAccount,
1003
1075
  isSigner: false,
@@ -1083,7 +1155,17 @@ class PumpTrader {
1083
1155
  isWritable: true,
1084
1156
  }, { pubkey: userVolumeAccumulator, isSigner: false, isWritable: true });
1085
1157
  }
1086
- remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1158
+ const POOL_DEFAULT_COIN_CREATOR = new web3_js_1.PublicKey("11111111111111111111111111111111");
1159
+ if (poolKeys.coinCreator && !poolKeys.coinCreator.equals(POOL_DEFAULT_COIN_CREATOR)) {
1160
+ remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1161
+ }
1162
+ else {
1163
+ remainingKeys.push({
1164
+ pubkey: PUMP_BUYBACK_FEE_RECIPIENTS[0],
1165
+ isSigner: false,
1166
+ isWritable: true,
1167
+ });
1168
+ }
1087
1169
  remainingKeys.push({ pubkey: newFeeRecipient, isSigner: false, isWritable: false }, {
1088
1170
  pubkey: newFeeRecipientTokenAccount,
1089
1171
  isSigner: false,
package/index.js CHANGED
@@ -193,9 +193,11 @@ export class PumpTrader {
193
193
  async signTx(tx) {
194
194
  if (this._wallet instanceof Keypair) {
195
195
  tx.sign(this._wallet);
196
- return tx;
196
+ } else {
197
+ const signed = await this._wallet.signTransaction(tx);
198
+ // Copy signatures back to the original tx (adapter returns a new tx)
199
+ tx.signatures = signed.signatures;
197
200
  }
198
- return this._wallet.signTransaction(tx);
199
201
  }
200
202
 
201
203
  /* ---------- Token Program 检测 ---------- */
@@ -490,22 +492,74 @@ export class PumpTrader {
490
492
 
491
493
  /* ---------- 价格查询 ---------- */
492
494
 
493
- async getPriceAndStatus(tokenAddr) {
495
+ async getSolPriceInUsdc() {
496
+ if (this._solPriceCache && Date.now() - this._solPriceCache.timestamp < 60000) {
497
+ return this._solPriceCache.price;
498
+ }
499
+ try {
500
+ const poolAddr = new PublicKey("7qbRF6YsyGuLUVs6Y1q64bdVrfe4ZcUUz1JRdoVNUJnm");
501
+ const acc = await this.connection.getAccountInfo(poolAddr);
502
+ if (!acc || acc.data.length < 304) throw new Error("Invalid pool data");
503
+ const tokenMintA = new PublicKey(acc.data.slice(40, 72));
504
+ const tokenVaultA = new PublicKey(acc.data.slice(104, 136));
505
+ const tokenVaultB = new PublicKey(acc.data.slice(136, 168));
506
+ const [balanceA, balanceB] = await Promise.all([
507
+ this.connection.getTokenAccountBalance(tokenVaultA),
508
+ this.connection.getTokenAccountBalance(tokenVaultB),
509
+ ]);
510
+ const SOL_ADDR = "So11111111111111111111111111111111111111112";
511
+ const solBalance = tokenMintA.toBase58() === SOL_ADDR
512
+ ? Number(balanceA.value.amount)
513
+ : Number(balanceB.value.amount);
514
+ const usdcBalance = tokenMintA.toBase58() === SOL_ADDR
515
+ ? Number(balanceB.value.amount)
516
+ : Number(balanceA.value.amount);
517
+ if (solBalance === 0) throw new Error("Zero balance");
518
+ const price = usdcBalance / solBalance;
519
+ this._solPriceCache = { price, timestamp: Date.now() };
520
+ return price;
521
+ } catch {
522
+ return 175;
523
+ }
524
+ }
525
+
526
+ async getPriceAndStatus(tokenAddr, quoteMint = null) {
494
527
  const mint = new PublicKey(tokenAddr);
495
528
  const { state } = await this.loadBonding(mint);
496
529
 
497
530
  if (state.complete) {
498
- const price = await this.getAmmPrice(mint);
531
+ const qm = quoteMint || (state.quoteMint && !state.quoteMint.equals(SOL_MINT) ? state.quoteMint : SOL_MINT);
532
+ const price = await this.getAmmPrice(mint, qm);
499
533
  return { price, completed: true };
500
534
  }
501
535
 
536
+ const qm = quoteMint || state.quoteMint || SOL_MINT;
537
+ const isSolQuote = qm.equals(SOL_MINT);
538
+
502
539
  const oneToken = BigInt(1_000_000);
503
- const solOut = this.calcSell(oneToken, state);
504
- const price = Number(solOut) / 1e9;
540
+
541
+ if (isSolQuote) {
542
+ const solOut = this.calcSell(oneToken, state);
543
+ const price = Number(solOut) / 1e9;
544
+ return { price, completed: false };
545
+ }
546
+
547
+ let quotePrice;
548
+ if (state.virtualQuoteReserves !== undefined) {
549
+ const newVirtualToken = state.virtualTokenReserves + oneToken;
550
+ const quoteOut = state.virtualQuoteReserves - (state.virtualQuoteReserves * state.virtualTokenReserves) / newVirtualToken;
551
+ quotePrice = Number(quoteOut) / 1e6;
552
+ } else {
553
+ const rawOut = this.calcSell(oneToken, state);
554
+ quotePrice = Number(rawOut) / 1e6;
555
+ }
556
+
557
+ const solPrice = await this.getSolPriceInUsdc();
558
+ const price = quotePrice / solPrice;
505
559
  return { price, completed: false };
506
560
  }
507
561
 
508
- async getAmmPrice(mint) {
562
+ async getAmmPrice(mint, quoteMint = SOL_MINT) {
509
563
  const [poolCreator] = PublicKey.findProgramAddressSync(
510
564
  [Buffer.from("pool-authority"), mint.toBuffer()],
511
565
  PROGRAM_IDS.PUMP,
@@ -518,7 +572,7 @@ export class PumpTrader {
518
572
  indexBuffer,
519
573
  poolCreator.toBuffer(),
520
574
  mint.toBuffer(),
521
- SOL_MINT.toBuffer(),
575
+ quoteMint.toBuffer(),
522
576
  ],
523
577
  PROGRAM_IDS.PUMP_AMM,
524
578
  );
@@ -532,7 +586,14 @@ export class PumpTrader {
532
586
  this.connection.getTokenAccountBalance(poolKeys.poolQuoteTokenAccount),
533
587
  ]);
534
588
 
535
- return quoteInfo.value.uiAmount / baseInfo.value.uiAmount;
589
+ let price = quoteInfo.value.uiAmount / baseInfo.value.uiAmount;
590
+
591
+ if (!quoteMint.equals(SOL_MINT)) {
592
+ const solPrice = await this.getSolPriceInUsdc();
593
+ price = price / solPrice;
594
+ }
595
+
596
+ return price;
536
597
  }
537
598
 
538
599
  /* ---------- 余额查询 ---------- */
@@ -1415,7 +1476,16 @@ export class PumpTrader {
1415
1476
  isWritable: true,
1416
1477
  });
1417
1478
  }
1418
- remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1479
+ const POOL_DEFAULT_COIN_CREATOR = new PublicKey("11111111111111111111111111111111");
1480
+ if (poolKeys.coinCreator && !poolKeys.coinCreator.equals(POOL_DEFAULT_COIN_CREATOR)) {
1481
+ remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1482
+ } else {
1483
+ remainingKeys.push({
1484
+ pubkey: PUMP_BUYBACK_FEE_RECIPIENTS[0],
1485
+ isSigner: false,
1486
+ isWritable: true,
1487
+ });
1488
+ }
1419
1489
  remainingKeys.push(
1420
1490
  { pubkey: newFeeRecipient, isSigner: false, isWritable: false },
1421
1491
  {
package/index.ts CHANGED
@@ -335,12 +335,14 @@ export class PumpTrader {
335
335
  this.tokenProgramCache = new Map();
336
336
  }
337
337
 
338
- private async signTx(tx: Transaction): Promise<Transaction> {
338
+ private async signTx(tx: Transaction): Promise<void> {
339
339
  if (this._wallet instanceof Keypair) {
340
340
  tx.sign(this._wallet);
341
- return tx;
341
+ } else {
342
+ const signed = await this._wallet.signTransaction(tx);
343
+ // Copy signatures back to the original tx (adapter returns a new tx)
344
+ tx.signatures = signed.signatures;
342
345
  }
343
- return this._wallet.signTransaction(tx);
344
346
  }
345
347
 
346
348
  /* ---------- Token Program 检测 ---------- */
@@ -698,24 +700,90 @@ export class PumpTrader {
698
700
 
699
701
  /* ---------- 价格查询 ---------- */
700
702
 
703
+ private solPriceCache: { price: number; timestamp: number } | null = null;
704
+
705
+ async getSolPriceInUsdc(): Promise<number> {
706
+ if (this.solPriceCache && Date.now() - this.solPriceCache.timestamp < 60000) {
707
+ return this.solPriceCache.price;
708
+ }
709
+ try {
710
+ // Use Orca USDC/SOL whirlpool (7qbRF6YsyGuLUVs6Y1q64bdVrfe4ZcUUz1JRdoVNUJnm)
711
+ // Read token vault balances directly to compute price
712
+ const poolAddr = new PublicKey("7qbRF6YsyGuLUVs6Y1q64bdVrfe4ZcUUz1JRdoVNUJnm");
713
+ const acc = await this.connection.getAccountInfo(poolAddr);
714
+ if (!acc || acc.data.length < 304) throw new Error("Invalid pool data");
715
+
716
+ // Whirlpool: tokenMintA at offset 40, tokenMintB at offset 72, vaultA at 104, vaultB at 136
717
+ const tokenMintA = new PublicKey(acc.data.slice(40, 72));
718
+ const tokenVaultA = new PublicKey(acc.data.slice(104, 136));
719
+ const tokenVaultB = new PublicKey(acc.data.slice(136, 168));
720
+
721
+ const [balanceA, balanceB] = await Promise.all([
722
+ this.connection.getTokenAccountBalance(tokenVaultA),
723
+ this.connection.getTokenAccountBalance(tokenVaultB),
724
+ ]);
725
+
726
+ // Determine which vault holds SOL by checking tokenMintA
727
+ const SOL_ADDR = "So11111111111111111111111111111111111111112";
728
+ const solBalance = tokenMintA.toBase58() === SOL_ADDR
729
+ ? Number(balanceA.value.amount)
730
+ : Number(balanceB.value.amount);
731
+ const usdcBalance = tokenMintA.toBase58() === SOL_ADDR
732
+ ? Number(balanceB.value.amount)
733
+ : Number(balanceA.value.amount);
734
+
735
+ if (solBalance === 0) throw new Error("Zero balance");
736
+ const price = usdcBalance / solBalance;
737
+ this.solPriceCache = { price, timestamp: Date.now() };
738
+ return price;
739
+ } catch {
740
+ return 175;
741
+ }
742
+ }
743
+
701
744
  async getPriceAndStatus(
702
745
  tokenAddr: string,
746
+ quoteMint?: PublicKey,
703
747
  ): Promise<{ price: number; completed: boolean }> {
704
748
  const mint = new PublicKey(tokenAddr);
705
749
  const { state } = await this.loadBonding(mint);
706
750
 
707
751
  if (state.complete) {
708
- const price = await this.getAmmPrice(mint);
752
+ const qm = quoteMint || (state.quoteMint && !state.quoteMint.equals(SOL_MINT) ? state.quoteMint : SOL_MINT);
753
+ const price = await this.getAmmPrice(mint, qm);
709
754
  return { price, completed: true };
710
755
  }
711
756
 
757
+ const qm = quoteMint || state.quoteMint || SOL_MINT;
758
+ const isSolQuote = qm.equals(SOL_MINT);
759
+
712
760
  const oneToken = BigInt(1_000_000);
713
- const solOut = this.calcSell(oneToken, state);
714
- const price = Number(solOut) / 1e9;
761
+
762
+ if (isSolQuote) {
763
+ const solOut = this.calcSell(oneToken, state);
764
+ const price = Number(solOut) / 1e9;
765
+ return { price, completed: false };
766
+ }
767
+
768
+ // USDC-paired bonding curve: pump stores USDC raw amount (6 decimals) in the
769
+ // virtualSolReserves field. calcSell returns USDC raw, divide by 1e6 for USDC price.
770
+ // Then convert to SOL using Orca USDC/SOL pool.
771
+ let quotePrice: number;
772
+ if (state.virtualQuoteReserves !== undefined) {
773
+ const newVirtualToken = state.virtualTokenReserves + oneToken;
774
+ const quoteOut = state.virtualQuoteReserves - (state.virtualQuoteReserves * state.virtualTokenReserves) / newVirtualToken;
775
+ quotePrice = Number(quoteOut) / 1e6;
776
+ } else {
777
+ const rawOut = this.calcSell(oneToken, state);
778
+ quotePrice = Number(rawOut) / 1e6;
779
+ }
780
+
781
+ const solPrice = await this.getSolPriceInUsdc();
782
+ const price = quotePrice / solPrice;
715
783
  return { price, completed: false };
716
784
  }
717
785
 
718
- async getAmmPrice(mint: PublicKey): Promise<number> {
786
+ async getAmmPrice(mint: PublicKey, quoteMint: PublicKey = SOL_MINT): Promise<number> {
719
787
  const [poolCreator] = PublicKey.findProgramAddressSync(
720
788
  [Buffer.from("pool-authority"), mint.toBuffer()],
721
789
  PROGRAM_IDS.PUMP,
@@ -728,7 +796,7 @@ export class PumpTrader {
728
796
  indexBuffer,
729
797
  poolCreator.toBuffer(),
730
798
  mint.toBuffer(),
731
- SOL_MINT.toBuffer(),
799
+ quoteMint.toBuffer(),
732
800
  ],
733
801
  PROGRAM_IDS.PUMP_AMM,
734
802
  );
@@ -742,7 +810,15 @@ export class PumpTrader {
742
810
  this.connection.getTokenAccountBalance(poolKeys.poolQuoteTokenAccount),
743
811
  ]);
744
812
 
745
- return quoteInfo.value.uiAmount! / baseInfo.value.uiAmount!;
813
+ let price = quoteInfo.value.uiAmount! / baseInfo.value.uiAmount!;
814
+
815
+ // If pool is not SOL-quoted, convert to SOL price
816
+ if (!quoteMint.equals(SOL_MINT)) {
817
+ const solPrice = await this.getSolPriceInUsdc();
818
+ price = price / solPrice;
819
+ }
820
+
821
+ return price;
746
822
  }
747
823
 
748
824
  /* ---------- 余额查询 ---------- */
@@ -1679,7 +1755,16 @@ export class PumpTrader {
1679
1755
  isWritable: true,
1680
1756
  });
1681
1757
  }
1682
- remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1758
+ const POOL_DEFAULT_COIN_CREATOR = new PublicKey("11111111111111111111111111111111");
1759
+ if (poolKeys.coinCreator && !poolKeys.coinCreator.equals(POOL_DEFAULT_COIN_CREATOR)) {
1760
+ remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1761
+ } else {
1762
+ remainingKeys.push({
1763
+ pubkey: PUMP_BUYBACK_FEE_RECIPIENTS[0],
1764
+ isSigner: false,
1765
+ isWritable: true,
1766
+ });
1767
+ }
1683
1768
  remainingKeys.push(
1684
1769
  { pubkey: newFeeRecipient, isSigner: false, isWritable: false },
1685
1770
  {
@@ -1824,7 +1909,16 @@ export class PumpTrader {
1824
1909
  { pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
1825
1910
  );
1826
1911
  }
1827
- remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1912
+ const POOL_DEFAULT_COIN_CREATOR = new PublicKey("11111111111111111111111111111111");
1913
+ if (poolKeys.coinCreator && !poolKeys.coinCreator.equals(POOL_DEFAULT_COIN_CREATOR)) {
1914
+ remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
1915
+ } else {
1916
+ remainingKeys.push({
1917
+ pubkey: PUMP_BUYBACK_FEE_RECIPIENTS[0],
1918
+ isSigner: false,
1919
+ isWritable: true,
1920
+ });
1921
+ }
1828
1922
  remainingKeys.push(
1829
1923
  { pubkey: newFeeRecipient, isSigner: false, isWritable: false },
1830
1924
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pump-trader",
3
- "version": "1.1.9",
3
+ "version": "1.2.3",
4
4
  "description": "PumpFun 交易库 - 自动判断 Token Program 和内盘/外盘",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",