@candledottv/cli 0.11.14 → 0.11.15
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 +75 -26
- package/dist/index.js +830 -75
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @candledottv/cli
|
|
2
2
|
|
|
3
|
-
The Candle CLI (current version 0.11.
|
|
3
|
+
The Candle CLI (current version 0.11.15): authorize a device from your browser, keep your own keys
|
|
4
4
|
in an encrypted vault on this machine, hand an agent a TEE wallet it can trade, and manage API
|
|
5
5
|
keys, wallets, and setup health from the terminal. Zero runtime dependencies; the whole thing is
|
|
6
6
|
one self-contained `dist/index.js` that runs under plain Node.
|
|
@@ -53,7 +53,7 @@ node packages/cli/dist/index.js auth login
|
|
|
53
53
|
|
|
54
54
|
## Custody tiers
|
|
55
55
|
|
|
56
|
-
The CLI keeps keys at two custody tiers, which are not the account plans (
|
|
56
|
+
The CLI keeps keys at two custody tiers, which are not the account plans (`candle plans` lists the ones in force).
|
|
57
57
|
**Tier 1, the vault**, is `vault.enc` on your machine: keys derived from a 24-word recovery phrase,
|
|
58
58
|
opened only by a factor you present (a passphrase or a FIDO2 security key), never by an environment
|
|
59
59
|
variable or `--yes`. **Tier 2, a TEE wallet**, is a vault key promoted with `candle vault promote`
|
|
@@ -71,38 +71,45 @@ emergency procedure, rebinding, trusted wallets and API key access levels are al
|
|
|
71
71
|
| `candle auth status` | Shows which storage backend is in use, both credential prefixes, the config file path, and a live validity check for each credential. |
|
|
72
72
|
| `candle auth logout [--keep-key]` | Revokes the stored API key (skipped with `--keep-key`), clears local credentials and config, and prints the portal URL for revoking the device itself. |
|
|
73
73
|
| `candle keys list [--scopes]` | Lists this account's API keys: prefix, name, Read, Read:Write or Read:Write:Transfer access, environment, timestamps, and which device minted each one. `--scopes` adds the raw scopes, sorted. |
|
|
74
|
-
| `candle keys create [--access read\|read-write\|read-write-transfer \| --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. `--access` mints one of the portal's three levels (`read-write-transfer` is Read:Write plus `transfer:bound`: the key can move funds out of the wallet it runs, to wallets you linked while signed in or marked trusted and to that wallet's vault); `--scopes` names raw scopes instead, never both. Stored locally only if the CLI does not already hold a working key. An account holds at most 12 active keys. |
|
|
74
|
+
| `candle keys create [--access read\|read-write\|read-write-transfer \| --scopes <a,b,c>] [--label <name>] [--expires-in <days>] [--tx-limit <usd> [--reset daily\|weekly\|monthly\|never]] [--embedded-wallet deny\|allow]` | 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. `--access` mints one of the portal's three levels (`read-write-transfer` is Read:Write plus `transfer:bound`: the key can move funds out of the wallet it runs, to wallets you linked while signed in or marked trusted and to that wallet's vault); `--scopes` names raw scopes instead, never both. `--embedded-wallet` defaults to `deny`; `allow` lets the key spend the account's embedded wallet and is confirmed at a terminal. Stored locally only if the CLI does not already hold a working key. An account holds at most 12 active keys. |
|
|
75
|
+
| `candle keys access <prefix\|label\|self> (--access read\|read-write\|read-write-transfer [--yes] \| --history)` | Changes an existing key's level in place (same key, wallets and caps). Widening needs the device token and the prefix typed back at a terminal; `--yes` skips the prompt when narrowing; `self` narrows the profile's own key and can never widen it. `--history` lists the key's changes and who made them. |
|
|
76
|
+
| `candle keys update <prefix\|label> --embedded-wallet allow\|deny [--yes]`, `candle keys self embedded-wallet deny` | Allow or deny a key the account's embedded wallet, with the device token (allowing needs the prefix typed back at a terminal). `self embedded-wallet deny` lets the profile's own key give it up with no prompt; a key can never allow itself. |
|
|
77
|
+
| `candle keys signer approve <code> --key <prefix\|label> [--reject]`, `candle keys signer move <prefix\|label> [--to-key <prefix\|label>]` | Key signers for bots on a different machine from the vault. `approve` accepts (or rejects) a key's signer request with the device token, after you type the full fingerprint the trading machine printed. `move`, on the machine holding a wallet's current signer, moves every wallet on the key onto its active signer; `--to-key` moves a revoked key's wallets to a live key. |
|
|
75
78
|
| `candle keys revoke <prefix>` | Revokes an API key by prefix. Revoking the CLI's own stored key also clears it locally. |
|
|
76
79
|
| `candle keys wallets <prefix>`, `keys wallets set <prefix> --wallets <id,id>`, `keys wallets scope <prefix> --scope all\|selected` | Each key is an agent profile with its own wallet set: list it, replace it, or limit the profile to its assigned wallets. |
|
|
77
80
|
| `candle wallets` (alias `candle wallet`) | 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 and a `Trusted` column saying whether it is yours (linked while signed in, or marked with `trust`). It links and revokes; it never generates or prints a key, which the vault now derives. |
|
|
78
81
|
| `candle wallets import --chain solana\|evm`, `wallets revoke <wallet-id>` | Link a wallet you own (key from `--key-file` or a hidden prompt, sealed to Privy before it leaves the machine), or unlink one. |
|
|
79
82
|
| `candle wallets trust\|untrust <label\|address\|id\|prefix*>...` | Mark linked wallets as yours so an agent's Read:Write:Transfer key can move funds into them, or clear the mark. Owner only, over the device token, with a typed confirm; a trailing `*`, as in `'tr-*'`, selects by prefix. |
|
|
80
|
-
| `candle
|
|
81
|
-
| `candle vault
|
|
82
|
-
| `candle vault
|
|
83
|
+
| `candle wallets close-empty [--wallet embedded] [--keep <mint>]... [--yes]` | Closes the embedded wallet's empty token accounts and returns their rent to it, after a preview (`transfer:write`). |
|
|
84
|
+
| `candle vault init\|status\|list\|new-key\|rename\|phrase show\|restore\|reconcile-exposure` | The encrypted local vault, `vault.enc` (Tier 1). `init` creates it with a passphrase factor and a 24-word recovery phrase (and no key), `new-key` derives a key inside it (`--count`, `--labels-from <file>` for many under one unlock), `list [filter] [--balances]` shows one line per key, `rename` changes a label only, `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 with a new passphrase (`--count`, `--tee-count`, `--external-count`, `--evm-count` and `--evm-tee-count` for EVM keys and Hood TEE wallets, or a Solana gap scan with `--rpc-url`); a restored vault never allocates new keys. `reconcile-exposure` re-reads the account and adds exposure records, clearing nothing. No key ever leaves the vault to reach Candle. See [CLI custody](https://docs.candle.tv/developers/cli-custody). |
|
|
85
|
+
| `candle vault factor list\|add passphrase\|add security-key\|add touch-id\|add passkey\|remove` (or `vault enroll <kind>`), `vault backup --to <path>\|icloud`, `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, keeping only the passphrase and security-key envelopes, 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 (`--install-helper` fetches and verifies this release's helper first); one key is not a recoverable factor, two keys are a pair, an enrolled key can authorize adding another, and the passphrase stays the recovery floor. `add touch-id` and `add passkey` are refused with `VAULT_FACTOR_UNSUPPORTED_ON_PLATFORM` until the Apple-signed helper ships. 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. |
|
|
86
|
+
| `candle vault transfer\|promote\|promote-batch\|fund\|demote\|export-key` | Moving value and authority. `transfer` and `fund` sign locally after showing the decoded transaction (`transfer` from a vault key or a promoted TEE wallet, which warns when an agent may be trading it and reports the finalized transfer to Candle's history; `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 --from <cold label>` derives a fresh TEE wallet pinned to that key (an EVM vault key becomes a Hood TEE wallet), `promote --in-place <label> --sweep-to <cold label>` promotes a key at its own address after a typed warning, `promote-batch --pairs-from <file>` does many in place under one unlock, `--to-key` binds the result to another of your keys, and `demote` (disable then sweep; `--emergency` sweeps even when the stop request fails) sends it back to its pinned vault; `export-key` is the one ceremony that writes a single private key to a file you name. |
|
|
83
87
|
| `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). |
|
|
84
88
|
| `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. |
|
|
85
89
|
| `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`. |
|
|
86
90
|
| `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`. |
|
|
87
91
|
| `candle vault import-legacy --tee`, `candle vault retire-legacy` | Copies the wallets in an existing `tee-wallets.enc` into the vault as imported keys (the recovery phrase does not restore them), then retires the old file once the vault holds everything and a backup has been verified. |
|
|
88
|
-
| `candle tee status\|disable\|sweep\|fund` | Operate a TEE wallet (Tier 2): `status` shows its server state and on-chain balances, `disable` stops the agent (exit 0 only on a verified stop, 3 while pending), `sweep --rpc-url <url>` moves everything to the pinned vault, signed locally (closing DAMM v2 positions after verifying each server-built close; `--emergency` sweeps when the API cannot be read and moves the position NFT instead), and `fund` prints what your vault signs.
|
|
92
|
+
| `candle tee status\|disable\|sweep\|fund` | Operate a TEE wallet (Tier 2): `status` shows its server state and on-chain balances, `disable` stops the agent (exit 0 only on a verified stop, 3 while pending), `sweep --rpc-url <url>` moves everything to the pinned vault, signed locally (closing DAMM v2 positions after verifying each server-built close; `--emergency` sweeps when the API cannot be read and moves the position NFT instead), and `fund` prints what your vault signs. On a Hood wallet (0x), `status` shows ETH, USDG and the gas reserve, and `sweep` moves USDG, WETH, every `--token` and then ETH last. See [CLI custody](https://docs.candle.tv/developers/cli-custody). |
|
|
93
|
+
| `candle tee signer new --key <prefix\|label> [--out <pem>] [--force]` | On the trading machine, with that key's API key: generates the key's signer here and waits for the owner to approve it with `keys signer approve`. The key's wallets then trade from this machine. `--out` also writes a plaintext PEM for an SDK process. |
|
|
89
94
|
| `candle tee rebind <wallet...> --to-key <prefix\|label>`, `candle tee rebinds [wallet]` | Move TEE wallets to another key on the same account (owner only, preview then `confirm`; funds and the relay signer do not move), and list the rebind history. |
|
|
90
95
|
| `candle tee new\|enable` | The legacy path: `new` seals a fresh key in its own `tee-wallets.enc` and `enable <address> --vault <address>` delegates it with a pinned sweep vault. New setups use `vault promote`; `vault import-legacy --tee` migrates an existing store. |
|
|
91
|
-
| `candle swap <from> <to> --amount <n>\|--percent <n> --wallet <tee
|
|
92
|
-
| `candle swap status <id> [--kind trade\|swap\|launch]` | Read an operation without resending it. |
|
|
93
|
-
| `candle transfer --to <address\|wallet name\|vault> --asset <SOL\|USDC\|CNDL>\|--mint <mint
|
|
94
|
-
| `candle launch --name <name> --symbol <symbol> --image-url <url> --wallet <tee
|
|
95
|
-
| `candle pnl [--profile <name>]` | P&L: realized net, fees, unrealized and total, then open positions. Without `--profile`, the account's books (every profile, the web app and the CLI, one ledger; needs the Read scope). With `--profile <name>`, that profile's key's
|
|
96
|
-
| `candle portfolio [--chain solana\|hood] [--rpc-url <url>] [--evm-rpc-url <url>]` | Vault, TEE and embedded wallets on Solana and Hood in one table with chain, amount, price and value, subtotals per group and per chain, and a total. Solana vault and external balances are read over your own Solana RPC; Candle is sent only the mints, for prices. EVM vault keys are read over your own Hood RPC (`--evm-rpc-url`, else `CANDLE_EVM_RPC_URL`, else the built-in Hood RPC) for ETH and USDG only, priced by asset, never by address; an RPC on another chain is refused. An unpriced Hood token shows why (`no-market-row`, `stale-mark`, ...). `--chain` shows one chain.
|
|
96
|
+
| `candle swap <from> <to> --amount <n>\|--percent <n> --wallet <tee> [--to <tee>] [--wait]` | Quote, confirm and swap through the TEE wallet's bound key; first buy after a launch is this command. The assets decide the chain (ETH, USDG or a 0x token is Hood; SOL, USDC, CNDL or a mint is Solana). SOL or USDC to ETH or USDG, or back, is a bridge through Relay into this key's own TEE wallet on the other chain (`--to` names it when there are several); `--wait` follows it for up to ten minutes. |
|
|
97
|
+
| `candle swap status <id> [--kind trade\|swap\|launch] [--wait]` | Read an operation without resending it; `--wait` follows a bridge until it ends. |
|
|
98
|
+
| `candle transfer --to <address\|wallet name\|vault> --asset <SOL\|USDC\|CNDL\|ETH\|USDG>\|--mint <mint>\|--token <0x...> --amount <decimal\|max> [--wallet <tee>] [--rpc-url <url>] [--yes]` | Move funds out of a TEE wallet through its bound Read:Write:Transfer key, to the wallet's own pinned vault (`--to vault`, any token, `max` allowed, one SOL transfer at most the server's backstop ceiling, 50 SOL by default) or to another of the account's wallets you linked while signed in or marked trusted (a base asset, counted against the key's caps, which must include a per-asset cap and a USD `--tx-limit`). The asset decides the chain: ETH, USDG or `--token` moves from a Hood TEE wallet. The destination and its kind are shown before you confirm; Candle builds, the relay signs, Candle broadcasts. |
|
|
99
|
+
| `candle launch --name <name> --symbol <symbol> --image-url <url> --wallet <tee> [--quote-asset <asset>] [--dex-version v3\|v4]` | Create a token with no first buy; needs `launch:write`, operator-enabled `allowLaunch`, and the Pro or Max plan. The wallet decides the chain: a Hood TEE wallet launches on Hood and needs `--dex-version`. `--quote-asset` is sol, usdc or cndl on Solana, eth or usdg on Hood. |
|
|
100
|
+
| `candle pnl [--profile <name>]` | P&L: realized net, fees, unrealized and total, then open positions, the same figures the console shows. Without `--profile`, the account's books (every profile, the web app and the CLI, one ledger; needs the Read scope), with a By agent table (each key, then Manual, then the account total). With `--profile <name>`, that profile's key's share of the same P&L: realized on its sales and the open positions that belong to it, with a row per wallet that sums to the total. Each wallet is its own average-cost pool, and a recorded move between the account's wallets carries its cost. Both show a Solana block, a Hood block, then the combined figure, the closed positions as money made, minus money lost, plus partial sells, and a `CHAIN` column (and `WALLET`, where the API names it) on positions. Unpriced positions are never valued at zero; dust (worth under one cent) is marked and still counted. A bridge between Solana and Hood is not a trade, and bridge and Relay costs are not netted. DAMM v2 LP positions are included: realized (withdrawals against the cost basis at the add, plus claimed fees), unrealized (open positions at their share of the pool plus unclaimed fees, against that basis) and vs holding (what the deposited tokens would be worth held); `Total` stays the console's token figure and `Total with LP` covers tokens and LP. |
|
|
101
|
+
| `candle portfolio [--chain solana\|hood] [--rpc-url <url>] [--evm-rpc-url <url>]` | Vault, TEE and embedded wallets on Solana and Hood in one table with chain, amount, price and value, subtotals per group and per chain, and a total. Solana vault and external balances are read over your own Solana RPC; Candle is sent only the mints, for prices. EVM vault keys are read over your own Hood RPC (`--evm-rpc-url`, else `CANDLE_EVM_RPC_URL`, else the built-in Hood RPC) for ETH and USDG only, priced by asset, never by address; an RPC on another chain is refused. An unpriced Hood token shows why (`no-market-row`, `stale-mark`, ...). `--chain` shows one chain. Each TEE wallet's DAMM v2 LP positions follow the tokens, valued by Candle at the same marks, and count in the total; one whose pool could not be read is shown as not read and the total says it is partial. |
|
|
102
|
+
| `candle plans` | The plans the API serves (`GET /api/v1/agent/plans`): each plan's monthly price, agent trade fee, Hyperliquid perps builder fee, the limits a new key gets, and one row per capability (buying and selling tokens not launched on Candle, self-launch, atomic launch, linked wallets, perps, limit orders). Every number is the server's; the CLI bundles none. Needs no key and sends none. `--json` is the server's body. Your own plan is `candle doctor`'s Plan row. |
|
|
97
103
|
| `candle lp pools\|add\|positions\|remove\|claim` | Meteora DAMM v2 liquidity from a TEE wallet through its bound key (`lp:write`, opt-in). `pools <token>` lists pools with liquidity, fee, volume and an estimated yield; `add <pool> --amount <n> <token> --wallet <tee>` opens or grows a position at the pool's ratio after showing both tokens' Token-2022 warnings; `positions` lists every position across your TEE wallets; `remove <position> --percent <n>` withdraws (100% also claims fees and closes the position); `claim <position>` claims fees and rewards. No Candle fee. A `tee sweep` closes open positions itself; see TEE wallets. |
|
|
98
|
-
| `candle perps setup\|open\|close\|cancel\|orders\|positions\|leverage` | Hyperliquid perpetuals from the EVM TEE wallet bound to the key (`perps:write`, opt-in). `setup` approves Candle's builder fee (0.1%, none on Max) once; `open <coin> <long\|short> <size>` trades at market, or as a limit with `--price`, with optional `--tp` and `--sl`; `close <coin>` closes reduce-only; `cancel <cloid>`; `leverage <coin> <x> [--isolated]`; `orders` and `positions` read live. Candle builds each action within the key's limits; the CLI recomputes its hash and checks the action type and Candle's builder before anything is signed, then submits the signed action to Hyperliquid itself. `CANDLE_HYPERLIQUID_BUILDER` pins the builder. |
|
|
104
|
+
| `candle perps setup\|deposit\|open\|close\|cancel\|orders\|positions\|leverage` | Hyperliquid perpetuals from the EVM TEE wallet bound to the key (`perps:write`, opt-in). `setup` approves Candle's builder fee (0.1%, none on Max) once; `deposit <amount> <SOL\|USDC\|ETH\|USDG>` moves funds onto the Hyperliquid account through Relay from the key's Solana or Hood TEE wallet (`swap:write`; `--to` names the EVM TEE wallet from Solana; `deposit status <id>` reads it; no withdrawal yet); `open <coin> <long\|short> <size>` trades at market, or as a limit with `--price`, with optional `--tp` and `--sl`; `close <coin>` closes reduce-only; `cancel <cloid>`; `leverage <coin> <x> [--isolated]`; `orders` and `positions` read live. Candle builds each action within the key's limits; the CLI recomputes its hash and checks the action type and Candle's builder before anything is signed, then submits the signed action to Hyperliquid itself. `CANDLE_HYPERLIQUID_BUILDER` pins the builder. |
|
|
99
105
|
| `candle profile list` | Lists profiles on this machine, with cached accounts. |
|
|
100
106
|
| `candle profile add <name> --api-url <url>` | Creates a profile before authenticating it. |
|
|
101
107
|
| `candle profile use <name>` | Makes a profile the active one. |
|
|
102
108
|
| `candle profile rename <old> <new>` | Renames a profile. |
|
|
103
109
|
| `candle profile remove <name> --yes` | Deletes a profile and its stored credentials. |
|
|
104
|
-
| `candle
|
|
105
|
-
| `candle
|
|
110
|
+
| `candle profile set <name> --rpc-url <url>\|--clear-rpc-url` | Sets or clears this profile's Solana RPC, used when `--rpc-url` and `CANDLE_SOLANA_RPC_URL` are not given. Only its host is ever shown. |
|
|
111
|
+
| `candle mcp [--tools <a,b,c>] [--read-only] [--print-config]` | Runs the Candle MCP server (built into this binary) with this CLI's stored API key and API URL in its environment, so an MCP client config is just `{"mcpServers": {"candle": {"command": "/Users/you/.local/bin/candle", "args": ["mcp"]}}}` -- the absolute path, because GUI hosts launch servers with the app's environment and never see your PATH. Run `--print-config` to print that block filled in for this install. `--read-only` starts it with no key and only the six keyless read tools; `--tools` pins an explicit allowlist. The server is bundled into the binary, so the host needs nothing else installed. |
|
|
112
|
+
| `candle doctor` | Runs a full health check (runtime, backend, credentials, API reachability, credential validity, wallet delegation, the install method, the account's plan and its trade fee, and whether the `candle-fido2` security key helper is beside the binary) as a PASS/FAIL/SKIP table meant for pasting into a bug report. Exits nonzero on any FAIL. |
|
|
106
113
|
| `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. |
|
|
107
114
|
| `candle update [--check] [--to <tag>]` | Replaces this binary, and the `candle-fido2` helper beside it, with the latest signed release. Nothing is renamed until both downloads pass; the binary 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. |
|
|
108
115
|
| `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`. |
|
|
@@ -114,6 +121,8 @@ Every command accepts these global options:
|
|
|
114
121
|
| --- | --- |
|
|
115
122
|
| `--api-url <url>` | Overrides the API base URL for this invocation, beating `CANDLE_API_URL` and the stored config value. |
|
|
116
123
|
| `--profile <name>` | Act as a named profile; see Profiles below. |
|
|
124
|
+
| `--factor <id\|kind>` | Vault commands: unlock with this envelope. |
|
|
125
|
+
| `--device <id>` | Vault commands: the security key to use, by id. |
|
|
117
126
|
| `--no-verify-account` | Skips the check that the stored key belongs to the profile's account. |
|
|
118
127
|
| `--json` | Machine-readable output instead of a formatted table or summary, generally the underlying API response. One exception: `auth login`'s JSON output still omits the plaintext device token and API key, matching its human-readable summary, since login never displays either value in any mode. |
|
|
119
128
|
| `--help`, `-h` | Prints usage. |
|
|
@@ -297,7 +306,8 @@ check is skipped when
|
|
|
297
306
|
`CANDLE_API_KEY` or `CANDLE_DEVICE_TOKEN` is overriding the stored credential, when a profile has
|
|
298
307
|
no cached account or no stored key, and for the commands that only read the identity or repair it:
|
|
299
308
|
`auth login`, `auth status`, `auth logout`, `doctor`, `verify` (which acts as no identity at all:
|
|
300
|
-
two files and a signature)
|
|
309
|
+
two files and a signature), `plans` (a public read that sends no credential) and the `profile`
|
|
310
|
+
commands. `setup` is guarded, because it skips its
|
|
301
311
|
login step whenever credentials are already stored.
|
|
302
312
|
|
|
303
313
|
A pre-profile install is migrated on first run: profile `default` is created from the existing
|
|
@@ -314,7 +324,15 @@ the profile they were migrated into.
|
|
|
314
324
|
| `CANDLE_API_URL` | Overrides the API base URL, beating the stored config value (but not an explicit `--api-url` flag). |
|
|
315
325
|
| `CANDLE_PROFILE` | Selects the profile when `--profile` is not given. |
|
|
316
326
|
| `CANDLE_KEYRING_PASSPHRASE` | The passphrase for the encrypted-file backend. Without it, a non-interactive process (no TTY) fails with a clear error rather than falling back to writing plaintext; an interactive session is prompted instead. |
|
|
317
|
-
| `CANDLE_CONFIG_DIR` |
|
|
327
|
+
| `CANDLE_CONFIG_DIR` | Where `vault.enc`, `tee-wallets.enc`, credentials and config live (default `~/.config/candle`). Set it once instead of passing `--keystore`. |
|
|
328
|
+
| `CANDLE_SOLANA_RPC_URL` | Solana RPC endpoint when `--rpc-url` is not given. Beats the profile's (`candle profile set <name> --rpc-url`); the public endpoint when none is set. |
|
|
329
|
+
| `CANDLE_EVM_RPC_URL` | EVM RPC endpoint for an EVM vault key when `--rpc-url` (transfer) or `--evm-rpc-url` (list) is not given; without it the built-in Hood RPC is used. |
|
|
330
|
+
| `CANDLE_FIDO2_HELPER` | Path to the `candle-fido2` helper, when it is not beside the binary. |
|
|
331
|
+
| `CANDLE_ENCLAVE_HELPER` | Path to the signed `candle-enclave.app` helper (macOS). |
|
|
332
|
+
| `CANDLE_HYPERLIQUID_BUILDER` | `candle perps`: pins Candle's Hyperliquid builder address for the check every build passes before it is signed. |
|
|
333
|
+
| `CANDLE_HYPERLIQUID_NETWORK` | `candle perps`: set to `testnet` to trade Hyperliquid testnet. |
|
|
334
|
+
| `CANDLE_NO_UPDATE_NOTIFIER` | Set to `1` to silence the update notice. |
|
|
335
|
+
| `CANDLE_KEYSTORE_PASSPHRASE` | Refused: no command reads it, and vault and tee commands stop while it is set. |
|
|
318
336
|
| `CANDLE_ALLOW_INSECURE_HTTP` | Allows an `http://` API URL pointing at a non-loopback host. The CLI attaches a device token or API key to nearly every request, so it refuses cleartext by default. Loopback (`localhost`, `127.0.0.0/8`, `::1`) is always allowed and needs no opt-in; set this only for a trusted local endpoint that is not loopback, such as a devcontainer reaching its host. |
|
|
319
337
|
|
|
320
338
|
`CANDLE_DEVICE_TOKEN` and `CANDLE_API_KEY` together mean CI needs no storage backend at all: set
|
|
@@ -328,11 +346,11 @@ the request path, no fee, and no `--private` flag. Bring your own keys (`candle
|
|
|
328
346
|
tools (`candle <plugin>`), and sign with an external wallet (`candle sign`); the request goes from
|
|
329
347
|
your machine to the service with your key, and nothing goes to Candle.
|
|
330
348
|
|
|
331
|
-
**
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
349
|
+
**Limit orders.** `candle swap`, `candle launch`, and `candle swap status` execute swaps, bridges
|
|
350
|
+
and token launches for a TEE wallet. They never open a vault or locally sign with a TEE private
|
|
351
|
+
key; Candle builds the transaction and Privy signs it through the relay. See TEE swaps and launches
|
|
352
|
+
below. Limit orders are a REST surface only (`/api/v1/trade/agent/orders`), not in this CLI, the
|
|
353
|
+
SDK or the MCP server.
|
|
336
354
|
|
|
337
355
|
**`keys limits`.** There is no command for setting per-key spend limits, because the API route
|
|
338
356
|
that sets them (`PUT /keys/:prefix/limits`) structurally rejects a device token. It only accepts
|
|
@@ -352,7 +370,7 @@ portal's job, not this CLI's.
|
|
|
352
370
|
|
|
353
371
|
A Solana sweep keeps its reads and send preflight at or after the newest finalized slot it has observed, including retained receipts. If the RPC cannot meet that context, signing stops; choose another RPC with `--rpc-url`. A transaction refused at simulation is reported as **rejected (not broadcast)** with its program error and up to 20 sanitized log lines. Once its local pending record is cleared, re-run the sweep immediately. A failed local cleanup instead requires waiting for blockhash expiry, normally within two minutes. Later independent accounts continue after a cleared rejection, up to three rejections per run; skipped accounts and SOL are listed as `not-attempted`. Connection failures after a send remain uncertain, and the CLI never re-sends automatically. `--json` adds `signature`, `broadcast`, `rejection` and `diagnostics` to rejection residuals, and `contextFloorSlot` (or `null`) at the top level. Exit codes are unchanged.
|
|
354
372
|
|
|
355
|
-
### TEE swaps and launches
|
|
373
|
+
### TEE swaps and launches
|
|
356
374
|
|
|
357
375
|
Use the profile holding the TEE wallet's bound API key and the machine that holds its
|
|
358
376
|
relay authorization key. `--wallet` accepts its id, address or unique label. These commands
|
|
@@ -372,7 +390,7 @@ candle swap status example-launch --kind launch --json
|
|
|
372
390
|
|
|
373
391
|
`candle lp` (Meteora DAMM v2) follows the same shape: the server builds and quotes, you confirm,
|
|
374
392
|
the relay signs, and this machine broadcasts over `--rpc-url` before `/confirm` writes the ledger.
|
|
375
|
-
The bound key needs the opt-in `lp:write` scope
|
|
393
|
+
The bound key needs the opt-in `lp:write` scope. An open
|
|
376
394
|
position is swept by `candle tee sweep`: the CLI discovers the position NFT locally (Token-2022,
|
|
377
395
|
amount 1, decimals 0), fetches one unsigned close per position, verifies every close (ordered
|
|
378
396
|
keys, program allowlist, simulation, writable-account classification) before signing any, and
|
|
@@ -380,7 +398,8 @@ keys, program allowlist, simulation, writable-account classification) before sig
|
|
|
380
398
|
|
|
381
399
|
A same-chain SOL/USDC/CNDL pair uses the base-swap rail. A Solana mint paired with one
|
|
382
400
|
of those assets uses the token rail, whether on Candle's curve or graduated to Jupiter/DFlow.
|
|
383
|
-
|
|
401
|
+
A Hood pair (ETH, USDG or a 0x token) swaps on Hood; SOL or USDC to ETH or USDG, or back, is a
|
|
402
|
+
bridge between the key's own TEE wallets. Token-to-token pairs without a supported quote asset
|
|
384
403
|
are not available. Mint precision and percentage balances use `--rpc-url` or
|
|
385
404
|
`CANDLE_SOLANA_RPC_URL`; balances include both classic SPL and Token-2022 accounts.
|
|
386
405
|
Amounts use exact decimal arithmetic. `--slippage-bps` defaults to 50.
|
|
@@ -411,3 +430,33 @@ original machine retries **confirmation only** using its saved signature. It nev
|
|
|
411
430
|
or rebroadcasts. A failed or abandoned build needs a new id after checking the old operation.
|
|
412
431
|
Keep the CLI's `operations` directory with its configuration; deleting it removes the local
|
|
413
432
|
record of an attempt whose request may not have reached the server.
|
|
433
|
+
|
|
434
|
+
### Hyperliquid per-key PnL
|
|
435
|
+
|
|
436
|
+
`candle pnl --profile <name>` / SDK `getProfilePnl(keyPrefix)` / MCP `candle_get_profile_pnl`
|
|
437
|
+
read the existing `GET /api/v1/agent/keys/{prefix}/pnl`. The answer adds an optional
|
|
438
|
+
`hyperliquid` section, and the CLI prints it under **Hyperliquid**. The existing read
|
|
439
|
+
authentication applies; on an older API the section is simply absent. No additional signing, deposit or setup is needed for this read.
|
|
440
|
+
|
|
441
|
+
The section reports main-exchange perp `realizedGrossUsd` (venue `closedPnl`), signed
|
|
442
|
+
`fundingUsd` (received positive, paid negative), `feesUsd` (venue fees including builder fees;
|
|
443
|
+
rebates are negative), and `realizedNetUsd = realizedGrossUsd + fundingUsd - feesUsd`.
|
|
444
|
+
Builder fees are already included in the venue fee and are not subtracted again. These figures
|
|
445
|
+
stay separate from spot and LP totals and exclude unrealized perps, deposits and withdrawals.
|
|
446
|
+
|
|
447
|
+
Coverage is **currently bound EVM TEE wallets since the current TEE binding**,
|
|
448
|
+
shown in `byWallet` with `startTime` in epoch milliseconds. That start is the latest rebind
|
|
449
|
+
onto this key, or the wallet's creation time when it was bound then and never rebound. A
|
|
450
|
+
rebound wallet does not bring its previous key's history. A wallet-set row is not required,
|
|
451
|
+
and an older one cannot move the start earlier than the binding. Revoked and previous
|
|
452
|
+
bindings, spot and HIP-3 fills are excluded. This is a binding-period read, not lifetime or
|
|
453
|
+
order-level attribution.
|
|
454
|
+
|
|
455
|
+
Reads use the venue client's two-second cache. `userFills` is capped at 2,000 recent rows;
|
|
456
|
+
`userFunding` at 500 rows from `startTime`, and this response covers at most 20 bound
|
|
457
|
+
wallets. `truncated` flags any reached history cap or remaining wallet page; `byWallet` names
|
|
458
|
+
`fillsTruncated` and `fundingTruncated`. Funding and fills can cover different time spans when
|
|
459
|
+
capped: a partial net must not be quoted as a lifetime figure. On upstream, wallet-discovery or
|
|
460
|
+
malformed-data failure the section is `{ read: false, reason }`, without amounts; spot PnL still
|
|
461
|
+
answers. An empty successful read is `{ read: true, ... }` with zero amounts. `--json` preserves
|
|
462
|
+
the section and its coverage fields. Agent boards are outside this slice.
|