================ CODE SNIPPETS ================ TITLE: Install ICSI Library using npm, pnpm, or yarn DESCRIPTION: Install the ICSI library using your preferred package manager. This is the first step before importing and using the library's functions. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_0 LANGUAGE: bash CODE: ``` npm install @jagad/icsi # or pnpm install @jagad/icsi # or yarn add @jagad/icsi ``` -------------------------------- TITLE: Install Dependencies and Start Local Replica DESCRIPTION: Installs all workspace dependencies using pnpm and starts a local Internet Computer replica with old metering enabled. This is a foundational step for local development and testing. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/CLAUDE.md#_snippet_0 LANGUAGE: bash CODE: ``` pnpm install pnpm run start:local:env ``` -------------------------------- TITLE: TypeScript: ICP Subaccount Indexer Quick Start Example DESCRIPTION: Demonstrates the full lifecycle of interacting with the ICP Subaccount Indexer. It sets up an agent, creates subaccounts for multiple tokens (ICP, ckUSDC, ckUSDT, ckBTC), retrieves deposit addresses and balances, and fetches recent transaction data. Includes optional webhook configuration and basic error handling. Requires '@dfinity/agent' and '@jagad/icsi' packages. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_10 LANGUAGE: typescript CODE: ``` import { HttpAgent, } from '@dfinity/agent'; import { createHostAgentAndIdentityFromSeed, addSubaccountForToken, getUserVaultTransactions, getDepositAddresses, getBalances, setWebhookUrl, Tokens, } from '@jagad/icsi'; async function quickStart() { try { // 1. Setup const { agent } = await createHostAgentAndIdentityFromSeed( 'your twelve word seed phrase here', 'https://ic0.app' ); const canisterId = 'qvn3w-rqaaa-aaaam-qd4kq-cai'; // 2. Set webhook (optional) const webhookResult = await setWebhookUrl( agent, canisterId, 'https://your-api.com/webhook' ); console.log('Webhook set:', 'Ok' in webhookResult); // 3. Create subaccounts for all tokens console.log('Creating subaccounts...'); const icpAddr = await addSubaccountForToken(agent, canisterId, Tokens.ICP); const usdcAddr = await addSubaccountForToken( agent, canisterId, Tokens.CKUSDC ); const usdtAddr = await addSubaccountForToken( agent, canisterId, Tokens.CKUSDT ); const btcAddr = await addSubaccountForToken( agent, canisterId, Tokens.CKBTC ); if ('Ok' in icpAddr) console.log('ICP address:', icpAddr.Ok); if ('Ok' in usdcAddr) console.log('ckUSDC address:', usdcAddr.Ok); if ('Ok' in usdtAddr) console.log('ckUSDT address:', usdtAddr.Ok); if ('Ok' in btcAddr) console.log('ckBTC address:', btcAddr.Ok); // 4. Get all addresses console.log('\nAll deposit addresses:'); const addresses = await getDepositAddresses(agent, canisterId); addresses.forEach((addr) => { const tokenType = Object.keys(addr.tokenType)[0]; console.log(`${tokenType}: ${addr.depositAddress}`); }); // 5. Check balances console.log('\nToken balances:'); const balances = await getBalances(agent, canisterId); balances.forEach((balance) => { const tokenType = Object.keys(balance.tokenType)[0]; console.log(`${tokenType}: ${balance.balance}`); }); // 6. Get recent transactions console.log('\nRecent transactions:'); const txResult = await getUserVaultTransactions( agent, canisterId, BigInt(5) ); if ('Ok' in txResult) { txResult.Ok.forEach((tx) => { const tokenType = Object.keys(tx.token_type)[0]; const status = Object.keys(tx.sweep_status)[0]; console.log(`${tokenType}: ${tx.amount} (${status})`); }); } console.log('\nSetup complete! Send tokens to the addresses above.'); } catch (error) { console.error('Error in quickStart:', error); } } // Run the example quickStart(); ``` -------------------------------- TITLE: Local Development Setup and Deployment with DFX and pnpm DESCRIPTION: This set of commands installs project dependencies using pnpm, starts a local replica with specific configurations, and deploys the project locally. It includes steps for generating a test wallet. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/README.md#_snippet_10 LANGUAGE: bash CODE: ``` # 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 ``` -------------------------------- TITLE: Create Agent and Identity using Seed Phrase or Private Key DESCRIPTION: Set up an agent and identity for interacting with the Internet Computer. This example shows how to create them using either a seed phrase or a PEM-formatted private key, connecting to the 'ic0.app' host. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_2 LANGUAGE: typescript CODE: ``` // Using seed phrase (recommended) const { agent, identity } = await createHostAgentAndIdentityFromSeed( 'your twelve word seed phrase here', 'https://ic0.app' ); // Or using private key const privateKey = `-----BEGIN EC PRIVATE KEY----- Your PEM private key here -----END EC PRIVATE KEY-----`; const { agent, identity } = await createHostAgentAndIdentityFromPrivateKey( privateKey, 'https://ic0.app' ); ``` -------------------------------- TITLE: Quick Start: Initialize Agent and Interact with ICSI-Lib DESCRIPTION: A quick start guide demonstrating how to initialize an HttpAgent and use key functions from the ICSI-Lib to manage subaccounts, retrieve deposit addresses, and fetch transactions. This example showcases basic usage for ckUSDC tokens. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/README.md#_snippet_0 LANGUAGE: typescript CODE: ``` import { HttpAgent, 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); ``` -------------------------------- TITLE: Initial Project Setup (Bash) DESCRIPTION: Clones the repository and installs project dependencies using pnpm. This is the first step for setting up the development environment. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/WORKSPACE.md#_snippet_8 LANGUAGE: bash CODE: ``` git clone cd icp-subaccount-indexer pnpm install ``` -------------------------------- TITLE: Quick Testing Workflow for ICP Subaccount Indexer DESCRIPTION: This comprehensive workflow guides users through setting up and testing the ICP Subaccount Indexer. It covers generating test wallets, funding them, deploying the mainnet canister, configuring the environment, starting a webhook server, testing various token deposits, and finally restoring production settings. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/TESTING_GUIDE.md#_snippet_49 LANGUAGE: bash CODE: ``` # 1. Generate test wallet pnpm run lib:generate:wallet # 2. Fund wallet with test tokens # 3. Deploy canister ./scripts/deploy-mainnet.sh deploy # 4. Configure environment echo 'USER_VAULT_CANISTER_ID="your-canister-id"' >> packages/icsi-lib/.env.test # 5. Start webhook server pnpm run lib:test:webhook # 6. Test deposits pnpm run lib:test:icp pnpm run lib:test:usdc pnpm run lib:test:usdt # 7. Restore production settings dfx canister call CANISTER_ID set_interval '(500 : nat64)' --network ic ``` -------------------------------- TITLE: Import ICSI Library Functions for TypeScript DESCRIPTION: Import necessary functions and types from the '@jagad/icsi' library. These imports are required for setting up the agent, identity, and interacting with ICSI functionalities. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_1 LANGUAGE: typescript CODE: ``` import { HttpAgent } from '@dfinity/agent'; import { createHostAgentAndIdentityFromSeed, addSubaccountForToken, getUserVaultTransactions, getDepositAddresses, Tokens, } from '@jagad/icsi'; ``` -------------------------------- TITLE: Environment Setup Commands DESCRIPTION: This section provides commands for setting up the development environment for both testnet and devnet. It includes setting the `DFX_WARNING` environment variable and using `dfx identity use` to switch identities. It also shows how to retrieve the canister ID from JSON configuration files using `cat` and `jq`. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/CANISTER_DEBUGGING_GUIDE.md#_snippet_15 LANGUAGE: bash CODE: ``` # Testnet setup export DFX_WARNING=-mainnet_plaintext_identity dfx identity use testnet_custodian CANISTER_ID=$(cat test_canister_ids.json | jq -r '.icp_subaccount_indexer.ic') # Devnet setup export DFX_WARNING=-mainnet_plaintext_identity dfx identity use default CANISTER_ID=$(cat canister_ids.json | jq -r '.icp_subaccount_indexer.ic') ``` -------------------------------- TITLE: Set ICSI Canister ID DESCRIPTION: Define the canister ID for the ICSI service. This example provides the mainnet canister ID. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_3 LANGUAGE: typescript CODE: ``` const canisterId = 'qvn3w-rqaaa-aaaam-qd4kq-cai'; // Mainnet canister ``` -------------------------------- TITLE: Troubleshoot 'Module hash is already installed' Error DESCRIPTION: Provides steps to resolve the error where the module hash is already installed, which typically requires a force upgrade with explicit arguments and verification of the WASM file's recency. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/CANISTER_DEBUGGING_GUIDE.md#_snippet_32 LANGUAGE: bash CODE: ``` # Force upgrade with explicit arguments dfx canister install $CANISTER_ID --network ic --mode upgrade \ --argument '(variant { Mainnet }, 15 : nat64, 10 : nat32, "ryjl3-tyaaa-aaaaa-aaaba-cai", "YOUR-PRINCIPAL")' # Verify WASM file is recent ls -la target/wasm32-unknown-unknown/release/icp_subaccount_indexer.wasm ``` -------------------------------- TITLE: Payment Processing Workflow Example DESCRIPTION: An example demonstrating a typical payment processing workflow using the '@jagad/icsi' library. It includes setting up webhooks, creating deposit addresses, monitoring payments, and sweeping collected funds. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/README.md#_snippet_24 LANGUAGE: typescript CODE: ``` 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); }; ``` -------------------------------- TITLE: Devnet Setup with DFX CLI DESCRIPTION: Configures the DFX CLI for local development (devnet), sets the default identity, and retrieves the devnet canister ID using jq. This setup is for individual developer control. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/CANISTER_DEBUGGING_GUIDE.md#_snippet_1 LANGUAGE: bash CODE: ``` # Set environment variables export DFX_WARNING=-mainnet_plaintext_identity # Use your default identity (or preferred development identity) dfx identity use default # Get canister ID CANISTER_ID=$(cat canister_ids.json | jq -r '.icp_subaccount_indexer.ic') echo "Devnet Canister ID: $CANISTER_ID" # Verify identity and principal dfx identity whoami dfx identity get-principal ``` -------------------------------- TITLE: Work with ICSI Token Types DESCRIPTION: Utilize the `Tokens` enum to represent different token types (ICP, ckUSDC, ckUSDT, CKBTC) when interacting with ICSI functions. This example also shows how to check token types within transaction data. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_8 LANGUAGE: typescript CODE: ``` import { Tokens } from '@jagad/icsi'; // Available tokens const icpToken = Tokens.ICP; // { ICP: null } const usdcToken = Tokens.CKUSDC; // { CKUSDC: null } const usdtToken = Tokens.CKUSDT; // { CKUSDT: null } const btcToken = Tokens.CKBTC; // { CKBTC: null } // Check token type in transactions transactions.forEach((tx) => { if (tx.tokenType.ICP) { console.log('ICP transaction'); } else if (tx.tokenType.CKUSDC) { console.log('ckUSDC transaction'); } else if (tx.tokenType.CKUSDT) { console.log('ckUSDT transaction'); } else if (tx.tokenType.CKBTC) { console.log('ckBTC transaction'); } }); ``` -------------------------------- TITLE: Install ICP Subaccount Indexer Canister (Bash) DESCRIPTION: Command to install the ICP subaccount indexer canister on the Mainnet. It specifies environment variables, the canister name, network, installation arguments, and mode. The command failed due to insufficient cycles. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/logs/TESTING_ATTEMPT.md#_snippet_5 LANGUAGE: bash CODE: ``` export DFX_WARNING=-mainnet_plaintext_identity && dfx canister install icp_subaccount_indexer --network ic --argument '(variant { Mainnet }, 5: nat64, 0: nat32, "ryjl3-tyaaa-aaaaa-aaaba-cai", "$(dfx identity get-principal)")' --mode install ``` -------------------------------- TITLE: Testnet Setup with DFX CLI DESCRIPTION: Configures the DFX CLI for testnet operations, sets the correct identity, and retrieves the testnet canister ID using jq. It emphasizes using the correct identity for operations versus upgrades. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/CANISTER_DEBUGGING_GUIDE.md#_snippet_0 LANGUAGE: bash CODE: ``` # Set environment variables export DFX_WARNING=-mainnet_plaintext_identity # Switch to testnet custodian identity for operations dfx identity use testnet_custodian # Get canister ID CANISTER_ID=$(cat test_canister_ids.json | jq -r '.icp_subaccount_indexer.ic') echo "Testnet Canister ID: $CANISTER_ID" # Verify identity and principal dfx identity whoami dfx identity get-principal ``` -------------------------------- TITLE: Pre-Upgrade Canister Preparation DESCRIPTION: Steps to prepare for a canister upgrade, including listing and verifying identities, checking canister controllers, and ensuring adequate cycle balance. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/CANISTER_DEBUGGING_GUIDE.md#_snippet_28 LANGUAGE: bash CODE: ``` # Step 1: Identity Verification dfx identity list for identity in $(dfx identity list | grep -v "^anonymous$"); do echo "$identity: $(dfx identity use $identity && dfx identity get-principal)" done # Step 2: Controller Verification dfx canister info $CANISTER_ID --network ic dfx identity get-principal # Ensure match with controllers # Step 3: Cycle Management dfx canister status $CANISTER_ID --network ic dfx canister deposit-cycles 200000000000 $CANISTER_ID --network ic # 200B minimum ``` -------------------------------- TITLE: NPM Version Update Examples DESCRIPTION: Illustrates bash commands for updating package versions according to semantic versioning principles. It shows examples for patch, minor, and major version increments. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/README.md#_snippet_34 LANGUAGE: bash CODE: ``` # 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 ``` -------------------------------- TITLE: Local Package Testing with NPM DESCRIPTION: Outlines the bash commands for building, packing, and locally installing an NPM package. This is useful for testing the package before publishing. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/README.md#_snippet_30 LANGUAGE: bash CODE: ``` # 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 ``` -------------------------------- TITLE: Create Subaccount for ICP or ckTokens DESCRIPTION: Create a new subaccount for depositing ICP or ckTokens (like ckUSDC). The function returns the deposit address on success or an error object. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_4 LANGUAGE: typescript CODE: ``` // Create an ICP subaccount const icpResult = await addSubaccountForToken(agent, canisterId, Tokens.ICP); if ('Ok' in icpResult) { console.log('ICP deposit address:', icpResult.Ok); } else { console.error('Error creating ICP subaccount:', icpResult.Err); } // Create a ckUSDC subaccount const usdcResult = await addSubaccountForToken( agent, canisterId, Tokens.CKUSDC ); if ('Ok' in usdcResult) { console.log('ckUSDC deposit address:', usdcResult.Ok); } else { console.error('Error creating ckUSDC subaccount:', usdcResult.Err); } ``` -------------------------------- TITLE: Environment Setup: Wallet and Canister ID Management DESCRIPTION: Commands and configurations for setting up the test environment, including generating new test wallets and managing canister IDs by saving them to .env.test. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/CLAUDE.md#_snippet_15 LANGUAGE: bash CODE: ``` # Generate fresh: pnpm run lib:generate:wallet # Add to .env.test: USER_VAULT_CANISTER_ID="your-id" ``` -------------------------------- TITLE: GitHub Actions Workflow for NPM Publishing DESCRIPTION: A YAML configuration file for a GitHub Actions workflow that automates the publishing of a package to NPM. It handles Node.js setup, dependency installation, building, and publishing using NPM_TOKEN for authentication. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/README.md#_snippet_33 LANGUAGE: yaml CODE: ``` 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 }} ``` -------------------------------- TITLE: Create and Deploy ICSI Canister DESCRIPTION: Guides through the process of creating a new canister for the ICSI and deploying it to the IC network with a specified amount of cycles. It strongly advises against using command substitution for principal arguments during deployment, recommending hardcoded principals instead. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/TESTING_GUIDE.md#_snippet_2 LANGUAGE: bash CODE: ``` # Create canister with sufficient cycles dfx canister create icp_subaccount_indexer --network ic --with-cycles 500000000000 # Get your principal and use it as hardcoded string (DO NOT use command substitution) echo "Use this principal in deployment: $(dfx identity get-principal)" ``` -------------------------------- TITLE: Handle 'Ok' and 'Err' Results in ICSI Functions DESCRIPTION: Implement robust error handling by checking the 'Ok' and 'Err' properties of function results. This pattern ensures proper handling of both successful operations and potential errors. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_7 LANGUAGE: typescript CODE: ``` const result = await someICSIFunction(); if ('Ok' in result) { // Success - use result.Ok console.log('Success:', result.Ok); } else { // Error - handle result.Err console.error('Error:', result.Err); } ``` -------------------------------- TITLE: Get All Deposit Addresses DESCRIPTION: Retrieve all associated deposit addresses for different token types. The function returns an array of objects, each containing the token type and its corresponding deposit address. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_5 LANGUAGE: typescript CODE: ``` const addresses = await getDepositAddresses(agent, canisterId); console.log('All deposit addresses:'); addresses.forEach((addr) => { const tokenName = Object.keys(addr.tokenType)[0]; console.log(`${tokenName}: ${addr.depositAddress}`); }); ``` -------------------------------- TITLE: Get All Token Balances with @jagad/icsi DESCRIPTION: Fetches all token balances for a given canister ID and iterates through them to log token names and their respective balances. This function requires an initialized agent and canister ID as input. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/EXAMPLES.md#_snippet_10 LANGUAGE: typescript CODE: ``` import { getBalances } from '@jagad/icsi'; const balances = await getBalances(agent, canisterId); balances.forEach((balance) => { const tokenName = Object.keys(balance.tokenType)[0]; console.log(`${tokenName}: ${balance.balance}`); }); ``` -------------------------------- TITLE: Setting up ICSI Local Test Environment (Scripts) DESCRIPTION: These commands are used to manage the local test environment for the ICSI library. They include starting the local DFX environment, deploying test tokens, and running the full test suite. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/test/README.md#_snippet_1 LANGUAGE: bash CODE: ``` # Start local DFX environment pnpm run start:local:env # Deploy test tokens locally ./packages/icsi-lib/scripts/deploy-test-tokens.sh # Run full test suite pnpm run test ``` -------------------------------- TITLE: Check for User Vault Transactions DESCRIPTION: Fetch user vault transactions, specifying the number of recent transactions to retrieve. The result indicates success with transaction details or an error. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_6 LANGUAGE: typescript CODE: ``` const transactionsResult = await getUserVaultTransactions( agent, canisterId, BigInt(10) // Get last 10 transactions ); if ('Ok' in transactionsResult) { const transactions = transactionsResult.Ok; console.log(`Found ${transactions.length} transactions`); transactions.forEach((tx) => { const tokenType = Object.keys(tx.tokenType)[0]; console.log(`${tokenType} transaction: ${tx.amount} (${tx.tx_hash})`); }); } else { console.error('Error fetching transactions:', transactionsResult.Err); } ``` -------------------------------- TITLE: Local Development Commands (Bash) DESCRIPTION: Starts a local replica, deploys the project, generates wallets, and runs ICP tests. These commands are essential for local development and testing. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/WORKSPACE.md#_snippet_9 LANGUAGE: bash CODE: ``` # Terminal 1: Start local replica pnpm run start:local:env # Terminal 2: Deploy and test pnpm run deploy:local pnpm run lib:generate:wallet pnpm run lib:test:icp ``` -------------------------------- TITLE: Funding and Deploying ICP Subaccount Indexer Canister DESCRIPTION: Commands to ensure adequate funding, create the canister with maximum cycles, and deploy it. These steps are crucial for setting up the indexer service on the Internet Computer. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/CANISTER_DEBUGGING_GUIDE.md#_snippet_3 LANGUAGE: bash CODE: ``` # Ensure adequate funding (minimum 0.5 ICP) dfx ledger balance --network ic dfx cycles convert --amount=0.5 --network ic # Create canister with maximum cycles dfx canister create icp_subaccount_indexer --network ic --with-cycles 800000000000 # Deploy immediately after creation dfx deploy icp_subaccount_indexer --network ic --argument '(...)' ``` -------------------------------- TITLE: Debug ICRC-3 Connectivity: Test Direct Ledger Access DESCRIPTION: This step involves directly querying specific ICRC token ledgers to isolate connectivity issues. It provides example commands to test access to the ckUSDC and ckBTC ledgers by calling their respective `icrc3_get_blocks` functions with specified start block numbers and lengths. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/TESTING_GUIDE.md#_snippet_37 LANGUAGE: bash CODE: ``` # Test ckUSDC ledger directly df_canister call xevnm-gaaaa-aaaar-qafnq-cai icrc3_get_blocks '(vec {record { start = 448800 : nat; length = 5 : nat }})' --network ic # Test ckBTC ledger directly df_canister call mxzaz-hqaaa-aaaar-qaada-cai icrc3_get_blocks '(vec {record { start = 3111616 : nat; length = 5 : nat }})' --network ic ``` -------------------------------- TITLE: Execute Canister Upgrade (Testnet) DESCRIPTION: Performs a canister upgrade on the testnet using the STAGING_DEPLOYER identity. This involves building the code, specifying the WASM file, and providing necessary installation arguments. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/CANISTER_DEBUGGING_GUIDE.md#_snippet_29 LANGUAGE: bash CODE: ``` # Use correct controller identity dfx identity use STAGING_DEPLOYER # Build latest code pnpm run build:canister # Execute upgrade with proper arguments dfx canister install $CANISTER_ID --network ic \ --wasm target/wasm32-unknown-unknown/release/icp_subaccount_indexer.wasm \ --argument '(variant { Mainnet }, 500: nat64, 25002500: nat32, "ryjl3-tyaaa-aaaaa-aaaba-cai", "controller-principal")' \ --mode upgrade # Switch back for operations dfx identity use testnet_custodian ``` -------------------------------- TITLE: Install All Dependencies with pnpm DESCRIPTION: Installs all project dependencies across the entire workspace, including the root project, the icsi-lib package, and any legacy scripts. This command ensures a consistent environment for development and testing. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/WORKSPACE.md#_snippet_0 LANGUAGE: bash CODE: ``` pnpm install ``` -------------------------------- TITLE: Troubleshooting Installation Issues (Bash) DESCRIPTION: Provides commands to perform a clean installation by removing existing dependencies and lock files, then reinstalling them. It also includes a command to prune the pnpm store, freeing up disk space. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/WORKSPACE.md#_snippet_11 LANGUAGE: bash CODE: ``` # Clean install rm -rf node_modules packages/*/node_modules pnpm-lock.yaml pnpm install # Clear pnpm cache pnpm store prune ``` -------------------------------- TITLE: Set up ICSI Agent and Identity with Seed Phrase DESCRIPTION: Initializes an HttpAgent and an identity using a seed phrase. This is a prerequisite for most operations and requires the '@dfinity/agent' and '@jagad/icsi' libraries. It takes a seed phrase and the canister host URL as input. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/EXAMPLES.md#_snippet_0 LANGUAGE: typescript CODE: ``` import { HttpAgent } from '@dfinity/agent'; import { createHostAgentAndIdentityFromSeed } from '@jagad/icsi'; // Create agent with seed phrase const { agent, identity } = await createHostAgentAndIdentityFromSeed( 'your twelve word seed phrase here', 'https://ic0.app' ); const canisterId = 'qvn3w-rqaaa-aaaam-qd4kq-cai'; ``` -------------------------------- TITLE: Install/Upgrade Testnet Canister DESCRIPTION: Installs or upgrades the canister on the testnet using the correct controller identity and the latest Wasm module. This is the critical step for deploying the multi-token capable indexer to the live testnet environment. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/logs/TESTING_ATTEMPT_11.md#_snippet_7 LANGUAGE: bash CODE: ``` dfx identity use STAGING_DEPLOYER export DFX_WARNING=-mainnet_plaintext_identity dfx canister install uiz2m-baaaa-aaaal-qjbxq-cai --network ic \ --wasm target/wasm32-unknown-unknown/release/icp_subaccount_indexer.wasm \ --argument '(variant { Mainnet }, 15: nat64, 25002500: nat32, "ryjl3-tyaaa-aaaaa-aaaba-cai", "pztcx-5wpjw-ko6rv-3cjff-466eb-4ywbn-a5jww-rs6yy-ypk4a-ceqfb-nqe")' \ --mode upgrade ``` -------------------------------- TITLE: Local Development Commands for ICSI Canister DESCRIPTION: Provides commands for local development of the ICSI canister. This includes starting a local replica, deploying the canister, building the project, and generating TypeScript declarations. Dependencies should be installed before running these commands. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/WORKSPACE.md#_snippet_1 LANGUAGE: bash CODE: ``` # Start local IC replica pnpm run start:local:env # Deploy to local network pnpm run deploy:local # Build everything pnpm run build # Build just the canister pnpm run build:canister # Build just the TypeScript library pnpm run build:lib # Generate TypeScript declarations pnpm run generate ``` -------------------------------- TITLE: Install/Upgrade Devnet Canister DESCRIPTION: Installs or upgrades a canister on the IC network with a new Wasm module and initialization arguments. This command is used to deploy the latest version of the subaccount indexer to the devnet for testing. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/logs/TESTING_ATTEMPT_11.md#_snippet_5 LANGUAGE: bash CODE: ``` dfx canister install y3hne-ryaaa-aaaag-aucea-cai --network ic \ --wasm target/wasm32-unknown-unknown/release/icp_subaccount_indexer.wasm \ --argument '(variant { Mainnet }, 15: nat64, 25002500: nat32, "ryjl3-tyaaa-aaaaa-aaaba-cai", "gf3g2-eaeha-ii22q-ij5tb-bep3w-xxwgx-h4roh-6c2sm-cx2sw-tppv4-qqe")' \ --mode upgrade ``` -------------------------------- TITLE: Upgrade ICP Subaccount Indexer Canister DESCRIPTION: Executes the upgrade of the ICP Subaccount Indexer canister. This involves selecting the correct controller identity, building the latest code, and then calling the dfx canister install command with the appropriate arguments and mode. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/TESTING_GUIDE.md#_snippet_15 LANGUAGE: bash CODE: ``` # Use correct controller identity dfx identity use STAGING_DEPLOYER # Build latest code pnpm run build:canister # Execute upgrade with proper arguments dfx canister install --network ic \ --wasm target/wasm32-unknown-unknown/release/icp_subaccount_indexer.wasm \ --argument '(variant { Mainnet }, 500: nat64, 25002500: nat32, "ryjl3-tyaaa-aaaaa-aaaba-cai", "controller-principal")' \ --mode upgrade ``` -------------------------------- TITLE: Rust: Example Usage of AccountIdentifier::new DESCRIPTION: Provides a practical example of how to use the `AccountIdentifier::new` function in Rust. It shows the creation of a Principal and then deriving an AccountIdentifier with a default subaccount. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/SUBACCOUNT_DERIVATION_MECHANISM.md#_snippet_5 LANGUAGE: rust CODE: ``` let principal = Principal::from_text("some-principal-id").unwrap(); let account_id = AccountIdentifier::new(principal, None); ``` -------------------------------- TITLE: Build ICSI Library with pnpm DESCRIPTION: Commands to build the ICSI library using pnpm. This involves navigating to the library's directory, installing dependencies, and running the build script. It's a prerequisite for running the test scripts. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/test/integration/README.md#_snippet_0 LANGUAGE: bash CODE: ``` cd packages/icsi-lib pnpm install pnpm run build ``` -------------------------------- TITLE: Running ICSI Library Tests Locally (pnpm) DESCRIPTION: This snippet outlines the commands to install dependencies and run various test suites for the ICSI library using pnpm. It includes commands for running all tests, unit tests, integration tests, tests with coverage, and tests in watch mode. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/test/README.md#_snippet_0 LANGUAGE: bash CODE: ``` # Install dependencies pnpm install # Run all tests (includes local setup) pnpm run test # Run only unit tests (fast) pnpm run test:unit # Run only integration tests pnpm run test:integration # Run tests with coverage pnpm run test:coverage # Watch mode for development pnpm run test:watch ``` -------------------------------- TITLE: Get Registered Tokens from Testnet Canister DESCRIPTION: Retrieves a list of all tokens that have been registered with the ICP subaccount indexer canister on the testnet. This is used to verify that multi-token support is functioning correctly after the upgrade. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/logs/TESTING_ATTEMPT_11.md#_snippet_8 LANGUAGE: bash CODE: ``` dfx identity use testnet_custodian dfx canister call uiz2m-baaaa-aaaal-qjbxq-cai get_registered_tokens --network ic ``` -------------------------------- TITLE: Transaction Monitoring Commands DESCRIPTION: This section outlines commands for monitoring transaction activity within the ICP subaccount indexer. It includes commands to get the total count of transactions, list recent transactions with an optional limit, retrieve a specific transaction by its hash, get the token type of a transaction, and check the balance for various tokens (ICP, CKUSDC, CKUSDT, CKBTC) using `dfx canister call`. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/CANISTER_DEBUGGING_GUIDE.md#_snippet_18 LANGUAGE: bash CODE: ``` # Check transaction activity dfx canister call $CANISTER_ID get_transactions_count --network ic dfx canister call $CANISTER_ID list_transactions '(opt 10)' --network ic dfx canister call $CANISTER_ID get_transaction '("transaction-hash-here")' --network ic dfx canister call $CANISTER_ID get_transaction_token_type '("tx-hash")' --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 ``` -------------------------------- TITLE: Configure DFX Environment and Identity DESCRIPTION: Sets up the DFX CLI environment for testing, including disabling mainnet plaintext identity warnings and verifying the current identity configuration. It also captures the deployer's principal, which is crucial for deployment arguments. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/TESTING_GUIDE.md#_snippet_0 LANGUAGE: bash CODE: ``` # Set up environment for testing export DFX_WARNING=-mainnet_plaintext_identity # Verify identity configuration dfx identity list dfx identity whoami dfx identity get-principal # Record your principal for deployment arguments DEPLOYER_PRINCIPAL=$(dfx identity get-principal) echo "Deployer Principal: $DEPLOYER_PRINCIPAL" # Check cycles balance (need substantial amount for large WASM) dfx cycles balance --network ic # Minimum required: 1.0 TC (trillion cycles) ``` -------------------------------- TITLE: Prepare Deployment Environment with DFX DESCRIPTION: This snippet prepares the local environment for deploying the ICP subaccount indexer. It involves setting DFX warnings, selecting the correct controller identity, and verifying ICP funding in the deployer wallet. Finally, it demonstrates converting ICP to cycles, which are necessary for canister operations. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/TESTING_GUIDE.md#_snippet_31 LANGUAGE: bash CODE: ``` # Set environment export DFX_WARNING=-mainnet_plaintext_identity df_identity use # Verify funding df_ledger balance --network ic # Minimum: 0.5 ICP # Convert to cycles df_cycles convert --amount=0.5 --network ic ``` -------------------------------- TITLE: Webhook POST Request Example DESCRIPTION: Illustrates the format of a POST request sent to a configured webhook URL. The request includes the transaction hash as a query parameter, enabling real-time transaction updates. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/README.md#_snippet_3 LANGUAGE: http CODE: ``` POST https://your-webhook.com/endpoint?tx_hash= ``` -------------------------------- TITLE: Start Webhook Script DESCRIPTION: Initiates the webhook script for testing purposes. This command assumes the project utilizes pnpm as its package manager and has a 'lib:test:webhook' script defined. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/logs/TESTING_ATTEMPT_10.md#_snippet_17 LANGUAGE: bash CODE: ``` pnpm run lib:test:webhook ``` -------------------------------- TITLE: Complete Payment System Implementation DESCRIPTION: A comprehensive payment processing system that initializes webhook URLs, creates customer wallets with subaccounts for various tokens, and processes incoming payments by fetching pending transactions and sweeping them. It uses a class-based structure for organization. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/EXAMPLES.md#_snippet_13 LANGUAGE: typescript CODE: ``` import { addSubaccountForToken, setWebhookUrl, getUserVaultTransactions, sweepByTokenType, Tokens, } from '@jagad/icsi'; class PaymentProcessor { constructor( private agent: HttpAgent, private canisterId: string ) {} async initialize(webhookUrl: string) { // Set webhook for notifications await setWebhookUrl(this.agent, this.canisterId, webhookUrl); console.log('Payment processor initialized'); } async createCustomerWallet(customerId: string) { const addresses = { customerId, icp: await addSubaccountForToken(this.agent, this.canisterId, Tokens.ICP), usdc: await addSubaccountForToken( this.agent, this.canisterId, Tokens.CKUSDC ), usdt: await addSubaccountForToken( this.agent, this.canisterId, Tokens.CKUSDT ), btc: await addSubaccountForToken( this.agent, this.canisterId, Tokens.CKBTC ), }; console.log(`Created wallet for customer ${customerId}:`, addresses); return addresses; } async processPayments() { // Get recent transactions const result = await getUserVaultTransactions( this.agent, this.canisterId, BigInt(100) ); if ('Ok' in result) { const pendingTransactions = result.Ok.filter( (tx) => tx.sweep_status.Pending !== undefined ); console.log(`Found ${pendingTransactions.length} pending payments`); // Process each transaction for (const tx of pendingTransactions) { await this.processTransaction(tx); } } } private async processTransaction(tx: any) { console.log(`Processing transaction: ${tx.tx_hash}`); // Your business logic here // e.g., update database, send notifications, etc. // Mark as processed by sweeping const tokenType = tx.token_type.ICP ? Tokens.ICP : tx.token_type.CKUSDC ? Tokens.CKUSDC : tx.token_type.CKUSDT ? Tokens.CKUSDT : Tokens.CKBTC; await sweepByTokenType(this.agent, this.canisterId, tokenType); } } // Usage const processor = new PaymentProcessor(agent, canisterId); await processor.initialize('https://your-api.com/webhook'); // Create customer wallets const wallet1 = await processor.createCustomerWallet('customer-123'); const wallet2 = await processor.createCustomerWallet('customer-456'); // Process incoming payments setInterval(async () => { await processor.processPayments(); }, 30000); // Check every 30 seconds ``` -------------------------------- TITLE: Use BigInt for Amounts and Intervals in ICSI DESCRIPTION: Handle numerical values like transaction amounts and polling intervals using JavaScript's `BigInt` type. This is crucial for precise financial calculations and time intervals within the ICSI library. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/GETTING_STARTED.md#_snippet_9 LANGUAGE: typescript CODE: ``` import { setUserVaultInterval } from '@jagad/icsi'; // Set polling interval to 30 seconds await setUserVaultInterval(agent, canisterId, BigInt(30)); // Get specific number of transactions await getUserVaultTransactions(agent, canisterId, BigInt(50)); ``` -------------------------------- TITLE: Handle Fee Amount Confusion for Different Token Types DESCRIPTION: Examples demonstrating how to correctly set fees for ICRC-1 token transfers, specifically highlighting the differences between ckUSDC/ckUSDT and ckBTC fee structures. This ensures that transactions are not rejected due to incorrect fee amounts or units. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/TESTING_GUIDE.md#_snippet_28 LANGUAGE: bash CODE: ``` # ckUSDC transfer (correct fee) dfx canister call xevnm-gaaaa-aaaar-qafnq-cai icrc1_transfer '(record { amount = 100000 : nat; # 0.1 ckUSDC fee = opt (10000 : nat); # ✅ CORRECT: 0.01 ckUSDC ... })' --network ic # ckBTC transfer (different fee structure) dfx canister call mxzaz-hqaaa-aaaar-qaada-cai icrc1_transfer '(record { amount = 100 : nat; # 100 satoshis fee = opt (10 : nat); # ✅ CORRECT: 10 satoshis ... })' --network ic ``` -------------------------------- TITLE: Identity and Authorization Troubleshooting for DFX DESCRIPTION: Commands and configurations to resolve identity and authorization errors when interacting with canisters. This includes listing and using identities, checking canister controllers, and managing DFX security warnings for mainnet operations. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/docs/CANISTER_DEBUGGING_GUIDE.md#_snippet_5 LANGUAGE: bash CODE: ``` # 1. Map all available identities to their principals dfx identity list for identity in $(dfx identity list | grep -v "^anonymous$"); do echo "$identity: $(dfx identity use $identity && dfx identity get-principal)" done # 2. Check canister controllers dfx canister info $CANISTER_ID --network ic # 3. Use correct identity for specific operations: # - Controller identity (e.g., STAGING_DEPLOYER): For canister upgrades # - Custodian identity (e.g., testnet_custodian): For operations # - Operator identity (e.g., default): For daily operations # 4. Fix corrupted identity configuration if needed cat ~/.config/dfx/identity.json # Should be: {"default": "default"} # 5. Suppress security warnings export DFX_WARNING=-mainnet_plaintext_identity ``` -------------------------------- TITLE: Get Balances (Legacy TypeScript) DESCRIPTION: Legacy TypeScript script to check balances for all subaccounts. Requires .env configuration and is run via 'pnpm run test:script'. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/test/README.md#_snippet_10 LANGUAGE: bash CODE: ``` pnpm run test:script -- test/scripts/legacy/getBalances.ts ``` -------------------------------- TITLE: Smart Sweep Operation with Fee Calculation using ICSI DESCRIPTION: Performs a 'smart sweep' operation for a specified token type, ensuring sufficient balance and calculating minimum sweep amounts based on predefined fees. This function uses authenticated ICSI calls to get balances and initiate the sweep. It returns an error if the balance is too low. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/packages/icsi-lib/docs/EXAMPLES.md#_snippet_19 LANGUAGE: typescript CODE: ``` import { getBalances, sweepByTokenType, Tokens } from '@jagad/icsi'; export const smartSweep = async ( userVaultCanisterId: string, tokenType: typeof Tokens.CKUSDC ) => { // Check balance first const balances = await addHttpAgent(getBalances, [userVaultCanisterId]); const tokenName = Object.keys(tokenType)[0]; const balance = balances.find( (b) => Object.keys(b.tokenType)[0] === tokenName ); if (!balance || balance.balance === 0) { return { Err: 'No balance to sweep' }; } // Calculate fees and minimum amounts const fees = { ICP: 10000, // 0.0001 ICP CKUSDC: 10000, // 0.01 CKUSDC CKUSDT: 10000, // 0.01 CKUSDT CKBTC: 10, // 0.0000001 BTC }; const fee = fees[tokenName] || 10000; const minAmount = fee * 10; // 10x fee as minimum if (balance.balance < minAmount) { return { Err: `Balance ${balance.balance} too low for efficient sweep (min: ${minAmount})`, }; } // Perform sweep return await addHttpAgent(sweepByTokenType, [userVaultCanisterId, tokenType]); }; ``` -------------------------------- TITLE: Generate and Fund Test Wallet using pnpm DESCRIPTION: This sequence of commands is part of the testing setup. First, it generates a test wallet. Second, it instructs to fund the generated wallet with test tokens, referring to `TESTING_GUIDE.md` for detailed instructions on obtaining and transferring test tokens. SOURCE: https://github.com/garudaidr/icp-subaccount-indexer/blob/main/README.md#_snippet_18 LANGUAGE: bash CODE: ``` pnpm run lib:generate:wallet # Fund the wallet with test tokens (see TESTING_GUIDE.md) ```