@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 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