Skip to main content

Installation & Setup

  • NPM Package
  • Development
# Production SDK
pnpm add @b3dotfun/sdk

# Import from main SDK
import { 
  BondkitTokenFactory, 
  BondkitToken 
} from "@b3dotfun/sdk/bondkit";

Core Classes

BondkitTokenFactory

The factory class handles deploying new bond tokens and querying deployed tokens.
import { BondkitTokenFactory } from "@b3dotfun/sdk/bondkit";
import { base } from "viem/chains";

const factory = new BondkitTokenFactory(
  base.id,                    // Chain ID (Base mainnet)
  process.env.WALLET_KEY      // Optional: private key for writes
);

Constructor

constructor(
  chainId: SupportedChainId,
  walletKey?: string
)
ParameterTypeRequiredDescription
chainIdnumberYesChain ID (currently only Base: 8453)
walletKeystringNoPrivate key for write operations

Methods

Deploy a new bond token
async deployBondkitToken(
  config: BondkitTokenConfig
): Promise<Address>
Parameters:
interface BondkitTokenConfig {
  name: string;                      // Token name
  symbol: string;                    // Token symbol
  feeRecipient: Address;            // Receives trading fees
  finalTokenSupply: bigint;         // Total supply (18 decimals)
  aggressivenessFactor: number;     // 0-100 curve steepness
  lpSplitRatioFeeRecipientBps: bigint; // LP fee share (basis points)
  targetAmount: bigint;             // Migration target in trading token (18 decimals)
  migrationAdminAddress: Address;   // Can trigger migration
  bondingPhaseSplitter: Address;    // Bonding phase fee splitter
  v4PoolManager: Address;           // Uniswap V4 pool manager
  v4Hook: Address;                  // Custom Uniswap V4 hook
  v4PoolFee: number;                // Pool fee tier (3000 = 0.3%)
  v4TickSpacing: number;            // Tick spacing for the pool
  tradingToken: Address;            // Token used for trading (B3/ETH/etc)
}
Example:
const tokenAddress = await factory.deployBondkitToken({
  name: "My Token",
  symbol: "MTK",
  feeRecipient: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
  finalTokenSupply: parseEther("1000000"),
  aggressivenessFactor: 50,
  lpSplitRatioFeeRecipientBps: 1000n, // 10%
  targetAmount: parseEther("10"),
  migrationAdminAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
  bondingPhaseSplitter: "0x2AB69e0d9D20D3700466153D84a6574128154Fd2",
  v4PoolManager: "0x498581fF718922c3f8e6A244956aF099B2652b2b",
  v4Hook: "0xB36f4A2FB18b745ef8eD31452781a463d2B3f0cC",
  v4PoolFee: 3000,
  v4TickSpacing: 60,
  tradingToken: "0xB3B32F9f8827D4634fE7d973Fa1034Ec9fdDB3B3"
});
Get all deployed tokens
async getDeployedBondkitTokens(): Promise<Address[]>
Returns: Array of token addressesExample:
const tokens = await factory.getDeployedBondkitTokens();
console.log(`Found ${tokens.length} tokens`);
Get token configuration
async getBondkitTokenConfig(
  tokenAddress: Address
): Promise<BondkitTokenConfig>
Example:
const config = await factory.getBondkitTokenConfig(
  "0x123..."
);
console.log(`Token name: ${config.name}`);
Get implementation contract
async getImplementationAddress(): Promise<Address>
Example:
const impl = await factory.getImplementationAddress();
console.log(`Implementation: ${impl}`);
Connect wallet provider
connect(provider?: EIP1193Provider): boolean
Example:
// Browser environment
const connected = factory.connect(window.ethereum);

// Custom provider
import { custom } from "viem";
const transport = custom(provider);
factory.connect(transport);

BondkitToken

The token class handles all operations for a specific bond token.
import { BondkitToken } from "@b3dotfun/sdk/bondkit";

const token = new BondkitToken(
  "0x123...",                 // Token address
  process.env.WALLET_KEY      // Optional: private key
);

Constructor

