This commit is contained in:
Hanh 2021-08-27 16:03:45 +08:00
parent d78622d6bf
commit 1ef47bb3c4
3 changed files with 80 additions and 0 deletions

View File

@ -76,6 +76,11 @@ branch = "warp-sync"
git = "https://github.com/hhanh00/zcash-params.git"
branch = "main"
[dependencies.zcash_address]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "19a97f16945c68c33aedcc89f2a4f4d398658b05"
[build-dependencies]
tonic-build = "0.4.2"

View File

@ -21,6 +21,7 @@ mod commitment;
mod db;
mod hash;
mod key;
mod ua;
mod mempool;
mod pay;
mod prices;
@ -46,3 +47,4 @@ pub use crate::pay::{broadcast_tx, sign_offline_tx, Tx};
pub use crate::print::*;
pub use crate::scan::{latest_height, scan_all, sync_async};
pub use crate::wallet::{Wallet, WalletBalance};
pub use crate::ua::{get_sapling, get_ua};

73
src/ua.rs Normal file
View File

@ -0,0 +1,73 @@
use zcash_address::unified::{Receiver, Address};
use zcash_address::{FromAddress, Network, UnsupportedAddress, ZcashAddress, ToAddress};
use std::convert::TryFrom;
#[derive(Debug, Clone)]
pub struct MyReceiver {
pub net: Network,
pub receiver: Receiver,
}
impl FromAddress for MyReceiver {
fn from_sapling(net: Network, data: [u8; 43]) -> Result<Self, UnsupportedAddress> {
Ok(MyReceiver { net: net, receiver: Receiver::Sapling(data) })
}
fn from_unified(net: Network, data: Address) -> Result<Self, UnsupportedAddress> {
for r in data.receivers().iter() {
match r {
Receiver::Sapling(data) => {
return Ok(MyReceiver { net: net, receiver: Receiver::Sapling(data.clone()) });
},
_ => (),
}
}
return FromAddress::from_unified(net, data);
}
fn from_transparent_p2pkh(net: Network, data: [u8; 20]) -> Result<Self, UnsupportedAddress> {
Ok(MyReceiver { net: net, receiver: Receiver::P2pkh(data) })
}
}
pub fn get_ua(sapling_addr: &str, transparent_addr: &str) -> anyhow::Result<ZcashAddress> {
let sapling_addr = ZcashAddress::try_from_encoded(sapling_addr)?;
let transparent_addr = ZcashAddress::try_from_encoded(transparent_addr)?;
let receivers: Vec<_> = vec![sapling_addr, transparent_addr].iter().map(|r| {
r.clone().convert::<MyReceiver>().unwrap()
}).collect();
let net = receivers.first().unwrap().net.clone();
let receivers: Vec<_> = receivers.iter().map(|r| r.receiver.clone()).collect();
let ua: Address = Address::try_from(receivers)?;
let ua_address = ZcashAddress::from_unified(net, ua);
Ok(ua_address)
}
pub fn get_sapling(ua_addr: &str) -> anyhow::Result<ZcashAddress> {
let ua_addr = ZcashAddress::try_from_encoded(ua_addr)?;
let r = ua_addr.convert::<MyReceiver>()?;
if let Receiver::Sapling(data) = r.receiver {
return Ok(ZcashAddress::from_sapling(r.net, data));
}
anyhow::bail!("Invalid UA");
}
#[cfg(test)]
mod tests {
use crate::ua::{get_ua, get_sapling};
#[test]
fn test_ua() -> anyhow::Result<()> {
let ua = get_ua("zs1lvzgfzzwl9n85446j292zg0valw2p47hmxnw42wnqsehsmyuvjk0mhxktcs0pqrplacm2vchh35", "t1UWSSWaojmV5dgDhrSfZC6MAfCwVQ9LLoo")?;
let ua_str = ua.to_string();
println!("{}", ua);
let za = get_sapling(&ua_str)?;
println!("{}", za);
Ok(())
}
}
// t1UWSSWaojmV5dgDhrSfZC6MAfCwVQ9LLoo
// zs1lvzgfzzwl9n85446j292zg0valw2p47hmxnw42wnqsehsmyuvjk0mhxktcs0pqrplacm2vchh35
// u16cdcqfguv574pnntjx7dfh78u8m5cu3myxyvs9gedkymstj60u366vpn9qhkcch77e26rzyecyhem7qnzrl7ws2huraj8se8tgek4t3ngn4lfs95l4774mhvgyea4jj93gm92jhg3z7