Skip to content

ICSI (ICP Sub-Account Indexer) is a robust solution designed to streamline the management and indexing of sub-accounts within the ICP (Internet Computer Protocol) ecosystem.

License

Notifications You must be signed in to change notification settings

garudaidr/icp-subaccount-indexer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🧑‍🚀 ICSI: ICP Sub-Account Indexer

Streamline the management and indexing of principal sub-accounts for ICRC transactions.

Build and Test ICP Prototype Backend

Overview

ICSI (ICP Sub-Account Indexer) is a robust solution designed to streamline the management and indexing of sub-accounts within the ICP (Internet Computer Protocol) ecosystem. This project aims to enhance the efficiency, security, and scalability of handling multiple sub-accounts under a single principal, making it easier for users and administrators to manage their ICP assets.

The ICSI canister provides methods that allow organizations to primarily carry out several operations:

  • Generate sub-account-ids supporting both formats:
    • ICP: Traditional hex_string AccountIdentifier format
    • ckUSDC/ckUSDT/ckBTC: ICRC-1 textual format (e.g., canister-id-checksum.index)
  • Track incoming token transfers (ICP, ckUSDC, ckUSDT, ckBTC) into created sub-account-ids
  • Manage multi-token balances across all sub-accounts
  • Send webhook notifications for incoming deposits (transaction hash as query parameter)
  • Sweep tokens from sub-accounts to main principal

Video Demo

If you are interested in learning more from the builders of ICSI, you can watch the product pitch and presentation in the attached videos below:

Description

1. Simplicity

ICSI simplifies the process of managing sub-accounts by providing a clear and intuitive interface for creating, tracking, and managing sub-accounts. Users can easily generate new sub-accounts and view transaction histories without dealing with the underlying complexities.

2. Security

Security is paramount in ICSI. By leveraging the ICP's robust security features and integrating additional validation mechanisms, ICSI ensures that all transactions are secure and compliant with best practices. Features like illicit transaction detection and refund capabilities add extra layers of protection for users' assets.

3. Scalability

ICSI is built to scale. With efficient indexing and transaction handling, the system can manage tens of thousands of sub-accounts without compromising performance. The design ensures that querying and managing transactions remains fast and reliable, even as the number of users grows.

4. Sequence Flow

sequenceDiagram
    participant User as User (via J-Wallet)
    participant ICSI as ICSI Canister
    participant Sub_Account as User Sub-Account
    participant Ledger as Token Ledger<br/>(ICP/ckUSDC/ckUSDT/ckBTC)
    participant Webhook as Webhook Server
    participant Admin as Admin

    User ->> ICSI: Request deposit address for token type
    ICSI ->> ICSI: Generate subaccount ID<br/>(hex for ICP, ICRC-1 for others)
    ICSI -->> User: Return deposit address

    User ->> Sub_Account: Send tokens to deposit address
    Sub_Account ->> Ledger: Transaction recorded on ledger

    Note over ICSI: Timer-based polling (configurable interval)

    loop Every polling interval
        ICSI ->> Ledger: query_blocks() for new transactions
        Ledger -->> ICSI: Return new blocks since last check
        ICSI ->> ICSI: Index transactions<br/>Update next_block position
    end

    ICSI ->> Webhook: POST /webhook?tx_hash=<hash>
    Webhook -->> ICSI: 200 OK

    Admin ->> ICSI: Trigger sweep operation
    ICSI ->> Sub_Account: Transfer tokens to main principal
    ICSI ->> ICSI: Mark transaction as swept

    Note right of ICSI: Multi-token support with<br/>unified APIs for all operations
Loading

How It Works

1. Subaccount Derivation

ICSI uses a sophisticated mechanism to derive sub-accounts from a single principal ID. Each sub-account is generated using a combination of the principal ID and a subaccount number, ensuring privacy and uniqueness. This allows for an infinite number of sub-accounts under one principal.

2. Transaction Management

Transactions are tracked and managed efficiently. ICSI can list, clear, and refund transactions across sub-accounts, ensuring that all financial activities are transparent and manageable.

3. Sweeping Mechanism

ICSI incorporates a sweeping mechanism to centralize funds from sub-accounts to a main principal account. This process involves validating transactions and ensuring that only legitimate deposits are swept to the main account.

Technical Specifications