constructor(
  contractAddress: string,
  walletKey?: string
)
ParameterTypeRequiredDescription
contractAddressstringYesToken contract address
walletKeystringNoPrivate key for write operations

Read Methods

// Basic token info
async name(): Promise<string>
async symbol(): Promise<string>
async decimals(): Promise<number>
async totalSupply(): Promise<bigint>

// Balances
async balanceOf(address: Address): Promise<bigint>
async allowance(
  owner: Address, 
  spender: Address
): Promise<bigint>

// Example
const balance = await token.balanceOf(userAddress);
console.log(`Balance: ${formatEther(balance)}`);
// Current price per token
async getCurrentBondingCurvePricePerToken(): Promise<bigint>

// Current price in trading token
async getCurrentPrice(): Promise<bigint>

// Quote for buying
async getAmountOfTokensToBuy(
  tradingTokenAmount: bigint | string
): Promise<bigint>

// Quote for selling
async getAmountOfTradingTokensToSell(
  tokenAmount: bigint
): Promise<bigint>

// Bonding progress
async getBondingProgress(): Promise<{
  progress: number;      // 0-1 (percentage)
  raised: number;        // Amount raised (converted to number)
  threshold: number;     // Target amount (converted to number)
}>

// Example
const progress = await token.getBondingProgress();
console.log(`Progress: ${(progress.progress * 100).toFixed(2)}%`);
// Token state
async getStatus(): Promise<TokenStatus>
async isMigrated(): Promise<boolean>
async canMigrate(): Promise<boolean>

// Configuration
async getOwner(): Promise<Address>
async getFeeRecipient(): Promise<Address>
async getAggressivenessFactor(): Promise<number>
async getTargetAmount(): Promise<bigint>

// Migration info
async getMigrationData(): Promise<{
  ethForLp: bigint;
  tokensForLp: bigint;
  sqrtPriceX96: bigint;
}>

// Example
if (await token.canMigrate()) {
  console.log("Ready to migrate!");
}
// Token holders
async getPaginatedHolders(
  offset: number,
  limit: number
): Promise<{
  holders: Address[];
  total: number;
}>

// Transaction history (from API)
async getTransactionHistory(
  options?: GetTransactionHistoryOptions
): Promise<TransactionResponse>

// Options interface
interface GetTransactionHistoryOptions {
  userAddress?: Address;
  type?: "buy" | "sell";
  from?: number;        // Timestamp
  to?: number;          // Timestamp
  limit?: number;       // 1-100
  offset?: number;
}

// Example
const history = await token.getTransactionHistory({
  type: "buy",
  limit: 10
});
Methods for interacting with the trading token
// Get trading token address (B3/ETH/etc)
async getTradingTokenAddress(): Promise<Address>

// Get trading token symbol  
async getTradingTokenSymbol(): Promise<string>

// Get user's trading token balance
async getTradingTokenBalanceOf(account: Address): Promise<bigint>

// Check current token status/phase
async currentStatus(): Promise<TokenStatus>
async getCurrentPhase(): Promise<string>

// Check if DEX swapping is available
async isSwapAvailable(): Promise<boolean>
Example:
// Check what trading token is used
const tradingTokenAddress = await token.getTradingTokenAddress();
const tradingTokenSymbol = await token.getTradingTokenSymbol();
console.log(`Trading with: ${tradingTokenSymbol} (${tradingTokenAddress})`);

// Check user's trading token balance
const tradingBalance = await token.getTradingTokenBalanceOf(userAddress);
console.log(`Trading token balance: ${formatEther(tradingBalance)}`);

// Check current phase
const status = await token.currentStatus();
if (status === TokenStatus.Dex) {
  console.log("Token is in DEX trading phase");
}
Built-in swap methods for DEX phase trading
// Get swap quotes
async getSwapQuoteForBondkitToken(
  amountTradingTokenIn: string,
  slippageTolerance?: number
): Promise<SwapQuote | null>

async getSwapQuoteForTradingToken(
  amountBondkitTokenIn: string, 
  slippageTolerance?: number
): Promise<SwapQuote | null>

