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