@paul.lumberwork/bonding-curve-sdk 1.3.0 → 1.5.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/dist/index.js CHANGED
@@ -237,7 +237,7 @@ var KickFunSDK = class {
237
237
  };
238
238
  }
239
239
  // ═══════════════════════════════════════════════════════════════════════════
240
- // Estimate Buy (tokens received for SOL)
240
+ // Estimate Buy (input SOL output tokens)
241
241
  // ═══════════════════════════════════════════════════════════════════════════
242
242
  async estimateBuy(mint, solAmount) {
243
243
  const addresses = this.deriveAddresses(mint);
@@ -245,27 +245,45 @@ var KickFunSDK = class {
245
245
  const k = BigInt(curve.k.toString());
246
246
  const soldSupply = BigInt(curve.soldSupply.toString());
247
247
  const tokensForCurve = BigInt(curve.tokensForCurve.toString());
248
- const solLamports = BigInt(Math.floor(solAmount * web3_js.LAMPORTS_PER_SOL));
249
- const feeAmount = solLamports / 100n;
250
- const solAfterFees = solLamports - feeAmount;
251
- const tokensOut = this.calculateTokensForSol(k, soldSupply, solAfterFees);
248
+ const solIn = BigInt(Math.floor(solAmount * web3_js.LAMPORTS_PER_SOL));
249
+ const fee = solIn / 100n;
250
+ const solAfterFee = solIn - fee;
251
+ const tokensOut = this.calculateTokensForSol(k, soldSupply, solAfterFee);
252
252
  const available = tokensForCurve - soldSupply;
253
253
  const actualTokensOut = tokensOut > available ? available : tokensOut;
254
- const pricePerToken = solAfterFees / (actualTokensOut / BigInt(10 ** TOKEN_DECIMALS));
254
+ const tokenUnits = actualTokensOut / BigInt(10 ** TOKEN_DECIMALS);
255
+ const pricePerToken = tokenUnits > 0n ? solAfterFee / tokenUnits : 0n;
255
256
  const newSoldSupply = soldSupply + actualTokensOut;
256
257
  const priceBefore = this.calculatePrice(k, soldSupply);
257
258
  const priceAfter = this.calculatePrice(k, newSoldSupply);
258
259
  const priceImpactBps = priceBefore > 0n ? Number((priceAfter - priceBefore) * 10000n / priceBefore) : 0;
259
- return {
260
- tokensOut: actualTokensOut,
261
- solCost: solLamports,
262
- pricePerToken,
263
- priceImpactBps,
264
- feeAmount
265
- };
260
+ return { solIn, solAfterFee, tokensOut: actualTokensOut, fee, pricePerToken, priceImpactBps };
266
261
  }
267
262
  // ═══════════════════════════════════════════════════════════════════════════
268
- // Estimate Sell (SOL received for tokens)
263
+ // Estimate Buy by Tokens (input tokens output SOL needed)
264
+ // ═══════════════════════════════════════════════════════════════════════════
265
+ async estimateBuyByTokens(mint, tokenAmount) {
266
+ const addresses = this.deriveAddresses(mint);
267
+ const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);
268
+ const k = BigInt(curve.k.toString());
269
+ const soldSupply = BigInt(curve.soldSupply.toString());
270
+ const tokensForCurve = BigInt(curve.tokensForCurve.toString());
271
+ const tokensRaw = BigInt(tokenAmount) * BigInt(10 ** TOKEN_DECIMALS);
272
+ const available = tokensForCurve - soldSupply;
273
+ const actualTokensOut = tokensRaw > available ? available : tokensRaw;
274
+ const solAfterFee = this.calculateCost(k, soldSupply, soldSupply + actualTokensOut);
275
+ const solIn = solAfterFee * 100n / 99n;
276
+ const fee = solIn - solAfterFee;
277
+ const tokenUnits = actualTokensOut / BigInt(10 ** TOKEN_DECIMALS);
278
+ const pricePerToken = tokenUnits > 0n ? solAfterFee / tokenUnits : 0n;
279
+ const newSoldSupply = soldSupply + actualTokensOut;
280
+ const priceBefore = this.calculatePrice(k, soldSupply);
281
+ const priceAfter = this.calculatePrice(k, newSoldSupply);
282
+ const priceImpactBps = priceBefore > 0n ? Number((priceAfter - priceBefore) * 10000n / priceBefore) : 0;
283
+ return { solIn, solAfterFee, tokensOut: actualTokensOut, fee, pricePerToken, priceImpactBps };
284
+ }
285
+ // ═══════════════════════════════════════════════════════════════════════════
286
+ // Estimate Sell (input tokens → output SOL)
269
287
  // ═══════════════════════════════════════════════════════════════════════════
