Installation & Setup

bash
# Production SDKpnpm add @b3dotfun/sdk# Import from main SDKimport { BondkitTokenFactory, BondkitToken } from "@b3dotfun/sdk/bondkit";

Core Classes

BondkitTokenFactory

The factory class handles deploying new bond tokens and querying deployed tokens.

typescript
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

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

Methods

Deploy a new bond token

typescript
async deployBondkitToken( config: BondkitTokenConfig): Promise<Address>

Parameters:

typescript
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:

typescript
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

typescript
async getDeployedBondkitTokens(): Promise<Address[]>

Returns: Array of token addresses

Example:

typescript
const tokens = await factory.getDeployedBondkitTokens();console.log(`Found ${tokens.length} tokens`);

Get token configuration

typescript
async getBondkitTokenConfig( tokenAddress: Address): Promise<BondkitTokenConfig>

Example:

typescript
const config = await factory.getBondkitTokenConfig( "0x123...");console.log(`Token name: ${config.name}`);

Get implementation contract

typescript
async getImplementationAddress(): Promise<Address>

Example:

typescript
const impl = await factory.getImplementationAddress();console.log(`Implementation: ${impl}`);

Connect wallet provider

typescript
connect(provider?: EIP1193Provider): boolean

Example:

typescript
// Browser environmentconst connected = factory.connect(window.ethereum);// Custom providerimport { custom } from "viem";const transport = custom(provider);factory.connect(transport);

BondkitToken

The token class handles all operations for a specific bond token.

