@pump-fun/pump-sdk 1.17.6 → 1.18.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pump-fun/pump-sdk",
3
- "version": "1.17.6",
3
+ "version": "1.18.0",
4
4
  "description": "Pump Bonding Curve SDK",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/pump-fun/pump-sdk#readme",
@@ -1,27 +1,7 @@
1
- import { PublicKey } from "@solana/web3.js";
2
- import { BondingCurve, Global } from "./state";
3
1
  import BN from "bn.js";
4
-
5
- function getFee(
6
- global: Global,
7
- bondingCurve: BondingCurve,
8
- amount: BN,
9
- isNewBondingCurve: boolean,
10
- ): BN {
11
- return computeFee(amount, global.feeBasisPoints).add(
12
- isNewBondingCurve || !PublicKey.default.equals(bondingCurve.creator)
13
- ? computeFee(amount, global.creatorFeeBasisPoints)
14
- : new BN(0),
15
- );
16
- }
17
-
18
- function computeFee(amount: BN, feeBasisPoints: BN): BN {
19
- return ceilDiv(amount.mul(feeBasisPoints), new BN(10_000));
20
- }
21
-
22
- function ceilDiv(a: BN, b: BN): BN {
23
- return a.add(b.subn(1)).div(b);
24
- }
2
+ import { PublicKey } from "@solana/web3.js";
3
+ import { BondingCurve, FeeConfig, Global } from "./state";
4
+ import { computeFeesBps, getFee } from "./fees";
25
5
 
