Skip to content

Commit

Permalink
1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Emivvvvv committed Jan 17, 2025
1 parent c041ad9 commit 586a29d
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 118 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "btc-vanity"
version = "1.3.2"
version = "1.4.0"
authors = ["Emirhan TALA <tala.emirhan@gmail.com>"]
description = "A bitcoin vanity address generator written with the Rust programming language."
edition = "2021"
Expand Down
36 changes: 5 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@

# <img src='Bitcoin.svg.png' width='22'> btc-vanity

A bitcoin vanity address generator written with the Rust programming language.

With btc-vanity you can create a private key which has a compressed bitcoin pay address that has a custom prefix, suffix or a string at somewhere in the address.
With btc-vanity, you can create a private key that generates a compressed Bitcoin pay address featuring a custom prefix, suffix, a specific string, or even a pattern matching your custom regex!

You can easily run btc-vanity terminal application locally or use it as a library to create your vanity keypair securely.

Expand All @@ -16,12 +15,11 @@ DO NOT USE THE PRIVATE KEYS ON THE SCREENSHOTS! NEVER EVER SHARE YOUR PRIVATE KE

## Features

- **Flexible Address Customization**: Generate Bitcoin addresses with prefixes, suffixes, or the desired pattern located anywhere in the address.
- **Flexible Address Customization**: Generate Bitcoin addresses with custom prefixes, suffixes, patterns matching your desired regex, or specific strings located anywhere in the address, with optional case insensitivity for enhanced flexibility.
- **Case Insensitivity Support**: Option to ignore case when searching for vanity addresses.
- **Batch Wallet Generation**: Input a file containing multiple desired addresses and generate wallets in bulk.
- **Output Wallets to File**: Automatically save generated wallet addresses to an output file for easy access.
- **Configurable Flags**: Use an input file to pass custom flags for each desired wallet address.
- **Comprehensive Documentation**: Full library documentation to help you get started and understand the available features.

## Installation

Expand All @@ -38,39 +36,15 @@ $ btc-vanity -c -a Emiv
```

```
$ btc-vanity -s -o wallet.txt TALA
$ btc-vanity -s -o wallet.txt fart
```

```
$ btc-vanity -f -p -c -i inputs.txt -o wallets.txt
$ btc-vanity -r ^E.*99.*T$
```

## CLI

```
$ btc-vanity --help
A bitcoin vanity address generator written with the Rust programming language.
Usage: btc-vanity [OPTIONS] [string]
Arguments:
[string] String used to match addresses.
Options:
-i, --input-file <input-file> File with strings to match addresses with.
Important: Write every string in a separate line.
-f, --force-flags Use this flag to override the flags in the input file
or use in file to override cli flags for only that string.
Note: Cli -f is stronger than input-file -f.
-o, --output-file <output-file> Crates a file that contains found wallet/s.
-p, --prefix Finds a vanity address which has 'string' prefix. [default]
-s, --suffix Finds a vanity address which has 'string' suffix.
-a, --anywhere Finds a vanity address which includes 'string' at any part of the address.
-t, --threads <threads> Number of threads to be used. [default: 16]
-c, --case-sensitive Use case sensitive comparison to match addresses.
-d, --disable-fast Disables fast mode to find a prefix more than 4 characters.
-h, --help Print help
-V, --version Print version
$ btc-vanity -f -p -c -i inputs.txt -o wallets.txt
```

## Documentation
Expand Down
5 changes: 3 additions & 2 deletions example-inputs.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Emiv -c -p
TALA -c -s
3169 -a
fart -s
3169 -a
^E.*99.*T$ -r
Binary file modified examples-input-file.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
127 changes: 67 additions & 60 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,6 @@
//!
//! ```bash
//! $ btc-vanity --help
//! A bitcoin vanity address generator written with the Rust programming language.
//!
//! Usage: btc-vanity [OPTIONS] [string]
//!
//! Arguments:
//! [string] String used to match addresses.
//!
//! Options:
//! -i, --input-file <input-file> File with strings to match addresses with.
//! Important: Write every string in a separate line.
//! -f, --force-flags Use this flag to override the flags in the input file
//! or use in file to override cli flags for only that string.
//! Note: Cli -f is stronger than input-file -f.
//! -o, --output-file <output-file> Crates a file that contains found wallet/s.
//! -p, --prefix Finds a vanity address which has 'string' prefix. [default]
//! -s, --suffix Finds a vanity address which has 'string' suffix.
//! -a, --anywhere Finds a vanity address which includes 'string' at any part of the address.
//! -t, --threads <threads> Number of threads to be used. [default: 16]
//! -c, --case-sensitive Use case sensitive comparison to match addresses.
//! -d, --disable-fast Disables fast mode to find a prefix more than 4 characters.
//! -h, --help Print help
//! -V, --version Print version
//! ```
//!
//! # Some Usage Examples
Expand All @@ -54,83 +32,112 @@
//! $ btc-vanity -f -s -i inputs.txt
//! ```
use clap;
use clap::{Arg, ArgAction, ArgGroup, Command};

