Vectr CLI: prices, tokens and the AI agent from a shell, on Robinhood Chain
Find a file
Vectr 97b5b2e7ce docs: rewrite the README for someone deciding whether to trust it, and state the real Node floor
The old README was a feature list. For a crypto CLI the first question is not
"what can it do" but "what can it do to me", so the rewrite answers that on the
first screen: four commands, 258 lines, one dependency, never signs anything.

README
------
- Centred header with .github/banner.svg (new) and badges that are all facts
  checkable from the repo: TypeScript 7.0, Node >=22.12, commander 15, one
  dependency, 258 source lines, the API host, "signs transactions: never", and
  one red badge admitting `pnpm dev` is broken on TS 7.
- "What this is" explains the whole architecture in a paragraph — commander
  parses, built-in fetch requests, print, exit — and points at src/api.ts and
  src/commands/ as the complete audit surface.
- The agent section says plainly what the key can and cannot do: it can build a
  buy, it cannot broadcast one. The signing rails and their three-layer
  allowlist live in the backend and stay there.
- Commands are now one section each with real sample output, the endpoint each
  one calls, and whether it needs a key, instead of a flag table.
- Install says outright there is no npm package and it builds from source,
  ending on `vectr price` because a keyless answer proves the network path.
  Uninstall notes the key stays in ~/.vectr/config.json until deleted.

Node floor: 18 -> 22.12
-----------------------
The README and `engines` both claimed Node 18 "because the CLI uses built-in
fetch". Wrong reason and wrong number: the real floor is the commander
dependency, which is ESM-only and needs 22.12. Someone on 18 would have
installed, built, and hit a module error with the docs telling them their
runtime was fine. Both now say >=22.12, and the website renders the same number
from src/lib/tooling.ts.

agent: tell the truth about where an unsigned transaction can go
----------------------------------------------------------------
The transaction block ended with "Sign this transaction in the Vectr terminal",
which reads as though the Terminal is the only way to use it and as though the
CLI handed something over. Neither is true: the transaction is unsigned and it
is the owner's, submittable from any wallet. Now: "Not signed. Submit it from
your wallet, or ask the same thing in the Vectr Terminal to confirm it there."

Also added pnpm-workspace.yaml with the @types/node release-age exclusion, and
bumped @types/node 25.9.1 -> 26.6.5.
2026-10-22 20:57:06 +03:00
.github docs: rewrite the README for someone deciding whether to trust it, and state the real Node floor 2026-10-22 20:57:06 +03:00
src docs: rewrite the README for someone deciding whether to trust it, and state the real Node floor 2026-10-22 20:57:06 +03:00
.gitignore init: Vectr CLI 2026-05-30 19:37:50 +03:00
LICENSE feat: default to api.vectr.bot, USD price column, git-based install docs 2026-09-22 00:40:15 +03:00
package.json docs: rewrite the README for someone deciding whether to trust it, and state the real Node floor 2026-10-22 20:57:06 +03:00
pnpm-lock.yaml docs: rewrite the README for someone deciding whether to trust it, and state the real Node floor 2026-10-22 20:57:06 +03:00
pnpm-workspace.yaml docs: rewrite the README for someone deciding whether to trust it, and state the real Node floor 2026-10-22 20:57:06 +03:00
README.md docs: rewrite the README for someone deciding whether to trust it, and state the real Node floor 2026-10-22 20:57:06 +03:00
tsconfig.json fix: replace process.exit(1) with process.exitCode + return across all commands to eliminate Windows libuv assertion crash 2026-06-03 00:41:14 +03:00

Vectr: build, launch, trade

vectr-cli

Four commands, 258 lines, one dependency. Prices, token lists and the Vectr agent from a shell. It never signs anything, which is the nicest thing you can say about a crypto CLI.

TypeScript Node commander Dependencies Lines API Signs ts-node License


What this is

A thin HTTP client over the public Vectr API, the same one the website uses. commander parses the arguments, Node's built-in fetch makes the request, the result is printed, the process exits. Every request it can make is in src/api.ts and the four files under src/commands/. There is nothing to audit that takes longer than a coffee.

The agent command is the one that matters. It sends a prompt to POST /agent/job, polls GET /agent/job/:id every 1.5 s, and prints the answer. If the answer is a transaction, the CLI prints what it is and tells you to go sign it in the Terminal. The key you give it can build a buy; it cannot broadcast one. The signing rails and their three-layer allowlist are in the backend and stay there.


