Skip to main content

decdn_common/cli/
mod.rs

1//! CLI argument parsing for the `decdn` binary.
2//!
3//! [`RunArgs`] is also re-used (flattened) by [`ConfigValidateArgs`] —
4//! `decdn config validate` runs the same resolver `decdn-node run`
5//! does, against the same `DECDN_*` env vars, without binding ports
6//! or starting any tasks. The daemon's own clap shell lives in
7//! `crates/node/src/main.rs` and is not part of this module.
8
9pub mod appeal;
10pub mod byte_size;
11pub mod common;
12pub mod config_cmd;
13pub mod fetch;
14pub mod gateway;
15pub mod get;
16pub mod key_gen;
17pub mod node;
18pub mod origin;
19pub mod pool;
20pub mod probe;
21pub mod publish;
22pub mod run;
23pub mod setup;
24pub mod whoami;
25
26pub use appeal::{AppealArgs, AppealCommand, AppealSlashArgs};
27pub use byte_size::parse_byte_size;
28pub use common::{
29    CommonChainArgs, ConfigPathSource, LogFormat, default_client_data_dir, default_config_path,
30    default_data_dir,
31};
32pub use config_cmd::{ConfigArgs, ConfigCommand, ConfigInitArgs, ConfigValidateArgs};
33pub use fetch::ClientFetchArgs;
34pub use gateway::GatewayArgs;
35pub use get::GetArgs;
36pub use key_gen::KeyGenArgs;
37pub use node::{
38    BondArgs, ChainArgs, DeregisterArgs, DoctorArgs, DrainArgs, EvictArgs, HealthArgs, LanesArgs,
39    LookupArgs, NodeArgs, NodeCommand, PoolsArgs, RegisterArgs, ReloadArgs, RotateKeyArgs,
40    RotateKeyTarget, SlashesArgs, StatusArgs, TopArgs, UnbondArgs, UpdateMultiaddrsArgs,
41    UpdateRegionArgs,
42};
43pub use origin::{OriginArgs, OriginCommand, OriginImportArgs};
44pub use pool::{
45    PoolArgs, PoolAssignArgs, PoolChainArgs, PoolCloseArgs, PoolCommand, PoolListArgs,
46    PoolOpenArgs, PoolReclaimArgs, PoolTopUpArgs,
47};
48pub use probe::ProbeArgs;
49pub use publish::{
50    AssignArgs, NamespaceArgs, NamespaceCommand, NamespaceCreateArgs, PublishArgs,
51    PublishChainArgs, PublishCommand, RevokeArgs,
52};
53pub use run::RunArgs;
54pub use setup::SetupArgs;
55pub use whoami::WhoamiArgs;
56
57use std::path::PathBuf;
58
59use clap::{Parser, Subcommand};
60
61/// User-facing deCDN CLI. The daemon lives in the separate `decdn-node`
62/// binary; this CLI is what you type from a terminal — probe, get, pools,
63/// publishing, node admin.
64#[derive(Parser, Debug)]
65#[command(
66    name = "decdn",
67    version,
68    about = "deCDN user CLI — probe, get, pools, publishing, node admin",
69    long_about = "User-facing deCDN CLI. Pairs with the `decdn-node` daemon: \
70                  this binary carries every command a human types in a \
71                  terminal (probe, get, payment pools, publishing, \
72                  origin import, node admin, key-gen, config). The \
73                  `node` subcommand group talks to a running daemon over \
74                  the loopback admin RPC surface \
75                  (`appendix-local-admin-http.md`) and fails cleanly on a \
76                  host with no daemon running."
77)]
78pub struct Cli {
79    /// Path to TOML config file [default: ~/.decdn/node.toml].
80    #[arg(long, global = true, value_name = "PATH")]
81    pub config: Option<PathBuf>,
82
83    /// Enable client-side logging at this level. Off by default (the CLI is a
84    /// terminal UI); `RUST_LOG` overrides this when set. Useful for diagnosing
85    /// a stalled `decdn get` from the client side. Deliberately not bound to
86    /// an environment variable: the CLI stays silent unless logging is asked
87    /// for on this invocation, even when the daemon's log-level env is exported.
88    #[arg(long, global = true, value_name = "LEVEL")]
89    pub log_level: Option<common::LogLevel>,
90
91    /// Enable client-side logging by count: `-v` is `info`, `-vv` is `debug`,
92    /// `-vvv` is `trace`. Shorthand for `--log-level`, which wins when both are
93    /// given; `RUST_LOG` wins over both.
94    #[arg(short = 'v', long, global = true, action = clap::ArgAction::Count)]
95    pub verbose: u8,
96
97    /// Subcommand to execute.
98    #[command(subcommand)]
99    pub command: Command,
100}
101
102/// Available subcommands. There is intentionally no `run` subcommand —
103/// running the daemon is `decdn-node run` (issue #421). For a dry-run
104/// resolution of the daemon's startup config without binding ports,
105/// see [`ConfigValidateArgs`] (`decdn config validate`), which
106/// flattens the same [`RunArgs`] the daemon parses.
107#[derive(Subcommand, Debug)]
108pub enum Command {
109    /// Generate a new Ed25519 node key and Ethereum keystore.
110    KeyGen(KeyGenArgs),
111    /// Print the local identity read-only: iroh node id, eth address, and the
112    /// resolved key paths. Generates and rotates nothing.
113    Whoami(WhoamiArgs),
114    /// Manage configuration files (`init`, `validate`).
115    Config(ConfigArgs),
116    /// Probe a running node over the `cdn/probe/v1` ALPN.
117    Probe(ProbeArgs),
118    /// Serve `decdn:` URIs to a browser from a loopback HTTP gateway, paid
119    /// with the scoped capabilities pages and the token holder register.
120    Gateway(Box<GatewayArgs>),
121    /// Pull what a `decdn:` URI names: a blob (`decdn:<hash>`), a whole bundle
122    /// (`decdn:<hash>/`), or one bundle entry (`decdn:<hash>/<path>`), over the
123    /// paid `cdn/client/v1` path, paying per-MB from a `PaymentPool`.
124    Get(Box<GetArgs>),
125    /// Guided node onboarding (ADR 019 Phases 1–2): pre-flight checks,
126    /// key generation, bond, and on-chain registration, with a final
127    /// readiness summary. Thin orchestration over `key-gen` / `node bond` /
128    /// `node register` — submits no transaction the primitives don't.
129    Setup(SetupArgs),
130    /// Operator-local admin commands that query a running node
131    /// over its loopback HTTP surface (`appendix-local-admin-http.md`).
132    Node(NodeArgs),
133    /// Seed a cache origin store from local content (`import`) — offline,
134    /// config-free filesystem work that writes each blob's sharded data object
135    /// and its `{hex}.obao4` outboard in the layout the daemon reads (ADR 037).
136    Origin(OriginArgs),
137    /// Client-side payment-pool lifecycle (`list`/`status`, `open`, `top-up`,
138    /// `close`, `reclaim`, `assign`).
139    Pool(PoolArgs),
140    /// Publisher control plane: create namespaces, and seat or unseat
141    /// authorized origins on-chain (issues #1029 / #1491).
142    /// Content is bound to a namespace off-chain at fetch time, so there is no
143    /// per-hash on-chain claim.
144    Publish(PublishArgs),
145    /// File a slash appeal, posting the appeal bond (ADR 028).
146    Appeal(AppealArgs),
147}
148
149#[cfg(test)]
150mod tests;