Skip to Content
Packages@cfxdevkit/wallet

@cfxdevkit/wallet

Session keys, signers, batched writes, capability policies.

Install

pnpm add @cfxdevkit/wallet

Scope: Focused wallet primitives — session keys, capability-scoped signers, batched transactions.

Responsibilities

  • Session key generation and lifecycle (including attestation)
  • Capability/policy enforcement on signers (e.g., gas limits, allowed methods)
  • Batched transaction helpers (multicall + multisend via TransactionBatcher)
  • Re-exports a curated subset of core wallet APIs for convenience

Depends on: @cfxdevkit/cdk, @cfxdevkit/services (for keystore).

Security note: this package is the only blessed entrypoint for automated signers.

Sub-paths

Sub-pathExports
.34 symbols
./batcher4 symbols
./signers3 symbols
./errors2 symbols
./hardware8 symbols
./hardware/onekey5 symbols
./hardware/ledger8 symbols
./hardware/satochip3 symbols
./init8 symbols
./policies3 symbols
./session-key5 symbols

.

Core wallet primitives and convenience re-exports.

export declare const __packageName: "@cfxdevkit/wallet"; // Batched transactions export { BatchTask, TransactionBatcherOptions, TransactionBatchResult } export declare class TransactionBatcher<T = unknown> { constructor(options?: TransactionBatcherOptions); add(task: BatchTask): void; execute(): Promise<TransactionBatchResult<T>>; } // Hardware wallets export { HardwareWalletAdapter, HardwareWalletKind, HARDWARE_WALLET_KINDS, EVM_DEFAULT_PATH } export declare function detectHardwareWallet(kind: HardwareWalletKind): Promise<HardwareWalletAdapter>; export declare function getHardwareWalletAdapter(kind: HardwareWalletKind): Promise<HardwareWalletAdapter>; export declare function getHardwareWalletPath(kind: HardwareWalletKind, index: number): string; export declare function signWithHardwareWallet(adapter: HardwareWalletAdapter, path: string, message: string): Promise<RawEvmSignature>; // Utilities export { RawEvmSignature, finaliseEip1559Tx, rawSignatureToHex, toCanonicalHex } // Errors export declare class SessionKeyError extends CfxError { constructor(message: string, cause?: Error); } export declare class HardwareWalletError extends CfxError { constructor(message: string, cause?: Error); } // Local wallet management export declare function defaultKeystorePath(): string; export declare function initLocalWallet(input: InitLocalWalletInput): Promise<InitLocalWalletResult>; export declare function openLocalWallet(input: OpenLocalWalletInput): Promise<OpenLocalWalletResult>; export declare function rotateLocalPassphrase(input: { keystorePath: string; oldPassphrase: string; newPassphrase: string; }): Promise<void>; // Capability-scoped signers export declare function withCapability(inner: Signer, capability?: Capability): Signer; export declare function checkCapability(capability: Capability, tx: SignableTx): SessionKeyError | null; export declare function isEmptyCapability(c: Capability): boolean; // Session keys export declare function createSessionKey(input: CreateSessionKeyInput): Promise<SessionKey>; export declare function canonicalAttestationMessage(sessionAddress: Address, parent: Address, c: Capability): string; // Signers export declare function signerFromKeystore(input: SignerFromKeystoreInput): Promise<Signer>; export declare function readonlySigner(address: Address): Signer; // Interfaces export interface InitLocalWalletInput { keystorePath: string; passphrase: string; } export interface InitLocalWalletResult { keystorePath: string; address: Address; } export interface OpenLocalWalletInput { keystorePath: string; passphrase: string; } export interface OpenLocalWalletResult { keystorePath: string; address: Address; } export interface CreateSessionKeyInput { parentSigner: Signer; parentPassphrase?: string; capability: Capability; nonce?: bigint; } export interface SessionKey { address: Address; privateKey: string; attestation: SessionAttestation; } export interface SessionAttestation { parent: Address; capability: Capability; nonce: bigint; signature: string; } export interface SignerFromKeystoreInput { keystorePath: string; passphrase: string; }

./batcher

Batched transaction execution via TransactionBatcher.

export { BatchTask, TransactionBatcherOptions, TransactionBatchResult } export declare class TransactionBatcher<T = unknown> { constructor(options?: TransactionBatcherOptions); add(task: BatchTask): void; execute(): Promise<TransactionBatchResult<T>>; }

./signers

Signer creation and wrappers.

export interface SignerFromKeystoreInput { keystorePath: string; passphrase: string; } export declare function signerFromKeystore(input: SignerFromKeystoreInput): Promise<Signer>; export declare function readonlySigner(address: Address): Signer;

