Solard Documentation

Solard is a local-first Solana trading terminal and a multi-wallet CLI/SDK for memecoin traders and AI agents. It runs entirely on your machine: transactions are constructed locally against venue programs directly (no Jupiter, no aggregator), signed with keys that never leave an encrypted local SQLite database, and submitted through your own RPC, Helius Sender, or Jito.

There is one binary with two personalities:

  • solard start — boots the supervised worker fleet and the web console (live pump feed, trading, portfolio, launches, signals).
  • solard <command> — the headless CLI: wallets, groups, trades, quotes, launches, scripts. Everything the console does, scriptable.

Both read and write the same local database, so anything you do in one is visible in the other — and in any script or agent you point at it.

Design rule: the kernel is boring on purpose. It knows how to talk to venues, sign, send, and persist. Strategy — when to buy, what to snipe, how to exit — lives in your scripts, outside the kernel. The kernel never imports scripts; scripts import the kernel.

#Quickstart

Requirements

  • Bun ≥ 1.1 — solard is Bun-native (SQLite, workers, single-file compile).
  • A Helius API key (free tier works for the feed; paid for LaserStream/Sender).
  • Optional: a Jito block engine endpoint for bundles.

Install

shell
$ git clone https://github.com/7flash/solard
$ cd solard
$ bun install
$ cp .env.example .env   # then set HELIUS_RPC_URL + SOLARD_MASTER_KEY

Boot the console

shell
$ bun bin/solard.ts start --open
# workers come online, console opens at http://localhost:3000
# flags: --host 0.0.0.0 --port 4000 to serve on your LAN

First (simulated) trade

shell
$ solard import <base58_private_key> main   # encrypted with SOLARD_MASTER_KEY
$ solard token <token_ca> wif              # register + fetch metadata
$ solard quote buy wif --sol 0.5            # inspect the quote, nothing sent
$ solard buy wif -w main --sol 0.5 --simulate-only

Nothing in the steps above can spend SOL. Live execution is a separate, explicit decision — see the safety model.

#How it works

Solard is a set of independent workers supervised by bgrun, all writing into one local SQLite database, with three read surfaces on top. No worker talks to another worker; the database is the only contract.

streams (helius-logs · laserstream · pumpportal · curve-snapshots · holder-snapshots) ──▶ solard.db (tokens · trades · holders · indicators · encrypted wallets) ──▶ surfaces (web console · CLI · SDK / scripts / agents)

The worker fleet

workerkindwhat it does
server-workerserverServes the web console and the HTTP API.
helius-logsstreamStandard logsSubscribe on the pump program; parses create/trade events from logs.
helius-laserstreamstreamtransactionSubscribe over LaserStream for full parsed transactions with lower latency.
pumpportal-livestreamIndependent second opinion on the same market — used to cross-check the Helius feeds.
curve-snapshotsstreamPolls bonding-curve accounts directly for ground-truth reserves and progress.
holder-snapshotsstreamSamples largest token accounts on an interval; powers the distribution view.
metadata-repairstreamBackfills missing token metadata behind a circuit breaker (fail fast, cool down, retry).
reconcilerreconcilerCompares feeds, marks stale ingestion, repairs divergence between sources.
telegram-signalssignalsPolls configured Telegram channels and projects calls into the signals table.

Supervision & tracing

Every worker registers with bgrun with a staleness deadline — if a stream stops writing heartbeats, it's restarted, and the console shows it as degraded before your positions notice. Every operation is traced end-to-end with measure-fn: quotes, sends, confirmations, feed ingestion — all have timing spans you can inspect when something is slow.

Why multiple feeds for the same market?

Because each one lies differently. Log parsing is cheap but drops events under load; LaserStream is complete but is a different subscription model; PumpPortal is someone else's infrastructure. The reconciler's job is to notice when they disagree, and the live doctor (/api/terminal/doctor) will tell you exactly which feed is stale and since when.

#CLI reference

Everything below persists into the shared database and is immediately visible in the web console. Run solard help for the always-current version of this list.

Wallets & tokens

solard — wallets & tokens
solard import <private_key> [name]          # encrypted at rest
cat key.json | solard import --stdin [name]
solard wallets [--token <token>] [--addresses-only]
solard token <token_ca> [name] [--metadata-json <json>]
solard token set <token|ca> [--pool <address>] [--quote-mint <mint>]
solard token refresh <token|ca>
solard tokens

Groups

solard — groups
solard group create <name> [description]
solard group add <group> <wallet> [weight_bps]   # weighted sizing
solard group add-many <group> w1,w2,w3
solard group show <group>
solard group list

Prices & quotes