26
6
  export function newBondingCurve(global: Global): BondingCurve {
27
7
  return {
@@ -78,11 +58,19 @@ export function getSellSolAmountFromTokenAmountQuote({
78
58
  .div(virtualTokenReserves.add(inputAmount));
79
59
  }
80
60
 
81
- export function getBuyTokenAmountFromSolAmount(
82
- global: Global,
83
- bondingCurve: BondingCurve | null,
84
- amount: BN,
85
- ): BN {
61
+ export function getBuyTokenAmountFromSolAmount({
62
+ global,
63
+ feeConfig,
64
+ mintSupply,
65
+ bondingCurve,
66
+ amount,
67
+ }: {
68
+ global: Global;
69
+ feeConfig: FeeConfig | null;
70
+ mintSupply: BN | null;
71
+ bondingCurve: BondingCurve | null;
72
+ amount: BN;
73
+ }): BN {
86
74
  if (amount.eq(new BN(0))) {
87
75
  return new BN(0);
88
76
  }
@@ -99,9 +87,18 @@ export function getBuyTokenAmountFromSolAmount(
99
87
  return new BN(0);
100
88
  }
101
89
 
102
- const totalFeeBasisPoints = global.feeBasisPoints.add(
90
+ const { virtualSolReserves, virtualTokenReserves } = bondingCurve;
91
+ const { protocolFeeBps, creatorFeeBps } = computeFeesBps({
92
+ global,
93
+ feeConfig,
94
+ mintSupply,
95
+ virtualSolReserves,
96
+ virtualTokenReserves,
97
+ });
98
+
99
+ const totalFeeBasisPoints = protocolFeeBps.add(
103
100
  isNewBondingCurve || !PublicKey.default.equals(bondingCurve.creator)
104
- ? global.creatorFeeBasisPoints
101
+ ? creatorFeeBps
105
102
  : new BN(0),
106
103
  );
107
104
 
@@ -116,11 +113,19 @@ export function getBuyTokenAmountFromSolAmount(
116
113
  return BN.min(tokensReceived, bondingCurve.realTokenReserves);
117
114
  }
118
115
 
119
- export function getBuySolAmountFromTokenAmount(
120
- global: Global,
121
- bondingCurve: BondingCurve | null,
122
- amount: BN,
123
- ): BN {
116
+ export function getBuySolAmountFromTokenAmount({
117
+ global,
118
+ feeConfig,
119
+ mintSupply,
120
+ bondingCurve,
121
+ amount,
122
+ }: {
123
+ global: Global;
124
+ feeConfig: FeeConfig | null;
125
+ mintSupply: BN | null;
126
+ bondingCurve: BondingCurve | null;
127
+ amount: BN;
128
+ }): BN {
124
129
  if (amount.eq(new BN(0))) {
125
130
  return new BN(0);
126
131
  }
@@ -145,14 +150,29 @@ export function getBuySolAmountFromTokenAmount(
145
150
  virtualSolReserves: bondingCurve.virtualSolReserves,
146
151
  });
147
152
 
148
- return solCost.add(getFee(global, bondingCurve, solCost, isNewBondingCurve));
153
+ return solCost.add(getFee({
154
+ global,
155
+ feeConfig,
156
+ mintSupply,
157
+ bondingCurve,
158
+ amount: solCost,
159
+ isNewBondingCurve,
160
+ }));
149
161
  }
150
162
 
151
- export function getSellSolAmountFromTokenAmount(
152
- global: Global,
153
- bondingCurve: BondingCurve,
154
- amount: BN,
155
- ): BN {
163
+ export function getSellSolAmountFromTokenAmount({
164
+ global,
165
+ feeConfig,
166
+ mintSupply,
167
+ bondingCurve,
168
+ amount,
169
+ }: {
170
+ global: Global;
171
+ feeConfig: FeeConfig | null;
172
+ mintSupply: BN | null;
173
+ bondingCurve: BondingCurve;
174
+ amount: BN;
175
+ }): BN {
156
176
  if (amount.eq(new BN(0))) {
157
177
  return new BN(0);
158
178
  }
@@ -168,7 +188,14 @@ export function getSellSolAmountFromTokenAmount(
168
188
  virtualSolReserves: bondingCurve.virtualSolReserves,
169
189
  });
170
190
 
171
- return solCost.sub(getFee(global, bondingCurve, solCost, false));
191
+ return solCost.sub(getFee({
192
+ global,
193
+ feeConfig,
194
+ mintSupply,
195
+ bondingCurve,
196
+ amount: solCost,
197
+ isNewBondingCurve: false,
198
+ }));
172
199
  }
173
200
 
174
201
  export function getStaticRandomFeeRecipient(): PublicKey {
@@ -186,3 +213,18 @@ const CURRENT_FEE_RECIPIENTS = [
186
213
  "FWsW1xNtWscwNmKv6wVsU1iTzRN6wmmk3MjxRP5tT7hz",
187
214
  "G5UZAVbAf46s7cKWoyKu8kYTip9DGTpbLZ2qa9Aq69dP",
188
215
  ];
216
+
217
+ export function bondingCurveMarketCap({
218
+ mintSupply,
219
+ virtualSolReserves,
220
+ virtualTokenReserves,
221
+ }: {
222
+ mintSupply: BN;
223
+ virtualSolReserves: BN;
224
+ virtualTokenReserves: BN;
225
+ }): BN {
226
+ if (virtualTokenReserves.isZero()) {
227
+ throw new Error("Division by zero: virtual token reserves cannot be zero");
228
+ }
229
+ return virtualSolReserves.mul(mintSupply).div(virtualTokenReserves);
230
+ }
package/src/fees.ts ADDED
@@ -0,0 +1,118 @@
1
+ import BN from "bn.js";
2
+ import { PublicKey } from "@solana/web3.js";
3
+ import { FeeConfig, Global, Fees, BondingCurve, FeeTier } from "./state";
4
+ import { bondingCurveMarketCap } from "./bondingCurve";
5
+
6
+ export interface CalculatedFeesBps {
7
+ protocolFeeBps: BN;
8
+ creatorFeeBps: BN;
9
+ }
10
+
11
+ export interface CalculatedFees {
12
+ protocolFee: BN;
13
+ creatorFee: BN;
14
+ }
15
+
16
+ export function createFeeConfigFromGlobalConfig(globalConfig: Global): FeeConfig {
17
+ let fees: Fees = {
18
+ lpFeeBps: new BN(0), // unused for pump
19
+ protocolFeeBps: globalConfig.feeBasisPoints,
20
+ creatorFeeBps: globalConfig.creatorFeeBasisPoints,
21
+ };
22
+ return {
23
+ admin: globalConfig.authority,
24
+ flatFees: fees,
25
+ feeTiers: [
26
+ {
27
+ marketCapLamportsThreshold: new BN(0), // unused for pump
28
+ fees,
29
+ },
30
+ ],
31
+ };
32
+ }
33
+
34
+ export function getFee({
35
+ global,
36
+ feeConfig,
37
+ mintSupply,
38
+ bondingCurve,
39
+ amount,
40
+ isNewBondingCurve,
41
+ }: {
42
+ global: Global;
43
+ feeConfig: FeeConfig | null;
44
+ mintSupply: BN | null;
45
+ bondingCurve: BondingCurve;
46
+ amount: BN;
47
+ isNewBondingCurve: boolean;
48
+ }) {
49
+ const { virtualSolReserves, virtualTokenReserves } = bondingCurve;
50
+ const { protocolFeeBps, creatorFeeBps } = computeFeesBps({
51
+ global,
52
+ feeConfig,
53
+ mintSupply,
54
+ virtualSolReserves,
55
+ virtualTokenReserves,
56
+ });
57
+
58
+ return fee(amount, protocolFeeBps).add(
59
+ isNewBondingCurve || !PublicKey.default.equals(bondingCurve.creator) ? fee(amount, creatorFeeBps) : new BN(0)
60
+ );
61
+ }
62
+
63
+ export function computeFeesBps({
64
+ global,
65
+ feeConfig,
66
+ mintSupply,
67
+ virtualSolReserves,
68
+ virtualTokenReserves,
69
+ }: {
70
+ global: Global;
71
+ feeConfig: FeeConfig | null;
72
+ mintSupply: BN | null;
73
+ virtualSolReserves: BN;
74
+ virtualTokenReserves: BN;
75
+ }): CalculatedFeesBps {
76
+ if (feeConfig != null && mintSupply != null) {
77
+ const marketCap = bondingCurveMarketCap({
78
+ mintSupply,
79
+ virtualSolReserves,
80
+ virtualTokenReserves,
81
+ });
82
+
83
+ return calculateFeeTier({
84
+ feeTiers: feeConfig.feeTiers,
85
+ marketCap,
86
+ });
87
+ }
88
+
89
+ return {
90
+ protocolFeeBps: global.feeBasisPoints,
91
+ creatorFeeBps: global.creatorFeeBasisPoints,
92
+ };
93
+ }
94
+
95
+ /// rust reference: pump-fees-math::calculate_fee_tier()
96
+ export function calculateFeeTier({ feeTiers, marketCap }: { feeTiers: FeeTier[]; marketCap: BN }): Fees {
97
+ const firstTier = feeTiers[0];
98
+
99
+ if (marketCap.lt(firstTier.marketCapLamportsThreshold)) {
100
+ return firstTier.fees;
101
+ }
102
+
103
+ for (const tier of feeTiers.slice().reverse()) {
104
+ if (marketCap.gte(tier.marketCapLamportsThreshold)) {
105
+ return tier.fees;
106
+ }
107
+ }
108
+
109
+ return firstTier.fees;
110
+ }
111
+
112
+ function fee(amount: BN, feeBasisPoints: BN): BN {
113
+ return ceilDiv(amount.mul(feeBasisPoints), new BN(10_000));
114
+ }
115
+
116
+ function ceilDiv(a: BN, b: BN): BN {
117
+ return a.add(b.subn(1)).div(b);
118
+ }
package/src/idl/pump.json CHANGED
@@ -656,7 +656,8 @@
656
656
  }
657
657
  },
658
658
  {
659
- "name": "program"
659
+ "name": "program",
660
+ "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
660
661
  },
661
662
  {
662
663
  "name": "global_volume_accumulator",
@@ -735,6 +736,75 @@
735
736
  }
736
737
  ]
737
738
  }
739
+ },
740
+ {
741
+ "name": "fee_config",
742
+ "optional": true,
743
+ "pda": {
744
+ "seeds": [
745
+ {
746
+ "kind": "const",
747
+ "value": [
748
+ 102,
749
+ 101,
750
+ 101,
751
+ 95,
752
+ 99,
753
+ 111,
754
+ 110,
755
+ 102,
756
+ 105,
757
+ 103
758
+ ]
759
+ },
760
+ {
761
+ "kind": "const",
762
+ "value": [
763
+ 1,
764
+ 86,
765
+ 224,
766
+ 246,
767
+ 147,
768
+ 102,
769
+ 90,
770
+ 207,
771
+ 68,
772
+ 219,
773
+ 21,
774
+ 104,
775
+ 191,
776
+ 23,
777
+ 91,
778
+ 170,
779
+ 81,
780
+ 137,
781
+ 203,
782
+ 151,
783
+ 245,
784
+ 210,
785
+ 255,
786
+ 59,
787
+ 101,
788
+ 93,
789
+ 43,
790
+ 182,
791
+ 253,
792
+ 109,
793
+ 24,
794
+ 176
795
+ ]
796
+ }
797
+ ],
798
+ "program": {
799
+ "kind": "account",
800
+ "path": "fee_program"
801
+ }
802
+ }
803
+ },
804
+ {
805
+ "name": "fee_program",
806
+ "optional": true,
807
+ "address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
738
808
  }
739
809
  ],
740
810
  "args": [
@@ -1010,7 +1080,8 @@
1010
1080
  }
1011
1081
  },
