@blinks-labs/spm
v0.1.1
Published
Solana Portfolio Manager CLI — swap, invest, trade, and predict from the terminal with a local keypair.
Readme
@blinks-labs/spm
Solana Portfolio Manager CLI — swap, invest, trade, and predict from the terminal, signing with a local Solana keypair.
npm install -g @blinks-labs/spm
# or run without installing
npx @blinks-labs/spm swap --in SOL --out USDC --amount 0.01 --simulateRequires Node.js 20+.
Commands
| Command | What it does |
| --- | --- |
| swap | Swap tokens via Jupiter |
| trade | Phoenix Eternal perps — markets, positions, orders, collateral |
| invest | Kamino Earn vaults — list, position, deposit, withdraw |
| predict | Jupiter prediction markets — events, positions, bet, close, claim |
Swap
spm swap --in SOL --out USDC --amount 0.01 [--slippage-bps 50] [--simulate] [--yes] [--json]--in / --out accept a known symbol (SOL, USDC, USDT, JUP, BONK, …) or any
base58 mint address — decimals for unknown mints are read on-chain.
The CLI prints a preview (expected output, minimum received, price impact, route,
priority fee) and asks for confirmation before signing. Use --simulate for a dry run
that never broadcasts, or --yes to skip the prompt in scripts.
$ spm swap --in SOL --out USDC --amount 0.01 --simulate
Swap on mainnet-beta
Wallet CgKa8mrAHCJ1jPPMbyoUMG9i6wn79Ea6xHrmMkSWXBfU
RPC https://api.mainnet-beta.solana.com
Pay 0.01 SOL (10000000 atomic)
Receive ~ 0.721099 USDC
Min received 0.717494 USDC (slippage 50 bps)
Price impact 0.0011%
Route GoonFi V2
Priority fee 0.000065718 SOLTrade
Perpetual futures on Phoenix Eternal. 60+ markets — crypto, equities and commodities.
spm trade markets [--filter SOL] [--limit 25] # no wallet needed
spm trade positions [--address <pubkey>]
spm trade deposit --amount 25 # USDC wallet → collateral
spm trade open --market SOL --side long --size 0.5 [--limit-price 70]
spm trade close --market SOL [--size 0.2]
spm trade cancel --market SOL
spm trade withdraw --amount 10markets needs no keypair at all, and positions --address <pubkey> reads any
wallet — handy for checking an account before you fund one.
$ spm trade markets --filter SOL
SYMBOL STATUS MAX LEV TAKER FEE
SOL active 25x 0.035%
$ spm trade open --market SOL --side long --size 0.1 --simulate
Market order — long 0.1 SOL
Wallet 5sd6f47RF9EtacmZcsBbPx2DcDDePWN8JVWfycHj3rqd
Market SOL (max 25x)
Size 0.1 SOL
Mark price 73.9100
Notional ~7.39 USDC
Taker fee ~0.0026 USDC
Margin cross (subaccount 0)Collateral is USDC, and you must deposit before your first order — that call
also creates your Phoenix trader account. Orders use cross margin against
that balance; isolated margin and TP/SL are only in the web app for now.
Phoenix perps are mainnet-only, so --cluster devnet is rejected rather than
silently trading somewhere unexpected.
Invest
Kamino Earn vaults. Deposits earn yield as the vault's share price rises; withdrawing redeems shares back to the underlying token.
spm invest vaults [--token USDC] [--limit 8] # no wallet needed
spm invest position --vault <address> [--address <pubkey>]
spm invest deposit --vault <address> --amount 10
spm invest withdraw --vault <address> [--percent 50]$ spm invest vaults --limit 3
VAULT APY TVL HOLDERS ADDRESS
Ethena PYUSD Prime 2.63% $250.69M 14 4TwKA9JX…
Sentora PYUSD 6.37% $119.21M 3604 A2wsxhA7…
Steakhouse High Yield USDG 7.21% $35.17M 674 BoZDRc1R…--percent defaults to 100, and withdrawals redeem shares directly rather than
converting through a token amount, which avoids share/token rounding.
Predict
Jupiter prediction markets. Contracts settle at $1.00, so a YES bought at $0.62 pays $1.00 if the market resolves yes — the price is the implied probability.
spm predict events [--category crypto] [--filter bitcoin] [--limit 15]
spm predict market --market <id> # or --event <id> for every market
spm predict positions [--address <pubkey>]
spm predict bet --market <id> --side yes --amount 5 [--limit-price 0.62]
spm predict close --position <pubkey> # sell back early
spm predict claim --position <pubkey> # collect a settled winBets deposit USDC by default (--token SOL|JUPUSD for the others); the minimum
order is $5. spm predict positions prints a ready-to-run claim line for any
position that has settled in your favour.
Unlike the other commands, predict never talks to RPC: Jupiter returns an
unsigned transaction, the CLI signs it locally, and Jupiter's keeper network
submits it. There is nothing to simulate, so --simulate is rejected rather
than silently ignored.
Signing
Transactions are signed locally. The keypair is resolved in this order:
--keypair <path>$SPM_KEYPAIR— path to a keypair JSON file$SPM_SECRET_KEY— base58-encoded secret key~/.config/solana/id.json
Your secret key is read from disk, used to sign in-process, and never sent anywhere — quotes go to Jupiter and only the signed transaction goes to the RPC endpoint you choose. There is no backend and no account: the CLI is non-custodial, and nothing happens on-chain without a signature from your key.
Prefer --simulate first on anything unfamiliar, and treat a keypair file used
with --yes in a script the same way you would treat any other hot wallet.
Network
By default the CLI talks directly to Jupiter, Phoenix, Kamino and a Solana RPC node. Choose an endpoint
with --rpc <url> or --cluster <mainnet-beta|devnet|testnet|localnet>. Without either,
it uses RPCFAST_URL, then ALCHEMY_API_KEY, then HELIUS_API_KEY, then the public
mainnet endpoint. Set JUPITER_API_KEY to use Jupiter's keyed host for higher rate limits.
Output
Human-readable output goes to stderr; --json emits a single JSON object on stdout, so
spm swap … --json | jq works cleanly.
Exit codes: 0 success · 2 usage/arguments · 3 keypair · 4 quote/build · 5 on-chain.
License
MIT © Blinks Labs
