@candledottv/cli 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -6
- package/dist/index.js +46057 -41857
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -59,11 +59,18 @@ node packages/cli/dist/index.js auth login
|
|
|
59
59
|
| `candle keys create [--scopes <a,b,c>] [--label <name>] [--expires-in <days>] [--tx-limit <usd> [--reset daily\|weekly\|monthly\|never]]` | Creates a new API key and prints the plaintext exactly once, with the same optional name, expiration, and USD transaction limit the portal's create form takes. Stored locally only if the CLI does not already hold a working key. |
|
|
60
60
|
| `candle keys revoke <prefix>` | Revokes an API key by prefix. Revoking the CLI's own stored key also clears it locally. |
|
|
61
61
|
| `candle wallets` | Shows the account's embedded (launch) wallets and any linked wallets, using the API key, with a `Signer` column saying whether this machine holds each linked wallet's signing key. |
|
|
62
|
-
| `candle vault init\|status\|new-key\|phrase show\|restore` | The encrypted local vault, `vault.enc`. `init` creates it with a passphrase factor and a 24-word recovery phrase, `new-key` derives a key inside it, `phrase show` displays the phrase on a terminal (never in `--json`, a log or a pipe), and `restore --phrase` rebuilds the derived keys on another machine. No key ever leaves the vault to reach Candle. See [The vault](https://docs.candle.tv/developers/cli#the-vault). |
|
|
62
|
+
| `candle vault init\|status\|new-key\|phrase show\|restore` | The encrypted local vault, `vault.enc`. `init` creates it with a passphrase factor and a 24-word recovery phrase, `new-key` derives a key inside it, `phrase show` displays the phrase on a terminal (never in `--json`, a log or a pipe), and `restore --phrase` rebuilds the derived keys on another machine (`--count`, `--tee-count`, `--external-count`, or a gap scan with `--rpc-url`). No key ever leaves the vault to reach Candle. See [The vault](https://docs.candle.tv/developers/cli#the-vault). |
|
|
63
63
|
| `candle vault factor list\|add passphrase\|add security-key\|add touch-id\|add passkey\|remove`, `vault backup --to <path>`, `vault verify-backup <path>` | What can open the vault, and proving a copy of it works: `backup` verifies the copy in full before reporting (a copy is sealed to the passphrase envelope unless it goes to a recognised local disk or removable drive, so a cloud folder and any path the CLI cannot place are both sealed unless `--accept-shared-domain` is passed), and `verify-backup` re-checks an existing one against this vault's key and address set. `add security-key` enrolls a FIDO2 security key (CTAP2 `hmac-secret`, user-verified with the key's PIN or biometric) through the bundled `candle-fido2` helper; one key is not a recoverable factor, two keys are a pair, and the passphrase stays the recovery floor. Every vault command then takes `--factor <id\|passphrase\|security-key>` to say which envelope opens it and `--device <id>` to name the key when several are attached. |
|
|
64
|
-
| `candle vault transfer\|promote\|fund\|demote\|export-key` | Moving value and authority. `transfer` and `fund` sign locally from a vault key after showing the decoded transaction; `promote` turns a vault key into a delegated TEE wallet (fresh, or the key's own address after a typed warning) and `demote` sweeps it back; `export-key` is the one ceremony that writes a single private key to a file you name. |
|
|
64
|
+
| `candle vault transfer\|promote\|fund\|demote\|export-key` | Moving value and authority. `transfer` and `fund` sign locally from a vault key after showing the decoded transaction (`fund` reaches a TEE wallet from its pinned vault key, or an external wallet, and confirms the destination's last six characters with no `--yes`); `promote` turns a vault key into a delegated TEE wallet (fresh, or the key's own address after a typed warning) and `demote` sweeps it back; `export-key` is the one ceremony that writes a single private key to a file you name. |
|
|
65
|
+
| `candle external new\|list\|sweep` | External wallets for outside tools: keys on the vault's third branch (`m/44'/501'/n'/2'`), never delegated to Privy and never registered with Candle. `new` allocates one (and moves the vault to format version 3; refused in a restored vault), `list` shows them, and `sweep <external> --to <vault>` sends everything back to a named vault key, signed locally, confirming the vault key's last six characters. See [Bring your own services](https://docs.candle.tv/developers/cli#bring-your-own-services). |
|
|
66
|
+
| `candle sign [--file <path>] --wallet <external>... [--broadcast] [--yes]`, `candle sign message --wallet <external> [--file <path>] [--yes]` | The generic signer: a base64 transaction any tool built, legacy or v0, decoded (lookup tables resolved) and simulated over your own RPC before it is displayed and signed with an external wallet only. A vault key, a TEE wallet or an unnamed signer is refused; a failing simulation is refused with no override; `--yes` skips the confirmation prompt and nothing else. `sign message` signs the exact bytes of a file or of stdin. |
|
|
67
|
+
| `candle secrets set\|list\|remove <name>` | Your own third-party API keys, in a keychain namespace separate from Candle's credentials (`tv.candle.cli.secrets`, or `secrets.enc` on the encrypted-file fallback). Typed on a hidden prompt, never sent to Candle, never printed after `set`; `list` shows names only. A plug-in receives one as `CANDLE_SECRET_<NAME>` only when named with `--secret`. |
|
|
68
|
+
| `candle plugins`, `candle <name> [--secret <name>]... [--wallet <label>]... [args]` | Git-style plug-ins: an executable `candle-<name>` on your `PATH` runs as `candle <name>` with an allowlist environment built from empty (`PATH`, `HOME`, `TMPDIR`, `TERM`, `TZ`, `LANG`, `LC_*`, the proxy variables, `CANDLE_PLUGIN_NETWORK`, `CANDLE_PLUGIN_RPC_URL`, the named wallets as `CANDLE_PLUGIN_WALLET_<LABEL>` and the named secrets as `CANDLE_SECRET_<NAME>`). No parent `CANDLE_*` variable, no Candle credential, no passphrase and no private key ever reach it; `--secret` and `--wallet` are stripped from its argv and everything else passes through verbatim. `plugins` lists what is on `PATH`. |
|
|
65
69
|
| `candle vault import-legacy --tee`, `candle vault retire-legacy` | Moves an existing `tee-wallets.enc` into the vault without deleting it, then retires the old file once the vault holds everything and a backup has been verified. |
|
|
66
70
|
| `candle tee new\|enable\|fund\|status\|disable\|sweep` | A dedicated, capped TEE wallet for one agent: the CLI generates the key and seals it locally in `tee-wallets.enc`, `enable` delegates it to this profile's API key with a pinned sweep vault, `fund` prints what your vault signs, and `disable` then `sweep` stop the agent and move everything back to the vault, signed locally. Solana only. See [TEE wallets](https://docs.candle.tv/developers/cli#tee-wallets). |
|
|
71
|
+
| `candle swap <from> <to> --amount <n>\|--percent <n> --wallet <tee>` | Quote, confirm and swap on Solana through the TEE wallet's bound key; first buy after a launch is this command. |
|
|
72
|
+
| `candle swap status <id> [--kind trade\|swap\|launch]` | Read an operation without resending it. |
|
|
73
|
+
| `candle launch --name <name> --symbol <symbol> --image-url <url> --wallet <tee>` | Create a Solana token with no first buy; needs `launch:write` and operator-enabled `allowLaunch`. |
|
|
67
74
|
| `candle profile list` | Lists profiles on this machine, with cached accounts. |
|
|
68
75
|
| `candle profile add <name> --api-url <url>` | Creates a profile before authenticating it. |
|
|
69
76
|
| `candle profile use <name>` | Makes a profile the active one. |
|
|
@@ -73,6 +80,8 @@ node packages/cli/dist/index.js auth login
|
|
|
73
80
|
| `candle doctor` | Runs a full health check (runtime, backend, credentials, API reachability, credential validity, wallet delegation) as a PASS/FAIL/SKIP table. Exits nonzero on any FAIL. |
|
|
74
81
|
| `candle verify <file> --bundle <path> [--identity <uri>] [--issuer <url>]` | Verifies a release asset's Sigstore bundle against the trusted root compiled into this binary. No network, no credentials, and nothing else installed: the bundle carries the certificate and the transparency-log entry. `--identity` defaults to the release identity for the version in a `latest.json` sitting beside the bundle; `--issuer` defaults to GitHub Actions'. Prints `verified: <identity>` and exits 0, or the reason on stderr and exits 1. |
|
|
75
82
|
| `candle update [--check] [--to <tag>]` | Replaces this binary with the latest signed release. The download is renamed over the running binary only after its SHA-256 matches both SHA256SUMS and `latest.json` AND its Sigstore bundle verifies in process against that exact version's release workflow. `--check` reports what is available and installs nothing; `--to <tag>` pins a release (an older one installs, with a warning). A Homebrew or npm install is left alone, with the command that owns it printed instead. |
|
|
83
|
+
| `candle completion <zsh\|bash\|fish>` | Prints a shell completion script to stdout, generated from the same data `candle help` prints, so it offers exactly the commands, subcommands and flags the help documents. Install it by redirecting: `candle completion zsh > "${fpath[1]}/_candle"`, `candle completion bash > ~/.local/share/bash-completion/completions/candle`, `candle completion fish > ~/.config/fish/completions/candle.fish`. Static: profile names, key labels and factor ids are not completed, because that would mean reading config or opening the vault at tab time. Regenerate after every `candle update`. |
|
|
84
|
+
| `candle help [<command>]` | The top-level screen (six groups of command words, the global flags, and every environment variable the CLI reads), or one command's own: its subcommands, the flags they share, examples, and the environment it reads. `candle <command> --help` is the same screen. Reads no config and makes no request, so it answers before any profile is selected. |
|
|
76
85
|
|
|
77
86
|
Every command accepts these global options:
|
|
78
87
|
|
|
@@ -129,6 +138,12 @@ guarantee is unconfirmed: a wallet stop whose remote enforcement is still pendin
|
|
|
129
138
|
enabled without verified signing authority, or a sweep that left a residual). Treat `3` as not
|
|
130
139
|
done: follow the printed next step, usually re-running the same command.
|
|
131
140
|
|
|
141
|
+
A failure envelope is `{ ok: false, code, message }`, with an optional one-line `suggestion` and,
|
|
142
|
+
where a refusal carries facts worth acting on, an optional nested `details`. A vault that is not
|
|
143
|
+
where the command looked answers with `details: { path, pathSource: "flag" | "env" | "default" }`,
|
|
144
|
+
so an agent can retry against the right file without parsing the message. Keys are added, never
|
|
145
|
+
removed, and `code` values never change; `message` and `suggestion` are prose and may.
|
|
146
|
+
|
|
132
147
|
A generated vault passphrase is shown once on the terminal and never inside a JSON value, so
|
|
133
148
|
`vault init` and `vault factor add passphrase` under `--json` take `--own-passphrase` (typed at a
|
|
134
149
|
hidden prompt, nothing shown) and refuse the generated form with exit `2`. Prompts themselves are
|
|
@@ -272,10 +287,17 @@ both and every command works without ever touching a keychain or the encrypted f
|
|
|
272
287
|
|
|
273
288
|
## What this CLI deliberately does not do
|
|
274
289
|
|
|
275
|
-
**
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
290
|
+
**A built-in integration with any third-party exchange or privacy service.** Candle is never a
|
|
291
|
+
party to a transaction you make elsewhere: no Candle API key for the service, no Candle server in
|
|
292
|
+
the request path, no fee, and no `--private` flag. Bring your own keys (`candle secrets`), your own
|
|
293
|
+
tools (`candle <plugin>`), and sign with an external wallet (`candle sign`); the request goes from
|
|
294
|
+
your machine to the service with your key, and nothing goes to Candle.
|
|
295
|
+
|
|
296
|
+
**Launch, trade, and order commands.** `candle swap`, `candle launch`, and `candle swap status`
|
|
297
|
+
execute same-chain Solana swaps and token launches for a TEE wallet. They never open a vault or
|
|
298
|
+
locally sign with a TEE private key; Candle builds the transaction and Privy signs it through the
|
|
299
|
+
relay. See TEE swaps and launches below. Order-book commands stay with the SDK and MCP, not this
|
|
300
|
+
CLI.
|
|
279
301
|
|
|
280
302
|
**`keys limits`.** There is no command for setting per-key spend limits, because the API route
|
|
281
303
|
that sets them (`PUT /keys/:prefix/limits`) structurally rejects a device token. It only accepts
|
|
@@ -290,3 +312,55 @@ a sibling device. A device token cannot list or revoke devices, including itself
|
|
|
290
312
|
device token. Sibling device prefixes are not themselves secret: they appear in `keys list`'s
|
|
291
313
|
"minted by" column, which is attribution and grants no capability. Device management is the
|
|
292
314
|
portal's job, not this CLI's.
|
|
315
|
+
|
|
316
|
+
### TEE swaps and launches (Phase 3)
|
|
317
|
+
|
|
318
|
+
Use the profile holding the TEE wallet's bound API key and the machine that holds its
|
|
319
|
+
relay authorization key. `--wallet` accepts its id, address or unique label. These commands
|
|
320
|
+
never open or locally sign with a vault or TEE private key. Candle builds the transaction,
|
|
321
|
+
and Privy signs it through Candle's relay. The server's scopes, raw/USD caps and atomic
|
|
322
|
+
budget reservation apply to the human and the agent alike. Wide routes require the server's
|
|
323
|
+
`TEE_WIDE_ROUTES_ENABLED=1`; it remains off by default.
|
|
324
|
+
|
|
325
|
+
```sh
|
|
326
|
+
candle swap SOL USDC --amount 0.1 --wallet trading --client-trade-id lunch-1
|
|
327
|
+
candle swap <mint> SOL --percent 25 --wallet trading --rpc-url https://your-solana-rpc --yes --json
|
|
328
|
+
candle launch --name Example --symbol EX --image-url https://example.com/token.png \
|
|
329
|
+
--wallet trading --rpc-url https://your-solana-rpc --client-trade-id example-launch
|
|
330
|
+
candle swap status lunch-1
|
|
331
|
+
candle swap status example-launch --kind launch --json
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
A same-chain SOL/USDC/CNDL pair uses the base-swap rail. A Solana mint paired with one
|
|
335
|
+
of those assets uses the token rail, whether on Candle's curve or graduated to Jupiter/DFlow.
|
|
336
|
+
Cross-chain and EVM pairs are refused. Token-to-token pairs without a supported quote asset
|
|
337
|
+
are not available. Mint precision and percentage balances use `--rpc-url` or
|
|
338
|
+
`CANDLE_SOLANA_RPC_URL`; balances include both classic SPL and Token-2022 accounts.
|
|
339
|
+
Amounts use exact decimal arithmetic. `--slippage-bps` defaults to 50.
|
|
340
|
+
|
|
341
|
+
Before signing, the command displays venue, price impact, tier fee, minimum received and
|
|
342
|
+
all returned token warnings. Missing price impact is explicitly **unavailable**, never zero.
|
|
343
|
+
`--yes` skips the ordinary prompt but still prints warnings. With `--json`, stdout is one
|
|
344
|
+
JSON result containing the quote; the preview and operation id go to stderr. Launch creation
|
|
345
|
+
has no price impact or token receipt, shows its maximum SOL debit, and makes no first buy.
|
|
346
|
+
Use a separate swap for that buy.
|
|
347
|
+
|
|
348
|
+
Swaps require `swap:write`. Launch requires `launch:write` **and** operator-enabled
|
|
349
|
+
`allowLaunch` on the wallet. The operator sets or clears it through the shipped
|
|
350
|
+
`PUT /api/v1/agent/wallets/<id>/capabilities` endpoint with device/session authentication and
|
|
351
|
+
`{"capability":"allowLaunch","enabled":true}`. An agent key cannot grant itself this permission.
|
|
352
|
+
|
|
353
|
+
For scripts, always supply a stable `--client-trade-id` for each intention. Otherwise the CLI
|
|
354
|
+
generates and prints one. Reusing an existing id reads its status instead of rebuilding.
|
|
355
|
+
The local operation marker survives restarts and prevents concurrent CLI invocations from
|
|
356
|
+
starting the same id twice. Base swaps additionally claim build and submission atomically in
|
|
357
|
+
Convex and keep the payer signature before broadcast, surviving an API restart. A timeout
|
|
358
|
+
or an unconfirmed signature is **not** permission to create a replacement transaction.
|
|
359
|
+
`swap status` never resends writes. Use `--kind trade|swap|launch` when an id exists on
|
|
360
|
+
multiple rails or when querying from another machine with limited scopes.
|
|
361
|
+
|
|
362
|
+
For a launch whose broadcast/confirm response was lost, rerunning the same launch id on the
|
|
363
|
+
original machine retries **confirmation only** using its saved signature. It never rebuilds
|
|
364
|
+
or rebroadcasts. A failed or abandoned build needs a new id after checking the old operation.
|
|
365
|
+
Keep the CLI's `operations` directory with its configuration; deleting it removes the local
|
|
366
|
+
record of an attempt whose request may not have reached the server.
|