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

@solana-payment/sdk

v1.0.1

Published

TypeScript SDK for Solana Payment Contract - Build unsigned transactions for frontend

Readme

@solana-payment/sdk

TypeScript SDK for Solana Payment Contract - Build unsigned transactions for frontend applications.

Features

  • 🔐 Wallet-agnostic: Build unsigned transactions, let frontend handle signing
  • 🎯 Type-safe: Full TypeScript support with comprehensive types
  • 🚀 Simple API: Clean, intuitive methods for all contract operations
  • 📦 Zero wallet dependencies: No wallet adapter required
  • Anchor-based: Built on Anchor framework for reliability

Installation

pnpm add @solana-payment/sdk

Or using npm/yarn:

npm install @solana-payment/sdk
yarn add @solana-payment/sdk

Browser/Frontend Setup

If you're using this SDK in a browser environment (React, Next.js, Vue, etc.), you need to configure Buffer polyfill. This SDK includes buffer as a dependency, but your bundler needs to be configured properly.

Quick setup for Vite:

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      buffer: 'buffer',
    },
  },
  define: {
    'global': 'globalThis',
  },
});

// main.tsx
import { Buffer } from 'buffer';
window.Buffer = Buffer;

For Next.js, Create React App, Webpack, and other frameworks: See detailed setup guide in docs/BROWSER_SETUP.md

Quick Start

import { VaultSDK, PROGRAM_ID } from '@solana-payment/sdk';
import { Connection, PublicKey } from '@solana/web3.js';

// Initialize SDK
const connection = new Connection('https://api.devnet.solana.com');
const sdk = new VaultSDK({
  connection,
  programId: PROGRAM_ID, // Optional, uses default if not provided
});

// Build a deposit transaction
const depositTx = await sdk.buildDepositTransaction({
  amount: 1000000, // Amount in raw token units
  user: userPublicKey,
  mint: tokenMintPublicKey,
});

// Frontend signs and sends (using wallet adapter or other method)
await wallet.signTransaction(depositTx);
await connection.sendRawTransaction(depositTx.serialize());

API Documentation

Constructor

new VaultSDK(config: VaultSDKConfig)

Parameters:

  • config.connection: Solana Connection instance
  • config.programId: Program ID (optional, defaults to deployed program)

Query Methods

getConfig()

Fetch vault configuration from on-chain.

const config = await sdk.getConfig();
console.log('Admin:', config.admin.toString());
console.log('Mint:', config.mint.toString());

Returns: Promise<VaultConfig>

getVaultBalance(mint)

Get current vault balance for a specific token mint.

const balance = await sdk.getVaultBalance(mintPublicKey);
console.log('Raw amount:', balance.amount);
console.log('Formatted:', balance.formatted);
console.log('Decimals:', balance.decimals);

Parameters:

  • mint: Token mint PublicKey

Returns: Promise<VaultBalanceInfo>

isInitialized()

Check if vault has been initialized.

const initialized = await sdk.isInitialized();
if (!initialized) {
  console.log('Vault needs to be initialized');
}

Returns: Promise<boolean>

Transaction Builders

All transaction builder methods return unsigned Transaction objects that need to be signed by the frontend before submission.

buildInitializeTransaction(params)

Build transaction to initialize the vault (one-time setup).

const tx = await sdk.buildInitializeTransaction({
  admin: adminPublicKey,
  mint: tokenMintPublicKey,
  payer: payerPublicKey,
});

// Sign and send
await wallet.signTransaction(tx);
await connection.sendRawTransaction(tx.serialize());

Parameters:

  • admin: PublicKey of the admin
  • mint: PublicKey of the SPL token mint
  • payer: PublicKey paying for transaction fees

Returns: Promise<Transaction>

buildDepositTransaction(params)

Build transaction to deposit tokens into the vault.

const tx = await sdk.buildDepositTransaction({
  amount: 1000000, // Raw token amount (e.g., 1 USDC = 1000000 with 6 decimals)
  user: userPublicKey,
  mint: tokenMintPublicKey,
});

// Sign and send
await wallet.signTransaction(tx);
await connection.sendRawTransaction(tx.serialize());

Parameters:

  • amount: Amount to deposit (number or BN)
  • user: PublicKey of the user depositing
  • mint: PublicKey of the token mint

Returns: Promise<Transaction>

buildWithdrawTransaction(params)

Build transaction to withdraw tokens from the vault (admin only).

const tx = await sdk.buildWithdrawTransaction({
  amount: 500000,
  admin: adminPublicKey,
  recipient: recipientPublicKey,
  mint: tokenMintPublicKey,
});

// Admin signs and sends
await adminWallet.signTransaction(tx);
await connection.sendRawTransaction(tx.serialize());

