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

@apollosolution/vault-sdk

v0.1.1

Published

TypeScript SDK for integrating SendIt vaults into external applications

Readme

@apollosolution/vault-sdk

TypeScript SDK for integrating SendIt vaults into external applications.

Note: This SDK focuses on vault operations and transaction construction. For wallet management, we recommend using @solana/wallet-adapter-react or similar wallet integration libraries.

What This SDK Does

Vault Discovery: Find vaults by type or deposit token
Vault Information: Get detailed vault metrics, APY, TVL, and configuration
User Positions: Track user deposits and earnings across vaults
Transaction Construction: Create unsigned transactions for deposits/withdrawals
Fee Calculations: Calculate deposit fees and estimate future earnings
Analytics: Get comprehensive vault statistics and performance metrics

What This SDK Doesn't Do

Wallet Management: Connect, disconnect, or manage wallet state
Transaction Signing: Sign transactions with user's private keys
Transaction Submission: Send transactions to the Solana network

Why this separation? Wallet management is a security-sensitive area best handled by dedicated, audited libraries like @solana/wallet-adapter-react. This keeps our SDK focused, lightweight, and secure.

Installation

npm install @apollosolution/vault-sdk
# or
yarn add @apollosolution/vault-sdk
# or
pnpm add @apollosolution/vault-sdk

Quick Start

import { VaultClient } from '@apollosolution/vault-sdk';

// Initialize the client
const client = new VaultClient({
  apiUrl: 'https://backend.sendit.fun' // Optional, this is the default
});

// Get vault information
const vault = await client.singleSided.getVault('VAULT_ADDRESS');
console.log(`Vault APY: ${vault.vault.metrics.grossAPY}%`);

// Get user position
const position = await client.singleSided.getUserPosition(
  'VAULT_ADDRESS',
  'USER_WALLET_ADDRESS'
);
console.log(`User position: ${position.position.underlyingAmount} tokens`);

Features

  • 🚀 Simple, intuitive API
  • 💼 Full TypeScript support
  • ⚡ Transaction construction
  • 📊 Position tracking and analytics
  • 💰 Fee calculation utilities

Documentation

For complete documentation and examples, see the integration guide.

API Reference

VaultClient

The main client for interacting with SendIt vaults.

const client = new VaultClient({
  apiUrl?: string;    // API endpoint (default: https://backend.sendit.fun)
  apiKey?: string;    // Optional API key for authentication
  timeout?: number;   // Request timeout in ms (default: 30000)
});

Single-Sided Vaults

Access single-sided vault functionality through client.singleSided:

Vault Discovery

// List all single-sided vaults
const vaults = await client.singleSided.listVaults();

// Get vault by deposit token (e.g., NOBODY vault)
const nobodyVault = await client.singleSided.getVaultByToken('C29ebrgYjYoJPMGPnPSGY1q3mMGk4iDSqnQeQQA7moon');
// Also accepts PublicKey objects
const vault = await client.singleSided.getVaultByToken(new PublicKey('C29ebrgYjYoJPMGPnPSGY1q3mMGk4iDSqnQeQQA7moon'));

Vault Information

// Get detailed vault information
const vault = await client.singleSided.getVault(vaultId);
console.log(vault.vault.metrics.grossAPY);  // Annual Percentage Yield
console.log(vault.vault.tvl.totalValueUsd); // Total Value Locked in USD

// Get vault statistics summary
const stats = await client.singleSided.getVaultStats(vaultId);
console.log(stats); // { tvl, tvlUsd, grossAPR, grossAPY, depositFeePercent, etc. }

User Positions

// Get user position in a vault
const position = await client.singleSided.getUserPosition(vaultId, walletAddress);
// Also accepts PublicKey objects
const position = await client.singleSided.getUserPosition(vaultId, new PublicKey('WALLET_ADDRESS'));

console.log(position.position.underlyingAmount);    // User's deposited amount
console.log(position.position.underlyingAmountUsd); // USD value
console.log(position.position.vaultTokens);         // Vault tokens owned
console.log(position.position.share);               // % of vault owned
console.log(position.wallet.depositToken.balance);  // Available wallet balance

Transactions

