npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tokena/sdk

v1.1.1

Published

SDK for interacting with Tokena bonding curve smart contracts on EVM chains

Readme

Tokena SDK

Multi-chain SDK for the Tokena bonding curve launchpad — EVM + Solana.

Create, trade, discover, and manage bonding curve tokens across EVM chains and Solana with a single npm package.

Install

npm install @tokena/sdk

Peer dependencies:

# EVM
npm install ethers

# Solana (if using Solana features)
npm install @solana/web3.js @solana/wallet-adapter-react @meteora-ag/dynamic-bonding-curve-sdk bn.js

Quick Start — EVM

import { Tokena } from '@tokena/sdk';
import { Wallet, JsonRpcProvider } from 'ethers';

// Initialize SDK
const tokena = new Tokena({ chainKey: 'bsc' });

// Read token state (includes auto-migration fields)
const state = await tokena.getTokenState('0xYourToken...');
console.log(`Price: ${state.currentPriceEth} ETH`);
console.log(`Finalized: ${state.finalized}`);
console.log(`AMM Reserve: ${state.ammEthReserve} ETH`);

// Preview a buy (price impact, fees, worst case)
const preview = await tokena.previewBuy('0xYourToken...', 0.5, 500);
console.log(`You'll get ~${preview.expectedOutput} tokens`);
console.log(`Price impact: ${preview.priceImpactPercent.toFixed(2)}%`);

// Connect a wallet & execute
const provider = new JsonRpcProvider('https://bsc-dataseed.binance.org');
const wallet = new Wallet(process.env.PRIVATE_KEY!, provider);

const tx = await tokena.buy(
  { tokenAddress: '0xYourToken...', ethAmount: '0.5', slippageBps: 500 },
  wallet
);
console.log(`Bought! TX: ${tx.txHash}`);

// Check lifecycle (supports auto-migration)
const lifecycle = await tokena.getLifecycleState('0xYourToken...');
console.log(`Stage: ${lifecycle.stage}, Progress: ${lifecycle.progress}%`);
// Stages: bonding → threshold_reached → finalized

Quick Start — Solana

import { solana } from '@tokena/sdk';
import { useWallet, useConnection } from '@solana/wallet-adapter-react';

// Get Solana connection + wallet from your React context
const wallet = useWallet();
const { connection } = useConnection();

// Read pool state
const poolState = await solana.getPoolState('PoolAddress...', connection);
console.log(`SOL Raised: ${poolState.solRaised}`);
console.log(`Progress: ${poolState.migrationProgress}%`);

// Quote a buy off-chain
const quote = solana.quoteBuyOffchain(0.5, poolState.solRaised, 150);
console.log(`Tokens out: ${quote.tokensOut}`);
console.log(`Fee: ${quote.feeSol} SOL`);

// Buy tokens
const result = await solana.buyTokens({
  poolAddress: 'PoolAddress...',
  mintAddress: 'MintAddress...',
  wallet,
  connection,
  solAmount: 0.5,
  currentSolRaised: poolState.solRaised,
}, {
  onTradeComplete: (trade) => {
    // Record to your database
    console.log(`Bought ${trade.tokenAmount} tokens, TX: ${trade.txSignature}`);
  },
});

// Launch a new token (with custom thresholds)
const token = await solana.launchToken({
  name: 'My Token',
  symbol: 'MTK',
  description: 'A great token',
  imageUrl: 'https://...',
  metadataUri: 'ipfs://...',
  initialPriceSol: 0.0000015,
  migrationThresholdSol: 25,
  totalSupply: 1_000_000_000,
  creatorFeePercent: 2,
  initialBuySol: 0.1,
  initialVirtualLpSol: 5,       // Optional: custom virtual LP (default: 5)
  migrationMarketCapSol: 180,   // Optional: custom graduation FDV (default: 180)
  wallet,
  connection,
}, {
  onTokenCreated: (info) => console.log(`Created: ${info.mintAddress}`),
  onInitialBuyComplete: (buy) => console.log(`Initial buy: ${buy.tokensOut} tokens`),
});