1012
1082
  {
1013
- "name": "program"
1083
+ "name": "program",
1084
+ "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
1014
1085
  },
1015
1086
  {
1016
1087
  "name": "payer",
@@ -2492,7 +2563,77 @@
2492
2563
  }
2493
2564
  },
2494
2565
  {
2495
- "name": "program"
2566
+ "name": "program",
2567
+ "address": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
2568
+ },
2569
+ {
2570
+ "name": "fee_config",
2571
+ "optional": true,
2572
+ "pda": {
2573
+ "seeds": [
2574
+ {
2575
+ "kind": "const",
2576
+ "value": [
2577
+ 102,
2578
+ 101,
2579
+ 101,
2580
+ 95,
2581
+ 99,
2582
+ 111,
2583
+ 110,
2584
+ 102,
2585
+ 105,
2586
+ 103
2587
+ ]
2588
+ },
2589
+ {
2590
+ "kind": "const",
2591
+ "value": [
2592
+ 1,
2593
+ 86,
2594
+ 224,
2595
+ 246,
2596
+ 147,
2597
+ 102,
2598
+ 90,
2599
+ 207,
2600
+ 68,
2601
+ 219,
2602
+ 21,
2603
+ 104,
2604
+ 191,
2605
+ 23,
2606
+ 91,
2607
+ 170,
2608
+ 81,
2609
+ 137,
2610
+ 203,
2611
+ 151,
2612
+ 245,
2613
+ 210,
2614
+ 255,
2615
+ 59,
2616
+ 101,
2617
+ 93,
2618
+ 43,
2619
+ 182,
2620
+ 253,
2621
+ 109,
2622
+ 24,
2623
+ 176
2624
+ ]
2625
+ }
2626
+ ],
2627
+ "program": {
2628
+ "kind": "account",
2629
+ "path": "fee_program"
2630
+ }
2631
+ }
2632
+ },
2633
+ {
2634
+ "name": "fee_program",
2635
+ "optional": true,
2636
+ "address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
2496
2637
  }