ICSI is built with a focus on modularity and extensibility. The core components include:

  • Subaccount Management: Efficient handling of subaccount creation and indexing.
  • Transaction Handling: Robust mechanisms for listing, clearing, and refunding transactions.
  • Security Features: Integration with third-party services for transaction validation and illicit activity detection.

Canister Methods

The canister provides several methods to assist with multi-token deposit management. The complete methods can be observed inside Candid File

Core Methods

// Generate deposit addresses
add_subaccount : (opt TokenType) -> (variant { Ok : text; Err : Error });
generate_icp_deposit_address : (nat32) -> (text);
generate_icrc1_deposit_address : (TokenType, nat32) -> (text);

// Token operations
sweep : (TokenType) -> (variant { Ok : vec text; Err : Error });
single_sweep : (TokenType, text) -> (variant { Ok : vec text; Err : Error });
sweep_all : (TokenType) -> (variant { Ok : vec text; Err : Error });

// Balance queries
get_balance : (TokenType) -> (nat);

// Transaction management
get_transactions_count : () -> (nat64);
list_transactions : (opt nat64) -> (vec Transaction);
get_transaction : (text) -> (opt Transaction);

Address Format Examples

  • ICP: bd54f8b5e0fe4c6b8c6b8c6b8c6b8c6b8c6b8c6b8c6b8c6b8c6b8c6b8c6b8c6b (hex)
  • ckUSDC: y3hne-ryaaa-aaaag-aucea-cai-dzfvpaa.5 (ICRC-1 textual)
  • ckUSDT: y3hne-ryaaa-aaaag-aucea-cai-2jmuz5q.10 (ICRC-1 textual)
  • ckBTC: y3hne-ryaaa-aaaag-aucea-cai-3xur6ta.15 (ICRC-1 textual)

Supported Token Types

type TokenType = variant { ICP; CKUSDC; CKUSDT; CKBTC };

The canister automatically registers all four token types during initialization:

  • ICP: ryjl3-tyaaa-aaaaa-aaaba-cai (Native ICP ledger)
  • ckUSDC: xevnm-gaaaa-aaaar-qafnq-cai (Chain-key USDC)
  • ckUSDT: cngnf-vqaaa-aaaar-qag4q-cai (Chain-key USDT)
  • ckBTC: mxzaz-hqaaa-aaaar-qaada-cai (Chain-key Bitcoin)

Webhook Configuration

set_webhook_url : (text) -> ();
get_webhook_url : () -> (opt text);

Webhooks send POST requests with transaction hash as query parameter:

POST https://your-webhook.com/endpoint?tx_hash=<transaction_hash>

Project Structure

This is a pnpm workspace monorepo containing:

  • Root: DFX canister configuration, deployment scripts, and build tools
  • src/icp_subaccount_indexer/: Rust canister implementation
  • packages/icsi-lib/: TypeScript SDK for canister interaction
    • /src: Library source code
    • /test/scripts: Modern test suite (shell and TypeScript)
    • /test/scripts/legacy: Deprecated test scripts
  • scripts/: Production deployment scripts
  • .maintain/: Maintenance scripts and tools
  • docs/logs/: Detailed testing logs and procedures

See WORKSPACE.md for detailed monorepo documentation.

Canister Environment Configuration

The project maintains five canister_ids.json files for different deployment environments:

1. canister_ids.json (Template/Active Configuration)

  • Canister ID: "" (empty - populated based on environment)
  • Purpose: Template file that gets populated with the appropriate canister ID
  • Usage: Active configuration file used by DFX and deployment scripts
  • Note: This file should be copied from one of the environment-specific files below

2. test_canister_ids.json (Shared Staging)

  • Canister ID: uiz2m-baaaa-aaaal-qjbxq-cai
  • Environment: Shared staging/testnet
  • Controller: STAGING_DEPLOYER identity (for upgrades), testnet_custodian (for operations)
  • Purpose: Team-shared environment for final testing before production
  • Usage: Used for coordinated testing and validation workflows

3. devnet_canister_ids.json (Individual Development)

  • Canister ID: y3hne-ryaaa-aaaag-aucea-cai
  • Environment: Individual developer environment
  • Controller: default identity
  • Purpose: Personal development, debugging, and experimentation
  • Usage: Individual developer testing without affecting shared environments

