From e9ad07c90dafd91ea7b28c28ce11e0b9ce0d7d23 Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Fri, 24 Sep 2021 21:10:45 -0300 Subject: [PATCH] [WIP] nice impl but that does not work because of private attributes of ZcashAddress --- Cargo.lock | 191 +++++++++++++++--- Cargo.toml | 6 +- src/lib.rs | 106 +++++++--- src/zcash_address.udl | 35 ++-- .../bindings/test_zcash_address_helper.swift | 47 +---- 5 files changed, 271 insertions(+), 114 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 864f056..aa87544 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,15 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" @@ -57,6 +63,12 @@ dependencies = [ "toml", ] +[[package]] +name = "bech32" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" + [[package]] name = "bitflags" version = "1.3.2" @@ -76,10 +88,45 @@ dependencies = [ ] [[package]] -name = "bytes" -version = "1.0.1" +name = "blake2b_simd" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +dependencies = [ + "sha2", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "camino" @@ -130,12 +177,54 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "f4jumble" +version = "0.0.0" +source = "git+https://github.com/zcash/librustzcash.git?rev=e13e746e8a4883d6683e24da00580d55f632b115#e13e746e8a4883d6683e24da00580d55f632b115" +dependencies = [ + "blake2b_simd", +] + [[package]] name = "funty" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "glob" version = "0.3.0" @@ -153,9 +242,9 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "lazy_static" @@ -176,6 +265,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "libc" +version = "0.2.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" + [[package]] name = "log" version = "0.4.14" @@ -214,6 +309,18 @@ dependencies = [ "version_check", ] +[[package]] +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "paste" version = "1.0.5" @@ -231,9 +338,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" dependencies = [ "unicode-xid", ] @@ -280,18 +387,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -300,15 +407,28 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "sha2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -317,9 +437,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "1.0.74" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0" dependencies = [ "proc-macro2", "quote", @@ -343,18 +463,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" dependencies = [ "proc-macro2", "quote", @@ -370,6 +490,12 @@ dependencies = [ "serde", ] +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + [[package]] name = "ucd-trie" version = "0.1.3" @@ -384,9 +510,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" @@ -483,5 +609,20 @@ dependencies = [ [[package]] name = "zcash_address" version = "0.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be44d6e2ddbadf6bc21f71b072e9e6e5829446a14e4366d16a24f32a79b34108" +source = "git+https://github.com/zcash/librustzcash.git?rev=e13e746e8a4883d6683e24da00580d55f632b115#e13e746e8a4883d6683e24da00580d55f632b115" +dependencies = [ + "bech32", + "blake2b_simd", + "bs58", + "f4jumble", + "zcash_encoding", +] + +[[package]] +name = "zcash_encoding" +version = "0.0.0" +source = "git+https://github.com/zcash/librustzcash.git?rev=e13e746e8a4883d6683e24da00580d55f632b115#e13e746e8a4883d6683e24da00580d55f632b115" +dependencies = [ + "byteorder", + "nonempty", +] diff --git a/Cargo.toml b/Cargo.toml index 4da3582..5a3c430 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,11 @@ name = "uniffi_zcash_addresses" uniffi_macros = "0.13" uniffi = {version = "0.13", features=["builtin-bindgen"]} thiserror = "1.0" -zcash_address = "0.0" +zcash_address = "0.0.0" [build-dependencies] uniffi_build = {version = "0.13", features=["builtin-bindgen"]} + + +[patch.crates-io] +zcash_address = { git = "https://github.com/zcash/librustzcash.git" , rev = "e13e746e8a4883d6683e24da00580d55f632b115" } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 8f34946..56089d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,19 +2,20 @@ // mod zcash_address::{ZcashAddress}; uniffi_macros::include_scaffolding!("zcash_address"); +use zcash_address::{ZcashAddress, ParseError, Network}; + #[derive(Debug, thiserror::Error)] pub enum AddressError { #[error("The received address string is invalid")] InvalidAddress, + #[error("The received address string does not appear to be a Zcash address")] + NotZcash, + #[error("The received address was matched as a UA but resulted invalid")] + InvalidUnifiedAddress, } + #[derive(Debug, Clone)] -pub enum Kind { - Sransparent, - Sapling, - Unified, -} -#[derive(Debug, Clone)] -pub enum Network { +pub enum NetworkType { Main, Test, Regtest @@ -22,38 +23,81 @@ pub enum Network { #[derive(Debug)] pub struct Address { - kind: Kind, - network: Network, + network: NetworkType, string: String, } +fn parse( + address_text: String +) -> Result { + ZcashAddress::try_from_encoded(&address_text.as_str()) + .map(|zcash_address| zcash_address.to_address()) + .map_err(|e| e.to_address_error()) +} -impl Address { - fn parse(address_text: &str) -> Result { - Err(AddressError::InvalidAddress) +fn derive_transparent_address( + seed_bytes: &[u8], + account: i32, + index: i32 +) -> Result { + Err(AddressError::InvalidAddress) +} + +fn derive_sapling_address( + seed_bytes: &[u8], + account: i32, + index: i32 +) -> Result { + Err(AddressError::InvalidAddress) +} + +fn derive_unified_address( + seed_bytes: &[u8], + account: i32, + index: i32 +) -> Result { + Err(AddressError::InvalidAddress) +} +trait ToAddress { + fn to_address(&self) -> Address; +} + +trait ToAddressError { + fn to_address_error(&self) -> AddressError; +} + +trait ToNetworkType { + fn to_network_type(&self) -> NetworkType; +} + +impl ToNetworkType for Network { + fn to_network_type(&self) -> NetworkType { + match self { + Network::Main => NetworkType::Main, + Network::Test => NetworkType::Test, + Network::Regtest => NetworkType::Regtest, + } } +} - fn derive_transaparent_address( - seed_bytes: &[u8], - account: i32, - index: i32 - ) -> Result { - Err(AddressError::InvalidAddress) +impl ToAddressError for ParseError { + fn to_address_error(&self) -> AddressError { + match self { + ParseError::InvalidEncoding => AddressError::InvalidAddress, + ParseError::NotZcash => AddressError::InvalidAddress, + ParseError::Unified(_) => AddressError::InvalidUnifiedAddress + } } +} +impl ToAddress for ZcashAddress { + fn to_address(&self) -> Address { + let address = Address { + network: self.net.to_network_type(), + string: self.to_string() + } - fn derive_sapling_address( - seed_bytes: &[u8], - account: i32, - index: i32 - ) -> Result { - Err(AddressError::InvalidAddress) - } - fn derive_unified_address( - seed_bytes: &[u8], - account: i32, - index: i32 - ) -> Result { - Err(AddressError::InvalidAddress) + return address + } } \ No newline at end of file diff --git a/src/zcash_address.udl b/src/zcash_address.udl index 7a2019b..41d8008 100644 --- a/src/zcash_address.udl +++ b/src/zcash_address.udl @@ -1,31 +1,28 @@ -namespace zcash_address { +namespace zcash_address_util { [Throws=AddressError] Address parse(string address_text); + [Throws=AddressError] + Address derive_transparent_address([ByRef] sequence seed_bytes, i32 account, i32 index); + [Throws=AddressError] + Address derive_sapling_address([ByRef] sequence seed_bytes, i32 account, i32 index); + [Throws=AddressError] + Address derive_unified_address([ByRef] sequence seed_bytes, i32 account, i32 index); }; -enum Kind { - "Transparent", "Sapling", "Unified" -}; - -enum Network { - "Test", "Main", "Regtest" +enum NetworkType { + "Test", + "Main", + "Regtest" }; dictionary Address { - Kind kind; - Network network; - string str; + NetworkType network; + string string; }; [Error] enum AddressError { - "InvalidAddress" -}; - -interface ZcashAddressHelper { - constructor(); - Address parse(string address_text); - Address derive_transparent_address(sequence seed_bytes, i32 account, i32 index); - Address derive_sapling_address(sequence seed_bytes, i32 account, i32 index); - Address derive_unified_address(sequence seed_bytes, i32 account, i32 index); + "InvalidAddress", + "NotZcash", + "InvalidUnifiedAddress" }; diff --git a/tests/bindings/test_zcash_address_helper.swift b/tests/bindings/test_zcash_address_helper.swift index 1ce86c4..25300a0 100644 --- a/tests/bindings/test_zcash_address_helper.swift +++ b/tests/bindings/test_zcash_address_helper.swift @@ -1,42 +1,13 @@ import zcash_address +extension zcash_address.Address: Equatable {} -// extension Network: Equatable { -// static func ==(lhs: Network, rhs: Network) -> Bool { -// switch lhs { -// case .main: -// switch rhs { -// case .main: -// return true -// default: -// return false -// } -// case .test: -// switch rhs { -// case .test: -// return true -// default: -// return false -// } -// case .regtest: -// switch rhs { -// case .regtest: -// return true -// default: -// return false -// } -// } -// } -// } - -// let helper = ZcashAddressHelper() - -// do { -// let testSaplingAddress = "ztestsapling1ysrf4uq52n5hhj0vzxpcfneszlk8flalh3ajdwsyucnpc0fjktp9afzcclnxdrnzfl7w7wyx3kz" -// let parsedAddress = try helper.parse(testSaplingAddress) -// // assert(parsedAddress.network == .test) -// assert(true) -// } catch { -// fatalError("Invalid Address when it should have been valid") -// } +do { + let testSaplingAddress = "ztestsapling1ysrf4uq52n5hhj0vzxpcfneszlk8flalh3ajdwsyucnpc0fjktp9afzcclnxdrnzfl7w7wyx3kz" + let parsedAddress = try zcash_address.parse(testSaplingAddress) + // assert(parsedAddress.network == .test) + assert(true) +} catch { + fatalError("Invalid Address when it should have been valid") +}