@pump-fun/pump-sdk 1.3.8-devnet.1 → 1.4.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
@@ -2,7 +2,6 @@ import { AnchorProvider, Program } from "@coral-xyz/anchor";
2
2
  import { PumpAmmSdk } from "@pump-fun/pump-swap-sdk";
3
3
  import {
4
4
  createAssociatedTokenAccountIdempotentInstruction,
5
- getAccount,
6
5
  getAssociatedTokenAddressSync,
7
6
  } from "@solana/spl-token";
8
7
  import {
@@ -115,14 +114,61 @@ export class PumpSdk {
115
114
  );
116
115
  }
117
116
 
118
- async createInstruction(
119
- mint: PublicKey,
120
- name: string,
121
- symbol: string,
122
- uri: string,
123
- creator: PublicKey,
124
- user: PublicKey,
125
- ): Promise<TransactionInstruction> {
117
+ async fetchBuyState(mint: PublicKey, user: PublicKey) {
118
+ const [bondingCurveAccountInfo, associatedUserAccountInfo] =
119
+ await this.connection.getMultipleAccountsInfo([
120
+ this.bondingCurvePda(mint),
121
+ getAssociatedTokenAddressSync(mint, user, true),
122
+ ]);
123
+
124
+ if (!bondingCurveAccountInfo) {
125
+ throw new Error(
126
+ `Bonding curve account not found for mint: ${mint.toBase58()}`,
127
+ );
128
+ }
129
+
130
+ const bondingCurve = this.decodeBondingCurve(bondingCurveAccountInfo);
131
+ return { bondingCurveAccountInfo, bondingCurve, associatedUserAccountInfo };
132
+ }
133
+
134
+ async fetchSellState(mint: PublicKey, user: PublicKey) {
135
+ const [bondingCurveAccountInfo, associatedUserAccountInfo] =
136
+ await this.connection.getMultipleAccountsInfo([
137
+ this.bondingCurvePda(mint),
138
+ getAssociatedTokenAddressSync(mint, user, true),
139
+ ]);
140
+
141
+ if (!bondingCurveAccountInfo) {
142
+ throw new Error(
143
+ `Bonding curve account not found for mint: ${mint.toBase58()}`,
144
+ );
145
+ }
146
+
147
+ if (!associatedUserAccountInfo) {
148
+ throw new Error(
149
+ `Associated token account not found for mint: ${mint.toBase58()} and user: ${user.toBase58()}`,
150
+ );
151
+ }
152
+
153
+ const bondingCurve = this.decodeBondingCurve(bondingCurveAccountInfo);
154
+ return { bondingCurveAccountInfo, bondingCurve };
155
+ }
156
+
157
+ async createInstruction({
158
+ mint,
159
+ name,
160
+ symbol,
161
+ uri,
162
+ creator,
163
+ user,
164
+ }: {
165
+ mint: PublicKey;
166
+ name: string;
167
+ symbol: string;
168
+ uri: string;
169
+ creator: PublicKey;
170
+ user: PublicKey;
171
+ }): Promise<TransactionInstruction> {
126
172
  return await this.pumpProgram.methods
127
173
  .create(name, symbol, uri, creator)
128
174
  .accountsPartial({
@@ -132,144 +178,208 @@ export class PumpSdk {
132
178
  .instruction();
133
179
  }
134
180
 
135
- async buyInstructions(
136
- global: Global,
137
- bondingCurveAccountInfo: AccountInfo<Buffer> | null,
138
- bondingCurve: BondingCurve,
139
- mint: PublicKey,
140
- user: PublicKey,
141
- amount: BN,
142
- solAmount: BN,
143
- slippage: number,
144
- newCoinCreator: PublicKey,
145
- ): Promise<TransactionInstruction[]> {
146
- return this.withFixBondingCurve(
147
- mint,
148
- bondingCurveAccountInfo,
149
- user,
150
- async () => {
151
- const instructions: TransactionInstruction[] = [];
181
+ async buyInstructions({
182
+ global,
183
+ bondingCurveAccountInfo,
184
+ bondingCurve,
185
+ associatedUserAccountInfo,
186
+ mint,
187
+ user,
188
+ amount,
189
+ solAmount,
190
+ slippage,
191
+ }: {
192
+ global: Global;
193
+ bondingCurveAccountInfo: AccountInfo<Buffer>;
194
+ bondingCurve: BondingCurve;
195
+ associatedUserAccountInfo: AccountInfo<Buffer> | null;
196
+ mint: PublicKey;
197
+ user: PublicKey;
198
+ amount: BN;
199
+ solAmount: BN;
200
+ slippage: number;
201
+ }): Promise<TransactionInstruction[]> {
202
+ const instructions: TransactionInstruction[] = [];
203
+
204
+ if (bondingCurveAccountInfo.data.length < BONDING_CURVE_NEW_SIZE) {
205
+ instructions.push(
206
+ await this.extendAccountInstruction({
207
+ account: this.bondingCurvePda(mint),
208
+ user,
209
+ }),
210
+ );
211
+ }
152
212
 
153
- const associatedUser = getAssociatedTokenAddressSync(mint, user, true);
213
+ const associatedUser = getAssociatedTokenAddressSync(mint, user, true);
154
214
 
155
- const userTokenAccount = await getAccount(
156
- this.connection,
215
+ if (!associatedUserAccountInfo) {
216
+ instructions.push(
217
+ createAssociatedTokenAccountIdempotentInstruction(
218
+ user,
157
219
  associatedUser,
158
- ).catch((e) => null);
159
-
160
- // if user account doesn't exist add an instruction to create it
161
- if (!userTokenAccount) {
162
- instructions.push(
163
- createAssociatedTokenAccountIdempotentInstruction(
164
- user,
165
- associatedUser,
166
- user,
167
- mint,
168
- ),
169
- );
170
- }
171
-
172
- instructions.push(
173
- await this.pumpProgram.methods
174
- .buy(
175
- amount,
176
- solAmount.add(
177
- solAmount
178
- .mul(new BN(Math.floor(slippage * 10)))
179
- .div(new BN(1000)),
180
- ),
181
- )
182
- .accountsPartial({
183
- feeRecipient: getFeeRecipient(global),
184
- mint,
185
- associatedUser,
186
- user,
187
- creatorVault: this.creatorVaultPda(
188
- bondingCurveAccountInfo === null
189
- ? newCoinCreator
190
- : bondingCurve.creator,
191
- ),
192
- })
193
- .instruction(),
194
- );
195
-
196
- return instructions;
197
- },
220
+ user,
221
+ mint,
222
+ ),
223
+ );
224
+ }
225
+
226
+ instructions.push(
227
+ await this.buyInstruction({
228
+ global,
229
+ mint,
230
+ creator: bondingCurve.creator,
231
+ user,
232
+ associatedUser,
233
+ amount,
234
+ solAmount,
235
+ slippage,
236
+ }),
198
237
  );
238
+
239
+ return instructions;
199
240
  }
200
241
 
201
- async sellInstructions(
202
- global: Global,
203
- bondingCurveAccountInfo: AccountInfo<Buffer> | null,
204
- mint: PublicKey,
205
- user: PublicKey,
206
- amount: BN,
207
- solAmount: BN,
208
- slippage: number,
209
- ): Promise<TransactionInstruction[]> {
210
- return this.withFixBondingCurve(
211
- mint,
212
- bondingCurveAccountInfo,
213
- user,
214
- async () => {
215
- return [
216
- await this.pumpProgram.methods
217
- .sell(
218
- amount,
219
- solAmount.sub(
220
- solAmount
221
- .mul(new BN(Math.floor(slippage * 10)))
222
- .div(new BN(1000)),
223
- ),
224
- )
225
- .accountsPartial({
226
- feeRecipient: getFeeRecipient(global),
227
- mint,
228
- associatedUser: getAssociatedTokenAddressSync(mint, user, true),
229
- user,
230
- })
231
- .instruction(),
232
- ];
233
- },
234
- );
242
+ async createAndBuyInstructions({
243
+ global,
244
+ mint,
245
+ name,
246
+ symbol,
247
+ uri,
248
+ creator,
249
+ user,
250
+ amount,
251
+ solAmount,
252
+ }: {
253
+ global: Global;
254
+ mint: PublicKey;
255
+ name: string;
256
+ symbol: string;
257
+ uri: string;
258
+ creator: PublicKey;
259
+ user: PublicKey;
260
+ amount: BN;
261
+ solAmount: BN;
262
+ }): Promise<TransactionInstruction[]> {
263
+ const associatedUser = getAssociatedTokenAddressSync(mint, user, true);
264
+ return [
265
+ await this.createInstruction({ mint, name, symbol, uri, creator, user }),
266
+ await this.extendAccountInstruction({
267
+ account: this.bondingCurvePda(mint),
268
+ user,
269
+ }),
270
+ createAssociatedTokenAccountIdempotentInstruction(
271
+ user,
272
+ associatedUser,
273
+ user,
274
+ mint,
275
+ ),
276
+ await this.buyInstruction({
277
+ global,
278
+ mint,
279
+ creator,
280
+ user,
281
+ associatedUser,
282
+ amount,
283
+ solAmount,
284
+ slippage: 1,
285
+ }),
286
+ ];
235
287
  }
236
288
 
237
- async fixExistingBondingCurve(
238
- mint: PublicKey,
239
- bondingCurveAccountInfo: AccountInfo<Buffer> | null,
240
- user: PublicKey,
241
- ): Promise<TransactionInstruction[]> {
242
- return this.withFixBondingCurve(
243
- mint,
244
- bondingCurveAccountInfo,
245
- user,
246
- async () => [],
247
- );
289
+ private async buyInstruction({
290
+ global,
291
+ mint,
292
+ creator,
293
+ user,
294
+ associatedUser,
295
+ amount,
296
+ solAmount,
297
+ slippage,
298
+ }: {
299
+ global: Global;
300
+ mint: PublicKey;
301
+ creator: PublicKey;
302
+ user: PublicKey;
303
+ associatedUser: PublicKey;
304
+ amount: BN;
305
+ solAmount: BN;
306
+ slippage: number;
307
+ }) {
308
+ return await this.pumpProgram.methods
309
+ .buy(
310
+ amount,
311
+ solAmount.add(
312
+ solAmount.mul(new BN(Math.floor(slippage * 10))).div(new BN(1000)),
313
+ ),
314
+ )
315
+ .accountsPartial({
316
+ feeRecipient: getFeeRecipient(global),
317
+ mint,
318
+ associatedUser,
319
+ user,
320
+ creatorVault: this.creatorVaultPda(creator),
321
+ })
322
+ .instruction();
248
323
  }
249
324
 
250
- private async withFixBondingCurve(
251
- mint: PublicKey,
252
- bondingCurveAccountInfo: AccountInfo<Buffer> | null,
253
- user: PublicKey,
254
- block: () => Promise<TransactionInstruction[]>,
255
- ): Promise<TransactionInstruction[]> {
256
- if (
257
- bondingCurveAccountInfo === null ||
258
- bondingCurveAccountInfo.data.length < BONDING_CURVE_NEW_SIZE
259
- ) {
260
- return [
261
- await this.extendAccount(this.bondingCurvePda(mint), user),
262
- ...(await block()),
263
- ];
325
+ async sellInstructions({
326
+ global,
327
+ bondingCurveAccountInfo,
328
+ bondingCurve,
329
+ mint,
330
+ user,
331
+ amount,
332
+ solAmount,
333
+ slippage,
334
+ }: {
335
+ global: Global;
336
+ bondingCurveAccountInfo: AccountInfo<Buffer>;
337
+ bondingCurve: BondingCurve;
338
+ mint: PublicKey;
339
+ user: PublicKey;
340
+ amount: BN;
341
+ solAmount: BN;
342
+ slippage: number;
343
+ }): Promise<TransactionInstruction[]> {
344
+ const instructions: TransactionInstruction[] = [];
345
+
346
+ if (bondingCurveAccountInfo.data.length < BONDING_CURVE_NEW_SIZE) {
347
+ instructions.push(
348
+ await this.extendAccountInstruction({
349
+ account: this.bondingCurvePda(mint),
350
+ user,
351
+ }),
352
+ );
264
353
  }
265
354
 
266
- return await block();
355
+ instructions.push(
356
+ await this.pumpProgram.methods
357
+ .sell(
358
+ amount,
359
+ solAmount.sub(
360
+ solAmount.mul(new BN(Math.floor(slippage * 10))).div(new BN(1000)),
361
+ ),
362
+ )
363
+ .accountsPartial({
364
+ feeRecipient: getFeeRecipient(global),
365
+ mint,
366
+ associatedUser: getAssociatedTokenAddressSync(mint, user, true),
367
+ user,
368
+ creatorVault: this.creatorVaultPda(bondingCurve.creator),
369
+ })
370
+ .instruction(),
371
+ );
372
+
373
+ return instructions;
267
374
  }
268
375
 
269
- async extendAccount(
270
- account: PublicKey,
271
- user: PublicKey,
272
- ): Promise<TransactionInstruction> {
376
+ async extendAccountInstruction({
377
+ account,
378
+ user,
379
+ }: {
380
+ account: PublicKey;
381
+ user: PublicKey;
382
+ }): Promise<TransactionInstruction> {
273
383
  return this.pumpProgram.methods
274
384
  .extendAccount()
275
385
  .accountsPartial({
@@ -279,15 +389,22 @@ export class PumpSdk {
279
389
  .instruction();
280
390
  }
281
391
 
282
- async migrateInstruction(
283
- mint: PublicKey,
284
- user: PublicKey,
285
- ): Promise<TransactionInstruction> {
392
+ async migrateInstruction({
393
+ global,
394
+ mint,
395
+ user,
396
+ }: {
397
+ global: Global;
398
+ mint: PublicKey;
399
+ user: PublicKey;
400
+ }): Promise<TransactionInstruction> {
286
401
  return this.pumpProgram.methods
287
402
  .migrate()
288
403
  .accountsPartial({
289
404
  mint,
290
405
  user,
406
+ pumpAmm: this.pumpAmmSdk.programId(),
407
+ withdrawAuthority: global.withdrawAuthority,
291
408
  })
292
409
  .instruction();
293
410
  }
@@ -1,65 +0,0 @@
1
- import { PublicKey } from "@solana/web3.js";
2
- import BN from "bn.js";
3
- import {
4
- getBuySolAmountFromTokenAmount,
5
- getBuyTokenAmountFromSolAmount,
6
- } from "./bondingCurve";
7
-
8
- describe("tests", () => {
9
- let initialVirtualTokenReserves = new BN(1_073_000_000_000_000);
10
- let initialVirtualSolReserves = new BN(30_000_000_000);
11
- let initialRealTokenReserves = new BN(793_100_000_000_000);
12
- let initialRealSolReserves = new BN(0);
13
- let tokenTotalSupply = new BN(1_000_000_000_000_000);
14
-
15
- const global = {
16
- initialized: true,
17
- authority: PublicKey.default,
18
- feeRecipient: PublicKey.default,
19
- initialVirtualTokenReserves,
20
- initialVirtualSolReserves,
21
- initialRealTokenReserves,
22
- tokenTotalSupply,
23
- feeBasisPoints: new BN(95),
24
- withdrawAuthority: PublicKey.default,
25
- enableMigrate: true,
26
- poolMigrationFee: new BN(0),
27
- creatorFeeBasisPoints: new BN(5),
28
- feeRecipients: [],
29
- };
30
-
31
- const bondingCurve = {
32
- creator: PublicKey.default,
33
- virtualTokenReserves: initialVirtualTokenReserves,
34
- virtualSolReserves: initialVirtualSolReserves,
35
- realTokenReserves: initialRealTokenReserves,
36
- realSolReserves: initialRealSolReserves,
37
- tokenTotalSupply: tokenTotalSupply,
38
- complete: true,
39
- };
40
-
41
- let solAmount = new BN(10_000_000);
42
- let tokenAmount = new BN(354_008_574_488);
43
-
44
- it("getBuyTokenAmountFromSolAmount", () => {
45
- const result = getBuyTokenAmountFromSolAmount(
46
- global,
47
- bondingCurve,
48
- solAmount,
49
- true,
50
- );
51
-
52
- expect(result.toString()).toBe(tokenAmount.toString());
53
- });
54
-
55
- it("getBuySolAmountFromTokenAmount", () => {
56
- const result = getBuySolAmountFromTokenAmount(
57
- global,
58
- bondingCurve,
59
- tokenAmount,
60
- true,
61
- );
62
-
63
- expect(result.toString()).toBe(solAmount.addn(1).toString());
64
- });
65
- });