secure, offline-first hd wallet generator & transaction signing tool
a command-line utility for generating and managing hierarchical deterministic (hd) wallets with emphasis on security, memory hygiene, and ecosystem interoperability. built in rust with full phantom/solflare wallet compatibility.
- memory-safe: automatic zeroization of sensitive data (mnemonics, private keys)
- multi-chain: supports ethereum (evm) and solana (svm)
- hd wallet: bip-39 mnemonic generation with bip-44/slip-0010 derivation
- phantom compatible: slip-0010 implementation ensures solana addresses match phantom/solflare
- transaction signing: sign arbitrary payloads with keccak256 (eth) or ed25519 (sol)
- secure by default: wallet files created with 0o600 permissions (owner read/write only)
- interactive tui: user-friendly prompts with hidden password input
# clone the repository
git clone https://github.com/bit2swaz/cold-cli.git
cd cold-cli
# build release binary
cargo build --release
# binary location
./target/release/cold-bincreate a fresh wallet with a new mnemonic:
# interactive mode (recommended for first-time users)
./target/release/cold-bin generate
# generate 3 solana accounts
./target/release/cold-bin generate --count 3 --coin sol
# generate both eth and sol accounts, save to file
./target/release/cold-bin generate --count 5 --coin eth --coin sol --output-path wallet.json
# non-interactive with json output (includes private keys in console)
./target/release/cold-bin generate --count 1 --coin sol --output-path wallet.json --jsonexample output:
cold wallet generator
generating wallet...
wallet generated successfully!
mnemonic (write this down!):
supreme lava canvas loud flee useful tourist chase where cereal vivid try
generated 3 accounts:
solana [0]:
address: Dota6gPTMao785ZR2Z3KuWCTTmFMSAXqdZkQF2i9Q2jx
solana [1]:
address: Vg2ofR1cDtrKnTse7sCw2AHJWzwLAj9dfmspjQFsvy8
solana [2]:
address: 2VwRX1csLmLp6WWwvg9Cx6AaVVstXAmqdiU6XsdkqEup
wallet saved to: wallet.json
file permissions set to 0o600 (owner read/write only)
recover accounts from an existing mnemonic:
# interactive mode
./target/release/cold-bin restore
# restore 5 solana accounts from mnemonic
./target/release/cold-bin restore \
--mnemonic "your twelve word mnemonic phrase here" \
--count 5 \
--coin sol \
--output-path restored.json
# restore with passphrase (prompted interactively)
./target/release/cold-bin restore --coin eth --coin solsign a transaction payload using a saved wallet:
# interactive account selection
./target/release/cold-bin sign \
--wallet-path wallet.json \
--to Dota6gPTMao785ZR2Z3KuWCTTmFMSAXqdZkQF2i9Q2jx \
--amount 1000000example output:
transaction signing
loaded wallet with 3 accounts
available accounts:
[0] solana 0 - Dota6gPTMao785ZR2Z3KuWCTTmFMSAXqdZkQF2i9Q2jx
[1] solana 1 - Vg2ofR1cDtrKnTse7sCw2AHJWzwLAj9dfmspjQFsvy8
[2] solana 2 - 2VwRX1csLmLp6WWwvg9Cx6AaVVstXAmqdiU6XsdkqEup
select account index to sign with [0]: 0
transaction details:
from: Dota6gPTMao785ZR2Z3KuWCTTmFMSAXqdZkQF2i9Q2jx
to: Vg2ofR1cDtrKnTse7sCw2AHJWzwLAj9dfmspjQFsvy8
amount: 1000000
nonce: 1737053123
coin: solana
payload (hex): 2c00...
signature (hex):
a4f2c8b3e5d6... (128 hex chars)
| chain | standard | path | notes |
|---|---|---|---|
| ethereum | bip-44 | m/44'/60'/0'/0/i |
standard evm derivation |
| solana | slip-0010 | m/44'/501'/i'/0' |
phantom/solflare compatible |
solana uses ed25519 signatures, which require slip-0010 derivation (not bip-32). this ensures addresses generated by cold-cli match exactly with phantom and solflare wallet imports.
all sensitive data (mnemonics, private keys) are automatically zeroized when dropped:
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct WalletOutput {
pub mnemonic: String, // zeroized on drop
pub accounts: Vec<Account>, // each account's private_key zeroized
}wallet json files are created with 0o600 permissions (owner read/write only):
$ ls -la wallet.json
-rw------- 1 user user 1234 jan 16 19:25 wallet.jsonadd an additional passphrase layer for enhanced security:
# will prompt for optional passphrase
./target/release/cold-bin generate --coin solrun the complete test suite (27 tests):
# run all tests
cargo test --all
# run with output
cargo test -- --nocapture
# run specific test
cargo test test_phantom_compatibility -- --nocaptureverify solana addresses match phantom wallet:
cargo test test_phantom_compatibility -- --nocapturethis test uses the mnemonic:
"supreme lava canvas loud flee useful tourist chase where cereal vivid try"
and verifies these exact addresses:
- index 0:
Dota6gPTMao785ZR2Z3KuWCTTmFMSAXqdZkQF2i9Q2jx - index 1:
Vg2ofR1cDtrKnTse7sCw2AHJWzwLAj9dfmspjQFsvy8 - index 2:
2VwRX1csLmLp6WWwvg9Cx6AaVVstXAmqdiU6XsdkqEup
- rust 1.70+ (edition 2024)
- linux/unix (for file permission features)
cold-cli/
├── cold-lib/ # core cryptographic library
│ ├── keys.rs # bip-39 mnemonic & seed generation
│ ├── eth.rs # ethereum bip-32 derivation
│ ├── sol.rs # solana slip-0010 derivation
│ ├── wallet.rs # wallet generation/restoration
│ └── tx.rs # transaction signing
└── cold-bin/ # cli interface
├── main.rs # command handlers
└── args.rs # clap argument definitions
this tool handles private keys. always use in an offline/air-gapped environment for maximum security:
- generate wallets on an offline machine
- transfer only public addresses to online systems
- sign transactions offline, broadcast signatures online
- never expose your mnemonic or private keys
mit license - see license file
issues and pull requests welcome! for major changes, please open an issue first.
made with love by bit2swaz