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

hook-amm-sdk

v0.4.2

Published

TypeScript SDK for Hook AMM - Solana AMM with automatic Token-2022 transfer hook handling

Readme

Hook AMM SDK

TypeScript SDK for interacting with the Hook AMM program - a Solana AMM with automatic Token-2022 transfer hook support.

🚀 Features

  • 🔄 Constant Product AMM: Automated market making with bonding curves
  • 🪝 Automatic Transfer Hooks: Zero-config Token-2022 transfer hook handling
  • Smart Detection: Automatically detects and handles different token types
  • 📊 Price Quotes: Get accurate price quotes before trading
  • 🧮 Math Utilities: Built-in calculations for reserves, prices, and slippage
  • 🔐 Type Safety: Full TypeScript support with comprehensive types
  • 🛡️ Error Handling: Comprehensive error handling for hook-related issues
  • 💻 Multi-Platform: Works with wallet adapters (browser) and keypairs (Node.js)

✨ What's New in v0.4.2

  • 📦 Built-in IDL: Program IDL is now included in the SDK - no need to provide it separately
  • 🚀 Zero Configuration: Import and use immediately with HookAmmIdl
  • 🔧 Simplified Setup: Reduced setup complexity for faster development
  • Ready to Use: All examples updated to use the built-in IDL

Installation

npm install hook-amm-sdk

Quick Start

Option 1: With Wallet Adapters (Recommended for dApps)

import { Connection, PublicKey } from '@solana/web3.js';
import { HookAmmClient, HookAmmIdl } from 'hook-amm-sdk';
import { useWallet } from '@solana/wallet-adapter-react';
import BN from 'bn.js';

// In a React component
function TradingComponent() {
  const { wallet, publicKey, signTransaction } = useWallet();
  const connection = new Connection('https://api.devnet.solana.com');

  // Create wallet adapter
  const walletAdapter = {
    publicKey,
    signTransaction,
    signAllTransactions: wallet?.adapter?.signAllTransactions,
    sendTransaction: wallet?.adapter?.sendTransaction
  };

  // Create client with built-in IDL
  const client = HookAmmClient.create(connection, walletAdapter, HookAmmIdl);
}

Option 2: With Keypairs (For testing/backends)

import { Connection, Keypair } from '@solana/web3.js';
import { HookAmmClient, HookAmmIdl } from 'hook-amm-sdk';
import BN from 'bn.js';

// Initialize connection and keypair
const connection = new Connection('https://api.devnet.solana.com');
const keypair = Keypair.generate();

// Create client with built-in IDL
const client = HookAmmClient.create(connection, keypair, HookAmmIdl);

Basic Trading Example

import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import { Wallet } from '@coral-xyz/anchor';
import { HookAmmClient, HookAmmIdl } from 'hook-amm-sdk';
import BN from 'bn.js';

// Initialize connection and wallet
const connection = new Connection('https://api.devnet.solana.com');
const wallet = new Wallet(Keypair.generate());

// Create client with built-in IDL
const client = new HookAmmClient(connection, wallet, HookAmmIdl);

// 🪝 Check if token has transfer hooks (automatic detection!)
const hasHooks = await client.isTokenWithHooks(tokenMint);
console.log(`Token has transfer hooks: ${hasHooks}`);

// Get a price quote
const quote = await client.getBuyQuote(
  bondingCurvePubkey,
  new BN(1000000000) // 1 SOL
);

console.log(`Price: ${quote.pricePerToken} SOL per token`);
console.log(`You'll receive: ${quote.tokenAmount.toString()} tokens`);
console.log(`Fee: ${quote.fee.toString()} lamports`);
console.log(`Price impact: ${quote.priceImpact}%`);

// 🚀 Buy tokens (automatically handles transfer hooks!)
const buyParams = {
  bondingCurve: bondingCurvePubkey,
  solAmount: new BN(1000000000),
  minTokenAmount: quote.tokenAmount.mul(new BN(95)).div(new BN(100)) // 5% slippage
};

// With wallet adapters (will prompt user for approval)
const signature = await client.buy(buyParams);

// With keypairs (for testing/backends)
// const signature = await client.buy(buyParams, userKeypair);

// ✅ Transfer hooks handled automatically - no additional configuration needed!

API Reference

HookAmmClient

Main client class for interacting with the Hook AMM program.

Constructors

// Original constructor (backwards compatible)
new HookAmmClient(connection: Connection, wallet: Wallet, programIdl: Idl)

// Factory method with wallet adapter support
HookAmmClient.create(connection: Connection, signer: WalletAdapter | Keypair, programIdl: Idl)