// Execute swaps
async swapTradingTokenForBondkitToken(
  amountTradingTokenIn: string,
  slippageTolerance?: number,
  walletClient: WalletClient
): Promise<string | null>

async swapBondkitTokenForTradingToken(
  amountBondkitTokenIn: string,
  slippageTolerance?: number, 
  walletClient: WalletClient
): Promise<string | null>
Example:
// Check if swapping is available (DEX phase only)
const canSwap = await token.isSwapAvailable();
if (!canSwap) {
  console.log("Still in bonding phase - use buy()/sell()");
  return;
}

// Get quote for trading 100 B3 tokens → bondkit tokens
const quote = await token.getSwapQuoteForBondkitToken(
  "100",      // 100 trading tokens
  0.005       // 0.5% slippage
);

if (quote) {
  console.log(`Will receive: ${quote.amountOut} bondkit tokens`);
  console.log(`Price impact: ${quote.priceImpact}%`);
  
  // Execute the swap
  const txHash = await token.swapTradingTokenForBondkitToken(
    "100",
    0.005,
    walletClient
  );
  console.log(`Swap completed: ${txHash}`);
}

Write Methods

Buy tokens with trading token
async buy(
  amount: bigint | string,
  minTokensOut: bigint
): Promise<Hex>
Parameters:
  • amount: Amount of trading token to spend (as string or bigint)
  • minTokensOut: Minimum tokens to receive (slippage protection)
Example:
// Get quote first
const quote = await token.getAmountOfTokensToBuy(
  parseEther("100") // 100 trading tokens
);

// Buy with 5% slippage tolerance
const minTokens = quote * 95n / 100n;
const txHash = await token.buy(
  parseEther("100"), // amount: 100 trading tokens
  minTokens          // minTokensOut: slippage protection
);

console.log(`Transaction: ${txHash}`);
Sell tokens for trading token
async sell(
  tokenAmount: bigint,
  minTradingTokenOut: bigint
): Promise<Hex>
Parameters:
  • tokenAmount: Amount of tokens to sell
  • minTradingTokenOut: Minimum trading token to receive (slippage protection)
Example:
// Sell 1000 tokens
const sellAmount = parseEther("1000");

// Get quote
const quote = await token.getAmountOfTradingTokensToSell(sellAmount);

// Sell with slippage protection
const minTradingTokenOut = quote * 95n / 100n;
const txHash = await token.sell(sellAmount, minTradingTokenOut);
Migrate to Uniswap v4
async migrateToDex(): Promise<Hex>
Requirements:
  • Caller must be migration admin
  • Target must be reached
Example:
if (await token.canMigrate()) {
  const txHash = await token.migrateToDex();
  console.log(`Migration tx: ${txHash}`);
}
Transfer or renounce token ownership
// Transfer ownership to new address
async transferTokenOwnership(
  newOwner: Address
): Promise<Hex>

// Renounce ownership (irreversible)
async renounceTokenOwnership(): Promise<Hex>
Example:
// Transfer ownership to multisig
const multisig = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1";
await token.transferTokenOwnership(multisig);

// Or renounce ownership completely (be careful!)
await token.renounceTokenOwnership();
Important: Renouncing ownership is irreversible and removes all admin capabilities. Only do this after migration or if you want to make the token completely decentralized.
// Standard transfers
async transfer(
  to: Address,
  amount: bigint
): Promise<Hex>

async transferFrom(
  from: Address,
  to: Address,
  amount: bigint
): Promise<Hex>

// Approvals
async approve(
  spender: Address,
  amount: bigint
): Promise<Hex>

// Example
await token.approve(
  spenderAddress,
  parseEther("1000")
);

Event Listeners

// Listen for buy events
token.onBuy((event: BoughtEventArgs) => {
  console.log("Buy:", {
    buyer: event.buyer,
    tradingTokenIn: formatEther(event.ethIn), // Note: 'ethIn' field represents trading token
    tokensOut: formatEther(event.tokensOut),
    fee: formatEther(event.feeRecipientFee)
  });
});

