@candledottv/cli 0.13.15 → 0.13.17

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.
Files changed (3) hide show
  1. package/README.md +35 -12
  2. package/dist/index.js +1804 -943
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -34,6 +34,11 @@ after the server accepted, the command prints address-keyed rows (`<address> <ne
34
34
  under `--json`) to run again: the old label no longer resolves on the server, and a re-run leaves
35
35
  the server label alone and finishes the vault.
36
36
 
37
+ `candle tui [--profile <name>]` opens Candle Harness in an interactive terminal. Install it
38
+ from the [Candle Harness releases](https://github.com/candledottv/harness/releases) and add
39
+ `candle-harness` to PATH. The CLI looks for `candle-harness` first, then falls back to
40
+ `candle-tui` for older installs; if neither is found, it prints the release link.
41
+
37
42
  ## Quick start
38
43
 
39
44
  ```
@@ -48,6 +53,12 @@ or with Homebrew:
48
53
  Then: candle setup
49
54
  ```
50
55
 
56
+ The installer checks the download's SHA-256 and its Sigstore signature before it writes anything,
57
+ and needs nothing beyond `curl` and `sha256sum` or `shasum`. It checks the signature with `cosign` or
58
+ a signed-in `gh` when one is installed, and otherwise with Candle's own `candle verify`, offline, from
59
+ a CLI release whose SHA-256 the script carries (it downloads that `candle` and checks it against the
60
+ SHA-256 before running it). If no check can run, it installs nothing.
61
+
51
62
  `candle setup` authorizes this device from your browser, shows the agent wallets as funding
52
63
  destinations, prints the skill and MCP install lines, and runs a full health check. `candle auth
53
64
  login` on its own does just the authorization step.
@@ -80,6 +91,10 @@ vault key with `candle tee sweep` or `candle vault demote`. Promoting, moving fu
80
91
  emergency procedure, rebinding, trusted wallets and API key access levels are all in
81
92
  [Custody tiers: the vault and TEE wallets](https://docs.candle.tv/developers/cli-custody).
82
93
 
94
+ The recovery phrase ceremony (`vault init`'s offer or `vault phrase show`) waits for you to save
95
+ all 24 words offline and press Enter, then clears the screen before asking for three randomly
96
+ chosen words from your saved copy. Clear your terminal's scrollback too: the CLI cannot erase it.
97
+
83
98
  ## Commands
84
99
 
85
100
  | Command | What it does |
@@ -89,8 +104,9 @@ emergency procedure, rebinding, trusted wallets and API key access levels are al
89
104
  | `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. |
90
105
  | `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. |
91
106
  | `candle keys list [--scopes]` | Lists this account's API keys: prefix, name, Read, Write or Withdraw access, environment, timestamps, and which device minted each one. `--scopes` adds the raw scopes, sorted. |
92
- | `candle keys create [--access read\|write\|withdraw \| --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 (`write` trades and launches and cannot move funds; `withdraw` is Write plus `transfer:write` and `transfer:bound`: the key can move funds between your own wallets and to addresses you approved, and 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 25 active keys. |
107
+ | `candle keys create [--access read\|write\|withdraw \| --scopes <a,b,c>] [--label <name>] [--expires-in <days>] [--tx-limit <usd> [--reset daily\|weekly\|monthly\|never]] [--embedded-wallet deny\|allow] [--no-store]` | 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 (`write` trades and launches and cannot move funds; `withdraw` is Write plus `transfer:write` and `transfer:bound`: the key can move funds between your own wallets and to addresses you approved, and 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. `--no-store` prints the new key without saving it or changing the profile's working key or metadata; `--json` reports `stored: false`. An account holds at most 25 active keys. |
93
108
  | `candle keys access <prefix\|label\|self> (--access read\|write\|withdraw [--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. |
109
+ | `candle keys limits <prefix> <asset>=<raw> [<asset>=<raw> ...]` | Sets a key's per-asset caps (`sol`, `usdc`, `cndl`, `eth`, `usdg`, in base units per transaction) with the profile's own API key. It can only tighten; raising or removing a cap is `LOOSEN_REQUIRES_SESSION`, and the owner does that in the web key manager. A device token cannot set these caps. |
94
110
  | `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. |
95
111
  | `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. |
96
112
  | `candle keys stop <prefix>` | Pause one key using the device token. Its requests are refused with `PROFILE_PAUSED` until resumed; the key and its local credential are kept. Repeating the command succeeds. |
@@ -103,10 +119,10 @@ emergency procedure, rebinding, trusted wallets and API key access levels are al
103
119
  | `candle wallets authorize` | Gives agents access to the account's embedded wallets. The grant is yours to make in a browser (each wallet's owner is you, so neither the CLI nor the API can attach Candle's signer): this opens the Agents page's grant-only step, creates no key, and with an API key waits until the wallets show as delegated. On a new account, run it before `candle auth login`. |
104
120
  | `candle wallets trust\|untrust <label\|address\|id\|prefix*>...` | Mark linked wallets as yours so an agent's Withdraw 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. |
105
121
  | `candle wallets allow-launch\|disallow-launch <label\|address\|id\|prefix*>...` | Deprecated. Where the server has `TEE_LAUNCH_BY_SCOPE_ENABLED` on, a key's `launch:write` decides TEE launches: `allow-launch` saves the value and exits 0, and `disallow-launch` saves it, prints the server's `ALLOW_LAUNCH_NOT_ENFORCED` message and exits 1, because no launch is stopped. A server with the switch off still lets TEE wallets pay for a launch (`candle launch`) only after `allow-launch`. Owner only, over the device token; the screen shows each wallet's label, address and bound key before a typed confirm. `disallow-launch --yes` skips the confirm. |
106
- | `candle wallets close-empty [--wallet embedded\|<tee address\|label>] [--keep <mint>]... [--yes]` | Closes a wallet's empty token accounts and returns their rent to it, after a preview: the embedded wallet (`transfer:write`), or a Solana TEE wallet bound to the key (`swap:write`), whose close transactions Candle builds, this machine checks and the key signer approves. |
107
- | `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). |
122
+ | `candle wallets close-empty [--wallet embedded\|<tee address\|label>] [--keep <mint>]... [--client-trade-id <id>] [--preview] [--yes]` | Closes a wallet's empty token accounts and returns their rent to it, after a preview: the embedded wallet (`transfer:write`), or a Solana TEE wallet bound to the key (`swap:write`), whose close transactions Candle builds, this machine checks and the key signer approves. `--preview` prints what would close — the whole preview as one JSON document on stdout under `--json` — and closes, signs and prompts nothing; headless without `--yes`, the `CONFIRMATION_REQUIRED` refusal carries that same preview under `details`. |
123
+ | `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), labels its read-back derivation as verification, and leaves security-key enrollment to the separate optional `candle vault enroll security-key` command; `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). |
108
124
  | `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. |
109
- | `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, with no `--yes`; both verify once, at the unlock, which names the send, then show the destination grouped in fours and take a typed `confirm`); `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. `demote` takes several addresses, or `--all --empty` for every Solana TEE wallet with nothing left to sweep, under one unlock and one typed `confirm` (`--yes` skips it), with a result line per wallet and one `--json` document. |
125
+ | `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, with no `--yes`; both verify once, at the unlock, which names the send, then show the destination grouped in fours and take a typed `confirm`); `promote --from <cold label>` derives a fresh TEE wallet pinned to that key (an EVM vault key becomes a Hood TEE wallet), shows the pinned vault address and asks you to type `confirm` to promote the new wallet (promotion moves no funds), `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. `demote` takes several addresses, or `--all --empty` for every Solana TEE wallet with nothing left to sweep, under one unlock and one typed `confirm` (`--yes` skips it), with a result line per wallet and one `--json` document. |
110
126
  | `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, confirmed by a typed `confirm` after the vault key's address is shown. See [Bring your own services](https://docs.candle.tv/developers/cli#bring-your-own-services). |
