@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/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
- import { bondingCurvePda, canonicalPumpPoolPda, creatorVaultPda, getGlobalParamsPda, getMayhemStatePda, getSolVaultPda, getTokenVaultPda, pumpPoolAuthorityPda } from "./pda";
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(mint, user, true, tokenProgram);
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(mint, user, true, TOKEN_2022_PROGRAM_ID);
348
+ const associatedUser = getAssociatedTokenAddressSync(
349
+ mint,
350
+ user,
351
+ true,
352
+ TOKEN_2022_PROGRAM_ID
353
+ );
277
354
  return [
278
- await this.createV2Instruction({ mint, name, symbol, uri, creator, user, mayhemMode }),
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(mint, bondingCurve, true, tokenProgram)
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(mint, poolAuthority, true, tokenProgram)
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(mint, pool, true, tokenProgram)
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(mint, user, true, tokenProgram),
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(mint, user, true, tokenProgram),
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
- export function getFeeRecipient(global: Global, mayhemMode: boolean): PublicKey {
673
- if (mayhemMode) {
674
- const feeRecipients = [global.reservedFeeRecipient, ...global.reservedFeeRecipients];
675
- return feeRecipients[Math.floor(Math.random() * feeRecipients.length)];
676
- } else {
677
- const feeRecipients = [global.feeRecipient, ...global.feeRecipients,];
678
- return feeRecipients[Math.floor(Math.random() * feeRecipients.length)];
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
  }