4. old_mainnet_canister_ids.json (Legacy Archive)

  • Canister ID: g5nrt-myaaa-aaaap-qhluq-cai
  • Environment: Previous production deployment (archived)
  • Status: Historical reference only
  • Purpose: Backup reference for migration and historical data
  • Usage: Not actively used, maintained for reference
  • Controllers (as of verification):
    • e3mmv-5qaaa-aaaah-aadma-cai (Black hole canister - version 0.0.0)
    • fgu3n-zl522-yxi3v-t4cie-ay33r-pc425-t6ua7-u6ygs-s7e63-d6aex-4ae
    • ndmaj-wyg44-p2rfh-grnup-pgseg-4eliy-dqaui-ijnbl-fja3x-mhguz-wae
  • Note: Black hole added as additional controller (not sole controller), maintaining transparency while retaining upgrade capability

5. Production Mainnet

  • Canister ID: qvn3w-rqaaa-aaaam-qd4kq-cai
  • Environment: Current production mainnet
  • Controllers (as of November 2025):
    • e3mmv-5qaaa-aaaah-aadma-cai (Black hole canister - version 0.0.0)
    • h74q4-sfve2-7tqhf-ucha6-yameo-l73ks-r3knw-bolek-gwp3j-mjzss-sqe (Custodian identity)
  • Polling Interval: 60 seconds (balanced performance and cost efficiency)
  • Purpose: Active production deployment for live operations
  • File: Copy this ID to canister_ids.json when deploying to production
  • Black Hole Configuration: Added as additional controller (November 7, 2025) for public transparency while maintaining upgrade capability

Environment Selection Strategy

The deployment and testing scripts use the active canister_ids.json file. To switch environments, copy the appropriate environment-specific file:

  • Production deployments: Copy production canister ID to canister_ids.json
  • Team testing: Copy test_canister_ids.json to canister_ids.json
  • Development work: Copy devnet_canister_ids.json to canister_ids.json
  • Legacy reference: Copy old_mainnet_canister_ids.json to canister_ids.json (if needed)

Independent Environment State

Each environment maintains completely independent:

  • Token balances: ICP, ckUSDC, ckUSDT, ckBTC balances are separate
  • Transaction history: No shared transaction data between environments
  • Block processing positions: Each environment tracks its own next_block positions
  • Webhook configurations: Separate webhook URLs and settings
  • Access control: Different controller and custodian principals
  • Cycle balances: Independent cycle management per environment

Environment Switching

To work with a specific environment, copy the appropriate file to canister_ids.json:

# Switch to staging environment
cp test_canister_ids.json canister_ids.json

# Switch to development environment
cp devnet_canister_ids.json canister_ids.json

# Switch to legacy archive (for reference)
cp old_mainnet_canister_ids.json canister_ids.json

# Switch to production mainnet (NEW_MAINNET_CUSTODIAN)
echo '{"icp_subaccount_indexer": {"ic": "qvn3w-rqaaa-aaaam-qd4kq-cai"}}' > canister_ids.json

# Always verify which environment you're targeting
cat canister_ids.json

⚠️ Important: Always verify which environment you're working with before making changes, especially when dealing with production funds or testing.

For detailed debugging and management procedures for each environment, see:

Usage

Quick Start

  1. Prerequisites

    • Install DFX
    • Install Node.js and pnpm (npm install -g pnpm)
    • Have ICP tokens for mainnet deployment
  2. Local Development

    # Install all dependencies (monorepo)
    pnpm install
    
    # Start local replica with old metering (required for ICP ledger)
    pnpm run start:local:env
    
    # Deploy locally with ICP ledger
    pnpm run deploy:local
    # OR use the deployment script directly
    .maintain/deploy.sh --network local [--clean]
    
    # Generate test wallet for testing
    pnpm run lib:generate:wallet
  3. Mainnet Deployment

    # Deploy to mainnet
    ./scripts/deploy-mainnet.sh deploy
    
    # Upgrade existing canister
    ./scripts/deploy-mainnet.sh upgrade

Deployment

Local Development

For local development with ICP ledger:

.maintain/deploy.sh --network local [--clean]

Mainnet Deployment

Option A: Using Deployment Script (Recommended)

./scripts/deploy-mainnet.sh deploy  # Initial deployment
./scripts/deploy-mainnet.sh upgrade # Upgrade existing

