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

@pipeit/actions

v0.1.2

Published

Composable DeFi InstructionPlan factories for Solana

Readme

@pipeit/actions

Composable InstructionPlan factories for Solana DeFi, starting with Titan integration.

This package provides Kit-compatible InstructionPlan factories that can be:

  • Executed directly with @pipeit/core's executePlan
  • Composed with other InstructionPlans using Kit's plan combinators
  • Used by anyone in the Kit ecosystem

Installation

pnpm install @pipeit/actions @pipeit/core @solana/kit

Quick Start

import { getTitanSwapPlan } from '@pipeit/actions/titan';
import { executePlan } from '@pipeit/core';
import { createSolanaRpc, createSolanaRpcSubscriptions } from '@solana/kit';

const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.mainnet-beta.solana.com');

// Get a swap plan from Titan
const { plan, lookupTableAddresses, quote } = await getTitanSwapPlan({
    swap: {
        inputMint: 'So11111111111111111111111111111111111111112', // SOL
        outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
        amount: 1_000_000_000n, // 1 SOL
        slippageBps: 50, // 0.5%
    },
    transaction: {
        userPublicKey: signer.address,
        createOutputTokenAccount: true,
    },
});

console.log(`Swapping 1 SOL for ~${quote.outputAmount / 1_000_000n} USDC`);

// Execute with ALT support for optimal transaction packing
await executePlan(plan, {
    rpc,
    rpcSubscriptions,
    signer,
    lookupTableAddresses,
});

Titan API

getTitanSwapPlan

The main entry point that fetches a quote, selects the best route, and returns a composable plan.

import { getTitanSwapPlan } from '@pipeit/actions/titan';

const { plan, lookupTableAddresses, quote, providerId, route } = await getTitanSwapPlan(
    {
        swap: {
            inputMint: 'So11111111111111111111111111111111111111112',
            outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
            amount: 1_000_000_000n,
            slippageBps: 50,
            // Optional filters
            dexes: ['Raydium', 'Orca'], // Only use these DEXes
            excludeDexes: ['Phoenix'], // Exclude these DEXes
            onlyDirectRoutes: false, // Allow multi-hop routes
            providers: ['titan'], // Only use specific providers
        },
        transaction: {
            userPublicKey: signer.address,
            createOutputTokenAccount: true,
            closeInputTokenAccount: false,
        },
    },
    {
        // Optional: specify a provider
        providerId: 'titan',
    },
);

Lower-Level APIs

For more control, you can use the individual functions:

import {
    createTitanClient,
    TITAN_DEMO_BASE_URLS,
    getTitanSwapQuote,
    selectTitanRoute,
    getTitanSwapInstructionPlanFromRoute,
} from '@pipeit/actions/titan';

// Create a client
const client = createTitanClient({
    // Option A: pick a demo region (us1 | jp1 | de1)
    demoRegion: 'us1',
    // Option B: specify a full base URL (demo or production)
    // baseUrl: TITAN_DEMO_BASE_URLS.jp1,
    // baseUrl: 'https://api.titan.ag/api/v1',
    authToken: 'optional-jwt-for-fees',
});

// Get quotes from all providers
const quotes = await getTitanSwapQuote(client, {
    swap: { inputMint, outputMint, amount },
    transaction: { userPublicKey },
});

// Select the best route (or a specific provider)
const { providerId, route } = selectTitanRoute(quotes, {
    providerId: 'titan', // Optional: use specific provider
});

// Build the instruction plan
const plan = getTitanSwapInstructionPlanFromRoute(route);

// Extract ALT addresses
const lookupTableAddresses = route.addressLookupTables.map(titanPubkeyToAddress);

Composing Plans

The real power of InstructionPlans is composition. Combine multiple plans:

import { getTitanSwapPlan } from '@pipeit/actions/titan';
import { sequentialInstructionPlan, parallelInstructionPlan, singleInstructionPlan } from '@solana/instruction-plans';
import { executePlan } from '@pipeit/core';

// Swap SOL → USDC
const swapResult = await getTitanSwapPlan({
    swap: {
        inputMint: SOL_MINT,
        outputMint: USDC_MINT,
        amount: 10_000_000_000n, // 10 SOL
    },
    transaction: { userPublicKey: signer.address },
});