/// Runs the clap app in order to use cli
pub fn cli() -> clap::Command {
clap::Command::new(env!("CARGO_PKG_NAME"))
/// Runs the clap app to create the CLI
pub fn cli() -> Command {
Command::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.about(env!("CARGO_PKG_DESCRIPTION"))
.next_line_help(true)
.arg(
clap::Arg::new("string")
Arg::new("string")
.index(1)
.required_unless_present_any(["input-file"])
.help("String used to match addresses."),
.help("The string (or regex) used to match Bitcoin vanity addresses."),
)
.arg(
clap::Arg::new("input-file")
Arg::new("input-file")
.short('i')
.long("input-file")
.required_unless_present_any(["string"])
.help("File with strings to match addresses with.\nImportant: Write every string in a separate line.")
.value_name("FILE")
.help("Path to a file containing strings to match addresses. \
\nImportant: Each string should be written on a separate line."),
)
.arg(
Arg::new("output-file")
.short('o')
.long("output-file")
.value_name("FILE")
.help("Creates or appends found wallet(s) to the specified file."),
)
.arg(
clap::Arg::new("force-flags")
Arg::new("force-flags")
.short('f')
.long("force-flags")
.action(clap::ArgAction::SetTrue)
.help("Use this flag to override the flags in the input file\nor use in file to override cli flags for only that string.\nNote: Cli -f is stronger than input-file -f.")
.action(ArgAction::SetTrue)
.help("Overrides the flags in the input file. \
\nIf set, this will enforce CLI-provided flags. \
\nNote: CLI -f is stronger than input-file -f."),
)
.arg(
clap::Arg::new("output-file")
.short('o')
.long("output-file")
.help("Crates a file that contains found wallet/s."),
.group(
ArgGroup::new("pattern")
.args(["prefix", "suffix", "anywhere", "regex"])
.multiple(false) // Only one pattern type can be used
.required(false), // Not required globally
)
.arg(
clap::Arg::new("prefix")
.conflicts_with("suffix")
.conflicts_with("anywhere")
Arg::new("prefix")
.short('p')
.long("prefix")
.action(clap::ArgAction::SetTrue)
.help("Finds a vanity address which has 'string' prefix. [default]")
.action(ArgAction::SetTrue)
.conflicts_with_all(["suffix", "anywhere", "regex"])
.help("Finds a vanity address with the specified string as a prefix. [default]"),
)
.arg(
clap::Arg::new("suffix")
.conflicts_with("prefix")
.conflicts_with("anywhere")
Arg::new("suffix")
.short('s')
.long("suffix")
.action(clap::ArgAction::SetTrue)
.help("Finds a vanity address which has 'string' suffix.")
.action(ArgAction::SetTrue)
.conflicts_with_all(["prefix", "anywhere", "regex"])
.help("Finds a vanity address with the specified string as a suffix."),
)
.arg(
clap::Arg::new("anywhere")
Arg::new("anywhere")
.short('a')
.long("anywhere")
.action(clap::ArgAction::SetTrue)
.help("Finds a vanity address which includes 'string' at any part of the address.")
.action(ArgAction::SetTrue)
.conflicts_with_all(["prefix", "suffix", "regex"])
.help("Finds a vanity address containing the specified string anywhere in the address."),
)
.arg(
Arg::new("regex")
.short('r')
.long("regex")
.action(ArgAction::SetTrue)
.conflicts_with_all(["prefix", "suffix", "anywhere"])
.long_help(
"Specifies a regex pattern for your desired vanity address. \
\nSupports common regex syntax, such as anchors (^, $), character classes, and wildcards. \
\nExample: '^1abc.*xyz$' matches addresses starting with '1abc' and ending with 'xyz'. \
\nNote: If your pattern starts with '^' but not '^1', '1' will automatically be prepended \
\n(e.g., '^E' becomes '^1E'). \
\nOnly Base58 characters (excluding '0', 'I', 'O', 'l') are valid in matches. \
\nRegex mode has no length restriction. However, long or restrictive patterns may \
\nsignificantly increase search time and could make finding a match impossible.",
),
)
.arg(
clap::Arg::new("threads")
Arg::new("threads")
.short('t')
.long("threads")
.default_value("16")
.help("Number of threads to be used."),
.value_name("N")
.default_value("8")
.help("Sets the number of threads to use."),
)
.arg(
clap::Arg::new("case-sensitive")
Arg::new("case-sensitive")
.short('c')
.long("case-sensitive")
.action(clap::ArgAction::SetTrue)
.help("Use case sensitive comparison to match addresses."),
.action(ArgAction::SetTrue)
.help("Enables case-sensitive matching for addresses."),
)
.arg(
clap::Arg::new("disable-fast-mode")
Arg::new("disable-fast-mode")
.short('d')
.long("disable-fast")
.action(clap::ArgAction::SetTrue)
.help("Disables fast mode to find a prefix more than 4 characters."),
.action(ArgAction::SetTrue)
.help("Disables fast mode, allowing for prefixes longer than 4 characters."),
)
}
10 changes: 7 additions & 3 deletions src/decoration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ pub fn get_decoration_strings<'a>(
};

// Sets case sensitivity decoration string.
let case_sensitive_str = match is_case_sensitive {
true => CASE_SENSITIVITY_STR[0],
false => CASE_SENSITIVITY_STR[1],
let case_sensitive_str = if vanity_mode == VanityMode::Regex {
CASE_SENSITIVITY_STR[0]
} else {
match is_case_sensitive {
true => CASE_SENSITIVITY_STR[0],
false => CASE_SENSITIVITY_STR[1],
}
};

(vanity_mode_str, case_sensitive_str)
Expand Down
4 changes: 4 additions & 0 deletions src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::{fs, io};

/// This struct is used to get set flags for each string input
/// from the file.
#[derive(Debug)]
pub struct FileFlags {
pub force_flags: bool,
pub is_case_sensitive: bool,
Expand Down Expand Up @@ -49,14 +50,17 @@ pub fn get_flags(line: &str) -> FileFlags {
arg == "-p"
|| arg == "-s"
|| arg == "-a"
|| arg == "-r"
|| arg == "--prefix"
|| arg == "--suffix"
|| arg == "--anywhere"
|| arg == "--regex"
});
let vanity_mode = match vanity_option {
Some(&vanity) => match vanity {
"-p" | "--prefix" => Some(VanityMode::Prefix),
"-s" | "--suffix" => Some(VanityMode::Suffix),
"-r" | "--regex" => Some(VanityMode::Regex),
_ => Some(VanityMode::Anywhere),
},
None => None,
Expand Down
9 changes: 6 additions & 3 deletions src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::vanity_addr_generator::VanityMode;
use clap::ArgMatches;

/// This struct is used to save the cli flags
#[derive(Debug)]
pub struct CliFlags {
threads: u64,
strings: Vec<String>,
Expand All @@ -16,7 +17,7 @@ pub struct CliFlags {
is_case_sensitive: bool,
is_fast_disabled: bool,
output_file_name: String,
vanity_mode: VanityMode,
pub vanity_mode: VanityMode,
}

impl CliFlags {
Expand Down Expand Up @@ -54,7 +55,9 @@ pub fn get_cli_flags(matches: ArgMatches) -> CliFlags {
};

// Sets vanity_mode for searching and mode to predefined decoration strings.
let cli_vanity_mode = if matches.get_flag("anywhere") {
let cli_vanity_mode = if matches.get_flag("regex") {
VanityMode::Regex
} else if matches.get_flag("anywhere") {
VanityMode::Anywhere
} else if matches.get_flag("suffix") {
VanityMode::Suffix
Expand All @@ -80,7 +83,7 @@ pub struct StringsFlags {
is_case_sensitive: bool,
is_fast_disabled: bool,
output_file_name: String,
vanity_mode: VanityMode,
pub vanity_mode: VanityMode,
}

impl StringsFlags {
Expand Down
20 changes: 12 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use btc_vanity::cli::cli;
use btc_vanity::decoration::get_decoration_strings;
use btc_vanity::file::write_output_file;
use btc_vanity::flags::{get_cli_flags, get_strings_flags};
use btc_vanity::vanity_addr_generator::VanityAddr;
use btc_vanity::vanity_addr_generator::{VanityAddr, VanityMode};
use clap::error::ErrorKind;
use std::fmt::Write;
use std::time::Instant;
Expand Down Expand Up @@ -58,13 +58,17 @@ fn main() {

// Generates the vanity address and measures the time elapsed while finding the address.
let start = Instant::now();
let result = VanityAddr::generate(
string,
cli_flags.get_threads(),
string_flags.get_case_sensitivity(),
!string_flags.get_is_fast_mode_disabled(),
string_flags.get_vanity_mode(),
);
let result = match string_flags.vanity_mode {
VanityMode::Regex => VanityAddr::generate_regex(string, cli_flags.get_threads()),
_ => VanityAddr::generate(
string,
cli_flags.get_threads(),
string_flags.get_case_sensitivity(),
!string_flags.get_is_fast_mode_disabled(),
string_flags.get_vanity_mode(),
),
};

let seconds = start.elapsed().as_secs_f64();

// Second buffer/print after the vanity address found
Expand Down
4 changes: 4 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! # Utils Module
//!
//! This module is used in [crate::vanity_addr_generator] to check only contains Base58 characters or not.
/// Returns true if `c` is a valid Base58 character for (legacy) Bitcoin addresses.
///
/// Valid base58:
Expand Down
Loading

0 comments on commit 586a29d

Please sign in to comment.