solard — prices
solard quote buy <token|ca> --sol 0.5      # inspect without submitting
solard price <token|ca>                    # sample current venue price
solard price average <token|ca> --period 15m
solard price watch <token...> [--interval 1s] [--period 1m]

Trading

solard — trading
solard buy <token|ca> (-w <wallet> | --wallets w1,w2 | --group <name>)
           --sol 0.5 [--slippage-bps 1500] [--sender rpc|helius|jito] [--simulate-only]

solard sell <token|ca> (-w <wallet> | --wallets w1,w2 | --group <name>)
            [--bps 10000] [--slippage-bps 1500] [--sender rpc|helius|jito] [--simulate-only]

solard claim <token|ca> -w <wallet>          # pump creator fees
solard unwrap-wsol (-w <wallet> | --group <name>)

Exactly one of --wallet, --wallets, or --group must be supplied. Group trades over --sender jito are packed as bundles, five transactions per bundle. --bps 10000 on sell means the full position; --bps 5000 is half.

Watching & transactions

solard — watch / history / ALTs
solard watch token <token|ca> [label]
solard watch wallet <wallet> [label]
solard watch program <address> [label]
solard watch list
solard history
solard jito tip-accounts
solard alt create -w <wallet>               # address lookup tables
solard alt extend <address> -w <wallet> <account...>

Scripts & workers

solard — scripts / workers
solard scripts                              # list solard.config.ts registrations
solard run <name-or-path> [flags...]
solard workers status                       # fleet health from the CLI
solard workers ensure                       # start anything that's down

#Web console

solard start --open serves the console at http://localhost:3000. It is a thin, fast view over the same database the CLI writes — SSR-rendered, keyboard-driven, no build step.

pagewhat's on it
/terminalThe live pump feed: new creates, trades, curve progress, SMA indicators, per-token holder distribution, feed-health strip.
/tradeBuy/sell forms against any registered token, wallet/group selector, sender choice, quote preview, simulation results before anything is live.
/portfolioPositions across all wallets and groups: cost basis, current venue price, unrealized PnL, claimable creator fees.
/walletsImport, group management, weights, batch SOL balances, batch fund/sweep.
/watchlistsWatched tokens, wallets, and programs with live activity.
/launchFull pump.fun launch flow: metadata upload, vanity mint, buyer-group coordination, submit mode — as a form. Launches run as background jobs with step-by-step logs.
/signalsTelegram signal projections mapped onto live token state.
/activityEverything solard has executed: sends, confirmations, errors, with measure-fn traces.

Auth

The console binds to localhost by default and needs no auth. If you serve it beyond localhost (--host 0.0.0.0), set SOLARD_WEB_TOKEN — every browser and API call must then send it as the x-solard-web-token header.

Exposure warning: the console can see wallet balances and (behind the live gate) trigger trades. Don't port-forward it to the internet; use a VPN or SSH tunnel if you need remote access.

#Venues & routing

A venue is anywhere a token can be traded. Solard ships two venue plugins and constructs their instructions manually — no aggregator in the path, which means no aggregator fees, no extra CPI depth, and quotes computed from on-chain state you fetched yourself.

pump-curve
  • pump.fun bonding curve, pre-migration
  • quote = exact curve math from the bonding account
  • buy/sell + creator-fee claims
  • launch deployments happen here
pumpswap-amm
  • PumpSwap pool, post-migration
  • quote = constant-product from pool reserves
  • buy/sell via direct AMM CPIs
  • pool + quote mint overridable per token

The route resolver

You never pick a venue by hand. For each trade the resolver reads the token's on-chain state: if the bonding curve is live and incomplete, the trade routes to pump-curve; once the token has migrated, it routes to pumpswap-amm using the stored (or auto-discovered) pool. The decision happens at quote time, so a token that migrates between your quote and your send fails loudly instead of trading against a dead curve.

Venues are a plugin interface — adding a new one means implementing quoteBuy / quoteSell / instruction builders, and every workflow, script, and console form gets it for free.

#Senders

Venue plugins produce instructions; senders get them on chain. Pick per trade with --sender.

senderpathwhen to use
rpcYour RPC's sendTransaction with priority fees.Default. Cheap, fine for anything that isn't a race.
heliusHelius Sender fast lane with a tip account.Latency-sensitive single transactions — snipes, exits. Configure HELIUS_SENDER_URL + HELIUS_TIP_ACCOUNT.
jitoBundles via a Jito block engine.Atomic group execution: 5 tx per bundle, all-or-nothing per bundle. Group buys/sells and coordinated launch buys.

Every sender path supports simulation first; --simulate-only runs the full pipeline — quote, build, simulate — and stops before broadcast, printing compute units and balance changes.

