├── sample.txt ├── .gitignore ├── .github ├── dependabot.yml └── workflows │ ├── test.yml │ └── publish.yml ├── Cargo.toml ├── LICENSE ├── src ├── cli.rs ├── address.rs └── main.rs ├── README.md └── Cargo.lock /sample.txt: -------------------------------------------------------------------------------- 1 | 1Kids 2 | 1Love -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # These are backup files generated by rustfmt 6 | **/*.rs.bk 7 | 8 | # MacOs files 9 | .DS_Store -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "10:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nakatoshi" 3 | version = "0.2.8" 4 | authors = ["ndelvalle "] 5 | edition = "2018" 6 | description = "Bitcoin vanity address generator" 7 | license = "MIT" 8 | readme = "README.md" 9 | homepage = "https://github.com/ndelvalle/nakatoshi" 10 | repository = "https://github.com/ndelvalle/nakatoshi" 11 | keywords = ["bitcoin", "address", "vanity", "vanity-address"] 12 | categories = ["command-line-utilities"] 13 | 14 | [dependencies] 15 | bitcoin = "0.29.2" 16 | clap = "4.5.0" 17 | time = "0.3.30" 18 | rayon = "1.8.1" 19 | getrandom = "0.2.12" 20 | serde = "1.0.185" 21 | serde_json = "1.0.109" 22 | spinners = "4.1.0" 23 | num_cpus = "1.16.0" 24 | indicatif = "0.17.8" 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Nicolas Del Valle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | 8 | jobs: 9 | rust-integration-jobs: 10 | name: rust-integration-jobs 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | rust: 15 | - stable 16 | steps: 17 | - name: Checkout sources 18 | uses: actions/checkout@v1 19 | 20 | - name: Install toolchain 21 | uses: actions-rs/toolchain@v1 22 | with: 23 | toolchain: ${{ matrix.rust }} 24 | override: true 25 | 26 | - name: Install rustfmt 27 | run: rustup component add rustfmt 28 | 29 | - name: Install clippy 30 | run: rustup component add clippy 31 | 32 | - uses: actions/cache@v2 33 | with: 34 | path: | 35 | ~/.cargo/registry 36 | ~/.cargo/git 37 | target 38 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 39 | 40 | - name: Run cargo fmt 41 | uses: actions-rs/cargo@v1 42 | with: 43 | command: fmt 44 | args: --all -- --check 45 | 46 | - name: Run cargo check 47 | uses: actions-rs/cargo@v1 48 | with: 49 | command: check 50 | 51 | - name: Run cargo clippy 52 | uses: actions-rs/cargo@v1 53 | with: 54 | command: clippy 55 | args: -- -D warnings 56 | 57 | - name: Run cargo test 58 | uses: actions-rs/cargo@v1 59 | with: 60 | command: test 61 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*.*.*' 7 | 8 | jobs: 9 | publish: 10 | name: Publish ${{ matrix.os }} 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | include: 15 | - os: ubuntu-latest 16 | artifact_name: nakatoshi 17 | asset_name: nakatoshi-linux-amd64 18 | - os: macos-latest 19 | artifact_name: nakatoshi 20 | asset_name: nakatoshi-macos-amd64 21 | 22 | steps: 23 | - name: Checkout sources 24 | uses: actions/checkout@v1 25 | 26 | - name: Install toolchain 27 | uses: actions-rs/toolchain@v1 28 | with: 29 | toolchain: stable 30 | override: true 31 | 32 | - uses: actions/cache@v2 33 | with: 34 | path: | 35 | ~/.cargo/registry 36 | ~/.cargo/git 37 | target 38 | key: ${{ matrix.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 39 | 40 | - name: Build 41 | run: | 42 | cargo build --all --release --locked 43 | strip target/release/nakatoshi 44 | cd target/release && tar -czf nakatoshi.tar.gz nakatoshi 45 | mv nakatoshi.tar.gz ${{ matrix.asset_name }}.tar.gz 46 | 47 | - name: Release 48 | uses: softprops/action-gh-release@v1 49 | with: 50 | files: target/release/${{ matrix.asset_name }}.tar.gz 51 | env: 52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 53 | 54 | - name: Publish package to rust package registry 55 | # Push to crates.io only once. 56 | if: matrix.os == 'ubuntu-latest' 57 | run: | 58 | cargo package 59 | cargo publish --token ${{ secrets.CARGO_TOKEN }} 60 | -------------------------------------------------------------------------------- /src/cli.rs: -------------------------------------------------------------------------------- 1 | pub fn prompt() -> clap::Command { 2 | clap::Command::new(env!("CARGO_PKG_NAME")) 3 | .version(env!("CARGO_PKG_VERSION")) 4 | .about(env!("CARGO_PKG_DESCRIPTION")) 5 | .arg( 6 | clap::Arg::new("prefix") 7 | .index(1) 8 | .required_unless_present_any(["input-file"]) 9 | .help("Prefix used to match addresses"), 10 | ) 11 | .arg( 12 | clap::Arg::new("input-file") 13 | .short('i') 14 | .long("input-file") 15 | .required_unless_present_any(["prefix"]) 16 | .help("File with prefixes to match addresses with"), 17 | ) 18 | .arg( 19 | clap::Arg::new("threads") 20 | .short('t') 21 | .long("threads") 22 | // This is not the actual default value, it is here to pretty display 23 | // the information. 24 | .default_value("The number of CPUs available on the current system") 25 | .help("Number of threads to be used"), 26 | ) 27 | .arg( 28 | clap::Arg::new("case-sensitive") 29 | .short('c') 30 | .long("case-sensitive") 31 | .action(clap::ArgAction::SetTrue) 32 | .help("Use case sensitive comparison to match addresses"), 33 | ) 34 | .arg( 35 | clap::Arg::new("bech32") 36 | .conflicts_with("case-sensitive") 37 | .short('b') 38 | .long("bech32") 39 | .action(clap::ArgAction::SetTrue) 40 | .help("Use Bech32 addresses. Starting with bc1q (Lowercase address)"), 41 | ) 42 | .arg( 43 | clap::Arg::new("uncompressed") 44 | .short('u') 45 | .long("uncompressed") 46 | .action(clap::ArgAction::SetTrue) 47 | .help("Use uncompressed private an public keys"), 48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /src/address.rs: -------------------------------------------------------------------------------- 1 | use bitcoin::network::constants::Network; 2 | use bitcoin::secp256k1; 3 | use bitcoin::secp256k1::{Secp256k1, SecretKey, Signing}; 4 | use bitcoin::util::address::Address; 5 | use bitcoin::util::key::{PrivateKey, PublicKey}; 6 | 7 | pub struct BitcoinAddress { 8 | pub private_key: PrivateKey, 9 | pub public_key: PublicKey, 10 | pub address: Address, 11 | } 12 | 13 | impl BitcoinAddress { 14 | pub fn new(secp: &Secp256k1, is_compressed: bool, is_bech32: bool) -> Self { 15 | let random_bytes = get_random_bytes(); 16 | let secret_key = 17 | SecretKey::from_slice(&random_bytes).expect("Failed to create Bitcoin secret key"); 18 | 19 | let private_key = PrivateKey { 20 | compressed: is_compressed, 21 | network: Network::Bitcoin, 22 | inner: secret_key, 23 | }; 24 | 25 | let public_key = PublicKey::from_private_key(secp, &private_key); 26 | 27 | let address: Address = if is_bech32 { 28 | Address::p2wpkh(&public_key, Network::Bitcoin) 29 | .expect("Failed to create Bitcoin bech32 address") 30 | } else { 31 | Address::p2pkh(&public_key, Network::Bitcoin) 32 | }; 33 | 34 | Self { 35 | private_key, 36 | public_key, 37 | address, 38 | } 39 | } 40 | 41 | pub fn starts_with(&self, prefix: &str, is_case_sensitive: bool) -> bool { 42 | if is_case_sensitive { 43 | self.address.to_string().starts_with(prefix) 44 | } else { 45 | self.address 46 | .to_string() 47 | .to_lowercase() 48 | .starts_with(prefix.to_lowercase().as_str()) 49 | } 50 | } 51 | 52 | pub fn starts_with_any(&self, prefixes: &[String], is_case_sensitive: bool) -> bool { 53 | for prefix in prefixes { 54 | if self.starts_with(prefix, is_case_sensitive) { 55 | return true; 56 | } 57 | } 58 | false 59 | } 60 | } 61 | 62 | fn get_random_bytes() -> [u8; secp256k1::constants::SECRET_KEY_SIZE] { 63 | let mut buf = [0u8; secp256k1::constants::SECRET_KEY_SIZE]; 64 | getrandom::getrandom(&mut buf).expect("Failed to create random bytes"); 65 | buf 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nakatoshi 2 | 3 | [![](https://github.com/ndelvalle/nakatoshi/workflows/Rust/badge.svg)](https://github.com/ndelvalle/nakatoshi/actions?query=workflow%3ARust) 4 | 5 | A [Bitcoin Vanity Address](https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc#vanity-addresses) generator. 6 | 7 | nakatoshi accepts as input a prefix string (Or a file with multiple prefixes) to search for and produce 8 | a Bitcoin address and private / public keys. The amount of time required to find a given pattern depends 9 | on how long the string is, the speed of your computer, and whether you get lucky. 10 | 11 | ## Install 12 | 13 | ### MacOS 14 | 15 | ``` 16 | $ brew tap ndelvalle/utilities 17 | $ brew install nakatoshi 18 | ``` 19 | 20 | ### Cargo 21 | 22 | ``` 23 | $ cargo install nakatoshi 24 | ``` 25 | 26 | ### Manually 27 | 28 | Download the latest [released binary](https://github.com/ndelvalle/nakatoshi/releases) 29 | and add executable permissions: 30 | 31 | ```bash 32 | # Linux example: 33 | $ wget -O nakatoshi "https://github.com/ndelvalle/nakatoshi/releases/download/v0.2.4/nakatoshi-linux-amd64" 34 | $ chmod +x nakatoshi 35 | ``` 36 | 37 | ## CLI 38 | 39 | ``` 40 | USAGE: 41 | nakatoshi [FLAGS] [OPTIONS] --input-file 42 | 43 | FLAGS: 44 | -b, --bech32 Use Bech32 addresses. Starting with bc1q (Lowercase address) 45 | -c, --case-sensitive Use case sensitive comparison to match addresses 46 | -h, --help Prints help information 47 | -u, --uncompressed Use uncompressed private an public keys 48 | -V, --version Prints version information 49 | 50 | OPTIONS: 51 | -i, --input-file File with prefixes to match addresses with 52 | -t, --threads Number of threads to be used [default: The number of CPUs available on the current 53 | system] 54 | 55 | ARGS: 56 | Prefix used to match addresses 57 | ``` 58 | 59 | 60 | ## Examples: 61 | 62 | #### Generate a vanity address 63 | 64 | ```shell 65 | nakatoshi 1Kids 66 | ``` 67 | 68 | #### Generate a vanity address and parse JSON response 69 | 70 | ```shell 71 | nakatoshi 1Bitc | jq 72 | ``` 73 | 74 | #### Use a file with multiple prefixes 75 | 76 | A file with one address prefix on each newline can be used to search for a vanity 77 | address. This reduces the time to find a result. 78 | 79 | Example: 80 | 81 | ```shell 82 | nakatoshi --input-file input.txt 83 | ``` 84 | 85 | The contents of the `input.txt` file looks like this: 86 | ``` 87 | 1Kids 88 | 1Love 89 | ``` 90 | 91 | #### Bech32 addresses 92 | 93 | ```shell 94 | nakatoshi -b bc1qki 95 | ``` 96 | 97 | Note: There is no need to search with the `case-sensitive` flag because `bc1q` addresses are 98 | always lowercase. 99 | 100 | ## Development 101 | 102 | ```shell 103 | # Build 104 | $ cargo build 105 | 106 | # Help 107 | $ cargo run -- -help 108 | ``` 109 | 110 | Note: `Cargo run` creates an unoptimized executable with debug info. When testing 111 | the speed/throughput of the application, make sure to use `cargo run --release`. 112 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use bitcoin::secp256k1::Secp256k1; 2 | use indicatif::{ProgressBar, ProgressStyle}; 3 | use rayon::iter::ParallelIterator; 4 | use serde_json::json; 5 | use std::fs; 6 | use std::io::BufRead; 7 | use std::io::BufReader; 8 | 9 | mod address; 10 | mod cli; 11 | 12 | use address::BitcoinAddress; 13 | 14 | fn main() { 15 | let matches = cli::prompt().get_matches(); 16 | let secp = Secp256k1::new(); 17 | 18 | let is_case_sensitive = matches.get_flag("case-sensitive"); 19 | let is_bech32 = matches.get_flag("bech32"); 20 | let is_compressed = !matches.get_flag("uncompressed"); 21 | 22 | let num_threads = matches 23 | .get_one::("threads") 24 | .and_then(|num_threads| num_threads.parse().ok()) 25 | .unwrap_or_else(num_cpus::get); 26 | 27 | let prefixes = match matches.get_one::("prefix") { 28 | Some(prefix) => vec![prefix.to_owned()], 29 | None => { 30 | let file_name = matches.get_one::("input-file").unwrap(); 31 | get_prefixes_from_file(file_name) 32 | } 33 | }; 34 | 35 | let rayon_pool = rayon::ThreadPoolBuilder::new() 36 | .num_threads(num_threads) 37 | .build() 38 | .expect("Failed to create thread pool"); 39 | 40 | let progress = ProgressBar::new_spinner(); 41 | let template = ProgressStyle::default_bar() 42 | .template("[{elapsed_precise}] {pos} attempts") 43 | .unwrap(); 44 | progress.set_style(template); 45 | // progress.set_draw_rate(10); 46 | 47 | let bitcoin_address: BitcoinAddress = rayon_pool.install(|| { 48 | rayon::iter::repeat(BitcoinAddress::new) 49 | .inspect(|_| progress.inc(1)) 50 | .map(|create| create(&secp, is_compressed, is_bech32)) 51 | .find_any(|address| address.starts_with_any(&prefixes, is_case_sensitive)) 52 | .expect("Failed to find Bitcoin address match") 53 | }); 54 | 55 | let attempts = progress.position(); 56 | progress.finish_and_clear(); 57 | 58 | let result = json!({ 59 | "private_key": bitcoin_address.private_key.to_string(), 60 | "public_key": bitcoin_address.public_key.to_string(), 61 | "address": bitcoin_address.address.to_string(), 62 | "attempts": attempts 63 | }); 64 | 65 | print!("{}", result); 66 | } 67 | 68 | fn get_prefixes_from_file(file_name: &str) -> Vec { 69 | let file = fs::File::open(file_name).unwrap(); 70 | let buffer = BufReader::new(file); 71 | 72 | let mut prefixes = buffer 73 | .lines() 74 | .map(|line| line.expect("Failed to read Bitcoin address pattern from input file")) 75 | .collect::>(); 76 | 77 | prefixes.sort_by_key(|a| a.len()); 78 | prefixes 79 | } 80 | 81 | #[cfg(test)] 82 | mod tests { 83 | use crate::address::BitcoinAddress; 84 | use bitcoin::secp256k1::Secp256k1; 85 | 86 | #[test] 87 | fn create_compressed_bitcoin_public_key() { 88 | let secp = Secp256k1::new(); 89 | let is_bech32 = false; 90 | let is_compressed = true; 91 | let bitcoin_address = BitcoinAddress::new(&secp, is_compressed, is_bech32); 92 | 93 | let actual = bitcoin_address.public_key.to_string().len(); 94 | let expected = 66; 95 | 96 | assert_eq!(actual, expected); 97 | } 98 | 99 | #[test] 100 | fn create_uncompressed_bitcoin_public_key() { 101 | let secp = Secp256k1::new(); 102 | let is_bech32 = false; 103 | let is_compressed = false; 104 | let bitcoin_address = BitcoinAddress::new(&secp, is_compressed, is_bech32); 105 | 106 | let actual = bitcoin_address.public_key.to_string().len(); 107 | let expected = 130; 108 | 109 | assert_eq!(actual, expected); 110 | } 111 | 112 | #[test] 113 | fn create_bech32_address() { 114 | let secp = Secp256k1::new(); 115 | let is_bech32 = true; 116 | let is_compressed = true; 117 | let bitcoin_address = BitcoinAddress::new(&secp, is_compressed, is_bech32); 118 | let address = bitcoin_address.address.to_string(); 119 | 120 | assert!(address.starts_with("bc1q")); 121 | } 122 | 123 | #[test] 124 | fn create_bitcoin_private_key() { 125 | let secp = Secp256k1::new(); 126 | let is_bech32 = false; 127 | let is_compressed = true; 128 | let bitcoin_address = BitcoinAddress::new(&secp, is_compressed, is_bech32); 129 | 130 | let actual = bitcoin_address.private_key.to_string().len(); 131 | let expected = 52; 132 | 133 | assert_eq!(actual, expected); 134 | } 135 | 136 | #[test] 137 | fn create_bitcoin_address() { 138 | let secp = Secp256k1::new(); 139 | let is_bech32 = false; 140 | let is_compressed = true; 141 | let bitcoin_address = BitcoinAddress::new(&secp, is_compressed, is_bech32); 142 | 143 | let actual = bitcoin_address.address.to_string().len(); 144 | let expected = 34; 145 | 146 | assert_eq!(actual, expected); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.7" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "utf8parse", 17 | ] 18 | 19 | [[package]] 20 | name = "anstyle" 21 | version = "1.0.0" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" 24 | 25 | [[package]] 26 | name = "anstyle-parse" 27 | version = "0.2.0" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" 30 | dependencies = [ 31 | "utf8parse", 32 | ] 33 | 34 | [[package]] 35 | name = "anstyle-query" 36 | version = "1.0.0" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" 39 | dependencies = [ 40 | "windows-sys", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle-wincon" 45 | version = "3.0.1" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" 48 | dependencies = [ 49 | "anstyle", 50 | "windows-sys", 51 | ] 52 | 53 | [[package]] 54 | name = "autocfg" 55 | version = "1.1.0" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 58 | 59 | [[package]] 60 | name = "bech32" 61 | version = "0.9.1" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" 64 | 65 | [[package]] 66 | name = "bitcoin" 67 | version = "0.29.2" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" 70 | dependencies = [ 71 | "bech32", 72 | "bitcoin_hashes", 73 | "secp256k1", 74 | ] 75 | 76 | [[package]] 77 | name = "bitcoin_hashes" 78 | version = "0.11.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" 81 | 82 | [[package]] 83 | name = "cc" 84 | version = "1.0.73" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 87 | 88 | [[package]] 89 | name = "cfg-if" 90 | version = "1.0.0" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 93 | 94 | [[package]] 95 | name = "clap" 96 | version = "4.5.0" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" 99 | dependencies = [ 100 | "clap_builder", 101 | ] 102 | 103 | [[package]] 104 | name = "clap_builder" 105 | version = "4.5.0" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" 108 | dependencies = [ 109 | "anstream", 110 | "anstyle", 111 | "clap_lex", 112 | "strsim", 113 | ] 114 | 115 | [[package]] 116 | name = "clap_lex" 117 | version = "0.7.0" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" 120 | 121 | [[package]] 122 | name = "colorchoice" 123 | version = "1.0.0" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 126 | 127 | [[package]] 128 | name = "console" 129 | version = "0.15.0" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" 132 | dependencies = [ 133 | "encode_unicode", 134 | "libc", 135 | "once_cell", 136 | "regex", 137 | "terminal_size", 138 | "unicode-width", 139 | "winapi", 140 | ] 141 | 142 | [[package]] 143 | name = "crossbeam-deque" 144 | version = "0.8.1" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" 147 | dependencies = [ 148 | "cfg-if", 149 | "crossbeam-epoch", 150 | "crossbeam-utils", 151 | ] 152 | 153 | [[package]] 154 | name = "crossbeam-epoch" 155 | version = "0.9.7" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" 158 | dependencies = [ 159 | "cfg-if", 160 | "crossbeam-utils", 161 | "lazy_static", 162 | "memoffset", 163 | "scopeguard", 164 | ] 165 | 166 | [[package]] 167 | name = "crossbeam-utils" 168 | version = "0.8.7" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" 171 | dependencies = [ 172 | "cfg-if", 173 | "lazy_static", 174 | ] 175 | 176 | [[package]] 177 | name = "deranged" 178 | version = "0.3.9" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" 181 | dependencies = [ 182 | "powerfmt", 183 | ] 184 | 185 | [[package]] 186 | name = "either" 187 | version = "1.6.1" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 190 | 191 | [[package]] 192 | name = "encode_unicode" 193 | version = "0.3.6" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 196 | 197 | [[package]] 198 | name = "getrandom" 199 | version = "0.2.12" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" 202 | dependencies = [ 203 | "cfg-if", 204 | "libc", 205 | "wasi", 206 | ] 207 | 208 | [[package]] 209 | name = "heck" 210 | version = "0.4.0" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 213 | 214 | [[package]] 215 | name = "hermit-abi" 216 | version = "0.3.1" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" 219 | 220 | [[package]] 221 | name = "indicatif" 222 | version = "0.17.8" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" 225 | dependencies = [ 226 | "console", 227 | "instant", 228 | "number_prefix", 229 | "portable-atomic", 230 | "unicode-width", 231 | ] 232 | 233 | [[package]] 234 | name = "instant" 235 | version = "0.1.12" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 238 | dependencies = [ 239 | "cfg-if", 240 | ] 241 | 242 | [[package]] 243 | name = "itoa" 244 | version = "1.0.1" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 247 | 248 | [[package]] 249 | name = "lazy_static" 250 | version = "1.4.0" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 253 | 254 | [[package]] 255 | name = "libc" 256 | version = "0.2.150" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" 259 | 260 | [[package]] 261 | name = "maplit" 262 | version = "1.0.2" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" 265 | 266 | [[package]] 267 | name = "memoffset" 268 | version = "0.6.5" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 271 | dependencies = [ 272 | "autocfg", 273 | ] 274 | 275 | [[package]] 276 | name = "nakatoshi" 277 | version = "0.2.8" 278 | dependencies = [ 279 | "bitcoin", 280 | "clap", 281 | "getrandom", 282 | "indicatif", 283 | "num_cpus", 284 | "rayon", 285 | "serde", 286 | "serde_json", 287 | "spinners", 288 | "time", 289 | ] 290 | 291 | [[package]] 292 | name = "num_cpus" 293 | version = "1.16.0" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 296 | dependencies = [ 297 | "hermit-abi", 298 | "libc", 299 | ] 300 | 301 | [[package]] 302 | name = "number_prefix" 303 | version = "0.4.0" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 306 | 307 | [[package]] 308 | name = "once_cell" 309 | version = "1.13.0" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" 312 | 313 | [[package]] 314 | name = "portable-atomic" 315 | version = "1.3.3" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" 318 | 319 | [[package]] 320 | name = "powerfmt" 321 | version = "0.2.0" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 324 | 325 | [[package]] 326 | name = "proc-macro2" 327 | version = "1.0.36" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" 330 | dependencies = [ 331 | "unicode-xid", 332 | ] 333 | 334 | [[package]] 335 | name = "quote" 336 | version = "1.0.15" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" 339 | dependencies = [ 340 | "proc-macro2", 341 | ] 342 | 343 | [[package]] 344 | name = "rayon" 345 | version = "1.8.1" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" 348 | dependencies = [ 349 | "either", 350 | "rayon-core", 351 | ] 352 | 353 | [[package]] 354 | name = "rayon-core" 355 | version = "1.12.1" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 358 | dependencies = [ 359 | "crossbeam-deque", 360 | "crossbeam-utils", 361 | ] 362 | 363 | [[package]] 364 | name = "regex" 365 | version = "1.5.6" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" 368 | dependencies = [ 369 | "regex-syntax", 370 | ] 371 | 372 | [[package]] 373 | name = "regex-syntax" 374 | version = "0.6.26" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" 377 | 378 | [[package]] 379 | name = "rustversion" 380 | version = "1.0.6" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" 383 | 384 | [[package]] 385 | name = "ryu" 386 | version = "1.0.9" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 389 | 390 | [[package]] 391 | name = "scopeguard" 392 | version = "1.1.0" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 395 | 396 | [[package]] 397 | name = "secp256k1" 398 | version = "0.24.2" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "d9512ffd81e3a3503ed401f79c33168b9148c75038956039166cd750eaa037c3" 401 | dependencies = [ 402 | "bitcoin_hashes", 403 | "secp256k1-sys", 404 | ] 405 | 406 | [[package]] 407 | name = "secp256k1-sys" 408 | version = "0.6.1" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" 411 | dependencies = [ 412 | "cc", 413 | ] 414 | 415 | [[package]] 416 | name = "serde" 417 | version = "1.0.185" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" 420 | 421 | [[package]] 422 | name = "serde_json" 423 | version = "1.0.109" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9" 426 | dependencies = [ 427 | "itoa", 428 | "ryu", 429 | "serde", 430 | ] 431 | 432 | [[package]] 433 | name = "spinners" 434 | version = "4.1.0" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "08615eea740067d9899969bc2891c68a19c315cb1f66640af9a9ecb91b13bcab" 437 | dependencies = [ 438 | "lazy_static", 439 | "maplit", 440 | "strum", 441 | ] 442 | 443 | [[package]] 444 | name = "strsim" 445 | version = "0.11.0" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" 448 | 449 | [[package]] 450 | name = "strum" 451 | version = "0.24.0" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "e96acfc1b70604b8b2f1ffa4c57e59176c7dbb05d556c71ecd2f5498a1dee7f8" 454 | dependencies = [ 455 | "strum_macros", 456 | ] 457 | 458 | [[package]] 459 | name = "strum_macros" 460 | version = "0.24.0" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef" 463 | dependencies = [ 464 | "heck", 465 | "proc-macro2", 466 | "quote", 467 | "rustversion", 468 | "syn", 469 | ] 470 | 471 | [[package]] 472 | name = "syn" 473 | version = "1.0.86" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" 476 | dependencies = [ 477 | "proc-macro2", 478 | "quote", 479 | "unicode-xid", 480 | ] 481 | 482 | [[package]] 483 | name = "terminal_size" 484 | version = "0.1.17" 485 | source = "registry+https://github.com/rust-lang/crates.io-index" 486 | checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" 487 | dependencies = [ 488 | "libc", 489 | "winapi", 490 | ] 491 | 492 | [[package]] 493 | name = "time" 494 | version = "0.3.30" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" 497 | dependencies = [ 498 | "deranged", 499 | "powerfmt", 500 | "serde", 501 | "time-core", 502 | ] 503 | 504 | [[package]] 505 | name = "time-core" 506 | version = "0.1.2" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 509 | 510 | [[package]] 511 | name = "unicode-width" 512 | version = "0.1.9" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" 515 | 516 | [[package]] 517 | name = "unicode-xid" 518 | version = "0.2.2" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 521 | 522 | [[package]] 523 | name = "utf8parse" 524 | version = "0.2.1" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 527 | 528 | [[package]] 529 | name = "wasi" 530 | version = "0.11.0+wasi-snapshot-preview1" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 533 | 534 | [[package]] 535 | name = "winapi" 536 | version = "0.3.9" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 539 | dependencies = [ 540 | "winapi-i686-pc-windows-gnu", 541 | "winapi-x86_64-pc-windows-gnu", 542 | ] 543 | 544 | [[package]] 545 | name = "winapi-i686-pc-windows-gnu" 546 | version = "0.4.0" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 549 | 550 | [[package]] 551 | name = "winapi-x86_64-pc-windows-gnu" 552 | version = "0.4.0" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 555 | 556 | [[package]] 557 | name = "windows-sys" 558 | version = "0.48.0" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 561 | dependencies = [ 562 | "windows-targets", 563 | ] 564 | 565 | [[package]] 566 | name = "windows-targets" 567 | version = "0.48.0" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" 570 | dependencies = [ 571 | "windows_aarch64_gnullvm", 572 | "windows_aarch64_msvc", 573 | "windows_i686_gnu", 574 | "windows_i686_msvc", 575 | "windows_x86_64_gnu", 576 | "windows_x86_64_gnullvm", 577 | "windows_x86_64_msvc", 578 | ] 579 | 580 | [[package]] 581 | name = "windows_aarch64_gnullvm" 582 | version = "0.48.0" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 585 | 586 | [[package]] 587 | name = "windows_aarch64_msvc" 588 | version = "0.48.0" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 591 | 592 | [[package]] 593 | name = "windows_i686_gnu" 594 | version = "0.48.0" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 597 | 598 | [[package]] 599 | name = "windows_i686_msvc" 600 | version = "0.48.0" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 603 | 604 | [[package]] 605 | name = "windows_x86_64_gnu" 606 | version = "0.48.0" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 609 | 610 | [[package]] 611 | name = "windows_x86_64_gnullvm" 612 | version = "0.48.0" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 615 | 616 | [[package]] 617 | name = "windows_x86_64_msvc" 618 | version = "0.48.0" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 621 | --------------------------------------------------------------------------------