// With built-in IDL (recommended)
import { HookAmmIdl } from 'hook-amm-sdk';
const client = HookAmmClient.create(connection, signer, HookAmmIdl);

Wallet Support

The SDK supports multiple wallet types:

// Wallet adapters (Phantom, Solflare, etc.)
interface WalletAdapter {
  publicKey: PublicKey | null;
  signTransaction?(transaction: Transaction): Promise<Transaction>;
  signAllTransactions?(transactions: Transaction[]): Promise<Transaction[]>;
  sendTransaction?(transaction: Transaction, connection: Connection, options?: any): Promise<string>;
}

// Keypairs (for testing/backends)
const keypair = Keypair.generate();

// Both work with the same API (using built-in IDL)
const client = HookAmmClient.create(connection, walletAdapter, HookAmmIdl);
const client2 = HookAmmClient.create(connection, keypair, HookAmmIdl);

Methods

Trading Operations
// Buy tokens with SOL (automatically handles transfer hooks)
async buy(
  params: BuyParams, 
  signer?: WalletAdapter | Keypair, // Optional - uses client's default signer
  additionalHookAccounts?: HookAccount[],
  options?: SendTransactionOptions
): Promise<string>

// Sell tokens for SOL (automatically handles transfer hooks)
async sell(
  params: SellParams, 
  signer?: WalletAdapter | Keypair, // Optional - uses client's default signer
  additionalHookAccounts?: HookAccount[],
  options?: SendTransactionOptions
): Promise<string>

// Get buy quote
async getBuyQuote(bondingCurve: PublicKey, solAmount: BN): Promise<PriceQuote>

// Get sell quote
async getSellQuote(bondingCurve: PublicKey, tokenAmount: BN): Promise<PriceQuote>
Curve Management
// Create new bonding curve
async createBondingCurve(
  params: CreateBondingCurveParams, 
  signer?: WalletAdapter | Keypair, // Optional - uses client's default signer
  options?: SendTransactionOptions
): Promise<string>

// Get bonding curve data
async getBondingCurve(bondingCurve: PublicKey): Promise<BondingCurve>

// Get all bonding curves
async getAllBondingCurves(): Promise<{publicKey: PublicKey, account: BondingCurve}[]>

// Get curves by creator
async getBondingCurvesByCreator(creator: PublicKey): Promise<{publicKey: PublicKey, account: BondingCurve}[]>
Configuration
// Initialize global config (admin only)
async initializeGlobalConfig(
  authority: PublicKey, 
  feeRecipient: PublicKey, 
  signer?: WalletAdapter | Keypair, // Optional - uses client's default signer
  options?: SendTransactionOptions
): Promise<string>

// Get global configuration
async getGlobalConfig(): Promise<GlobalConfig>
Token-2022 Hook Support
// Check if token has transfer hooks
async isTokenWithHooks(mintAddress: PublicKey): Promise<boolean>

// Get transfer hook accounts with full metadata
async getTransferHookAccountsForTrade(
  mintAddress: PublicKey,
  source: PublicKey, 
  destination: PublicKey,
  owner: PublicKey,
  amount: BN
): Promise<HookAccount[]>

// Type for hook accounts
interface HookAccount {
  pubkey: PublicKey;
  isSigner: boolean;
  isWritable: boolean;
}

Types

Core Types

interface BondingCurve {
  mint: PublicKey;
  creator: PublicKey;
  virtualTokenReserves: BN;
  virtualSolReserves: BN;
  realTokenReserves: BN;
  realSolReserves: BN;
  tokenTotalSupply: BN;
  complete: boolean;
  index: BN;
}

interface PriceQuote {
  tokenAmount: BN;
  solAmount: BN;
  fee: BN;
  pricePerToken: number;
  priceImpact: number;
}

Parameter Types

interface BuyParams {
  bondingCurve: PublicKey;
  solAmount: BN;
  minTokenAmount: BN;
}

interface SellParams {
  bondingCurve: PublicKey;
  tokenAmount: BN;
  minSolAmount: BN;
}

// Updated in v0.4.0 to match program structure
interface CreateBondingCurveParams {
  tokenMint: PublicKey;
  initialSupply: BN;           // Changed from tokenTotalSupply
  virtualTokenReserves: BN;    // Changed from initialVirtualTokenReserves
  virtualSolReserves: BN;      // Changed from initialVirtualSolReserves
}

Utilities

PDA Functions