typescript
import { BondkitToken } from "@b3dotfun/sdk/bondkit";const token = new BondkitToken( "0x123...", // Token address process.env.WALLET_KEY // Optional: private key);

Constructor

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

Read Methods

typescript
// Basic token infoasync name(): Promise<string>async symbol(): Promise<string>async decimals(): Promise<number>async totalSupply(): Promise<bigint>// Balancesasync balanceOf(address: Address): Promise<bigint>async allowance( owner: Address, spender: Address): Promise<bigint>// Exampleconst balance = await token.balanceOf(userAddress);console.log(`Balance: ${formatEther(balance)}`);
typescript
// Current price per tokenasync getCurrentBondingCurvePricePerToken(): Promise<bigint>// Current price in trading tokenasync getCurrentPrice(): Promise<bigint>// Quote for buyingasync getAmountOfTokensToBuy( tradingTokenAmount: bigint | string): Promise<bigint>// Quote for sellingasync getAmountOfTradingTokensToSell( tokenAmount: bigint): Promise<bigint>// Bonding progressasync getBondingProgress(): Promise<{ progress: number; // 0-1 (percentage) raised: number; // Amount raised (converted to number) threshold: number; // Target amount (converted to number)}>// Exampleconst progress = await token.getBondingProgress();console.log(`Progress: ${(progress.progress * 100).toFixed(2)}%`);
typescript
// Token stateasync getStatus(): Promise<TokenStatus>async isMigrated(): Promise<boolean>async canMigrate(): Promise<boolean>// Configurationasync getOwner(): Promise<Address>async getFeeRecipient(): Promise<Address>async getAggressivenessFactor(): Promise<number>async getTargetAmount(): Promise<bigint>// Migration infoasync getMigrationData(): Promise<{ ethForLp: bigint; tokensForLp: bigint; sqrtPriceX96: bigint;}>// Exampleif (await token.canMigrate()) { console.log("Ready to migrate!");}
typescript
// Token holdersasync getPaginatedHolders( offset: number, limit: number): Promise<{ holders: Address[]; total: number;}>// Transaction history (from API)async getTransactionHistory( options?: GetTransactionHistoryOptions): Promise<TransactionResponse>// Options interfaceinterface GetTransactionHistoryOptions { userAddress?: Address; type?: "buy" | "sell"; from?: number; // Timestamp to?: number; // Timestamp limit?: number; // 1-100 offset?: number;}// Exampleconst history = await token.getTransactionHistory({ type: "buy", limit: 10});

Methods for interacting with the trading token

typescript
// Get trading token address (B3/ETH/etc)async getTradingTokenAddress(): Promise<Address>// Get trading token symbol async getTradingTokenSymbol(): Promise<string>// Get user's trading token balanceasync getTradingTokenBalanceOf(account: Address): Promise<bigint>// Check current token status/phaseasync currentStatus(): Promise<TokenStatus>async getCurrentPhase(): Promise<string>// Check if DEX swapping is availableasync isSwapAvailable(): Promise<boolean>

Example:

typescript
// Check what trading token is usedconst tradingTokenAddress = await token.getTradingTokenAddress();const tradingTokenSymbol = await token.getTradingTokenSymbol();console.log(`Trading with: ${tradingTokenSymbol} (${tradingTokenAddress})`);// Check user's trading token balanceconst tradingBalance = await token.getTradingTokenBalanceOf(userAddress);console.log(`Trading token balance: ${formatEther(tradingBalance)}`);// Check current phaseconst status = await token.currentStatus();if (status === TokenStatus.Dex) { console.log("Token is in DEX trading phase");}

Built-in swap methods for DEX phase trading

typescript
// Get swap quotesasync getSwapQuoteForBondkitToken( amountTradingTokenIn: string, slippageTolerance?: number): Promise<SwapQuote | null>async getSwapQuoteForTradingToken( amountBondkitTokenIn: string, slippageTolerance?: number): Promise<SwapQuote | null>// Execute swapsasync swapTradingTokenForBondkitToken( amountTradingTokenIn: string, slippageTolerance?: number, walletClient: WalletClient): Promise<string | null>async swapBondkitTokenForTradingToken( amountBondkitTokenIn: string, slippageTolerance?: number, walletClient: WalletClient): Promise<string | null>

Example:

typescript
// 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 tokensconst 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

typescript
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:

typescript
// Get quote firstconst quote = await token.getAmountOfTokensToBuy( parseEther("100") // 100 trading tokens);// Buy with 5% slippage toleranceconst 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

typescript
async sell( tokenAmount: bigint, minTradingTokenOut: bigint): Promise<Hex>

Parameters:

  • tokenAmount: Amount of tokens to sell
  • minTradingTokenOut: Minimum trading token to receive (slippage protection)

Example:

typescript
// Sell 1000 tokensconst sellAmount = parseEther("1000");// Get quoteconst quote = await token.getAmountOfTradingTokensToSell(sellAmount);// Sell with slippage protectionconst minTradingTokenOut = quote * 95n / 100n;const txHash = await token.sell(sellAmount, minTradingTokenOut);

Migrate to Uniswap v4

typescript
async migrateToDex(): Promise<Hex>

Requirements:

  • Caller must be migration admin
  • Target must be reached

Example:

typescript
if (await token.canMigrate()) { const txHash = await token.migrateToDex(); console.log(`Migration tx: ${txHash}`);}

Transfer or renounce token ownership

typescript
// Transfer ownership to new addressasync transferTokenOwnership( newOwner: Address): Promise<Hex>// Renounce ownership (irreversible)async renounceTokenOwnership(): Promise<Hex>

Example:

typescript
// Transfer ownership to multisigconst multisig = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1";await token.transferTokenOwnership(multisig);// Or renounce ownership completely (be careful!)await token.renounceTokenOwnership();
Warning

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.

typescript
// Standard transfersasync transfer( to: Address, amount: bigint): Promise<Hex>async transferFrom( from: Address, to: Address, amount: bigint): Promise<Hex>// Approvalsasync approve( spender: Address, amount: bigint): Promise<Hex>// Exampleawait token.approve( spenderAddress, parseEther("1000"));

Event Listeners

typescript
// Listen for buy eventstoken.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 eventstoken.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 migrationtoken.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.

Info

When to use: After migration when tokens are trading on Uniswap V4. During bonding phase, use token.buy() and token.sell() instead.

Constructor

typescript
import { BondkitSwapService } from "@b3dotfun/sdk/bondkit";const swapService = new BondkitSwapService( "0x123..." // bondkitTokenAddress);

Methods

Get swap price quote

typescript
async getSwapQuote(params: SwapParams): Promise<SwapQuote | null>

Parameters:

typescript
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:

typescript
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:

typescript
// Get quote for swapping 100 B3 tokens for bondkit tokensconst 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

typescript
async executeSwap(params: SwapParams, walletClient: WalletClient): Promise<string | null>

Parameters:

  • params: Same SwapParams as getSwapQuote
  • walletClient: Connected wallet client

Example:

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

Complete Example

typescript
import { BondkitSwapService } from "@b3dotfun/sdk/bondkit";import { createWalletClient, custom } from "viem";// Initialize serviceconst swapService = new BondkitSwapService(bondkitTokenAddress);// Set up swap parametersconst 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 acceptableconst 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");}
Warning

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.

Info

Use case: Display price charts, volume data, and trading indicators for your Bondkit tokens in web applications.

Installation & Setup

typescript
import TradingView from "@b3dotfun/sdk/bondkit/components/TradingView";
Note

Requirements:

  • React 18+
  • TradingView charting library (loaded automatically from CDN)
  • Tailwind CSS for styling (optional, but recommended)

Props

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

Basic Usage

tsx
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

tsx
// In your Next.js app, configure the CDN// next.config.jsmodule.exports = { env: { NEXT_PUBLIC_CDN_URL: "https://your-cdn-domain.com", NEXT_PUBLIC_FORCE_CDN: "true" // Force CDN usage in development }};// Custom styled chartfunction 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

tsx
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

typescript
// utils/cdn.ts - Configure your CDN settingsexport 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 availabilityimport { checkCDNResource, preloadFromCDN } from "@b3dotfun/sdk/bondkit/components";// Preload TradingView librarypreloadFromCDN("/static/charting_library/charting_library.js");
Warning

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

typescript
// Token configurationinterface 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 enumenum TokenStatus { Uninitialized = 0, Bonding = 1, Dex = 2}// Token detailsinterface TokenDetails { name: string; symbol: string; decimals: number; totalSupply: bigint; owner: Address;}

Event Types

typescript
// Buy eventinterface BoughtEventArgs { buyer: Address; ethIn: bigint; tokensOut: bigint; feeRecipientFee: bigint;}// Sell eventinterface SoldEventArgs { seller: Address; tokensIn: bigint; ethOut: bigint; feeRecipientFee: bigint;}// Migration eventinterface DexMigrationEventArgs { ethForLp: bigint; tokensForLp: bigint; ethForFeeRecipient: bigint;}// Factory creation eventinterface BondkitTokenCreatedEventArgs { tokenAddress: Address; implementationAddress: Address; name: string; symbol: string; feeRecipient: Address; migrationAdmin: Address;}

Transaction Types

typescript
// Transaction historyinterface Transaction { timestamp: number; price: number; amount: string; type: "buy" | "sell"; userAddress: Address; txHash: Hex; chainId: number; blockNumber?: number; totalRaisedBonding?: string; value?: string;}// API responseinterface TransactionResponse { total: number; limit: number; skip: number; data: Transaction[];}

Configuration

Network Support

typescript
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

typescript
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

typescript
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

typescript
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

Warning

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
Info

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

GitHub

Source code and issues

Discord

Community support

Troubleshooting

Fix common integration issues

Learn More
Demo App

Example implementation

Learn More
Ask a question... ⌘I