#Launching tokens

A pump.fun launch in solard is one command coordinating three phases: metadata → deployment → buyer wave.

shell
$ solard launch pump --creator dev \
    --image ./logo.png --description "..." \
    --buyer-group snipers \
    --submit-mode spam-after-market-ready \
    --sender-tps 40 --helius-tip-sol 0.01 \
    --live

Metadata

Uploaded to IPFS through the pump frontend endpoint by default, or Pinata with PUMP_METADATA_PROVIDER=pinata + a JWT. Twitter/Telegram/website/video links ride along; --hide-name supported. You can also pre-upload with solard metadata upload and pass --uri.

Vanity mints

The launcher can grind a mint keypair whose address ends in your chosen suffix (multi-threaded, runs while you prepare metadata), so your CA reads like ...pump or your ticker.

Submit modes

modebehavior
after-deploy-processedWait for the deploy tx to reach processed, then send buyer transactions. Safest, default.
spam-after-market-readyStart firing buys the instant the curve account exists, resending at --sender-tps until confirmed. For competitive launches.
fast-spamFire buys alongside the deploy without waiting. Maximum aggression, expect some failures.

Buyer-group transactions are pre-built against a prepared address lookup table (solard run prepare-pump-launch-alt) so they fit and land smaller. Every launch runs as a background job — watch it on /launch or tail the CLI output.

#Scripts & workflows

Your strategy is a TypeScript file that imports the SDK. Register it in solard.config.ts, run it with solard run, pass it flags like any command.

solard.config.ts
import { defineSolardConfig } from "solard/runner";

export default defineSolardConfig({
  scripts: {
    snipe: "./scripts/snipe.ts",
    dca:   { path: "./scripts/dca.ts", description: "laddered entries" },
  },
});
scripts/snipe.ts
import { openSolard } from "solard";

const solard = await openSolard();          // shared db + env

// wait for a launch matching a name, then buy across a group
const launch = await solard.launches.waitFor({ name: "EXACT NAME" });
const receipt = await solard.buy({
  token: launch.mint,
  group: "snipers",
  sol: 0.05,
  sender: "jito",
  live: process.argv.includes("--live"),   // simulate by default
});
console.log(receipt.signatures);

Built-in workflows

workflowwhat it composes
snipeLaunch discovery → group buy the moment the market exists.
claim-trade-sendClaim creator fees from any claim source → buy a token quoted in the same asset → deliver the guaranteed minimum output to a recipient. Venue-agnostic.
wait-launch-trade-groupBlock on a launch source, then execute a coordinated group entry with per-wallet sizing.

Workflows are plugins too — they receive a host with resolveToken, route, signer, and the sender registry, so they work on any venue that exists now or later.

#AI agents

Solard was built to be driven by agents as much as by humans. There are three integration surfaces, in order of tightness. In all three, the safety gate stays in charge: an agent cannot trade live unless you flipped SOLARD_ENABLE_LIVE_TRADES=1, no matter what it asks for.

1 · The SDK — for TypeScript agents

If your agent runs in Bun/Node, import solard directly. Everything is typed: wallet refs, token refs, group refs, quotes, receipts. This is the same code path the CLI uses.

agent.ts
import { openSolard } from "solard";

const solard = await openSolard();

// register the agent — its actions are attributed in activity logs
const agent = await solard.agents.create("scout-1", {
  wallet: "agent-hot",
  config: { maxSolPerTrade: 0.25, allowedVenues: ["pump-curve"] },
});

// read market state the workers have already indexed
const feed = await solard.terminal.feed({ limit: 50 });
const holders = await solard.terminal.holders(feed[0].mint);

// quote → decide → execute (simulated unless the gate is open)
const quote = await solard.quoteBuy(feed[0].mint, { sol: 0.1 });
if (quote.priceImpactBps < 300) {
  await agent.buy({ token: feed[0].mint, sol: 0.1, sender: "helius" });
}

2 · The CLI — for tool-calling agents

For LLM agents that execute shell tools (Claude Code, custom harnesses), the CLI is the tool set. Every command reads flags, prints structured output, and exits nonzero on failure — exactly what a tool loop wants. A minimal tool manifest:

tools for an LLM agent
solard tokens                       # list what's registered
solard price <token>                # current venue price
solard quote buy <token> --sol X    # read-only quote
solard buy ... --simulate-only      # full dry-run with balance deltas
solard buy ...                      # only works if the gate is open
solard history                      # what happened
Recommended agent posture: give the agent quote, price, and --simulate-only freely; require human confirmation (or a size-capped agent wallet) for anything live. The weight_bps on group membership and a dedicated low-balance agent wallet are your blast-radius controls.