Install

There is no npm package. It builds from source:

git clone https://git.vectr.bot/vectr/cli.git vectr-cli
cd vectr-cli
pnpm install
pnpm build
npm link            # puts `vectr` on PATH
vectr price         # keyless, so an answer proves the network path

Node 22.12 or newer: the commander dependency is ESM-only and needs it. Update with git pull && pnpm install && pnpm build. Uninstall with npm unlink -g @vectr/cli; your key stays in ~/.vectr/config.json until you delete it.


Commands

vectr login --key vectr_... [--url <api>]

Writes the key (and optionally a backend URL) to ~/.vectr/config.json. Keys are made at vectr.bot/profile?tab=api-keys, where read-only, read-write, IP and recipient restrictions are set at creation and cannot be widened afterwards. The CLI checks that the key starts with vectr_ and nothing else; the backend does the rest.

vectr price

ETH  $2775.87

GET /price/native. The symbol comes from the backend, so the same binary prints whatever the deployment's gas coin is. No key.

vectr tokens [-n 10] [--search <q>]

Top tokens by market cap as a fixed-width table, or a name and symbol search. Price is USD; graduated tokens get a tag. GET /tokens?limit= or GET /tokens/search?q=. No key.

vectr agent "<prompt>" [--json] [--model <id>]

vectr agent "what tokens are trending?"
vectr agent "what did my launches earn this week"
vectr agent "build a 0.01 ETH buy of the top token"
vectr agent "top 3 by mcap" --json | jq -r .response

Prints Thinking and a dot every 600 ms until the job settles. --json dumps the raw job (status, response, richData); without it you get the response text and, if the agent built a transaction, a --- Transaction --- block with the action and details and a pointer to vectr.bot/terminal to confirm it. --model passes a model id through to the backend's catalog. Each turn is billed against the key owner's credit balance.

Exit code 1 on a failed job, an API error, or a missing key. Errors go to stderr.


Configuration

~/.vectr/config.json:

{ "apiKey": "vectr_...", "apiUrl": "https://api.vectr.bot" }

VECTR_API_KEY and VECTR_API_URL are read only when the file does not set that field. The file wins. If you once ran vectr login --url https://some-dev-host and that host is gone, no environment variable will save you; edit the file. Ask how we know.


Scripting

Non-zero exit and stderr on failure, so it chains and crons:

0 * * * * vectr price >> ~/vectr-price.log 2>&1
vectr tokens -n 50 > snapshot.txt
vectr agent "top 3 by mcap" --json | jq -r .response

For anything the four commands don't do, call the API. The CLI is a formatter, not a client library.


Development

pnpm build          # tsc -> dist/, CommonJS, ES2020
node dist/index.js price

pnpm dev is ts-node src/index.ts and it does not run. TypeScript 7 removed the JS compiler API ts-node loads (Cannot read properties of undefined (reading 'fileExists')). Build and run dist/ instead; the build takes about a second.

The version string is hard-coded as 1.0.0 in src/index.ts, separately from package.json. They agree today.


Layout

src/
  index.ts            commander program, four subcommands
  api.ts              getApiClient(): config + env resolution, get/post with X-API-Key
  config.ts           ~/.vectr/config.json read and write
  commands/
    login.ts
    agent.ts          job submit, poll, print, transaction block
    price.ts
    tokens.ts
dist/                 tsc output, gitignored, what `bin` points at

Skeletons in the closet

  • Six of the seven source files start with a UTF-8 byte-order mark. tsc strips it, so the shebang in dist/index.js survives and the binary runs; the diffs just look haunted.
  • pnpm dev has been dead since the TypeScript 7 bump in commit 5775f08. The script is still in package.json, and the old README told you to use it.
  • --model suggests claude-opus-4-7 in its help text. The backend's default is claude-sonnet-5, and it has a catalog of nine. The help text picked a favourite and never updated it.
  • process.exit() in getApiClient is a deliberate process.exitCode = 1 followed by a bare process.exit(), because process.exit(1) tripped a libuv assertion on Windows. Commit 4090f75 has the story. Every other error path sets exitCode and returns.
  • The agent poll has no timeout. A job that never settles is a CLI that never exits. Ctrl+C is the timeout.

License

MIT. Says so in three places and they all agree, which is more than the other repos manage.