How wallets are created, imported, exported, backed up, recovered, and migrated.
Generates a new BIP-39 mnemonic and derives initial accounts.
ows wallet create --name "agent-treasury" --chain evmconst wallet = await ows.createWallet({
name: "agent-treasury",
chainType: "evm",
chains: ["eip155:8453"], // derive accounts for these chains
accountCount: 1, // number of accounts per chain
mnemonicStrength: 128 // 128 = 12 words, 256 = 24 words
});
// Returns: WalletDescriptor (never the mnemonic)Flow:
- Generate 128 or 256 bits of cryptographically secure randomness
- Encode as BIP-39 mnemonic (12 or 24 words)
- Derive master seed via PBKDF2
- Derive accounts for each requested chain using BIP-44 paths
- Encrypt mnemonic with vault passphrase (scrypt + AES-256-GCM)
- Write encrypted wallet file to
~/.ows/wallets/<uuid>.json - Wipe mnemonic, seed, and private keys from memory
- Return only the
WalletDescriptor(addresses, IDs, metadata)
The mnemonic is never returned to the caller. Only public information (addresses, IDs, metadata) is returned.
Import a raw private key (for single-chain wallets).
echo "<private-key>" | ows wallet import --name "imported" --chain evm --format rawconst wallet = await ows.importWallet({
name: "imported",
chainType: "evm",
chains: ["eip155:8453"],
keyMaterial: privateKeyBytes, // Uint8Array, wiped after import
keyType: "private_key"
});The key material is encrypted immediately and the input buffer is zeroed.
OWS supports importing from standard formats:
ows wallet import --name "from-geth" --format keystore --file ~/keystore/UTC--2024-01-01T00-00-00.000Z--abc123The importer reads the v3 JSON, wraps it in the OWS envelope, and optionally re-encrypts with the vault passphrase. If the keystore uses a different passphrase than the vault, the user is prompted for both.
ows wallet import --name "from-metamask" --format mnemonic --chain evm
# Prompts for mnemonic words interactively (never as a CLI argument)The mnemonic is entered interactively to avoid shell history exposure. It is read via stdin, encrypted, and the input buffer is zeroed.
echo "<wif-key>" | ows wallet import --name "btc-wallet" --format wif --chain bitcoinows wallet import --name "sol-wallet" --format solana-keypair --file ~/.config/solana/id.jsonReads the 64-byte keypair JSON array format used by the Solana CLI.
ows wallet import --name "sui-wallet" --format sui-keystore --file ~/.sui/sui_config/sui.keystoreReads the base64-encoded keypair array format used by the Sui CLI (sui keytool).
Export operations extract key material for use with other wallet software. They require explicit confirmation and produce a visible security warning.
ows wallet export --id 3198bc9c-... --format mnemonic
# Displays the 12/24 word mnemonic on screen
# Warning: "This mnemonic provides full access to all accounts derived from this wallet."const mnemonic = await ows.exportWallet("3198bc9c-...", {
format: "mnemonic"
});
// Returns string (12 or 24 words)
// Caller MUST handle securely and wipe from memoryows wallet export --id 3198bc9c-... --format keystore --output ~/exported.jsonExports a standard Ethereum Keystore v3 file compatible with geth, MetaMask, etc. Only works for key_type: "private_key" or single-account EVM wallets.
ows wallet export --id 3198bc9c-... --format raw --account eip155:8453:0xab16...Exports a single account's private key as hex. For mnemonic-based wallets, the specific account's key is derived and exported (not the mnemonic itself).
ows backup --output ~/ows-backup-2026-02-27.tar.gz.encCreates an encrypted archive of the entire ~/.ows/ directory:
- Tar the vault directory (excluding
logs/andstate/) - Encrypt the tar with a backup passphrase (separate from vault passphrase)
- Write to the output path
The backup is self-contained — it includes wallet files, policies, plugins, and config.
ows restore --input ~/ows-backup-2026-02-27.tar.gz.encDecrypts and extracts the backup to ~/.ows/. If the vault directory already exists, the user is prompted to merge or overwrite.
In ~/.ows/config.json:
{
"backup": {
"enabled": true,
"schedule": "daily",
"destination": "~/.ows/backups/",
"retention": 30,
"passphrase_env": "OWS_BACKUP_PASSPHRASE"
}
}If the vault is lost but the mnemonic is available:
ows wallet recover --name "recovered" --chain evm --chains eip155:8453,eip155:1
# Prompts for mnemonic interactively
# Scans for accounts with balance using gap limit of 20The recovery process:
- Accept mnemonic interactively
- Derive accounts using the chain's BIP-44 path, incrementing the index
- For each derived address, query the RPC for balance or transaction history
- Stop after 20 consecutive empty addresses (BIP-44 gap limit)
- Create a new wallet file with all discovered accounts
See "Restore from Backup" above.
See "Import > Ethereum Keystore v3" above.
ows wallet delete --id 3198bc9c-...
# Warning: "This will permanently delete the encrypted wallet file.
# Ensure you have exported the mnemonic or private key before proceeding."
# Requires --confirm flag or interactive confirmationDeletion:
- Verifies the wallet exists
- Prompts for confirmation (unless
--confirmis passed) - Securely overwrites the wallet file with random bytes before unlinking (to prevent recovery from disk)
- Removes the wallet ID from the
wallet_idsarray of all API keys that reference it - Logs the deletion to the audit log
OWS supports creating a new wallet and migrating assets from an old one:
ows wallet rotate --from old-wallet --to new-wallet --chain eip155:8453This is a convenience operation that:
- Creates a new wallet (or uses an existing one)
- Queries balances on the old wallet
- Constructs transfer transactions for all assets
- Signs and sends using the old wallet
- Verifies receipt on the new wallet
Key rotation does NOT re-encrypt the old wallet — it transfers assets to a new key.
For environments where multiple tools may create OWS wallets, a discovery mechanism helps avoid duplicate wallet creation:
// Find wallets matching criteria
const wallets = await ows.discoverWallets({
chainType: "evm",
chainId: "eip155:8453",
name: "agent-*", // glob pattern
hasPolicy: true
});The ows wallet list CLI command also supports filtering:
ows wallet list --chain evm --with-policy
ows wallet list --name "agent-*" ┌─────────┐
│ Create │
│ Import │
│ Recover │
└────┬────┘
│
▼
┌─────────┐
┌────▶│ Active │◀───────┐
│ └────┬────┘ │
│ │ │
Unlock Sign/Send Attach Policy
│ │ │
│ ┌────▼────┐ │
└─────│ Locked │ │
└────┬────┘ │
│ │
┌────▼────┐ ┌────┴────┐
│ Export │ │ Rotate │
│ Backup │ └─────────┘
└────┬────┘
│
┌────▼────┐
│ Delete │
└─────────┘