1use super::*;
2
3pub mod balances;
4pub mod decode;
5pub mod env;
6pub mod epochs;
7pub mod find;
8pub mod index;
9pub mod list;
10pub mod parse;
11pub mod runes;
12pub mod server;
13mod settings;
14pub mod subsidy;
15pub mod supply;
16pub mod teleburn;
17pub mod traits;
18pub mod wallet;
19
20#[derive(Debug, Parser)]
21pub(crate) enum Subcommand {
22 #[command(about = "List all rune balances")]
23 Balances,
24 #[command(about = "Decode a transaction")]
25 Decode(decode::Decode),
26 #[command(about = "Start a regtest ord and bitcoind instance")]
27 Env(env::Env),
28 #[command(about = "List the first satoshis of each reward epoch")]
29 Epochs,
30 #[command(about = "Find a satoshi's current location")]
31 Find(find::Find),
32 #[command(subcommand, about = "Index commands")]
33 Index(index::IndexSubcommand),
34 #[command(about = "List the satoshis in an output")]
35 List(list::List),
36 #[command(about = "Parse a satoshi from ordinal notation")]
37 Parse(parse::Parse),
38 #[command(about = "List all runes")]
39 Runes,
40 #[command(about = "Run the explorer server")]
41 Server(server::Server),
42 #[command(about = "Display settings")]
43 Settings,
44 #[command(about = "Display information about a block's subsidy")]
45 Subsidy(subsidy::Subsidy),
46 #[command(about = "Display Bitcoin supply information")]
47 Supply,
48 #[command(about = "Generate teleburn addresses")]
49 Teleburn(teleburn::Teleburn),
50 #[command(about = "Display satoshi traits")]
51 Traits(traits::Traits),
52 #[command(about = "Wallet commands")]
53 Wallet(wallet::WalletCommand),
54}
55
56impl Subcommand {
57 pub(crate) fn run(self, settings: Settings) -> SubcommandResult {
58 match self {
59 Self::Balances => balances::run(settings),
60 Self::Decode(decode) => decode.run(settings),
61 Self::Env(env) => env.run(),
62 Self::Epochs => epochs::run(),
63 Self::Find(find) => find.run(settings),
64 Self::Index(index) => index.run(settings),
65 Self::List(list) => list.run(settings),
66 Self::Parse(parse) => parse.run(),
67 Self::Runes => runes::run(settings),
68 Self::Server(server) => {
69 let index = Arc::new(Index::open(&settings)?);
70 let handle = axum_server::Handle::new();
71 LISTENERS.lock().unwrap().push(handle.clone());
72 server.run(settings, index, handle)
73 }
74 Self::Settings => settings::run(settings),
75 Self::Subsidy(subsidy) => subsidy.run(),
76 Self::Supply => supply::run(),
77 Self::Teleburn(teleburn) => teleburn.run(),
78 Self::Traits(traits) => traits.run(),
79 Self::Wallet(wallet) => wallet.run(settings),
80 }
81 }
82}
83
84pub trait Output: Send {
85 fn print_json(&self, minify: bool);
86}
87
88impl<T> Output for T
89where
90 T: Serialize + Send,
91{
92 fn print_json(&self, minify: bool) {
93 if minify {
94 serde_json::to_writer(io::stdout(), self).ok();
95 } else {
96 serde_json::to_writer_pretty(io::stdout(), self).ok();
97 }
98 println!();
99 }
100}
101
102pub(crate) type SubcommandResult = Result<Option<Box<dyn Output>>>;