./errors

Custom error types.

export { SessionKeyError, HardwareWalletError }

./hardware

Hardware wallet abstraction and utilities.

export { HardwareWalletAdapter, HardwareWalletKind, HARDWARE_WALLET_KINDS, EVM_DEFAULT_PATH } export declare function detectHardwareWallet(kind: HardwareWalletKind): Promise<HardwareWalletAdapter>; export declare function getHardwareWalletAdapter(kind: HardwareWalletKind): Promise<HardwareWalletAdapter>; export declare function getHardwareWalletPath(kind: HardwareWalletKind, index: number): string; export declare function signWithHardwareWallet(adapter: HardwareWalletAdapter, path: string, message: string): Promise<RawEvmSignature>;

./hardware/onekey

OneKey hardware wallet support.

export { OneKeyAdapter } export declare function detectOneKey(): Promise<OneKeyAdapter>; export declare function getOneKeyAdapter(): Promise<OneKeyAdapter>; export declare function getOneKeyPath(index: number): string; export declare function signWithOneKey(adapter: OneKeyAdapter, path: string, message: string): Promise<RawEvmSignature>;

./hardware/ledger

Ledger hardware wallet support.

export { LedgerAdapter } export declare function detectLedger(): Promise<LedgerAdapter>; export declare function getLedgerAdapter(): Promise<LedgerAdapter>; export declare function getLedgerPath(index: number): string; export declare function signWithLedger(adapter: LedgerAdapter, path: string, message: string): Promise<RawEvmSignature>; export declare function getLedgerAppVersion(adapter: LedgerAdapter): Promise<string>; export declare function isLedgerAppOpen(adapter: LedgerAdapter): Promise<boolean>; export declare function openLedgerApp(adapter: LedgerAdapter): Promise<void>; export declare function closeLedgerApp(adapter: LedgerAdapter): Promise<void>;

./hardware/satochip

Satochip hardware wallet support.

export { SatochipAdapter } export declare function detectSatochip(): Promise<SatochipAdapter>; export declare function getSatochipAdapter(): Promise<SatochipAdapter>; export declare function signWithSatochip(adapter: SatochipAdapter, path: string, message: string): Promise<RawEvmSignature>;

./init

Local wallet initialization and passphrase management.

export { InitLocalWalletInput, InitLocalWalletResult } export { OpenLocalWalletInput, OpenLocalWalletResult } export declare function defaultKeystorePath(): string; export declare function initLocalWallet(input: InitLocalWalletInput): Promise<InitLocalWalletResult>; export declare function openLocalWallet(input: OpenLocalWalletInput): Promise<OpenLocalWalletResult>; export declare function rotateLocalPassphrase(input: { keystorePath: string; oldPassphrase: string; newPassphrase: string; }): Promise<void>;

./policies

Capability-based signer restrictions.

export { Capability } export declare function withCapability(inner: Signer, capability?: Capability): Signer; export declare function checkCapability(capability: Capability, tx: SignableTx): SessionKeyError | null; export declare function isEmptyCapability(c: Capability): boolean;

./session-key

Session key generation and attestation.

export { CreateSessionKeyInput, SessionKey, SessionAttestation } export declare function createSessionKey(input: CreateSessionKeyInput): Promise<SessionKey>; export declare function canonicalAttestationMessage(sessionAddress: Address, parent: Address, c: Capability): string;

Usage

import { initLocalWallet, signerFromKeystore, createSessionKey, withCapability, TransactionBatcher, BatchTask } from '@cfxdevkit/wallet'; // Initialize a new local wallet const { keystorePath, address } = await initLocalWallet({ keystorePath: '/path/to/keystore', passphrase: 'secure-passphrase' }); // Create a session key with limited capability const parentSigner = await signerFromKeystore({ keystorePath, passphrase: 'secure-passphrase' }); const sessionKey = await createSessionKey({ parentSigner, capability: { gasLimit: 1_000_000n, methods: ['cfx_sendTransaction'] } }); // Wrap the session key with capability enforcement const sessionSigner = withCapability(sessionKey, sessionKey.capability); // Batch multiple transactions const batcher = new TransactionBatcher(); batcher.add(BatchTask.multicall([ { to: '0x...', data: '0x...' }, { to: '0x...', data: '0x...' } ])); batcher.add(BatchTask.multisend([ { to: '0x...', value: 1n }, { to: '0x...', value: 2n } ])); const result = await batcher.execute();

API Reference

See API.md for the full public surface.

Tier

Tier 0 — framework — Must not runtime-import from any higher tier.

