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}