Guide: Format WIF Base58 Private Key for ElizaOS EVM Configuration
If the ElizaOS EVM plugin rejects your private key, you are likely passing a Wallet Import Format (WIF) Base58 string. Viem requires a strict 64-character hexadecimal scalar prefixed with 0x. To fix this, you must decode the Base58 string, strip the checksum and version bytes, and inject the raw hex directly into your .env configuration.
Programmatic Conversion Script
Execute this Node.js script using bs58 to securely format your payload:
const bs58 = require('bs58');
function wifToHex(wifKey) {
const decoded = bs58.decode(wifKey);
// Strip version byte (first) and checksum (last 4 bytes)
const privateKeyBytes = decoded.slice(1, decoded.length - 4);
return '0x' + Buffer.from(privateKeyBytes).toString('hex');
}
console.log("EVM_PRIVATE_KEY:", wifToHex('5KxpX...YourWifHere'));
Architectural Context: Viem Validation and Cryptographic Scalars
ElizaOS orchestrates EVM transactions using the viem library, which relies on the @noble/curves engine for secp256k1 operations. This stack expects the EVM_PRIVATE_KEY to map directly to a mathematical scalar point on the elliptic curve.
Wallet Import Format (WIF) was designed for human readability and error-checking in older Bitcoin-derived clients, wrapping the underlying bytes in Base58 encodings and appending checksums. Passing a WIF string into a modern EVM validation engine triggers an immediate type rejection because the parser reads invalid non-hexadecimal characters (like G, H, Z). Operators building automated security infrastructure, such as those checking an elizaos agent wallet maximum notional usdc limits security config, frequently encounter this format crash during initial .env boot logic.
The Anatomy of a WIF Private Key
To understand why ElizaOS fails, we must dissect the WIF structure. A standard uncompressed WIF key (starting with 5) or a compressed WIF key (starting with K or L) is not a raw key; it is a serialized object containing:
- Version Byte: For Bitcoin mainnet, this is
0x80. - The Private Key: 32 bytes of raw entropy (the scalar).
- Compression Flag (Optional): A
0x01byte appended to the key if it corresponds to a compressed public key. - Checksum: 4 bytes derived from a Double-SHA256 of the previous bytes.
When you use the bs58.decode() function, you are reversing the Base58 encoding into a Buffer. However, viem’s privateKeyToAccount function performs a strict length check. If you pass the decoded buffer without stripping the version byte and checksum, the length will be 37 bytes (uncompressed) or 38 bytes (compressed). Viem specifically looks for 0x + 64 hex characters (32 bytes). Any deviation results in a InvalidHexError or SizeExceeds32Bytes exception.
Deep Dive: @noble/curves and secp256k1
Underneath viem, the @noble/curves library handles the elliptic curve cryptography (ECC). The secp256k1 curve used by Ethereum (and consequently ElizaOS) defines a private key as any integer between 1 and n - 1, where n is the order of the curve.
In hex, this order is approximately 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141. When the ElizaOS EVM plugin initializes, it calls hexToBytes() on your .env string. If that string is WIF-encoded, the characters outside the 0-9, a-f range cause the parser to fail before it even reaches the curve validation logic. By converting to raw hex, you are providing the engine with the exact scalar needed to derive the public key point $P = k \times G$ (where $k$ is your private key and $G$ is the generator point).
Preventative Maintenance: Automated Configuration Parsing
To prevent formatting errors from halting your AI agent infrastructure, you must move beyond manual string manipulation and implement a robust configuration lifecycle.
1. Zod-Based Environment Validation
Instead of relying on raw process.env calls, implement a validation schema using Zod. This ensures that the agent refuses to boot if the key is incorrectly formatted, providing immediate feedback during deployment.
import { z } from 'zod';
const envSchema = z.object({
EVM_PRIVATE_KEY: z.string().regex(/^0x[a-fA-F0-9]{64}$/, {
message: "EVM_PRIVATE_KEY must be a 64-char hex string prefixed with 0x. WIF is not supported."
}),
NODE_ENV: z.enum(["development", "production"]),
});
export const ENV = envSchema.parse(process.env);
2. Pre-Flight Interceptors and Dockerization
Add an entrypoint.ts validation hook in your Docker container that automatically parses, validates, and reformats any .env keys from WIF to Hex before passing them to the ElizaOS plugin logic. This is particularly useful for teams migrating legacy wallets that were generated in WIF-standard environments.
Production Check-list:
- Hex-Length Enforcement: Use strict regex (
/^0x[a-fA-F0-9]{64}$/) to block the container boot process immediately if a key is too long or missing the0xprefix. - Checksum Verification: If your conversion script detects a 37/38 byte array after Base58 decoding, it should perform a Double-SHA256 checksum validation to ensure the key wasn’t corrupted during copy-paste.
- Vault Derivation: Instead of storing raw strings in
.envfiles, use a secure vault (like HashiCorp Vault or AWS Secrets Manager) that outputs derived raw hexadecimal buffers directly to the runtime memory via an API call.
3. Security Policies for Key Management
In a production-grade ElizaOS deployment, private keys should be treated as ephemeral or strictly vaulted assets.
- Least Privilege Execution: The wallet associated with the
EVM_PRIVATE_KEYshould only hold the minimum amount of capital required for the agent’s immediate tasks. Use an elizaos agent wallet maximum notional usdc limits security config to enforce this. - No-Logging Policy: Ensure that your conversion scripts and ElizaOS logs do not inadvertently print the private key scalar. Use a custom logger that masks strings matching the 64-character hex pattern.
- Hardware Fallback: For high-value operations, avoid passing raw hex keys altogether. Configure the ElizaOS EVM plugin to use a hardware-backed signer or a Multi-Party Computation (MPC) solution where the “key” is never fully present in the
.envfile.
Advanced FAQ: Technical Contextual Analysis
How does the WIF checksum actually protect the key?
The WIF format appends a 4-byte checksum calculated as the first four bytes of SHA256(SHA256(version + key)). When a wallet or conversion script decodes the Base58 string, it re-calculates this hash. If a single character in the WIF string was mistyped (e.g., changing a 5 to a 6), the checksums will not match, and the script will throw an error before an invalid private key is ever used to attempt a signature.
Why does Viem require the ‘0x’ prefix if it’s already hex?
The 0x prefix is a standard in the Ethereum ecosystem (EIP-55 and beyond) to explicitly distinguish hexadecimal strings from decimal or other numeric formats. Inside the viem source code, the isHex utility checks for this prefix. Without it, the library may interpret the string as a decimal value if it only contains digits, or throw a type error if it contains a-f characters without the explicit hex indicator.
Can ElizaOS support BIP-39 mnemonics instead of raw hex keys?
Yes, but the underlying implementation still converts that mnemonic into a hex scalar. Using viem, the flow is mnemonicToAccount(mnemonic). This effectively derives the 512-bit seed, applies the m/44'/60'/0'/0/0 derivation path, and extracts the 32-byte private key. Using a mnemonic is often safer than raw hex for human backup, but for CI/CD and autonomous nodes, a raw hex scalar (or a vault reference) is the standard interface.