270
288
  async estimateSell(mint, tokenAmount) {
271
289
  const addresses = this.deriveAddresses(mint);
@@ -273,28 +291,46 @@ var KickFunSDK = class {
273
291
  const k = BigInt(curve.k.toString());
274
292
  const soldSupply = BigInt(curve.soldSupply.toString());
275
293
  const realSolReserves = BigInt(curve.realSolReserves.toString());
276
- const tokensRaw = BigInt(tokenAmount) * BigInt(10 ** TOKEN_DECIMALS);
277
- if (tokensRaw > soldSupply) {
294
+ const tokensIn = BigInt(tokenAmount) * BigInt(10 ** TOKEN_DECIMALS);
295
+ if (tokensIn > soldSupply) {
278
296
  throw new Error(`Cannot sell ${tokenAmount} tokens. Only ${soldSupply / BigInt(10 ** TOKEN_DECIMALS)} available.`);
279
297
  }
280
- const grossRefund = this.calculateRefund(k, soldSupply, soldSupply - tokensRaw);
281
- const cappedRefund = grossRefund > realSolReserves ? realSolReserves : grossRefund;
282
- const feeAmount = cappedRefund / 100n;
283
- const netSolOut = cappedRefund - feeAmount;
284
- const pricePerToken = netSolOut / BigInt(tokenAmount);
285
- const newSoldSupply = soldSupply - tokensRaw;
298
+ const grossRefund = this.calculateRefund(k, soldSupply, soldSupply - tokensIn);
299
+ const solBeforeFee = grossRefund > realSolReserves ? realSolReserves : grossRefund;
300
+ const fee = solBeforeFee / 100n;
301
+ const solOut = solBeforeFee - fee;
302
+ const pricePerToken = tokenAmount > 0 ? solOut / BigInt(tokenAmount) : 0n;
303
+ const newSoldSupply = soldSupply - tokensIn;
286
304
  const priceBefore = this.calculatePrice(k, soldSupply);
287
305
  const priceAfter = this.calculatePrice(k, newSoldSupply);
288
306
  const priceImpactBps = priceBefore > 0n ? Number((priceBefore - priceAfter) * 10000n / priceBefore) : 0;
289
- return {
290
- tokensOut: tokensRaw,
291
- // tokens being sold
292
- solCost: netSolOut,
293
- // SOL to receive
294
- pricePerToken,
295
- priceImpactBps,
296
- feeAmount
297
- };
307
+ return { tokensIn, solBeforeFee, solOut, fee, pricePerToken, priceImpactBps };
308
+ }
309
+ // ═══════════════════════════════════════════════════════════════════════════
310
+ // Estimate Sell by SOL (input SOL desired → output tokens to sell)
311
+ // ═══════════════════════════════════════════════════════════════════════════
312
+ async estimateSellBySol(mint, solAmount) {
313
+ const addresses = this.deriveAddresses(mint);
314
+ const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);
315
+ const k = BigInt(curve.k.toString());
316
+ const soldSupply = BigInt(curve.soldSupply.toString());
317
+ const realSolReserves = BigInt(curve.realSolReserves.toString());
318
+ const solDesired = BigInt(Math.floor(solAmount * web3_js.LAMPORTS_PER_SOL));
319
+ const solBeforeFee = solDesired * 100n / 99n;
320
+ const cappedGross = solBeforeFee > realSolReserves ? realSolReserves : solBeforeFee;
321
+ const tokensIn = this.calculateTokensForSolSell(k, soldSupply, cappedGross);
322
+ const actualTokensIn = tokensIn > soldSupply ? soldSupply : tokensIn;
323
+ const actualGross = this.calculateRefund(k, soldSupply, soldSupply - actualTokensIn);
324
+ const actualSolBeforeFee = actualGross > realSolReserves ? realSolReserves : actualGross;
325
+ const fee = actualSolBeforeFee / 100n;
326
+ const solOut = actualSolBeforeFee - fee;
327
+ const tokenUnits = actualTokensIn / BigInt(10 ** TOKEN_DECIMALS);
328
+ const pricePerToken = tokenUnits > 0n ? solOut / tokenUnits : 0n;
329
+ const newSoldSupply = soldSupply - actualTokensIn;
330
+ const priceBefore = this.calculatePrice(k, soldSupply);
331
+ const priceAfter = this.calculatePrice(k, newSoldSupply);
332
+ const priceImpactBps = priceBefore > 0n ? Number((priceBefore - priceAfter) * 10000n / priceBefore) : 0;
333
+ return { tokensIn: actualTokensIn, solBeforeFee: actualSolBeforeFee, solOut, fee, pricePerToken, priceImpactBps };
298
334
  }
299
335
  // ═══════════════════════════════════════════════════════════════════════════
300
336
  // Get Curve State
@@ -497,6 +533,17 @@ var KickFunSDK = class {
497
533
  const s2 = this.isqrt(s2Sq);
498
534
  return s2 - currentSupply;
499
535
  }
536
+ /** Calculate tokens to sell to receive target SOL: inverse of refund formula
537
+ * s2 = sqrt(s1² - 2×solOut×K_SCALE/k), return s1 - s2 */
538
+ calculateTokensForSolSell(k, currentSupply, solOut) {
539
+ if (solOut === 0n || k === 0n) return 0n;
540
+ const s1Sq = currentSupply * currentSupply;
541
+ const subtraction = 2n * solOut * K_SCALE / k;
542
+ if (subtraction >= s1Sq) return currentSupply;
543
+ const s2Sq = s1Sq - subtraction;
544
+ const s2 = this.isqrt(s2Sq);
545
+ return currentSupply - s2;
546
+ }
500
547
  /** Calculate refund for selling tokens: refund = (k/2) × (s1² - s2²) / K_SCALE */
501
548
  calculateRefund(k, s1, s2) {
502
549
  if (s1 <= s2) return 0n;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sdk/index.ts"],"names":["PublicKey","LAMPORTS_PER_SOL","getAssociatedTokenAddressSync","SystemProgram","Keypair","TOKEN_PROGRAM_ID","ASSOCIATED_TOKEN_PROGRAM_ID","SYSVAR_RENT_PUBKEY","getAccount","BN","ComputeBudgetProgram"],"mappings":"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","file":"index.js","sourcesContent":["import * as anchor from \"@coral-xyz/anchor\";\nimport { Program, BN } from \"@coral-xyz/anchor\";\nimport { KickFunProgram } from \"../types/kick_fun_program\";\nimport {\n Keypair,\n SystemProgram,\n PublicKey,\n LAMPORTS_PER_SOL,\n ComputeBudgetProgram,\n Connection,\n TransactionInstruction,\n SYSVAR_RENT_PUBKEY,\n} from \"@solana/web3.js\";\nimport {\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n getAssociatedTokenAddressSync,\n getAccount,\n} from \"@solana/spl-token\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Constants\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport const PROGRAM_ID = new PublicKey(\"6o7oTqg2CfvcMCJTLNEJsef7c875zGpTvcnFctNAjudL\");\nexport const ADMIN_WALLET = new PublicKey(\"7eGpbyRpcM7WpNKQtd6XkteNQWHbWXP7icZjKzNK2aTk\");\nexport const METADATA_PROGRAM_ID = new PublicKey(\"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s\");\nexport const K_SCALE = 10_000_000_000_000_000_000_000n; // 10^22\nexport const LAMPORTS = LAMPORTS_PER_SOL;\nexport const TOKEN_DECIMALS = 6;\nexport const FEE_BPS = 100; // 1% total fee (0.5% admin immediate + 0.5% accumulated)\nexport const CURVE_PERCENT = 70; // 70% for bonding curve\nexport const LP_PERCENT = 20; // 20% for LP\nexport const TREASURY_PERCENT = 10; // 10% for treasury\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface TokenLaunchConfig {\n name: string;\n symbol: string;\n uri: string;\n creatorWallet?: PublicKey; // Optional: custom creator wallet, defaults to SDK wallet\n}\n\nexport interface BondingCurveState {\n tokenLaunch: PublicKey;\n k: bigint;\n totalSupply: bigint;\n soldSupply: bigint;\n realSolReserves: bigint;\n tokenReservesForLp: bigint;\n tokenReservesForTreasury: bigint;\n tokensForCurve: bigint;\n accumulatedFees: bigint;\n complete: boolean;\n bump: number;\n}\n\nexport interface TokenLaunchState {\n creator: PublicKey;\n mint: PublicKey;\n vault: PublicKey;\n bondingCurve: PublicKey;\n totalSupply: bigint;\n curveAllocation: bigint;\n lpAllocation: bigint;\n treasuryAllocation: bigint;\n totalSolRaised: bigint;\n tradingActive: boolean;\n migrated: boolean;\n initialK: bigint;\n name: string;\n symbol: string;\n}\n\nexport interface LaunchAddresses {\n mint: PublicKey;\n tokenLaunch: PublicKey;\n bondingCurve: PublicKey;\n vault: PublicKey;\n curveTokenAccount: PublicKey;\n metadata: PublicKey; // Metaplex metadata PDA\n}\n\nexport interface TradeResult {\n txSignature: string;\n tokensTraded: bigint;\n solTraded: bigint;\n newProgress: number;\n isCurveComplete: boolean;\n}\n\nexport interface EstimateResult {\n tokensOut: bigint;\n solCost: bigint;\n pricePerToken: bigint;\n priceImpactBps: number;\n feeAmount: bigint;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Event Types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface LaunchCreatedEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n creator: PublicKey;\n name: string;\n symbol: string;\n totalSupply: bigint;\n curveAllocation: bigint;\n lpAllocation: bigint;\n treasuryAllocation: bigint;\n initialK: bigint;\n initialPrice: bigint;\n timestamp: bigint;\n}\n\nexport interface TokensPurchasedEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n buyer: PublicKey;\n solAmount: bigint;\n solAfterFees: bigint;\n tokensReceived: bigint;\n curveFee: bigint;\n adminFee: bigint;\n priceAfter: bigint;\n totalSold: bigint;\n progress: number;\n timestamp: bigint;\n isCurveComplete: boolean;\n}\n\nexport interface TokensSoldEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n seller: PublicKey;\n tokensSold: bigint;\n grossSolRefund: bigint;\n netSolRefund: bigint;\n curveFee: bigint;\n adminFee: bigint;\n priceAfter: bigint;\n totalSold: bigint;\n progress: number;\n timestamp: bigint;\n}\n\nexport interface CurveCompleteEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n totalSolRaised: bigint;\n finalPrice: bigint;\n timestamp: bigint;\n}\n\nexport interface AdminWithdrawEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n admin: PublicKey;\n creator: PublicKey;\n treasury: PublicKey;\n solWithdrawn: bigint;\n tokensWithdrawn: bigint;\n feesToTreasury: bigint;\n treasuryTokens: bigint;\n timestamp: bigint;\n}\n\nexport type KickFunEvent =\n | { name: \"LaunchCreated\"; data: LaunchCreatedEvent }\n | { name: \"TokensPurchased\"; data: TokensPurchasedEvent }\n | { name: \"TokensSold\"; data: TokensSoldEvent }\n | { name: \"CurveComplete\"; data: CurveCompleteEvent }\n | { name: \"AdminWithdraw\"; data: AdminWithdrawEvent };\n\nexport type EventCallback<T> = (event: T, slot: number, signature: string) => void;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// KickFunSDK Class\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport class KickFunSDK {\n public program: Program<KickFunProgram>;\n public connection: Connection;\n public wallet: anchor.Wallet;\n public launchpadPda: PublicKey;\n\n constructor(\n program: Program<KickFunProgram>,\n wallet: anchor.Wallet\n ) {\n this.program = program;\n this.connection = program.provider.connection;\n this.wallet = wallet;\n\n [this.launchpadPda] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"launchpad\")],\n program.programId\n );\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // PDA Derivation Helpers\n // ═══════════════════════════════════════════════════════════════════════════\n\n deriveAddresses(mint: PublicKey): LaunchAddresses {\n const [tokenLaunch] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"token_launch\"), mint.toBuffer()],\n this.program.programId\n );\n const [bondingCurve] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"bonding_curve\"), tokenLaunch.toBuffer()],\n this.program.programId\n );\n const [vault] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"vault\"), tokenLaunch.toBuffer()],\n this.program.programId\n );\n const curveTokenAccount = getAssociatedTokenAddressSync(mint, bondingCurve, true);\n\n // Metaplex metadata PDA\n const [metadata] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"metadata\"), METADATA_PROGRAM_ID.toBuffer(), mint.toBuffer()],\n METADATA_PROGRAM_ID\n );\n\n return { mint, tokenLaunch, bondingCurve, vault, curveTokenAccount, metadata };\n }\n\n deriveUserPosition(tokenLaunch: PublicKey, user: PublicKey): PublicKey {\n const [userPosition] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"user_position\"), tokenLaunch.toBuffer(), user.toBuffer()],\n this.program.programId\n );\n return userPosition;\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Initialize Launchpad (one-time setup)\n // ═══════════════════════════════════════════════════════════════════════════\n\n async initializeLaunchpad(platformFeeBps: number = 200): Promise<string> {\n try {\n await this.program.account.launchpad.fetch(this.launchpadPda);\n return \"already_initialized\";\n } catch {\n const tx = await this.program.methods\n .initializeLaunchpad(platformFeeBps)\n .accountsPartial({\n authority: this.wallet.publicKey,\n launchpad: this.launchpadPda,\n treasury: this.wallet.publicKey,\n systemProgram: SystemProgram.programId,\n })\n .rpc();\n return tx;\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Create Token Launch\n // ═══════════════════════════════════════════════════════════════════════════\n\n async createTokenLaunch(config: TokenLaunchConfig): Promise<{\n txSignature: string;\n addresses: LaunchAddresses;\n mintKeypair: Keypair;\n }> {\n const mintKeypair = Keypair.generate();\n const addresses = this.deriveAddresses(mintKeypair.publicKey);\n\n // Use custom creator wallet or default to SDK wallet\n const creatorWallet = config.creatorWallet || this.wallet.publicKey;\n\n const tx = await this.program.methods\n .createTokenLaunch(config.name, config.symbol, config.uri)\n .accountsPartial({\n creator: creatorWallet,\n launchpad: this.launchpadPda,\n mint: mintKeypair.publicKey,\n tokenLaunch: addresses.tokenLaunch,\n bondingCurve: addresses.bondingCurve,\n vault: addresses.vault,\n curveTokenAccount: addresses.curveTokenAccount,\n metadata: addresses.metadata,\n tokenProgram: TOKEN_PROGRAM_ID,\n associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,\n metadataProgram: METADATA_PROGRAM_ID,\n systemProgram: SystemProgram.programId,\n rent: SYSVAR_RENT_PUBKEY,\n })\n .signers([mintKeypair])\n .transaction();\n\n const { blockhash } = await this.connection.getLatestBlockhash();\n tx.recentBlockhash = blockhash;\n tx.feePayer = this.wallet.publicKey;\n tx.partialSign(mintKeypair);\n const signedTx = await this.wallet.signTransaction(tx);\n const txSignature = await this.connection.sendRawTransaction(signedTx.serialize(), {\n skipPreflight: true,\n });\n\n await this.connection.confirmTransaction({\n signature: txSignature,\n ...(await this.connection.getLatestBlockhash()),\n });\n \n return { txSignature, addresses, mintKeypair };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Buy Tokens\n // ═══════════════════════════════════════════════════════════════════════════\n\n async buy(\n mint: PublicKey,\n solAmount: number, // In SOL (e.g., 1.5 for 1.5 SOL)\n options?: { computeUnits?: number }\n ): Promise<TradeResult> {\n const addresses = this.deriveAddresses(mint);\n const userTokenAccount = getAssociatedTokenAddressSync(mint, this.wallet.publicKey);\n const userPosition = this.deriveUserPosition(addresses.tokenLaunch, this.wallet.publicKey);\n\n // Get state before\n const curveBefore = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n let tokensBefore = 0n;\n try {\n const account = await getAccount(this.connection, userTokenAccount);\n tokensBefore = account.amount;\n } catch {\n // Account doesn't exist yet\n }\n\n const solLamports = new BN(Math.floor(solAmount * LAMPORTS_PER_SOL));\n\n const preInstructions: TransactionInstruction[] = [];\n if (options?.computeUnits) {\n preInstructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({ units: options.computeUnits })\n );\n }\n\n const tx = await this.program.methods\n .buyTokens(solLamports)\n .accountsPartial({\n contributor: this.wallet.publicKey,\n launchpad: this.launchpadPda,\n adminWallet: ADMIN_WALLET,\n tokenLaunch: addresses.tokenLaunch,\n bondingCurve: addresses.bondingCurve,\n mint: mint,\n vault: addresses.vault,\n curveTokenAccount: addresses.curveTokenAccount,\n userTokenAccount: userTokenAccount,\n userPosition: userPosition,\n systemProgram: SystemProgram.programId,\n tokenProgram: TOKEN_PROGRAM_ID,\n associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,\n })\n .preInstructions(preInstructions)\n .rpc();\n\n // Get state after\n const curveAfter = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n const tokensAfter = (await getAccount(this.connection, userTokenAccount)).amount;\n\n const tokensReceived = tokensAfter - tokensBefore;\n const progress = Number(curveAfter.soldSupply.toString()) / Number(curveAfter.tokensForCurve.toString()) * 100;\n\n return {\n txSignature: tx,\n tokensTraded: tokensReceived,\n solTraded: BigInt(solLamports.toString()),\n newProgress: progress,\n isCurveComplete: curveAfter.complete,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Sell Tokens\n // ═══════════════════════════════════════════════════════════════════════════\n\n async sell(\n mint: PublicKey,\n tokenAmount: number, // In tokens (e.g., 1000000 for 1M tokens)\n minSolOut: number = 0, // Minimum SOL to receive (slippage protection)\n options?: { computeUnits?: number }\n ): Promise<TradeResult> {\n const addresses = this.deriveAddresses(mint);\n const userTokenAccount = getAssociatedTokenAddressSync(mint, this.wallet.publicKey);\n const userPosition = this.deriveUserPosition(addresses.tokenLaunch, this.wallet.publicKey);\n\n // Get state before\n const curveBefore = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n const walletBefore = await this.connection.getBalance(this.wallet.publicKey);\n\n const tokensRaw = new BN(tokenAmount).mul(new BN(10 ** TOKEN_DECIMALS));\n const minSolLamports = new BN(Math.floor(minSolOut * LAMPORTS_PER_SOL));\n\n const preInstructions: TransactionInstruction[] = [];\n if (options?.computeUnits) {\n preInstructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({ units: options.computeUnits })\n );\n }\n\n const tx = await this.program.methods\n .sellTokens(tokensRaw, minSolLamports)\n .accountsPartial({\n contributor: this.wallet.publicKey,\n launchpad: this.launchpadPda,\n adminWallet: ADMIN_WALLET,\n tokenLaunch: addresses.tokenLaunch,\n bondingCurve: addresses.bondingCurve,\n mint: mint,\n vault: addresses.vault,\n curveTokenAccount: addresses.curveTokenAccount,\n userTokenAccount: userTokenAccount,\n userPosition: userPosition,\n systemProgram: SystemProgram.programId,\n tokenProgram: TOKEN_PROGRAM_ID,\n })\n .preInstructions(preInstructions)\n .rpc();\n\n // Get state after\n const curveAfter = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n const walletAfter = await this.connection.getBalance(this.wallet.publicKey);\n\n const solReceived = BigInt(walletAfter - walletBefore);\n const progress = Number(curveAfter.soldSupply.toString()) / Number(curveAfter.tokensForCurve.toString()) * 100;\n\n return {\n txSignature: tx,\n tokensTraded: BigInt(tokensRaw.toString()),\n solTraded: solReceived,\n newProgress: progress,\n isCurveComplete: curveAfter.complete,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Admin Withdraw\n // ═══════════════════════════════════════════════════════════════════════════\n\n async adminWithdraw(mint: PublicKey): Promise<{\n txSignature: string;\n solWithdrawn: bigint;\n tokensWithdrawn: bigint;\n feesToTreasury: bigint;\n treasuryTokens: bigint;\n }> {\n const addresses = this.deriveAddresses(mint);\n const adminTokenAccount = getAssociatedTokenAddressSync(mint, this.wallet.publicKey);\n\n // Get launchpad to find treasury\n const launchpad = await this.program.account.launchpad.fetch(this.launchpadPda);\n const treasuryWallet = launchpad.treasury;\n const treasuryTokenAccount = getAssociatedTokenAddressSync(mint, treasuryWallet, true);\n\n // Get state before\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n const lpSol = BigInt(curve.realSolReserves.toString());\n const lpTokens = BigInt(curve.tokenReservesForLp.toString());\n const accumulatedFees = BigInt(curve.accumulatedFees.toString());\n const treasuryTokensAmount = BigInt(curve.tokenReservesForTreasury.toString());\n\n const tx = await this.program.methods\n .adminWithdraw()\n .accountsPartial({\n admin: this.wallet.publicKey,\n launchpad: this.launchpadPda,\n tokenLaunch: addresses.tokenLaunch,\n bondingCurve: addresses.bondingCurve,\n mint: mint,\n vault: addresses.vault,\n curveTokenAccount: addresses.curveTokenAccount,\n adminTokenAccount: adminTokenAccount,\n treasuryWallet: treasuryWallet,\n treasuryTokenAccount: treasuryTokenAccount,\n systemProgram: SystemProgram.programId,\n tokenProgram: TOKEN_PROGRAM_ID,\n associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,\n })\n .rpc();\n\n return {\n txSignature: tx,\n solWithdrawn: lpSol,\n tokensWithdrawn: lpTokens,\n feesToTreasury: accumulatedFees,\n treasuryTokens: treasuryTokensAmount,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Estimate Buy (tokens received for SOL)\n // ═══════════════════════════════════════════════════════════════════════════\n\n async estimateBuy(mint: PublicKey, solAmount: number): Promise<EstimateResult> {\n const addresses = this.deriveAddresses(mint);\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n\n const k = BigInt(curve.k.toString());\n const soldSupply = BigInt(curve.soldSupply.toString());\n const tokensForCurve = BigInt(curve.tokensForCurve.toString());\n\n const solLamports = BigInt(Math.floor(solAmount * LAMPORTS_PER_SOL));\n\n // Deduct 1% fee first\n const feeAmount = solLamports / 100n;\n const solAfterFees = solLamports - feeAmount;\n\n // Calculate tokens out using formula: s2 = sqrt(s1² + 2×sol×K_SCALE/k) - s1\n const tokensOut = this.calculateTokensForSol(k, soldSupply, solAfterFees);\n\n // Cap at available\n const available = tokensForCurve - soldSupply;\n const actualTokensOut = tokensOut > available ? available : tokensOut;\n\n // Calculate price per token\n const pricePerToken = solAfterFees / (actualTokensOut / BigInt(10 ** TOKEN_DECIMALS));\n\n // Calculate price impact\n const newSoldSupply = soldSupply + actualTokensOut;\n const priceBefore = this.calculatePrice(k, soldSupply);\n const priceAfter = this.calculatePrice(k, newSoldSupply);\n const priceImpactBps = priceBefore > 0n\n ? Number((priceAfter - priceBefore) * 10000n / priceBefore)\n : 0;\n\n return {\n tokensOut: actualTokensOut,\n solCost: solLamports,\n pricePerToken,\n priceImpactBps,\n feeAmount,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Estimate Sell (SOL received for tokens)\n // ═══════════════════════════════════════════════════════════════════════════\n\n async estimateSell(mint: PublicKey, tokenAmount: number): Promise<EstimateResult> {\n const addresses = this.deriveAddresses(mint);\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n\n const k = BigInt(curve.k.toString());\n const soldSupply = BigInt(curve.soldSupply.toString());\n const realSolReserves = BigInt(curve.realSolReserves.toString());\n\n const tokensRaw = BigInt(tokenAmount) * BigInt(10 ** TOKEN_DECIMALS);\n\n // Can't sell more than sold\n if (tokensRaw > soldSupply) {\n throw new Error(`Cannot sell ${tokenAmount} tokens. Only ${soldSupply / BigInt(10 ** TOKEN_DECIMALS)} available.`);\n }\n\n // Calculate gross SOL refund using formula: refund = (k/2) × (s1² - s2²)\n const grossRefund = this.calculateRefund(k, soldSupply, soldSupply - tokensRaw);\n\n // Cap at available SOL\n const cappedRefund = grossRefund > realSolReserves ? realSolReserves : grossRefund;\n\n // Deduct 1% fee\n const feeAmount = cappedRefund / 100n;\n const netSolOut = cappedRefund - feeAmount;\n\n // Calculate price per token\n const pricePerToken = netSolOut / BigInt(tokenAmount);\n\n // Calculate price impact\n const newSoldSupply = soldSupply - tokensRaw;\n const priceBefore = this.calculatePrice(k, soldSupply);\n const priceAfter = this.calculatePrice(k, newSoldSupply);\n const priceImpactBps = priceBefore > 0n\n ? Number((priceBefore - priceAfter) * 10000n / priceBefore)\n : 0;\n\n return {\n tokensOut: tokensRaw, // tokens being sold\n solCost: netSolOut, // SOL to receive\n pricePerToken,\n priceImpactBps,\n feeAmount,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Get Curve State\n // ═══════════════════════════════════════════════════════════════════════════\n\n async getCurveState(mint: PublicKey): Promise<BondingCurveState> {\n const addresses = this.deriveAddresses(mint);\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n\n return {\n tokenLaunch: curve.tokenLaunch,\n k: BigInt(curve.k.toString()),\n totalSupply: BigInt(curve.totalSupply.toString()),\n soldSupply: BigInt(curve.soldSupply.toString()),\n realSolReserves: BigInt(curve.realSolReserves.toString()),\n tokenReservesForLp: BigInt(curve.tokenReservesForLp.toString()),\n tokenReservesForTreasury: BigInt(curve.tokenReservesForTreasury.toString()),\n tokensForCurve: BigInt(curve.tokensForCurve.toString()),\n accumulatedFees: BigInt(curve.accumulatedFees.toString()),\n complete: curve.complete,\n bump: curve.bump,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Get Token Launch State\n // ═══════════════════════════════════════════════════════════════════════════\n\n async getTokenLaunchState(mint: PublicKey): Promise<TokenLaunchState> {\n const addresses = this.deriveAddresses(mint);\n const launch = await this.program.account.tokenLaunch.fetch(addresses.tokenLaunch);\n\n return {\n creator: launch.creator,\n mint: launch.mint,\n vault: launch.vault,\n bondingCurve: launch.bondingCurve,\n totalSupply: BigInt(launch.totalSupply.toString()),\n curveAllocation: BigInt(launch.curveAllocation.toString()),\n lpAllocation: BigInt(launch.lpAllocation.toString()),\n treasuryAllocation: BigInt(launch.treasuryAllocation.toString()),\n totalSolRaised: BigInt(launch.totalSolRaised.toString()),\n tradingActive: launch.tradingActive,\n migrated: launch.migrated,\n initialK: BigInt(launch.initialK.toString()),\n name: launch.name,\n symbol: launch.symbol,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Get Progress\n // ═══════════════════════════════════════════════════════════════════════════\n\n async getProgress(mint: PublicKey): Promise<{\n percent: number;\n soldSupply: bigint;\n tokensForCurve: bigint;\n solRaised: bigint;\n currentPrice: bigint;\n isComplete: boolean;\n }> {\n const curve = await this.getCurveState(mint);\n\n const percent = Number(curve.soldSupply * 100n / curve.tokensForCurve);\n const currentPrice = this.calculatePrice(curve.k, curve.soldSupply);\n\n return {\n percent,\n soldSupply: curve.soldSupply,\n tokensForCurve: curve.tokensForCurve,\n solRaised: curve.realSolReserves,\n currentPrice,\n isComplete: curve.complete,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Event Listeners\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Listen for LaunchCreated events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onLaunchCreated(callback: EventCallback<LaunchCreatedEvent>): number {\n return this.program.addEventListener(\"launchCreated\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n creator: event.creator,\n name: event.name,\n symbol: event.symbol,\n totalSupply: BigInt(event.totalSupply.toString()),\n curveAllocation: BigInt(event.curveAllocation.toString()),\n lpAllocation: BigInt(event.lpAllocation.toString()),\n treasuryAllocation: BigInt(event.treasuryAllocation.toString()),\n initialK: BigInt(event.initialK.toString()),\n initialPrice: BigInt(event.initialPrice.toString()),\n timestamp: BigInt(event.timestamp.toString()),\n }, slot, signature);\n });\n }\n\n /**\n * Listen for TokensPurchased events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onTokensPurchased(callback: EventCallback<TokensPurchasedEvent>): number {\n return this.program.addEventListener(\"tokensPurchased\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n buyer: event.buyer,\n solAmount: BigInt(event.solAmount.toString()),\n solAfterFees: BigInt(event.solAfterFees.toString()),\n tokensReceived: BigInt(event.tokensReceived.toString()),\n curveFee: BigInt(event.curveFee.toString()),\n adminFee: BigInt(event.adminFee.toString()),\n priceAfter: BigInt(event.priceAfter.toString()),\n totalSold: BigInt(event.totalSold.toString()),\n progress: event.progress,\n timestamp: BigInt(event.timestamp.toString()),\n isCurveComplete: event.isCurveComplete,\n }, slot, signature);\n });\n }\n\n /**\n * Listen for TokensSold events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onTokensSold(callback: EventCallback<TokensSoldEvent>): number {\n return this.program.addEventListener(\"tokensSold\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n seller: event.seller,\n tokensSold: BigInt(event.tokensSold.toString()),\n grossSolRefund: BigInt(event.grossSolRefund.toString()),\n netSolRefund: BigInt(event.netSolRefund.toString()),\n curveFee: BigInt(event.curveFee.toString()),\n adminFee: BigInt(event.adminFee.toString()),\n priceAfter: BigInt(event.priceAfter.toString()),\n totalSold: BigInt(event.totalSold.toString()),\n progress: event.progress,\n timestamp: BigInt(event.timestamp.toString()),\n }, slot, signature);\n });\n }\n\n /**\n * Listen for CurveComplete events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onCurveComplete(callback: EventCallback<CurveCompleteEvent>): number {\n return this.program.addEventListener(\"curveComplete\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n totalSolRaised: BigInt(event.totalSolRaised.toString()),\n finalPrice: BigInt(event.finalPrice.toString()),\n timestamp: BigInt(event.timestamp.toString()),\n }, slot, signature);\n });\n }\n\n /**\n * Listen for AdminWithdraw events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onAdminWithdraw(callback: EventCallback<AdminWithdrawEvent>): number {\n return this.program.addEventListener(\"adminWithdraw\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n admin: event.admin,\n creator: event.creator,\n treasury: event.treasury,\n solWithdrawn: BigInt(event.solWithdrawn.toString()),\n tokensWithdrawn: BigInt(event.tokensWithdrawn.toString()),\n feesToTreasury: BigInt(event.feesToTreasury.toString()),\n treasuryTokens: BigInt(event.treasuryTokens.toString()),\n timestamp: BigInt(event.timestamp.toString()),\n }, slot, signature);\n });\n }\n\n /**\n * Remove an event listener\n * @param listenerId The ID returned from addEventListener\n */\n async removeEventListener(listenerId: number): Promise<void> {\n await this.program.removeEventListener(listenerId);\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Math Helpers (Pure functions, no async)\n // ═══════════════════════════════════════════════════════════════════════════\n\n /** Calculate price at a given supply: price = k × supply / K_SCALE */\n calculatePrice(k: bigint, supply: bigint): bigint {\n if (supply === 0n) return 0n;\n return (k * supply) / K_SCALE;\n }\n\n /** Calculate cost to buy from s1 to s2: cost = (k/2) × (s2² - s1²) / K_SCALE */\n calculateCost(k: bigint, s1: bigint, s2: bigint): bigint {\n if (s2 <= s1) return 0n;\n const s1Sq = s1 * s1;\n const s2Sq = s2 * s2;\n const diffSq = s2Sq - s1Sq;\n return (k * diffSq) / 2n / K_SCALE;\n }\n\n /** Calculate tokens received for SOL: s2 = sqrt(s1² + 2×sol×K_SCALE/k) */\n calculateTokensForSol(k: bigint, currentSupply: bigint, solIn: bigint): bigint {\n if (solIn === 0n || k === 0n) return 0n;\n\n const s1Sq = currentSupply * currentSupply;\n const addition = (2n * solIn * K_SCALE) / k;\n const s2Sq = s1Sq + addition;\n const s2 = this.isqrt(s2Sq);\n\n return s2 - currentSupply;\n }\n\n /** Calculate refund for selling tokens: refund = (k/2) × (s1² - s2²) / K_SCALE */\n calculateRefund(k: bigint, s1: bigint, s2: bigint): bigint {\n if (s1 <= s2) return 0n;\n const s1Sq = s1 * s1;\n const s2Sq = s2 * s2;\n const diffSq = s1Sq - s2Sq;\n return (k * diffSq) / 2n / K_SCALE;\n }\n\n /** Integer square root using Newton's method */\n isqrt(n: bigint): bigint {\n if (n === 0n) return 0n;\n if (n === 1n) return 1n;\n\n let x = n;\n let y = (x + 1n) / 2n;\n\n while (y < x) {\n x = y;\n y = (x + n / x) / 2n;\n }\n\n return x;\n }\n\n /** Calculate K for a given target SOL and curve supply */\n static calculateK(curveSupply: bigint, targetSol: bigint): bigint {\n // k = 2 × target_sol × K_SCALE / curve_supply²\n const numerator = 2n * targetSol * K_SCALE;\n const denominator = curveSupply * curveSupply;\n return numerator / denominator;\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Utility Functions\n// ═══════════════════════════════════════════════════════════════════════════\n\n/** Format raw token amount to human-readable */\nexport function formatTokens(raw: bigint): string {\n const tokens = Number(raw) / (10 ** TOKEN_DECIMALS);\n return tokens.toLocaleString(undefined, { maximumFractionDigits: 2 });\n}\n\n/** Format lamports to SOL */\nexport function formatSol(lamports: bigint): string {\n const sol = Number(lamports) / LAMPORTS_PER_SOL;\n return sol.toFixed(4);\n}\n\n/** Parse SOL to lamports */\nexport function parseSol(sol: number): bigint {\n return BigInt(Math.floor(sol * LAMPORTS_PER_SOL));\n}\n\n/** Parse tokens to raw */\nexport function parseTokens(tokens: number): bigint {\n return BigInt(Math.floor(tokens * (10 ** TOKEN_DECIMALS)));\n}\n\nexport default KickFunSDK;\n"]}