import { getGlobalConfigPDA, getBondingCurvePDA, getCurveTokenAccountPDA } from 'hook-amm-sdk';

const [globalConfig, bump] = getGlobalConfigPDA();
const [bondingCurve, bump] = getBondingCurvePDA(tokenMint);
const [curveTokenAccount, bump] = getCurveTokenAccountPDA(bondingCurve, tokenMint);

Math Functions

import { calculateBuyAmount, calculateSellAmount, calculateTokenPrice } from 'hook-amm-sdk';

// Calculate buy amounts (matches program's exact formula)
const { tokenAmount, fee } = calculateBuyAmount(
  solAmountAfterFee,
  currentSolReserves,
  currentTokenReserves,
  realSolReserves,
  realTokenReserves
);

// Calculate sell amounts (matches program's exact formula)
const { solAmount, fee } = calculateSellAmount(
  tokenAmountIn,
  currentTokenReserves,
  currentSolReserves,
  realTokenReserves,
  realSolReserves
);

// Get current token price
const priceInSol = calculateTokenPrice(
  virtualSolReserves,
  virtualTokenReserves,
  realSolReserves,
  realTokenReserves
);

Token Utilities

import { getTokenProgramId, getMintInfo, isToken2022, hasTransferHooks } from 'hook-amm-sdk';

// Detect token program
const tokenProgramId = await getTokenProgramId(connection, mintAddress);

// Get mint information
const mintInfo = await getMintInfo(connection, mintAddress);

// Check if Token-2022
const isT22 = isToken2022(mintAccountInfo);

// Check if token has transfer hooks
const hasHooks = await hasTransferHooks(connection, mintAddress);

🪝 Token-2022 Transfer Hook Support

The SDK automatically handles Token-2022 transfer hooks - no configuration required!

Automatic Mode (Recommended)

// ✅ Zero configuration - SDK automatically handles everything
await client.buy(buyParams, userKeypair);
await client.sell(sellParams, userKeypair);

// The SDK automatically:
// 1. Detects if token has transfer hooks
// 2. Resolves hook program accounts
// 3. Includes required accounts in transaction
// 4. Handles hook-specific PDAs and meta accounts

Manual Mode (Advanced)

// 🔧 Manual control for advanced use cases
const hookAccounts = await client.getTransferHookAccountsForTrade(
  tokenMint,
  sourceAccount,
  destinationAccount,
  owner,
  amount
);

// Add additional custom hook accounts if needed
const customAccounts = [
  { pubkey: customPDA, isSigner: false, isWritable: true }
];

await client.buy(buyParams, userKeypair, [...hookAccounts, ...customAccounts]);

Hook Detection

// Check if token supports transfer hooks
const hasHooks = await client.isTokenWithHooks(tokenMint);
if (hasHooks) {
  console.log('🪝 This token uses transfer hooks - handled automatically!');
} else {
  console.log('📄 Standard token - no hooks needed');
}

Examples

Wallet Adapter Integration

// React component with wallet adapter
import { useWallet } from '@solana/wallet-adapter-react';
import { HookAmmClient, HookAmmIdl } from 'hook-amm-sdk';

function TradingComponent() {
  const { wallet, publicKey, signTransaction, sendTransaction } = useWallet();
  const connection = new Connection('https://api.devnet.solana.com');

  const handleTrade = async () => {
    if (!wallet || !publicKey) {
      throw new Error('Wallet not connected');
    }

    // Create wallet adapter
    const walletAdapter = {
      publicKey,
      signTransaction,
      signAllTransactions: wallet.adapter.signAllTransactions,
      sendTransaction
    };

    // Create client with built-in IDL
    const client = HookAmmClient.create(connection, walletAdapter, HookAmmIdl);

    // Trade - wallet will prompt user for approval
    const buyParams = {
      bondingCurve: bondingCurvePubkey,
      solAmount: new BN(1000000000),
      minTokenAmount: new BN(0)
    };

    const signature = await client.buy(buyParams);
    console.log('Trade successful:', signature);
  };

  return (
    <button onClick={handleTrade} disabled={!publicKey}>
      {publicKey ? 'Buy Tokens' : 'Connect Wallet'}
    </button>
  );
}

Mixed Signer Usage

// Different signers for different operations
const connection = new Connection('https://api.devnet.solana.com');
const adminKeypair = Keypair.generate();
const client = HookAmmClient.create(connection, adminKeypair, HookAmmIdl);

// Admin operations use admin keypair (default)
await client.initializeGlobalConfig(
  adminKeypair.publicKey,
  feeRecipient
);