Option B: Manual Deployment

  1. Create Internet Identity & Fund Wallet

  2. Setup Local Identity

    # Create new identity
    dfx identity new custodian_name
    dfx identity use custodian_name
    
    # Get and save your principal
    export CUSTODIAN_PRINCIPAL=$(dfx identity get-principal)
    echo "Principal: $CUSTODIAN_PRINCIPAL"
  3. Create Canister via NNS Dashboard

    • Create new canister in NNS with sufficient cycles
    • Add your principal as controller
    • Save the canister ID
  4. Deploy Canister

    # Add canister ID to canister_ids.json
    echo '{"icp_subaccount_indexer": {"ic": "your-canister-id"}}' > canister_ids.json
    
    # Convert ICP to cycles
    dfx cycles convert 0.3 --network ic
    
    # Deploy with your principal (replace with actual value)
    dfx deploy icp_subaccount_indexer --network ic --argument '(variant { Mainnet }, 5: nat64, 0: nat32, "ryjl3-tyaaa-aaaaa-aaaba-cai", "YOUR-PRINCIPAL-HERE")'

Post-Deployment Configuration

After deployment, configure the multi-token block positions:

# Replace <CANISTER_ID> with your actual canister ID

# 1. Verify tokens are registered (should show ICP, CKUSDC, CKUSDT, CKBTC)
dfx canister call <CANISTER_ID> get_registered_tokens --network ic

# 2. Set correct mainnet block positions for each token
# ICP - use a recent block number
dfx canister call <CANISTER_ID> set_token_next_block_update '(variant { ICP }, 25288400 : nat64)' --network ic
# CKUSDC - current block ~391,355 (as of July 2025)
dfx canister call <CANISTER_ID> set_token_next_block_update '(variant { CKUSDC }, 391300 : nat64)' --network ic
# CKUSDT - current block ~524,113 (as of July 2025)
dfx canister call <CANISTER_ID> set_token_next_block_update '(variant { CKUSDT }, 524100 : nat64)' --network ic
# CKBTC - current block ~150,000 (as of July 2025)
dfx canister call <CANISTER_ID> set_token_next_block_update '(variant { CKBTC }, 150000 : nat64)' --network ic

# 3. Set polling interval
# For normal production use (balanced)
dfx canister call <CANISTER_ID> set_interval '(60 : nat64)' --network ic
# For maximum cycle conservation
dfx canister call <CANISTER_ID> set_interval '(500 : nat64)' --network ic

# 4. Verify block positions were set correctly
dfx canister call <CANISTER_ID> get_token_next_block_query '(variant { CKUSDC })' --network ic
dfx canister call <CANISTER_ID> get_token_next_block_query '(variant { CKUSDT })' --network ic
dfx canister call <CANISTER_ID> get_token_next_block_query '(variant { CKBTC })' --network ic

Important Notes:

  • Large WASM files (1.9MB) need ~500B cycles for deployment
  • Each token ledger has independent block numbering
  • CKUSDC/CKUSDT/CKBTC blocks are much lower than ICP blocks
  • Start blocks ~50-100 before current to catch recent transactions
  • Polling intervals: 60s for normal use, 500s for maximum cycle conservation

Optional: Making Your Canister Immutable with Black Hole

Once your canister is deployed and configured, you can optionally set a black hole canister as a controller to make your canister immutable and enable public monitoring.

What is a Black Hole Canister?

A black hole canister is an immutable canister that, when set as a controller of your canister, provides the following benefits:

  • Immutability: Makes your canister non-upgradable, guaranteeing code cannot be changed
  • Public Status: Allows anyone to query canister_status to monitor health and cycles balance
  • Transparency: Provides programmatic access to canister information (cycles, module hash, etc.)
  • Trust: Users can verify your canister is truly immutable and unchanged

For more details, see the ic-blackhole repository (available as a submodule at packages/ic-blackhole/).

Black Hole Canister ID (Version 0.0.0):

e3mmv-5qaaa-aaaah-aadma-cai

How to Add Black Hole as Controller:

⚠️ WARNING: Be extremely cautious with these steps. Setting the black hole as the sole controller will permanently remove your ability to upgrade or modify the canister!

# Step 1: Add black hole as an additional controller (recommended first step)
# This keeps your control while enabling public monitoring
dfx canister update-settings \
    --network ic \
    --add-controller e3mmv-5qaaa-aaaah-aadma-cai \
    <CANISTER_ID>