// Listen for sell events
token.onSell((event: SoldEventArgs) => {
  console.log("Sell:", {
    seller: event.seller,
    tokensIn: formatEther(event.tokensIn),
    tradingTokenOut: formatEther(event.ethOut), // Note: 'ethOut' field represents trading token
    fee: formatEther(event.feeRecipientFee)
  });
});

// Listen for migration
token.onMigration((event: DexMigrationEventArgs) => {
  console.log("Migrated:", {
    ethForLp: formatEther(event.ethForLp),
    tokensForLp: formatEther(event.tokensForLp)
  });
});

BondkitSwapService

The swap service handles Uniswap V4 trading for tokens after they migrate to the DEX phase.
When to use: After migration when tokens are trading on Uniswap V4. During bonding phase, use token.buy() and token.sell() instead.

Constructor

import { BondkitSwapService } from "@b3dotfun/sdk/bondkit";

const swapService = new BondkitSwapService(
  "0x123..." // bondkitTokenAddress
);

Methods

Get swap price quote
async getSwapQuote(params: SwapParams): Promise<SwapQuote | null>
Parameters:
interface SwapParams {
  tokenIn: Address;           // Token to sell
  tokenOut: Address;          // Token to buy
  amountIn: string;           // Amount to sell (human readable)
  tokenInDecimals: number;    // Decimals of input token
  tokenOutDecimals: number;   // Decimals of output token
  slippageTolerance: number;  // Slippage tolerance (0.01 = 1%)
  recipient: Address;         // Address to receive tokens
  deadline?: number;          // Transaction deadline (timestamp)
}
Returns:
interface SwapQuote {
  amountOut: string;          // Expected output amount
  amountOutMin: string;       // Minimum output (with slippage)
  priceImpact: string;        // Price impact percentage
  executionPrice: string;     // Execution price
  fee: string;                // Swap fee
}
Example:
// Get quote for swapping 100 B3 tokens for bondkit tokens
const quote = await swapService.getSwapQuote({
  tokenIn: "0xB3B32F9f8827D4634fE7d973Fa1034Ec9fdDB3B3", // B3 token
  tokenOut: bondkitTokenAddress,
  amountIn: "100",
  tokenInDecimals: 18,
  tokenOutDecimals: 18,
  slippageTolerance: 0.005, // 0.5%
  recipient: userAddress
});

if (quote) {
  console.log(`Will receive: ${quote.amountOut} tokens`);
  console.log(`Price impact: ${quote.priceImpact}%`);
}
Execute swap transaction
async executeSwap(params: SwapParams, walletClient: WalletClient): Promise<string | null>
Parameters:
  • params: Same SwapParams as getSwapQuote
  • walletClient: Connected wallet client
Example:
// First get a quote
const quote = await swapService.getSwapQuote(swapParams);

if (quote) {
  // Execute the swap
  const txHash = await swapService.executeSwap(
    swapParams,
    walletClient
  );
  
  console.log(`Swap executed: ${txHash}`);
}

Complete Example

import { BondkitSwapService } from "@b3dotfun/sdk/bondkit";
import { createWalletClient, custom } from "viem";

// Initialize service
const swapService = new BondkitSwapService(bondkitTokenAddress);

// Set up swap parameters
const swapParams = {
  tokenIn: "0xB3B32F9f8827D4634fE7d973Fa1034Ec9fdDB3B3", // B3 token
  tokenOut: bondkitTokenAddress,
  amountIn: "50", // 50 B3 tokens
  tokenInDecimals: 18,
  tokenOutDecimals: 18,
  slippageTolerance: 0.01, // 1%
  recipient: userAddress,
  deadline: Math.floor(Date.now() / 1000) + 1200 // 20 minutes
};

// Get quote and execute if acceptable
const quote = await swapService.getSwapQuote(swapParams);