1
+ {"version":3,"sources":["../src/sdk/index.ts"],"names":["PublicKey","LAMPORTS_PER_SOL","getAssociatedTokenAddressSync","SystemProgram","Keypair","TOKEN_PROGRAM_ID","ASSOCIATED_TOKEN_PROGRAM_ID","SYSVAR_RENT_PUBKEY","getAccount","BN","ComputeBudgetProgram"],"mappings":"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","file":"index.js","sourcesContent":["import * as anchor from \"@coral-xyz/anchor\";\nimport { Program, BN } from \"@coral-xyz/anchor\";\nimport { KickFunProgram } from \"../types/kick_fun_program\";\nimport {\n Keypair,\n SystemProgram,\n PublicKey,\n LAMPORTS_PER_SOL,\n ComputeBudgetProgram,\n Connection,\n TransactionInstruction,\n SYSVAR_RENT_PUBKEY,\n} from \"@solana/web3.js\";\nimport {\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n getAssociatedTokenAddressSync,\n getAccount,\n} from \"@solana/spl-token\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Constants\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport const PROGRAM_ID = new PublicKey(\"6o7oTqg2CfvcMCJTLNEJsef7c875zGpTvcnFctNAjudL\");\nexport const ADMIN_WALLET = new PublicKey(\"7eGpbyRpcM7WpNKQtd6XkteNQWHbWXP7icZjKzNK2aTk\");\nexport const METADATA_PROGRAM_ID = new PublicKey(\"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s\");\nexport const K_SCALE = 10_000_000_000_000_000_000_000n; // 10^22\nexport const LAMPORTS = LAMPORTS_PER_SOL;\nexport const TOKEN_DECIMALS = 6;\nexport const FEE_BPS = 100; // 1% total fee (0.5% admin immediate + 0.5% accumulated)\nexport const CURVE_PERCENT = 70; // 70% for bonding curve\nexport const LP_PERCENT = 20; // 20% for LP\nexport const TREASURY_PERCENT = 10; // 10% for treasury\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface TokenLaunchConfig {\n name: string;\n symbol: string;\n uri: string;\n creatorWallet?: PublicKey; // Optional: custom creator wallet, defaults to SDK wallet\n}\n\nexport interface BondingCurveState {\n tokenLaunch: PublicKey;\n k: bigint;\n totalSupply: bigint;\n soldSupply: bigint;\n realSolReserves: bigint;\n tokenReservesForLp: bigint;\n tokenReservesForTreasury: bigint;\n tokensForCurve: bigint;\n accumulatedFees: bigint;\n complete: boolean;\n bump: number;\n}\n\nexport interface TokenLaunchState {\n creator: PublicKey;\n mint: PublicKey;\n vault: PublicKey;\n bondingCurve: PublicKey;\n totalSupply: bigint;\n curveAllocation: bigint;\n lpAllocation: bigint;\n treasuryAllocation: bigint;\n totalSolRaised: bigint;\n tradingActive: boolean;\n migrated: boolean;\n initialK: bigint;\n name: string;\n symbol: string;\n}\n\nexport interface LaunchAddresses {\n mint: PublicKey;\n tokenLaunch: PublicKey;\n bondingCurve: PublicKey;\n vault: PublicKey;\n curveTokenAccount: PublicKey;\n metadata: PublicKey; // Metaplex metadata PDA\n}\n\nexport interface TradeResult {\n txSignature: string;\n tokensTraded: bigint;\n solTraded: bigint;\n newProgress: number;\n isCurveComplete: boolean;\n}\n\nexport interface EstimateBuyResult {\n solIn: bigint; // Total SOL user pays (including fee)\n solAfterFee: bigint; // SOL that goes into the curve (after fee)\n tokensOut: bigint; // Tokens user receives\n fee: bigint; // Fee in SOL (lamports)\n pricePerToken: bigint;\n priceImpactBps: number;\n}\n\nexport interface EstimateSellResult {\n tokensIn: bigint; // Tokens user sells\n solBeforeFee: bigint; // Gross SOL from curve (before fee)\n solOut: bigint; // Net SOL user receives (after fee)\n fee: bigint; // Fee in SOL (lamports)\n pricePerToken: bigint;\n priceImpactBps: number;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Event Types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface LaunchCreatedEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n creator: PublicKey;\n name: string;\n symbol: string;\n totalSupply: bigint;\n curveAllocation: bigint;\n lpAllocation: bigint;\n treasuryAllocation: bigint;\n initialK: bigint;\n initialPrice: bigint;\n timestamp: bigint;\n}\n\nexport interface TokensPurchasedEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n buyer: PublicKey;\n solAmount: bigint;\n solAfterFees: bigint;\n tokensReceived: bigint;\n curveFee: bigint;\n adminFee: bigint;\n priceAfter: bigint;\n totalSold: bigint;\n progress: number;\n timestamp: bigint;\n isCurveComplete: boolean;\n}\n\nexport interface TokensSoldEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n seller: PublicKey;\n tokensSold: bigint;\n grossSolRefund: bigint;\n netSolRefund: bigint;\n curveFee: bigint;\n adminFee: bigint;\n priceAfter: bigint;\n totalSold: bigint;\n progress: number;\n timestamp: bigint;\n}\n\nexport interface CurveCompleteEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n totalSolRaised: bigint;\n finalPrice: bigint;\n timestamp: bigint;\n}\n\nexport interface AdminWithdrawEvent {\n tokenLaunch: PublicKey;\n mint: PublicKey;\n admin: PublicKey;\n creator: PublicKey;\n treasury: PublicKey;\n solWithdrawn: bigint;\n tokensWithdrawn: bigint;\n feesToTreasury: bigint;\n treasuryTokens: bigint;\n timestamp: bigint;\n}\n\nexport type KickFunEvent =\n | { name: \"LaunchCreated\"; data: LaunchCreatedEvent }\n | { name: \"TokensPurchased\"; data: TokensPurchasedEvent }\n | { name: \"TokensSold\"; data: TokensSoldEvent }\n | { name: \"CurveComplete\"; data: CurveCompleteEvent }\n | { name: \"AdminWithdraw\"; data: AdminWithdrawEvent };\n\nexport type EventCallback<T> = (event: T, slot: number, signature: string) => void;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// KickFunSDK Class\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport class KickFunSDK {\n public program: Program<KickFunProgram>;\n public connection: Connection;\n public wallet: anchor.Wallet;\n public launchpadPda: PublicKey;\n\n constructor(\n program: Program<KickFunProgram>,\n wallet: anchor.Wallet\n ) {\n this.program = program;\n this.connection = program.provider.connection;\n this.wallet = wallet;\n\n [this.launchpadPda] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"launchpad\")],\n program.programId\n );\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // PDA Derivation Helpers\n // ═══════════════════════════════════════════════════════════════════════════\n\n deriveAddresses(mint: PublicKey): LaunchAddresses {\n const [tokenLaunch] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"token_launch\"), mint.toBuffer()],\n this.program.programId\n );\n const [bondingCurve] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"bonding_curve\"), tokenLaunch.toBuffer()],\n this.program.programId\n );\n const [vault] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"vault\"), tokenLaunch.toBuffer()],\n this.program.programId\n );\n const curveTokenAccount = getAssociatedTokenAddressSync(mint, bondingCurve, true);\n\n // Metaplex metadata PDA\n const [metadata] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"metadata\"), METADATA_PROGRAM_ID.toBuffer(), mint.toBuffer()],\n METADATA_PROGRAM_ID\n );\n\n return { mint, tokenLaunch, bondingCurve, vault, curveTokenAccount, metadata };\n }\n\n deriveUserPosition(tokenLaunch: PublicKey, user: PublicKey): PublicKey {\n const [userPosition] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"user_position\"), tokenLaunch.toBuffer(), user.toBuffer()],\n this.program.programId\n );\n return userPosition;\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Initialize Launchpad (one-time setup)\n // ═══════════════════════════════════════════════════════════════════════════\n\n async initializeLaunchpad(platformFeeBps: number = 200): Promise<string> {\n try {\n await this.program.account.launchpad.fetch(this.launchpadPda);\n return \"already_initialized\";\n } catch {\n const tx = await this.program.methods\n .initializeLaunchpad(platformFeeBps)\n .accountsPartial({\n authority: this.wallet.publicKey,\n launchpad: this.launchpadPda,\n treasury: this.wallet.publicKey,\n systemProgram: SystemProgram.programId,\n })\n .rpc();\n return tx;\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Create Token Launch\n // ═══════════════════════════════════════════════════════════════════════════\n\n async createTokenLaunch(config: TokenLaunchConfig): Promise<{\n txSignature: string;\n addresses: LaunchAddresses;\n mintKeypair: Keypair;\n }> {\n const mintKeypair = Keypair.generate();\n const addresses = this.deriveAddresses(mintKeypair.publicKey);\n\n // Use custom creator wallet or default to SDK wallet\n const creatorWallet = config.creatorWallet || this.wallet.publicKey;\n\n const tx = await this.program.methods\n .createTokenLaunch(config.name, config.symbol, config.uri)\n .accountsPartial({\n creator: creatorWallet,\n launchpad: this.launchpadPda,\n mint: mintKeypair.publicKey,\n tokenLaunch: addresses.tokenLaunch,\n bondingCurve: addresses.bondingCurve,\n vault: addresses.vault,\n curveTokenAccount: addresses.curveTokenAccount,\n metadata: addresses.metadata,\n tokenProgram: TOKEN_PROGRAM_ID,\n associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,\n metadataProgram: METADATA_PROGRAM_ID,\n systemProgram: SystemProgram.programId,\n rent: SYSVAR_RENT_PUBKEY,\n })\n .signers([mintKeypair])\n .transaction();\n\n const { blockhash } = await this.connection.getLatestBlockhash();\n tx.recentBlockhash = blockhash;\n tx.feePayer = this.wallet.publicKey;\n tx.partialSign(mintKeypair);\n const signedTx = await this.wallet.signTransaction(tx);\n const txSignature = await this.connection.sendRawTransaction(signedTx.serialize(), {\n skipPreflight: true,\n });\n\n await this.connection.confirmTransaction({\n signature: txSignature,\n ...(await this.connection.getLatestBlockhash()),\n });\n \n return { txSignature, addresses, mintKeypair };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Buy Tokens\n // ═══════════════════════════════════════════════════════════════════════════\n\n async buy(\n mint: PublicKey,\n solAmount: number, // In SOL (e.g., 1.5 for 1.5 SOL)\n options?: { computeUnits?: number }\n ): Promise<TradeResult> {\n const addresses = this.deriveAddresses(mint);\n const userTokenAccount = getAssociatedTokenAddressSync(mint, this.wallet.publicKey);\n const userPosition = this.deriveUserPosition(addresses.tokenLaunch, this.wallet.publicKey);\n\n // Get state before\n const curveBefore = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n let tokensBefore = 0n;\n try {\n const account = await getAccount(this.connection, userTokenAccount);\n tokensBefore = account.amount;\n } catch {\n // Account doesn't exist yet\n }\n\n const solLamports = new BN(Math.floor(solAmount * LAMPORTS_PER_SOL));\n\n const preInstructions: TransactionInstruction[] = [];\n if (options?.computeUnits) {\n preInstructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({ units: options.computeUnits })\n );\n }\n\n const tx = await this.program.methods\n .buyTokens(solLamports)\n .accountsPartial({\n contributor: this.wallet.publicKey,\n launchpad: this.launchpadPda,\n adminWallet: ADMIN_WALLET,\n tokenLaunch: addresses.tokenLaunch,\n bondingCurve: addresses.bondingCurve,\n mint: mint,\n vault: addresses.vault,\n curveTokenAccount: addresses.curveTokenAccount,\n userTokenAccount: userTokenAccount,\n userPosition: userPosition,\n systemProgram: SystemProgram.programId,\n tokenProgram: TOKEN_PROGRAM_ID,\n associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,\n })\n .preInstructions(preInstructions)\n .rpc();\n\n // Get state after\n const curveAfter = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n const tokensAfter = (await getAccount(this.connection, userTokenAccount)).amount;\n\n const tokensReceived = tokensAfter - tokensBefore;\n const progress = Number(curveAfter.soldSupply.toString()) / Number(curveAfter.tokensForCurve.toString()) * 100;\n\n return {\n txSignature: tx,\n tokensTraded: tokensReceived,\n solTraded: BigInt(solLamports.toString()),\n newProgress: progress,\n isCurveComplete: curveAfter.complete,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Sell Tokens\n // ═══════════════════════════════════════════════════════════════════════════\n\n async sell(\n mint: PublicKey,\n tokenAmount: number, // In tokens (e.g., 1000000 for 1M tokens)\n minSolOut: number = 0, // Minimum SOL to receive (slippage protection)\n options?: { computeUnits?: number }\n ): Promise<TradeResult> {\n const addresses = this.deriveAddresses(mint);\n const userTokenAccount = getAssociatedTokenAddressSync(mint, this.wallet.publicKey);\n const userPosition = this.deriveUserPosition(addresses.tokenLaunch, this.wallet.publicKey);\n\n // Get state before\n const curveBefore = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n const walletBefore = await this.connection.getBalance(this.wallet.publicKey);\n\n const tokensRaw = new BN(tokenAmount).mul(new BN(10 ** TOKEN_DECIMALS));\n const minSolLamports = new BN(Math.floor(minSolOut * LAMPORTS_PER_SOL));\n\n const preInstructions: TransactionInstruction[] = [];\n if (options?.computeUnits) {\n preInstructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({ units: options.computeUnits })\n );\n }\n\n const tx = await this.program.methods\n .sellTokens(tokensRaw, minSolLamports)\n .accountsPartial({\n contributor: this.wallet.publicKey,\n launchpad: this.launchpadPda,\n adminWallet: ADMIN_WALLET,\n tokenLaunch: addresses.tokenLaunch,\n bondingCurve: addresses.bondingCurve,\n mint: mint,\n vault: addresses.vault,\n curveTokenAccount: addresses.curveTokenAccount,\n userTokenAccount: userTokenAccount,\n userPosition: userPosition,\n systemProgram: SystemProgram.programId,\n tokenProgram: TOKEN_PROGRAM_ID,\n })\n .preInstructions(preInstructions)\n .rpc();\n\n // Get state after\n const curveAfter = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n const walletAfter = await this.connection.getBalance(this.wallet.publicKey);\n\n const solReceived = BigInt(walletAfter - walletBefore);\n const progress = Number(curveAfter.soldSupply.toString()) / Number(curveAfter.tokensForCurve.toString()) * 100;\n\n return {\n txSignature: tx,\n tokensTraded: BigInt(tokensRaw.toString()),\n solTraded: solReceived,\n newProgress: progress,\n isCurveComplete: curveAfter.complete,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Admin Withdraw\n // ═══════════════════════════════════════════════════════════════════════════\n\n async adminWithdraw(mint: PublicKey): Promise<{\n txSignature: string;\n solWithdrawn: bigint;\n tokensWithdrawn: bigint;\n feesToTreasury: bigint;\n treasuryTokens: bigint;\n }> {\n const addresses = this.deriveAddresses(mint);\n const adminTokenAccount = getAssociatedTokenAddressSync(mint, this.wallet.publicKey);\n\n // Get launchpad to find treasury\n const launchpad = await this.program.account.launchpad.fetch(this.launchpadPda);\n const treasuryWallet = launchpad.treasury;\n const treasuryTokenAccount = getAssociatedTokenAddressSync(mint, treasuryWallet, true);\n\n // Get state before\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n const lpSol = BigInt(curve.realSolReserves.toString());\n const lpTokens = BigInt(curve.tokenReservesForLp.toString());\n const accumulatedFees = BigInt(curve.accumulatedFees.toString());\n const treasuryTokensAmount = BigInt(curve.tokenReservesForTreasury.toString());\n\n const tx = await this.program.methods\n .adminWithdraw()\n .accountsPartial({\n admin: this.wallet.publicKey,\n launchpad: this.launchpadPda,\n tokenLaunch: addresses.tokenLaunch,\n bondingCurve: addresses.bondingCurve,\n mint: mint,\n vault: addresses.vault,\n curveTokenAccount: addresses.curveTokenAccount,\n adminTokenAccount: adminTokenAccount,\n treasuryWallet: treasuryWallet,\n treasuryTokenAccount: treasuryTokenAccount,\n systemProgram: SystemProgram.programId,\n tokenProgram: TOKEN_PROGRAM_ID,\n associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,\n })\n .rpc();\n\n return {\n txSignature: tx,\n solWithdrawn: lpSol,\n tokensWithdrawn: lpTokens,\n feesToTreasury: accumulatedFees,\n treasuryTokens: treasuryTokensAmount,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Estimate Buy (input SOL → output tokens)\n // ═══════════════════════════════════════════════════════════════════════════\n\n async estimateBuy(mint: PublicKey, solAmount: number): Promise<EstimateBuyResult> {\n const addresses = this.deriveAddresses(mint);\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n\n const k = BigInt(curve.k.toString());\n const soldSupply = BigInt(curve.soldSupply.toString());\n const tokensForCurve = BigInt(curve.tokensForCurve.toString());\n\n const solIn = BigInt(Math.floor(solAmount * LAMPORTS_PER_SOL));\n\n // Deduct 1% fee first\n const fee = solIn / 100n;\n const solAfterFee = solIn - fee;\n\n // Calculate tokens out\n const tokensOut = this.calculateTokensForSol(k, soldSupply, solAfterFee);\n\n // Cap at available\n const available = tokensForCurve - soldSupply;\n const actualTokensOut = tokensOut > available ? available : tokensOut;\n\n // Calculate price per token\n const tokenUnits = actualTokensOut / BigInt(10 ** TOKEN_DECIMALS);\n const pricePerToken = tokenUnits > 0n ? solAfterFee / tokenUnits : 0n;\n\n // Calculate price impact\n const newSoldSupply = soldSupply + actualTokensOut;\n const priceBefore = this.calculatePrice(k, soldSupply);\n const priceAfter = this.calculatePrice(k, newSoldSupply);\n const priceImpactBps = priceBefore > 0n\n ? Number((priceAfter - priceBefore) * 10000n / priceBefore)\n : 0;\n\n return { solIn, solAfterFee, tokensOut: actualTokensOut, fee, pricePerToken, priceImpactBps };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Estimate Buy by Tokens (input tokens → output SOL needed)\n // ═══════════════════════════════════════════════════════════════════════════\n\n async estimateBuyByTokens(mint: PublicKey, tokenAmount: number): Promise<EstimateBuyResult> {\n const addresses = this.deriveAddresses(mint);\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n\n const k = BigInt(curve.k.toString());\n const soldSupply = BigInt(curve.soldSupply.toString());\n const tokensForCurve = BigInt(curve.tokensForCurve.toString());\n\n const tokensRaw = BigInt(tokenAmount) * BigInt(10 ** TOKEN_DECIMALS);\n\n // Cap at available\n const available = tokensForCurve - soldSupply;\n const actualTokensOut = tokensRaw > available ? available : tokensRaw;\n\n // Calculate gross SOL cost (before fee)\n const solAfterFee = this.calculateCost(k, soldSupply, soldSupply + actualTokensOut);\n\n // Add 1% fee on top: user pays solAfterFee / 0.99\n const solIn = solAfterFee * 100n / 99n;\n const fee = solIn - solAfterFee;\n\n // Calculate price per token\n const tokenUnits = actualTokensOut / BigInt(10 ** TOKEN_DECIMALS);\n const pricePerToken = tokenUnits > 0n ? solAfterFee / tokenUnits : 0n;\n\n // Calculate price impact\n const newSoldSupply = soldSupply + actualTokensOut;\n const priceBefore = this.calculatePrice(k, soldSupply);\n const priceAfter = this.calculatePrice(k, newSoldSupply);\n const priceImpactBps = priceBefore > 0n\n ? Number((priceAfter - priceBefore) * 10000n / priceBefore)\n : 0;\n\n return { solIn, solAfterFee, tokensOut: actualTokensOut, fee, pricePerToken, priceImpactBps };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Estimate Sell (input tokens → output SOL)\n // ═══════════════════════════════════════════════════════════════════════════\n\n async estimateSell(mint: PublicKey, tokenAmount: number): Promise<EstimateSellResult> {\n const addresses = this.deriveAddresses(mint);\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n\n const k = BigInt(curve.k.toString());\n const soldSupply = BigInt(curve.soldSupply.toString());\n const realSolReserves = BigInt(curve.realSolReserves.toString());\n\n const tokensIn = BigInt(tokenAmount) * BigInt(10 ** TOKEN_DECIMALS);\n\n // Can't sell more than sold\n if (tokensIn > soldSupply) {\n throw new Error(`Cannot sell ${tokenAmount} tokens. Only ${soldSupply / BigInt(10 ** TOKEN_DECIMALS)} available.`);\n }\n\n // Calculate gross SOL refund\n const grossRefund = this.calculateRefund(k, soldSupply, soldSupply - tokensIn);\n\n // Cap at available SOL\n const solBeforeFee = grossRefund > realSolReserves ? realSolReserves : grossRefund;\n\n // Deduct 1% fee\n const fee = solBeforeFee / 100n;\n const solOut = solBeforeFee - fee;\n\n // Calculate price per token\n const pricePerToken = tokenAmount > 0 ? solOut / BigInt(tokenAmount) : 0n;\n\n // Calculate price impact\n const newSoldSupply = soldSupply - tokensIn;\n const priceBefore = this.calculatePrice(k, soldSupply);\n const priceAfter = this.calculatePrice(k, newSoldSupply);\n const priceImpactBps = priceBefore > 0n\n ? Number((priceBefore - priceAfter) * 10000n / priceBefore)\n : 0;\n\n return { tokensIn, solBeforeFee, solOut, fee, pricePerToken, priceImpactBps };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Estimate Sell by SOL (input SOL desired → output tokens to sell)\n // ═══════════════════════════════════════════════════════════════════════════\n\n async estimateSellBySol(mint: PublicKey, solAmount: number): Promise<EstimateSellResult> {\n const addresses = this.deriveAddresses(mint);\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n\n const k = BigInt(curve.k.toString());\n const soldSupply = BigInt(curve.soldSupply.toString());\n const realSolReserves = BigInt(curve.realSolReserves.toString());\n\n const solDesired = BigInt(Math.floor(solAmount * LAMPORTS_PER_SOL));\n\n // Reverse fee: user wants solDesired after fee, so gross = solDesired / 0.99\n const solBeforeFee = solDesired * 100n / 99n;\n\n // Cap at available SOL reserves\n const cappedGross = solBeforeFee > realSolReserves ? realSolReserves : solBeforeFee;\n\n // Calculate tokens needed to sell\n const tokensIn = this.calculateTokensForSolSell(k, soldSupply, cappedGross);\n\n // Cap at sold supply\n const actualTokensIn = tokensIn > soldSupply ? soldSupply : tokensIn;\n\n // Recalculate actual SOL from capped tokens\n const actualGross = this.calculateRefund(k, soldSupply, soldSupply - actualTokensIn);\n const actualSolBeforeFee = actualGross > realSolReserves ? realSolReserves : actualGross;\n const fee = actualSolBeforeFee / 100n;\n const solOut = actualSolBeforeFee - fee;\n\n // Calculate price per token\n const tokenUnits = actualTokensIn / BigInt(10 ** TOKEN_DECIMALS);\n const pricePerToken = tokenUnits > 0n ? solOut / tokenUnits : 0n;\n\n // Calculate price impact\n const newSoldSupply = soldSupply - actualTokensIn;\n const priceBefore = this.calculatePrice(k, soldSupply);\n const priceAfter = this.calculatePrice(k, newSoldSupply);\n const priceImpactBps = priceBefore > 0n\n ? Number((priceBefore - priceAfter) * 10000n / priceBefore)\n : 0;\n\n return { tokensIn: actualTokensIn, solBeforeFee: actualSolBeforeFee, solOut, fee, pricePerToken, priceImpactBps };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Get Curve State\n // ═══════════════════════════════════════════════════════════════════════════\n\n async getCurveState(mint: PublicKey): Promise<BondingCurveState> {\n const addresses = this.deriveAddresses(mint);\n const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);\n\n return {\n tokenLaunch: curve.tokenLaunch,\n k: BigInt(curve.k.toString()),\n totalSupply: BigInt(curve.totalSupply.toString()),\n soldSupply: BigInt(curve.soldSupply.toString()),\n realSolReserves: BigInt(curve.realSolReserves.toString()),\n tokenReservesForLp: BigInt(curve.tokenReservesForLp.toString()),\n tokenReservesForTreasury: BigInt(curve.tokenReservesForTreasury.toString()),\n tokensForCurve: BigInt(curve.tokensForCurve.toString()),\n accumulatedFees: BigInt(curve.accumulatedFees.toString()),\n complete: curve.complete,\n bump: curve.bump,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Get Token Launch State\n // ═══════════════════════════════════════════════════════════════════════════\n\n async getTokenLaunchState(mint: PublicKey): Promise<TokenLaunchState> {\n const addresses = this.deriveAddresses(mint);\n const launch = await this.program.account.tokenLaunch.fetch(addresses.tokenLaunch);\n\n return {\n creator: launch.creator,\n mint: launch.mint,\n vault: launch.vault,\n bondingCurve: launch.bondingCurve,\n totalSupply: BigInt(launch.totalSupply.toString()),\n curveAllocation: BigInt(launch.curveAllocation.toString()),\n lpAllocation: BigInt(launch.lpAllocation.toString()),\n treasuryAllocation: BigInt(launch.treasuryAllocation.toString()),\n totalSolRaised: BigInt(launch.totalSolRaised.toString()),\n tradingActive: launch.tradingActive,\n migrated: launch.migrated,\n initialK: BigInt(launch.initialK.toString()),\n name: launch.name,\n symbol: launch.symbol,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Get Progress\n // ═══════════════════════════════════════════════════════════════════════════\n\n async getProgress(mint: PublicKey): Promise<{\n percent: number;\n soldSupply: bigint;\n tokensForCurve: bigint;\n solRaised: bigint;\n currentPrice: bigint;\n isComplete: boolean;\n }> {\n const curve = await this.getCurveState(mint);\n\n const percent = Number(curve.soldSupply * 100n / curve.tokensForCurve);\n const currentPrice = this.calculatePrice(curve.k, curve.soldSupply);\n\n return {\n percent,\n soldSupply: curve.soldSupply,\n tokensForCurve: curve.tokensForCurve,\n solRaised: curve.realSolReserves,\n currentPrice,\n isComplete: curve.complete,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Event Listeners\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Listen for LaunchCreated events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onLaunchCreated(callback: EventCallback<LaunchCreatedEvent>): number {\n return this.program.addEventListener(\"launchCreated\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n creator: event.creator,\n name: event.name,\n symbol: event.symbol,\n totalSupply: BigInt(event.totalSupply.toString()),\n curveAllocation: BigInt(event.curveAllocation.toString()),\n lpAllocation: BigInt(event.lpAllocation.toString()),\n treasuryAllocation: BigInt(event.treasuryAllocation.toString()),\n initialK: BigInt(event.initialK.toString()),\n initialPrice: BigInt(event.initialPrice.toString()),\n timestamp: BigInt(event.timestamp.toString()),\n }, slot, signature);\n });\n }\n\n /**\n * Listen for TokensPurchased events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onTokensPurchased(callback: EventCallback<TokensPurchasedEvent>): number {\n return this.program.addEventListener(\"tokensPurchased\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n buyer: event.buyer,\n solAmount: BigInt(event.solAmount.toString()),\n solAfterFees: BigInt(event.solAfterFees.toString()),\n tokensReceived: BigInt(event.tokensReceived.toString()),\n curveFee: BigInt(event.curveFee.toString()),\n adminFee: BigInt(event.adminFee.toString()),\n priceAfter: BigInt(event.priceAfter.toString()),\n totalSold: BigInt(event.totalSold.toString()),\n progress: event.progress,\n timestamp: BigInt(event.timestamp.toString()),\n isCurveComplete: event.isCurveComplete,\n }, slot, signature);\n });\n }\n\n /**\n * Listen for TokensSold events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onTokensSold(callback: EventCallback<TokensSoldEvent>): number {\n return this.program.addEventListener(\"tokensSold\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n seller: event.seller,\n tokensSold: BigInt(event.tokensSold.toString()),\n grossSolRefund: BigInt(event.grossSolRefund.toString()),\n netSolRefund: BigInt(event.netSolRefund.toString()),\n curveFee: BigInt(event.curveFee.toString()),\n adminFee: BigInt(event.adminFee.toString()),\n priceAfter: BigInt(event.priceAfter.toString()),\n totalSold: BigInt(event.totalSold.toString()),\n progress: event.progress,\n timestamp: BigInt(event.timestamp.toString()),\n }, slot, signature);\n });\n }\n\n /**\n * Listen for CurveComplete events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onCurveComplete(callback: EventCallback<CurveCompleteEvent>): number {\n return this.program.addEventListener(\"curveComplete\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n totalSolRaised: BigInt(event.totalSolRaised.toString()),\n finalPrice: BigInt(event.finalPrice.toString()),\n timestamp: BigInt(event.timestamp.toString()),\n }, slot, signature);\n });\n }\n\n /**\n * Listen for AdminWithdraw events\n * @param callback Function to call when event is emitted\n * @returns Listener ID for removal\n */\n onAdminWithdraw(callback: EventCallback<AdminWithdrawEvent>): number {\n return this.program.addEventListener(\"adminWithdraw\", (event: any, slot: number, signature: string) => {\n callback({\n tokenLaunch: event.tokenLaunch,\n mint: event.mint,\n admin: event.admin,\n creator: event.creator,\n treasury: event.treasury,\n solWithdrawn: BigInt(event.solWithdrawn.toString()),\n tokensWithdrawn: BigInt(event.tokensWithdrawn.toString()),\n feesToTreasury: BigInt(event.feesToTreasury.toString()),\n treasuryTokens: BigInt(event.treasuryTokens.toString()),\n timestamp: BigInt(event.timestamp.toString()),\n }, slot, signature);\n });\n }\n\n /**\n * Remove an event listener\n * @param listenerId The ID returned from addEventListener\n */\n async removeEventListener(listenerId: number): Promise<void> {\n await this.program.removeEventListener(listenerId);\n }\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Math Helpers (Pure functions, no async)\n // ═══════════════════════════════════════════════════════════════════════════\n\n /** Calculate price at a given supply: price = k × supply / K_SCALE */\n calculatePrice(k: bigint, supply: bigint): bigint {\n if (supply === 0n) return 0n;\n return (k * supply) / K_SCALE;\n }\n\n /** Calculate cost to buy from s1 to s2: cost = (k/2) × (s2² - s1²) / K_SCALE */\n calculateCost(k: bigint, s1: bigint, s2: bigint): bigint {\n if (s2 <= s1) return 0n;\n const s1Sq = s1 * s1;\n const s2Sq = s2 * s2;\n const diffSq = s2Sq - s1Sq;\n return (k * diffSq) / 2n / K_SCALE;\n }\n\n /** Calculate tokens received for SOL: s2 = sqrt(s1² + 2×sol×K_SCALE/k) */\n calculateTokensForSol(k: bigint, currentSupply: bigint, solIn: bigint): bigint {\n if (solIn === 0n || k === 0n) return 0n;\n\n const s1Sq = currentSupply * currentSupply;\n const addition = (2n * solIn * K_SCALE) / k;\n const s2Sq = s1Sq + addition;\n const s2 = this.isqrt(s2Sq);\n\n return s2 - currentSupply;\n }\n\n /** Calculate tokens to sell to receive target SOL: inverse of refund formula\n * s2 = sqrt(s1² - 2×solOut×K_SCALE/k), return s1 - s2 */\n calculateTokensForSolSell(k: bigint, currentSupply: bigint, solOut: bigint): bigint {\n if (solOut === 0n || k === 0n) return 0n;\n\n const s1Sq = currentSupply * currentSupply;\n const subtraction = (2n * solOut * K_SCALE) / k;\n\n // If subtraction exceeds s1², need to sell all tokens\n if (subtraction >= s1Sq) return currentSupply;\n\n const s2Sq = s1Sq - subtraction;\n const s2 = this.isqrt(s2Sq);\n\n return currentSupply - s2;\n }\n\n /** Calculate refund for selling tokens: refund = (k/2) × (s1² - s2²) / K_SCALE */\n calculateRefund(k: bigint, s1: bigint, s2: bigint): bigint {\n if (s1 <= s2) return 0n;\n const s1Sq = s1 * s1;\n const s2Sq = s2 * s2;\n const diffSq = s1Sq - s2Sq;\n return (k * diffSq) / 2n / K_SCALE;\n }\n\n /** Integer square root using Newton's method */\n isqrt(n: bigint): bigint {\n if (n === 0n) return 0n;\n if (n === 1n) return 1n;\n\n let x = n;\n let y = (x + 1n) / 2n;\n\n while (y < x) {\n x = y;\n y = (x + n / x) / 2n;\n }\n\n return x;\n }\n\n /** Calculate K for a given target SOL and curve supply */\n static calculateK(curveSupply: bigint, targetSol: bigint): bigint {\n // k = 2 × target_sol × K_SCALE / curve_supply²\n const numerator = 2n * targetSol * K_SCALE;\n const denominator = curveSupply * curveSupply;\n return numerator / denominator;\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Utility Functions\n// ═══════════════════════════════════════════════════════════════════════════\n\n/** Format raw token amount to human-readable */\nexport function formatTokens(raw: bigint): string {\n const tokens = Number(raw) / (10 ** TOKEN_DECIMALS);\n return tokens.toLocaleString(undefined, { maximumFractionDigits: 2 });\n}\n\n/** Format lamports to SOL */\nexport function formatSol(lamports: bigint): string {\n const sol = Number(lamports) / LAMPORTS_PER_SOL;\n return sol.toFixed(4);\n}\n\n/** Parse SOL to lamports */\nexport function parseSol(sol: number): bigint {\n return BigInt(Math.floor(sol * LAMPORTS_PER_SOL));\n}\n\n/** Parse tokens to raw */\nexport function parseTokens(tokens: number): bigint {\n return BigInt(Math.floor(tokens * (10 ** TOKEN_DECIMALS)));\n}\n\nexport default KickFunSDK;\n"]}
package/dist/index.mjs CHANGED
@@ -235,7 +235,7 @@ var KickFunSDK = class {
235
235
  };
