@paul.lumberwork/bonding-curve-sdk 1.0.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/README.md +484 -0
- package/dist/index.d.mts +3411 -0
- package/dist/index.d.ts +3411 -0
- package/dist/index.js +560 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +544 -0
- package/dist/index.mjs.map +1 -0
- package/idl/pump_fun_program.json +3051 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
# Pump.fun SDK
|
|
2
|
+
|
|
3
|
+
Solana program with Linear Bonding Curve for token launches, similar to pump.fun.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
- **Program ID**: `6o7oTqg2CfvcMCJTLNEJsef7c875zGpTvcnFctNAjudL`
|
|
8
|
+
- **Admin Wallet**: `7eGpbyRpcM7WpNKQtd6XkteNQWHbWXP7icZjKzNK2aTk`
|
|
9
|
+
- **Network**: Devnet / Localnet
|
|
10
|
+
|
|
11
|
+
## Token Allocation
|
|
12
|
+
|
|
13
|
+
| Allocation | Percent | Description |
|
|
14
|
+
|------------|---------|-------------|
|
|
15
|
+
| Bonding Curve | 80% | Available for trading |
|
|
16
|
+
| LP Reserve | 20% | Reserved for DEX migration |
|
|
17
|
+
|
|
18
|
+
## Trading Fees (Hardcoded)
|
|
19
|
+
|
|
20
|
+
| Fee | Percent | Recipient |
|
|
21
|
+
|-----|---------|-----------|
|
|
22
|
+
| Creator Fee | 0.5% | Token creator |
|
|
23
|
+
| Admin Fee | 0.5% | Platform admin |
|
|
24
|
+
| **Total** | **1%** | |
|
|
25
|
+
|
|
26
|
+
## Bonding Curve Formula
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Price = K × sold_supply
|
|
30
|
+
Cost = K × (s2² - s1²) / 2 / K_SCALE
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Where `K_SCALE = 10^22`
|
|
34
|
+
|
|
35
|
+
### K Value Reference
|
|
36
|
+
|
|
37
|
+
| K Value | Target SOL | Use Case |
|
|
38
|
+
|---------|------------|----------|
|
|
39
|
+
| 60 | ~2 SOL | Testing |
|
|
40
|
+
| 312 | ~10 SOL | Small launch |
|
|
41
|
+
| 2156 | ~69 SOL | pump.fun style |
|
|
42
|
+
| 3125 | ~100 SOL | Large launch |
|
|
43
|
+
|
|
44
|
+
**Formula**: `Target SOL ≈ K × 0.032`
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## SDK Usage
|
|
49
|
+
|
|
50
|
+
### Installation
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install github:lumberworks/kickdotfun-contracts-sdk
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Setup
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import * as anchor from "@coral-xyz/anchor";
|
|
60
|
+
import { Program } from "@coral-xyz/anchor";
|
|
61
|
+
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
|
62
|
+
import { PumpFunSDK, formatTokens, formatSol, PROGRAM_ID } from "pump-fun-sdk";
|
|
63
|
+
import idl from "pump-fun-sdk/idl/pump_fun_program.json";
|
|
64
|
+
|
|
65
|
+
// Setup connection and wallet
|
|
66
|
+
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
|
|
67
|
+
const wallet = new anchor.Wallet(keypair);
|
|
68
|
+
const provider = new anchor.AnchorProvider(connection, wallet, { commitment: "confirmed" });
|
|
69
|
+
|
|
70
|
+
// Create program instance
|
|
71
|
+
const program = new Program(idl as anchor.Idl, provider);
|
|
72
|
+
|
|
73
|
+
// Create SDK instance
|
|
74
|
+
const sdk = new PumpFunSDK(program, wallet);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 1. Initialize Launchpad (one-time)
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
const result = await sdk.initializeLaunchpad();
|
|
81
|
+
// Returns: "already_initialized" or transaction signature
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 2. Create Token Launch
|
|
85
|
+
|
|
86
|
+
**Default (creator = transaction signer):**
|
|
87
|
+
```typescript
|
|
88
|
+
const { txSignature, addresses, mintKeypair } = await sdk.createTokenLaunch({
|
|
89
|
+
name: "My Token",
|
|
90
|
+
symbol: "MTK",
|
|
91
|
+
uri: "https://example.com/metadata.json",
|
|
92
|
+
totalSupply: 1_000_000_000, // 1B tokens
|
|
93
|
+
k: 60, // ~2 SOL target
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const mint = mintKeypair.publicKey;
|
|
97
|
+
console.log("Mint:", mint.toString());
|
|
98
|
+
console.log("Token Launch PDA:", addresses.tokenLaunch.toString());
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**With Custom Creator Wallet:**
|
|
102
|
+
```typescript
|
|
103
|
+
import { PublicKey } from "@solana/web3.js";
|
|
104
|
+
|
|
105
|
+
const customCreator = new PublicKey("YourCreatorWalletAddress...");
|
|
106
|
+
|
|
107
|
+
const { txSignature, addresses, mintKeypair } = await sdk.createTokenLaunch({
|
|
108
|
+
name: "My Token",
|
|
109
|
+
symbol: "MTK",
|
|
110
|
+
uri: "https://example.com/metadata.json",
|
|
111
|
+
totalSupply: 1_000_000_000,
|
|
112
|
+
k: 60,
|
|
113
|
+
creatorWallet: customCreator, // Optional: receives 0.5% trading fees
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Parameters:**
|
|
118
|
+
- `name`: Token name
|
|
119
|
+
- `symbol`: Token symbol
|
|
120
|
+
- `uri`: Metadata URI
|
|
121
|
+
- `totalSupply`: Total supply in tokens (e.g., 1B)
|
|
122
|
+
- `k`: K value for bonding curve
|
|
123
|
+
- `creatorWallet`: (Optional) Custom creator wallet to receive trading fees. Defaults to SDK wallet if not provided.
|
|
124
|
+
|
|
125
|
+
**Returns:**
|
|
126
|
+
- `txSignature`: Transaction hash
|
|
127
|
+
- `addresses.mint`: Token mint address
|
|
128
|
+
- `addresses.tokenLaunch`: Token launch PDA
|
|
129
|
+
- `addresses.bondingCurve`: Bonding curve PDA
|
|
130
|
+
- `addresses.vault`: SOL vault PDA
|
|
131
|
+
- `mintKeypair`: Keypair of the new token
|
|
132
|
+
|
|
133
|
+
**Note:** The creator wallet will receive 0.5% of all trading fees (buy/sell). Use `creatorWallet` parameter if you want fees to go to a different address than the transaction signer.
|
|
134
|
+
|
|
135
|
+
### 3. Buy Tokens
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
const result = await sdk.buy(mint, 0.5, { computeUnits: 400_000 });
|
|
139
|
+
|
|
140
|
+
console.log("Tokens received:", formatTokens(result.tokensTraded));
|
|
141
|
+
console.log("Progress:", result.newProgress.toFixed(2) + "%");
|
|
142
|
+
console.log("Curve complete:", result.isCurveComplete);
|
|
143
|
+
console.log("Tx:", result.txSignature);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Parameters:**
|
|
147
|
+
- `mint`: Token mint address (PublicKey)
|
|
148
|
+
- `solAmount`: SOL to spend (number, e.g., 0.5 for 0.5 SOL)
|
|
149
|
+
- `options.computeUnits`: Optional compute budget (default: none)
|
|
150
|
+
|
|
151
|
+
**Returns:**
|
|
152
|
+
- `txSignature`: Transaction hash
|
|
153
|
+
- `tokensTraded`: Tokens received (bigint, raw with 6 decimals)
|
|
154
|
+
- `solTraded`: SOL spent (bigint, lamports)
|
|
155
|
+
- `newProgress`: Progress percentage (0-100)
|
|
156
|
+
- `isCurveComplete`: True if 80% sold
|
|
157
|
+
|
|
158
|
+
### 4. Sell Tokens
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const result = await sdk.sell(mint, 10_000_000, 0, { computeUnits: 400_000 });
|
|
162
|
+
|
|
163
|
+
console.log("SOL received:", formatSol(result.solTraded));
|
|
164
|
+
console.log("Progress:", result.newProgress.toFixed(2) + "%");
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Parameters:**
|
|
168
|
+
- `mint`: Token mint address (PublicKey)
|
|
169
|
+
- `tokenAmount`: Tokens to sell (number, e.g., 10_000_000 for 10M)
|
|
170
|
+
- `minSolOut`: Minimum SOL to receive, slippage protection (default: 0)
|
|
171
|
+
- `options.computeUnits`: Optional compute budget
|
|
172
|
+
|
|
173
|
+
### 5. Estimate Buy
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
const estimate = await sdk.estimateBuy(mint, 0.5);
|
|
177
|
+
|
|
178
|
+
console.log("Tokens out:", formatTokens(estimate.tokensOut));
|
|
179
|
+
console.log("Fee (1%):", formatSol(estimate.feeAmount));
|
|
180
|
+
console.log("Price impact:", estimate.priceImpactBps, "bps");
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 6. Estimate Sell
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const estimate = await sdk.estimateSell(mint, 10_000_000);
|
|
187
|
+
|
|
188
|
+
console.log("SOL out:", formatSol(estimate.solCost));
|
|
189
|
+
console.log("Fee (1%):", formatSol(estimate.feeAmount));
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 7. Get Progress
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const progress = await sdk.getProgress(mint);
|
|
196
|
+
|
|
197
|
+
console.log("Progress:", progress.percent + "%");
|
|
198
|
+
console.log("SOL raised:", formatSol(progress.solRaised));
|
|
199
|
+
console.log("Current price:", progress.currentPrice.toString(), "lamports/token");
|
|
200
|
+
console.log("Complete:", progress.isComplete);
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 8. Get Curve State
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const curve = await sdk.getCurveState(mint);
|
|
207
|
+
|
|
208
|
+
console.log("K:", curve.k.toString());
|
|
209
|
+
console.log("Sold:", formatTokens(curve.soldSupply));
|
|
210
|
+
console.log("Available:", formatTokens(curve.tokensForCurve));
|
|
211
|
+
console.log("SOL reserves:", formatSol(curve.realSolReserves));
|
|
212
|
+
console.log("Complete:", curve.complete);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 9. Get Token Launch State
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
const launch = await sdk.getTokenLaunchState(mint);
|
|
219
|
+
|
|
220
|
+
console.log("Name:", launch.name, `(${launch.symbol})`);
|
|
221
|
+
console.log("Creator:", launch.creator.toString());
|
|
222
|
+
console.log("Trading active:", launch.tradingActive);
|
|
223
|
+
console.log("Migrated:", launch.migrated);
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 10. Admin Withdraw (Admin Only)
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// Only ADMIN_WALLET can call this
|
|
230
|
+
if (wallet.publicKey.equals(ADMIN_WALLET)) {
|
|
231
|
+
const result = await sdk.adminWithdraw(mint);
|
|
232
|
+
console.log("SOL withdrawn:", formatSol(result.solWithdrawn));
|
|
233
|
+
console.log("LP tokens:", formatTokens(result.tokensWithdrawn));
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Requirements:**
|
|
238
|
+
- Caller must be `ADMIN_WALLET`
|
|
239
|
+
- Curve must be complete (80% sold)
|
|
240
|
+
- Token not already migrated
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Event Listeners
|
|
245
|
+
|
|
246
|
+
Subscribe to real-time events from the Pump.fun program.
|
|
247
|
+
|
|
248
|
+
### Available Events
|
|
249
|
+
|
|
250
|
+
| Event | Description |
|
|
251
|
+
|-------|-------------|
|
|
252
|
+
| `LaunchCreated` | New token launch created |
|
|
253
|
+
| `TokensPurchased` | Tokens bought on bonding curve |
|
|
254
|
+
| `TokensSold` | Tokens sold on bonding curve |
|
|
255
|
+
| `CurveComplete` | Bonding curve reached 100% |
|
|
256
|
+
| `AdminWithdraw` | Admin withdrew SOL + LP tokens |
|
|
257
|
+
|
|
258
|
+
### Listen for Token Purchases
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// Subscribe to buy events
|
|
262
|
+
const listenerId = sdk.onTokensPurchased((event, slot, signature) => {
|
|
263
|
+
console.log("Buy Event:", {
|
|
264
|
+
buyer: event.buyer.toString(),
|
|
265
|
+
mint: event.mint.toString(),
|
|
266
|
+
tokensReceived: formatTokens(event.tokensReceived),
|
|
267
|
+
solSpent: formatSol(event.solAmount),
|
|
268
|
+
progress: event.progress + "%",
|
|
269
|
+
complete: event.isCurveComplete,
|
|
270
|
+
slot,
|
|
271
|
+
signature,
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Unsubscribe when done
|
|
276
|
+
await sdk.removeEventListener(listenerId);
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Listen for Token Sales
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
const listenerId = sdk.onTokensSold((event, slot, signature) => {
|
|
283
|
+
console.log("Sell Event:", {
|
|
284
|
+
seller: event.seller.toString(),
|
|
285
|
+
tokensSold: formatTokens(event.tokensSold),
|
|
286
|
+
solReceived: formatSol(event.netSolRefund),
|
|
287
|
+
progress: event.progress + "%",
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Listen for New Launches
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
sdk.onLaunchCreated((event, slot, signature) => {
|
|
296
|
+
console.log("New Launch:", {
|
|
297
|
+
name: event.name,
|
|
298
|
+
symbol: event.symbol,
|
|
299
|
+
mint: event.mint.toString(),
|
|
300
|
+
creator: event.creator.toString(),
|
|
301
|
+
totalSupply: formatTokens(event.totalSupply),
|
|
302
|
+
initialK: event.initialK.toString(),
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Listen for Curve Completion
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
sdk.onCurveComplete((event, slot, signature) => {
|
|
311
|
+
console.log("Curve Complete!", {
|
|
312
|
+
mint: event.mint.toString(),
|
|
313
|
+
totalSolRaised: formatSol(event.totalSolRaised),
|
|
314
|
+
finalPrice: event.finalPrice.toString(),
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Listen for Admin Withdrawals
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
sdk.onAdminWithdraw((event, slot, signature) => {
|
|
323
|
+
console.log("Admin Withdrawal:", {
|
|
324
|
+
mint: event.mint.toString(),
|
|
325
|
+
solWithdrawn: formatSol(event.solWithdrawn),
|
|
326
|
+
tokensWithdrawn: formatTokens(event.tokensWithdrawn),
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Complete Event Listener Example
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
import { PumpFunSDK, formatTokens, formatSol } from "pump-fun-sdk";
|
|
335
|
+
|
|
336
|
+
async function watchToken(sdk: PumpFunSDK, mint: PublicKey) {
|
|
337
|
+
// Track buys
|
|
338
|
+
const buyListener = sdk.onTokensPurchased((event, slot, sig) => {
|
|
339
|
+
if (event.mint.equals(mint)) {
|
|
340
|
+
console.log(`[Buy] ${formatTokens(event.tokensReceived)} tokens bought`);
|
|
341
|
+
|
|
342
|
+
if (event.isCurveComplete) {
|
|
343
|
+
console.log("🎉 Curve completed!");
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
// Track sells
|
|
349
|
+
const sellListener = sdk.onTokensSold((event, slot, sig) => {
|
|
350
|
+
if (event.mint.equals(mint)) {
|
|
351
|
+
console.log(`[Sell] ${formatTokens(event.tokensSold)} tokens sold`);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Wait for curve completion
|
|
356
|
+
const completeListener = sdk.onCurveComplete((event, slot, sig) => {
|
|
357
|
+
if (event.mint.equals(mint)) {
|
|
358
|
+
console.log(`Curve complete! Total raised: ${formatSol(event.totalSolRaised)} SOL`);
|
|
359
|
+
|
|
360
|
+
// Clean up listeners
|
|
361
|
+
sdk.removeEventListener(buyListener);
|
|
362
|
+
sdk.removeEventListener(sellListener);
|
|
363
|
+
sdk.removeEventListener(completeListener);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Utility Functions
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
import { formatTokens, formatSol, parseSol, parseTokens } from "./sdk";
|
|
375
|
+
|
|
376
|
+
// Format raw values to readable strings
|
|
377
|
+
formatTokens(1000000000000n); // "1,000,000" (1M tokens)
|
|
378
|
+
formatSol(500000000n); // "0.5000" (0.5 SOL)
|
|
379
|
+
|
|
380
|
+
// Parse human values to raw
|
|
381
|
+
parseSol(0.5); // 500000000n (lamports)
|
|
382
|
+
parseTokens(1000000); // 1000000000000n (raw with 6 decimals)
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Constants
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import { ADMIN_WALLET, K_SCALE, TOKEN_DECIMALS, FEE_BPS } from "./sdk";
|
|
391
|
+
|
|
392
|
+
ADMIN_WALLET // PublicKey: "7eGpbyRpcM7WpNKQtd6XkteNQWHbWXP7icZjKzNK2aTk"
|
|
393
|
+
K_SCALE // 10^22 (bigint)
|
|
394
|
+
TOKEN_DECIMALS // 6
|
|
395
|
+
FEE_BPS // 100 (1%)
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## PDA Seeds
|
|
401
|
+
|
|
402
|
+
| PDA | Seeds |
|
|
403
|
+
|-----|-------|
|
|
404
|
+
| Launchpad | `["launchpad"]` |
|
|
405
|
+
| Token Launch | `["token_launch", mint]` |
|
|
406
|
+
| Bonding Curve | `["bonding_curve", token_launch]` |
|
|
407
|
+
| Vault | `["vault", token_launch]` |
|
|
408
|
+
| User Position | `["user_position", token_launch, user]` |
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## Full Example
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
import * as anchor from "@coral-xyz/anchor";
|
|
416
|
+
import { Program } from "@coral-xyz/anchor";
|
|
417
|
+
import { PumpFunProgram } from "./target/types/pump_fun_program";
|
|
418
|
+
import { PumpFunSDK, formatTokens, formatSol, ADMIN_WALLET } from "./sdk";
|
|
419
|
+
|
|
420
|
+
async function main() {
|
|
421
|
+
const provider = anchor.AnchorProvider.env();
|
|
422
|
+
anchor.setProvider(provider);
|
|
423
|
+
const program = anchor.workspace.PumpFunProgram as Program<PumpFunProgram>;
|
|
424
|
+
const wallet = provider.wallet as anchor.Wallet;
|
|
425
|
+
const sdk = new PumpFunSDK(program, wallet);
|
|
426
|
+
|
|
427
|
+
// 1. Initialize launchpad
|
|
428
|
+
await sdk.initializeLaunchpad();
|
|
429
|
+
|
|
430
|
+
// 2. Create token
|
|
431
|
+
const { addresses, mintKeypair } = await sdk.createTokenLaunch({
|
|
432
|
+
name: "Test Token",
|
|
433
|
+
symbol: "TEST",
|
|
434
|
+
uri: "https://example.com/metadata.json",
|
|
435
|
+
totalSupply: 1_000_000_000,
|
|
436
|
+
k: 60,
|
|
437
|
+
});
|
|
438
|
+
const mint = mintKeypair.publicKey;
|
|
439
|
+
|
|
440
|
+
// 3. Buy tokens
|
|
441
|
+
const buy = await sdk.buy(mint, 0.5, { computeUnits: 400_000 });
|
|
442
|
+
console.log("Bought:", formatTokens(buy.tokensTraded));
|
|
443
|
+
|
|
444
|
+
// 4. Sell tokens
|
|
445
|
+
const sell = await sdk.sell(mint, 10_000_000, 0, { computeUnits: 400_000 });
|
|
446
|
+
console.log("Sold for:", formatSol(sell.solTraded), "SOL");
|
|
447
|
+
|
|
448
|
+
// 5. Check progress
|
|
449
|
+
const progress = await sdk.getProgress(mint);
|
|
450
|
+
console.log("Progress:", progress.percent + "%");
|
|
451
|
+
|
|
452
|
+
// 6. Admin withdraw (when curve complete)
|
|
453
|
+
if (progress.isComplete && wallet.publicKey.equals(ADMIN_WALLET)) {
|
|
454
|
+
const withdraw = await sdk.adminWithdraw(mint);
|
|
455
|
+
console.log("Withdrawn:", formatSol(withdraw.solWithdrawn), "SOL");
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
main().catch(console.error);
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Running Tests
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
# Start local validator
|
|
468
|
+
solana-test-validator --reset
|
|
469
|
+
|
|
470
|
+
# In another terminal
|
|
471
|
+
cd pump_fun_program
|
|
472
|
+
anchor build && anchor deploy
|
|
473
|
+
|
|
474
|
+
# Run test
|
|
475
|
+
ANCHOR_PROVIDER_URL=http://127.0.0.1:8899 \
|
|
476
|
+
ANCHOR_WALLET=./test-keypair.json \
|
|
477
|
+
npx ts-node test-sdk.ts
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
## License
|
|
483
|
+
|
|
484
|
+
MIT
|