API Reference

.

// Package name identifier for @cfxdevkit/wallet export declare const __packageName: "@cfxdevkit/wallet"; // Represents a single task in a batched transaction operation export { BatchTask } // Configuration options for the TransactionBatcher export { TransactionBatcherOptions } // Result structure returned after executing a batch of transactions export { TransactionBatchResult } // Abstract interface for hardware wallet adapters export { HardwareWalletAdapter } // Enum-like type representing supported hardware wallet kinds export { HardwareWalletKind } // Raw EVM signature format (r, s, v components) export { RawEvmSignature } // Default derivation path for EVM-compatible addresses on hardware wallets export { EVM_DEFAULT_PATH } // Finalizes an EIP-1559 transaction with proper signature encoding export { finaliseEip1559Tx } // Array of all supported hardware wallet kinds export { HARDWARE_WALLET_KINDS } // Converts a raw signature object into its hex string representation export { rawSignatureToHex } // Converts a hex-encoded value to canonical (lowercase, 0x-prefixed) format export { toCanonicalHex } // Batches multiple transactions into a single call for improved efficiency export declare class TransactionBatcher<T = unknown> { // Constructs a new batcher instance constructor(options?: TransactionBatcherOptions); // Adds a transaction to the batch add(task: BatchTask): void; // Executes the batched transactions and returns results execute(): Promise<TransactionBatchResult<T>>; } // Error thrown when session key validation fails export declare class SessionKeyError extends CfxError { // Constructs a new SessionKeyError with optional cause constructor(message: string, cause?: Error); } // Error thrown when hardware wallet interaction fails export declare class HardwareWalletError extends CfxError { // Constructs a new HardwareWalletError with optional cause constructor(message: string, cause?: Error); } // Returns the default path to the local keystore file export declare function defaultKeystorePath(): string; // Initializes a new local wallet with a new keystore and passphrase export declare function initLocalWallet(input: InitLocalWalletInput): Promise<InitLocalWalletResult>; // Opens an existing local wallet using its keystore and passphrase export declare function openLocalWallet(input: OpenLocalWalletInput): Promise<OpenLocalWalletResult>; // Rotates the passphrase of an existing local wallet export declare function rotateLocalPassphrase(input: { keystorePath: string; oldPassphrase: string; newPassphrase: string; }): Promise<void>; // Wraps a signer with a capability restriction for fine-grained authorization export declare function withCapability(inner: Signer, capability?: Capability): Signer; // Checks whether a given capability permits signing a specific transaction export declare function checkCapability(capability: Capability, tx: SignableTx): SessionKeyError | null; // Determines if a capability is empty (i.e., grants no permissions) export declare function isEmptyCapability(c: Capability): boolean; // Creates a new session key with specified capabilities and expiration export declare function createSessionKey(input: CreateSessionKeyInput): Promise<SessionKey>; // Generates the canonical message used to attest a session key export declare function canonicalAttestationMessage(sessionAddress: Address, parent: Address, c: Capability): string; // Creates a signer from a local keystore file export declare function signerFromKeystore(input: SignerFromKeystoreInput): Promise<Signer>; // Creates a read-only signer that cannot sign transactions export declare function readonlySigner(address: Address): Signer; // Input interface for initializing a new local wallet export interface InitLocalWalletInput { keystorePath: string; passphrase: string; } // Result interface returned after initializing a local wallet export interface InitLocalWalletResult { address: Address; keystorePath: string; } // Input interface for opening an existing local wallet export interface OpenLocalWalletInput { keystorePath: string; passphrase: string; } // Result interface returned after opening a local wallet export interface OpenLocalWalletResult { address: Address; signer: Signer; } // Input interface for creating a session key export interface CreateSessionKeyInput { parentAddress: Address; sessionAddress: Address; capability: Capability; expiration?: number; } // Represents a session key with its attestation and metadata export interface SessionKey { address: Address; capability: Capability; attestation: SessionAttestation; parentAddress: Address; expiration?: number; } // Attestation data for a session key, including signature and timestamp export interface SessionAttestation { message: string; signature: string; timestamp: number; } // Input interface for creating a signer from a local keystore export interface SignerFromKeystoreInput { keystorePath: string; passphrase: string; }

Usage

import { openLocalWallet, signerFromKeystore } from '@cfxdevkit/wallet'; // Open an existing wallet const { signer } = await openLocalWallet({ keystorePath: '/path/to/keystore', passphrase: 'my-secret-passphrase' }); // Or create a signer directly from keystore const signer = await signerFromKeystore({ keystorePath: '/path/to/keystore', passphrase: 'my-secret-passphrase' });