# Step 2 (OPTIONAL): Set black hole as SOLE controller (permanent!)
# Only do this when you're absolutely certain the canister is production-ready
# This will REMOVE YOUR ABILITY to upgrade or modify the canister forever!
dfx canister update-settings \
    --network ic \
    --set-controller e3mmv-5qaaa-aaaah-aadma-cai \
    <CANISTER_ID>

Verifying Black Hole Setup:

# Check controllers
dfx canister info <CANISTER_ID> --network ic

# Query public canister status (anyone can do this now)
dfx canister call e3mmv-5qaaa-aaaah-aadma-cai canister_status \
    "(record {canister_id = principal \"<CANISTER_ID>\"})" \
    --network ic

Important Considerations:

  • Cycle Management: With public status, anyone can see your cycles balance and consumption rate
  • Security: Attackers may use cycle information to launch targeted attacks
  • Mitigation: Use automatic cycle top-up services (e.g., Tip Jar)
  • Testing: Always test thoroughly before setting black hole as sole controller
  • Irreversible: Setting black hole as sole controller is permanent and cannot be undone

Our Mainnet Canisters with Black Hole:

Both ICSI mainnet canisters have been configured with the black hole canister as an additional controller (not sole controller):

Current Production Canister (qvn3w-rqaaa-aaaam-qd4kq-cai):

  • Added black hole on November 7, 2025
  • Controllers: Black hole + custodian identity
  • Status: Active production, retains upgrade capability

Legacy Archive Canister (g5nrt-myaaa-aaaap-qhluq-cai):

  • Black hole added as additional controller (historical)
  • Controllers: Black hole + two custodian identities
  • Status: Archived, retains upgrade capability

You can verify the controllers of any canister with:

# Current production canister
dfx canister info qvn3w-rqaaa-aaaam-qd4kq-cai --network ic

# Legacy archive canister
dfx canister info g5nrt-myaaa-aaaap-qhluq-cai --network ic

Why Additional Controller Instead of Sole Controller?

We chose to add black hole as an additional controller rather than the sole controller because:

  1. Transparency: Enables public monitoring of canister status and cycles
  2. Flexibility: Retains ability to upgrade and fix bugs if needed
  3. Trust: Anyone can verify canister health and module hash
  4. Safety: Not permanently locked - can still respond to security issues

This approach balances transparency with operational flexibility for production canisters.

Canister Cycle Efficiency & Cost Analysis

Current Production Canister (qvn3w-rqaaa-aaaam-qd4kq-cai) - As of November 2025

Measured Performance Metrics

Based on actual production data from October 31 - November 7, 2025:

Polling Configuration:

  • Interval: 15 seconds (highly aggressive for real-time deposit detection)
  • Polls per hour: 240 polls/hour
  • Polls per day: 5,760 polls/day

Consumption Rates:

  • Per poll: ~12.95 million cycles/poll
  • Per hour: ~3.11 billion cycles/hour
  • Per day: ~74.61 billion cycles/day
  • Per week: ~522.3 billion cycles/week
  • Per month: ~2.24 trillion cycles/month (30 days)

Cost Analysis (at 1 trillion cycles ≈ 1 ICP):

  • Daily cost: ~0.0746 ICP/day
  • Weekly cost: ~0.5223 ICP/week
  • Monthly cost: ~2.24 ICP/month
  • Annual cost: ~27.2 ICP/year

Top-Up History:

  • Date: October 31, 2025 at 04:39:29 UTC
  • Amount: 1.0 ICP (1 trillion cycles)
  • Previous balance: 60 million cycles
  • Total after top-up: 1.006 trillion cycles
  • Consumed in 6.81 days: 507.82 billion cycles (50.78%)
  • Remaining as of Nov 7: 492.24 billion cycles
  • Projected depletion: ~6.6 days from November 7 (November 13, 2025)

Interval Configuration vs. Cycle Cost

The 15-second polling interval provides near-instant deposit detection but consumes cycles aggressively. Consider these alternatives based on your requirements:

Interval Polls/Day Cycles/Day* ICP/Month* Use Case
15s (current) 5,760 ~74.6B ~2.24 Real-time deposits (production)
30s 2,880 ~37.3B ~1.12 Fast detection (recommended)
60s 1,440 ~18.7B ~0.56 Normal operations (balanced)
300s (5 min) 288 ~3.7B ~0.11 Low-frequency monitoring
500s 172.8 ~2.2B ~0.07 Maximum cycle conservation