if (quote && parseFloat(quote.priceImpact) < 5) {
  console.log(`Swapping ${swapParams.amountIn} B3 for ${quote.amountOut} tokens`);
  
  const walletClient = createWalletClient({
    transport: custom(window.ethereum)
  });
  
  const txHash = await swapService.executeSwap(swapParams, walletClient);
  console.log(`Transaction: ${txHash}`);
} else {
  console.log("Price impact too high or quote failed");
}
Important Notes:
  • Only works after token migration to DEX phase
  • Automatically handles token approvals (ERC20 → Permit2 → Universal Router)
  • Uses Uniswap V4 with custom hooks and pool configuration
  • Slippage protection is built into the quotes

TradingView Component

A React component that renders professional trading charts for Bondkit tokens using TradingView’s charting library.
Use case: Display price charts, volume data, and trading indicators for your Bondkit tokens in web applications.

Installation & Setup

import TradingView from "@b3dotfun/sdk/bondkit/components/TradingView";
Requirements:
  • React 18+
  • TradingView charting library (loaded automatically from CDN)
  • Tailwind CSS for styling (optional, but recommended)

Props

interface TradingViewProps {
  className?: string;      // CSS classes for styling
  tokenAddress?: string;   // Bondkit token address
  tokenSymbol?: string;    // Token symbol (e.g., "DEMO")
}

Basic Usage

import React from "react";
import TradingView from "@b3dotfun/sdk/bondkit/components/TradingView";

function TokenChart({ token }) {
  return (
    <div className="h-96 w-full">
      <TradingView 
        tokenAddress={token.address}
        tokenSymbol={token.symbol}
        className="w-full h-full"
      />
    </div>
  );
}

Advanced Configuration

// In your Next.js app, configure the CDN
// next.config.js
module.exports = {
  env: {
    NEXT_PUBLIC_CDN_URL: "https://your-cdn-domain.com",
    NEXT_PUBLIC_FORCE_CDN: "true" // Force CDN usage in development
  }
};

// Custom styled chart
function ProfessionalChart({ tokenAddress, tokenSymbol }) {
  return (
    <div className="rounded-lg border bg-white shadow-lg">
      <div className="p-4 border-b">
        <h3 className="font-semibold">{tokenSymbol} Price Chart</h3>
      </div>
      <div className="h-[500px] p-4">
        <TradingView 
          tokenAddress={tokenAddress}
          tokenSymbol={tokenSymbol}
          className="w-full h-full rounded"
        />
      </div>
    </div>
  );
}

Features

Built-in Support:
  • Candlestick charts
  • Volume indicators
  • Price overlays
  • Technical analysis tools
  • Multiple timeframes (1m, 5m, 1h, 1D, etc.)
Customization:
  • Light/dark themes
  • Responsive design
  • Mobile-friendly interface
  • Professional trading UI
Automatic Data Feeds:
  • Real-time price data from B3 API
  • OHLCV (Open, High, Low, Close, Volume) data
  • Historical price charts
  • Transaction-based price updates
UDF Compatible:
  • Standard TradingView datafeed format
  • Configurable API endpoints
  • Fallback configurations
Optimized Loading:
  • TradingView library loaded from CDN
  • Lazy loading with loading states
  • Error handling and fallbacks
  • Configurable CDN domains
Production Ready:
  • Automatic CDN switching
  • Custom domain support
  • Development/production configurations

Complete Integration Example

import React, { useState, useEffect } from "react";
import { BondkitToken } from "@b3dotfun/sdk/bondkit";
import TradingView from "@b3dotfun/sdk/bondkit/components/TradingView";

