Skip to main content

btc_vanity/
cli.rs

1//! # Cli With Using Clap Crate
2//!
3//! This module is used for creating a cli app for btc-vanity with using clap crate
4//!
5//! # Usage
6//!
7//! ```bash
8//! $ btc-vanity --help
9//! ```
10//!
11//! The CLI tool provides several options to customize your address generation:
12//!
13//! ```shell
14//! $ btc-vanity [OPTIONS] <PATTERN>
15//! ```
16//!
17//! #### Blockchain Selection
18//! `--btc`: Generates Bitcoin keypairs and addresses. [default] <br>
19//! `--eth`: Generates Ethereum keypairs and addresses. <br>
20//! `--sol`: Generates Solana keypairs and addresses. <br>
21//!
22//! #### General Options
23//! `-i, --input-file <FILE>`: Reads patterns and it's flags from the specified file for vanity address generation, with one pattern per line. <br>
24//! `-o, --output-file <FILE>`: Saves generated wallet details to the specified file, creating it if it doesn’t exist or appending if it does. <br>
25//! `-t, --threads <N>`: Sets the number of threads for address generation. <br>
26//! `-f, --force-flags`: Forces CLI flags to override any flags specified in the input file, ensuring consistent behavior across all patterns. <br>
27//! `-d, --disable-fast`: Disables fast mode to allow longer patterns (5 for BTC and SOL, 16 for ETH), though it may increase search time. <br>
28//!
29//! #### Matching Options
30//! `-p, --prefix`: Matches the pattern as a prefix of the address. [default] <br>
31//! `-s, --suffix`: Matches the pattern as a suffix of the address. <br>
32//! `-a, --anywhere`: Matches the pattern anywhere in the address. <br>
33//! `-r, --regex <REGEX>`: Matches addresses using a regex pattern, supporting advanced customization like anchors and wildcards. <br>
34//! `-c, --case-sensitive`: Enables case-sensitive matching, making patterns distinguish between uppercase and lowercase characters. <br>
35//!
36//! ### Bitcoin CLI Examples
37//!
38//! Generate a Bitcoin address with prefix `1Emiv` (case-insensitive):
39//!
40//! ```shell
41//! $ btc-vanity Emiv
42//! ```
43//!
44//! Generate a Bitcoin address containing the substring `test` (case-sensitive):
45//!
46//! ```shell
47//! $ btc-vanity -a -c test
48//! ```
49//!
50//! Generate a Bitcoin address using a regex pattern `^1E.*T$`:
51//!
52//! ```shell
53//! $ btc-vanity -r "^1E.*T$"
54//! ```
55//!
56//! Generate multiple Bitcoin addresses and save to wallets.txt:
57//!
58//! > [!NOTE]
59//! > -f flag will override any pattern flags inside the `input-file.txt`.
60//! > For example if there line `emiv -s --eth` will become `emiv -p --btc -c`.
61//! > The resulting wallet will be printed in `wallets.txt`.
62//!
63//! ```shell
64//! $ btc-vanity -f --btc -p -c -i input-file.txt -o wallets.txt
65//! ```
66//!
67//! Generate an Ethereum address starting with 0xdead with 8 threads:
68//!
69//! ```shell
70//! $ btc-vanity --eth -t 8 dead
71//! ```
72//!
73//! Generate a Solana address ending with 123:
74//!
75//! ```shell
76//! $ btc-vanity --sol -s 123
77//! ```
78
79use clap::{Arg, ArgAction, ArgGroup, Command};
80
81/// Runs the clap app to create the CLI
82pub fn cli() -> Command {
83    Command::new(env!("CARGO_PKG_NAME"))
84        .version(env!("CARGO_PKG_VERSION"))
85        .about(env!("CARGO_PKG_DESCRIPTION"))
86        .next_line_help(true)
87        .arg(
88            Arg::new("bitcoin")
89                .long("btc")
90                .action(ArgAction::SetTrue)
91                .conflicts_with_all(["ethereum", "solana"])
92                .help("Generates Bitcoin keypairs and addresses. [default]")
93        )
94        .arg(
95            Arg::new("ethereum")
96                .long("eth")
97                .action(ArgAction::SetTrue)
98                .conflicts_with_all(["bitcoin", "solana", "case-sensitive"])
99                .help("Generates Ethereum keypairs and addresses.")
100        )
101        .arg(
102            Arg::new("solana")
103                .long("sol")
104                .action(ArgAction::SetTrue)
105                .conflicts_with_all(["bitcoin", "ethereum"])
106                .help("Generates Solana keypairs and addresses.")
107        )
108        .arg(
109            Arg::new("string")
110                .index(1)
111                .required_unless_present_any(["input-file"])
112                .help("The string (or regex) used to match Bitcoin vanity addresses."),
113        )
114        .arg(
115            Arg::new("input-file")
116                .short('i')
117                .long("input-file")
118                .required_unless_present_any(["string"])
119                .value_name("FILE")
120                .help("Reads patterns and it's flags from the specified file for vanity address generation, with one pattern and it's flags per line."),
121        )
122        .arg(
123            Arg::new("output-file")
124                .short('o')
125                .long("output-file")
126                .value_name("FILE")
127                .help("Saves generated wallet details to the specified file, creating it if it doesn’t exist or appending if it does."),
128        )
129        .arg(
130            Arg::new("force-flags")
131                .short('f')
132                .long("force-flags")
133                .action(ArgAction::SetTrue)
134                .help("Forces CLI flags to override any flags specified in the input file, ensuring consistent behavior across all patterns."),
135        )
136        .group(
137            ArgGroup::new("pattern")
138                .args(["prefix", "suffix", "anywhere", "regex"])
139                .multiple(false) // Only one pattern type can be used
140                .required(false), // Not required globally
141        )
142        .arg(
143            Arg::new("prefix")
144                .short('p')
145                .long("prefix")
146                .action(ArgAction::SetTrue)
147                .conflicts_with_all(["suffix", "anywhere", "regex"])
148                .help("Matches the pattern as a prefix of the address. [default]"),
149        )
150        .arg(
151            Arg::new("suffix")
152                .short('s')
153                .long("suffix")
154                .action(ArgAction::SetTrue)
155                .conflicts_with_all(["prefix", "anywhere", "regex"])
156                .help("Matches the pattern as a suffix of the address."),
157        )
158        .arg(
159            Arg::new("anywhere")
160                .short('a')
161                .long("anywhere")
162                .action(ArgAction::SetTrue)
163                .conflicts_with_all(["prefix", "suffix", "regex"])
164                .help("Matches the pattern anywhere in the address."),
165        )
166        .arg(
167            Arg::new("regex")
168                .short('r')
169                .long("regex")
170                .action(ArgAction::SetTrue)
171                .conflicts_with_all(["prefix", "suffix", "anywhere"])
172                .help("Matches addresses using a regex pattern, supporting advanced customization like anchors and wildcards."),
173        )
174        .arg(
175            Arg::new("threads")
176                .short('t')
177                .long("threads")
178                .value_name("N")
179                .default_value("8")
180                .help("Sets the number of threads for address generation."),
181        )
182        .arg(
183            Arg::new("case-sensitive")
184                .short('c')
185                .long("case-sensitive")
186                .action(ArgAction::SetTrue)
187                .help("Enables case-sensitive matching, making patterns distinguish between uppercase and lowercase characters."),
188        )
189        .arg(
190            Arg::new("disable-fast-mode")
191                .short('d')
192                .long("disable-fast")
193                .action(ArgAction::SetTrue)
194                .help("Disables fast mode to allow longer patterns (5 for BTC and SOL, 16 for ETH), though it may increase search time."),
195        )
196}