10 releases (6 breaking)
0.6.0 | Oct 2, 2024 |
---|---|
0.4.0 | Aug 20, 2024 |
0.3.2 | Mar 6, 2024 |
0.3.0 | Jun 6, 2023 |
0.0.0 | Mar 7, 2021 |
#8 in #sapling
6,383 downloads per month
Used in 23 crates
(10 directly)
775KB
10K
SLoC
zcash_address
Zcash address parsing and serialization. This library allows its users to easily recognize and give good error messages for new Zcash address types.
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
lib.rs
:
Parser for all defined Zcash address types.
This crate implements address parsing as a two-phase process, built around the opaque
ZcashAddress
type.
ZcashAddress
can be parsed from, and encoded to, strings.ZcashAddress::convert
orZcashAddress::convert_if_network
can be used to convert a parsed address into custom types that implement theTryFromAddress
orTryFromRawAddress
traits.- Custom types can be converted into a
ZcashAddress
via its implementation of theToAddress
trait.
s.parse() .convert()
--------> --------->
Strings ZcashAddress Custom types
<-------- <---------
.encode() ToAddress
It is important to note that this crate does not depend on any of the Zcash protocol
crates (e.g. sapling-crypto
or orchard
). This crate has minimal dependencies by
design; it focuses solely on parsing, handling those concerns for you, while exposing
APIs that enable you to convert the parsed data into the Rust types you want to use.
Using this crate
I just need to validate Zcash addresses
fn is_valid_zcash_address(addr_string: &str) -> bool {
addr_string.parse::<ZcashAddress>().is_ok()
}
I want to parse Zcash addresses in a Rust wallet app that uses the zcash_primitives
transaction builder
Use zcash_client_backend::address::RecipientAddress
, which implements the traits in
this crate to parse address strings into protocol types that work with the transaction
builder in the zcash_primitives
crate (as well as the wallet functionality in the
zcash_client_backend
crate itself).
We intend to refactor the key and address types from the
zcash_client_backend
andzcash_primitives
crates into a separate crate focused on dealing with Zcash key material. That crate will then be what you should use.
I want to parse Unified Addresses
See the unified::Address
documentation for examples.
While the unified::Address
type does have parsing methods, you should still parse
your address strings with ZcashAddress
and then convert; this will ensure that for
other Zcash address types you get a ConversionError::Unsupported
, which is a
better error for your users.
I want to parse mainnet Zcash addresses in a language that supports C FFI
As an example, you could use static functions to create the address types in the target language from the parsed data.
use std::ffi::{CStr, c_char, c_void};
use std::ptr;
use zcash_address::{ConversionError, Network, TryFromRawAddress, ZcashAddress};
// Functions that return a pointer to a heap-allocated address of the given kind in
// the target language. These should be augmented to return any relevant errors.
extern {
fn addr_from_sapling(data: *const u8) -> *mut c_void;
fn addr_from_transparent_p2pkh(data: *const u8) -> *mut c_void;
}
struct ParsedAddress(*mut c_void);
impl TryFromRawAddress for ParsedAddress {
type Error = &'static str;
fn try_from_raw_sapling(
data: [u8; 43],
) -> Result<Self, ConversionError<Self::Error>> {
let parsed = unsafe { addr_from_sapling(data[..].as_ptr()) };
if parsed.is_null() {
Err("Reason for the failure".into())
} else {
Ok(Self(parsed))
}
}
fn try_from_raw_transparent_p2pkh(
data: [u8; 20],
) -> Result<Self, ConversionError<Self::Error>> {
let parsed = unsafe { addr_from_transparent_p2pkh(data[..].as_ptr()) };
if parsed.is_null() {
Err("Reason for the failure".into())
} else {
Ok(Self(parsed))
}
}
}
pub extern "C" fn parse_zcash_address(encoded: *const c_char) -> *mut c_void {
let encoded = unsafe { CStr::from_ptr(encoded) }.to_str().expect("valid");
let addr = match ZcashAddress::try_from_encoded(encoded) {
Ok(addr) => addr,
Err(e) => {
// This was either an invalid address encoding, or not a Zcash address.
// You should pass this error back across the FFI.
return ptr::null_mut();
}
};
match addr.convert_if_network::<ParsedAddress>(Network::Main) {
Ok(parsed) => parsed.0,
Err(e) => {
// We didn't implement all of the methods of `TryFromRawAddress`, so if an
// address with one of those kinds is parsed, it will result in an error
// here that should be passed back across the FFI.
ptr::null_mut()
}
}
}
Dependencies
~1.1–1.9MB
~36K SLoC