How wallets are created, imported, exported, backed up, recovered, and migrated.
Generates a new BIP-39 mnemonic and derives accounts for all supported chains.
onecipher wallet create --name "agent-treasury"
onecipher wallet create --name "cold-storage" --words 24
onecipher wallet create --name "verify-once" --show-mnemonic # DANGEROUS: prints the phrase onceFlow:
- Generate 128–256 bits of cryptographically secure randomness
- Encode as BIP-39 mnemonic (12/15/18/21/24 words)
- Derive master seed via PBKDF2
- Derive one account per supported chain using each chain's BIP-44 path
- Encrypt mnemonic with vault passphrase (age scrypt)
- Write encrypted wallet file to
~/.onecipher/wallets/<uuid>.json - Wipe mnemonic, seed, and private keys from memory
- Print only public information (addresses, IDs, derivation paths)
The mnemonic is never returned to the caller unless --show-mnemonic is passed explicitly.
Import a mnemonic or a raw private key. Secrets are read from environment variables or stdin — never as CLI arguments — to avoid shell-history exposure.
# Mnemonic via stdin
echo "goose puzzle decorate ..." | onecipher wallet import --name "from-metamask" --mnemonic
# Private key via env var
ONECIPHER_PRIVATE_KEY="4c0883a691..." onecipher wallet import --name "from-evm" --private-key
# Ed25519 key (curve inferred from --chain)
ONECIPHER_PRIVATE_KEY="9d61b19d..." onecipher wallet import --name "from-sol" --private-key --chain solana
# Explicit keys for both curves
ONECIPHER_SECP256K1_KEY="4c0883a691..." \
ONECIPHER_ED25519_KEY="9d61b19d..." \
onecipher wallet import --name "both"
# Interactive prompt
onecipher wallet import --name "manual" --interactivePrivate key imports generate all chain accounts: the provided key covers its curve's chains and a random key is generated for the other curve. The key material is encrypted immediately and input buffers are zeroed.
onecipher wallet list # all wallets in the vault
onecipher wallet info # vault path + supported chainsExport operations extract key material for use with other wallet software.
onecipher wallet export --wallet agent-treasury- Mnemonic wallets output the phrase.
- Private-key wallets output JSON:
{"secp256k1":"hex...","ed25519":"hex..."}.
onecipher wallet export --wallet agent-treasury --public-key --chain ethereum
onecipher wallet export --wallet agent-treasury --public-key --compressed # secp256k1 onlyPublic keys are safe to share — no --confirm-style warnings needed.
Change a wallet's encryption passphrase without touching key material:
onecipher wallet change-password --wallet agent-treasury
# Non-interactive (falls back to ONECIPHER_PASSPHRASE / ONECIPHER_NEW_PASSPHRASE)
onecipher wallet change-password --wallet agent-treasury \
--passphrase "$OLD" --new-passphrase "$NEW"API keys are unaffected: their encrypted secret copies are derived from the API token, not the wallet passphrase.
onecipher wallet rename --wallet old-name --new-name new-name
onecipher wallet delete --wallet old-name --confirm # --confirm requiredDeletion removes the encrypted wallet file and logs the operation to the audit log. Ensure you have exported the mnemonic or private key first — deletion is not reversible.
OneCipher ships an age-encrypted .ocbk backup bundle format
(multi-X25519-recipient, ocenv/1 tag:backup envelope):
# Export an age-encrypted backup of the wallet to two recipients
onecipher backup export --out ~/backups/treasury.ocbk --recipient <age1...> [--recipient ...]
# Restore from a backup bundle (identity of one of the export recipients)
onecipher backup import --in ~/backups/treasury.ocbk --identity <AGE-SECRET-KEY-1...>The .ocbk bundle is self-contained and safe to store on any media —
it is encrypted at rest.
If the vault is lost but the mnemonic is available, re-import it:
echo "<mnemonic>" | onecipher wallet import --name "recovered" --mnemonicAll chain addresses derive deterministically from the same mnemonic at the same account index, so the recovered wallet controls the same accounts. For deeper recovery flows (scanning historical indices), derive candidate addresses offline:
echo "<mnemonic>" | onecipher mnemonic derive --chain ethereum --count 20Wallets created before the unified secret vault used keystore v3-style JSON files. Migrate them into age-encrypted vault entries:
onecipher migrate # migrate legacy wallets into the unified vault
onecipher migrate --dry-run # preview what would be migrated
onecipher migrate --rollback # remove migrated .age entries (legacy files are kept)Legacy .json files are never deleted by migration, so rollback is always
possible.
Rotate the age encryption layer itself (e.g., after adding/removing devices):
onecipher age recipient add age1newdevice...
onecipher age reencrypt # re-encrypt every entry to current recipientsThis changes who can decrypt the vault — it does not rotate blockchain keys. To rotate blockchain keys, create a new wallet and transfer assets.
┌─────────┐
│ Create │
│ Import │
└────┬────┘
│
▼
┌─────────┐
┌────▶│ Active │◀───────┐
│ └────┬────┘ │
│ │ │
Unlock Sign/Send Attach Policy
│ │ │
│ ┌────▼────┐ │
└─────│ Locked │ │
└────┬────┘ │
│ │
┌────▼────┐ ┌────┴──────────┐
│ Export │ │ change-password│
│ Backup │ │ age reencrypt │
└────┬────┘ └───────────────┘
│
┌────▼────┐
│ Delete │
└─────────┘