@cfxdevkit/cdk
Conflux RPC client, contract I/O, addresses, units, errors.
Install
pnpm
pnpm add @cfxdevkit/cdkThe chain-aware client + signer layer everything else in @cfxdevkit/* builds on.
Cross-space first: every primitive works on Conflux eSpace (EVM, viem-backed)
and Core Space (Conflux-native, cive-backed) through a single discriminated
union (client.family === 'espace' | 'core').
Sub-paths
| Sub-path | Concern |
|---|---|
@cfxdevkit/cdk/client | createClient, http, ws, fallback (EspaceClient ∪ CoreSpaceClient) |
@cfxdevkit/cdk/wallet | Mnemonic derivation, dual-address accounts, signerFromPrivateKey (signs both spaces via viem & cive) |
@cfxdevkit/cdk/chains | Built-in chain configs (espaceMainnet, espaceTestnet, coreSpaceMainnet, coreSpaceTestnet, …) |
@cfxdevkit/cdk/address | Base32 ↔ hex codec (hexToBase32, base32ToHex, isBase32Address, getCoreAddress) |
@cfxdevkit/cdk/units | Decimal helpers (formatCFX/parseCFX, formatDrip/parseDrip, formatGDrip/parseGDrip) |
@cfxdevkit/cdk/types | Shared primitives (Address, Hex, Hash, Wei, BlockTag, EpochTag, NodeStatus, CoreLog…, SponsorInfo) |
@cfxdevkit/cdk/errors | CfxError + typed error codes |
What lives where
-
createClient({ chain, transport })returns the right client for the chain’sfamily(EspaceClient∪CoreSpaceClientdiscriminated union).- eSpace:
getBlockNumber,getBlock,getBalance,getTransactionReceipt,estimateGas - Core Space:
getEpochNumber,getStatus,getBalance,getTransactionReceipt,getTransaction,getLogs,getSponsorInfo,getAdmin - Both:
request({ method, params })for any RPC the typed surface doesn’t cover.
- eSpace:
-
signerFromPrivateKey(pk, coreNetworkId?)returns aSignerthat signs both EIP-1559 (eSpace) and Conflux native (CIP-1559 / CIP-2930 / legacy) transactions via viem and cive respectively. PasscoreNetworkIdto populateaccount.coreAddress.
MUST NOT depend on any other @cfxdevkit/* package.
Usage
Create a client
import { createClient, http, espaceTestnet } from '@cfxdevkit/cdk'
const client = createClient({
chain: espaceTestnet,
transport: http('https://testnet.confluxrpc.com')
})
const blockNumber = await client.getBlockNumber()Sign and send a transaction (eSpace)
import { signerFromPrivateKey, parseCFX } from '@cfxdevkit/cdk'
const signer = signerFromPrivateKey('0x…', espaceTestnet.id)
const txHash = await client.sendRawTransaction({
to: '0x…',
value: parseCFX('1'),
gas: 21_000n,
gasPrice: 1_000_000_000n,
...signer
})Sign and send a transaction (Core Space)
import { signerFromPrivateKey, parseCFX, coreSpaceTestnet } from '@cfxdevkit/cdk'
const signer = signerFromPrivateKey('0x…', coreSpaceTestnet.id)
const txHash = await client.sendRawTransaction({
to: '0x…',
value: parseCFX('1'),
gas: 21_000n,
gasPrice: 1_000_000_000n,
...signer
})Address utilities
import { hexToBase32, base32ToHex, getCoreAddress } from '@cfxdevkit/cdk'
const base32 = hexToBase32('0x1234…', espaceTestnet.id)
const hex = base32ToHex(base32)
const coreAddr = getCoreAddress(base32)Units
import { formatCFX, parseCFX, formatDrip, parseDrip } from '@cfxdevkit/cdk'
const cfx = formatCFX(1_000_000_000_000_000_000n) // '1.0'
const drip = parseCFX('1.0') // 1_000_000_000_000_000_000n
const dripStr = formatDrip(drip) // '1000000000000000000'Chain configs
import { espaceMainnet, coreSpaceTestnet, getChain } from '@cfxdevkit/cdk'
const chain = getChain('conflux-espace-testnet')
console.log(chain.family) // 'espace'Error handling
import { isCfxError, CfxError } from '@cfxdevkit/cdk'
try {
await client.getBlockNumber()
} catch (err) {
if (isCfxError(err)) {
console.log(err.code, err.message)
}
}API Reference
See API.md for the full public surface.
Tier
Tier 0 — framework — Must not runtime-import from any higher tier.
API Reference
.
Usage
import { createClient, espaceMainnet, http } from '@cfxdevkit/cdk';
const client = createClient({
chain: espaceMainnet,
transport: http(),
});// Converts a hex address to a base32 address, supporting both Core and eSpace networks
export declare function hexToBase32(hexAddress: Hex, networkId: number, opts?: {
// Whether to include the network prefix (e.g., "cfx") in the output
}): string;
// Converts a base32 address to a hex address, handling both Core and eSpace formats
export declare function base32ToHex(base32Address: string, opts?: {
// Whether to include the "0x" prefix in the output
}): Hex;
// Checks if a string is a valid base32 address (Core or eSpace format)
export declare function isBase32Address(address: string): boolean;
// Returns the canonical Core address for a given address (resolves base32 or eSpace hex to Core hex)
export declare function getCoreAddress(address: string): string;
// Retrieves the configuration for a specific chain by ID or name
export declare function getChain(idOrName: ChainId | string): ChainConfig;
// Returns a list of available chains, optionally filtered by family or network type
export declare function listChains(filter?: {
// Optional filter to restrict chains by family or network
}): ChainConfig[];
// Defines and registers a custom chain configuration for use with the SDK
export declare function defineChain(input: ChainConfig): ChainConfig;./address
Usage
import { hexToBase32 } from '@cfxdevkit/cdk/address';
const base32 = hexToBase32('0x...', 1);// Converts a hex address to a base32 address, supporting both Core and eSpace networks
export declare function hexToBase32(hexAddress: Hex, networkId: number, opts?: {
// Whether to include the network prefix (e.g., "cfx") in the output
}): string;
// Converts a base32 address to a hex address, handling both Core and eSpace formats
export declare function base32ToHex(base32Address: string, opts?: {
// Whether to include the "0x" prefix in the output
}): Hex;
// Checks if a string is a valid base32 address (Core or eSpace format)
export declare function isBase32Address(address: string): boolean;
// Returns the canonical Core address for a given address (resolves base32 or eSpace hex to Core hex)
export declare function getCoreAddress(address: string): string;./chains
Usage
import { espaceMainnet } from '@cfxdevkit/cdk/chains';
console.log(espaceMainnet.id);// Represents the family of the chain: 'core' (Conflux Core Space) or 'espace' (Conflux eSpace)
export type ChainFamily = 'core' | 'espace';
// Represents the network environment: mainnet, testnet, devnet, or local
export type Network = 'mainnet' | 'testnet' | 'devnet' | 'local';
// Configuration for a blockchain chain, including ID, name, RPC endpoints, and metadata
export interface ChainConfig {
// Chain identifier, name, RPC endpoints, and other metadata
}
// Espace mainnet configuration (public testnet for eSpace)
export declare const espaceMainnet: ChainConfig;
// Espace testnet configuration (public testnet for eSpace)
export declare const espaceTestnet: ChainConfig;
// Espace local configuration (for local development/testing)
export declare const espaceLocal: ChainConfig;
// Core-Espace mainnet configuration (public mainnet for Core Space)
export declare const coreSpaceMainnet: ChainConfig;
// Core-Espace testnet configuration (public testnet for Core Space)
export declare const coreSpaceTestnet: ChainConfig;
// Core-Espace local configuration (for local development/testing)
export declare const coreSpaceLocal: ChainConfig;
// Retrieves the configuration for a specific chain by ID or name
export declare function getChain(idOrName: ChainId | string): ChainConfig;
// Returns a list of available chains, optionally filtered by family or network type
export declare function listChains(filter?: {
// Optional filter to restrict chains by family or network
}): ChainConfig[];
// Defines and registers a custom chain configuration for use with the SDK
export declare function defineChain(input: ChainConfig): ChainConfig;./client
Usage
import { createClient, http } from '@cfxdevkit/cdk/client';
import { espaceMainnet } from '@cfxdevkit/cdk/chains';
const client = createClient({
chain: espaceMainnet,
transport: http(),
});// Options for configuring an HTTP transport (e.g., batch size, headers)
export { HttpTransportOptions }
// Type representing a generic transport mechanism for RPC communication
export { Transport }
// Options for configuring a WebSocket transport (e.g., reconnect settings)
export { WsTransportOptions }
// Creates a fallback transport that tries multiple transports in sequence
export { fallback }
// Creates an HTTP transport for RPC communication
export { http }
// Creates a WebSocket transport for real-time RPC communication
export { ws }
// Parameters for an RPC request, including method name and arguments
export interface RpcRequest {
// Method name and parameters for an RPC call
}
// Common options for RPC method calls (e.g., timeout, custom headers)
export interface CallOptions {
// Common options for RPC method calls (e.g., timeout, headers)
}
// Additional options specific to balance queries (e.g., block number)
export interface GetBalanceOptions extends CallOptions {
// Additional options specific to balance queries (e.g., block number)
}
// Core-specific RPC call options (e.g., epoch parameter)
export interface CoreCallOptions extends CallOptions {
// Core-specific RPC call options (e.g., epoch parameter)
}
// Client interface for interacting with the eSpace network
export interface EspaceClient extends ClientBase {
// Espace-specific RPC methods and utilities
}
// Client interface for interacting with the Core Space network
export interface CoreSpaceClient extends ClientBase {
// Core-specific RPC methods and utilities
}
// Input configuration for initializing a client instance
export interface CreateClientInput {
// Chain and transport configuration for client initialization
}
// Initialization parameters for SDK errors (code, message, context)
export interface CfxErrorInit {
// Error code, message, and optional context for SDK errors
}
// Status information of a node, including sync state, consensus info, and version
export interface NodeStatus {
// Node synchronization, consensus, and version info
}
// Filter criteria for querying Core network logs
export interface CoreLogFilter {
// Criteria for filtering Core network logs (e.g., address, topics)
}
// A log entry emitted by the Core network during transaction execution
export interface CoreLog {
// Log data including address, topics, data, and block info
}
// Information about transaction sponsorship (gas limit, collateral, sponsor address)
export interface SponsorInfo {
// Sponsor address, gas limit, and collateral details for sponsored transactions
}
// Represents a blockchain account with optional private key or signer reference
export interface Account {
// Address and optional private key or signer reference
}
// A transaction object that can be signed (e.g., before submission)
export interface SignableTx {
// Transaction fields required for signing (e.g., nonce, gas, value)
}
// Options for signing a transaction (e.g., chain ID override, nonce hint)
export interface SignOptions {
// Options like chain ID override or nonce hint during signing
}
// Interface for an object capable of signing transactions and messages
export interface Signer {
// Interface for signing transactions and messages
}
// Espace mainnet configuration (re-exported for convenience)
export declare const espaceMainnet: ChainConfig;
// Espace testnet configuration (re-exported for convenience)
export declare const espaceTestnet: ChainConfig;
// Espace local configuration (re-exported for convenience)
export declare const espaceLocal: ChainConfig;
// Core-Espace mainnet configuration (re-exported for convenience)
export declare const coreSpaceMainnet: ChainConfig;
// Core-Espace testnet configuration (re-exported for convenience)
export declare const coreSpaceTestnet: ChainConfig;
// Core-Espace local configuration (re-exported for convenience)
export declare const coreSpaceLocal: ChainConfig;
// Maximum value of a uint256 type (2^256 - 1)
export declare const MAX_UINT256: bigint;
// Maximum value of a uint128 type (2^128 - 1)
export declare const MAX_UINT128: bigint;
// The zero address (0x0000000000000000000000000000000000000000)
export declare const ZERO_ADDRESS: Address;./errors
Usage
import { CfxError, RpcError, ContractError } from '@cfxdevkit/cdk/errors';
try {
// ...
} catch (err) {
if (err instanceof RpcError) {
console.error('RPC error:', err.message);
}
}// Base error class for all SDK errors, providing standardized error codes and context
export declare class CfxError extends Error {
// Base error with standardized code and context
}
// Error class wrapping RPC response failures (e.g., invalid method, server error)
export declare class RpcError extends CfxError {
// Wraps RPC response errors with status and data
}
// Error class for contract execution failures (e.g., revert, out-of-gas)
export declare class ContractError extends CfxError {
// Thrown on revert, out-of-gas, or other contract execution issues
}
// Error class for wallet-related failures (e.g., account creation, signing)
export declare class WalletError extends CfxError {
// Thrown during account creation, signing, or key management
}
// Error class for keystore operations (e.g., encryption, decryption, file I/O)
export declare class KeystoreError extends CfxError {
// Thrown on keystore encryption/decryption or file I/O failures
}./types
Usage
import { Hex, Address, ChainId } from '@cfxdevkit/cdk/types';
const hex: Hex = '0x1234';
const address: Address = '0x...';
const chainId: ChainId = 1;// Hex-encoded string (must start with '0x')
export type Hex = string;
// Conflux address (hex or base32 format)
export type Address = string;
// Chain identifier number (e.g., 1029 for Core mainnet, 1030 for eSpace mainnet)
export type ChainId = number;
// Block number specifier (e.g., 'latest_mined', 'earliest', or hex)
export type BlockNumber = 'latest_state' | 'latest_mined' | 'earliest' | Hex;
// Hex-encoded transaction hash
export type TransactionHash = Hex;
// Hex-encoded block hash
export type BlockHash = Hex;
// Index of a log in its transaction
export type LogIndex = number;
// Index of a transaction in its block
export type TransactionIndex = number;
// Hex-encoded transaction nonce
export type Nonce = Hex;
// Hex-encoded gas limit or used gas
export type Gas = Hex;
// Hex-encoded gas price (in drips)
export type GasPrice = Hex;
// Hex-encoded value (in drips)
export type Value = Hex;
// Hex-encoded arbitrary data (e.g., calldata)
export type Data = Hex;
// Topics filter for logs (single topic, array, or null for any)
export type FilterTopics = Hex | Hex[] | null;
// Input for a call (read-only) request
export type CallRequest = {
// From/to address, gas, value, data, etc.
};
// Input for a transaction request (write)
export type TransactionRequest = {
// Full transaction fields including nonce, gas, value, data, etc.
};./units
Usage
import { formatUnits, parseUnits } from '@cfxdevkit/cdk/units';
const formatted = formatUnits('1000000000000000000', 18); // '1'
const parsed = parseUnits('1', 18); // '1000000000000000000'// Formats a raw value (in drips) into a human-readable unit (e.g., CFX)
export { formatUnits }
// Parses a human-readable value (e.g., '1.5') into raw drips (as hex string)
export { parseUnits }
// Core network ID type (used internally for chain identification)
export { CoreNetworkId }
// Unit name for Conflux native token (CFX)
export type Unit = 'cfx' | 'drip';
// Unit name for various denominations (including wei, nfi, fi, drip, cfx)
export type UnitName = 'cfx' | 'drip' | 'nfi' | 'fi' | 'wei';
// Input value for unit conversion (string, number, or bigint)
export type UnitValue = string | number | bigint;
// Options for formatting units (e.g., rounding mode, decimal precision)
export interface FormatUnitsOptions {
// Rounding mode and decimal precision settings
}
// Options for parsing units (e.g., decimal places, validation behavior)
export interface ParseUnitsOptions {
// Decimal places and validation behavior
}./wallet
Usage
import { deriveAccount, generateMnemonic } from '@cfxdevkit/cdk/wallet';
const mnemonic = generateMnemonic();
const account = deriveAccount(mnemonic, { path: "m/44'/503'/0'/0/0" });// Input for deriving a single account from a mnemonic or private key
export { DeriveAccountInput }
// Input for deriving multiple accounts from a mnemonic or private key
export { DeriveAccountsInput }
// Input for deriving both Core and eSpace addresses from a mnemonic
export { DeriveDualAccountInput }
// Result of account derivation: includes address, private key, and path
export { DerivedAccount }
// Result of dual-address derivation: includes both Core and eSpace addresses
export { DualAddressAccount }
// Derives the Core address from a raw private key
export { coreAddressFromPrivateKey }
// Default BIP44 path for Core Space accounts
export { DEFAULT_CORE_PATH }
// Default BIP44 path for eSpace accounts
export { DEFAULT_ESPACE_PATH }
// Derives a single account from a mnemonic or private key at a given path
export { deriveAccount }
// Derives multiple accounts from a mnemonic or private key at sequential paths
export { deriveAccounts }
// Derives both Core and eSpace addresses from a mnemonic at a given path
export { deriveDualAccount }
// Derives multiple dual-address accounts from a mnemonic at sequential paths
export { deriveDualAccounts }
// Generates a new BIP39-compliant mnemonic phrase
export { generateMnemonic }
// Validates a BIP39-compliant mnemonic phrase
export { validateMnemonic }