236
236
  }
237
237
  // ═══════════════════════════════════════════════════════════════════════════
238
- // Estimate Buy (tokens received for SOL)
238
+ // Estimate Buy (input SOL output tokens)
239
239
  // ═══════════════════════════════════════════════════════════════════════════
240
240
  async estimateBuy(mint, solAmount) {
241
241
  const addresses = this.deriveAddresses(mint);
@@ -243,27 +243,45 @@ var KickFunSDK = class {
243
243
  const k = BigInt(curve.k.toString());
244
244
  const soldSupply = BigInt(curve.soldSupply.toString());
245
245
  const tokensForCurve = BigInt(curve.tokensForCurve.toString());
246
- const solLamports = BigInt(Math.floor(solAmount * LAMPORTS_PER_SOL));
247
- const feeAmount = solLamports / 100n;
248
- const solAfterFees = solLamports - feeAmount;
249
- const tokensOut = this.calculateTokensForSol(k, soldSupply, solAfterFees);
246
+ const solIn = BigInt(Math.floor(solAmount * LAMPORTS_PER_SOL));
247
+ const fee = solIn / 100n;
248
+ const solAfterFee = solIn - fee;
249
+ const tokensOut = this.calculateTokensForSol(k, soldSupply, solAfterFee);
250
250
  const available = tokensForCurve - soldSupply;
251
251
  const actualTokensOut = tokensOut > available ? available : tokensOut;
252
- const pricePerToken = solAfterFees / (actualTokensOut / BigInt(10 ** TOKEN_DECIMALS));
252
+ const tokenUnits = actualTokensOut / BigInt(10 ** TOKEN_DECIMALS);
253
+ const pricePerToken = tokenUnits > 0n ? solAfterFee / tokenUnits : 0n;
253
254
  const newSoldSupply = soldSupply + actualTokensOut;
254
255
  const priceBefore = this.calculatePrice(k, soldSupply);
255
256
  const priceAfter = this.calculatePrice(k, newSoldSupply);
256
257
  const priceImpactBps = priceBefore > 0n ? Number((priceAfter - priceBefore) * 10000n / priceBefore) : 0;
257
- return {
258
- tokensOut: actualTokensOut,
259
- solCost: solLamports,
260
- pricePerToken,
261
- priceImpactBps,
262
- feeAmount
263
- };
258
+ return { solIn, solAfterFee, tokensOut: actualTokensOut, fee, pricePerToken, priceImpactBps };
264
259
  }
265
260
  // ═══════════════════════════════════════════════════════════════════════════
266
- // Estimate Sell (SOL received for tokens)
261
+ // Estimate Buy by Tokens (input tokens output SOL needed)
262
+ // ═══════════════════════════════════════════════════════════════════════════
263
+ async estimateBuyByTokens(mint, tokenAmount) {
264
+ const addresses = this.deriveAddresses(mint);
265
+ const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);
266
+ const k = BigInt(curve.k.toString());
267
+ const soldSupply = BigInt(curve.soldSupply.toString());
268
+ const tokensForCurve = BigInt(curve.tokensForCurve.toString());
269
+ const tokensRaw = BigInt(tokenAmount) * BigInt(10 ** TOKEN_DECIMALS);
270
+ const available = tokensForCurve - soldSupply;
271
+ const actualTokensOut = tokensRaw > available ? available : tokensRaw;
272
+ const solAfterFee = this.calculateCost(k, soldSupply, soldSupply + actualTokensOut);
273
+ const solIn = solAfterFee * 100n / 99n;
274
+ const fee = solIn - solAfterFee;
275
+ const tokenUnits = actualTokensOut / BigInt(10 ** TOKEN_DECIMALS);
276
+ const pricePerToken = tokenUnits > 0n ? solAfterFee / tokenUnits : 0n;
277
+ const newSoldSupply = soldSupply + actualTokensOut;
278
+ const priceBefore = this.calculatePrice(k, soldSupply);
279
+ const priceAfter = this.calculatePrice(k, newSoldSupply);
280
+ const priceImpactBps = priceBefore > 0n ? Number((priceAfter - priceBefore) * 10000n / priceBefore) : 0;
281
+ return { solIn, solAfterFee, tokensOut: actualTokensOut, fee, pricePerToken, priceImpactBps };
282
+ }
283
+ // ═══════════════════════════════════════════════════════════════════════════
284
+ // Estimate Sell (input tokens → output SOL)
267
285
  // ═══════════════════════════════════════════════════════════════════════════
