Overview
Coldstar is a command-line cold wallet for Solana. It stores your private key encrypted on an ordinary USB drive. When you sign a transaction, the key is decrypted in your computer's memory, used for about 100 microseconds, and then overwritten.
The USB drive is storage only. It doesn't run anything or sign anything itself, so any drive will do, and you can replace one whenever you like.
Coldstar is written in Python, with the parts that touch your private key written in Rust.
Not audited yet. Coldstar is in active development and hasn't had a third-party security audit. An independent audit is in progress. Until it's finished, use small amounts. Follow @buildcoldstar for updates.
Install
You need Python 3.8 or later and Rust. Coldstar runs on Windows, macOS and Linux.
With the installer
The installer checks for Python and Rust, installs whichever is missing, installs the Python dependencies and builds the Rust signer.
git clone https://github.com/devsyrem/coldstar.git cd coldstar chmod +x install.sh && ./install.sh
git clone https://github.com/devsyrem/coldstar.git cd coldstar powershell -ExecutionPolicy Bypass -File install.ps1
On macOS the installer uses Homebrew to install Python if it isn't there.
Run it
python main.py
The first run compiles the Rust signer, which takes a few minutes. Later runs start straight away.
Create a wallet
Plug in a USB drive and run python main.py. When Coldstar finds the drive, choose Flash Cold Wallet OS to USB.
This erases the drive. Everything on the selected drive is deleted. Check you've picked the right one before you confirm.
Coldstar then:
- Downloads a minimal Alpine Linux root filesystem (about 50 MB).
- Adds the Solana signing tools to it.
- Builds a bootable cold wallet layout.
- Writes it to the USB drive.
- Generates your keypair and saves it to the drive, encrypted with your passphrase.
This takes several minutes. Already have a Coldstar drive? Choose Mount USB instead to open it.
What's on the drive
wallet/ keypair.json # your private key, encrypted pubkey.txt # your public address inbox/ # transactions waiting to be signed outbox/ # signed transactions, ready to send .coldstar/ last_boot_id # used to spot a new machine or session backup/ # copies of keypair.json and pubkey.txt
keypair.json never holds your key in plain text. It holds the encrypted key, plus the salt and nonce needed to decrypt it and your public key:
{
"version": 1,
"salt": "<32 bytes, base64>",
"nonce": "<12 bytes, base64>",
"ciphertext": "<48 bytes, base64>",
"public_key": "<base58 address>"
}Someone who copies or takes the drive gets only this file. Without your passphrase they can't use it.
Send a transaction
Signing is split into three steps. Each step moves a file between the drive's folders.
Build an unsigned transaction. It's saved to inbox/.
Pick it from the inbox and enter your passphrase. The signed copy goes to outbox/.
Pick a signed transaction and send it to Solana.
Only the signature leaves the signer. The private key itself never goes over the network.
Wallet screen
Once a wallet drive is mounted, Coldstar opens a full-screen wallet in the terminal. It shows your tokens and recent transactions. Use the arrow keys to move through lists.
| Key | Action |
|---|---|
| r | Refresh balances and history |
| c | Copy your address |
| x | Copy a link to the selected transaction |
| u | Unmount the wallet drive |
| q or Esc | Quit |
How keys are protected
The code that handles your private key is a separate Rust library. The Python app hands it the encrypted key and the transaction, and gets back only the signature. The decrypted key never enters Python's memory.
| Step | What happens |
|---|---|
| Passphrase to key | Argon2id turns your passphrase into an encryption key, using 64 MB of memory, 3 passes and 4 lanes with a random 32-byte salt. This makes each password guess slow and expensive. |
| Encryption | The private key is encrypted with AES-256-GCM and a random 12-byte nonce. If the file is changed, decryption fails. |
| Locked memory | The decrypted key sits in memory locked with mlock, so the operating system can't swap it to disk. |
| Signing | The transaction is signed with Ed25519, the scheme Solana uses. The key is in plain form for about 100 microseconds. |
| Wiping | The private key, the derived key and the passphrase are overwritten with zeros. This happens even if signing fails partway through. |
What it can't protect
Coldstar is clear about what it assumes. It expects that you control the computer it runs on and that the computer isn't fully compromised.
It protects against
- A private key sitting exposed for months or years
- Backdoored hardware wallet firmware
- Tampered hardware in the supply chain
- A lost or seized USB drive
It doesn't protect against
- An operating system compromised at kernel level
- A memory dump taken at the exact moment of signing (needs root access)
- A hardware keylogger capturing your passphrase
- A cold boot attack on RAM removed within seconds
- Physical tampering with the CPU or RAM
Checks on plug-in
Each time you plug the drive into a machine, Coldstar checks it automatically:
- Works out whether this is a new machine or session.
- Checks that
keypair.jsonandpubkey.txtexist and aren't empty. - Restores either file from
.coldstar/backup/only if it's missing or damaged. - Refreshes the backups from the current good files.
What you can sign
Every asset goes through the same signing process:
- SOL transfers
- SPL tokens, including stablecoins
- Tokenized commodities such as PAXG, and tokenized stocks (xStocks)
- Staking and delegation
- Custom program instructions
Further reading
Every document from the repository is on this site. See all docs, or start with:
Found a bug or have a question? Open an issue on GitHub.