Skip to content

Commit d1b0608

Browse files
committed
chore: bump version to 0.3.0
2 parents ad1116d + fcc821e commit d1b0608

File tree

19 files changed

+845
-106
lines changed

19 files changed

+845
-106
lines changed

Cargo.lock

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ The library strictly adheres to the following standards:
3434
* **[Ed25519](https://ed25519.cr.yp.to/)**: High-speed Edwards-curve Digital Signature Algorithm.
3535
* **[Base58](https://learn.bybit.com/blockchain/what-is-base58/)**: Standard Solana address encoding.
3636

37+
### TON (The Open Network)
38+
* **[V4R2](https://ton.org/docs)**: Standard high-performance wallet contract (Wallet ID `0x29a9a317`).
39+
* **[V5R1](https://docs.ton.org/v3/guidelines/smart-contracts/wallet-v5)**: Latest W5 standard (Wallet ID `0x7fffff11`), optimized for gasless operations.
40+
* **Smart Addresses**: Generates non-bounceable (UQ) addresses by default, and automatically switches to bounceable (EQ) if the prefix starts with `E`.
41+
3742
## Architecture
3843

3944
The project employs a specific **Verify-after-Generate** architecture to eliminate single points of failure in the cryptographic logic.
@@ -42,7 +47,7 @@ The project employs a specific **Verify-after-Generate** architecture to elimina
4247
Using the `rand::OsRng` system entropy source, a 256-bit private key is generated. The corresponding public key and address are derived via RustCrypto or libsecp256k1. This process is parallelized across all logical CPU cores using a work-stealing scheduler (`rayon`).
4348

4449
2. **Cross-Verification (Python)**:
45-
Upon identifying a candidate address matching the user's constraints, the key material is passed to an isolated subprocess. This process invokes reference Python implementations (`eth_account` for Ethereum, `base58`/`bech32` for Bitcoin) to independently re-derive the address from the private key.
50+
Upon identifying a candidate address matching the user's constraints, the key material is passed to an isolated subprocess. This process invokes reference Python implementations (`eth_account` for Ethereum, `base58`/`bech32` for Bitcoin, manual derivation for TON) to independently re-derive the address from the private key.
4651

4752
3. **Validation**:
4853
The result is presented to the user **if and only if** the Rust-derived address and the Python-derived address are bitwise identical.
@@ -112,13 +117,20 @@ vc --chain bitcoin --btc-type taproot --prefix bc1p
112117

113118
# Solana
114119
vc --chain solana --prefix abc
120+
121+
# TON (V4R2)
122+
vc --chain ton --ton-version v4r2 --prefix EQA
123+
124+
# TON (V5R1)
125+
vc --chain ton --ton-version v5r1 --prefix UQ
115126
```
116127

117128
| Argument | Description |
118129
| :--- | :--- |
119-
| `--chain <ethereum\|bitcoin\|solana>` | Select the blockchain network (Default: ethereum). |
130+
| `--chain <ethereum\|bitcoin\|solana\|ton>` | Select the blockchain network (Default: ethereum). |
120131
| `--prefix <STRING>` | The case-insensitive string to search for. |
121132
| `--btc-type <legacy\|segwit\|taproot>` | **[Bitcoin]** The address type to generate. |
133+
| `--ton-version <v4r2\|v5r1>` | **[TON]** The wallet contract version (Default: v4r2). |
122134
| `--case-sensitive` | Strictly enforce casing (e.g. `DeaD` vs `dead`). |
123135
| `--threads <N>` | Override thread count (Default: logical core count). |
124136
| `--no-tui` | Disable the TUI and output only the final result JSON. |
@@ -141,6 +153,10 @@ python3 tests/verify_validate/fuzz_test.py --chain bitcoin --btc-type legacy
141153

142154
# Audit Bitcoin (Taproot/Schnorr)
143155
python3 tests/verify_validate/fuzz_test.py --chain bitcoin --btc-type taproot
156+
157+
# Audit TON (V4R2 & V5R1)
158+
python3 tests/verify_validate/fuzz_test.py --chain ton --ton-version v4r2
159+
python3 tests/verify_validate/fuzz_test.py --chain ton --ton-version v5r1
144160
```
145161

146162
## License

crates/cli/src/main.rs

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use std::sync::Arc;
44
use std::{sync::mpsc, thread};
55
use vanity_core::VanityGenerator;
66
use vanity_ui::{
7-
app::{BitcoinType as UiBtcType, Chain as UiChain, Network as UiNetwork},
7+
app::{
8+
BitcoinType as UiBtcType, Chain as UiChain, Network as UiNetwork,
9+
TonVersion as UiTonVersion,
10+
},
811
run_tui,
912
};
1013
use vanity_wallet::{
@@ -16,6 +19,7 @@ enum Chain {
1619
Ethereum,
1720
Bitcoin,
1821
Solana,
22+
Ton,
1923
}
2024

2125
#[derive(Debug, Clone, ValueEnum)]
@@ -32,12 +36,37 @@ enum BtcType {
3236
Taproot,
3337
}
3438

39+
#[derive(Debug, Clone, ValueEnum)]
40+
enum TonVersion {
41+
V4R2,
42+
V5R1,
43+
}
44+
45+
impl From<TonVersion> for vanity_core::TonWalletVersion {
46+
fn from(v: TonVersion) -> Self {
47+
match v {
48+
TonVersion::V4R2 => vanity_core::TonWalletVersion::V4R2,
49+
TonVersion::V5R1 => vanity_core::TonWalletVersion::V5R1,
50+
}
51+
}
52+
}
53+
54+
impl From<TonVersion> for UiTonVersion {
55+
fn from(v: TonVersion) -> Self {
56+
match v {
57+
TonVersion::V4R2 => UiTonVersion::V4R2,
58+
TonVersion::V5R1 => UiTonVersion::V5R1,
59+
}
60+
}
61+
}
62+
3563
impl From<Chain> for UiChain {
3664
fn from(c: Chain) -> Self {
3765
match c {
3866
Chain::Ethereum => UiChain::Ethereum,
3967
Chain::Bitcoin => UiChain::Bitcoin,
4068
Chain::Solana => UiChain::Solana,
69+
Chain::Ton => UiChain::Ton,
4170
}
4271
}
4372
}
@@ -112,6 +141,10 @@ struct Args {
112141
#[arg(long, value_enum, default_value_t = BtcType::Segwit)]
113142
btc_type: BtcType,
114143

144+
/// TON wallet version (only used if chain is ton)
145+
#[arg(long, value_enum, default_value_t = TonVersion::V4R2)]
146+
ton_version: TonVersion,
147+
115148
/// Prefix must start with this string (e.g., "0xDEAD")
116149
#[arg(short, long, default_value = "")]
117150
prefix: String,
@@ -168,7 +201,8 @@ fn main() {
168201
p_case: bool,
169202
p_chain: UiChain,
170203
p_network: UiNetwork,
171-
p_btc_type: UiBtcType| {
204+
p_btc_type: UiBtcType,
205+
p_ton_version: UiTonVersion| {
172206
let p_prefix = if let Some(stripped) = p_prefix.strip_prefix("0x") {
173207
stripped.to_string()
174208
} else {
@@ -177,6 +211,7 @@ fn main() {
177211

178212
let my_attempts = attempts_clone.clone();
179213
let my_tx = tx.clone();
214+
// capture cli_ton_version only needed if not passed, but we pass it now.
180215

181216
thread::spawn(move || {
182217
let (pk, addr) = match p_chain {
@@ -197,6 +232,18 @@ fn main() {
197232
let gen = SolanaVanityGenerator::new(&p_prefix, &p_suffix, p_case);
198233
gen.search(Some(my_attempts))
199234
}
235+
UiChain::Ton => {
236+
// Convert UiTonVersion to CoreVersion manually
237+
let core_version: vanity_core::TonWalletVersion = p_ton_version.into();
238+
239+
let gen = vanity_wallet::TonVanityGenerator::new(
240+
&p_prefix,
241+
&p_suffix,
242+
p_case,
243+
core_version,
244+
);
245+
gen.search(Some(my_attempts))
246+
}
200247
};
201248

202249
// Send tuple (Address, PrivateKey) as strings
@@ -218,6 +265,7 @@ fn main() {
218265
let ui_chain: UiChain = cli_chain.into();
219266
let ui_network: UiNetwork = cli_network.into();
220267
let ui_btc_type: UiBtcType = cli_btc_type.into();
268+
let ui_ton_version: UiTonVersion = args.ton_version.clone().into();
221269

222270
// Spawn search thread directly
223271
on_search_start(
@@ -227,13 +275,14 @@ fn main() {
227275
ui_chain,
228276
ui_network,
229277
ui_btc_type,
278+
ui_ton_version,
230279
);
231280

232281
// Simple loop waiting for result
233282
loop {
234283
if let Ok(res) = rx.try_recv() {
235284
println!("\nAddress: {}\nPrivate Key: {}", res.0, res.1);
236-
run_verification(&res.1);
285+
run_verification(&res.1, &format!("{:?}", args.chain).to_lowercase());
237286
break;
238287
}
239288
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -256,6 +305,7 @@ fn main() {
256305
let initial_ui_chain: UiChain = cli_chain.into();
257306
let initial_ui_network: UiNetwork = cli_network.into();
258307
let initial_ui_btc_type: UiBtcType = cli_btc_type.into();
308+
let initial_ui_ton_version: UiTonVersion = args.ton_version.clone().into();
259309

260310
if start_immediately {
261311
on_search_start(
@@ -265,6 +315,7 @@ fn main() {
265315
initial_ui_chain,
266316
initial_ui_network,
267317
initial_ui_btc_type,
318+
initial_ui_ton_version,
268319
);
269320
}
270321

@@ -278,6 +329,7 @@ fn main() {
278329
initial_ui_chain,
279330
initial_ui_network,
280331
initial_ui_btc_type,
332+
initial_ui_ton_version,
281333
on_search_start,
282334
) {
283335
Ok(res) => res,
@@ -287,13 +339,14 @@ fn main() {
287339
}
288340
};
289341

290-
if let Some((_, pk)) = result {
291-
run_verification(&pk);
342+
if let Some((_, pk, chain)) = result {
343+
// TUI now returns the selected chain, so we use it for verification.
344+
run_verification(&pk, &format!("{:?}", chain).to_lowercase());
292345
}
293346
}
294347
}
295348

296-
fn run_verification(pk: &str) {
349+
fn run_verification(pk: &str, chain: &str) {
297350
// Check if python3 is available
298351
use std::process::Command;
299352

@@ -318,7 +371,11 @@ fn run_verification(pk: &str) {
318371
system_python
319372
};
320373

321-
let output = Command::new(python_cmd).arg(script_path).arg(pk).output();
374+
let output = Command::new(python_cmd)
375+
.arg(script_path)
376+
.arg(pk)
377+
.arg(chain)
378+
.output();
322379

323380
match output {
324381
Ok(out) => {
@@ -347,6 +404,12 @@ fn run_batch_generation(count: u64, args: &Args) {
347404
Box::new(BitcoinVanityGenerator::new("", "", false, net, t))
348405
}
349406
Chain::Solana => Box::new(SolanaVanityGenerator::new("", "", false)), // No prefix/suffix for batch random
407+
Chain::Ton => Box::new(vanity_wallet::TonVanityGenerator::new(
408+
"",
409+
"",
410+
false,
411+
args.ton_version.clone().into(),
412+
)),
350413
};
351414

352415
for _ in 0..count {

crates/cli/tests/snapshots/integration__help_snapshot.snap

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ Usage: vc [OPTIONS]
88

99
Options:
1010
--chain <CHAIN>
11-
Blockchain to generate address for [default: ethereum] [possible values: ethereum, bitcoin, solana]
11+
Blockchain to generate address for [default: ethereum] [possible values: ethereum, bitcoin, solana, ton]
1212
--network <NETWORK>
1313
Network (mainnet, testnet, regtest) [default: mainnet] [possible values: mainnet, testnet, regtest]
1414
--btc-type <BTC_TYPE>
1515
Bitcoin address type (only used if chain is bitcoin) [default: segwit] [possible values: legacy, segwit, taproot]
16+
--ton-version <TON_VERSION>
17+
TON wallet version (only used if chain is ton) [default: v4r2] [possible values: v4r2, v5r1]
1618
-p, --prefix <PREFIX>
1719
Prefix must start with this string (e.g., "0xDEAD") [default: ]
1820
-s, --suffix <SUFFIX>

crates/cli/tests/snapshots/integration__help_snapshot.snap.new

Lines changed: 0 additions & 30 deletions
This file was deleted.

crates/cli/tests/snapshots/integration__version_snapshot.snap.new

Lines changed: 0 additions & 6 deletions
This file was deleted.

crates/core/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ pub mod types;
55

66
pub use error::CoreError;
77
pub use traits::VanityGenerator;
8-
pub use types::{Address, PrivateKey};
8+
pub use types::{Address, PrivateKey, TonWalletVersion};

0 commit comments

Comments
 (0)