111
127
  | `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. |
112
128
  | `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`. |
@@ -116,13 +132,13 @@ emergency procedure, rebinding, trusted wallets and API key access levels are al
116
132
  | `candle tee signer new --key <prefix\|label> [--out <pem>] [--force] [--no-wait]` | 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 P-256 authorization key for Privy wallet RPC; it cannot sign Solana transactions (the TEE signs them). `--no-wait` exits 0 once the request exists. With `--json`, stdout is newline-delimited JSON: a pending event (`state`, `userCode`, `verificationUriComplete`, `expiresAt`, `fingerprint`) immediately, then an active result or error when waiting. A retry re-attaches to the same live request without changing its code or deadline. |
117
133
  | `candle tee signer status --key <prefix\|label> [--json]` | Read the current server signer state without generating a key, requesting a code or waiting. On the requesting machine, also shows the cached approval URL and code while the same request is live. |
118
134
  | `candle tee signer remove --key <prefix\|label>` | Removes this machine's key signer once it owns no wallets, and tells the server the signer is gone. Refuses while a wallet is still owned by it. Uses the device token, or the key's own API key. |
119
- | `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. |
135
+ | `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, filtered to one wallet by its id, address or exact label. |
120
136
  | `candle tee rename <label\|address\|id> <new-label>`, `candle tee rename --pairs-from <file> [--dry-run]` | Rename one TEE wallet, or 1–256 from a pairs file: the label Candle holds and the vault entry when there is one (owner only; one server call, all or nothing, then one vault commit). |
121
137
  | `candle tee new\|enable` | `new` adds a key to an existing `tee-wallets.enc` and refuses when that store is absent (`vault new-key --chain solana`, then `vault promote --from <label> --to-key <prefix>`). `--factor` does not apply. `enable <address> --vault <address>` delegates an existing key with a pinned sweep vault. `vault import-legacy --tee` migrates an existing store. |
122
138
  | `candle swap <from> <to> --amount <n>\|--percent <n> --wallet <tee> [--to <tee>] [--wait]` | Quote, confirm and swap through the TEE wallet's bound key; the first buy after a launch is this command, unless `candle launch --buy` made it. 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. With `--json`, stdout is exactly one JSON value for swaps, token trades, replays and `swap status`: `kind`, `status`, `clientTradeId`, `signature` (the primary transaction, or `null`), `signatures` (a list) and `raw` (the original response). Every human line is on stderr. The keys older versions printed stay beside them. |
123
139
  | `candle swap status <id> [--kind trade\|swap\|launch] [--wait]` | Read an operation without resending it; `--wait` follows a bridge until it ends. |
124
140
  | `candle transfer --to <address\|wallet name\|allowlist label\|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 Withdraw 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`). Where the server has `TEE_WITHDRAWALS_ENABLED` on (it ships off), also to an address on the account's withdrawal allowlist, named by its label, id or address, with the same base-asset rule. 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. |
125
- | `candle launch --name <name> --symbol <symbol> --image <path>\|--image-url <url> --wallet <tee>\|embedded [--banner <file\|URL>] [--description <text>] [--website <url>] [--x <url>] [--telegram <url>] [--discord <url>] [--buy <amount>] [--quote-asset <asset>] [--dex-version v3\|v4] [--mode <mode>] [--curve-v <V> --curve-g <G>] [--creator-fee-bps 0\|100\|200] [--staker-allocation-bps <bps>] [--visibility production\|test\|local\|hidden] [--pool-fee 25\|50\|100] [--pool-fee-from <bps> --pool-fee-minutes <min>] [--pool-open legacy\|curve_price] [--exp-pool-shape floor\|full_range] [--fee-wallet <address>\|--fee-wallet-multisig <address> [--fee-wallet-multisig-vault-index <n>]] [--require-fee-wallet] [--dry-run] [--check] [--client-trade-id <id>] [--yes]` | Create a token from the named wallet, with an optional first buy. `--wallet embedded` (or `main`) uses `/launch/headless` on Solana or Hood, with or without `--buy`; every plan can use it with `launch:write` and the key's embedded-wallet allowance, without `swap:write`. It previews through `/launch/headless/dry-run`, shows the quote for confirmation, then sends one headless request. A Solana buy is a creator bundle signed by Candle, preserving `bundleId` in the result; a Hood buy is best effort after creation. The server's slippage floor applies; there is no separate CLI build-floor comparison. TEE wallets use `/launch/self` and need Pro or Max, `launch:write`, the bound key and verified signing authority; a server with `TEE_LAUNCH_BY_SCOPE_ENABLED` off also asks for the owner's `allowLaunch` (deprecated). A TEE first buy needs `TEE_LAUNCH_BUYS_ENABLED` (off by default), and with `TEE_LAUNCH_BY_SCOPE_ENABLED` on it also needs `swap:write` (a key without it gets `SCOPE_MISSING`); Solana creator buys also need `AGENT_TRADING_ENABLED` and a configured Jito engine. No gate or plan default changes. `--buy` is a decimal in whole quote units (SOL/USDC/CNDL on Solana, ETH on Hood; USDG has no first buy); zero or empty means no buy. A Hood launch needs `--dex-version v3\|v4`. `--description` and the four absolute http(s) socials flags travel with every preview/build: `--x` maps to `socials.twitter`. `--staker-allocation-bps` accepts 50–1000; `--visibility` is production, test, local or hidden (test keys need test or hidden). `--mode exp-custom` needs `--curve-v` and `--curve-g` in whole quote units; ranges and common help come from the shared launch definition and appear in `candle launch --help`. `--pool-fee` sets the Solana graduated pool fee (default 50 bps); `--pool-fee-from` and `--pool-fee-minutes` add a fall to that rate. Preset `--pool-open curve_price` opens at the curve's last price and burns the rest; omitted it applies when allocations fit `graduation.maxStakerCarveBps`, otherwise falls back to legacy. Exp `--exp-pool-shape` is floor or full_range. `--image-url` is https; `--image` uploads a local PNG/JPEG/GIF/WebP up to 10MB. `--banner` takes a wide local file or https URL. Uploads are public and permanent before confirmation, even on a dry run or decline. `--dry-run` stops at the preview without claiming the launch id. Reuse `--client-trade-id` for recovery, and always pass `--json` in scripts. `--check` answers which launch path works before any of it, in one call (`GET /api/v1/launch/preflight`): the key's tier and embedded-wallet allowance, each bound TEE wallet's allowLaunch (served `true` where the server has `TEE_LAUNCH_BY_SCOPE_ENABLED` on) and verified-active state, and the server's `TEE_LAUNCH_BY_SCOPE_ENABLED`, `TEE_LAUNCH_BUYS_ENABLED` and `AGENT_TRADING_ENABLED` switches. No name, symbol or image is needed, nothing is uploaded or sent, `--wallet <name>` narrows the answer to one wallet, and it exits 1 when no launch path works. |
141
+ | `candle launch --name <name> --symbol <symbol> --image <path>\|--image-url <url> --wallet <tee>\|embedded [--banner <file\|URL>] [--description <text>] [--website <url>] [--x <url>] [--telegram <url>] [--discord <url>] [--buy <amount>] [--quote-asset <asset>] [--dex-version v3\|v4] [--mode <mode>] [--curve-v <V> --curve-g <G>] [--creator-fee-bps 0\|100\|200] [--staker-allocation-bps <bps>] [--visibility production\|test\|local\|hidden] [--pool-fee 25\|50\|100] [--pool-fee-from <bps> --pool-fee-minutes <min>] [--pool-open legacy\|curve_price] [--exp-pool-shape floor\|full_range] [--fee-wallet <address>\|--fee-wallet-multisig <address> [--fee-wallet-multisig-vault-index <n>]] [--require-fee-wallet] [--open-in <duration>] [--max-buy-per-wallet <amount> --cap-window <duration>] [--allowlist <path> --allowlist-window <duration>] [--dev-buy-max <amount>] [--dry-run] [--check] [--client-trade-id <id>] [--yes]` | Create a token from the named wallet, with an optional first buy. `--wallet embedded` (or `main`) uses `/launch/headless` on Solana or Hood, with or without `--buy`; every plan can use it with `launch:write` and the key's embedded-wallet allowance, without `swap:write`. It previews through `/launch/headless/dry-run`, shows the quote for confirmation, then sends one headless request. A Solana buy is a creator bundle signed by Candle, preserving `bundleId` in the result; a Hood buy is best effort after creation. The server's slippage floor applies; there is no separate CLI build-floor comparison. TEE wallets use `/launch/self` and need Pro or Max, `launch:write`, the bound key and verified signing authority; a server with `TEE_LAUNCH_BY_SCOPE_ENABLED` off also asks for the owner's `allowLaunch` (deprecated). A TEE first buy needs `TEE_LAUNCH_BUYS_ENABLED` (off by default), and with `TEE_LAUNCH_BY_SCOPE_ENABLED` on it also needs `swap:write` (a key without it gets `SCOPE_MISSING`); Solana creator buys also need `AGENT_TRADING_ENABLED` and a configured Jito engine. No gate or plan default changes. `--buy` is a decimal in whole quote units (SOL/USDC/CNDL on Solana, ETH on Hood; USDG has no first buy); zero or empty means no buy. A Hood launch needs `--dex-version v3\|v4`. `--description` and the four absolute http(s) socials flags travel with every preview/build: `--x` maps to `socials.twitter`. `--staker-allocation-bps` accepts 50–1000; `--visibility` is production, test, local or hidden (test keys need test or hidden). `--mode exp-custom` needs `--curve-v` and `--curve-g` in whole quote units; ranges and common help come from the shared launch definition and appear in `candle launch --help`. `--pool-fee` sets the Solana graduated pool fee (default 50 bps); `--pool-fee-from` and `--pool-fee-minutes` add a fall to that rate. Preset `--pool-open curve_price` opens at the curve's last price and burns the rest; omitted it applies when allocations fit `graduation.maxStakerCarveBps`, otherwise falls back to legacy. Exp `--exp-pool-shape` is floor or full_range. `--image-url` is https; `--image` uploads a local PNG/JPEG/GIF/WebP up to 10MB. `--banner` takes a wide local file or https URL. Uploads are public and permanent before confirmation, even on a dry run or decline. `--dry-run` stops at the preview without claiming the launch id. Reuse `--client-trade-id` for recovery, and always pass `--json` in scripts. `--check` answers which launch path works before any of it, in one call (`GET /api/v1/launch/preflight`): the key's tier and embedded-wallet allowance, each bound TEE wallet's allowLaunch (served `true` where the server has `TEE_LAUNCH_BY_SCOPE_ENABLED` on) and verified-active state, and the server's `TEE_LAUNCH_BY_SCOPE_ENABLED`, `TEE_LAUNCH_BUYS_ENABLED` and `AGENT_TRADING_ENABLED` switches. No name, symbol or image is needed, nothing is uploaded or sent, `--wallet <name>` narrows the answer to one wallet, and it exits 1 when no launch path works. On Solana, where the server has `CURVE_LAUNCH_RULES_ENABLED` on, launch rules are fixed at launch and enforced by the curve program: `--open-in` delays the open (until then only the launching wallet may buy, up to `--dev-buy-max`, which defaults to `--buy`), `--max-buy-per-wallet` with `--cap-window` caps what each wallet spends on the curve after the open, and `--allowlist <path>` (one address per line, or comma separated, at most 4,096) with `--allowlist-window` lets only the listed wallets buy. Durations are seconds or `90m`, `6h`, `2d` (the open at most 7 days away, each window at most 24 hours); amounts are whole quote units. The CLI checks each value before any request with the API's bounds, sends the request's nested `launchRules` in raw units, and the preview prints a Launch rules block from the API's answer. Nobody can change the rules after the launch. |
126
142
  | `candle launch status <mint-or-client-launch-id> [--wait]` | One launch state, `build`, `signed`, `confirmed`, `trading`, `bonded` or `migrated`, for a mint or a `clientLaunchId`. Reads `GET /api/v1/launch/status/{id}` (`launch:read`) and reports the market's own `lifecycle` and `migration` fields. `--wait` follows it until the token is trading, the launch has failed, or ten minutes pass. Nothing is sent. |
127
143
  | `candle image upload <path>` | Uploads a PNG, JPEG, GIF or WebP file, at most 10MB, and prints the `https://` URL Candle hosts it at, ready to be a launch's `imageUrl`. The type is read from the file's first bytes. The file becomes public and permanent. Needs `launch:write`; spends nothing and does not count against the launch cap. `--json` adds the content type and the size. |