Parameters:

  • amount: Amount to withdraw (number or BN)
  • admin: PublicKey of the admin (must match vault config)
  • recipient: PublicKey receiving the tokens
  • mint: PublicKey of the token mint

Returns: Promise<Transaction>

buildUpdateAdminTransaction(params)

Build transaction to update vault admin (current admin only).

const tx = await sdk.buildUpdateAdminTransaction({
  currentAdmin: currentAdminPublicKey,
  newAdmin: newAdminPublicKey,
});

// Current admin signs and sends
await adminWallet.signTransaction(tx);
await connection.sendRawTransaction(tx.serialize());

Parameters:

  • currentAdmin: PublicKey of current admin (must match vault config)
  • newAdmin: PublicKey of new admin

Returns: Promise<Transaction>

Factory Pattern (Singleton)

For applications that need a single SDK instance:

import { initVaultSDK, getVaultSDK } from '@solana-payment/sdk';

// Initialize once
initVaultSDK({ connection, programId });

// Use anywhere in your app
const sdk = getVaultSDK();
const config = await sdk.getConfig();

Advanced Usage

Working with Token Amounts

The SDK provides utilities for handling token amounts with decimals:

import { formatTokenAmount, validateAmount } from '@solana-payment/sdk';
import { BN } from '@coral-xyz/anchor';

// Format raw amount with decimals
const formatted = formatTokenAmount(new BN(1000000), 6);
console.log(formatted); // "1"

// Validate and convert to BN
const amount = validateAmount(1000000);

PDA Derivation

Manually derive PDAs if needed:

import {
  deriveConfigPDA,
  deriveVaultPDA,
  findVaultTokenAccount,
  findUserTokenAccount,
} from '@solana-payment/sdk';

const { publicKey: configPDA, bump } = await deriveConfigPDA();
const { publicKey: vaultPDA } = await deriveVaultPDA(configPDA);
const vaultATA = await findVaultTokenAccount(vaultPDA, mint);
const userATA = await findUserTokenAccount(userPubkey, mint);

Error Handling

try {
  const tx = await sdk.buildDepositTransaction({
    amount: 0, // Invalid: will throw
    user: userPublicKey,
    mint: mintPublicKey,
  });
} catch (error) {
  console.error('Failed to build transaction:', error.message);
  // Error: Amount must be greater than 0
}

Common errors:

  • "Amount must be greater than 0" - Invalid amount parameter
  • "Missing required parameters" - Required parameters not provided
  • "Config account not found" - Vault not initialized
  • "New admin must be different from current admin" - Same admin provided

Integration Examples

React with Wallet Adapter

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

function DepositButton() {
  const { connection } = useConnection();
  const { publicKey, signTransaction } = useWallet();

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

    const sdk = new VaultSDK({ connection });
    const tx = await sdk.buildDepositTransaction({
      amount: 1000000,
      user: publicKey,
      mint: USDC_MINT,
    });

    const signed = await signTransaction(tx);
    const signature = await connection.sendRawTransaction(signed.serialize());
    await connection.confirmTransaction(signature);
  };

  return <button onClick={handleDeposit}>Deposit</button>;
}

Next.js API Route

// pages/api/build-transaction.ts
import { Connection, PublicKey } from '@solana/web3.js';
import { VaultSDK } from '@solana-payment/sdk';

export default async function handler(req, res) {
  const { amount, user, mint } = req.body;

  const connection = new Connection(process.env.RPC_URL);
  const sdk = new VaultSDK({ connection });

  const tx = await sdk.buildDepositTransaction({
    amount: Number(amount),
    user: new PublicKey(user),
    mint: new PublicKey(mint),
  });

  // Serialize and send to frontend
  const serialized = tx.serialize({ requireAllSignatures: false });
  res.json({ transaction: serialized.toString('base64') });
}

Constants

import {
  PROGRAM_ID,
  TOKEN_PROGRAM_ID,
  ASSOCIATED_TOKEN_PROGRAM_ID,
  RPC_ENDPOINTS,
} from '@solana-payment/sdk';

console.log('Program ID:', PROGRAM_ID.toString());
console.log('Devnet RPC:', RPC_ENDPOINTS.devnet);

TypeScript Types

The SDK exports all TypeScript types for use in your application:

import type {
  VaultSDKConfig,
  VaultConfig,
  InitializeParams,
  DepositParams,
  WithdrawParams,
  UpdateAdminParams,
  VaultBalanceInfo,
} from '@solana-payment/sdk';

Development

# Install dependencies
pnpm install

# Build SDK
pnpm build

# Watch mode
pnpm watch

License

MIT

Support

For issues and questions, please open an issue on GitHub.