// Create deposit transaction (returns unsigned transactions)
const depositTxs = await client.singleSided.deposit(vaultId, amount, walletAddress);

// Create withdrawal transaction (returns unsigned transactions)
const withdrawTxs = await client.singleSided.withdraw(vaultId, amount, walletAddress);

// Withdraw entire position (returns unsigned transactions)
const withdrawMaxTxs = await client.singleSided.withdrawMax(vaultId, walletAddress);

// All transaction methods accept string or PublicKey for wallet address
const depositTxs = await client.singleSided.deposit(vaultId, amount, new PublicKey('WALLET_ADDRESS'));

Financial Calculations

// Calculate deposit fees
const fees = await client.singleSided.calculateDepositFee(vaultId, amount);
console.log(fees); // { fee, feePercentage, netDeposit }

// Estimate earnings over time
const earnings = await client.singleSided.estimateEarnings(vaultId, amount);
console.log(earnings); // { dailyEarnings, monthlyEarnings, yearlyEarnings, grossAPR, grossAPY }

Examples

Wallet Integration with @solana/wallet-adapter-react

import { VaultClient } from '@apollosolution/vault-sdk';
import { useWallet, useConnection } from '@solana/wallet-adapter-react';
import { useState } from 'react';

export function DepositComponent() {
  const { publicKey, signAllTransactions } = useWallet();
  const { connection } = useConnection();
  const [amount, setAmount] = useState('');
  
  const client = new VaultClient();

  const handleDeposit = async () => {
    if (!publicKey || !signAllTransactions) return;

    try {
      // Calculate fees before deposit
      const fees = await client.singleSided.calculateDepositFee('VAULT_ADDRESS', amount);
      console.log(`Deposit fee: ${fees.fee} (${fees.feePercentage}%)`);
      console.log(`Net deposit: ${fees.netDeposit}`);

      // Create deposit transactions (returns UNSIGNED transactions)
      const transactions = await client.singleSided.deposit(
        'VAULT_ADDRESS',
        amount,
        publicKey
      );

      // ⚠️ SDK returns unsigned transactions - you must sign them with your wallet
      const signedTxs = await signAllTransactions(transactions);

      // Send transactions using your preferred method
      for (const tx of signedTxs) {
        const signature = await connection.sendTransaction(tx, {
          skipPreflight: false,
          maxRetries: 3
        });
        await connection.confirmTransaction(signature, 'confirmed');
        console.log(`Transaction confirmed: ${signature}`);
      }
    } catch (error) {
      console.error('Deposit failed:', error);
    }
  };

  return (
    <div>
      <input 
        value={amount} 
        onChange={(e) => setAmount(e.target.value)}
        placeholder="Amount to deposit" 
      />
      <button onClick={handleDeposit}>Deposit</button>
    </div>
  );
}

Complete Vault Discovery Example

import { VaultClient, PublicKey } from '@apollosolution/vault-sdk';

const client = new VaultClient();

async function findAndAnalyzeVault() {
  // Find NOBODY vault
  const nobodyMint = 'C29ebrgYjYoJPMGPnPSGY1q3mMGk4iDSqnQeQQA7moon';
  
  try {
    // Get the NOBODY vault directly by token
    const vault = await client.singleSided.getVaultByToken(nobodyMint);
    const stats = await client.singleSided.getVaultStats(vault.vault.address);
    
    console.log(`NOBODY Vault ${vault.vault.address}:`);
    console.log(`  APY: ${vault.vault.metrics.grossAPY}%`);
    console.log(`  TVL: $${stats.tvlUsd.toLocaleString()}`);
    console.log(`  Deposit Fee: ${stats.depositFeePercent}%`);
    console.log(`  Deposit Token: ${vault.vault.depositToken.symbol}`);
    console.log(`  Vault Token: ${vault.vault.vaultToken.symbol}`);
    
    return vault;
  } catch (error) {
    console.log('NOBODY vault not found');
    return null;
  }
}

Monitor User Position

import { VaultClient } from '@apollosolution/vault-sdk';

const client = new VaultClient();