// User operations can use different signers
const userWallet = getConnectedWallet(); // From wallet adapter
await client.buy(buyParams, userWallet); // Specify different signer

// Or with keypair for testing
const testKeypair = Keypair.generate();
await client.buy(buyParams, testKeypair);

Creating a Bonding Curve

import { Keypair } from '@solana/web3.js';
import BN from 'bn.js';

const tokenMint = new PublicKey('...');

// Updated parameters structure in v0.4.0
const params = {
  tokenMint,
  initialSupply: new BN('1000000000000'),        // Total supply to deposit
  virtualTokenReserves: new BN('1000000000000'), // Virtual token reserves
  virtualSolReserves: new BN('30000000000'),     // Virtual SOL reserves (30 SOL)
};

// With wallet adapter (prompts user)
const signature = await client.createBondingCurve(params);

// With specific keypair
const creatorKeypair = Keypair.generate();
const signature2 = await client.createBondingCurve(params, creatorKeypair);

Trading with Price Quotes

// Get a quote first
const buyQuote = await client.getBuyQuote(
  bondingCurvePubkey,
  new BN('1000000000') // 1 SOL
);

// Check slippage tolerance
if (buyQuote.priceImpact > 5) { // 5% max slippage
  throw new Error('Price impact too high');
}

// Execute the trade
const buyParams = {
  bondingCurve: bondingCurvePubkey,
  solAmount: new BN('1000000000'),
  minTokenAmount: buyQuote.tokenAmount.mul(new BN(95)).div(new BN(100)) // 5% slippage
};

// With wallet adapter (default)
const signature = await client.buy(buyParams);

// With specific keypair (for testing/backends)
const userKeypair = Keypair.generate();
const signature2 = await client.buy(buyParams, userKeypair);

Error Handling

try {
  await client.buy(buyParams);
} catch (error) {
  if (error.message.includes('SlippageTooHigh')) {
    console.error('Trade failed due to slippage');
  } else if (error.message.includes('InsufficientFunds')) {
    console.error('Insufficient balance');
  } else if (error.message.includes('User rejected')) {
    console.error('User cancelled the transaction');
  } else if (error.message.includes('does not support signing')) {
    console.error('Wallet cannot sign transactions');
  } else {
    console.error('Trade failed:', error);
  }
}

Migration Guide

From v0.4.1 to v0.4.2

Built-in IDL: No need to provide IDL separately anymore!

// Before (v0.4.1)
import { HookAmmClient } from 'hook-amm-sdk';
const programIdl = { /* you had to provide this */ };
const client = HookAmmClient.create(connection, signer, programIdl);

// After (v0.4.2)
import { HookAmmClient, HookAmmIdl } from 'hook-amm-sdk';
const client = HookAmmClient.create(connection, signer, HookAmmIdl);

From v0.3.0 to v0.4.0

  1. Remove V2/V3 imports: Use only HookAmmClient now

    // Before
    import { HookAmmClientV2 } from 'hook-amm-sdk';
       
    // After
    import { HookAmmClient, HookAmmIdl } from 'hook-amm-sdk';
  2. Update CreateBondingCurveParams: Parameter names have changed

    // Before
    const params = {
      tokenMint,
      initialVirtualTokenReserves: new BN('1000000000000'),
      initialVirtualSolReserves: new BN('30000000000'),
      initialRealTokenReserves: new BN('0'),
      tokenTotalSupply: new BN('1000000000000'),
    };
       
    // After
    const params = {
      tokenMint,
      initialSupply: new BN('1000000000000'),        // Renamed from tokenTotalSupply
      virtualTokenReserves: new BN('1000000000000'), // Renamed from initialVirtualTokenReserves
      virtualSolReserves: new BN('30000000000'),     // Renamed from initialVirtualSolReserves
    };
  3. Use built-in IDL: Import HookAmmIdl instead of providing your own

    // Before
    const client = new HookAmmClientV2(connection, wallet, yourIdl);
       
    // After
    import { HookAmmIdl } from 'hook-amm-sdk';
    const client = HookAmmClient.create(connection, walletOrKeypair, HookAmmIdl);

Constants

import { PROGRAM_ID, FEE_BASIS_POINTS, FEE_DENOMINATOR } from 'hook-amm-sdk';

console.log('Program ID:', PROGRAM_ID.toBase58());
console.log('Fee:', FEE_BASIS_POINTS / FEE_DENOMINATOR * 100, '%'); // 1%

Development

# Install dependencies
npm install

# Build
npm run build

# Test
npm run test

# Lint
npm run lint

License

MIT