@cfxdevkit/wallet
Session keys, signers, batched writes, capability policies.
Install
pnpm
pnpm add @cfxdevkit/walletScope: 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
corewallet 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-path | Exports |
|---|---|
. | 34 symbols |
./batcher | 4 symbols |
./signers | 3 symbols |
./errors | 2 symbols |
./hardware | 8 symbols |
./hardware/onekey | 5 symbols |
./hardware/ledger | 8 symbols |
./hardware/satochip | 3 symbols |
./init | 8 symbols |
./policies | 3 symbols |
./session-key | 5 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
});