A self-custodial CLI and Electron desktop application for managing multiple Solana wallets and executing token swaps through the Jupiter aggregator. The project provides wallet generation, fund distribution, mass buy/sell operations, and an automated volume bot that cycles buy-sell pairs across configurable sub-wallets.
The project is split into two interfaces that share the same core libraries:
-
CLI -- A
citty-based command-line tool compiled to standalone platform binaries. Runs headless, suitable for servers or scripting. -
Desktop App -- An Electron application with a Vue 3 + Tailwind CSS v4 renderer. Provides a visual trading terminal with real-time stats, activity feeds, and log streaming.
Both interfaces read from and write to the same local SQLite database
(wallets.db) managed by Drizzle ORM. No data leaves the machine unless
you explicitly submits transactions to an RPC endpoint.
The Electron app spawns two isolated child processes using
utilityProcess.fork() to keep the renderer thread unblocked:
-
OperationWorker -- Handles all synchronous SQLite reads/writes and cryptographic key derivation. The main process forwards IPC requests tagged with a
crypto.randomUUID()request ID; the worker resolves them asynchronously. -
Volume Bot Worker -- A separate process forked with environment variables (
SOLANA_BOTS_INTERNAL=volume-worker). Its stdout is parsed line-by-line for structured__BOT_METRIC__:JSON events (stats, logs, activity, status), which are forwarded to the renderer viawebContents.send().
All private keys and the Jupiter API key are encrypted before being written to the local SQLite database. The encryption scheme:
| Parameter | Value |
|---|---|
| KDF | crypto.scryptSync |
| Scrypt N | 16384 |
| Scrypt r | 8 |
| Scrypt p | 1 |
| Derived key size | 32 bytes |
| Cipher | AES-256-GCM (authenticated encryption) |
| Salt | 32 bytes (random per encryption) |
| IV | 12 bytes (random per encryption) |
| Auth tag | 16 bytes (GCM integrity tag) |
| Storage layout | salt (32B) || iv (12B) || tag (16B) || ciphertext |
The encrypted payload is stored as a BLOB in the api_rpc and private_key_encrypted
column. Each encryption call generates a fresh salt and IV, so encrypting
the same key twice produces different ciphertexts. The GCM authentication
tag ensures that tampered or corrupted ciphertext is detected immediately
during decryption, rather than silently producing garbage bytes.
In the desktop app, your master password is encrypted in memory using
Electron's safeStorage API, which delegates to the operating system's
native credential store (DPAPI on Windows, Keychain on macOS,
libsecret/kwallet on Linux). The encrypted password is held in a
process-local variable and decrypted on demand when a child
process needs it. The password is never written to disk.
The database file and volume bot state files are stored at:
| Platform | Path |
|---|---|
| Linux | ~/.solana-bot/wallets.db |
| macOS | ~/.solana-bot/wallets.db |
| Windows | %APPDATA%\SolanaBot\wallets.db |
The volume bot writes its stats and PID file to the same directory:
volumeBot.pid, volumeBot.stats.json, volumeBot.ui.json.
Database migrations are generated by drizzle-kit and applied
automatically at startup. The migration files are bundled into the compiled
binaries.
Caution
wallets.db contains your encrypted private keys. Do not
delete this file unless all funds have been moved to your main wallet.
Run solana-bots --help for the full command tree. All commands require the
--password flag, which is the same master password used during initial
setup.
| Command | Description |
|---|---|
main |
Import and store the main wallet from a private key file |
create |
Generate N new sub-wallets (default: 1) |
api-rpc |
Set the Jupiter API key and Solana RPC URL |
split |
Distribute SOL from the main wallet to all sub-wallets |
drain |
Sweep all sub-wallet SOL back to the main wallet |
read-all |
Print balance and metadata for every wallet |
read |
Print balance and metadata for a single wallet by pubkey |
airdrop |
Request a devnet SOL airdrop to the main wallet |
| Command | Description |
|---|---|
buy |
Mass buy a token across N sub-wallets via Jupiter |
sell |
Mass sell a token across N sub-wallets (configurable percentage) |
out |
Liquidate every token position across all sub-wallets to SOL |
volume-start |
Start the volume bot as a background process |
volume-stop |
Stop the volume bot (sends SIGTERM, triggers mass-out) |
volume-status |
Print current volume bot stats from disk |
Provide a --help flag to see the full list of commands and usage, or for a specific command.
solana-bots --helpsolana-bots buy --helpStore the main wallet:
solana-bots main --password "mypass" --pathToPrivateKey ./my-key.jsonConfigure Jupiter API key and a custom RPC:
solana-bots api-rpc --password "mypass" --api "YOUR_KEY" --rpc "https://your-rpc.com"Create 10 sub-wallets and fund each with 0.5 SOL:
solana-bots create --password "mypass" --count 10
solana-bots split --password "mypass" --amount 0.5Mass buy a token using 5 wallets, spending 0.1 SOL each:
solana-bots buy --password "mypass" --target "TOKEN_MINT_ADDRESS" --wallets 5 --amounts 0.1Sell 100% of a token from 5 wallets:
solana-bots sell --password "mypass" --target "TOKEN_MINT_ADDRESS" --wallets 5Sell 50% of a token position:
solana-bots sell --password "mypass" --target "TOKEN_MINT_ADDRESS" --wallets 5 --percentage 50Liquidate all positions across all wallets:
solana-bots out --password "mypass"Start the volume bot (0.01 SOL per cycle, 3 wallets, 60-second TTL):
solana-bots volume-start --password "mypass" --target "TOKEN_MINT_ADDRESS" --wallets 3 --amount 0.01 --ttl 60Check status or stop:
solana-bots volume-status
solana-bots volume-stopDrain all sub-wallet funds back to the main wallet:
solana-bots drain --password "mypass"The volume bot runs a continuous loop of buy-then-sell cycles against a target token mint. On each cycle it:
- Queries eligible sub-wallets (those with sufficient SOL balance).
- Selects a rotating subset of wallets (round-robin offset).
- Executes a mass buy via Jupiter (
/orderthen/execute). - Waits for the configured interval.
- Executes a mass sell of the same token.
- Writes stats to
volumeBot.stats.jsonand emits structured events.
The loop continues until the TTL expires, a SIGTERM is received, or the
you stop it from the desktop UI. On shutdown, the bot optionally runs a
mass-out operation to close all remaining positions.
Swaps are executed through the Jupiter Swap API v2
(https://api.jup.ag/swap/v2). Each wallet's transaction follows this
sequence:
- Request a quote and serialized transaction from
GET /order. - Deserialize the base64 payload into a
VersionedTransaction. - Sign with the sub-wallet's decrypted keypair.
- Submit the signed transaction to
POST /execute.
Wallets within a batch are processed concurrently using Promise.all.
Batches are throttled by a configurable chunk size (default: 2 concurrent
wallets for buy, 1 for volume bot cycles). A fee buffer of 0.005 SOL is
reserved per wallet to prevent transactions from failing due to
insufficient gas.
The desktop app is a Electron app running a Vue 3 renderer. It connects to the same SQLite database and shared libraries as the CLI.
| View | Purpose |
|---|---|
| Onboarding | First-run wizard: password, main wallet, RPC, API key setup |
| Home | Wallet overview with balances |
| Wallets | Wallet management (create, drain, distribute) |
| Trade | Manual buy/sell/out operations |
| Volume Bot | Start/stop bot, real-time stats, activity feed, log console |
| Settings | Update RPC and Jupiter API key |
When you enter your password in the onboarding flow, it is encrypted using your OS encryption mechanism and stored in memory as a base64 string. On each IPC call that requires decryption, it then decrypts it with the same mechanism and recover the plaintext password, which is passed to the utility process. The password is not serialized, nor stored to disk.
solana-bots_1.0.0_amd64.deb
solana-bots-linux
| Artifact | Format | File |
|---|---|---|
| CLI (Linux) | Standalone binary (bun-linux) | solana-bots-linux |
| CLI (Windows) | Setup installer | SolanaBotInstaller.exe |
| CLI (macOS) | Standalone binary | solana-bots-macos |
| Desktop (Windows) | installer | Solana Bots-VERSION Setup.exe |
| Desktop (Linux, Debian) | .deb package | solana-bots_VERSION_amd64.deb |
| Desktop (Linux, Fedora) | .rpm package | solana-bots-VERSION-1.x86_64.rpm |
-
Single Jupiter DEX. All swaps route through Jupiter. There is no fallback to Raydium, Orca, or other DEXes if Jupiter is unavailable or returns unfavorable quotes.
-
Local data You must keep and protect your wallets.db database at all cost when there is funds in the sub-wallets. loosing it, will results in all your funds in them to be loss forever.
-
Password Your password cannot be recovered. It is used with AES-256-GCM to encrypt your keys. Losing your password while you still have funds in your wallets will prevent you from accessing them ever again.
-
No Code Signing Your operating system may flag this software as a virus/malware
-
No delete mechanism You cannot delete sub-wallets easily, if you want to delete a wallet list/group you need to drain all of their funds first to your main wallet, delete the
wallets.dbdatabase and start the onboarding again. -
Not Tested on macOS The software only tested on a linux (Ubuntu), and a Windows machine.
Caution
Read before using
This software is provided strictly for educational and research purposes. Do not use this application for market manipulation, wash trading, or any other illegal activities. You must ensure your usage complies with all applicable local and international laws.
I will not be responsible for any financial losses, damages, or other consequences incurred while using this application. Cryptocurrency trading carries significant risk, and the automated nature of this tool can result in rapid capital loss if misconfigured. Never trade money you can't afford to loss.
Additionally, your master password encrypts your local database and cannot be recovered. If you lose your password while funds remain in your sub-wallets, you will permanently lose access to those funds. Always drain your sub-wallets back to your main wallet before making system changes or if you risk forgetting your credentials.
This software uses cryptography technologies (AES-256-GCM and Scrypt) to secure private keys. The use, import, or export of strong encryption software is heavily restricted, regulated, or outright illegal in certain countries and jurisdictions. It is your sole responsibility to verify and comply with the cryptography laws in your country before downloading or using this software.
Apache License 2.0.