Onchain Solana First Trade¶
Use this tutorial to make a small Onchain Solana trade from the CLI. It starts with read-only Solana checks, uses preview before live submission, and ends with post-trade reconciliation.
Onchain (Solana) trading is experimental. Keep first trades small and use explicit SPL mint addresses for token trades.
Prerequisites¶
Update the CLI when you intend to replace the installed binary:
State change: Upgrade the installed Bullpen CLI.
Then check auth before trading:
Run bullpen login only when status or auth diagnostics say login is required.
Then enable Solana:
State change: Enable the experimental Solana command group.
Fund your Bullpen-managed Solana wallet through the web app deposit flow:
After the deposit settles, refresh balances:
Example refreshed balance output
Find a Token¶
Search by symbol or name, then inspect the exact mint:
bullpen solana search WIF --output json
bullpen solana token <MINT> --output json
bullpen solana price <MINT> --output json
Use the mint address from search output. Do not use a ticker alone for buy,
sell, swap, SPL withdraw, limit-order, or DCA commands. Native SOL withdrawal
is different: omit --token instead of passing a mint. General reads such as
balance, portfolio, and unfiltered history do not require a mint.
Check Token Risk¶
Review token risk before previewing a buy:
Continue only when the risk warnings, holder concentration, developer context, and token metadata match your tolerance. Treat missing risk fields as incomplete evidence, not as a clean bill of health.
Solana token trades and SPL withdrawals require base58 SPL token mint
addresses. Use bullpen solana search <SYMBOL> for discovery, then pass the
returned mint to buy, sell, swap, limit-buy, limit-sell,
dca create, or withdraw --token; symbols such as BONK are not accepted
as trade inputs. Native SOL withdrawal omits --token.
Preview the Buy¶
Preview returns a Jupiter Ultra quote without signing or submitting a transaction:
Review the input amount, output amount, route, price impact, slippage, fees, and any shield warnings.
Example buy preview output
Default slippage is 50 bps. Use --slippage-bps only when you have reviewed
the route and price impact.
Submit the Buy¶
Run the live command only after the preview matches your intent:
Live: Run the buy preview first. Submit only when the route, mint, amount, slippage, and warnings match your intent.
The live path signs with the Bullpen-managed Turnkey Solana signer and submits
through Bullpen's Solana transaction path. If the command reports an auth or
signing-session error, run bullpen status --output json and
bullpen doctor auth --output json; run bullpen login only when diagnostics
or the failed command says login is required. Then rerun the same preview
before submitting again.
Example live buy output shape
{
"kind": "solana_swap_result",
"success": true,
"status": "confirmed",
"signature": "5Zk...abc",
"tx_signature": "5Zk...abc",
"readback_status": "confirmed",
"receipt_status": "confirmed",
"input_mint": "EPjF...Dt1v",
"input_symbol": "USDC",
"input_amount": "5",
"output_mint": "<MINT>",
"output_symbol": "TOKEN",
"output_amount": "1234.56",
"input": {
"mint": "EPjF...Dt1v",
"symbol": "USDC",
"amount": "5"
},
"output": {
"mint": "<MINT>",
"symbol": "TOKEN",
"amount": "1234.56"
},
"slot": 341234567
}
Reconcile After Submission¶
Refresh balances and inspect recent activity:
bullpen solana balance --refresh --output json
bullpen solana history --limit 10 --output json
bullpen solana orders --output json
balance --refresh is the preferred post-trade check because it requests a
portfolio refresh and overlays fresh on-chain SOL and SPL-token balances when a
Solana RPC source is available. JSON output includes freshness.status,
freshness.source, freshness.on_chain_proven, freshness.checked_at_ms, and
freshness.warning.
Treat freshness.status: "fresh" with on_chain_proven: true as the strongest
post-fill proof. If the CLI returns pending_indexer_refresh, the command kept
the portfolio cache and attached a warning because it could not prove the latest
on-chain state through RPC. Wait briefly and run the refresh again before
submitting another live buy or declaring cleanup failed.
When a live swap report returns success: true, the transaction landed even if
readback_status is readback_pending or readback_failed. If you need to
sell the received token immediately, run:
Match the live report signature against entries[].signature, then use the
matching received.amount for the cleanup sell. Do not size cleanup from a
stale balance snapshot.
Sell or Swap Back¶
Preview the exit first. If you plan to use rate-limit retry for the live sell, include it in the preview too so the documented intent matches:
bullpen solana sell <MINT> <TOKEN_AMOUNT> --preview --retry-after-rate-limit --output json
bullpen solana swap <MINT> EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v <TOKEN_AMOUNT> --preview --output json
Submit only after reviewing the route:
Live: Submit only after the matching sell preview shows the intended route, mint, amount, slippage, and rate-limit retry behavior.
--retry-after-rate-limit waits for Jupiter's returned cooldown and retries
once when the first live submit was rate-limited before a transaction signature
existed. It does not replay a transaction after a signature or receipt exists.
If the sell succeeds but leaves only sub-cent residual token dust, the live JSON
report includes post_swap_dust; leave that dust alone unless the balance grows
enough for a normal sell route.
Native SOL as the input side of a live sell or swap may require a Jupiter
auxiliary signature that Bullpen cannot provide. If the CLI returns
SOLANA_SWAP_UNSUPPORTED_ROUTE, use an SPL-token input route or retry with a
USDC-to-token flow.
Preview Limit Orders¶
Use a limit order when you want Jupiter Trigger to buy or sell only at a target
price. Preview first; the preview builds the request without signing or
submitting.
Jupiter Trigger requires at least about $5 per limit order. The examples below
use the minimum valid size; smaller orders return
SOLANA_TRIGGER_ORDER_TOO_SMALL before signing or provider submission.
bullpen solana limit-buy <MINT> 5 --price <USD> --preview --output json
bullpen solana orders --status active --output json
bullpen solana cancel-order <ORDER_KEY> --preview --output json
Submit or cancel only after you review the preview:
Live: Submit or cancel only after the matching preview shows the intended mint, price, amount, order key, and route.
bullpen solana limit-buy <MINT> 5 --price <USD> --yes --output json
bullpen solana cancel-order <ORDER_KEY> --yes --output json
orders is read-only. Use the order key returned by orders or by the live
create response; do not invent one from the token mint. Live limit-order JSON
results expose kind, success, status, order_key, signature, and the
compatibility aliases order and tx_signature. After a live cancel, run
bullpen solana balance --refresh --output json before relying on returned
funds.
Preview DCA¶
Use DCA when you want Jupiter Recurring to split a USDC-to-token buy over time.
--per-cycle is in input-token units. For USDC input, --per-cycle 50 means
50 USDC per cycle. --cycles must be between 2 and 1000; invalid cycle counts
return SOLANA_DCA_INVALID_CYCLES before Jupiter is called.
bullpen solana dca create EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v <MINT> --per-cycle 50 --cycles 4 --interval 1d --preview --output json
bullpen solana dca list --status active --output json
bullpen solana dca cancel <ORDER_KEY> --preview --output json
Jupiter Recurring enforces provider-side minimums. If the CLI reports
SOLANA_DCA_MINIMUM_PER_CYCLE, increase --per-cycle or use a normal preview
buy instead.
After a live DCA create, inspect index_status in JSON output. If the schedule
is still indexing, the CLI returns index_status: "index_timeout" on create or
SOLANA_DCA_INDEX_PENDING on cancel with retry_after_secs and next_command.
Wait before retrying and run bullpen solana dca list --all --output json
before creating another schedule. Live DCA JSON results expose kind,
success, status, order_key, signature, and tx_signature. After a live
cancel, run bullpen solana balance --refresh --output json before relying on
returned funds.
Troubleshooting¶
| Symptom | What to run |
|---|---|
| Solana command is hidden | bullpen experimental enable solana |
| Balance looks stale | bullpen solana balance --refresh --output json |
| Jupiter rate limited the route | Read next_command_after, wait for retry_after_secs, rerun preview, then retry the same live command only if the preview is still acceptable. Use --retry-after-rate-limit for unattended cleanup after a confirmed buy or swap. |
| Signing session expired | Run bullpen status --output json and bullpen doctor auth --output json; run bullpen login only when diagnostics or the failed command requires login |
| Token ticker is ambiguous | bullpen solana search <QUERY> --output json and use the mint |
| Live route is unsupported | Use an SPL-token route or a USDC-to-token buy |
See Onchain (Solana) for the full command surface and current limitations.
Use generated references for exact flags:
buy,
sell,
swap,
history,
limit-buy,
orders,
cancel-order,
dca create,
dca list,
dca cancel,
token risk,
token hide, and
token unhide.