./batcher

// Represents a single transaction task in a batch export { BatchTask } // Configuration options for the TransactionBatcher export { TransactionBatcherOptions } // Result structure returned after executing a batch of transactions export { TransactionBatchResult } // Batches multiple transactions into a single call for improved efficiency export declare class TransactionBatcher<T = unknown> { constructor(options?: TransactionBatcherOptions); add(task: BatchTask): void; execute(): Promise<TransactionBatchResult<T>>; }

Usage

import { TransactionBatcher } from '@cfxdevkit/wallet/batcher'; const batcher = new TransactionBatcher(); batcher.add({ to: 'cfx:...', value: '0x1', data: '0x' }); batcher.add({ to: 'cfx:...', value: '0x2', data: '0x' }); const result = await batcher.execute(); console.log(result.results); // Array of transaction hashes or errors

./signers

// Input interface for creating a signer from a local keystore export interface SignerFromKeystoreInput { keystorePath: string; passphrase: string; } // Creates a signer from a local keystore file export declare function signerFromKeystore(input: SignerFromKeystoreInput): Promise<Signer>; // Creates a read-only signer that cannot sign transactions export declare function readonlySigner(address: Address): Signer;

Usage

import { signerFromKeystore, readonlySigner } from '@cfxdevkit/wallet/signers'; const signer = await signerFromKeystore({ keystorePath: '/path/to/keystore', passphrase: 'secret' }); const readOnly = readonlySigner('cfx:...'); // For address-only operations

./errors

// Error thrown when session key validation fails export declare class SessionKeyError extends CfxError { constructor(message: string, cause?: Error); } // Error thrown when hardware wallet interaction fails export declare class HardwareWalletError extends CfxError { constructor(message: string, cause?: Error); }

Usage