function TokenDashboard({ tokenAddress }) {
  const [tokenData, setTokenData] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    const loadTokenData = async () => {
      try {
        const token = new BondkitToken(tokenAddress);
        const [details, price, progress] = await Promise.all([
          token.getTokenDetails(),
          token.getCurrentPrice(), 
          token.getBondingProgress()
        ]);
        
        setTokenData({ details, price, progress });
      } catch (error) {
        console.error("Failed to load token data:", error);
      } finally {
        setLoading(false);
      }
    };
    
    loadTokenData();
  }, [tokenAddress]);
  
  if (loading) return <div>Loading...</div>;
  
  return (
    <div className="space-y-6">
      {/* Token Info */}
      <div className="grid grid-cols-3 gap-4">
        <div className="bg-white p-4 rounded-lg shadow">
          <h3 className="font-medium text-gray-500">Token</h3>
          <p className="text-2xl font-bold">{tokenData.details.symbol}</p>
        </div>
        <div className="bg-white p-4 rounded-lg shadow">
          <h3 className="font-medium text-gray-500">Price</h3>
          <p className="text-2xl font-bold">${formatEther(tokenData.price)}</p>
        </div>
        <div className="bg-white p-4 rounded-lg shadow">
          <h3 className="font-medium text-gray-500">Progress</h3>
          <p className="text-2xl font-bold">{(tokenData.progress.progress * 100).toFixed(1)}%</p>
        </div>
      </div>
      
      {/* Trading Chart */}
      <div className="bg-white rounded-lg shadow overflow-hidden">
        <div className="p-4 border-b">
          <h2 className="text-lg font-semibold">Price Chart</h2>
        </div>
        <div className="h-96">
          <TradingView 
            tokenAddress={tokenAddress}
            tokenSymbol={tokenData.details.symbol}
            className="w-full h-full"
          />
        </div>
      </div>
    </div>
  );
}

CDN Configuration

// utils/cdn.ts - Configure your CDN settings
export const CDN_CONFIG = {
  baseUrl: process.env.NEXT_PUBLIC_CDN_URL || "https://cdn.b3.fun",
  chartingLibrary: {
    basePath: "/static/charting_library",
    // TradingView library files will be loaded from this path
  }
};

// Check CDN availability
import { checkCDNResource, preloadFromCDN } from "@b3dotfun/sdk/bondkit/components";

// Preload TradingView library
preloadFromCDN("/static/charting_library/charting_library.js");
Setup Requirements:
  1. TradingView License: Ensure you have proper licensing for TradingView library usage
  2. CDN Setup: Configure CDN URLs in your environment variables
  3. API Access: Ensure your app can access the B3 analytics API for chart data
  4. CORS: Configure CORS settings if using custom API endpoints

Type Definitions

Core Types

// Token configuration
interface BondkitTokenConfig {
  name: string;
  symbol: string;
  feeRecipient: Address;
  finalTokenSupply: bigint;
  aggressivenessFactor: number;
  lpSplitRatioFeeRecipientBps: bigint;
  targetAmount: bigint;
  migrationAdminAddress: Address;
  bondingPhaseSplitter: Address;
  v4PoolManager: Address;
  v4Hook: Address;
  v4PoolFee: number;
  v4TickSpacing: number;
  tradingToken: Address;
}

// Token status enum
enum TokenStatus {
  Uninitialized = 0,
  Bonding = 1,
  Dex = 2
}

// Token details
interface TokenDetails {
  name: string;
  symbol: string;
  decimals: number;
  totalSupply: bigint;
  owner: Address;
}

Event Types

// Buy event
interface BoughtEventArgs {
  buyer: Address;
  ethIn: bigint;
  tokensOut: bigint;
  feeRecipientFee: bigint;
}

// Sell event
interface SoldEventArgs {
  seller: Address;
  tokensIn: bigint;
  ethOut: bigint;
  feeRecipientFee: bigint;
}

// Migration event
interface DexMigrationEventArgs {
  ethForLp: bigint;
  tokensForLp: bigint;
  ethForFeeRecipient: bigint;
}

// Factory creation event
interface BondkitTokenCreatedEventArgs {
  tokenAddress: Address;
  implementationAddress: Address;
  name: string;
  symbol: string;
  feeRecipient: Address;
  migrationAdmin: Address;
}

Transaction Types

// Transaction history
interface Transaction {
  timestamp: number;
  price: number;
  amount: string;
  type: "buy" | "sell";
  userAddress: Address;
  txHash: Hex;
  chainId: number;
  blockNumber?: number;
  totalRaisedBonding?: string;
  value?: string;
}

// API response
interface TransactionResponse {
  total: number;
  limit: number;
  skip: number;
  data: Transaction[];
}

Configuration

Network Support

import { getConfig } from "@b3dotfun/sdk/bondkit";
import { base } from "viem/chains";

