Chainweb Client
Fast, lightweight client for Chainweb and Pact APIs on the Kadena blockchain.
Features
- 🚀 Simple & Powerful - Clean API focused on common use cases
- 🌐 Cross-Platform - Works in browsers, Node.js, and React Native
- ⚡ Fast - Native fetch API with minimal overhead
- 🔄 Robust - Built-in timeout and error handling
- 📦 Lightweight - No external dependencies beyond pact-toolbox core
- 🔧 TypeScript - Full type safety and IntelliSense support
Installation
pnpm add @pact-toolbox/chainweb-client
Quick Start
import { ChainwebClient, createMainnetClient, createTestnetClient } from '@pact-toolbox/chainweb-client';
// Use built-in network clients
const mainnetClient = createMainnetClient();
const testnetClient = createTestnetClient();
// Or create custom client
const client = new ChainwebClient({
networkId: 'mainnet01',
chainId: '0',
rpcUrl: (networkId, chainId) =>
`https://api.chainweb.com/chainweb/0.0/${networkId}/chain/${chainId}/pact/api/v1`
});
// Send a transaction and wait for result
const result = await client.submitAndWait(signedTransaction);
console.log('Transaction result:', result);
Core API
Send Transactions
// Send signed transactions
const result = await client.send([signedTransaction]);
console.log('Request keys:', result.requestKeys);
// Submit and wait for result
const txResult = await client.submitAndWait(signedTransaction);
console.log('Transaction result:', txResult);
Query Blockchain
// Execute local (read-only) queries
const localResult = await client.local({
cmd: JSON.stringify({
code: '(coin.get-balance "alice")',
data: {},
meta: { chainId: '0', sender: '', gasLimit: 1000, gasPrice: 0.000001, ttl: 28800 }
})
});
// Poll for transaction status
const pollResult = await client.poll(['request-key-123']);
// Listen for single transaction
const listenResult = await client.listen('request-key-123');
Batch Operations
// Process multiple transactions in batches
const batchResult = await client.submitBatch(signedTransactions, {
batchSize: 10,
pollInterval: 5000
});
console.log(`${batchResult.successCount} succeeded, ${batchResult.failureCount} failed`);
Network Information
// Check network health
const health = await client.healthCheck();
console.log('Network healthy:', health.healthy);
// Get network info
const networkInfo = await client.getNetworkInfo();
console.log('Chains:', networkInfo.chains);
// Get current cut info
const cut = await client.getCut();
console.log('Current height:', cut.height);
Client Configuration
// Create clients for different chains/networks
const chain5Client = client.forChain('5');
const devnetClient = client.forNetwork('development');
// Custom configuration
const customClient = client.withConfig({
timeout: 60000,
headers: { 'Authorization': 'Bearer token' }
});
Configuration Options
interface NetworkConfig {
/** Network ID (e.g., 'mainnet01', 'testnet04', 'development') */
networkId: string;
/** Chain ID (e.g., '0', '1', '2', etc.) */
chainId: string;
/** Function to build RPC URLs */
rpcUrl: (networkId: string, chainId: string) => string;
/** Request timeout in milliseconds (default: 30000) */
timeout?: number;
/** Custom headers to include in requests */
headers?: Record<string, string>;
}
Error Handling
The client provides detailed error information through ChainwebClientError
:
try {
await client.send([transaction]);
} catch (error) {
if (error instanceof ChainwebClientError) {
console.log('Error code:', error.code);
console.log('HTTP status:', error.status);
console.log('Response:', error.response);
}
}
Error codes:
NETWORK_ERROR
- Network connectivity issues
TIMEOUT
- Request timeout
HTTP_ERROR
- HTTP status errors (4xx, 5xx)
PARSE_ERROR
- Invalid response format
VALIDATION_ERROR
- Invalid input parameters
TRANSACTION_ERROR
- Transaction processing errors
Built-in Network Clients
Mainnet
import { createMainnetClient } from '@pact-toolbox/chainweb-client';
const client = createMainnetClient({
chainId: '1', // Optional: defaults to '0'
timeout: 60000 // Optional: custom timeout
});
Testnet
import { createTestnetClient } from '@pact-toolbox/chainweb-client';
const client = createTestnetClient({
chainId: '0' // Optional: defaults to '0'
});
Development/Local
import { createDevnetClient, createPactServerClient } from '@pact-toolbox/chainweb-client';
// For local chainweb node
const devClient = createDevnetClient(8080);
// For pact-server
const pactClient = createPactServerClient(8080);
Integration with Pact Toolbox
The client integrates seamlessly with other pact-toolbox packages:
import { ChainwebClient } from '@pact-toolbox/chainweb-client';
import { finalizeTransaction } from '@pact-toolbox/signers';
import type { Transaction } from '@pact-toolbox/types';
const client = new ChainwebClient(config);
// Sign and send transaction
const signedTx = finalizeTransaction(transaction);
const result = await client.submitAndWait(signedTx);
Helper Functions
The package provides utility functions for common operations:
import {
dirtyReadOrFail,
localOrFail,
submit,
submitAndListen,
getClient,
getTxDataOrFail
} from '@pact-toolbox/chainweb-client';
// Use helper functions for cleaner code
const result = await submitAndListen(client, signedTransactions);
const data = getTxDataOrFail(result);
Platform Compatibility
- Browsers - Modern browsers with native fetch support
- Node.js - Version 18+ (native fetch) or 16+ with fetch polyfill
- React Native - All recent versions with fetch support
- Deno/Bun - Full compatibility
Migration from @kadena/client
Before (@kadena/client)
import { createClient } from '@kadena/client';
const client = createClient('https://api.chainweb.com/chainweb/0.0/mainnet01/chain/0/pact');
const result = await client.dirtyRead({ code: '(+ 1 2)' });
After (@pact-toolbox/chainweb-client)
import { createMainnetClient } from '@pact-toolbox/chainweb-client';
const client = createMainnetClient();
const result = await client.local({
cmd: JSON.stringify({
code: '(+ 1 2)',
data: {},
meta: { chainId: '0', sender: '', gasLimit: 1000, gasPrice: 0.000001, ttl: 28800 }
})
});
Performance Tips
- Reuse client instances - Create once, use throughout your app
- Use batch operations - For multiple transactions
- Configure timeouts - Based on your network conditions
- Handle errors gracefully - Implement proper retry logic for critical operations
API Reference
Core Methods
send(transactions)
- Send signed transactions
poll(requestKeys)
- Poll for transaction results
listen(requestKey)
- Listen for single transaction result
local(command)
- Execute read-only local query
submitAndWait(transaction)
- Send transaction and wait for result
submitBatch(transactions, options)
- Process multiple transactions in batches
Network Methods
healthCheck()
- Check network health
getNetworkInfo()
- Get network information
getCut()
- Get current cut information
getChainInfo(chainId?)
- Get chain-specific information
getTransaction(requestKey)
- Get transaction by request key
Utility Methods
withConfig(config)
- Create client with new configuration
forChain(chainId)
- Create client for different chain
forNetwork(networkId)
- Create client for different network
The chainweb-client package provides a modern, performant alternative to traditional Kadena client libraries while maintaining full compatibility with the Pact ecosystem.