@kokosro/ledger-client
v0.3.0
Published
Lightweight browser/Node.js client for interacting with ledger RPC
Readme
@kokosro/ledger-client
⚠️ Experimental: This package is in active development and the API may change.
Lightweight browser and Node.js client for interacting with the TypeScript ledger via JSON-RPC.
Installation
npm install @kokosro/ledger-client viemDescription
A production-grade client library for connecting to ledger RPC servers. Features:
- Account management with mnemonic support
- Transaction signing and submission
- State queries and balance checks
- Cryptographic proof generation and verification
- Type-safe RPC methods
- Works in both browser and Node.js environments
Suitable for building dApps, wallets, and integrations with the ledger.
Quick Start
Basic RPC Client
import { createRpcClient } from "@kokosro/ledger-client";
const client = createRpcClient({
url: "http://localhost:37847",
timeout: 30000,
});
// Get chain info
const chainId = await client.call("eth_chainId");
const blockNumber = await client.call("eth_blockNumber");
// Get account balance
const balance = await client.call("eth_getBalance", [address, "latest"]);
// Send signed transaction
const txHash = await client.call("eth_sendRawTransaction", [signedTxHex]);
// Get transaction receipt
const receipt = await client.call("eth_getTransactionReceipt", [txHash]);High-Level Blockchain Client
import { BlockchainClient } from "@kokosro/ledger-client";
const client = new BlockchainClient({
rpcUrl: "http://localhost:37847",
accountsPath: "./accounts.json", // Optional: persist accounts
});
await client.initialize();
// Create or load accounts with mnemonic
const accounts = await client.loadOrCreateAccounts(3);
const [alice, bob, carol] = accounts;
console.log("Alice:", alice.address);
console.log("Mnemonic:", client.getMnemonic());
// Check balances
const balance = await client.getBalance(alice.address);
console.log(`Alice balance: ${balance}`);
// Submit transaction
const txHash = await client.submitTransaction(
alice, // sender account
bob.address, // recipient
1000n // amount
);
console.log("Transaction submitted:", txHash);
// Mine block (validator only)
const validator = accounts[0];
const block = await client.mineBlock(validator);
console.log("Block mined:", block.header.height);
// Verify state with proof
const proof = await client.generateProof(alice.address);
const isValid = await client.verifyProof(proof);
console.log("Proof valid:", isValid);API Reference
RPC Client
import { createRpcClient, type RpcClient } from '@kokosro/ledger-client';
type RpcClientConfig = {
url: string;
timeout?: number;
headers?: Record<string, string>;
};
const client = createRpcClient(config: RpcClientConfig): RpcClient;
interface RpcClient {
call<T>(method: string, params?: unknown[]): Promise<T>;
close(): void;
}Blockchain Client
import { BlockchainClient } from "@kokosro/ledger-client";
class BlockchainClient {
constructor(config: { rpcUrl: string; accountsPath?: string });
// Initialization
initialize(): Promise<void>;
// Account Management
loadOrCreateAccounts(count: number): Promise<Account[]>;
getMnemonic(): string | null;
saveAccounts(): Promise<void>;
// Queries
getBalance(address: Address): Promise<bigint>;
getAccount(address: Address): Promise<Account>;
getBlock(height: bigint): Promise<Block>;
getLatestBlock(): Promise<Block>;
getChainHeight(): Promise<bigint>;
getTransactionReceipt(txHash: Hash): Promise<Receipt | null>;
// Transactions
submitTransaction(
from: Account,
to: Address,
value: bigint,
data?: string,
kind?: TxKind
): Promise<Hash>;
// Block Production (Validators)
mineBlock(validator: Account): Promise<Block>;
// State Proofs
generateProof(address: Address): Promise<StateProof>;
verifyProof(proof: StateProof): Promise<boolean>;
}Account Manager
import { AccountManager } from "@kokosro/ledger-client";
class AccountManager {
constructor(accountsPath?: string);
generateMnemonic(): string;
createAccountsFromMnemonic(mnemonic: string, count: number): Account[];
loadAccounts(): Promise<{
mnemonic: string;
accounts: Account[];
} | null>;
saveAccounts(mnemonic: string, accounts: Account[]): Promise<void>;
}Proof Generator
import { ProofGenerator } from "@kokosro/ledger-client";
class ProofGenerator {
constructor(rpcClient: RpcClient);
generateAccountProof(address: Address): Promise<StateProof>;
verifyAccountProof(proof: StateProof): Promise<boolean>;
generateStorageProof(address: Address, key: string): Promise<StorageProof>;
verifyStorageProof(proof: StorageProof): Promise<boolean>;
}Usage Examples
Transfer Tokens
import { BlockchainClient } from "@kokosro/ledger-client";
const client = new BlockchainClient({
rpcUrl: "http://localhost:37847",
});
await client.initialize();
const accounts = await client.loadOrCreateAccounts(2);
const [sender, recipient] = accounts;
// Transfer 1000 tokens
const txHash = await client.submitTransaction(sender, recipient.address, 1000n);
console.log("Transaction:", txHash);Deploy Contract
const txHash = await client.submitTransaction(
deployer,
"0x0000000000000000000000000000000000000000", // null address
0n, // no value
"myContract", // contract code reference
"DEPLOY" // transaction kind
);Call Contract
const contractAddress = "0x..."; // deployed contract address
const callData = JSON.stringify({ method: "increment", args: [] });
const txHash = await client.submitTransaction(
caller,
contractAddress,
0n, // value to send
callData, // contract call data
"CALL" // transaction kind
);Verify State Proofs
import { ProofGenerator } from "@kokosro/ledger-client";
const proofGen = new ProofGenerator(rpcClient);
// Generate proof for account
const proof = await proofGen.generateAccountProof(address);
// Verify proof against state root
const isValid = await proofGen.verifyAccountProof(proof);
console.log("Account proof valid:", isValid);
// Generate storage proof
const storageProof = await proofGen.generateStorageProof(
contractAddress,
"storageKey"
);
const isStorageValid = await proofGen.verifyStorageProof(storageProof);
console.log("Storage proof valid:", isStorageValid);Error Handling
import { RpcError } from "@kokosro/ledger-client";
try {
await client.submitTransaction(sender, recipient, amount);
} catch (error) {
if (error instanceof RpcError) {
console.error("RPC Error:", error.code, error.message);
console.error("Data:", error.data);
} else {
console.error("Unexpected error:", error);
}
}Supported RPC Methods
The client supports all standard Ethereum JSON-RPC methods:
Chain Info:
eth_chainId- Get chain IDeth_blockNumber- Get latest block number
Accounts:
eth_getBalance- Get account balanceeth_getTransactionCount- Get account nonceeth_getCode- Get contract code
Blocks:
eth_getBlockByNumber- Get block by numbereth_getBlockByHash- Get block by hash
Transactions:
eth_sendRawTransaction- Submit signed transactioneth_getTransactionReceipt- Get transaction receipteth_getTransactionByHash- Get transaction details
State:
eth_getStorageAt- Get contract storageeth_call- Execute read-only contract call
Proofs:
eth_getProof- Get Merkle proof for account/storage
Environment Support
- ✅ Node.js 16+
- ✅ Modern browsers (Chrome, Firefox, Safari, Edge)
- ✅ TypeScript 4.0+
- ✅ ES Modules and CommonJS
Related Packages
- @kokosro/ledger - Server-side ledger and RPC server
- @kokosro/ledger-common - Shared types and utilities
License
ISC © 2025 kokosro