const config = getConfig(base.id);

console.log({
  chain: config.chain.name,           // "Base"
  factoryAddress: config.factoryAddress,
  rpcUrl: config.rpcUrl,
  apiEndpoint: config.apiEndpoint
});

Supported Chains

ChainChain IDStatus
Base Mainnet8453✅ Supported
Base Sepolia84532🚧 Coming Soon

Error Handling

try {
  const txHash = await token.buy(minTokens, "1");
} catch (error) {
  if (error.message.includes("insufficient funds")) {
    console.error("Not enough ETH");
  } else if (error.message.includes("slippage")) {
    console.error("Price moved, try again");
  } else if (error.message.includes("target exceeded")) {
    console.error("Would exceed migration target");
  } else {
    console.error("Transaction failed:", error);
  }
}

Complete Examples

Deploy and Trade

import { 
  BondkitTokenFactory, 
  BondkitToken 
} from "@b3dotfun/sdk/bondkit";
import { parseEther, formatEther } from "viem";
import { base } from "viem/chains";

async function deployAndTrade() {
  // 1. Deploy token
  const factory = new BondkitTokenFactory(
    base.id,
    process.env.WALLET_KEY
  );
  
  const tokenAddress = await factory.deployBondkitToken({
    name: "Test Token",
    symbol: "TEST",
    finalTokenSupply: parseEther("1000000"),
    aggressivenessFactor: 50,
    targetAmount: parseEther("10"),
    feeRecipient: process.env.WALLET_ADDRESS,
    lpSplitRatioFeeRecipientBps: 1000n,
    migrationAdminAddress: process.env.WALLET_ADDRESS,
    bondingPhaseSplitter: "0x2AB69e0d9D20D3700466153D84a6574128154Fd2",
    v4PoolManager: "0x498581fF718922c3f8e6A244956aF099B2652b2b",
    v4Hook: "0xB36f4A2FB18b745ef8eD31452781a463d2B3f0cC",
    v4PoolFee: 3000,
    v4TickSpacing: 60,
    tradingToken: "0xB3B32F9f8827D4634fE7d973Fa1034Ec9fdDB3B3"
  });
  
  // 2. Initialize token client
  const token = new BondkitToken(
    tokenAddress,
    process.env.WALLET_KEY
  );
  
  // 3. Buy tokens
  const buyAmount = parseEther("0.5");
  const expectedTokens = await token.getAmountOfTokensToBuy(buyAmount);
  await token.buy(expectedTokens * 95n / 100n, "0.5");
  
  // 4. Check progress
  const progress = await token.getBondingProgress();
  console.log(`Progress: ${(progress.progress * 100).toFixed(2)}%`);
  
  // 5. Monitor events
  token.onBuy((event) => {
    console.log(`New buy: ${formatEther(event.tokensOut)} tokens`);
  });
}

Portfolio Tracker

async function trackPortfolio(userAddress: Address) {
  const factory = new BondkitTokenFactory(base.id);
  const tokens = await factory.getDeployedBondkitTokens();
  
  const portfolio = [];
  
  for (const tokenAddress of tokens) {
    const token = new BondkitToken(tokenAddress);
    const balance = await token.balanceOf(userAddress);
    
    if (balance > 0n) {
      const [name, symbol, price] = await Promise.all([
        token.name(),
        token.symbol(),
        token.getCurrentPrice()
      ]);
      
      portfolio.push({
        address: tokenAddress,
        name,
        symbol,
        balance: formatEther(balance),
        value: formatEther(balance * price / 10n ** 18n)
      });
    }
  }
  
  return portfolio;
}

Best Practices

Security Considerations
  1. Never expose private keys in client-side code
  2. Always use slippage protection in trades
  3. Validate addresses before transactions
  4. Handle errors gracefully with try-catch
  5. Monitor gas prices before large operations
Performance Tips
  1. Batch read operations with Promise.all()
  2. Cache token instances to avoid recreating
  3. Use event listeners instead of polling
  4. Implement exponential backoff for retries
  5. Consider pagination for large datasets

Support & Resources