3 · The HTTP API — for anything else

Python agents, remote orchestrators, anything that speaks HTTP — the console's API is a complete surface. See the endpoint list. Authenticate with x-solard-web-token when the token is set.

python
import requests

S = "http://localhost:3000"
H = {"x-solard-web-token": token}

feed  = requests.get(f"{S}/api/terminal/feed", headers=H).json()
quote = requests.post(f"{S}/api/trade/buy", headers=H, json={
    "token": feed["data"][0]["mint"],
    "wallet": "agent-hot",
    "sol": 0.1,
    "live": False,          # simulation; live=True requires the env gate
}).json()

#HTTP API

All routes are served by the console server. Responses use a uniform envelope: { ok, data } on success, { ok: false, error: { code, message } } on failure.

routemethodpurpose
/api/statusGETServer + gate status, versions, db path.
/api/health · /api/terminal/healthGETWorker fleet health with staleness per stream.
/api/terminal/doctorGETDeep feed diagnosis — which source is stale, last event per feed.
/api/terminal/feed · /api/pump-liveGETLive pump feed: creates, trades, curve progress.
/api/terminal/tradesGETTrade stream for a mint.
/api/terminal/curveGETBonding-curve snapshots for a mint.
/api/terminal/holders · /api/token-holdersGETHolder distribution series (the terminal chart's data).
/api/market/smaGETSMA indicator values.
/api/priceGETVenue price for a registered token.
/api/portfolio · /api/overviewGETPositions, balances, PnL across wallets/groups.
/api/wallets/importPOSTImport a wallet (encrypted at rest).
/api/groups/create · /api/groups/addPOSTGroup management.
/api/trade/buy · /api/trade/sellPOSTExecute or simulate a trade; live:true rejected unless the gate is open.
/api/launch/pumpPOSTStart a launch job; poll /api/jobs for progress.
/api/signals · /api/terminal/signalsGETTelegram signal projections.
/api/processes · /api/workers/ensureGET/POSTInspect and (re)start the worker fleet.

#Environment

variabledefaultmeaning
SOLARD_DB_PATH./solard.dbThe shared SQLite database — wallets, tokens, feed, everything.
SOLARD_MASTER_KEYRequired to import/decrypt wallets. Lose it and stored keys are unrecoverable.
HELIUS_RPC_URLPrimary RPC. RPC_ENDPOINT accepted for compatibility.
HELIUS_API_KEYUsed to derive the websocket URL for stream workers.
HELIUS_SENDER_URLHelius Sender fast-lane endpoint (regional or global).
HELIUS_TIP_ACCOUNTTip account for Sender submissions.
JITO_BLOCK_ENGINE_URLmainnet.block-engine.jito.wtfOnly when explicitly selecting the jito sender.
SOLARD_ENABLE_LIVE_TRADES0The live gate. Everything is simulation until this is 1.
SOLARD_WEB_TOKENWhen set, all console/API calls must send x-solard-web-token.
SOLARD_PUMP_FEED_SOURCEheliusPrimary feed source for the terminal.
PUMP_METADATA_PROVIDERpump-frontendIPFS provider for launch metadata; pinata needs PINATA_JWT.
SOLARD_LOG_LEVELinfomeasure-fn log verbosity.
SOLARD_MAX_JOBS100Background job retention (launches).
SOLARD_METADATA_CIRCUIT_*5 / 60000 / 10000Metadata-repair circuit breaker: failures to open, open ms, half-open retry ms.

#Safety model

Solard assumes you will eventually connect something impulsive to it — a 4am you, or an agent. The defaults are built for that.

  • Dry-run by default. SOLARD_ENABLE_LIVE_TRADES=0 ships in .env.example. Live buy, sell, and launch — CLI, console, and API alike — reject live=true until you flip it. Simulation runs the entire pipeline and reports balance deltas.
  • Keys encrypted at rest. Wallet secrets are encrypted with SOLARD_MASTER_KEY before touching disk. The key itself lives only in your environment.
  • Simulate anything. --simulate-only works on every trade path including group bundles, printing compute and slippage before you commit.
  • Blast-radius controls for agents. Dedicated low-balance agent wallets, per-wallet weight_bps in groups, and per-agent config caps.
  • Local by default. The console binds localhost. Widening it is an explicit flag, and a token gate exists for when you do.
  • Everything attributable. Every execution is logged with its origin (CLI, console, script, agent) and its full measure-fn trace on /activity.
Not financial advice. Solard is execution infrastructure. Memecoin markets are adversarial; simulate first, size for loss, and read the code — that's why it's open.