2497
2638
  ],
2498
2639
  "args": [
@@ -3243,6 +3384,19 @@
3243
3384
  96
3244
3385
  ]
3245
3386
  },
3387
+ {
3388
+ "name": "FeeConfig",
3389
+ "discriminator": [
3390
+ 143,
3391
+ 52,
3392
+ 146,
3393
+ 187,
3394
+ 219,
3395
+ 123,
3396
+ 76,
3397
+ 155
3398
+ ]
3399
+ },
3246
3400
  {
3247
3401
  "name": "Global",
3248
3402
  "discriminator": [
@@ -4048,6 +4202,80 @@
4048
4202
  ]
4049
4203
  }
4050
4204
  },
4205
+ {
4206
+ "name": "FeeConfig",
4207
+ "type": {
4208
+ "kind": "struct",
4209
+ "fields": [
4210
+ {
4211
+ "name": "bump",
4212
+ "type": "u8"
4213
+ },
4214
+ {
4215
+ "name": "admin",
4216
+ "type": "pubkey"
4217
+ },
4218
+ {
4219
+ "name": "flat_fees",
4220
+ "type": {
4221
+ "defined": {
4222
+ "name": "Fees"
4223
+ }
4224
+ }
4225
+ },
4226
+ {
4227
+ "name": "fee_tiers",
4228
+ "type": {
4229
+ "vec": {
4230
+ "defined": {
4231
+ "name": "FeeTier"
4232
+ }
4233
+ }
4234
+ }
4235
+ }
4236
+ ]
4237
+ }
4238
+ },
4239
+ {
4240
+ "name": "FeeTier",
4241
+ "type": {
4242
+ "kind": "struct",
4243
+ "fields": [
4244
+ {
4245
+ "name": "market_cap_lamports_threshold",
4246
+ "type": "u128"
4247
+ },
4248
+ {
4249
+ "name": "fees",
4250
+ "type": {
4251
+ "defined": {
4252
+ "name": "Fees"
4253
+ }
4254
+ }
4255
+ }
4256
+ ]
4257
+ }
4258
+ },
4259
+ {
4260
+ "name": "Fees",
4261
+ "type": {
4262
+ "kind": "struct",
4263
+ "fields": [
4264
+ {
4265
+ "name": "lp_fee_bps",
4266
+ "type": "u64"
4267
+ },
4268
+ {
4269
+ "name": "protocol_fee_bps",
4270
+ "type": "u64"
4271
+ },
4272
+ {
4273
+ "name": "creator_fee_bps",
4274
+ "type": "u64"
4275
+ }
4276
+ ]
4277
+ }
4278
+ },
4051
4279
  {
4052
4280
  "name": "Global",
4053
4281
  "type": {