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

@jagad/icsi

v1.1.2

Published

Internet Computer Subaccount Indexer Library - TypeScript SDK for ICP multi-token subaccount management, transaction tracking, and automated sweeping with webhook support

Readme

🧑‍🚀 ICSI-Lib - @jagad/icsi

Internet Computer Subaccount Indexer Library - A TypeScript library for interacting with ICP user vault canisters.

Build and Test ICP Prototype Backend npm version License: MIT

Internet Computer Subaccount Indexer Library - A comprehensive TypeScript SDK for ICP multi-token subaccount management, transaction tracking, and automated sweeping with webhook support.

Features

🚀 Multi-Token Support: ICP, ckUSDC, and ckUSDT
🏦 Subaccount Management: Generate and manage unique deposit addresses
📊 Transaction Tracking: Real-time transaction indexing and monitoring
🧹 Automated Sweeping: Automatic token collection from subaccounts
🔔 Webhook Integration: Real-time notifications for new transactions
Production Ready: Fully tested and production-proven codebase
🔒 Type Safe: Complete TypeScript support with full type definitions

Installation

npm install @jagad/icsi
# or
pnpm install @jagad/icsi
# or
yarn add @jagad/icsi

Quick Start

import { HttpAgent } from '@dfinity/agent';
import {
  getUserVaultTransactions,
  addSubaccountForToken,
  getDepositAddresses,
  Tokens,
} from '@jagad/icsi';

// Initialize agent
const agent = new HttpAgent({ host: 'https://ic0.app' });
const canisterId = 'your-canister-id';

// Create a new subaccount for ckUSDC
const subaccount = await addSubaccountForToken(
  agent,
  canisterId,
  Tokens.CKUSDC
);
console.log('New ckUSDC subaccount:', subaccount);

// Get all deposit addresses
const addresses = await getDepositAddresses(agent, canisterId);
console.log('Deposit addresses:', addresses);

// Fetch recent transactions
const transactions = await getUserVaultTransactions(
  agent,
  canisterId,
  BigInt(10)
);
console.log('Recent transactions:', transactions);

Supported Tokens

| Token | Type | Ledger Canister ID | Address Format | | ---------- | ------ | ----------------------------- | --------------------- | | ICP | Native | ryjl3-tyaaa-aaaaa-aaaba-cai | Hex AccountIdentifier | | ckUSDC | ICRC-1 | xevnm-gaaaa-aaaar-qafnq-cai | ICRC-1 Textual | | ckUSDT | ICRC-1 | cngnf-vqaaa-aaaar-qag4q-cai | ICRC-1 Textual | | ckBTC | ICRC-1 | mxzaz-hqaaa-aaaar-qaada-cai | ICRC-1 Textual |

Documentation

API Reference

Query Functions (Read-only)

Transaction Management

// Get transactions with optional limit
getUserVaultTransactions(agent: HttpAgent, canisterId: string, limit?: bigint): Promise<Result_9>

// Get total transaction count
getTransactionsCount(agent: HttpAgent, canisterId: string): Promise<number>

// Get transactions by token type
getTransactionsByTokenType(agent: HttpAgent, canisterId: string, tokenType: TokenType): Promise<Transaction[]>

Subaccount Operations

// Get subaccount by index and token type
getSubaccountId(agent: HttpAgent, canisterId: string, index: number, tokenType: TokenType): Promise<string>

// Get ICRC account format
getIcrcAccount(agent: HttpAgent, canisterId: string, index: number): Promise<string>

// Get total subaccount count
getSubaccountCount(agent: HttpAgent, canisterId: string): Promise<number>

Configuration & Status

// Get polling interval
getUserVaultInterval(agent: HttpAgent, canisterId: string): Promise<bigint>

// Get webhook URL
getWebhookUrl(agent: HttpAgent, canisterId: string): Promise<string>

// Get network type
getNetwork(agent: HttpAgent, canisterId: string): Promise<'Mainnet' | 'Local'>

// Get registered tokens
getRegisteredTokens(agent: HttpAgent, canisterId: string): Promise<Result_7>

Update Functions (State-modifying)

Subaccount Creation

// Create basic ICP subaccount
addSubaccount(agent: HttpAgent, canisterId: string): Promise<Result_1>

