@chainberry/berry-keys
v1.0.1
Published
HD wallet generation for multiple blockchain networks — EVM, BTC, BCH, LTC, SOL, TRX, XRP, TON
Maintainers
Readme
BerryKey
HD wallet generation library for multiple blockchain networks. Generates BIP39 mnemonics and derives wallet addresses and private keys for every supported chain from a single mnemonic.
Built on TrustWallet WalletCore.
Installation
npm install @chainberry/berry-keysInstall peer dependencies for the chains you need:
# Required for all chains:
npm install @trustwallet/wallet-core
# LTC testnet only:
npm install bitcoinjs-lib ecpair tiny-secp256k1
# TON only:
npm install @ton/core @ton/crypto @ton/tonSupported Chains
EVM (ETH, BNB, POL, AVAX, ARB, OP, BASE, SONIC), Bitcoin, Litecoin, Solana, TRON, XRP Ledger, TON — mainnet and testnet for all.
Usage
Generate a mnemonic
import { generateMnemonic } from "@chainberry/berry-keys";
const mnemonic = await generateMnemonic();
// 24-word BIP39 phrase — store this encrypted, never in plaintextDerive a wallet
import { deriveWallet } from "@chainberry/berry-keys";
const { address, privateKey } = await deriveWallet(mnemonic, "ETH");
const { address, privateKey } = await deriveWallet(mnemonic, "BTC");
const { address, privateKey } = await deriveWallet(mnemonic, "SOL");
const { address, privateKey } = await deriveWallet(mnemonic, "TON");
const { address, privateKey } = await deriveWallet(mnemonic, "TRX");
const { address, privateKey } = await deriveWallet(mnemonic, "XRP");
const { address, privateKey } = await deriveWallet(mnemonic, "LTC");
// EVM chains all share the same address
const { address, privateKey } = await deriveWallet(mnemonic, "BNB");
const { address, privateKey } = await deriveWallet(mnemonic, "ARB");
const { address, privateKey } = await deriveWallet(mnemonic, "OP");
const { address, privateKey } = await deriveWallet(mnemonic, "BASE");
const { address, privateKey } = await deriveWallet(mnemonic, "AVAX");
const { address, privateKey } = await deriveWallet(mnemonic, "SONIC");Testnet
const { address, privateKey } = await deriveWallet(mnemonic, "BTC", { isMainnet: false });
const { address, privateKey } = await deriveWallet(mnemonic, "LTC", { isMainnet: false }); // tltc1...isMainnet defaults to true.
Address or private key only
import { getAddress, getPrivateKey } from "@chainberry/berry-keys";
const address = await getAddress(mnemonic, "ETH");
const privateKey = await getPrivateKey(mnemonic, "ETH");Full Example — Generate and sign
BerryKey derives the key, @chainberry/berry-signer signs the transaction. They are designed to work together.
import { generateMnemonic, deriveWallet } from "@chainberry/berry-keys";
import { signEvmTransaction } from "@chainberry/berry-signer";
// 1. Generate mnemonic once per vault — encrypt and store it
const mnemonic = await generateMnemonic();
// 2. Derive wallet for the chain
const { address, privateKey } = await deriveWallet(mnemonic, "ETH");
// 3. Sign a transaction
const signedTx = await signEvmTransaction(privateKey, {
to: "0xRecipient...",
chainId: 1,
nonce: 5,
gasLimit: "21000",
maxFeePerGas: "30000000000",
maxPriorityFeePerGas: "1000000000",
value: "10000000000000000", // 0.01 ETH in wei
});
// 4. Broadcast (server-side or directly)
await fetch("/api/broadcast", {
method: "POST",
body: JSON.stringify({ signedTx, network: "ETH" }),
});API
generateMnemonic(): Promise<string>
deriveWallet(mnemonic: string, chain: Chain, options?: { isMainnet?: boolean }): Promise<{
address: string;
privateKey: string; // 32-byte hex, no 0x prefix
}>
getAddress(mnemonic: string, chain: Chain, options?: { isMainnet?: boolean }): Promise<string>
getPrivateKey(mnemonic: string, chain: Chain): Promise<string>
type Chain =
| "BTC" | "LTC"
| "ETH" | "BNB" | "POL" | "AVAX" | "ARB" | "OP" | "BASE" | "SONIC"
| "SOL" | "TRX" | "XRP" | "TON";Notes
WalletCore initialization — WalletCore is a WebAssembly module. The first call to deriveWallet initializes it automatically and caches it for all subsequent calls (~200ms on first call, near-instant after).
EVM addresses — ETH, BNB, POL, AVAX, ARB, OP, BASE, and SONIC all derive from the same path and produce the same address. This is standard EVM behavior — one address works across all EVM networks.
LTC testnet — WalletCore has no native LTC testnet support. Testnet derivation uses bitcoinjs-lib internally, which is why it requires additional peer dependencies. LTC mainnet uses WalletCore only.
TON address format — Returns the non-bounceable format (UQ...). Use this when receiving funds for the first time or from exchanges. Bounceable addresses (EQ...) can cause funds to bounce if the wallet contract is not yet deployed on-chain.
Private key format — All private keys are returned as 64-character hex strings (32 bytes, no 0x prefix), compatible directly with @chainberry/berry-signer.
Security
The mnemonic is the master key — it controls every wallet derived from it. Losing it means losing access to all funds, permanently.
- Never log the mnemonic or private key
- Always encrypt the mnemonic before storing (KMS or AES-GCM)
- Never send the mnemonic or private key over the network
- Generate keys in a secure environment (hardware enclave, KMS-backed vault, or client-side)
License
MIT