*Estimated based on current cycle cost per poll

Recommendation for Production:

# For real-time deposit detection (current setting)
dfx canister call qvn3w-rqaaa-aaaam-qd4kq-cai set_interval '(15 : nat64)' --network ic

# For balanced performance and cost (recommended for most use cases)
dfx canister call qvn3w-rqaaa-aaaam-qd4kq-cai set_interval '(60 : nat64)' --network ic

# For maximum cycle conservation (low-traffic applications)
dfx canister call qvn3w-rqaaa-aaaam-qd4kq-cai set_interval '(300 : nat64)' --network ic

Cycle Top-Up Recommendations

Based on current consumption rates:

Short-term (15s interval):

  • Top up ~2.5 ICP for 30 days of operation
  • Top up ~5.0 ICP for 60 days of operation

Optimized (60s interval):

  • Top up ~0.6 ICP for 30 days of operation
  • Top up ~1.2 ICP for 60 days of operation

Budget-friendly (300s interval):

  • Top up ~0.15 ICP for 30 days of operation
  • Top up ~0.30 ICP for 60 days of operation

Monitoring Cycle Balance

# Check current cycle balance via blackhole controller (public access)
dfx canister call e3mmv-5qaaa-aaaah-aadma-cai canister_status \
    "(record {canister_id = principal \"qvn3w-rqaaa-aaaam-qd4kq-cai\"})" \
    --network ic

# Add cycles when balance is low
dfx canister deposit-cycles 2000000000000 qvn3w-rqaaa-aaaam-qd4kq-cai --network ic

Cycle Warning Threshold: Set up monitoring alerts when cycles drop below 1 trillion to ensure uninterrupted service.

Notes:

  • Conversion rate: 1 trillion cycles ≈ 1 ICP (approximate, varies with ICP/XDR rate)
  • Actual consumption may vary based on transaction volume and network conditions
  • These metrics are from actual production usage, not estimates
  • Consider using automatic top-up services like Tip Jar for production canisters

Testing

Quick Testing Guide

The project includes a comprehensive test suite for multi-token deposits and webhook functionality:

# From root directory (recommended)
pnpm install  # Install all workspace dependencies

# Step 1: Generate test wallet
pnpm run lib:generate:wallet
# Fund the wallet with test tokens (see TESTING_GUIDE.md)

# Step 2: Start webhook server (keep running in separate terminal)
pnpm run lib:test:webhook

# Step 3: Run deposit tests (in new terminal)
pnpm run lib:test:icp    # Test ICP deposits (0.001 ICP)
pnpm run lib:test:usdc   # Test ckUSDC deposits (0.1 ckUSDC)
pnpm run lib:test:usdt   # Test ckUSDT deposits (0.1 ckUSDT)
pnpm run lib:test:btc    # Test ckBTC deposits (0.0001 ckBTC)

Key Testing Features:

  • Multi-token support: Test ICP, ckUSDC, ckUSDT, and ckBTC deposits
  • Automated webhook testing: ngrok integration for local webhook testing
  • ICRC-1 compliance: Proper handling of ICRC-1 textual addresses
  • Production-ready: Follows actual mainnet testing procedures
  • Comprehensive logging: All tests documented in docs/logs/

Important Testing Notes:

  1. Mainnet testing costs real money - Each test uses actual tokens
  2. Webhook server must stay running - Keep the webhook terminal open
  3. Transaction indexing takes time - Wait 30-45 seconds for detection
  4. Use test wallets only - Never use personal wallets for testing

See Testing Guide for complete documentation including:

  • Manual DFX commands for advanced testing
  • Troubleshooting common errors
  • Production deployment procedures
  • Detailed test logs and lessons learned

Test Scripts Architecture

Modern Scripts (packages/icsi-lib/test/scripts/):

  • Shell scripts for complete deposit workflows
  • TypeScript webhook server with ngrok integration
  • Automated test wallet generation

Legacy Scripts (packages/icsi-lib/test/scripts/legacy/):

  • Manual token operations (deprecated)
  • Use modern test suite instead

See Testing Guide for details.

Essential Canister Management Commands

Mainnet Canister Controllers Reference

Current Production Canister (qvn3w-rqaaa-aaaam-qd4kq-cai):

