@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.
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/icsiQuick 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
- Getting Started Guide - Quick setup and basic usage
- Complete API Reference - Detailed function documentation with auth requirements
- Examples - Examples from basic usage to production patterns
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 suiteTypeScript 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
- NPM Account: Create an account at npmjs.com
- Organization Scope: Set up the
@jagadorganization scope - Authentication: Log in to NPM locally
npm login
# Enter your NPM credentialsPre-Publishing Checklist
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 majorRun Quality Checks: The
prepublishOnlyscript automatically runs:- TypeScript type checking
- Code formatting validation
- Unit tests
- Build process
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-run2. Publish to NPM
# For scoped packages (first time)
npm publish --access public
# For subsequent releases
npm publish3. Verify Publication
# Check if package is available
npm view @jagad/icsi
# Install from NPM to verify
npm install @jagad/icsiAutomated 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
- Create GitHub Release: Document the changes
- Update Documentation: Update any external docs
- Announce Release: Share with community
- 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.0Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run the test suite
- Submit a pull request
License
MIT License - see LICENSE.md for details.
Support
- Issues: GitHub Issues
- Documentation: GitHub Repository
- Community: Internet Computer Forum
Related Projects
- Internet Computer - The blockchain this library is built for
- DFinity Agent JS - Core Internet Computer agent library
- IC-CDK - Canister Development Kit for Rust
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