// Claim creator fees (platform split is automatic)
await solana.claimCreatorFees({
  poolAddress: 'PoolAddress...',
  wallet,
  connection,
  creatorFeePercent: 2,
});

API Reference — EVM

new Tokena(config)

| Option | Type | Description | |---|---|---| | chainKey | string | Default chain (e.g. "bsc", "ethereum", "base", "arbitrum") | | chains | Record<string, ChainConfig> | Custom chain configs to add or override | | factoryAddress | string | Override factory address for the default chain | | cache | CacheOptions | Enable request caching ({ ttlMs, staleWhileRevalidate }) | | metadataAdapter | MetadataAdapter | Adapter for token metadata (logo, description, links) | | debug | boolean | Enable debug logging |

Core Methods

| Method | Description | |---|---| | getTokenState(addr) | Read full on-chain state (price, reserves, threshold, tax, finalized, ammEthReserve) | | getEnrichedTokenState(addr) | State + computed progress, marketCap, remainingEth | | getTokenBalance(token, wallet) | Get wallet's token balance | | createToken(params, signer) | Deploy a new bonding curve token | | getCreationFee() | Get the factory's creation fee | | getFactoryConfig() | Get all factory settings (typed) |

createToken — Configurable Thresholds

| Param | Type | Description | |---|---|---| | ethThreshold | string | ETH required to trigger auto-migration (e.g. "5") | | initialVirtualEth | string? | Virtual ETH for initial pricing (e.g. "1"). Defaults to factory default. | | initialBuyEth | string? | ETH to spend on initial buy bundled with creation |

await tokena.createToken({
  name: 'My Token',
  symbol: 'MTK',
  totalSupply: '1000000000',
  ethThreshold: '10',        // Custom: migrate at 10 ETH raised
  initialVirtualEth: '2',    // Custom: 2 ETH virtual LP (higher starting FDV)
  isTaxToken: false,
  initialBuyEth: '0.5',
}, signer);

Trading

| Method | Description | |---|---| | quoteBuy(token, ethAmount) | Estimate tokens out for an ETH amount | | quoteSell(token, tokenAmount, slippage) | Estimate ETH out for a token amount | | previewBuy(token, eth, slippage) | Full preview: output, impact, fees, worst case | | previewSell(token, amount, slippage) | Full preview for sells | | buy(params, signer) | Buy tokens (auto-slippage, safety checks) | | sell(params, signer) | Sell tokens (auto-slippage, safety checks) |

Lifecycle & Auto-Migration

| Method | Description | |---|---| | getLifecycleState(token) | Full stage info (bondingthreshold_reachedfinalized) | | isFinalized(token) | Whether auto-migration has completed | | getMigrationState(token) | Migration details (Uniswap pair, progress) | | finalizeToken(token, signer) | ⚠️ Deprecated — auto-migration handles this atomically |

Auto-Migration: New contracts auto-finalize during buy() when the ETH threshold is reached. The SDK reads migration status via getMigrationStatus() with a fallback to legacy thresholdReached()/ethThreshold() for older contracts.

Discovery

| Method | Description | |---|---| | getAllTokens(options?) | Paginated list of all tokens | | getNewTokens(limit?) | Most recently created tokens | | searchTokens(query, limit?) | Search by name or symbol | | getTokenCount() | Total tokens created |

Fees

| Method | Description | |---|---| | getPendingFees(token, wallet) | Check claimable fees | | claimFees(token, signer) | Claim accumulated fees | | getClaimHistory(token, wallet) | Scan historical claim events |

Events

| Method | Description | |---|---| | getTradeHistory(token, options?) | Historical buy/sell events | | subscribeTrades(token, callback) | Real-time trade stream | | subscribeNewTokens(callback) | Real-time new token stream |


API Reference — Solana

All Solana functions are available under the solana namespace:

import { solana } from '@tokena/sdk';

Connection & Client