128
144
  | `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. |
@@ -151,6 +167,8 @@ emergency procedure, rebinding, trusted wallets and API key access levels are al
151
167
 
152
168
  `candle vault transfer <to> --amount max --asset SOL --from <label>` sends the source wallet’s SOL balance minus the exact quoted transaction fee. The plain system wallet is emptied, so its source rent reserve is zero. The balance and fee are refreshed after confirmation; a changed amount or fee is displayed and must be confirmed again (at most three confirmations). An unavailable or unstable fee quote, or a balance that cannot cover the fee and a positive send, refuses before signing. Nonce and program accounts cannot use this plain transfer shape. SPL and Token-2022 `max` send the source associated token account’s full raw balance (mint fees may reduce what arrives); SOL must still cover fees and any destination token account rent. Hood native `max` deducts the fee cap; ERC-20 `max` sends the whole token balance.
153
169
 
170
+ `candle transfer --asset SOL --amount max` (including `--to vault` from a TEE wallet) sends the balance minus 10,000 lamports of fee headroom and the RPC-reported rent-exempt minimum for a zero-byte system account. It keeps the payer rent-exempt. If no positive amount remains, Candle refuses before signing with `TRANSFER_AMOUNT_UNAVAILABLE`; the message reports the spendable lamports, fee headroom and rent minimum. The returned `amountRaw` is the amount the transaction moves.
171
+
154
172
  The documented `--access` values are `read`, `write` and `withdraw`. The older `read-write`, `transfer` and `read-write-transfer` values remain accepted as silent, permanent aliases.
155
173
 
156
174
  Every command accepts these global options:
@@ -206,7 +224,7 @@ which `candle verify` cannot read.
206
224
 
207
225
  No cosign or gh installed? `candle verify <file> --bundle <path>` (this CLI's own command, see the
208
226
  table above) runs the same check against the trusted root compiled into the binary, no network
209
- call required. Full walkthrough, including the installer script's own signature and the
227
+ call required. It is also what `install.sh` uses on a machine with neither. Full walkthrough, including the installer script's own signature and the
210
228
  transparency log: [Verify a Candle release](https://docs.candle.tv/developers/verify-a-candle-release).
211
229
 
212
230
  ## The `--json` contract
@@ -217,7 +235,11 @@ result on success, or a failure envelope -- and stderr carries diagnostics only.
217
235
  wrong; nothing ran), `3` not yet verified (the command did its part, but the outcome it exists to
218
236
  guarantee is unconfirmed: a wallet stop whose remote enforcement is still pending, a TEE wallet
219
237
  enabled without verified signing authority, or a sweep that left a residual). Treat `3` as not
220
- done: follow the printed next step, usually re-running the same command.
238
+ done: follow the printed next step, usually re-running the same command. `5` cancelled: you
239
+ declined a confirmation prompt, or typed the wrong word at a typed confirm, so nothing was
240
+ signed, sent or written (BE-2674). Under `--json` the document still says what happened --
241
+ `status: "cancelled"` for a result, or the `CANCELLED` / `DESTINATION_NOT_CONFIRMED` envelope --
242
+ and a script can now tell a user decline from a refusal by the exit code alone.
221
243
 
222
244
  A swap or token trade also exits `3` when it may be on chain: the server answered
223
245
  `stage: "unconfirmed"` (sent, outcome not seen) or, for a token trade, `stage: "executed"` (the
@@ -400,10 +422,11 @@ key; Candle builds the transaction and Privy signs it through the relay. See TEE
400
422
  below. Limit orders are a REST surface only (`/api/v1/trade/agent/orders`), not in this CLI, the
401
423
  SDK or the MCP server.
402
424
 
403
- **`keys limits`.** There is no command for setting per-key spend limits, because the API route
404
- that sets them (`PUT /keys/:prefix/limits`) structurally rejects a device token. It only accepts
405
- an agent key or a live session, since a spend limit is fund-movement authority, and this CLI's
406
- device token is scoped narrowly to key management. Manage limits from the portal.
425
+ **`keys limits`.** The API route that sets per-key spend limits (`PUT /keys/:prefix/limits`)
426
+ structurally rejects a device token: a spend limit is fund-movement authority, and this CLI's
427
+ device token is scoped narrowly to key management. So `candle keys limits` sends the profile's own
428
+ API key, and an agent key may only tighten (lower a cap, or add one where none was set). Raising
429
+ or removing a cap is refused with `LOOSEN_REQUIRES_SESSION`; the owner does that from the portal.
407
430
 
408
431
  **`devices list` / `devices revoke`.** The device-token endpoints (`GET`/`DELETE
409
432
  /device/tokens`) are session-only by design: this is the self-renewal guard that keeps a stolen