async function monitorPosition(vaultId: string, wallet: string) {
  try {
    const position = await client.singleSided.getUserPosition(vaultId, wallet);
    
    console.log('Current Position:', {
      vaultTokens: position.position.vaultTokens,
      underlyingValue: position.position.underlyingAmount,
      valueUsd: position.position.underlyingAmountUsd,
      shareOfVault: `${position.position.share}%`
    });
    
    console.log('Wallet Balance:', {
      depositToken: position.wallet.depositToken.balance,
      valueUsd: position.wallet.depositToken.balanceUsd
    });
    
    // Calculate potential earnings
    const earnings = await client.singleSided.estimateEarnings(
      vaultId, 
      position.position.underlyingAmount
    );
    
    console.log('Estimated Earnings:', {
      daily: `$${Number(earnings.dailyEarnings).toFixed(2)}`,
      monthly: `$${Number(earnings.monthlyEarnings).toFixed(2)}`,
      yearly: `$${Number(earnings.yearlyEarnings).toFixed(2)}`
    });
    
  } catch (error) {
    console.error('Failed to fetch position:', error);
  }
}

// Monitor every 30 seconds
setInterval(() => {
  monitorPosition('VAULT_ADDRESS', 'WALLET_ADDRESS');
}, 30000);

Error Handling Best Practices

import { VaultClient, ApiError } from '@apollosolution/vault-sdk';

const client = new VaultClient();

async function safeVaultOperation() {
  try {
    const vault = await client.singleSided.getVault('VAULT_ADDRESS');
    return vault;
  } catch (error) {
    if (error instanceof ApiError) {
      // Handle SDK-specific errors
      console.error(`API Error (${error.code}):`, error.message);
      
      switch (error.code) {
        case 'VAULT_NOT_FOUND':
          console.log('This vault does not exist');
          break;
        case 'NETWORK_ERROR':
          console.log('Please check your internet connection');
          break;
        default:
          console.log('An unexpected error occurred');
      }
    } else {
      // Handle other errors
      console.error('Unexpected error:', error);
    }
    throw error;
  }
}

TypeScript Types

The SDK provides comprehensive TypeScript types for all responses:

import { 
  VaultClient,
  VaultResponse,
  UserPositionResponse,
  VaultListResponse,
  VaultType,
  TokenInfo,
  VaultMetrics,
  PublicKey
} from '@apollosolution/vault-sdk';

// All API responses are fully typed
const client = new VaultClient();

// VaultResponse type includes all vault information
const vault: VaultResponse = await client.singleSided.getVault('VAULT_ID');

// Access nested properties with full IntelliSense support
const apy: number = vault.vault.metrics.grossAPY;
const tvl: number = vault.vault.tvl.totalValueUsd;
const depositToken: TokenInfo = vault.vault.depositToken;

// UserPositionResponse includes both position and wallet data
const position: UserPositionResponse = await client.singleSided.getUserPosition('VAULT_ID', 'WALLET');
const userBalance: string = position.wallet.depositToken.balance;
const vaultShare: number = position.position.share;

Configuration

Client Configuration

const client = new VaultClient({
  apiUrl: 'https://backend.sendit.fun',  // Default: https://backend.sendit.fun
  apiKey: 'your-api-key',                // Optional: for authenticated endpoints
  timeout: 30000                         // Default: 30000ms (30 seconds)
});

Environment Variables

You can also configure the SDK using environment variables:

# Optional: Override default API URL
VAULT_SDK_API_URL=https://backend.sendit.fun

# Optional: Set default API key
VAULT_SDK_API_KEY=your-api-key

# Optional: Set default timeout
VAULT_SDK_TIMEOUT=30000

Supported Vault Types

Currently supported vault types:

  • single-sided: Single-token vaults (accessible via client.singleSided)
  • 🔜 sol: SOL-specific vaults (coming soon)

Rate Limits

The SDK respects the backend API rate limits. If you encounter rate limiting:

  • Implement exponential backoff for retries
  • Cache vault information when possible
  • Use batch operations where available

Security

  • No Private Keys: SDK never handles private keys or seeds
  • HTTPS Only: All API calls use HTTPS
  • Input Validation: All inputs are validated before API calls
  • Error Handling: Comprehensive error handling with specific error codes

License

MIT