268
286
  async estimateSell(mint, tokenAmount) {
269
287
  const addresses = this.deriveAddresses(mint);
@@ -271,28 +289,46 @@ var KickFunSDK = class {
271
289
  const k = BigInt(curve.k.toString());
272
290
  const soldSupply = BigInt(curve.soldSupply.toString());
273
291
  const realSolReserves = BigInt(curve.realSolReserves.toString());
274
- const tokensRaw = BigInt(tokenAmount) * BigInt(10 ** TOKEN_DECIMALS);
275
- if (tokensRaw > soldSupply) {
292
+ const tokensIn = BigInt(tokenAmount) * BigInt(10 ** TOKEN_DECIMALS);
293
+ if (tokensIn > soldSupply) {
276
294
  throw new Error(`Cannot sell ${tokenAmount} tokens. Only ${soldSupply / BigInt(10 ** TOKEN_DECIMALS)} available.`);
277
295
  }
278
- const grossRefund = this.calculateRefund(k, soldSupply, soldSupply - tokensRaw);
279
- const cappedRefund = grossRefund > realSolReserves ? realSolReserves : grossRefund;
280
- const feeAmount = cappedRefund / 100n;
281
- const netSolOut = cappedRefund - feeAmount;
282
- const pricePerToken = netSolOut / BigInt(tokenAmount);
283
- const newSoldSupply = soldSupply - tokensRaw;
296
+ const grossRefund = this.calculateRefund(k, soldSupply, soldSupply - tokensIn);
297
+ const solBeforeFee = grossRefund > realSolReserves ? realSolReserves : grossRefund;
298
+ const fee = solBeforeFee / 100n;
299
+ const solOut = solBeforeFee - fee;
300
+ const pricePerToken = tokenAmount > 0 ? solOut / BigInt(tokenAmount) : 0n;
301
+ const newSoldSupply = soldSupply - tokensIn;
284
302
  const priceBefore = this.calculatePrice(k, soldSupply);
285
303
  const priceAfter = this.calculatePrice(k, newSoldSupply);
286
304
  const priceImpactBps = priceBefore > 0n ? Number((priceBefore - priceAfter) * 10000n / priceBefore) : 0;
287
- return {
288
- tokensOut: tokensRaw,
289
- // tokens being sold
290
- solCost: netSolOut,
291
- // SOL to receive
292
- pricePerToken,
293
- priceImpactBps,
294
- feeAmount
295
- };
305
+ return { tokensIn, solBeforeFee, solOut, fee, pricePerToken, priceImpactBps };
306
+ }
307
+ // ═══════════════════════════════════════════════════════════════════════════
308
+ // Estimate Sell by SOL (input SOL desired → output tokens to sell)
309
+ // ═══════════════════════════════════════════════════════════════════════════
310
+ async estimateSellBySol(mint, solAmount) {
311
+ const addresses = this.deriveAddresses(mint);
312
+ const curve = await this.program.account.bondingCurve.fetch(addresses.bondingCurve);
313
+ const k = BigInt(curve.k.toString());
314
+ const soldSupply = BigInt(curve.soldSupply.toString());
315
+ const realSolReserves = BigInt(curve.realSolReserves.toString());
316
+ const solDesired = BigInt(Math.floor(solAmount * LAMPORTS_PER_SOL));
317
+ const solBeforeFee = solDesired * 100n / 99n;
318
+ const cappedGross = solBeforeFee > realSolReserves ? realSolReserves : solBeforeFee;
319
+ const tokensIn = this.calculateTokensForSolSell(k, soldSupply, cappedGross);
320
+ const actualTokensIn = tokensIn > soldSupply ? soldSupply : tokensIn;
321
+ const actualGross = this.calculateRefund(k, soldSupply, soldSupply - actualTokensIn);
322
+ const actualSolBeforeFee = actualGross > realSolReserves ? realSolReserves : actualGross;
323
+ const fee = actualSolBeforeFee / 100n;
324
+ const solOut = actualSolBeforeFee - fee;
325
+ const tokenUnits = actualTokensIn / BigInt(10 ** TOKEN_DECIMALS);
326
+ const pricePerToken = tokenUnits > 0n ? solOut / tokenUnits : 0n;
327
+ const newSoldSupply = soldSupply - actualTokensIn;
328
+ const priceBefore = this.calculatePrice(k, soldSupply);
329
+ const priceAfter = this.calculatePrice(k, newSoldSupply);
330
+ const priceImpactBps = priceBefore > 0n ? Number((priceBefore - priceAfter) * 10000n / priceBefore) : 0;
331
+ return { tokensIn: actualTokensIn, solBeforeFee: actualSolBeforeFee, solOut, fee, pricePerToken, priceImpactBps };
296
332
  }
297
333
  // ═══════════════════════════════════════════════════════════════════════════
298
334
  // Get Curve State
@@ -495,6 +531,17 @@ var KickFunSDK = class {
495
531
  const s2 = this.isqrt(s2Sq);
496
532
  return s2 - currentSupply;
497
533
  }
534
+ /** Calculate tokens to sell to receive target SOL: inverse of refund formula
535
+ * s2 = sqrt(s1² - 2×solOut×K_SCALE/k), return s1 - s2 */
536
+ calculateTokensForSolSell(k, currentSupply, solOut) {
537
+ if (solOut === 0n || k === 0n) return 0n;
538
+ const s1Sq = currentSupply * currentSupply;
539
+ const subtraction = 2n * solOut * K_SCALE / k;
540
+ if (subtraction >= s1Sq) return currentSupply;
541
+ const s2Sq = s1Sq - subtraction;
542
+ const s2 = this.isqrt(s2Sq);
543
+ return currentSupply - s2;
544
+ }
498
545
  /** Calculate refund for selling tokens: refund = (k/2) × (s1² - s2²) / K_SCALE */
499
546
  calculateRefund(k, s1, s2) {
500
547
  if (s1 <= s2) return 0n;