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.
Downloads
51
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