# Verify controllers
dfx canister info qvn3w-rqaaa-aaaam-qd4kq-cai --network ic
# Controllers:
#   - e3mmv-5qaaa-aaaah-aadma-cai (Black hole - version 0.0.0)
#   - h74q4-sfve2-7tqhf-ucha6-yameo-l73ks-r3knw-bolek-gwp3j-mjzss-sqe (Custodian identity)

# Query public canister status (anyone can do this)
dfx canister call e3mmv-5qaaa-aaaah-aadma-cai canister_status \
    "(record {canister_id = principal \"qvn3w-rqaaa-aaaam-qd4kq-cai\"})" \
    --network ic

Legacy Archive Canister (g5nrt-myaaa-aaaap-qhluq-cai):

# Verify controllers
dfx canister info g5nrt-myaaa-aaaap-qhluq-cai --network ic
# Controllers:
#   - e3mmv-5qaaa-aaaah-aadma-cai (Black hole - version 0.0.0)
#   - fgu3n-zl522-yxi3v-t4cie-ay33r-pc425-t6ua7-u6ygs-s7e63-d6aex-4ae
#   - ndmaj-wyg44-p2rfh-grnup-pgseg-4eliy-dqaui-ijnbl-fja3x-mhguz-wae

Note: Both canisters use black hole as an additional controller for transparency while retaining upgrade capability.

Quick Health Check

# Set canister ID for easier usage
CANISTER_ID="your-canister-id-here"

# Check canister status and cycles
dfx canister status $CANISTER_ID --network ic

# Check current settings
dfx canister call $CANISTER_ID get_interval --network ic
dfx canister call $CANISTER_ID get_registered_tokens --network ic
dfx canister call $CANISTER_ID get_next_block --network ic

Transaction Monitoring

# Get transaction count
dfx canister call $CANISTER_ID get_transactions_count --network ic

# List recent transactions
dfx canister call $CANISTER_ID list_transactions '(opt 10)' --network ic

# Check token balances
dfx canister call $CANISTER_ID get_balance '(variant { ICP })' --network ic
dfx canister call $CANISTER_ID get_balance '(variant { CKUSDC })' --network ic
dfx canister call $CANISTER_ID get_balance '(variant { CKUSDT })' --network ic
dfx canister call $CANISTER_ID get_balance '(variant { CKBTC })' --network ic

Subaccount Management

# Generate new subaccount
dfx canister call $CANISTER_ID add_subaccount '(opt variant { CKUSDC })' --network ic

# Generate specific format addresses
dfx canister call $CANISTER_ID generate_icp_deposit_address '(123456789 : nat32)' --network ic
dfx canister call $CANISTER_ID generate_icrc1_deposit_address '(variant { CKUSDC }, 5 : nat32)' --network ic
dfx canister call $CANISTER_ID generate_icrc1_deposit_address '(variant { CKBTC }, 10 : nat32)' --network ic

Configuration Management

# Set polling interval (seconds)
dfx canister call $CANISTER_ID set_interval '(500 : nat64)' --network ic  # Production
dfx canister call $CANISTER_ID set_interval '(30 : nat64)' --network ic   # Testing

# Set webhook URL
dfx canister call $CANISTER_ID set_webhook_url '("https://your-api.com/webhook")' --network ic

# Update token block positions
dfx canister call $CANISTER_ID set_token_next_block_update '(variant { CKUSDC }, 391300 : nat64)' --network ic
dfx canister call $CANISTER_ID set_token_next_block_update '(variant { CKBTC }, 150000 : nat64)' --network ic

Troubleshooting Commands

# Add cycles if running low
dfx canister deposit-cycles 200000000000 $CANISTER_ID --network ic

# Check webhook configuration
dfx canister call $CANISTER_ID get_webhook_url --network ic

# Verify custodian access
dfx canister call $CANISTER_ID get_custodian --network ic

For comprehensive debugging procedures, see:

Conclusion

ICSI represents a significant advancement in the management of ICP sub-accounts, offering simplicity, security, and scalability. By leveraging advanced indexing and transaction handling techniques, ICSI provides a reliable and user-friendly solution for managing ICP assets.

Research Documents

The following are some of the research documents during specification design:

Context7 MCP

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

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

License

MIT © Jagad

About

ICSI (ICP Sub-Account Indexer) is a robust solution designed to streamline the management and indexing of sub-accounts within the ICP (Internet Computer Protocol) ecosystem.

Topics

Resources

License

Stars

Watchers

Forks

Contributors 5