// Create token-specific subaccount
addSubaccountForToken(agent: HttpAgent, canisterId: string, tokenType: TokenType): Promise<Result_1>

Token Management

// Register a new token type
registerToken(agent: HttpAgent, canisterId: string, tokenType: TokenType, ledgerCanisterId: string): Promise<Result_5>

Sweep Operations

// Sweep all tokens from all subaccounts
sweep(agent: HttpAgent, canisterId: string): Promise<Result_3>

// Sweep specific token type
sweepByTokenType(agent: HttpAgent, canisterId: string, tokenType: TokenType): Promise<Result_3>

// Sweep specific subaccount
sweepSubaccountId(agent: HttpAgent, canisterId: string, subaccountId: string, amount: number, tokenType?: TokenType): Promise<Result_2>

Configuration

// Set polling interval
setUserVaultInterval(agent: HttpAgent, canisterId: string, interval: bigint): Promise<Result_6>

// Set webhook URL
setWebhookUrl(agent: HttpAgent, canisterId: string, url: string): Promise<Result_4>

Helper Functions

// Get all deposit addresses for all tokens
getDepositAddresses(agent: HttpAgent, canisterId: string): Promise<DepositAddress[]>

// Get balances for all tokens
getBalances(agent: HttpAgent, canisterId: string): Promise<TokenBalance[]>

// Validate ICRC account format
validateIcrcAccount(agent: HttpAgent, canisterId: string, account: string): Promise<boolean>

Token Constants

import { Tokens } from '@jagad/icsi';

// Available token types
Tokens.ICP; // { ICP: null }
Tokens.CKUSDC; // { CKUSDC: null }
Tokens.CKUSDT; // { CKUSDT: null }
Tokens.CKBTC; // { CKBTC: null }

Authentication

The library supports multiple authentication methods:

Using Seed Phrase

import { createHostAgentAndIdentityFromSeed } from '@jagad/icsi';

const { agent } = await createHostAgentAndIdentityFromSeed(
  'your twelve word seed phrase here',
  'https://ic0.app'
);

Using Private Key

import { createHostAgentAndIdentityFromPrivateKey } from '@jagad/icsi';

const privateKey = `-----BEGIN EC PRIVATE KEY-----
Your PEM private key here
-----END EC PRIVATE KEY-----`;

const { agent } = await createHostAgentAndIdentityFromPrivateKey(
  privateKey,
  'https://ic0.app'
);

Examples

Payment Processing Workflow

import { HttpAgent } from '@dfinity/agent';
import {
  addSubaccountForToken,
  getUserVaultTransactions,
  sweepByTokenType,
  setWebhookUrl,
  Tokens,
} from '@jagad/icsi';

const agent = new HttpAgent({ host: 'https://ic0.app' });
const canisterId = 'your-canister-id';

// 1. Set up webhook for real-time notifications
await setWebhookUrl(agent, canisterId, 'https://your-api.com/webhook');

// 2. Create deposit addresses for customers
const usdcAddress = await addSubaccountForToken(
  agent,
  canisterId,
  Tokens.CKUSDC
);
console.log('Customer USDC deposit address:', usdcAddress);

// 3. Monitor for incoming payments
const checkPayments = async () => {
  const transactions = await getUserVaultTransactions(
    agent,
    canisterId,
    BigInt(50)
  );

  if ('Ok' in transactions) {
    const recentTransactions = transactions.Ok.filter(
      (tx) =>
        tx.token_type.CKUSDC !== undefined &&
        tx.sweep_status.Pending !== undefined
    );

    console.log(`Found ${recentTransactions.length} pending USDC payments`);
  }
};

// 4. Sweep collected funds
const sweepFunds = async () => {
  const result = await sweepByTokenType(agent, canisterId, Tokens.CKUSDC);
  console.log('Sweep result:', result);
};

Multi-Token Deposit Address Generation

import { getDepositAddresses, Tokens } from '@jagad/icsi';

