zcash_client_backend: Migrate `RecipientAddress` to `zcash_address`

This commit is contained in:
Jack Grigg 2022-06-06 19:30:23 +00:00
parent b8e8a0c491
commit f20366cf86
2 changed files with 43 additions and 18 deletions

View File

@ -33,6 +33,7 @@ secp256k1 = { version = "0.21", optional = true }
sha2 = { version = "0.10.1", optional = true }
subtle = "2.2.3"
time = "0.2"
zcash_address = { version = "0.1", path = "../components/zcash_address" }
zcash_note_encryption = { version = "0.1", path = "../components/zcash_note_encryption" }
zcash_primitives = { version = "0.6", path = "../zcash_primitives" }

View File

@ -1,11 +1,17 @@
//! Structs for handling supported address types.
use zcash_primitives::{consensus, legacy::TransparentAddress, sapling::PaymentAddress};
use zcash_address::{ConversionError, Network, ToAddress, TryFromRawAddress, ZcashAddress};
use zcash_primitives::{consensus, constants, legacy::TransparentAddress, sapling::PaymentAddress};
use crate::encoding::{
decode_payment_address, decode_transparent_address, encode_payment_address_p,
encode_transparent_address_p,
};
fn params_to_network<P: consensus::Parameters>(params: &P) -> Network {
// Use the Sapling HRP as an indicator of network.
match params.hrp_sapling_payment_address() {
constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS => Network::Main,
constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS => Network::Test,
constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS => Network::Regtest,
_ => panic!("Unsupported network kind"),
}
}
/// An address that funds can be sent to.
// TODO: rename to ParsedAddress
@ -27,25 +33,43 @@ impl From<TransparentAddress> for RecipientAddress {
}
}
impl TryFromRawAddress for RecipientAddress {
type Error = &'static str;
fn try_from_raw_sapling(data: [u8; 43]) -> Result<Self, ConversionError<Self::Error>> {
let pa = PaymentAddress::from_bytes(&data).ok_or("Invalid Sapling payment address")?;
Ok(pa.into())
}
fn try_from_raw_transparent_p2pkh(
data: [u8; 20],
) -> Result<Self, ConversionError<Self::Error>> {
Ok(TransparentAddress::PublicKey(data).into())
}
fn try_from_raw_transparent_p2sh(data: [u8; 20]) -> Result<Self, ConversionError<Self::Error>> {
Ok(TransparentAddress::Script(data).into())
}
}
impl RecipientAddress {
pub fn decode<P: consensus::Parameters>(params: &P, s: &str) -> Option<Self> {
if let Ok(Some(pa)) = decode_payment_address(params.hrp_sapling_payment_address(), s) {
Some(pa.into())
} else if let Ok(Some(addr)) = decode_transparent_address(
&params.b58_pubkey_address_prefix(),
&params.b58_script_address_prefix(),
s,
) {
Some(addr.into())
} else {
None
}
let addr = ZcashAddress::try_from_encoded(s).ok()?;
addr.convert_if_network(params_to_network(params)).ok()
}
pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String {
let net = params_to_network(params);
match self {
RecipientAddress::Shielded(pa) => encode_payment_address_p(params, pa),
RecipientAddress::Transparent(addr) => encode_transparent_address_p(params, addr),
RecipientAddress::Shielded(pa) => ZcashAddress::from_sapling(net, pa.to_bytes()),
RecipientAddress::Transparent(addr) => match addr {
TransparentAddress::PublicKey(data) => {
ZcashAddress::from_transparent_p2pkh(net, *data)
}
TransparentAddress::Script(data) => ZcashAddress::from_transparent_p2sh(net, *data),
},
}
.to_string()
}
}