iotex-node-sdk
v0.2.3
Published
Comprehensive npm package for querying the IoTeX blockchain via native gRPC protocol with account management, HD wallet support, and full TypeScript types.
Maintainers
Readme
IoTeX Node.js SDK
A comprehensive npm package for querying the IoTeX blockchain using the native gRPC protocol. This SDK provides a TypeScript-first interface for blockchain queries, account management, and delegate information.
Features
- Native gRPC Support: Direct connection to IoTeX nodes via gRPC (api.iotex.one:443)
- Blockchain Queries: Access chain metadata, blocks, epochs, and transaction receipts
- Node Delegate Queries: Query blockchain delegates, epochs, and consensus information
- Voting Bucket Queries: Query staking buckets with custom protobuf encoding/decoding
- Account Queries: Get balances, metadata, nonce, and action history
- Account Management: Create, import, export accounts with keystore encryption
- HD Wallet Support: Hierarchical Deterministic wallets with BIP44 derivation (m/44'/304'/...)
- Address Conversion: Seamless conversion between IoTeX and Ethereum address formats
- TypeScript Native: Full TypeScript support with comprehensive type definitions
- Modern Stack: Built with ethers v6, @grpc/grpc-js, and official IoTeX libraries
Installation
npm install iotex-node-sdkQuick Start
import { IoTeXSDK } from 'iotex-node-sdk';
// Create SDK instance for mainnet
const sdk = IoTeXSDK.mainnet();
// Connect to blockchain
await sdk.connect();
// Get chain metadata
const chainMeta = await sdk.blockchain.getChainMeta();
console.log(`Height: ${chainMeta.height}, Epoch: ${chainMeta.epoch.num}`);
// Get account balance
const balance = await sdk.account.getBalance('io1gh7xfrsnj6p5uqgjpk9xq6jg9na28aewgp7a9v');
console.log(`Balance: ${balance} IOTX`);
// Get current delegates
const delegates = await sdk.node.getDelegates();
console.log(`Total delegates: ${delegates.length}`);
// Get voting buckets
const buckets = await sdk.blockchain.getBucketList({
voterAddress: 'io1jzdxuv7etyfvs7th7jwyspswr6y660zjd7lykg'
});
console.log(`Total buckets: ${buckets.length}`);
// Disconnect
sdk.disconnect();Network Configuration
Mainnet
const sdk = IoTeXSDK.mainnet();
// or
const sdk = new IoTeXSDK({ endpoint: 'api.iotex.one:443', secure: true });Testnet
const sdk = IoTeXSDK.testnet();
// or
const sdk = new IoTeXSDK({ endpoint: 'api.testnet.iotex.one:443', secure: true });Local Node
const sdk = IoTeXSDK.localhost();
// or
const sdk = new IoTeXSDK({ endpoint: 'localhost:14014', secure: false });Account Management
Create New Account
// Create account with password-protected keystore
const account = await sdk.account.create('password123');
console.log('Address:', account.address);
console.log('Private key:', account.privateKey);Import Account from Private Key
const address = await sdk.account.importKey(
'your-private-key-hex',
'password123'
);Export Private Key
const privateKey = await sdk.account.exportKey(
'io1gh7xfrsnj6p5uqgjpk9xq6jg9na28aewgp7a9v',
'password123'
);List Accounts
const accounts = sdk.account.list();
for (const account of accounts) {
console.log(account.address);
}Sign and Verify Messages
// Sign message
const signature = await sdk.account.sign(
'io1gh7xfrsnj6p5uqgjpk9xq6jg9na28aewgp7a9v',
'password123',
'Hello, IoTeX!'
);
// Verify signature
const isValid = sdk.account.verify(
'Hello, IoTeX!',
signature,
'io1gh7xfrsnj6p5uqgjpk9xq6jg9na28aewgp7a9v'
);HD Wallet (Hierarchical Deterministic Wallet)
Create HD Wallet
// Create HD wallet with mnemonic
const mnemonic = await sdk.account.createHDWallet('password123', 'english');
console.log('Mnemonic:', mnemonic);
// Save this mnemonic securely!Import HD Wallet
await sdk.account.importHDWallet(
'your twelve word mnemonic phrase here',
'password123'
);Derive Accounts
// Derive account at path m/44'/304'/0'/0/0
const account1 = await sdk.account.deriveHDAccount('password123', 0, 0, 0);
console.log('Address:', account1.address);
console.log('Path:', account1.path);
// Derive account at path m/44'/304'/0'/0/1
const account2 = await sdk.account.deriveHDAccount('password123', 0, 0, 1);
// Derive account at path m/44'/304'/1'/0/0
const account3 = await sdk.account.deriveHDAccount('password123', 1, 0, 0);Address Conversion
import { toEthAddress, toIoAddress } from 'iotex-node-sdk';
// Convert IoTeX to Ethereum format
const ethAddr = toEthAddress('io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw');
// Returns: 0xb8744ae4032be5e5ef9fab94ee9c3bf38d5d2ae0
// Convert Ethereum to IoTeX format
const ioAddr = toIoAddress('0xb8744ae4032be5e5ef9fab94ee9c3bf38d5d2ae0');
// Returns: io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4twBlockchain Queries
Get Chain Metadata
const chainMeta = await sdk.blockchain.getChainMeta();
console.log('Height:', chainMeta.height.toString());
console.log('Epoch:', chainMeta.epoch.num.toString());
console.log('TPS:', chainMeta.tps);Get Block Information
// Get block by height
const block = await sdk.blockchain.getBlock(1000000);
// Get block by hash
const blockByHash = await sdk.blockchain.getBlock('block-hash-here');
console.log('Block hash:', block.blockHash);
console.log('Timestamp:', block.timestamp);
console.log('Producer:', block.producerAddress);Get Epoch Metadata
// Get current epoch
const currentEpoch = await sdk.blockchain.getEpochMeta();
// Get specific epoch
const epoch1000 = await sdk.blockchain.getEpochMeta(1000);
console.log('Epoch:', currentEpoch.num.toString());
console.log('Height:', currentEpoch.height.toString());Get Voting Buckets
// Get buckets by voter address
const buckets = await sdk.blockchain.getBucketList({
voterAddress: 'io1jzdxuv7etyfvs7th7jwyspswr6y660zjd7lykg',
offset: 0,
limit: 100
});
// Get buckets by candidate name
const candidateBuckets = await sdk.blockchain.getBucketList({
candidateName: 'iotexlab'
});
// Get all buckets (paginated)
const allBuckets = await sdk.blockchain.getBucketList({
offset: 0,
limit: 100
});
// Get specific bucket by index
const bucket = await sdk.blockchain.getBucket(32);
console.log('Bucket info:', {
index: bucket.index,
candidateAddress: bucket.candidateAddress,
stakedAmount: bucket.stakedAmount,
stakedDuration: bucket.stakedDuration,
autoStake: bucket.autoStake,
owner: bucket.owner
});Get Blockchain Version
const version = await sdk.blockchain.getVersion();
console.log('Version:', version.packageVersion);
console.log('Commit:', version.packageCommitID);Node Delegate Queries
Get Current Delegates
// Get top 36 delegates with full candidate information
const delegates = await sdk.node.getDelegates();
for (const delegate of delegates) {
console.log(`${delegate.rank}. ${delegate.name}`);
console.log(` Operator Address: ${delegate.operatorAddress || delegate.address}`);
console.log(` Owner Address: ${delegate.ownerAddress}`);
console.log(` Reward Address: ${delegate.rewardAddress}`);
console.log(` Votes: ${delegate.votes} IOTX`);
console.log(` Total Weighted Votes: ${delegate.totalWeightedVotes}`);
console.log(` Self-staking Tokens: ${delegate.selfStakingTokens}`);
console.log(` Production: ${delegate.production}`);
console.log(` Active: ${delegate.active}`);
}Get All Delegates
// Get all delegates for current epoch (includes all registered candidates)
const allDelegates = await sdk.node.getDelegates({ all: true });
// Get delegates for specific epoch
const epoch1000Delegates = await sdk.node.getDelegates({
epochNumber: 1000,
all: true
});
// Access extended delegate fields
console.log('Owner:', allDelegates[0].ownerAddress);
console.log('Operator:', allDelegates[0].operatorAddress);
console.log('Reward:', allDelegates[0].rewardAddress);
console.log('Self-stake bucket index:', allDelegates[0].selfStakeBucketIdx);
console.log('ID:', allDelegates[0].id);Get Current Epoch
const currentEpoch = await sdk.node.getCurrentEpoch();
console.log('Epoch:', currentEpoch.num.toString());
console.log('Height:', currentEpoch.height.toString());Account Information
Get Account Balance
const balance = await sdk.account.getBalance('io1jzdxuv7etyfvs7th7jwyspswr6y660zjd7lykg');
console.log(`Balance: ${balance} IOTX`);
// Also works with Ethereum addresses
const balance2 = await sdk.account.getBalance('0x909a6e33d95912c87977f49c48060e1e89ad3c52');Get Account Metadata
const meta = await sdk.account.getMeta('io1jzdxuv7etyfvs7th7jwyspswr6y660zjd7lykg');
console.log('Address:', meta.address);
console.log('Balance:', meta.balance);
console.log('Nonce:', meta.nonce.toString());
console.log('Pending Nonce:', meta.pendingNonce.toString());
console.log('Number of Actions:', meta.numActions.toString());Get Account Nonce
const nonce = await sdk.account.getNonce('io1jzdxuv7etyfvs7th7jwyspswr6y660zjd7lykg');
console.log('Current nonce:', nonce.toString());Utility Functions
Amount Conversion
import { iotxToRau, rauToIotx } from 'iotex-node-sdk';
// Convert IOTX to Rau (smallest unit)
const rau = iotxToRau('100'); // Returns: 100000000000000000000n
const iotx = rauToIotx(rau); // Returns: "100"Validation
import {
isValidIoAddress,
isValidEthAddress,
isValidAmount,
isValidCandidateName
} from 'iotex-node-sdk';
isValidIoAddress('io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw'); // true
isValidEthAddress('0xb8744ae4032be5e5ef9fab94ee9c3bf38d5d2ae0'); // true
isValidAmount('100.5'); // true
isValidCandidateName('iotexlab'); // trueError Handling
import { IoTeXError } from 'iotex-node-sdk';
try {
const balance = await sdk.account.getBalance('invalid-address');
} catch (error) {
if (error instanceof IoTeXError) {
console.error('Error code:', error.code);
console.error('Message:', error.message);
console.error('Details:', error.details);
}
}Examples
See the examples/ directory for complete working examples:
get-balance.ts- Query account balancesget-delegates.ts- Query blockchain delegatescreate-account.ts- Create and manage accountshdwallet.ts- HD wallet operationsblockchain-info.ts- Query blockchain information
Run an example:
npx ts-node examples/get-balance.tsTesting
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm test -- --coverageBuilding
npm run buildArchitecture
iotex-node-sdk/
├── src/
│ ├── client/ # gRPC client and configuration
│ ├── account/ # Account management, keystore, HD wallet, crypto
│ ├── node/ # Node delegate queries
│ ├── stake/ # Staking operations (stake2)
│ ├── blockchain/ # Blockchain queries
│ ├── utils/ # Utilities (conversion, validation, errors)
│ └── index.ts # Main SDK export
├── proto/ # Protobuf definitions from iotex-proto
├── examples/ # Usage examples
└── test/ # Unit testsDependencies
Core Dependencies
- @grpc/grpc-js ^1.12.0 - Modern gRPC for Node.js
- @grpc/proto-loader ^0.7.13 - Dynamic protobuf loading
- @iotexproject/iotex-address-ts ^1.0.2 - Official address conversion
- ethers ^6.13.0 - Ethereum-compatible cryptography
- bip39 ^3.1.0 - Mnemonic generation/validation
- hdkey ^2.1.0 - HD wallet key derivation
Comparison with ioctl
This SDK replicates the core functionality of the ioctl CLI tool:
| ioctl Command | SDK Method |
|---------------|------------|
| ioctl account balance | sdk.account.getBalance() |
| ioctl account create | sdk.account.create() |
| ioctl account import | sdk.account.importKey() |
| ioctl hdwallet create | sdk.account.createHDWallet() |
| ioctl hdwallet derive | sdk.account.deriveHDAccount() |
| ioctl node delegate | sdk.node.getDelegates() |
| ioctl bc info | sdk.blockchain.getChainMeta() |
| ioctl bc block | sdk.blockchain.getBlock() |
📚 Documentation
Complete documentation is available in the docs/ folder:
- DOCUMENTATION_INDEX.md - Start here! Master index to all documentation
- GETTING_STARTED.md - Installation and first steps
- README_QUERIES.md - Query examples and patterns
- ACCOUNT_MANAGEMENT.md - Account creation, keystore, HD wallet
- API_COMPLETE_REFERENCE.md - Exhaustive API documentation
- ADVANCED_QUERIES.md - Advanced query patterns and error handling
- FEATURES_STATUS.md - Feature implementation status
All features are fully documented with examples and best practices.
Development Status
Fully Implemented ✅
- gRPC client with TLS support
- Account management (create, import, export, sign)
- Account queries (balance, metadata, nonce)
- Keystore encryption/decryption
- HD wallet with BIP44 derivation
- Cryptographic operations (signing, verification, hashing)
- Address conversion (IoTeX ↔ Ethereum)
- Blockchain queries (chain meta, blocks, epochs)
- Voting bucket queries (custom protobuf encoding/decoding)
- Node delegate queries
- Utility functions (conversion, validation, errors)
- Comprehensive test suite (52 tests passing)
Not Yet Implemented ❌
- Write operations (staking, transfers, contract calls)
- Smart contract interaction
- Action submission (requires protobuf serialization)
- Event streaming
- WebSocket support
Roadmap
- Phase 1: Complete protobuf action building for staking operations
- Phase 2: Implement smart contract ABI encoding/decoding
- Phase 3: Add WebSocket support for real-time events
- Phase 4: Browser compatibility (using grpc-web)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
Links
Support
For issues and questions:
- GitHub Issues: Create an issue
- IoTeX Discord: Join the community