import { SessionKeyError } from '@cfxdevkit/wallet/errors'; try { // some operation } catch (err) { if (err instanceof SessionKeyError) { console.error('Session key error:', err.message); } }

./hardware

// Abstract interface for hardware wallet adapters export { HardwareWalletAdapter } // Enum-like type representing supported hardware wallet kinds export { HardwareWalletKind } // Raw EVM signature format (r, s, v components) export { RawEvmSignature } // Default derivation path for EVM-compatible addresses on hardware wallets export { EVM_DEFAULT_PATH } // Finalizes an EIP-1559 transaction with proper signature encoding export { finaliseEip1559Tx } // Array of all supported hardware wallet kinds export { HARDWARE_WALLET_KINDS } // Converts a raw signature object into its hex string representation export { rawSignatureToHex } // Converts a hex-encoded value to canonical (lowercase, 0x-prefixed) format export { toCanonicalHex }

Usage

import { HARDWARE_WALLET_KINDS, EVM_DEFAULT_PATH } from '@cfxdevkit/wallet/hardware'; console.log(HARDWARE_WALLET_KINDS); // ['ledger', 'onekey', 'satochip'] console.log(EVM_DEFAULT_PATH); // "m/44'/60'/0'/0/0"

./hardware/onekey

// Interface describing the OneKey SDK API surface export interface OneKeySdkLike { // SDK methods for interacting with OneKey hardware wallets } // Parameters for signing a transaction on OneKey export interface OneKeyTxParams { // Transaction fields required for signing } // Core transaction parameters used internally by OneKey export interface OneKeyCoreTxParams { // Internal transaction representation } // Input interface for creating a signer from OneKey hardware wallet export interface SignerFromOneKeyInput { sdk: OneKeySdkLike; path?: string; } // Generic response type from OneKey SDK export type OneKeyResponse<T> = { success: boolean; data?: T; error?: string; }; // Creates a signer from OneKey hardware wallet export declare function signerFromOneKey(input: SignerFromOneKeyInput): Promise<Signer>; // Input interface for creating a signer from OneKey Core (non-SDK) export { SignerFromOneKeyCoreInput } // Default derivation path for OneKey Core export { CORE_DEFAULT_PATH } // Creates a signer from OneKey Core hardware wallet export { signerFromOneKeyCore }

Usage

import { signerFromOneKey } from '@cfxdevkit/wallet/hardware/onekey'; const sdk = new OneKeySdk(); const signer = await signerFromOneKey({ sdk });

./hardware/ledger

// Creates an instance of Ledger Ethereum app export { createLedgerEthApp } // Creates a Node HID transport for Ledger devices export { createNodeHidLedgerTransport } // Creates a signer from Ledger hardware wallet export { signerFromLedger } // Interface describing Ledger Ethereum app API export { LedgerEthAppLike } // Interface describing Ledger transport API export { LedgerTransportLike } // Input interface for creating a signer from Ledger export { SignerFromLedgerInput } // Input interface for creating a Ledger hardware adapter export interface LedgerHardwareAdapterInput extends Omit<SignerFromLedgerInput, 'path'> { // Additional options for adapter setup } // Creates a hardware wallet adapter for Ledger devices export declare function createLedgerHardwareAdapter(input: LedgerHardwareAdapterInput): HardwareWalletAdapter;

Usage

import { createLedgerHardwareAdapter } from '@cfxdevkit/wallet/hardware/ledger'; const adapter = await createLedgerHardwareAdapter({ path: "m/44'/60'/0'/0/0" }); const signer = adapter.signer;

./hardware/satochip

// Configuration for Satochip bridge connection export interface SatochipBridgeConfig { // Bridge connection options } // Input interface for creating a signer from Satochip export interface SignerFromSatochipInput extends SatochipBridgeConfig { // Optional path override } // Creates a signer from Satochip hardware wallet export declare function signerFromSatochip(input?: SignerFromSatochipInput): Promise<Signer>;

Usage

import { signerFromSatochip } from '@cfxdevkit/wallet/hardware/satochip'; const signer = await signerFromSatochip({ // bridge config });

./init

// Returns the default path to the local keystore file export declare function defaultKeystorePath(): string; // Initializes a new local wallet with a new keystore and passphrase export declare function initLocalWallet(input: InitLocalWalletInput): Promise<InitLocalWalletResult>; // Opens an existing local wallet using its keystore and passphrase export declare function openLocalWallet(input: OpenLocalWalletInput): Promise<OpenLocalWalletResult>; // Rotates the passphrase of an existing local wallet export declare function rotateLocalPassphrase(input: { keystorePath: string; oldPassphrase: string; newPassphrase: string; }): Promise<void>; // Input interface for initializing a new local wallet export interface InitLocalWalletInput { keystorePath: string; passphrase: string; } // Result interface returned after initializing a local wallet export interface InitLocalWalletResult { address: Address; keystorePath: string; } // Input interface for opening an existing local wallet export interface OpenLocalWalletInput { keystorePath: string; passphrase: string; } // Result interface returned after opening a local wallet export interface OpenLocalWalletResult { address: Address; signer: Signer; }

Usage

import { initLocalWallet, openLocalWallet } from '@cfxdevkit/wallet/init'; // Initialize new wallet const result = await initLocalWallet({ keystorePath: '/path/to/new/keystore', passphrase: 'new-secret' }); // Open existing wallet const { signer } = await openLocalWallet({ keystorePath: result.keystorePath, passphrase: 'new-secret' });

./policies

// Wraps a signer with a capability restriction for fine-grained authorization export declare function withCapability(inner: Signer, capability?: Capability): Signer; // Checks whether a given capability permits signing a specific transaction export declare function checkCapability(capability: Capability, tx: SignableTx): SessionKeyError | null; // Determines if a capability is empty (i.e., grants no permissions) export declare function isEmptyCapability(c: Capability): boolean;

Usage

import { withCapability, checkCapability, isEmptyCapability } from '@cfxdevkit/wallet/policies'; const baseSigner = await signerFromKeystore(...); const restrictedSigner = withCapability(baseSigner, { allowedTo: ['transfer'], maxAmount: '0x1000000000000000000' // 1 CFX }); const err = checkCapability(restrictedSigner.capability, tx); if (err) throw err;

./session-key

// Input interface for creating a session key export interface CreateSessionKeyInput { parentAddress: Address; sessionAddress: Address; capability: Capability; expiration?: number; } // Represents a session key with its attestation and metadata export interface SessionKey { address: Address; capability: Capability; attestation: SessionAttestation; parentAddress: Address; expiration?: number; } // Attestation data for a session key, including signature and timestamp export interface SessionAttestation { message: string; signature: string; timestamp: number; } // Creates a new session key with specified capabilities and expiration export declare function createSessionKey(input: CreateSessionKeyInput): Promise<SessionKey>; // Generates the canonical message used to attest a session key export declare function canonicalAttestationMessage(sessionAddress: Address, parent: Address, c: Capability): string;

Usage

import { createSessionKey } from '@cfxdevkit/wallet/session-key'; const sessionKey = await createSessionKey({ parentAddress: 'cfx:...', sessionAddress: 'cfx:...', capability: { allowedTo: ['transfer'], maxAmount: '0x1000000000000000000' }, expiration: Date.now() + 86400000 // 1 day });
Last updated on