pump-trader 1.1.1 → 1.1.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 +3 -0
- package/dist/index.js +47 -6
- package/index.js +76 -6
- package/index.ts +79 -6
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ interface BondingCurveState {
|
|
|
33
33
|
realSolReserves: bigint;
|
|
34
34
|
tokenTotalSupply: bigint;
|
|
35
35
|
complete: boolean;
|
|
36
|
+
isMayhemMode?: boolean;
|
|
37
|
+
isCashbackCoin?: boolean;
|
|
36
38
|
}
|
|
37
39
|
interface BondingInfo {
|
|
38
40
|
bonding: PublicKey;
|
|
@@ -101,6 +103,7 @@ export declare class PumpTrader {
|
|
|
101
103
|
getTradeMode(tokenAddr: string): Promise<"bonding" | "amm">;
|
|
102
104
|
loadGlobal(): Promise<GlobalState>;
|
|
103
105
|
getBondingPda(mint: PublicKey): PublicKey;
|
|
106
|
+
deriveBondingCurveV2(mint: PublicKey): PublicKey;
|
|
104
107
|
loadBonding(mint: PublicKey): Promise<BondingInfo>;
|
|
105
108
|
calcBuy(solIn: bigint, state: BondingCurveState): bigint;
|
|
106
109
|
calcSell(tokenIn: bigint, state: BondingCurveState): bigint;
|
package/dist/index.js
CHANGED
|
@@ -100,6 +100,8 @@ function parsePoolKeys(data) {
|
|
|
100
100
|
const coinCreator = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
|
|
101
101
|
offset += 32;
|
|
102
102
|
const isMayhemMode = data.readUInt8(offset) === 1;
|
|
103
|
+
offset += 1;
|
|
104
|
+
const isCashbackCoin = offset < data.length ? data.readUInt8(offset) === 1 : false;
|
|
103
105
|
return {
|
|
104
106
|
creator,
|
|
105
107
|
baseMint,
|
|
@@ -108,7 +110,8 @@ function parsePoolKeys(data) {
|
|
|
108
110
|
poolBaseTokenAccount,
|
|
109
111
|
poolQuoteTokenAccount,
|
|
110
112
|
coinCreator,
|
|
111
|
-
isMayhemMode
|
|
113
|
+
isMayhemMode,
|
|
114
|
+
isCashbackCoin
|
|
112
115
|
};
|
|
113
116
|
}
|
|
114
117
|
/* ================= PumpTrader 类 ================= */
|
|
@@ -176,7 +179,15 @@ class PumpTrader {
|
|
|
176
179
|
*/
|
|
177
180
|
async getTradeMode(tokenAddr) {
|
|
178
181
|
const isAmmMode = await this.isAmmCompleted(tokenAddr);
|
|
179
|
-
|
|
182
|
+
if (isAmmMode)
|
|
183
|
+
return "amm";
|
|
184
|
+
try {
|
|
185
|
+
await this.getAmmPoolInfo(new web3_js_1.PublicKey(tokenAddr));
|
|
186
|
+
return "amm";
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
return "bonding";
|
|
190
|
+
}
|
|
180
191
|
}
|
|
181
192
|
/* ---------- Global State ---------- */
|
|
182
193
|
async loadGlobal() {
|
|
@@ -213,6 +224,9 @@ class PumpTrader {
|
|
|
213
224
|
getBondingPda(mint) {
|
|
214
225
|
return web3_js_1.PublicKey.findProgramAddressSync([SEEDS.BONDING, mint.toBuffer()], PROGRAM_IDS.PUMP)[0];
|
|
215
226
|
}
|
|
227
|
+
deriveBondingCurveV2(mint) {
|
|
228
|
+
return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("bonding-curve-v2"), mint.toBuffer()], PROGRAM_IDS.PUMP)[0];
|
|
229
|
+
}
|
|
216
230
|
async loadBonding(mint) {
|
|
217
231
|
const bonding = this.getBondingPda(mint);
|
|
218
232
|
const acc = await this.connection.getAccountInfo(bonding);
|
|
@@ -229,6 +243,10 @@ class PumpTrader {
|
|
|
229
243
|
state.complete = data[offset] === 1;
|
|
230
244
|
offset += 1;
|
|
231
245
|
const creator = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
|
|
246
|
+
offset += 32;
|
|
247
|
+
state.isMayhemMode = offset < data.length ? data[offset] === 1 : false;
|
|
248
|
+
offset += 1;
|
|
249
|
+
state.isCashbackCoin = offset < data.length ? data[offset] === 1 : false;
|
|
232
250
|
return { bonding, state, creator };
|
|
233
251
|
}
|
|
234
252
|
/* ---------- 价格计算 ---------- */
|
|
@@ -456,6 +474,7 @@ class PumpTrader {
|
|
|
456
474
|
async buy(tokenAddr, totalSolIn, tradeOpt) {
|
|
457
475
|
const mint = new web3_js_1.PublicKey(tokenAddr);
|
|
458
476
|
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
477
|
+
const bondingCurveV2 = this.deriveBondingCurveV2(mint);
|
|
459
478
|
if (!this.globalState)
|
|
460
479
|
await this.loadGlobal();
|
|
461
480
|
const { bonding, state, creator } = await this.loadBonding(mint);
|
|
@@ -500,7 +519,8 @@ class PumpTrader {
|
|
|
500
519
|
{ pubkey: globalVolumeAccumulator, isSigner: false, isWritable: false },
|
|
501
520
|
{ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
|
|
502
521
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
503
|
-
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false }
|
|
522
|
+
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
523
|
+
{ pubkey: bondingCurveV2, isSigner: false, isWritable: false }
|
|
504
524
|
],
|
|
505
525
|
data: Buffer.concat([DISCRIMINATORS.BUY, u64(tokenOut), u64(maxSol)])
|
|
506
526
|
}));
|
|
@@ -530,6 +550,7 @@ class PumpTrader {
|
|
|
530
550
|
async sell(tokenAddr, totalTokenIn, tradeOpt) {
|
|
531
551
|
const mint = new web3_js_1.PublicKey(tokenAddr);
|
|
532
552
|
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
553
|
+
const bondingCurveV2 = this.deriveBondingCurveV2(mint);
|
|
533
554
|
if (!this.globalState)
|
|
534
555
|
await this.loadGlobal();
|
|
535
556
|
const { bonding, state, creator } = await this.loadBonding(mint);
|
|
@@ -545,6 +566,12 @@ class PumpTrader {
|
|
|
545
566
|
const userAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, this.wallet.publicKey, false, tokenProgram.programId, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID);
|
|
546
567
|
const [creatorVault] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("creator-vault"), creator.toBuffer()], PROGRAM_IDS.PUMP);
|
|
547
568
|
const [feeConfig] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("fee_config"), SEEDS.FEE_CONFIG], PROGRAM_IDS.FEE);
|
|
569
|
+
const [userVolumeAccumulator] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()], PROGRAM_IDS.PUMP);
|
|
570
|
+
const sellRemainingKeys = [];
|
|
571
|
+
if (state.isCashbackCoin) {
|
|
572
|
+
sellRemainingKeys.push({ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true });
|
|
573
|
+
}
|
|
574
|
+
sellRemainingKeys.push({ pubkey: bondingCurveV2, isSigner: false, isWritable: false });
|
|
548
575
|
for (let i = 0; i < tokenChunks.length; i++) {
|
|
549
576
|
try {
|
|
550
577
|
const tokenIn = tokenChunks[i];
|
|
@@ -573,7 +600,8 @@ class PumpTrader {
|
|
|
573
600
|
{ pubkey: PROGRAM_IDS.EVENT_AUTHORITY, isSigner: false, isWritable: false },
|
|
574
601
|
{ pubkey: PROGRAM_IDS.PUMP, isSigner: false, isWritable: false },
|
|
575
602
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
576
|
-
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false }
|
|
603
|
+
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
604
|
+
...sellRemainingKeys
|
|
577
605
|
],
|
|
578
606
|
data: Buffer.concat([
|
|
579
607
|
DISCRIMINATORS.SELL,
|
|
@@ -763,6 +791,12 @@ class PumpTrader {
|
|
|
763
791
|
const [feeConfig] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("fee_config"), SEEDS.AMM_FEE_CONFIG], PROGRAM_IDS.FEE);
|
|
764
792
|
const protocolFeeRecipient = globalConfig.protocolFeeRecipients[0];
|
|
765
793
|
const protocolFeeRecipientTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(SOL_MINT, protocolFeeRecipient, true, spl_token_1.TOKEN_PROGRAM_ID, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID);
|
|
794
|
+
const remainingKeys = [];
|
|
795
|
+
if (poolKeys.isCashbackCoin) {
|
|
796
|
+
const userVolumeAccumulatorWsolAta = (0, spl_token_1.getAssociatedTokenAddressSync)(SOL_MINT, userVolumeAccumulator, true, spl_token_1.TOKEN_PROGRAM_ID, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID);
|
|
797
|
+
remainingKeys.push({ pubkey: userVolumeAccumulatorWsolAta, isSigner: false, isWritable: true });
|
|
798
|
+
}
|
|
799
|
+
remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
|
|
766
800
|
return new web3_js_1.TransactionInstruction({
|
|
767
801
|
programId: PROGRAM_IDS.PUMP_AMM,
|
|
768
802
|
keys: [
|
|
@@ -789,7 +823,7 @@ class PumpTrader {
|
|
|
789
823
|
{ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
|
|
790
824
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
791
825
|
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
792
|
-
|
|
826
|
+
...remainingKeys
|
|
793
827
|
],
|
|
794
828
|
data: Buffer.concat([
|
|
795
829
|
DISCRIMINATORS.BUY,
|
|
@@ -808,6 +842,13 @@ class PumpTrader {
|
|
|
808
842
|
const [feeConfig] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("fee_config"), SEEDS.AMM_FEE_CONFIG], PROGRAM_IDS.FEE);
|
|
809
843
|
const protocolFeeRecipient = globalConfig.protocolFeeRecipients[0];
|
|
810
844
|
const protocolFeeRecipientTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(SOL_MINT, protocolFeeRecipient, true, spl_token_1.TOKEN_PROGRAM_ID, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID);
|
|
845
|
+
const [userVolumeAccumulator] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()], PROGRAM_IDS.PUMP_AMM);
|
|
846
|
+
const userVolumeAccumulatorWsolAta = (0, spl_token_1.getAssociatedTokenAddressSync)(SOL_MINT, userVolumeAccumulator, true, spl_token_1.TOKEN_PROGRAM_ID, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID);
|
|
847
|
+
const remainingKeys = [];
|
|
848
|
+
if (poolKeys.isCashbackCoin) {
|
|
849
|
+
remainingKeys.push({ pubkey: userVolumeAccumulatorWsolAta, isSigner: false, isWritable: true }, { pubkey: userVolumeAccumulator, isSigner: false, isWritable: true });
|
|
850
|
+
}
|
|
851
|
+
remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
|
|
811
852
|
return new web3_js_1.TransactionInstruction({
|
|
812
853
|
programId: PROGRAM_IDS.PUMP_AMM,
|
|
813
854
|
keys: [
|
|
@@ -832,7 +873,7 @@ class PumpTrader {
|
|
|
832
873
|
{ pubkey: coinCreatorVaultAuthority, isSigner: false, isWritable: false },
|
|
833
874
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
834
875
|
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
835
|
-
|
|
876
|
+
...remainingKeys
|
|
836
877
|
],
|
|
837
878
|
data: Buffer.concat([
|
|
838
879
|
DISCRIMINATORS.SELL,
|
package/index.js
CHANGED
|
@@ -141,6 +141,8 @@ function parsePoolKeys(data) {
|
|
|
141
141
|
offset += 32;
|
|
142
142
|
|
|
143
143
|
const isMayhemMode = data.readUInt8(offset) === 1;
|
|
144
|
+
offset += 1;
|
|
145
|
+
const isCashbackCoin = offset < data.length ? data.readUInt8(offset) === 1 : false;
|
|
144
146
|
|
|
145
147
|
return {
|
|
146
148
|
creator,
|
|
@@ -150,7 +152,8 @@ function parsePoolKeys(data) {
|
|
|
150
152
|
poolBaseTokenAccount,
|
|
151
153
|
poolQuoteTokenAccount,
|
|
152
154
|
coinCreator,
|
|
153
|
-
isMayhemMode
|
|
155
|
+
isMayhemMode,
|
|
156
|
+
isCashbackCoin
|
|
154
157
|
};
|
|
155
158
|
}
|
|
156
159
|
|
|
@@ -230,7 +233,13 @@ export class PumpTrader {
|
|
|
230
233
|
*/
|
|
231
234
|
async getTradeMode(tokenAddr) {
|
|
232
235
|
const isAmmMode = await this.isAmmCompleted(tokenAddr);
|
|
233
|
-
|
|
236
|
+
if (isAmmMode) return "amm";
|
|
237
|
+
try {
|
|
238
|
+
await this.getAmmPoolInfo(new PublicKey(tokenAddr));
|
|
239
|
+
return "amm";
|
|
240
|
+
} catch {
|
|
241
|
+
return "bonding";
|
|
242
|
+
}
|
|
234
243
|
}
|
|
235
244
|
|
|
236
245
|
/* ---------- Global State ---------- */
|
|
@@ -278,6 +287,13 @@ export class PumpTrader {
|
|
|
278
287
|
)[0];
|
|
279
288
|
}
|
|
280
289
|
|
|
290
|
+
deriveBondingCurveV2(mint) {
|
|
291
|
+
return PublicKey.findProgramAddressSync(
|
|
292
|
+
[Buffer.from("bonding-curve-v2"), mint.toBuffer()],
|
|
293
|
+
PROGRAM_IDS.PUMP
|
|
294
|
+
)[0];
|
|
295
|
+
}
|
|
296
|
+
|
|
281
297
|
async loadBonding(mint) {
|
|
282
298
|
const bonding = this.getBondingPda(mint);
|
|
283
299
|
const acc = await this.connection.getAccountInfo(bonding);
|
|
@@ -296,6 +312,10 @@ export class PumpTrader {
|
|
|
296
312
|
offset += 1;
|
|
297
313
|
|
|
298
314
|
const creator = new PublicKey(data.slice(offset, offset + 32));
|
|
315
|
+
offset += 32;
|
|
316
|
+
state.isMayhemMode = offset < data.length ? data[offset] === 1 : false;
|
|
317
|
+
offset += 1;
|
|
318
|
+
state.isCashbackCoin = offset < data.length ? data[offset] === 1 : false;
|
|
299
319
|
|
|
300
320
|
return { bonding, state, creator };
|
|
301
321
|
}
|
|
@@ -611,6 +631,7 @@ export class PumpTrader {
|
|
|
611
631
|
async buy(tokenAddr, totalSolIn, tradeOpt) {
|
|
612
632
|
const mint = new PublicKey(tokenAddr);
|
|
613
633
|
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
634
|
+
const bondingCurveV2 = this.deriveBondingCurveV2(mint);
|
|
614
635
|
|
|
615
636
|
if (!this.globalState) await this.loadGlobal();
|
|
616
637
|
|
|
@@ -647,6 +668,17 @@ export class PumpTrader {
|
|
|
647
668
|
PROGRAM_IDS.FEE
|
|
648
669
|
);
|
|
649
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 });
|
|
681
|
+
|
|
650
682
|
for (let i = 0; i < solChunks.length; i++) {
|
|
651
683
|
try {
|
|
652
684
|
const solIn = solChunks[i];
|
|
@@ -685,7 +717,8 @@ export class PumpTrader {
|
|
|
685
717
|
{ pubkey: globalVolumeAccumulator, isSigner: false, isWritable: false },
|
|
686
718
|
{ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
|
|
687
719
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
688
|
-
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false }
|
|
720
|
+
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
721
|
+
{ pubkey: bondingCurveV2, isSigner: false, isWritable: false }
|
|
689
722
|
],
|
|
690
723
|
data: Buffer.concat([DISCRIMINATORS.BUY, u64(tokenOut), u64(maxSol)])
|
|
691
724
|
})
|
|
@@ -721,6 +754,7 @@ export class PumpTrader {
|
|
|
721
754
|
async sell(tokenAddr, totalTokenIn, tradeOpt) {
|
|
722
755
|
const mint = new PublicKey(tokenAddr);
|
|
723
756
|
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
757
|
+
const bondingCurveV2 = this.deriveBondingCurveV2(mint);
|
|
724
758
|
|
|
725
759
|
if (!this.globalState) await this.loadGlobal();
|
|
726
760
|
|
|
@@ -798,7 +832,8 @@ export class PumpTrader {
|
|
|
798
832
|
{ pubkey: PROGRAM_IDS.EVENT_AUTHORITY, isSigner: false, isWritable: false },
|
|
799
833
|
{ pubkey: PROGRAM_IDS.PUMP, isSigner: false, isWritable: false },
|
|
800
834
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
801
|
-
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false }
|
|
835
|
+
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
836
|
+
...sellRemainingKeys
|
|
802
837
|
],
|
|
803
838
|
data: Buffer.concat([
|
|
804
839
|
DISCRIMINATORS.SELL,
|
|
@@ -1119,6 +1154,19 @@ export class PumpTrader {
|
|
|
1119
1154
|
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
1120
1155
|
);
|
|
1121
1156
|
|
|
1157
|
+
const remainingKeys = [];
|
|
1158
|
+
if (poolKeys.isCashbackCoin) {
|
|
1159
|
+
const userVolumeAccumulatorWsolAta = getAssociatedTokenAddressSync(
|
|
1160
|
+
SOL_MINT,
|
|
1161
|
+
userVolumeAccumulator,
|
|
1162
|
+
true,
|
|
1163
|
+
TOKEN_PROGRAM_ID,
|
|
1164
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
1165
|
+
);
|
|
1166
|
+
remainingKeys.push({ pubkey: userVolumeAccumulatorWsolAta, isSigner: false, isWritable: true });
|
|
1167
|
+
}
|
|
1168
|
+
remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
|
|
1169
|
+
|
|
1122
1170
|
return new TransactionInstruction({
|
|
1123
1171
|
programId: PROGRAM_IDS.PUMP_AMM,
|
|
1124
1172
|
keys: [
|
|
@@ -1145,7 +1193,7 @@ export class PumpTrader {
|
|
|
1145
1193
|
{ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
|
|
1146
1194
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
1147
1195
|
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
1148
|
-
|
|
1196
|
+
...remainingKeys
|
|
1149
1197
|
],
|
|
1150
1198
|
data: Buffer.concat([
|
|
1151
1199
|
DISCRIMINATORS.BUY,
|
|
@@ -1192,6 +1240,28 @@ export class PumpTrader {
|
|
|
1192
1240
|
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
1193
1241
|
);
|
|
1194
1242
|
|
|
1243
|
+
const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
|
|
1244
|
+
[Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
|
|
1245
|
+
PROGRAM_IDS.PUMP_AMM
|
|
1246
|
+
);
|
|
1247
|
+
|
|
1248
|
+
const userVolumeAccumulatorWsolAta = getAssociatedTokenAddressSync(
|
|
1249
|
+
SOL_MINT,
|
|
1250
|
+
userVolumeAccumulator,
|
|
1251
|
+
true,
|
|
1252
|
+
TOKEN_PROGRAM_ID,
|
|
1253
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
1254
|
+
);
|
|
1255
|
+
|
|
1256
|
+
const remainingKeys = [];
|
|
1257
|
+
if (poolKeys.isCashbackCoin) {
|
|
1258
|
+
remainingKeys.push(
|
|
1259
|
+
{ pubkey: userVolumeAccumulatorWsolAta, isSigner: false, isWritable: true },
|
|
1260
|
+
{ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true }
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
|
|
1264
|
+
|
|
1195
1265
|
return new TransactionInstruction({
|
|
1196
1266
|
programId: PROGRAM_IDS.PUMP_AMM,
|
|
1197
1267
|
keys: [
|
|
@@ -1216,7 +1286,7 @@ export class PumpTrader {
|
|
|
1216
1286
|
{ pubkey: coinCreatorVaultAuthority, isSigner: false, isWritable: false },
|
|
1217
1287
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
1218
1288
|
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
1219
|
-
|
|
1289
|
+
...remainingKeys
|
|
1220
1290
|
],
|
|
1221
1291
|
data: Buffer.concat([
|
|
1222
1292
|
DISCRIMINATORS.SELL,
|
package/index.ts
CHANGED
|
@@ -63,6 +63,8 @@ interface BondingCurveState {
|
|
|
63
63
|
realSolReserves: bigint;
|
|
64
64
|
tokenTotalSupply: bigint;
|
|
65
65
|
complete: boolean;
|
|
66
|
+
isMayhemMode?: boolean;
|
|
67
|
+
isCashbackCoin?: boolean;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
interface BondingInfo {
|
|
@@ -239,6 +241,8 @@ function parsePoolKeys(data: Buffer) {
|
|
|
239
241
|
offset += 32;
|
|
240
242
|
|
|
241
243
|
const isMayhemMode = data.readUInt8(offset) === 1;
|
|
244
|
+
offset += 1;
|
|
245
|
+
const isCashbackCoin = offset < data.length ? data.readUInt8(offset) === 1 : false;
|
|
242
246
|
|
|
243
247
|
return {
|
|
244
248
|
creator,
|
|
@@ -248,7 +252,8 @@ function parsePoolKeys(data: Buffer) {
|
|
|
248
252
|
poolBaseTokenAccount,
|
|
249
253
|
poolQuoteTokenAccount,
|
|
250
254
|
coinCreator,
|
|
251
|
-
isMayhemMode
|
|
255
|
+
isMayhemMode,
|
|
256
|
+
isCashbackCoin
|
|
252
257
|
};
|
|
253
258
|
}
|
|
254
259
|
|
|
@@ -328,7 +333,13 @@ export class PumpTrader {
|
|
|
328
333
|
*/
|
|
329
334
|
async getTradeMode(tokenAddr: string): Promise<"bonding" | "amm"> {
|
|
330
335
|
const isAmmMode = await this.isAmmCompleted(tokenAddr);
|
|
331
|
-
|
|
336
|
+
if (isAmmMode) return "amm";
|
|
337
|
+
try {
|
|
338
|
+
await this.getAmmPoolInfo(new PublicKey(tokenAddr));
|
|
339
|
+
return "amm";
|
|
340
|
+
} catch {
|
|
341
|
+
return "bonding";
|
|
342
|
+
}
|
|
332
343
|
}
|
|
333
344
|
|
|
334
345
|
/* ---------- Global State ---------- */
|
|
@@ -376,6 +387,13 @@ export class PumpTrader {
|
|
|
376
387
|
)[0];
|
|
377
388
|
}
|
|
378
389
|
|
|
390
|
+
deriveBondingCurveV2(mint: PublicKey): PublicKey {
|
|
391
|
+
return PublicKey.findProgramAddressSync(
|
|
392
|
+
[Buffer.from("bonding-curve-v2"), mint.toBuffer()],
|
|
393
|
+
PROGRAM_IDS.PUMP
|
|
394
|
+
)[0];
|
|
395
|
+
}
|
|
396
|
+
|
|
379
397
|
async loadBonding(mint: PublicKey): Promise<BondingInfo> {
|
|
380
398
|
const bonding = this.getBondingPda(mint);
|
|
381
399
|
const acc = await this.connection.getAccountInfo(bonding);
|
|
@@ -394,6 +412,11 @@ export class PumpTrader {
|
|
|
394
412
|
offset += 1;
|
|
395
413
|
|
|
396
414
|
const creator = new PublicKey(data.slice(offset, offset + 32));
|
|
415
|
+
offset += 32;
|
|
416
|
+
|
|
417
|
+
state.isMayhemMode = offset < data.length ? data[offset] === 1 : false;
|
|
418
|
+
offset += 1;
|
|
419
|
+
state.isCashbackCoin = offset < data.length ? data[offset] === 1 : false;
|
|
397
420
|
|
|
398
421
|
return { bonding, state, creator };
|
|
399
422
|
}
|
|
@@ -716,6 +739,7 @@ export class PumpTrader {
|
|
|
716
739
|
async buy(tokenAddr: string, totalSolIn: bigint, tradeOpt: TradeOptions): Promise<TradeResult> {
|
|
717
740
|
const mint = new PublicKey(tokenAddr);
|
|
718
741
|
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
742
|
+
const bondingCurveV2 = this.deriveBondingCurveV2(mint);
|
|
719
743
|
|
|
720
744
|
if (!this.globalState) await this.loadGlobal();
|
|
721
745
|
|
|
@@ -792,7 +816,8 @@ export class PumpTrader {
|
|
|
792
816
|
{ pubkey: globalVolumeAccumulator, isSigner: false, isWritable: false },
|
|
793
817
|
{ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
|
|
794
818
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
795
|
-
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false }
|
|
819
|
+
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
820
|
+
{ pubkey: bondingCurveV2, isSigner: false, isWritable: false }
|
|
796
821
|
],
|
|
797
822
|
data: Buffer.concat([DISCRIMINATORS.BUY, u64(tokenOut), u64(maxSol)])
|
|
798
823
|
})
|
|
@@ -828,6 +853,7 @@ export class PumpTrader {
|
|
|
828
853
|
async sell(tokenAddr: string, totalTokenIn: bigint, tradeOpt: TradeOptions): Promise<TradeResult> {
|
|
829
854
|
const mint = new PublicKey(tokenAddr);
|
|
830
855
|
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
856
|
+
const bondingCurveV2 = this.deriveBondingCurveV2(mint);
|
|
831
857
|
|
|
832
858
|
if (!this.globalState) await this.loadGlobal();
|
|
833
859
|
|
|
@@ -871,6 +897,17 @@ export class PumpTrader {
|
|
|
871
897
|
PROGRAM_IDS.FEE
|
|
872
898
|
);
|
|
873
899
|
|
|
900
|
+
const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
|
|
901
|
+
[Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
|
|
902
|
+
PROGRAM_IDS.PUMP
|
|
903
|
+
);
|
|
904
|
+
|
|
905
|
+
const sellRemainingKeys = [];
|
|
906
|
+
if (state.isCashbackCoin) {
|
|
907
|
+
sellRemainingKeys.push({ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true });
|
|
908
|
+
}
|
|
909
|
+
sellRemainingKeys.push({ pubkey: bondingCurveV2, isSigner: false, isWritable: false });
|
|
910
|
+
|
|
874
911
|
for (let i = 0; i < tokenChunks.length; i++) {
|
|
875
912
|
try {
|
|
876
913
|
const tokenIn = tokenChunks[i];
|
|
@@ -905,7 +942,8 @@ export class PumpTrader {
|
|
|
905
942
|
{ pubkey: PROGRAM_IDS.EVENT_AUTHORITY, isSigner: false, isWritable: false },
|
|
906
943
|
{ pubkey: PROGRAM_IDS.PUMP, isSigner: false, isWritable: false },
|
|
907
944
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
908
|
-
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false }
|
|
945
|
+
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
946
|
+
...sellRemainingKeys
|
|
909
947
|
],
|
|
910
948
|
data: Buffer.concat([
|
|
911
949
|
DISCRIMINATORS.SELL,
|
|
@@ -1232,6 +1270,19 @@ export class PumpTrader {
|
|
|
1232
1270
|
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
1233
1271
|
);
|
|
1234
1272
|
|
|
1273
|
+
const remainingKeys = [];
|
|
1274
|
+
if (poolKeys.isCashbackCoin) {
|
|
1275
|
+
const userVolumeAccumulatorWsolAta = getAssociatedTokenAddressSync(
|
|
1276
|
+
SOL_MINT,
|
|
1277
|
+
userVolumeAccumulator,
|
|
1278
|
+
true,
|
|
1279
|
+
TOKEN_PROGRAM_ID,
|
|
1280
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
1281
|
+
);
|
|
1282
|
+
remainingKeys.push({ pubkey: userVolumeAccumulatorWsolAta, isSigner: false, isWritable: true });
|
|
1283
|
+
}
|
|
1284
|
+
remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
|
|
1285
|
+
|
|
1235
1286
|
return new TransactionInstruction({
|
|
1236
1287
|
programId: PROGRAM_IDS.PUMP_AMM,
|
|
1237
1288
|
keys: [
|
|
@@ -1258,7 +1309,7 @@ export class PumpTrader {
|
|
|
1258
1309
|
{ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true },
|
|
1259
1310
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
1260
1311
|
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
1261
|
-
|
|
1312
|
+
...remainingKeys
|
|
1262
1313
|
],
|
|
1263
1314
|
data: Buffer.concat([
|
|
1264
1315
|
DISCRIMINATORS.BUY,
|
|
@@ -1312,6 +1363,28 @@ export class PumpTrader {
|
|
|
1312
1363
|
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
1313
1364
|
);
|
|
1314
1365
|
|
|
1366
|
+
const [userVolumeAccumulator] = PublicKey.findProgramAddressSync(
|
|
1367
|
+
[Buffer.from("user_volume_accumulator"), this.wallet.publicKey.toBuffer()],
|
|
1368
|
+
PROGRAM_IDS.PUMP_AMM
|
|
1369
|
+
);
|
|
1370
|
+
|
|
1371
|
+
const userVolumeAccumulatorWsolAta = getAssociatedTokenAddressSync(
|
|
1372
|
+
SOL_MINT,
|
|
1373
|
+
userVolumeAccumulator,
|
|
1374
|
+
true,
|
|
1375
|
+
TOKEN_PROGRAM_ID,
|
|
1376
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
1377
|
+
);
|
|
1378
|
+
|
|
1379
|
+
const remainingKeys = [];
|
|
1380
|
+
if (poolKeys.isCashbackCoin) {
|
|
1381
|
+
remainingKeys.push(
|
|
1382
|
+
{ pubkey: userVolumeAccumulatorWsolAta, isSigner: false, isWritable: true },
|
|
1383
|
+
{ pubkey: userVolumeAccumulator, isSigner: false, isWritable: true }
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
remainingKeys.push({ pubkey: poolV2, isSigner: false, isWritable: false });
|
|
1387
|
+
|
|
1315
1388
|
return new TransactionInstruction({
|
|
1316
1389
|
programId: PROGRAM_IDS.PUMP_AMM,
|
|
1317
1390
|
keys: [
|
|
@@ -1336,7 +1409,7 @@ export class PumpTrader {
|
|
|
1336
1409
|
{ pubkey: coinCreatorVaultAuthority, isSigner: false, isWritable: false },
|
|
1337
1410
|
{ pubkey: feeConfig, isSigner: false, isWritable: false },
|
|
1338
1411
|
{ pubkey: PROGRAM_IDS.FEE, isSigner: false, isWritable: false },
|
|
1339
|
-
|
|
1412
|
+
...remainingKeys
|
|
1340
1413
|
],
|
|
1341
1414
|
data: Buffer.concat([
|
|
1342
1415
|
DISCRIMINATORS.SELL,
|