@pump-fun/pump-sdk 1.23.0 → 1.25.0-devnet.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +10043 -320
- package/dist/index.d.mts +11853 -1496
- package/dist/index.d.ts +11853 -1496
- package/dist/index.js +10039 -317
- package/package.json +1 -1
- package/src/errors.ts +52 -0
- package/src/fees.ts +10 -0
- package/src/idl/pump.json +792 -31
- package/src/idl/pump.ts +792 -31
- package/src/idl/pump_amm.json +5878 -0
- package/src/idl/pump_amm.ts +5884 -0
- package/src/idl/pump_fees.json +2761 -0
- package/src/idl/pump_fees.ts +2767 -0
- package/src/index.ts +11 -0
- package/src/pda.ts +35 -3
- package/src/sdk.ts +395 -61
- package/src/state.ts +28 -0
package/src/sdk.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { AnchorProvider, Program } from "@coral-xyz/anchor";
|
|
2
|
-
import { PUMP_AMM_SDK } from "@pump-fun/pump-swap-sdk";
|
|
3
2
|
import {
|
|
4
3
|
createAssociatedTokenAccountIdempotentInstruction,
|
|
4
|
+
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
5
5
|
getAssociatedTokenAddressSync,
|
|
6
|
+
NATIVE_MINT,
|
|
6
7
|
TOKEN_2022_PROGRAM_ID,
|
|
7
8
|
TOKEN_PROGRAM_ID,
|
|
8
9
|
} from "@solana/spl-token";
|
|
@@ -15,79 +16,138 @@ import {
|
|
|
15
16
|
import pumpIdl from "./idl/pump.json";
|
|
16
17
|
import { Pump } from "./idl/pump";
|
|
17
18
|
import BN from "bn.js";
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
import {
|
|
20
|
+
NoShareholdersError,
|
|
21
|
+
TooManyShareholdersError,
|
|
22
|
+
ZeroShareError,
|
|
23
|
+
ShareCalculationOverflowError,
|
|
24
|
+
InvalidShareTotalError,
|
|
25
|
+
DuplicateShareholderError,
|
|
26
|
+
PoolRequiredForGraduatedError,
|
|
27
|
+
} from "./errors";
|
|
28
|
+
|
|
29
|
+
import { bondingCurvePda, canonicalPumpPoolPda, creatorVaultPda, getGlobalParamsPda, getMayhemStatePda, getSolVaultPda, getTokenVaultPda, pumpPoolAuthorityPda, ammCreatorVaultPda, feeSharingConfigPda } from "./pda";
|
|
20
30
|
import {
|
|
21
31
|
BondingCurve,
|
|
22
32
|
FeeConfig,
|
|
23
33
|
Global,
|
|
24
34
|
GlobalVolumeAccumulator,
|
|
25
35
|
UserVolumeAccumulator,
|
|
36
|
+
Shareholder,
|
|
37
|
+
SharingConfig,
|
|
38
|
+
DistributeCreatorFeesEvent,
|
|
39
|
+
MinimumDistributableFeeEvent,
|
|
26
40
|
} from "./state";
|
|
27
41
|
import { getStaticRandomFeeRecipient } from "./bondingCurve";
|
|
42
|
+
import { getFeeRecipient } from "./fees";
|
|
28
43
|
import { OFFLINE_PUMP_PROGRAM } from "./onlineSdk";
|
|
44
|
+
import PumpAmmIdl from "./idl/pump_amm.json";
|
|
45
|
+
import { PumpAmm } from "./idl/pump_amm";
|
|
46
|
+
import PumpFeesIdl from "./idl/pump_fees.json";
|
|
47
|
+
import { PumpFees } from "./idl/pump_fees";
|
|
48
|
+
import { coinCreatorVaultAtaPda, coinCreatorVaultAuthorityPda, PUMP_AMM_EVENT_AUTHORITY_PDA, pumpAmmPda } from "@pump-fun/pump-swap-sdk";
|
|
29
49
|
|
|
30
50
|
export function getPumpProgram(connection: Connection): Program<Pump> {
|
|
31
51
|
return new Program(
|
|
32
52
|
pumpIdl as Pump,
|
|
33
|
-
new AnchorProvider(connection, null as any, {})
|
|
53
|
+
new AnchorProvider(connection, null as any, {})
|
|
34
54
|
);
|
|
35
55
|
}
|
|
36
56
|
|
|
37
57
|
export const PUMP_PROGRAM_ID = new PublicKey(
|
|
38
|
-
"6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
|
|
58
|
+
"6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
|
|
39
59
|
);
|
|
40
60
|
|
|
61
|
+
export function getPumpAmmProgram(connection: Connection): Program<PumpAmm> {
|
|
62
|
+
return new Program(
|
|
63
|
+
PumpAmmIdl as PumpAmm,
|
|
64
|
+
new AnchorProvider(connection, null as any, {}),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function getPumpFeeProgram(
|
|
69
|
+
connection: Connection,
|
|
70
|
+
): Program<PumpFees> {
|
|
71
|
+
return new Program(
|
|
72
|
+
PumpFeesIdl as PumpFees,
|
|
73
|
+
new AnchorProvider(connection, null as any, {}),
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
41
77
|
export const PUMP_AMM_PROGRAM_ID = new PublicKey(
|
|
42
|
-
"pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"
|
|
78
|
+
"pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"
|
|
43
79
|
);
|
|
44
80
|
|
|
45
81
|
export const MAYHEM_PROGRAM_ID = new PublicKey(
|
|
46
|
-
"MAyhSmzXzV1pTf7LsNkrNwkWKTo4ougAJ1PPg47MD4e"
|
|
82
|
+
"MAyhSmzXzV1pTf7LsNkrNwkWKTo4ougAJ1PPg47MD4e"
|
|
47
83
|
);
|
|
48
84
|
|
|
49
85
|
export const PUMP_FEE_PROGRAM_ID = new PublicKey(
|
|
50
|
-
"pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
|
|
86
|
+
"pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
|
|
51
87
|
);
|
|
52
88
|
|
|
53
89
|
export const BONDING_CURVE_NEW_SIZE = 151;
|
|
54
90
|
|
|
55
91
|
export const PUMP_TOKEN_MINT = new PublicKey(
|
|
56
|
-
"pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn"
|
|
92
|
+
"pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn"
|
|
57
93
|
);
|
|
58
94
|
|
|
95
|
+
export const MAX_SHAREHOLDERS = 10;
|
|
96
|
+
|
|
59
97
|
export class PumpSdk {
|
|
60
98
|
private readonly offlinePumpProgram: Program<Pump>;
|
|
99
|
+
private readonly offlinePumpFeeProgram: Program<PumpFees>;
|
|
100
|
+
private readonly offlinePumpAmmProgram: Program<PumpAmm>;
|
|
61
101
|
|
|
62
102
|
constructor() {
|
|
63
103
|
this.offlinePumpProgram = OFFLINE_PUMP_PROGRAM;
|
|
104
|
+
// Create offline programs for fee and AMM
|
|
105
|
+
this.offlinePumpFeeProgram = new Program(
|
|
106
|
+
PumpFeesIdl as PumpFees,
|
|
107
|
+
new AnchorProvider(null as any, null as any, {})
|
|
108
|
+
);
|
|
109
|
+
this.offlinePumpAmmProgram = new Program(
|
|
110
|
+
PumpAmmIdl as PumpAmm,
|
|
111
|
+
new AnchorProvider(null as any, null as any, {})
|
|
112
|
+
);
|
|
64
113
|
}
|
|
65
114
|
|
|
66
115
|
decodeGlobal(accountInfo: AccountInfo<Buffer>): Global {
|
|
67
116
|
return this.offlinePumpProgram.coder.accounts.decode<Global>(
|
|
68
117
|
"global",
|
|
69
|
-
accountInfo.data
|
|
118
|
+
accountInfo.data
|
|
70
119
|
);
|
|
71
120
|
}
|
|
72
121
|
|
|
73
122
|
decodeFeeConfig(accountInfo: AccountInfo<Buffer>): FeeConfig {
|
|
74
123
|
return this.offlinePumpProgram.coder.accounts.decode<FeeConfig>(
|
|
75
124
|
"feeConfig",
|
|
76
|
-
accountInfo.data
|
|
125
|
+
accountInfo.data
|
|
77
126
|
);
|
|
78
127
|
}
|
|
79
128
|
|
|
80
129
|
decodeBondingCurve(accountInfo: AccountInfo<Buffer>): BondingCurve {
|
|
81
130
|
return this.offlinePumpProgram.coder.accounts.decode<BondingCurve>(
|
|
82
131
|
"bondingCurve",
|
|
83
|
-
accountInfo.data
|
|
132
|
+
accountInfo.data
|
|
84
133
|
);
|
|
85
134
|
}
|
|
86
135
|
|
|
87
136
|
decodeBondingCurveNullable(
|
|
88
|
-
accountInfo: AccountInfo<Buffer
|
|
137
|
+
accountInfo: AccountInfo<Buffer>
|
|
89
138
|
): BondingCurve | null {
|
|
90
139
|
try {
|
|
140
|
+
let data = accountInfo.data;
|
|
141
|
+
// Ensure buffer is at least 82 bytes
|
|
142
|
+
if (data.length < 82) {
|
|
143
|
+
const padded = Buffer.alloc(82);
|
|
144
|
+
data.copy(padded);
|
|
145
|
+
accountInfo = {
|
|
146
|
+
...accountInfo,
|
|
147
|
+
data: padded,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
91
151
|
return this.decodeBondingCurve(accountInfo);
|
|
92
152
|
} catch (e) {
|
|
93
153
|
console.warn("Failed to decode bonding curve", e);
|
|
@@ -96,25 +156,25 @@ export class PumpSdk {
|
|
|
96
156
|
}
|
|
97
157
|
|
|
98
158
|
decodeGlobalVolumeAccumulator(
|
|
99
|
-
accountInfo: AccountInfo<Buffer
|
|
159
|
+
accountInfo: AccountInfo<Buffer>
|
|
100
160
|
): GlobalVolumeAccumulator {
|
|
101
161
|
return this.offlinePumpProgram.coder.accounts.decode<GlobalVolumeAccumulator>(
|
|
102
162
|
"globalVolumeAccumulator",
|
|
103
|
-
accountInfo.data
|
|
163
|
+
accountInfo.data
|
|
104
164
|
);
|
|
105
165
|
}
|
|
106
166
|
|
|
107
167
|
decodeUserVolumeAccumulator(
|
|
108
|
-
accountInfo: AccountInfo<Buffer
|
|
168
|
+
accountInfo: AccountInfo<Buffer>
|
|
109
169
|
): UserVolumeAccumulator {
|
|
110
170
|
return this.offlinePumpProgram.coder.accounts.decode<UserVolumeAccumulator>(
|
|
111
171
|
"userVolumeAccumulator",
|
|
112
|
-
accountInfo.data
|
|
172
|
+
accountInfo.data
|
|
113
173
|
);
|
|
114
174
|
}
|
|
115
175
|
|
|
116
176
|
decodeUserVolumeAccumulatorNullable(
|
|
117
|
-
accountInfo: AccountInfo<Buffer
|
|
177
|
+
accountInfo: AccountInfo<Buffer>
|
|
118
178
|
): UserVolumeAccumulator | null {
|
|
119
179
|
try {
|
|
120
180
|
return this.decodeUserVolumeAccumulator(accountInfo);
|
|
@@ -124,6 +184,13 @@ export class PumpSdk {
|
|
|
124
184
|
}
|
|
125
185
|
}
|
|
126
186
|
|
|
187
|
+
decodeSharingConfig(accountInfo: AccountInfo<Buffer>): SharingConfig {
|
|
188
|
+
return this.offlinePumpFeeProgram.coder.accounts.decode<SharingConfig>(
|
|
189
|
+
"sharingConfig",
|
|
190
|
+
accountInfo.data,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
127
194
|
/**
|
|
128
195
|
* @deprecated Use `createInstructionV2` instead.
|
|
129
196
|
*/
|
|
@@ -159,7 +226,7 @@ export class PumpSdk {
|
|
|
159
226
|
uri,
|
|
160
227
|
creator,
|
|
161
228
|
user,
|
|
162
|
-
mayhemMode
|
|
229
|
+
mayhemMode,
|
|
163
230
|
}: {
|
|
164
231
|
mint: PublicKey;
|
|
165
232
|
name: string;
|
|
@@ -214,11 +281,16 @@ export class PumpSdk {
|
|
|
214
281
|
await this.extendAccountInstruction({
|
|
215
282
|
account: bondingCurvePda(mint),
|
|
216
283
|
user,
|
|
217
|
-
})
|
|
284
|
+
})
|
|
218
285
|
);
|
|
219
286
|
}
|
|
220
287
|
|
|
221
|
-
const associatedUser = getAssociatedTokenAddressSync(
|
|
288
|
+
const associatedUser = getAssociatedTokenAddressSync(
|
|
289
|
+
mint,
|
|
290
|
+
user,
|
|
291
|
+
true,
|
|
292
|
+
tokenProgram
|
|
293
|
+
);
|
|
222
294
|
|
|
223
295
|
if (!associatedUserAccountInfo) {
|
|
224
296
|
instructions.push(
|
|
@@ -228,7 +300,7 @@ export class PumpSdk {
|
|
|
228
300
|
user,
|
|
229
301
|
mint,
|
|
230
302
|
tokenProgram
|
|
231
|
-
)
|
|
303
|
+
)
|
|
232
304
|
);
|
|
233
305
|
}
|
|
234
306
|
|
|
@@ -244,7 +316,7 @@ export class PumpSdk {
|
|
|
244
316
|
slippage,
|
|
245
317
|
tokenProgram,
|
|
246
318
|
mayhemMode: bondingCurve.isMayhemMode,
|
|
247
|
-
})
|
|
319
|
+
})
|
|
248
320
|
);
|
|
249
321
|
|
|
250
322
|
return instructions;
|
|
@@ -273,9 +345,22 @@ export class PumpSdk {
|
|
|
273
345
|
solAmount: BN;
|
|
274
346
|
mayhemMode: boolean;
|
|
275
347
|
}): Promise<TransactionInstruction[]> {
|
|
276
|
-
const associatedUser = getAssociatedTokenAddressSync(
|
|
348
|
+
const associatedUser = getAssociatedTokenAddressSync(
|
|
349
|
+
mint,
|
|
350
|
+
user,
|
|
351
|
+
true,
|
|
352
|
+
TOKEN_2022_PROGRAM_ID
|
|
353
|
+
);
|
|
277
354
|
return [
|
|
278
|
-
await this.createV2Instruction({
|
|
355
|
+
await this.createV2Instruction({
|
|
356
|
+
mint,
|
|
357
|
+
name,
|
|
358
|
+
symbol,
|
|
359
|
+
uri,
|
|
360
|
+
creator,
|
|
361
|
+
user,
|
|
362
|
+
mayhemMode,
|
|
363
|
+
}),
|
|
279
364
|
await this.extendAccountInstruction({
|
|
280
365
|
account: bondingCurvePda(mint),
|
|
281
366
|
user,
|
|
@@ -285,7 +370,7 @@ export class PumpSdk {
|
|
|
285
370
|
associatedUser,
|
|
286
371
|
user,
|
|
287
372
|
mint,
|
|
288
|
-
TOKEN_2022_PROGRAM_ID
|
|
373
|
+
TOKEN_2022_PROGRAM_ID
|
|
289
374
|
),
|
|
290
375
|
await this.buyInstruction({
|
|
291
376
|
global,
|
|
@@ -337,7 +422,7 @@ export class PumpSdk {
|
|
|
337
422
|
user,
|
|
338
423
|
associatedUser,
|
|
339
424
|
user,
|
|
340
|
-
mint
|
|
425
|
+
mint
|
|
341
426
|
),
|
|
342
427
|
await this.buyInstruction({
|
|
343
428
|
global,
|
|
@@ -385,7 +470,7 @@ export class PumpSdk {
|
|
|
385
470
|
feeRecipient: getFeeRecipient(global, mayhemMode),
|
|
386
471
|
amount,
|
|
387
472
|
solAmount: solAmount.add(
|
|
388
|
-
solAmount.mul(new BN(Math.floor(slippage * 10))).div(new BN(1000))
|
|
473
|
+
solAmount.mul(new BN(Math.floor(slippage * 10))).div(new BN(1000))
|
|
389
474
|
),
|
|
390
475
|
tokenProgram,
|
|
391
476
|
});
|
|
@@ -401,7 +486,7 @@ export class PumpSdk {
|
|
|
401
486
|
solAmount,
|
|
402
487
|
slippage,
|
|
403
488
|
tokenProgram = TOKEN_PROGRAM_ID,
|
|
404
|
-
mayhemMode = false
|
|
489
|
+
mayhemMode = false,
|
|
405
490
|
}: {
|
|
406
491
|
global: Global;
|
|
407
492
|
bondingCurveAccountInfo: AccountInfo<Buffer>;
|
|
@@ -421,7 +506,7 @@ export class PumpSdk {
|
|
|
421
506
|
await this.extendAccountInstruction({
|
|
422
507
|
account: bondingCurvePda(mint),
|
|
423
508
|
user,
|
|
424
|
-
})
|
|
509
|
+
})
|
|
425
510
|
);
|
|
426
511
|
}
|
|
427
512
|
|
|
@@ -433,10 +518,10 @@ export class PumpSdk {
|
|
|
433
518
|
feeRecipient: getFeeRecipient(global, mayhemMode),
|
|
434
519
|
amount,
|
|
435
520
|
solAmount: solAmount.sub(
|
|
436
|
-
solAmount.mul(new BN(Math.floor(slippage * 10))).div(new BN(1000))
|
|
521
|
+
solAmount.mul(new BN(Math.floor(slippage * 10))).div(new BN(1000))
|
|
437
522
|
),
|
|
438
523
|
tokenProgram,
|
|
439
|
-
})
|
|
524
|
+
})
|
|
440
525
|
);
|
|
441
526
|
|
|
442
527
|
return instructions;
|
|
@@ -462,21 +547,36 @@ export class PumpSdk {
|
|
|
462
547
|
withdrawAuthority,
|
|
463
548
|
mint,
|
|
464
549
|
user,
|
|
465
|
-
tokenProgram = TOKEN_PROGRAM_ID
|
|
550
|
+
tokenProgram = TOKEN_PROGRAM_ID,
|
|
466
551
|
}: {
|
|
467
552
|
withdrawAuthority: PublicKey;
|
|
468
553
|
mint: PublicKey;
|
|
469
554
|
user: PublicKey;
|
|
470
555
|
tokenProgram: PublicKey;
|
|
471
556
|
}): Promise<TransactionInstruction> {
|
|
472
|
-
const bondingCurve = bondingCurvePda(mint)
|
|
473
|
-
const associatedBondingCurve = getAssociatedTokenAddressSync(
|
|
557
|
+
const bondingCurve = bondingCurvePda(mint);
|
|
558
|
+
const associatedBondingCurve = getAssociatedTokenAddressSync(
|
|
559
|
+
mint,
|
|
560
|
+
bondingCurve,
|
|
561
|
+
true,
|
|
562
|
+
tokenProgram
|
|
563
|
+
);
|
|
474
564
|
|
|
475
565
|
const poolAuthority = pumpPoolAuthorityPda(mint);
|
|
476
|
-
const poolAuthorityMintAccount = getAssociatedTokenAddressSync(
|
|
566
|
+
const poolAuthorityMintAccount = getAssociatedTokenAddressSync(
|
|
567
|
+
mint,
|
|
568
|
+
poolAuthority,
|
|
569
|
+
true,
|
|
570
|
+
tokenProgram
|
|
571
|
+
);
|
|
477
572
|
|
|
478
573
|
const pool = canonicalPumpPoolPda(mint);
|
|
479
|
-
const poolBaseTokenAccount = getAssociatedTokenAddressSync(
|
|
574
|
+
const poolBaseTokenAccount = getAssociatedTokenAddressSync(
|
|
575
|
+
mint,
|
|
576
|
+
pool,
|
|
577
|
+
true,
|
|
578
|
+
tokenProgram
|
|
579
|
+
);
|
|
480
580
|
return this.offlinePumpProgram.methods
|
|
481
581
|
.migrate()
|
|
482
582
|
.accountsPartial({
|
|
@@ -485,13 +585,13 @@ export class PumpSdk {
|
|
|
485
585
|
withdrawAuthority,
|
|
486
586
|
associatedBondingCurve,
|
|
487
587
|
poolAuthorityMintAccount,
|
|
488
|
-
poolBaseTokenAccount
|
|
588
|
+
poolBaseTokenAccount,
|
|
489
589
|
})
|
|
490
590
|
.instruction();
|
|
491
591
|
}
|
|
492
592
|
|
|
493
593
|
async syncUserVolumeAccumulator(
|
|
494
|
-
user: PublicKey
|
|
594
|
+
user: PublicKey
|
|
495
595
|
): Promise<TransactionInstruction> {
|
|
496
596
|
return await this.offlinePumpProgram.methods
|
|
497
597
|
.syncUserVolumeAccumulator()
|
|
@@ -499,15 +599,6 @@ export class PumpSdk {
|
|
|
499
599
|
.instruction();
|
|
500
600
|
}
|
|
501
601
|
|
|
502
|
-
async syncUserVolumeAccumulatorBothPrograms(
|
|
503
|
-
user: PublicKey,
|
|
504
|
-
): Promise<TransactionInstruction[]> {
|
|
505
|
-
return [
|
|
506
|
-
await this.syncUserVolumeAccumulator(user),
|
|
507
|
-
await PUMP_AMM_SDK.syncUserVolumeAccumulator(user),
|
|
508
|
-
];
|
|
509
|
-
}
|
|
510
|
-
|
|
511
602
|
async setCreator({
|
|
512
603
|
mint,
|
|
513
604
|
setCreatorAuthority,
|
|
@@ -540,7 +631,7 @@ export class PumpSdk {
|
|
|
540
631
|
}
|
|
541
632
|
|
|
542
633
|
async closeUserVolumeAccumulator(
|
|
543
|
-
user: PublicKey
|
|
634
|
+
user: PublicKey
|
|
544
635
|
): Promise<TransactionInstruction> {
|
|
545
636
|
return await this.offlinePumpProgram.methods
|
|
546
637
|
.closeUserVolumeAccumulator()
|
|
@@ -567,7 +658,12 @@ export class PumpSdk {
|
|
|
567
658
|
}): Promise<TransactionInstruction> {
|
|
568
659
|
return await this.getBuyInstructionInternal({
|
|
569
660
|
user,
|
|
570
|
-
associatedUser: getAssociatedTokenAddressSync(
|
|
661
|
+
associatedUser: getAssociatedTokenAddressSync(
|
|
662
|
+
mint,
|
|
663
|
+
user,
|
|
664
|
+
true,
|
|
665
|
+
tokenProgram
|
|
666
|
+
),
|
|
571
667
|
mint,
|
|
572
668
|
creator,
|
|
573
669
|
feeRecipient,
|
|
@@ -632,7 +728,7 @@ export class PumpSdk {
|
|
|
632
728
|
feeRecipient,
|
|
633
729
|
amount,
|
|
634
730
|
solAmount,
|
|
635
|
-
tokenProgram
|
|
731
|
+
tokenProgram,
|
|
636
732
|
});
|
|
637
733
|
}
|
|
638
734
|
|
|
@@ -658,23 +754,261 @@ export class PumpSdk {
|
|
|
658
754
|
.accountsPartial({
|
|
659
755
|
feeRecipient,
|
|
660
756
|
mint,
|
|
661
|
-
associatedUser: getAssociatedTokenAddressSync(
|
|
757
|
+
associatedUser: getAssociatedTokenAddressSync(
|
|
758
|
+
mint,
|
|
759
|
+
user,
|
|
760
|
+
true,
|
|
761
|
+
tokenProgram
|
|
762
|
+
),
|
|
662
763
|
user,
|
|
663
764
|
creatorVault: creatorVaultPda(creator),
|
|
664
|
-
tokenProgram: tokenProgram
|
|
765
|
+
tokenProgram: tokenProgram,
|
|
665
766
|
})
|
|
666
767
|
.instruction();
|
|
667
768
|
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Creates a fee sharing configuration for a token.
|
|
772
|
+
*
|
|
773
|
+
* @param params - Parameters for creating a fee sharing configuration
|
|
774
|
+
* @param params.creator - The creator of the token
|
|
775
|
+
* @param params.mint - The mint address of the token
|
|
776
|
+
* @param params.pool - The pool address of the token (null for ungraduated coins)
|
|
777
|
+
*/
|
|
778
|
+
async createFeeSharingConfig({
|
|
779
|
+
creator,
|
|
780
|
+
mint,
|
|
781
|
+
pool,
|
|
782
|
+
}: {
|
|
783
|
+
creator: PublicKey;
|
|
784
|
+
mint: PublicKey;
|
|
785
|
+
pool: PublicKey | null;
|
|
786
|
+
}): Promise<TransactionInstruction> {
|
|
787
|
+
return await this.offlinePumpFeeProgram.methods
|
|
788
|
+
.createFeeSharingConfig()
|
|
789
|
+
.accountsPartial({
|
|
790
|
+
payer: creator,
|
|
791
|
+
mint,
|
|
792
|
+
pool,
|
|
793
|
+
})
|
|
794
|
+
.instruction();
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Updates the fee shares for a token's creator fee distribution.
|
|
800
|
+
*
|
|
801
|
+
* @param params - Parameters for updating fee shares
|
|
802
|
+
* @param params.authority - The current authority that can modify the fee sharing config
|
|
803
|
+
* @param params.mint - The mint address of the token
|
|
804
|
+
* @param params.curShareholders - Array of current shareholders
|
|
805
|
+
* @param params.newShareholders - Array of new shareholders and their share percentages
|
|
806
|
+
*
|
|
807
|
+
* @requirements for newShareholders:
|
|
808
|
+
* - Must contain at least 1 shareholder (cannot be empty)
|
|
809
|
+
* - Maximum of 10 shareholders allowed
|
|
810
|
+
* - Each shareholder must have a positive share (shareBps > 0)
|
|
811
|
+
* - Total shares must equal exactly 10,000 basis points (100%)
|
|
812
|
+
* - No duplicate addresses allowed
|
|
813
|
+
* - shareBps is in basis points where 1 bps = 0.01% (e.g., 1500 = 15%)
|
|
814
|
+
*
|
|
815
|
+
* @throws {NoShareholdersError} If shareholders array is empty
|
|
816
|
+
* @throws {TooManyShareholdersError} If more than 10 shareholders
|
|
817
|
+
* @throws {ZeroShareError} If any shareholder has zero or negative shares
|
|
818
|
+
* @throws {InvalidShareTotalError} If total shares don't equal 10,000 basis points
|
|
819
|
+
* @throws {DuplicateShareholderError} If duplicate addresses are found
|
|
820
|
+
*
|
|
821
|
+
* @example
|
|
822
|
+
* ```typescript
|
|
823
|
+
* const instruction = await PUMP_SDK.updateFeeShares({
|
|
824
|
+
* authority: authorityPublicKey,
|
|
825
|
+
* mint: mintPublicKey,
|
|
826
|
+
* curShareholders: [wallet1, wallet2, wallet3],
|
|
827
|
+
* newShareholders: [
|
|
828
|
+
* { address: wallet1, shareBps: 5000 }, // 50%
|
|
829
|
+
* { address: wallet2, shareBps: 3000 }, // 30%
|
|
830
|
+
* { address: wallet3, shareBps: 2000 }, // 20%
|
|
831
|
+
* ]
|
|
832
|
+
* });
|
|
833
|
+
* ```
|
|
834
|
+
*/
|
|
835
|
+
async updateFeeShares({
|
|
836
|
+
authority,
|
|
837
|
+
mint,
|
|
838
|
+
currentShareholders,
|
|
839
|
+
newShareholders,
|
|
840
|
+
}: {
|
|
841
|
+
authority: PublicKey;
|
|
842
|
+
mint: PublicKey;
|
|
843
|
+
currentShareholders: PublicKey[];
|
|
844
|
+
newShareholders: Shareholder[];
|
|
845
|
+
}): Promise<TransactionInstruction> {
|
|
846
|
+
if (newShareholders.length === 0) {
|
|
847
|
+
throw new NoShareholdersError();
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
if (newShareholders.length > MAX_SHAREHOLDERS) {
|
|
851
|
+
throw new TooManyShareholdersError(newShareholders.length, MAX_SHAREHOLDERS);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
let totalShares = 0;
|
|
855
|
+
const addresses = new Set<string>();
|
|
856
|
+
|
|
857
|
+
for (const shareholder of newShareholders) {
|
|
858
|
+
if (shareholder.shareBps <= 0) {
|
|
859
|
+
throw new ZeroShareError(shareholder.address.toString());
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
totalShares += shareholder.shareBps;
|
|
863
|
+
addresses.add(shareholder.address.toString());
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
if (totalShares !== 10_000) {
|
|
867
|
+
throw new InvalidShareTotalError(totalShares);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
if (addresses.size !== newShareholders.length) {
|
|
871
|
+
throw new DuplicateShareholderError();
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
const sharingConfigPda = feeSharingConfigPda(mint);
|
|
875
|
+
const coinCreatorVaultAuthority = coinCreatorVaultAuthorityPda(sharingConfigPda);
|
|
876
|
+
|
|
877
|
+
return await this.offlinePumpFeeProgram.methods
|
|
878
|
+
.updateFeeShares(
|
|
879
|
+
newShareholders.map(sh => ({
|
|
880
|
+
address: sh.address,
|
|
881
|
+
shareBps: sh.shareBps,
|
|
882
|
+
}))
|
|
883
|
+
)
|
|
884
|
+
.accountsPartial({
|
|
885
|
+
authority,
|
|
886
|
+
mint,
|
|
887
|
+
coinCreatorVaultAta: coinCreatorVaultAtaPda(coinCreatorVaultAuthority, NATIVE_MINT, TOKEN_PROGRAM_ID),
|
|
888
|
+
})
|
|
889
|
+
.remainingAccounts(
|
|
890
|
+
currentShareholders.map((pubkey) => ({
|
|
891
|
+
pubkey,
|
|
892
|
+
isWritable: true,
|
|
893
|
+
isSigner: false,
|
|
894
|
+
}))
|
|
895
|
+
)
|
|
896
|
+
.instruction();
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
decodeDistributeCreatorFeesEvent(data: Buffer): DistributeCreatorFeesEvent {
|
|
900
|
+
return this.offlinePumpProgram.coder.types.decode<DistributeCreatorFeesEvent>(
|
|
901
|
+
"distributeCreatorFeesEvent",
|
|
902
|
+
data
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
async distributeCreatorFees({
|
|
907
|
+
mint,
|
|
908
|
+
sharingConfig,
|
|
909
|
+
sharingConfigAddress,
|
|
910
|
+
}: {
|
|
911
|
+
mint: PublicKey;
|
|
912
|
+
sharingConfig: SharingConfig;
|
|
913
|
+
sharingConfigAddress: PublicKey;
|
|
914
|
+
}): Promise<TransactionInstruction> {
|
|
915
|
+
return await this.offlinePumpProgram.methods
|
|
916
|
+
.distributeCreatorFees()
|
|
917
|
+
.accountsPartial({
|
|
918
|
+
mint,
|
|
919
|
+
creatorVault: creatorVaultPda(sharingConfigAddress),
|
|
920
|
+
})
|
|
921
|
+
.remainingAccounts(
|
|
922
|
+
sharingConfig.shareholders.map((shareholder) => ({
|
|
923
|
+
pubkey: shareholder.address,
|
|
924
|
+
isWritable: true,
|
|
925
|
+
isSigner: false,
|
|
926
|
+
}))
|
|
927
|
+
)
|
|
928
|
+
.instruction();
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
decodeMinimumDistributableFee(data: Buffer): MinimumDistributableFeeEvent {
|
|
932
|
+
return this.offlinePumpProgram.coder.types.decode<MinimumDistributableFeeEvent>(
|
|
933
|
+
"minimumDistributableFeeEvent",
|
|
934
|
+
data
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
async getMinimumDistributableFee({
|
|
939
|
+
mint,
|
|
940
|
+
sharingConfig,
|
|
941
|
+
sharingConfigAddress,
|
|
942
|
+
}: {
|
|
943
|
+
mint: PublicKey;
|
|
944
|
+
sharingConfig: SharingConfig;
|
|
945
|
+
sharingConfigAddress: PublicKey;
|
|
946
|
+
}): Promise<TransactionInstruction> {
|
|
947
|
+
return await this.offlinePumpProgram.methods
|
|
948
|
+
.getMinimumDistributableFee()
|
|
949
|
+
.accountsPartial({
|
|
950
|
+
mint,
|
|
951
|
+
creatorVault: creatorVaultPda(sharingConfigAddress),
|
|
952
|
+
})
|
|
953
|
+
.remainingAccounts(
|
|
954
|
+
sharingConfig.shareholders.map((shareholder) => ({
|
|
955
|
+
pubkey: shareholder.address,
|
|
956
|
+
isWritable: true,
|
|
957
|
+
isSigner: false,
|
|
958
|
+
}))
|
|
959
|
+
)
|
|
960
|
+
.instruction();
|
|
961
|
+
}
|
|
668
962
|
}
|
|
669
963
|
|
|
670
964
|
export const PUMP_SDK = new PumpSdk();
|
|
671
965
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
966
|
+
/**
|
|
967
|
+
* Checks if a creator has migrated to using a fee sharing configuration.
|
|
968
|
+
*
|
|
969
|
+
* When a creator sets up fee sharing, the creator address in the BondingCurve or Pool
|
|
970
|
+
* is replaced with the fee sharing config PDA address. This function checks if that
|
|
971
|
+
* migration has occurred.
|
|
972
|
+
*
|
|
973
|
+
* @param params - Parameters for checking migration status
|
|
974
|
+
* @param params.mint - The mint address of the token
|
|
975
|
+
* @param params.creator - The creator address to check
|
|
976
|
+
* - For ungraduated coins: use BondingCurve.creator
|
|
977
|
+
* - For graduated coins: use Pool.coinCreator (from AMM pool)
|
|
978
|
+
*
|
|
979
|
+
* @returns true if the creator has migrated to fee sharing config, false otherwise
|
|
980
|
+
*
|
|
981
|
+
* @example
|
|
982
|
+
* ```typescript
|
|
983
|
+
* import { hasCoinCreatorMigratedToSharingConfig } from "@pump-fun/sdk";
|
|
984
|
+
*
|
|
985
|
+
* // For an ungraduated coin
|
|
986
|
+
* const bondingCurve = await program.account.bondingCurve.fetch(bondingCurvePda(mint));
|
|
987
|
+
* const hasMigrated = hasCoinCreatorMigratedToSharingConfig({
|
|
988
|
+
* mint,
|
|
989
|
+
* creator: bondingCurve.creator
|
|
990
|
+
* });
|
|
991
|
+
*
|
|
992
|
+
* // For a graduated coin
|
|
993
|
+
* const pool = await ammProgram.account.pool.fetch(poolAddress);
|
|
994
|
+
* const hasMigrated = hasCoinCreatorMigratedToSharingConfig({
|
|
995
|
+
* mint,
|
|
996
|
+
* creator: pool.coinCreator
|
|
997
|
+
* });
|
|
998
|
+
*
|
|
999
|
+
* if (hasMigrated) {
|
|
1000
|
+
* // Creator fees are distributed according to fee sharing config
|
|
1001
|
+
* } else {
|
|
1002
|
+
* // Creator fees go directly to the creator address
|
|
1003
|
+
* }
|
|
1004
|
+
* ```
|
|
1005
|
+
*/
|
|
1006
|
+
export function hasCoinCreatorMigratedToSharingConfig({
|
|
1007
|
+
mint,
|
|
1008
|
+
creator,
|
|
1009
|
+
}: {
|
|
1010
|
+
mint: PublicKey;
|
|
1011
|
+
creator: PublicKey;
|
|
1012
|
+
}): boolean {
|
|
1013
|
+
return feeSharingConfigPda(mint).equals(creator);
|
|
680
1014
|
}
|