| Function | Description | |---|---| | getSolanaConnection(rpcUrl) | Cached Solana Connection factory | | confirmTx(signature, connection) | Confirm with timeout + retry | | getDbcClient(connection) | Singleton Meteora DBC client |

Pool State

| Function | Description | |---|---| | getPoolState(poolAddr, connection) | Full on-chain pool state (solRaised, price, migration) | | getOnChainMcap(poolAddr, connection, solPrice) | Lightweight market cap | | startPoolStatePolling(poolAddr, connection, callback, interval?) | Poll state (returns unsubscribe) |

Trading

| Function | Description | |---|---| | buyTokens(params, callbacks?) | Buy tokens via DBC swap | | sellTokens(params, callbacks?) | Sell tokens via DBC swap |

Both accept optional TradeCallbacks with onTradeComplete for database recording.

Off-Chain Quotes

| Function | Description | |---|---| | quoteBuyOffchain(solIn, currentRaised, solPrice, overrides?) | Instant buy quote (no RPC) | | quoteSellOffchain(tokensIn, currentRaised, solPrice, overrides?) | Instant sell quote (no RPC) | | getCachedSolPrice() | SOL/USD price (CoinGecko, 60s cache) |

Bonding Curve Math

All math functions accept an optional CurveOverrides parameter to customize the curve:

| Function | Description | |---|---| | getMcapSol(solRaised, overrides?) | Market cap in SOL | | getMcapUsd(solRaised, solPrice, overrides?) | Market cap in USD | | getTokenPriceSol(solRaised, overrides?) | Token price in SOL | | getTokenPriceUsd(solRaised, solPrice, overrides?) | Token price in USD | | getMigrationProgress(solRaised, overrides?) | Progress 0-100% | | getSolRaisedFromMcapUsd(mcapUsd, solPrice, overrides?) | Reverse: mcap → solRaised | | getTokensSold(solRaised, overrides?) | Tokens sold at a given level |

CurveOverrides

| Field | Type | Default | Description | |---|---|---|---| | initialLpSol | number | 5 | Virtual LP in SOL — sets starting FDV | | migrationLpSol | number | 25 | SOL raised threshold for migration | | totalSupply | number | 1,000,000,000 | Total token supply |

import { solana } from '@tokena/sdk';

// Custom curve: 10 SOL virtual LP, 50 SOL migration, 500M supply
const overrides = { initialLpSol: 10, migrationLpSol: 50, totalSupply: 500_000_000 };

const mcap = solana.getMcapSol(15, overrides);       // Uses custom formula
const quote = solana.quoteBuyOffchain(1, 10, 150, overrides);
const progress = solana.getMigrationProgress(30, overrides); // 60%

Fee Claiming

| Function | Description | |---|---| | getClaimableFee(poolAddr, connection, creatorFeePct) | Creator's claimable fee | | getClaimableFeesForPools(pools, connection, feeMap) | Batch claimable fees | | claimCreatorFees(params) | Claim with atomic platform fee split |

Fee System:

  • 1% total trading fee → 0.2% Meteora protocol, 0.8% to feeClaimer
  • Of 0.8%: 0.4% creator + 0.4% platform (split at claim time)
  • Creator tax (0-5%) adds on top; platform always gets 0.4% via atomic transfer in the claim transaction

Token Launch

| Function | Description | |---|---| | launchToken(params, callbacks?) | Full launch: config + pool + optional initial buy |

launchToken — Configurable Thresholds

| Param | Type | Default | Description | |---|---|---|---| | initialVirtualLpSol | number? | 5 | Virtual LP in SOL — sets starting FDV | | migrationMarketCapSol | number? | 180 | FDV in SOL at which pool graduates to DEX |

The migration threshold (SOL raised) is derived from these values: migrationThreshold ≈ sqrt(migrationMarketCapSol × initialVirtualLpSol) - initialVirtualLpSol


Supported Chains

EVM — Auto-Migration