// Add a transfer instruction
const transferPlan = singleInstructionPlan(transferInstruction);

// Combine: swap then transfer
const combinedPlan = sequentialInstructionPlan([swapResult.plan, transferPlan]);

// Execute with all ALTs
await executePlan(combinedPlan, {
    rpc,
    rpcSubscriptions,
    signer,
    lookupTableAddresses: swapResult.lookupTableAddresses,
});

ALT (Address Lookup Table) Support

Titan swaps often require Address Lookup Tables to stay under transaction size limits. The @pipeit/core executePlan function handles this automatically:

  1. Planner-time compression: ALTs are used during transaction planning, so Kit can pack more instructions per transaction.
  2. Executor-time compression: Messages are compressed before simulation and signing, ensuring what you simulate is what you send.
// Option 1: Pass ALT addresses (core will fetch them)
await executePlan(plan, {
    rpc,
    rpcSubscriptions,
    signer,
    lookupTableAddresses: swapResult.lookupTableAddresses,
});

// Option 2: Pre-fetch ALT data yourself
import { fetchAddressLookupTables } from '@pipeit/core';

const addressesByLookupTable = await fetchAddressLookupTables(rpc, swapResult.lookupTableAddresses);

await executePlan(plan, {
    rpc,
    rpcSubscriptions,
    signer,
    addressesByLookupTable,
});

Swap Modes

Titan supports two swap modes:

  • ExactIn (default): Swap exactly N input tokens, get variable output
  • ExactOut: Get exactly N output tokens, use variable input
// ExactIn: Swap exactly 1 SOL, get as much USDC as possible
const exactInResult = await getTitanSwapPlan({
    swap: {
        inputMint: SOL_MINT,
        outputMint: USDC_MINT,
        amount: 1_000_000_000n, // 1 SOL
        swapMode: 'ExactIn',
    },
    transaction: { userPublicKey: signer.address },
});

// ExactOut: Get exactly 100 USDC, use as little SOL as possible
const exactOutResult = await getTitanSwapPlan({
    swap: {
        inputMint: SOL_MINT,
        outputMint: USDC_MINT,
        amount: 100_000_000n, // 100 USDC
        swapMode: 'ExactOut',
    },
    transaction: { userPublicKey: signer.address },
});

Error Handling

import {
    TitanApiError,
    NoRoutesError,
    ProviderNotFoundError,
    NoInstructionsError,
} from '@pipeit/actions/titan';

try {
    const result = await getTitanSwapPlan({ ... });
} catch (error) {
    if (error instanceof TitanApiError) {
        console.error(`API error (${error.statusCode}): ${error.responseBody}`);
    } else if (error instanceof NoRoutesError) {
        console.error(`No routes available for quote ${error.quoteId}`);
    } else if (error instanceof ProviderNotFoundError) {
        console.error(`Provider ${error.providerId} not found. Available: ${error.availableProviders}`);
    } else if (error instanceof NoInstructionsError) {
        console.error('Route has no instructions (may only provide pre-built transaction)');
    }
}

Type Exports

Client

  • createTitanClient - Create a Titan REST API client
  • TitanClient - Client interface
  • TitanClientConfig - Client configuration

Plan Building

  • getTitanSwapPlan - Main entry point
  • getTitanSwapQuote - Fetch raw quotes
  • selectTitanRoute - Select best route from quotes
  • getTitanSwapInstructionPlanFromRoute - Build plan from route
  • TitanSwapPlanResult - Result type
  • TitanSwapPlanOptions - Options type

Types

  • SwapQuoteParams - Quote request parameters
  • SwapQuotes - Quote response
  • SwapRoute - Individual route
  • RoutePlanStep - Step in a route
  • SwapMode - 'ExactIn' | 'ExactOut'

Errors

  • TitanApiError - API request failed
  • NoRoutesError - No routes available
  • ProviderNotFoundError - Requested provider not found
  • NoInstructionsError - Route has no instructions

Conversion Utilities

  • titanInstructionToKit - Convert Titan instruction to Kit
  • titanPubkeyToAddress - Convert Titan pubkey to Kit Address
  • encodeBase58 - Encode bytes as base58

License

MIT