const generateCustomerAddresses = async (customerId: string) => {
  const addresses = await getDepositAddresses(agent, canisterId);

  const customerAddresses = {
    customerId,
    addresses: {
      ICP: addresses.find((addr) => addr.tokenType.ICP)?.depositAddress,
      USDC: addresses.find((addr) => addr.tokenType.CKUSDC)?.depositAddress,
      USDT: addresses.find((addr) => addr.tokenType.CKUSDT)?.depositAddress,
    },
  };

  return customerAddresses;
};

Error Handling

import { getUserVaultTransactions } from '@jagad/icsi';

try {
  const transactions = await getUserVaultTransactions(agent, canisterId);

  if ('Ok' in transactions) {
    console.log('Transactions:', transactions.Ok);
  } else {
    console.error('Error fetching transactions:', transactions.Err);
  }
} catch (error) {
  console.error('Network or authentication error:', error);
}

Testing

The library includes comprehensive test suites:

# Run unit tests
pnpm test:unit

# Run integration tests (requires canister access)
pnpm test:query      # Safe read-only tests
pnpm test:functions  # Interactive test runner
pnpm test:all        # Complete test suite

TypeScript Support

Full TypeScript support with complete type definitions:

import type {
  TokenType,
  Transaction,
  DepositAddress,
  TokenBalance,
  Result_9,
} from '@jagad/icsi';

// All functions are fully typed
const handleTransactions = (transactions: Result_9) => {
  if ('Ok' in transactions) {
    transactions.Ok.forEach((tx: Transaction) => {
      console.log(`Transaction ${tx.tx_hash}: ${tx.amount} ${tx.token_type}`);
    });
  }
};

Publishing to NPM

Prerequisites

  1. NPM Account: Create an account at npmjs.com
  2. Organization Scope: Set up the @jagad organization scope
  3. Authentication: Log in to NPM locally
npm login
# Enter your NPM credentials

Pre-Publishing Checklist

  1. Update Version: Use semantic versioning

    # For patch releases (bug fixes)
    npm version patch
    
    # For minor releases (new features)
    npm version minor
    
    # For major releases (breaking changes)
    npm version major
  2. Run Quality Checks: The prepublishOnly script automatically runs:

    • TypeScript type checking
    • Code formatting validation
    • Unit tests
    • Build process
  3. Test Package Locally:

    # Build the package
    pnpm run build
    
    # Test locally with npm pack
    npm pack
    
    # Test installation in another project
    npm install ./jagad-icsi-1.0.0.tgz

Publishing Steps

1. Dry Run (Recommended)

# See what would be published
npm publish --dry-run

2. Publish to NPM

# For scoped packages (first time)
npm publish --access public

# For subsequent releases
npm publish

3. Verify Publication

# Check if package is available
npm view @jagad/icsi

# Install from NPM to verify
npm install @jagad/icsi

Automated Publishing with GitHub Actions

Create .github/workflows/publish.yml:

name: Publish to NPM

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          registry-url: 'https://registry.npmjs.org/'

      - name: Install pnpm
        uses: pnpm/action-setup@v2
        with:
          version: 8

      - name: Install dependencies
        run: pnpm install

      - name: Build package
        run: pnpm run build
        working-directory: packages/icsi-lib

      - name: Publish to NPM
        run: npm publish --access public
        working-directory: packages/icsi-lib
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Post-Publishing

  1. Create GitHub Release: Document the changes
  2. Update Documentation: Update any external docs
  3. Announce Release: Share with community
  4. Monitor: Watch for issues or feedback

Versioning Strategy

Follow Semantic Versioning:

  • Patch (1.0.1): Bug fixes, no breaking changes
  • Minor (1.1.0): New features, backward compatible
  • Major (2.0.0): Breaking changes

Example version updates:

# Bug fix release
npm version patch   # 1.0.0 → 1.0.1

# New feature release
npm version minor   # 1.0.1 → 1.1.0

# Breaking change release
npm version major   # 1.1.0 → 2.0.0

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Run the test suite
  6. Submit a pull request

License

MIT License - see LICENSE.md for details.

Support

Related Projects


Context7 MCP

ICSI-Lib is available in Context7 Model Context Protocol at:
https://context7.com/garudaidr/icp-subaccount-indexer

This provides developers with AI-powered access to ICSI-Lib documentation and examples.


Built with ❤️ for the Internet Computer ecosystem