v1.1.1: The factory contract now supports auto-migration. When a token reaches its ETH threshold during a buy() call, the contract atomically creates the DEX pair, adds liquidity, and locks it — all in one transaction. The AutoFinalized event is emitted.

| Chain | Key | Factory | Migration DEX Router | |---|---|---|---| | Ethereum | ethereum | 0x153B33eee6412066f187B2146deEC10A3A4893C3 | 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D (Uniswap V2) | | BNB Chain | bsc | 0x153B33eee6412066f187B2146deEC10A3A4893C3 | 0x10ED43C718714eb63d5aA57B78B54704E256024E (PancakeSwap V2) | | Base | base | 0x153B33eee6412066f187B2146deEC10A3A4893C3 | 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24 (Uniswap V2) | | Arbitrum | arbitrum | 0x153B33eee6412066f187B2146deEC10A3A4893C3 | 0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506 (SushiSwap V2) | | Sepolia Testnet | sepolia | 0x153B33eee6412066f187B2146deEC10A3A4893C3 | 0xC532a74256D3Db42D0Bf7a0400fEFDbad7694008 (Uniswap V2 Fork) |

Solana — Meteora DBC

| Param | Value | |---|---| | Program ID | dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN | | Token Decimals | 6 | | Total Supply | 1,000,000,000 | | Initial Virtual LP | 5 SOL | | Migration Threshold | 25 SOL raised | | Curve Formula | mcap_sol = (5 + solRaised)² / 5 | | Trading Fee | 1% (0.2% Meteora + 0.4% creator + 0.4% platform) |

Custom EVM Chains

const tokena = new Tokena({
  chainKey: 'mychain',
  chains: {
    mychain: {
      chainId: 31337,
      name: 'My Local Chain',
      shortName: 'LOCAL',
      rpcUrl: 'http://localhost:8545',
      explorerUrl: 'http://localhost:4000',
      nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
      factoryAddress: '0x...',
    },
  },
});

Error Handling

The SDK throws typed errors for EVM operations:

import { Tokena, SlippageExceededError, TradePausedError, InsufficientBalanceError } from '@tokena/sdk';

try {
  await tokena.buy(params, signer);
} catch (e) {
  if (e instanceof SlippageExceededError) {
    console.log('Increase slippage tolerance');
  } else if (e instanceof TradePausedError) {
    console.log('Trading is paused on this token');
  } else if (e instanceof InsufficientBalanceError) {
    console.log('Not enough ETH');
  }
}

Error types: TokenaError, InsufficientBalanceError, SlippageExceededError, ChainMismatchError, TokenNotFoundError, TradePausedError, ThresholdAlreadyReachedError, InvalidAddressError, InvalidAmountError, TransactionFailedError, ContractNotFoundError, RpcError


Offline Simulation

Simulate EVM trades instantly without RPC calls:

import { simulateBuy, simulateSell } from '@tokena/sdk';

const state = await tokena.getTokenState('0x...');
const buyPreview = simulateBuy(0.5, state, 500);
console.log(`~${buyPreview.expectedOutput} tokens, ${buyPreview.priceImpactPercent}% impact`);

For Solana, use the off-chain quote functions:

import { solana } from '@tokena/sdk';

const quote = solana.quoteBuyOffchain(0.5, currentSolRaised, solPriceUsd);
console.log(`~${quote.tokensOut} tokens, fee: ${quote.feeSol} SOL`);

Utilities

import { formatTokenAmount, formatEthAmount, shortenAddress, explorerTxUrl } from '@tokena/sdk';

formatTokenAmount(1234567.89);    // "1,234,567.89"
formatEthAmount(0.004238);        // "0.0042 ETH"
shortenAddress('0x1234...5678');   // "0x1234...5678"
explorerTxUrl(txHash, chain);     // "https://etherscan.io/tx/0x..."

Migration from Axolotl

All old names still work as deprecated aliases:

// Old (still works)
import { Axolotl } from '@tokena/sdk';

// New
import { Tokena, solana } from '@tokena/sdk';

License

MIT