From 507edfacf9dbfda77d26f39669c1d460211eb9e6 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Fri, 13 Sep 2024 17:07:42 -0400 Subject: [PATCH 01/16] Wallet is now generic and is able to be generically backed by the MemoryWalletDb --- Cargo.lock | 1 + Cargo.toml | 2 +- src/bindgen/wallet.rs | 12 ++++++-- src/lib.rs | 7 +++++ src/wallet.rs | 65 ++++++++++++++++++++++--------------------- tests/tests.rs | 6 ++++ 6 files changed, 57 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de8e16a..b06e7bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2470,6 +2470,7 @@ dependencies = [ "ripemd", "secrecy", "sha2", + "subtle", "thiserror", "tokio", "tonic", diff --git a/Cargo.toml b/Cargo.toml index bdec4fa..da49fb8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,7 @@ nonempty = "0.7" hex = "0.4.3" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing = "0.1.40" - +subtle = "2.6.1" [dev-dependencies] wasm-bindgen-test = "0.3.42" diff --git a/src/bindgen/wallet.rs b/src/bindgen/wallet.rs index 9c1530c..916a58e 100644 --- a/src/bindgen/wallet.rs +++ b/src/bindgen/wallet.rs @@ -6,10 +6,11 @@ use wasm_bindgen::prelude::*; use tonic_web_wasm_client::Client; use zcash_address::ZcashAddress; +use zcash_client_memory::MemoryWalletDb; use zcash_primitives::consensus::{self, BlockHeight}; use crate::error::Error; -use crate::{BlockRange, Wallet}; +use crate::{BlockRange, MemoryWallet, Wallet, PRUNING_DEPTH}; /// # A Zcash wallet /// @@ -32,7 +33,7 @@ use crate::{BlockRange, Wallet}; /// #[wasm_bindgen] pub struct WebWallet { - inner: Wallet, + inner: MemoryWallet, } #[wasm_bindgen] @@ -56,7 +57,12 @@ impl WebWallet { let client = Client::new(lightwalletd_url.to_string()); Ok(Self { - inner: Wallet::new(client, network, min_confirmations)?, + inner: Wallet::new( + MemoryWalletDb::new(network, PRUNING_DEPTH), + client, + network, + min_confirmations, + )?, }) } diff --git a/src/lib.rs b/src/lib.rs index 85be778..2f54314 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,13 @@ pub mod wallet; pub use wallet::Wallet; use wasm_bindgen::prelude::*; +use zcash_client_memory::MemoryWalletDb; +use zcash_primitives::consensus; + +/// The maximum number of checkpoints to store in each shard-tree +pub const PRUNING_DEPTH: usize = 100; #[wasm_bindgen] pub struct BlockRange(pub u32, pub u32); + +pub type MemoryWallet = Wallet, T>; diff --git a/src/wallet.rs b/src/wallet.rs index 6a5f4e4..c8624ae 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -9,11 +9,16 @@ use tonic::{ codegen::{Body, Bytes, StdError}, }; +use crate::error::Error; +use crate::BlockRange; +use std::fmt::Debug; +use std::hash::Hash; +use subtle::ConditionallySelectable; use zcash_address::ZcashAddress; -use zcash_client_backend::data_api::scanning::ScanRange; use zcash_client_backend::data_api::wallet::{ create_proposed_transactions, input_selection::GreedyInputSelector, propose_transfer, }; +use zcash_client_backend::data_api::{scanning::ScanRange, WalletCommitmentTrees}; use zcash_client_backend::data_api::{ AccountBirthday, AccountPurpose, InputSource, NullifierQuery, WalletRead, WalletSummary, WalletWrite, @@ -34,15 +39,12 @@ use zcash_primitives::transaction::fees::zip317::FeeRule; use zcash_primitives::transaction::TxId; use zcash_proofs::prover::LocalTxProver; -use crate::error::Error; -use crate::BlockRange; -const BATCH_SIZE: u32 = 10000; +use zcash_client_backend::proposal::Proposal; -/// The maximum number of checkpoints to store in each shard-tree -const PRUNING_DEPTH: usize = 100; +const BATCH_SIZE: u32 = 10000; -type Proposal = - zcash_client_backend::proposal::Proposal; +// type Proposal = +// zcash_client_backend::proposal::Proposal; /// # A Zcash wallet /// @@ -63,18 +65,30 @@ type Proposal = /// /// TODO /// - -pub struct Wallet { +pub struct Wallet { /// Internal database used to maintain wallet data (e.g. accounts, transactions, cached blocks) - pub(crate) db: MemoryWalletDb, + pub(crate) db: W, // gRPC client used to connect to a lightwalletd instance for network data pub(crate) client: CompactTxStreamerClient, pub(crate) network: consensus::Network, pub(crate) min_confirmations: NonZeroU32, } -impl Wallet +impl Wallet where + W: WalletRead + + WalletWrite + + InputSource< + AccountId = ::AccountId, + Error = ::Error, + NoteRef = NoteRef, + > + WalletCommitmentTrees, + + AccountId: Copy + Debug + Eq + Hash + Default + Send + ConditionallySelectable + 'static, + NoteRef: Copy + Eq + Ord + Debug, + Error: From<::Error>, + + // GRPC connection Trait Bounds T: GrpcService, T::Error: Into, T::ResponseBody: Body + std::marker::Send + 'static, @@ -82,12 +96,13 @@ where { /// Create a new instance of a Zcash wallet for a given network pub fn new( + db: W, client: T, network: Network, min_confirmations: NonZeroU32, - ) -> Result, Error> { + ) -> Result { Ok(Wallet { - db: MemoryWalletDb::new(network, PRUNING_DEPTH), + db, client: CompactTxStreamerClient::new(client), network, min_confirmations, @@ -257,16 +272,7 @@ where Ok(()) } - pub fn get_wallet_summary( - &self, - ) -> Result< - Option< - WalletSummary< - as WalletRead>::AccountId, - >, - >, - Error, - > { + pub fn get_wallet_summary(&self) -> Result>, Error> { Ok(self.db.get_wallet_summary(self.min_confirmations.into())?) } @@ -296,7 +302,7 @@ where account_index: usize, to_address: ZcashAddress, value: u64, - ) -> Result { + ) -> Result, Error> { let account_id = self.db.get_account_ids()?[account_index]; let input_selector = GreedyInputSelector::new( @@ -317,12 +323,7 @@ where .get_target_and_anchor_heights(self.min_confirmations)? ); - let proposal = propose_transfer::< - _, - _, - _, - as InputSource>::Error, - >( + let proposal = propose_transfer::<_, _, _, ::Error>( &mut self.db, &self.network, account_id, @@ -343,7 +344,7 @@ where /// pub(crate) fn create_proposed_transactions( &mut self, - proposal: Proposal, + proposal: Proposal, usk: &UnifiedSpendingKey, ) -> Result, Error> { let prover = LocalTxProver::bundled(); diff --git a/tests/tests.rs b/tests/tests.rs index 300bb33..9e41d76 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -50,6 +50,10 @@ async fn test_get_and_scan_range() { #[cfg(feature = "native")] #[tokio::test] async fn test_get_and_scan_range_native() { + use webz_core::PRUNING_DEPTH; + use zcash_client_memory::MemoryWalletDb; + use zcash_primitives::consensus; + initialize(); let url = "https://testnet.zec.rocks:443"; let c = tonic::transport::Channel::from_shared(url).unwrap(); @@ -58,7 +62,9 @@ async fn test_get_and_scan_range_native() { .domain_name("testnet.zec.rocks") .with_webpki_roots(); let channel = c.tls_config(tls).unwrap(); + let wallet_db = MemoryWalletDb::new(consensus::Network::TestNetwork, PRUNING_DEPTH); let mut w = Wallet::new( + wallet_db, channel.connect().await.unwrap(), Network::TestNetwork, NonZeroU32::try_from(1).unwrap(), From b5963a4c52f5fe51e52be62940ec3b9bc31690f0 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Fri, 13 Sep 2024 17:43:31 -0400 Subject: [PATCH 02/16] added sqlite --- Cargo.lock | 163 +++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 +- justfile | 3 + src/error.rs | 4 ++ tests/tests.rs | 59 ++++++++++++++++++ 5 files changed, 232 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index b06e7bf..20947fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,6 +56,18 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -65,6 +77,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "anyhow" version = "1.0.86" @@ -426,6 +444,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "daggy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91a9304e55e9d601a39ae4deaba85406d5c0980e106f65afcf0460e9af1e7602" +dependencies = [ + "petgraph", +] + [[package]] name = "delegate-display" version = "2.1.1" @@ -506,6 +533,18 @@ dependencies = [ "blake2b_simd", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fancy_constructor" version = "1.2.2" @@ -749,6 +788,19 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] [[package]] name = "heck" @@ -993,6 +1045,17 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libsqlite3-sys" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -1355,6 +1418,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "poly1305" version = "0.8.0" @@ -1626,6 +1695,21 @@ dependencies = [ "digest", ] +[[package]] +name = "rusqlite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" +dependencies = [ + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", + "time", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1719,6 +1803,29 @@ dependencies = [ "zip32", ] +[[package]] +name = "schemer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835d8f9478fd2936195fc941a8666b0d0894d5bf3631cbb884a8ce8ba631f339" +dependencies = [ + "daggy", + "log", + "thiserror", + "uuid", +] + +[[package]] +name = "schemer-rusqlite" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fb5ac1fa52c58e2c6a618e3149d464e7ad8d0effca74990ea29c1fe2338b3b1" +dependencies = [ + "rusqlite", + "schemer", + "uuid", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -1914,11 +2021,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", + "itoa", "js-sys", "num-conv", "powerfmt", "serde", "time-core", + "time-macros", ] [[package]] @@ -1927,6 +2036,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -2249,6 +2368,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" @@ -2471,6 +2596,7 @@ dependencies = [ "secrecy", "sha2", "subtle", + "tempfile", "thiserror", "tokio", "tonic", @@ -2485,6 +2611,7 @@ dependencies = [ "zcash_address", "zcash_client_backend", "zcash_client_memory", + "zcash_client_sqlite", "zcash_keys", "zcash_primitives", "zcash_proofs", @@ -2701,6 +2828,42 @@ dependencies = [ "zip32", ] +[[package]] +name = "zcash_client_sqlite" +version = "0.11.2" +source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +dependencies = [ + "bs58", + "byteorder", + "document-features", + "group", + "incrementalmerkletree", + "jubjub", + "maybe-rayon", + "nonempty", + "orchard", + "prost 0.13.2", + "regex", + "rusqlite", + "sapling-crypto", + "schemer", + "schemer-rusqlite", + "secrecy", + "shardtree", + "static_assertions", + "subtle", + "time", + "tracing", + "uuid", + "zcash_address", + "zcash_client_backend", + "zcash_encoding", + "zcash_keys", + "zcash_primitives", + "zcash_protocol", + "zip32", +] + [[package]] name = "zcash_encoding" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index da49fb8..7bdd97c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ default = ["native"] wasm = ["console_error_panic_hook", "dep:tracing-web"] native = ["dep:tokio", "tonic/channel", "tonic/gzip", "tonic/tls-webpki-roots"] - +sqlite-db = ["dep:zcash_client_sqlite"] console_error_panic_hook = ["dep:console_error_panic_hook"] [dependencies] @@ -55,6 +55,7 @@ tonic = { version = "0.12", default-features = false, features = [ # Used in Native tests tokio = { version = "1.0", features = ["rt", "macros"], optional = true } +zcash_client_sqlite = { git = "https://github.com/ChainSafe/librustzcash", rev = "a77e8a0204dab421fdbf5822e585716339567b96", default-features = false, features = ["unstable", "orchard"], optional = true } getrandom = { version = "0.2", features = ["js"] } thiserror = "1.0.63" @@ -72,6 +73,7 @@ subtle = "2.6.1" [dev-dependencies] wasm-bindgen-test = "0.3.42" +tempfile = "3.12" [patch.crates-io] zip32 = { git = "https://github.com/zcash/zip32.git", branch = "diversifier_index_ord"} diff --git a/justfile b/justfile index 7b4d8bc..e1e007a 100644 --- a/justfile +++ b/justfile @@ -10,5 +10,8 @@ test-web: test-native: cargo test -r -- --nocapture +test-sqlite: + cargo test -r --features="sqlite-db" test_get_and_scan_range_native_sqlite -- --nocapture + check: cargo check diff --git a/src/error.rs b/src/error.rs index 283a6ef..fb12f12 100644 --- a/src/error.rs +++ b/src/error.rs @@ -44,6 +44,10 @@ pub enum Error { InvalidAmount(#[from] zcash_primitives::transaction::components::amount::BalanceError), #[error("Failed to send transaction")] SendFailed { code: i32, reason: String }, + + #[cfg(feature = "sqlite-db")] + #[error("Sqlite error: {0}")] + SqliteError(#[from] zcash_client_sqlite::error::SqliteClientError), } impl From for JsValue { diff --git a/tests/tests.rs b/tests/tests.rs index 9e41d76..5cee2e5 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -95,3 +95,62 @@ async fn test_get_and_scan_range_native() { let summary = w.get_wallet_summary().unwrap(); tracing::info!("Wallet summary: {:?}", summary); } + +#[cfg(all(feature = "native", feature = "sqlite-db"))] +#[tokio::test] +async fn test_get_and_scan_range_native_sqlite() { + use tempfile::{tempdir, NamedTempFile}; + use zcash_client_sqlite::{ + chain::init::init_blockmeta_db, wallet::init::init_wallet_db, FsBlockDb, WalletDb, + }; + use zcash_primitives::consensus; + + initialize(); + let url = "https://testnet.zec.rocks:443"; + let c = tonic::transport::Channel::from_shared(url).unwrap(); + + let tls = tonic::transport::ClientTlsConfig::new() + .domain_name("testnet.zec.rocks") + .with_webpki_roots(); + let channel = c.tls_config(tls).unwrap(); + + let db_cache = tempdir().unwrap(); + let db_data = NamedTempFile::new_in(db_cache.path()).unwrap(); + + let mut db_cache = FsBlockDb::for_path(&db_cache).unwrap(); + let mut wallet_db = WalletDb::for_path(&db_data, consensus::Network::TestNetwork).unwrap(); + init_blockmeta_db(&mut db_cache).unwrap(); + init_wallet_db(&mut wallet_db, None).unwrap(); + + let mut w = Wallet::new( + wallet_db, + channel.connect().await.unwrap(), + Network::TestNetwork, + NonZeroU32::try_from(1).unwrap(), + ) + .unwrap(); + + let id = w.create_account(SEED, HD_INDEX, BIRTHDAY).await.unwrap(); + tracing::info!("Created account with id: {}", id); + + tracing::info!("Syncing wallet"); + w.sync(|scanned_to, tip| { + println!("Scanned: {}/{}", scanned_to, tip); + }) + .await + .unwrap(); + + tracing::info!("Syncing complete :)"); + + let summary = w.get_wallet_summary().unwrap(); + tracing::info!("Wallet summary: {:?}", summary); + + tracing::info!("Proposing a transaction"); + let addr = ZcashAddress::try_from_encoded("utest1z00xn09t4eyeqw9zmjss75sf460423dymgyfjn8rtlj26cffy0yad3eea82xekk24s00wnm38cvyrm2c6x7fxlc0ns4a5j7utgl6lchvglfvl9g9p56fqwzvzvj9d3z6r6ft88j654d7dj0ep6myq5duz9s8x78fdzmtx04d2qn8ydkxr4lfdhlkx9ktrw98gd97dateegrr68vl8xu"); + + w.transfer(SEED, 0, addr.unwrap(), 1000).await.unwrap(); + tracing::info!("Transaction proposed"); + + let summary = w.get_wallet_summary().unwrap(); + tracing::info!("Wallet summary: {:?}", summary); +} From 1e903268636ec7ae990e45a9d1e5e80de0c4f421 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Fri, 13 Sep 2024 17:58:32 -0400 Subject: [PATCH 03/16] clean up test file and merge the memorydb and sqlite test --- justfile | 2 +- tests/tests.rs | 76 ++++++++++++-------------------------------------- 2 files changed, 19 insertions(+), 59 deletions(-) diff --git a/justfile b/justfile index e1e007a..7faa255 100644 --- a/justfile +++ b/justfile @@ -11,7 +11,7 @@ test-native: cargo test -r -- --nocapture test-sqlite: - cargo test -r --features="sqlite-db" test_get_and_scan_range_native_sqlite -- --nocapture + cargo test -r --features="sqlite-db" -- --nocapture check: cargo check diff --git a/tests/tests.rs b/tests/tests.rs index 5cee2e5..075c0e1 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -50,9 +50,9 @@ async fn test_get_and_scan_range() { #[cfg(feature = "native")] #[tokio::test] async fn test_get_and_scan_range_native() { - use webz_core::PRUNING_DEPTH; - use zcash_client_memory::MemoryWalletDb; use zcash_primitives::consensus; + let db_cache = tempfile::tempdir().unwrap(); + let _db_data = tempfile::NamedTempFile::new_in(db_cache.path()).unwrap(); initialize(); let url = "https://testnet.zec.rocks:443"; @@ -62,65 +62,25 @@ async fn test_get_and_scan_range_native() { .domain_name("testnet.zec.rocks") .with_webpki_roots(); let channel = c.tls_config(tls).unwrap(); - let wallet_db = MemoryWalletDb::new(consensus::Network::TestNetwork, PRUNING_DEPTH); - let mut w = Wallet::new( - wallet_db, - channel.connect().await.unwrap(), - Network::TestNetwork, - NonZeroU32::try_from(1).unwrap(), - ) - .unwrap(); - - let id = w.create_account(SEED, HD_INDEX, BIRTHDAY).await.unwrap(); - tracing::info!("Created account with id: {}", id); - - tracing::info!("Syncing wallet"); - w.sync(|scanned_to, tip| { - println!("Scanned: {}/{}", scanned_to, tip); - }) - .await - .unwrap(); - - tracing::info!("Syncing complete :)"); - - let summary = w.get_wallet_summary().unwrap(); - tracing::info!("Wallet summary: {:?}", summary); - tracing::info!("Proposing a transaction"); - let addr = ZcashAddress::try_from_encoded("utest1z00xn09t4eyeqw9zmjss75sf460423dymgyfjn8rtlj26cffy0yad3eea82xekk24s00wnm38cvyrm2c6x7fxlc0ns4a5j7utgl6lchvglfvl9g9p56fqwzvzvj9d3z6r6ft88j654d7dj0ep6myq5duz9s8x78fdzmtx04d2qn8ydkxr4lfdhlkx9ktrw98gd97dateegrr68vl8xu"); - - w.transfer(SEED, 0, addr.unwrap(), 1000).await.unwrap(); - tracing::info!("Transaction proposed"); - - let summary = w.get_wallet_summary().unwrap(); - tracing::info!("Wallet summary: {:?}", summary); -} - -#[cfg(all(feature = "native", feature = "sqlite-db"))] -#[tokio::test] -async fn test_get_and_scan_range_native_sqlite() { - use tempfile::{tempdir, NamedTempFile}; - use zcash_client_sqlite::{ - chain::init::init_blockmeta_db, wallet::init::init_wallet_db, FsBlockDb, WalletDb, + #[cfg(feature = "sqlite-db")] + let wallet_db = { + use zcash_client_sqlite::{ + chain::init::init_blockmeta_db, wallet::init::init_wallet_db, FsBlockDb, WalletDb, + }; + + let mut db_cache = FsBlockDb::for_path(&db_cache).unwrap(); + let mut wallet_db = WalletDb::for_path(&_db_data, consensus::Network::TestNetwork).unwrap(); + init_blockmeta_db(&mut db_cache).unwrap(); + init_wallet_db(&mut wallet_db, None).unwrap(); + wallet_db }; - use zcash_primitives::consensus; - - initialize(); - let url = "https://testnet.zec.rocks:443"; - let c = tonic::transport::Channel::from_shared(url).unwrap(); - - let tls = tonic::transport::ClientTlsConfig::new() - .domain_name("testnet.zec.rocks") - .with_webpki_roots(); - let channel = c.tls_config(tls).unwrap(); - - let db_cache = tempdir().unwrap(); - let db_data = NamedTempFile::new_in(db_cache.path()).unwrap(); - let mut db_cache = FsBlockDb::for_path(&db_cache).unwrap(); - let mut wallet_db = WalletDb::for_path(&db_data, consensus::Network::TestNetwork).unwrap(); - init_blockmeta_db(&mut db_cache).unwrap(); - init_wallet_db(&mut wallet_db, None).unwrap(); + #[cfg(not(feature = "sqlite-db"))] + let wallet_db = zcash_client_memory::MemoryWalletDb::new( + consensus::Network::TestNetwork, + webz_core::PRUNING_DEPTH, + ); let mut w = Wallet::new( wallet_db, From d9c48b9e81a7b12d3857f8db9f3e2aabcd430b93 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Fri, 13 Sep 2024 19:07:37 -0400 Subject: [PATCH 04/16] scan using the postboard ufvk --- src/wallet.rs | 40 +++++++++++++++++++++++++- tests/tests.rs | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/src/wallet.rs b/src/wallet.rs index c8624ae..9a9714f 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -32,7 +32,7 @@ use zcash_client_backend::wallet::OvkPolicy; use zcash_client_backend::zip321::{Payment, TransactionRequest}; use zcash_client_backend::ShieldedProtocol; use zcash_client_memory::MemoryWalletDb; -use zcash_keys::keys::UnifiedSpendingKey; +use zcash_keys::keys::{UnifiedFullViewingKey, UnifiedSpendingKey}; use zcash_primitives::consensus::{self, BlockHeight, Network}; use zcash_primitives::transaction::components::amount::NonNegativeAmount; use zcash_primitives::transaction::fees::zip317::FeeRule; @@ -159,6 +159,44 @@ where Ok("0".to_string()) } + pub async fn import_ufvk( + &mut self, + ufvk: UnifiedFullViewingKey, + birthday_height: Option, + ) -> Result { + let birthday = match birthday_height { + Some(height) => height, + None => { + let chain_tip: u32 = self + .client + .get_latest_block(service::ChainSpec::default()) + .await? + .into_inner() + .height + .try_into() + .expect("block heights must fit into u32"); + chain_tip - 100 + } + }; + // Construct an `AccountBirthday` for the account's birthday. + let birthday = { + // Fetch the tree state corresponding to the last block prior to the wallet's + // birthday height. NOTE: THIS APPROACH LEAKS THE BIRTHDAY TO THE SERVER! + let request = service::BlockId { + height: (birthday - 1).into(), + ..Default::default() + }; + let treestate = self.client.get_tree_state(request).await?.into_inner(); + AccountBirthday::from_treestate(treestate, None).map_err(|_| Error::BirthdayError)? + }; + + let _account = self + .db + .import_account_ufvk(&ufvk, &birthday, AccountPurpose::Spending)?; + + Ok("0".to_string()) + } + pub fn suggest_scan_ranges(&self) -> Result, Error> { Ok(self.db.suggest_scan_ranges().map(|ranges| { ranges diff --git a/tests/tests.rs b/tests/tests.rs index 075c0e1..327abe9 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -114,3 +114,80 @@ async fn test_get_and_scan_range_native() { let summary = w.get_wallet_summary().unwrap(); tracing::info!("Wallet summary: {:?}", summary); } + +// let s = zcash_keys::encoding::decode_extended_full_viewing_key( +// constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, +// &self.ufvk.trim(), +// ) +// .unwrap() +// .to_diversifiable_full_viewing_key(); +// let ufvk = UnifiedFullViewingKey::new(None, Some(s), None).unwrap(); + +#[cfg(feature = "native")] +#[tokio::test] +async fn test_post_board() { + let key_str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz"; + + use zcash_keys::keys::UnifiedFullViewingKey; + use zcash_primitives::{consensus, constants}; + let db_cache = tempfile::tempdir().unwrap(); + let _db_data = tempfile::NamedTempFile::new_in(db_cache.path()).unwrap(); + + initialize(); + let url = "https://zec.rocks:443"; + let c = tonic::transport::Channel::from_shared(url).unwrap(); + + let tls = tonic::transport::ClientTlsConfig::new() + .domain_name("zec.rocks") + .with_webpki_roots(); + let channel = c.tls_config(tls).unwrap(); + + #[cfg(feature = "sqlite-db")] + let wallet_db = { + use zcash_client_sqlite::{ + chain::init::init_blockmeta_db, wallet::init::init_wallet_db, FsBlockDb, WalletDb, + }; + + let mut db_cache = FsBlockDb::for_path(&db_cache).unwrap(); + let mut wallet_db = WalletDb::for_path(&_db_data, consensus::Network::MainNetwork).unwrap(); + init_blockmeta_db(&mut db_cache).unwrap(); + init_wallet_db(&mut wallet_db, None).unwrap(); + wallet_db + }; + + #[cfg(not(feature = "sqlite-db"))] + let wallet_db = zcash_client_memory::MemoryWalletDb::new( + consensus::Network::MainNetwork, + webz_core::PRUNING_DEPTH, + ); + + let mut w = Wallet::new( + wallet_db, + channel.connect().await.unwrap(), + Network::MainNetwork, + NonZeroU32::try_from(1).unwrap(), + ) + .unwrap(); + + let s = zcash_keys::encoding::decode_extended_full_viewing_key( + constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, + &key_str.trim(), + ) + .unwrap(); + + let ufvk = UnifiedFullViewingKey::from_sapling_extended_full_viewing_key(s).unwrap(); + let id = w.import_ufvk(ufvk, Some(2477329)).await.unwrap(); + tracing::info!("Created account with id: {}", id); + + tracing::info!("Syncing wallet"); + w.sync(|scanned_to, tip| { + println!("Scanned: {}/{}", scanned_to, tip); + }) + .await + .unwrap(); + + tracing::info!("Syncing complete :)"); + + let summary = w.get_wallet_summary().unwrap(); + tracing::info!("Wallet summary: {:?}", summary); +} From 4c7fa06992c5f6319b212818b4846b5fb56c2f43 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 12:03:18 -0400 Subject: [PATCH 05/16] trying to get web wallet working still --- src/bindgen/wallet.rs | 18 +++++++++++++++++- src/wallet.rs | 2 +- tests/tests.rs | 19 +++++++++++++++---- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/bindgen/wallet.rs b/src/bindgen/wallet.rs index 916a58e..82f2bf4 100644 --- a/src/bindgen/wallet.rs +++ b/src/bindgen/wallet.rs @@ -7,7 +7,8 @@ use tonic_web_wasm_client::Client; use zcash_address::ZcashAddress; use zcash_client_memory::MemoryWalletDb; -use zcash_primitives::consensus::{self, BlockHeight}; +use zcash_keys::keys::UnifiedFullViewingKey; +use zcash_primitives::consensus::{self, BlockHeight, NetworkConstants, MAIN_NETWORK}; use crate::error::Error; use crate::{BlockRange, MemoryWallet, Wallet, PRUNING_DEPTH}; @@ -84,6 +85,21 @@ impl WebWallet { .await } + pub async fn import_ufvk( + &mut self, + key: &str, + birthday_height: Option, + ) -> Result { + let s = zcash_keys::encoding::decode_extended_full_viewing_key( + MAIN_NETWORK.hrp_sapling_extended_full_viewing_key(), + &key.trim(), + ) + .unwrap(); + let ufvk = UnifiedFullViewingKey::from_sapling_extended_full_viewing_key(s).unwrap(); + + self.inner.import_ufvk(ufvk, birthday_height).await + } + pub fn suggest_scan_ranges(&self) -> Result, Error> { self.inner.suggest_scan_ranges() } diff --git a/src/wallet.rs b/src/wallet.rs index 9a9714f..488c4b2 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -192,7 +192,7 @@ where let _account = self .db - .import_account_ufvk(&ufvk, &birthday, AccountPurpose::Spending)?; + .import_account_ufvk(&ufvk, &birthday, AccountPurpose::ViewOnly)?; Ok("0".to_string()) } diff --git a/tests/tests.rs b/tests/tests.rs index 327abe9..0fd21a5 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -3,7 +3,11 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); use webz_core::{bindgen::wallet::WebWallet, Wallet}; use zcash_address::ZcashAddress; -use zcash_primitives::consensus::Network; +use zcash_keys::keys::UnifiedFullViewingKey; +use zcash_primitives::{ + consensus::{MainNetwork, Network}, + constants, +}; const SEED: &str = "visit armed kite pen cradle toward reward clay marble oil write dove blind oyster silk oyster original message skate bench tone enable stadium element"; const HD_INDEX: u32 = 0; @@ -17,6 +21,7 @@ pub fn initialize() { webz_core::init::start(); }); } +const key_str: &'static str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz"; #[wasm_bindgen_test] async fn test_get_and_scan_range() { @@ -24,7 +29,15 @@ async fn test_get_and_scan_range() { let mut w = WebWallet::new("test", "https://zcash-testnet.chainsafe.dev", 1).unwrap(); - let id = w.create_account(SEED, HD_INDEX, BIRTHDAY).await.unwrap(); + // let id = w.create_account(SEED, HD_INDEX, BIRTHDAY).await.unwrap(); + let s = zcash_keys::encoding::decode_extended_full_viewing_key( + constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, + &key_str.trim(), + ) + .unwrap(); + + let id = w.import_ufvk(&key_str, Some(2477329)).await.unwrap(); + tracing::info!("Created account with id: {}", id); tracing::info!("Syncing wallet"); @@ -126,8 +139,6 @@ async fn test_get_and_scan_range_native() { #[cfg(feature = "native")] #[tokio::test] async fn test_post_board() { - let key_str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz"; - use zcash_keys::keys::UnifiedFullViewingKey; use zcash_primitives::{consensus, constants}; let db_cache = tempfile::tempdir().unwrap(); From fbb8e2da71033637b0dfc3f198122efaec0ab1c0 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 12:04:24 -0400 Subject: [PATCH 06/16] remove comment --- src/wallet.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/wallet.rs b/src/wallet.rs index c8624ae..481cf49 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -43,9 +43,6 @@ use zcash_client_backend::proposal::Proposal; const BATCH_SIZE: u32 = 10000; -// type Proposal = -// zcash_client_backend::proposal::Proposal; - /// # A Zcash wallet /// /// A wallet is a set of accounts that can be synchronized together with the blockchain. From 7642ef283a44037b0bdefa7d3637db197e838de1 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 12:39:10 -0400 Subject: [PATCH 07/16] move native test to example --- Cargo.toml | 6 ++- examples/simple-sync.rs | 82 +++++++++++++++++++++++++++++++++++++++++ justfile | 8 ++-- tests/tests.rs | 74 +------------------------------------ 4 files changed, 93 insertions(+), 77 deletions(-) create mode 100644 examples/simple-sync.rs diff --git a/Cargo.toml b/Cargo.toml index 7bdd97c..43a8a20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,10 @@ edition = "2021" [lib] crate-type = ["cdylib", "rlib"] +[[example]] +name = "simple-sync" +path = "examples/simple-sync.rs" + [profile.release] # Tell `rustc` to optimize for small code size. opt-level = 3 @@ -54,7 +58,7 @@ tonic = { version = "0.12", default-features = false, features = [ ] } # Used in Native tests -tokio = { version = "1.0", features = ["rt", "macros"], optional = true } +tokio = { version = "1.0", features = ["rt", "macros", "rt-multi-thread"], optional = true } zcash_client_sqlite = { git = "https://github.com/ChainSafe/librustzcash", rev = "a77e8a0204dab421fdbf5822e585716339567b96", default-features = false, features = ["unstable", "orchard"], optional = true } getrandom = { version = "0.2", features = ["js"] } diff --git a/examples/simple-sync.rs b/examples/simple-sync.rs new file mode 100644 index 0000000..fb7dcf1 --- /dev/null +++ b/examples/simple-sync.rs @@ -0,0 +1,82 @@ +use std::sync::Once; + +use std::num::NonZeroU32; +use webz_core::Wallet; +use zcash_address::ZcashAddress; +use zcash_primitives::consensus::Network; + +const SEED: &str = "visit armed kite pen cradle toward reward clay marble oil write dove blind oyster silk oyster original message skate bench tone enable stadium element"; +const HD_INDEX: u32 = 0; +const BIRTHDAY: Option = Some(2577329); + +static INIT: Once = Once::new(); +pub fn initialize() { + INIT.call_once(|| { + webz_core::init::start(); + }); +} + +#[cfg(feature = "native")] +#[tokio::main] +async fn main() { + let db_cache = tempfile::tempdir().unwrap(); + let _db_data = tempfile::NamedTempFile::new_in(db_cache.path()).unwrap(); + + initialize(); + let url = "https://testnet.zec.rocks:443"; + let c = tonic::transport::Channel::from_shared(url).unwrap(); + + let tls = tonic::transport::ClientTlsConfig::new() + .domain_name("testnet.zec.rocks") + .with_webpki_roots(); + let channel = c.tls_config(tls).unwrap(); + + #[cfg(feature = "sqlite-db")] + let wallet_db = { + use zcash_client_sqlite::{ + chain::init::init_blockmeta_db, wallet::init::init_wallet_db, FsBlockDb, WalletDb, + }; + + let mut db_cache = FsBlockDb::for_path(&db_cache).unwrap(); + let mut wallet_db = WalletDb::for_path(&_db_data, Network::TestNetwork).unwrap(); + init_blockmeta_db(&mut db_cache).unwrap(); + init_wallet_db(&mut wallet_db, None).unwrap(); + wallet_db + }; + + #[cfg(not(feature = "sqlite-db"))] + let wallet_db = + zcash_client_memory::MemoryWalletDb::new(Network::TestNetwork, webz_core::PRUNING_DEPTH); + + let mut w = Wallet::new( + wallet_db, + channel.connect().await.unwrap(), + Network::TestNetwork, + NonZeroU32::try_from(1).unwrap(), + ) + .unwrap(); + + let id = w.create_account(SEED, HD_INDEX, BIRTHDAY).await.unwrap(); + tracing::info!("Created account with id: {}", id); + + tracing::info!("Syncing wallet"); + w.sync(|scanned_to, tip| { + println!("Scanned: {}/{}", scanned_to, tip); + }) + .await + .unwrap(); + + tracing::info!("Syncing complete :)"); + + let summary = w.get_wallet_summary().unwrap(); + tracing::info!("Wallet summary: {:?}", summary); + + tracing::info!("Proposing a transaction"); + let addr = ZcashAddress::try_from_encoded("utest1z00xn09t4eyeqw9zmjss75sf460423dymgyfjn8rtlj26cffy0yad3eea82xekk24s00wnm38cvyrm2c6x7fxlc0ns4a5j7utgl6lchvglfvl9g9p56fqwzvzvj9d3z6r6ft88j654d7dj0ep6myq5duz9s8x78fdzmtx04d2qn8ydkxr4lfdhlkx9ktrw98gd97dateegrr68vl8xu"); + + w.transfer(SEED, 0, addr.unwrap(), 1000).await.unwrap(); + tracing::info!("Transaction proposed"); + + let summary = w.get_wallet_summary().unwrap(); + tracing::info!("Wallet summary: {:?}", summary); +} diff --git a/justfile b/justfile index 7faa255..d328e04 100644 --- a/justfile +++ b/justfile @@ -7,11 +7,11 @@ build: test-web: WASM_BINDGEN_TEST_TIMEOUT=99999 wasm-pack test --release --firefox --no-default-features --features="wasm" -Z build-std="panic_abort,std" -test-native: - cargo test -r -- --nocapture +run-example-native: + cargo run -r --example simple-sync -test-sqlite: - cargo test -r --features="sqlite-db" -- --nocapture +run-example-sqlite: + cargo run -r --example simple-sync --features="sqlite-db" check: cargo check diff --git a/tests/tests.rs b/tests/tests.rs index 075c0e1..610cd67 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,16 +1,14 @@ use wasm_bindgen_test::*; wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); -use webz_core::{bindgen::wallet::WebWallet, Wallet}; -use zcash_address::ZcashAddress; -use zcash_primitives::consensus::Network; +use std::sync::Once; +use webz_core::bindgen::wallet::WebWallet; const SEED: &str = "visit armed kite pen cradle toward reward clay marble oil write dove blind oyster silk oyster original message skate bench tone enable stadium element"; const HD_INDEX: u32 = 0; const BIRTHDAY: Option = Some(2577329); // Required to initialize the logger and panic hooks only once -use std::{num::NonZeroU32, sync::Once}; static INIT: Once = Once::new(); pub fn initialize() { INIT.call_once(|| { @@ -46,71 +44,3 @@ async fn test_get_and_scan_range() { let summary = w.get_wallet_summary().unwrap(); tracing::info!("Wallet summary: {:?}", summary); } - -#[cfg(feature = "native")] -#[tokio::test] -async fn test_get_and_scan_range_native() { - use zcash_primitives::consensus; - let db_cache = tempfile::tempdir().unwrap(); - let _db_data = tempfile::NamedTempFile::new_in(db_cache.path()).unwrap(); - - initialize(); - let url = "https://testnet.zec.rocks:443"; - let c = tonic::transport::Channel::from_shared(url).unwrap(); - - let tls = tonic::transport::ClientTlsConfig::new() - .domain_name("testnet.zec.rocks") - .with_webpki_roots(); - let channel = c.tls_config(tls).unwrap(); - - #[cfg(feature = "sqlite-db")] - let wallet_db = { - use zcash_client_sqlite::{ - chain::init::init_blockmeta_db, wallet::init::init_wallet_db, FsBlockDb, WalletDb, - }; - - let mut db_cache = FsBlockDb::for_path(&db_cache).unwrap(); - let mut wallet_db = WalletDb::for_path(&_db_data, consensus::Network::TestNetwork).unwrap(); - init_blockmeta_db(&mut db_cache).unwrap(); - init_wallet_db(&mut wallet_db, None).unwrap(); - wallet_db - }; - - #[cfg(not(feature = "sqlite-db"))] - let wallet_db = zcash_client_memory::MemoryWalletDb::new( - consensus::Network::TestNetwork, - webz_core::PRUNING_DEPTH, - ); - - let mut w = Wallet::new( - wallet_db, - channel.connect().await.unwrap(), - Network::TestNetwork, - NonZeroU32::try_from(1).unwrap(), - ) - .unwrap(); - - let id = w.create_account(SEED, HD_INDEX, BIRTHDAY).await.unwrap(); - tracing::info!("Created account with id: {}", id); - - tracing::info!("Syncing wallet"); - w.sync(|scanned_to, tip| { - println!("Scanned: {}/{}", scanned_to, tip); - }) - .await - .unwrap(); - - tracing::info!("Syncing complete :)"); - - let summary = w.get_wallet_summary().unwrap(); - tracing::info!("Wallet summary: {:?}", summary); - - tracing::info!("Proposing a transaction"); - let addr = ZcashAddress::try_from_encoded("utest1z00xn09t4eyeqw9zmjss75sf460423dymgyfjn8rtlj26cffy0yad3eea82xekk24s00wnm38cvyrm2c6x7fxlc0ns4a5j7utgl6lchvglfvl9g9p56fqwzvzvj9d3z6r6ft88j654d7dj0ep6myq5duz9s8x78fdzmtx04d2qn8ydkxr4lfdhlkx9ktrw98gd97dateegrr68vl8xu"); - - w.transfer(SEED, 0, addr.unwrap(), 1000).await.unwrap(); - tracing::info!("Transaction proposed"); - - let summary = w.get_wallet_summary().unwrap(); - tracing::info!("Wallet summary: {:?}", summary); -} From e0624654e7aaebf924d7a65d831c85031968abc4 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 12:45:39 -0400 Subject: [PATCH 08/16] ignore .idea --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a981609..5ea1458 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target node_modules .DS_STORE +.idea From 8da363911d8ad54aca654880095ce5e9f51cd47a Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 13:31:26 -0400 Subject: [PATCH 09/16] message board sync on web --- justfile | 13 +++++- src/bindgen/wallet.rs | 35 ++++++++------- src/error.rs | 2 + src/wallet.rs | 4 +- tests/message-board-sync.rs | 47 +++++++++++++++++++++ tests/{tests.rs => simple-sync-and-send.rs} | 1 + 6 files changed, 83 insertions(+), 19 deletions(-) create mode 100644 tests/message-board-sync.rs rename tests/{tests.rs => simple-sync-and-send.rs} (99%) diff --git a/justfile b/justfile index d9863e4..d97a854 100644 --- a/justfile +++ b/justfile @@ -4,13 +4,22 @@ default: build: wasm-pack build -t web --release --out-dir ./packages/webz-core -Z --no-default-features --features="wasm" build-std="panic_abort,std" +## Wasm Tests test-web: WASM_BINDGEN_TEST_TIMEOUT=99999 wasm-pack test --release --firefox --no-default-features --features="wasm" -Z build-std="panic_abort,std" + +test-message-board-web: + WASM_BINDGEN_TEST_TIMEOUT=99999 wasm-pack test --release --firefox --no-default-features --features="wasm" -Z build-std="panic_abort,std" --test message-board-sync + +test-simple-web: + WASM_BINDGEN_TEST_TIMEOUT=99999 wasm-pack test --release --firefox --no-default-features --features="wasm" -Z build-std="panic_abort,std" --test simple-sync-and-send -example-native: + +## Native Examples +example-simple: cargo run -r --example simple-sync -example-sqlite: +example-simple-sqlite: cargo run -r --example simple-sync --features="sqlite-db" example-message-board: diff --git a/src/bindgen/wallet.rs b/src/bindgen/wallet.rs index 82f2bf4..8502fbd 100644 --- a/src/bindgen/wallet.rs +++ b/src/bindgen/wallet.rs @@ -37,6 +37,20 @@ pub struct WebWallet { inner: MemoryWallet, } +impl WebWallet { + fn network_from_str ( + network: &str + ) -> Result { + match network { + "main" => Ok(consensus::Network::MainNetwork), + "test" => Ok(consensus::Network::TestNetwork), + _ => { + Err(Error::InvalidNetwork(network.to_string())) + } + } + } +} + #[wasm_bindgen] impl WebWallet { /// Create a new instance of a Zcash wallet for a given network @@ -46,13 +60,7 @@ impl WebWallet { lightwalletd_url: &str, min_confirmations: u32, ) -> Result { - let network = match network { - "main" => consensus::Network::MainNetwork, - "test" => consensus::Network::TestNetwork, - _ => { - return Err(Error::InvalidNetwork(network.to_string())); - } - }; + let network = Self::network_from_str(network)?; let min_confirmations = NonZeroU32::try_from(min_confirmations) .map_err(|_| Error::InvalidMinConformations(min_confirmations))?; let client = Client::new(lightwalletd_url.to_string()); @@ -67,6 +75,7 @@ impl WebWallet { }) } + /// Add a new account to the wallet /// /// # Arguments @@ -90,14 +99,10 @@ impl WebWallet { key: &str, birthday_height: Option, ) -> Result { - let s = zcash_keys::encoding::decode_extended_full_viewing_key( - MAIN_NETWORK.hrp_sapling_extended_full_viewing_key(), - &key.trim(), - ) - .unwrap(); - let ufvk = UnifiedFullViewingKey::from_sapling_extended_full_viewing_key(s).unwrap(); - - self.inner.import_ufvk(ufvk, birthday_height).await + + let ufvk = UnifiedFullViewingKey::decode(&self.inner.network, key).map_err(Error::KeyParseError)?; + + self.inner.import_ufvk(&ufvk, birthday_height).await } pub fn suggest_scan_ranges(&self) -> Result, Error> { diff --git a/src/error.rs b/src/error.rs index fb12f12..0987210 100644 --- a/src/error.rs +++ b/src/error.rs @@ -44,6 +44,8 @@ pub enum Error { InvalidAmount(#[from] zcash_primitives::transaction::components::amount::BalanceError), #[error("Failed to send transaction")] SendFailed { code: i32, reason: String }, + #[error("Failed to parse key: {0}")] + KeyParseError(String), #[cfg(feature = "sqlite-db")] #[error("Sqlite error: {0}")] diff --git a/src/wallet.rs b/src/wallet.rs index 4748d3f..1df6572 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -158,7 +158,7 @@ where pub async fn import_ufvk( &mut self, - ufvk: UnifiedFullViewingKey, + ufvk: &UnifiedFullViewingKey, birthday_height: Option, ) -> Result { let birthday = match birthday_height { @@ -189,7 +189,7 @@ where let _account = self .db - .import_account_ufvk(&ufvk, &birthday, AccountPurpose::ViewOnly)?; + .import_account_ufvk(ufvk, &birthday, AccountPurpose::ViewOnly)?; Ok("0".to_string()) } diff --git a/tests/message-board-sync.rs b/tests/message-board-sync.rs new file mode 100644 index 0000000..d66d4e1 --- /dev/null +++ b/tests/message-board-sync.rs @@ -0,0 +1,47 @@ +use wasm_bindgen_test::*; +wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + +use std::sync::Once; +use zcash_keys::keys::UnifiedFullViewingKey; +use zcash_primitives::consensus::Network; +use zcash_primitives::constants; +use webz_core::bindgen::wallet::WebWallet; + +// Required to initialize the logger and panic hooks only once +static INIT: Once = Once::new(); +pub fn initialize() { + INIT.call_once(|| { + webz_core::init::start(); + }); +} +const SAPLING_EFVK: &'static str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz"; + +#[wasm_bindgen_test] +async fn test_message_board() { + initialize(); + + let mut w = WebWallet::new("main", "https://zcash-mainnet.chainsafe.dev", 1).unwrap(); + + let s = zcash_keys::encoding::decode_extended_full_viewing_key( + constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, + &SAPLING_EFVK.trim(), + ) + .unwrap(); + + let ufvk = UnifiedFullViewingKey::from_sapling_extended_full_viewing_key(s).unwrap(); + let ufvk_str = ufvk.encode(&Network::MainNetwork); + let id = w.import_ufvk(&ufvk_str, Some(2477329)).await.unwrap(); + tracing::info!("Created account with id: {}", id); + + tracing::info!("Syncing wallet"); + w.sync(&js_sys::Function::new_with_args( + "scanned_to, tip", + "console.log('Scanned: ', scanned_to, '/', tip)", + )) + .await + .unwrap(); + tracing::info!("Syncing complete :)"); + + let summary = w.get_wallet_summary().unwrap(); + tracing::info!("Wallet summary: {:?}", summary); +} diff --git a/tests/tests.rs b/tests/simple-sync-and-send.rs similarity index 99% rename from tests/tests.rs rename to tests/simple-sync-and-send.rs index 610cd67..392f731 100644 --- a/tests/tests.rs +++ b/tests/simple-sync-and-send.rs @@ -44,3 +44,4 @@ async fn test_get_and_scan_range() { let summary = w.get_wallet_summary().unwrap(); tracing::info!("Wallet summary: {:?}", summary); } + From 2e102574165e5fbc7b3e2a726946f2ea9487c38b Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 13:32:30 -0400 Subject: [PATCH 10/16] fmt --- examples/message-board-sync.rs | 10 +++++----- src/bindgen/wallet.rs | 13 ++++--------- tests/message-board-sync.rs | 8 ++++---- tests/simple-sync-and-send.rs | 1 - 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/examples/message-board-sync.rs b/examples/message-board-sync.rs index 864ddee..8ee963a 100644 --- a/examples/message-board-sync.rs +++ b/examples/message-board-sync.rs @@ -51,13 +51,13 @@ async fn main() { Network::MainNetwork, NonZeroU32::try_from(1).unwrap(), ) - .unwrap(); + .unwrap(); let s = zcash_keys::encoding::decode_extended_full_viewing_key( constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, &SAPLING_EFVK.trim(), ) - .unwrap(); + .unwrap(); let ufvk = UnifiedFullViewingKey::from_sapling_extended_full_viewing_key(s).unwrap(); let id = w.import_ufvk(ufvk, Some(2477329)).await.unwrap(); @@ -67,11 +67,11 @@ async fn main() { w.sync(|scanned_to, tip| { println!("Scanned: {}/{}", scanned_to, tip); }) - .await - .unwrap(); + .await + .unwrap(); tracing::info!("Syncing complete :)"); let summary = w.get_wallet_summary().unwrap(); tracing::info!("Wallet summary: {:?}", summary); -} \ No newline at end of file +} diff --git a/src/bindgen/wallet.rs b/src/bindgen/wallet.rs index 8502fbd..04f72e8 100644 --- a/src/bindgen/wallet.rs +++ b/src/bindgen/wallet.rs @@ -38,15 +38,11 @@ pub struct WebWallet { } impl WebWallet { - fn network_from_str ( - network: &str - ) -> Result { + fn network_from_str(network: &str) -> Result { match network { "main" => Ok(consensus::Network::MainNetwork), "test" => Ok(consensus::Network::TestNetwork), - _ => { - Err(Error::InvalidNetwork(network.to_string())) - } + _ => Err(Error::InvalidNetwork(network.to_string())), } } } @@ -75,7 +71,6 @@ impl WebWallet { }) } - /// Add a new account to the wallet /// /// # Arguments @@ -99,8 +94,8 @@ impl WebWallet { key: &str, birthday_height: Option, ) -> Result { - - let ufvk = UnifiedFullViewingKey::decode(&self.inner.network, key).map_err(Error::KeyParseError)?; + let ufvk = UnifiedFullViewingKey::decode(&self.inner.network, key) + .map_err(Error::KeyParseError)?; self.inner.import_ufvk(&ufvk, birthday_height).await } diff --git a/tests/message-board-sync.rs b/tests/message-board-sync.rs index d66d4e1..236728a 100644 --- a/tests/message-board-sync.rs +++ b/tests/message-board-sync.rs @@ -2,10 +2,10 @@ use wasm_bindgen_test::*; wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); use std::sync::Once; +use webz_core::bindgen::wallet::WebWallet; use zcash_keys::keys::UnifiedFullViewingKey; use zcash_primitives::consensus::Network; use zcash_primitives::constants; -use webz_core::bindgen::wallet::WebWallet; // Required to initialize the logger and panic hooks only once static INIT: Once = Once::new(); @@ -26,7 +26,7 @@ async fn test_message_board() { constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, &SAPLING_EFVK.trim(), ) - .unwrap(); + .unwrap(); let ufvk = UnifiedFullViewingKey::from_sapling_extended_full_viewing_key(s).unwrap(); let ufvk_str = ufvk.encode(&Network::MainNetwork); @@ -38,8 +38,8 @@ async fn test_message_board() { "scanned_to, tip", "console.log('Scanned: ', scanned_to, '/', tip)", )) - .await - .unwrap(); + .await + .unwrap(); tracing::info!("Syncing complete :)"); let summary = w.get_wallet_summary().unwrap(); diff --git a/tests/simple-sync-and-send.rs b/tests/simple-sync-and-send.rs index 392f731..610cd67 100644 --- a/tests/simple-sync-and-send.rs +++ b/tests/simple-sync-and-send.rs @@ -44,4 +44,3 @@ async fn test_get_and_scan_range() { let summary = w.get_wallet_summary().unwrap(); tracing::info!("Wallet summary: {:?}", summary); } - From 22845f053c0ffbaffd2e9b5d5ee29e0b6508f18d Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 13:34:48 -0400 Subject: [PATCH 11/16] clippy --- src/bindgen/wallet.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindgen/wallet.rs b/src/bindgen/wallet.rs index 04f72e8..542f48c 100644 --- a/src/bindgen/wallet.rs +++ b/src/bindgen/wallet.rs @@ -8,7 +8,7 @@ use tonic_web_wasm_client::Client; use zcash_address::ZcashAddress; use zcash_client_memory::MemoryWalletDb; use zcash_keys::keys::UnifiedFullViewingKey; -use zcash_primitives::consensus::{self, BlockHeight, NetworkConstants, MAIN_NETWORK}; +use zcash_primitives::consensus::{self, BlockHeight}; use crate::error::Error; use crate::{BlockRange, MemoryWallet, Wallet, PRUNING_DEPTH}; From 3ea4de459d1f845cd4a38b8d3058ddf9a37cc938 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 13:43:19 -0400 Subject: [PATCH 12/16] more clippy --- examples/message-board-sync.rs | 4 ++-- tests/message-board-sync.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/message-board-sync.rs b/examples/message-board-sync.rs index 8ee963a..ba97a58 100644 --- a/examples/message-board-sync.rs +++ b/examples/message-board-sync.rs @@ -4,7 +4,7 @@ use std::num::NonZeroU32; use webz_core::Wallet; use zcash_primitives::consensus::Network; static INIT: Once = Once::new(); -const SAPLING_EFVK: &'static str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz"; +const SAPLING_EFVK: &str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz"; pub fn initialize() { INIT.call_once(|| { webz_core::init::start(); @@ -60,7 +60,7 @@ async fn main() { .unwrap(); let ufvk = UnifiedFullViewingKey::from_sapling_extended_full_viewing_key(s).unwrap(); - let id = w.import_ufvk(ufvk, Some(2477329)).await.unwrap(); + let id = w.import_ufvk(&ufvk, Some(2477329)).await.unwrap(); tracing::info!("Created account with id: {}", id); tracing::info!("Syncing wallet"); diff --git a/tests/message-board-sync.rs b/tests/message-board-sync.rs index 236728a..752612d 100644 --- a/tests/message-board-sync.rs +++ b/tests/message-board-sync.rs @@ -14,7 +14,7 @@ pub fn initialize() { webz_core::init::start(); }); } -const SAPLING_EFVK: &'static str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz"; +const SAPLING_EFVK: &str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz"; #[wasm_bindgen_test] async fn test_message_board() { From 540ee497e81efc3aa0b1faec5840c754c0ec2323 Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 13:46:39 -0400 Subject: [PATCH 13/16] lint --- examples/message-board-sync.rs | 2 +- tests/message-board-sync.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/message-board-sync.rs b/examples/message-board-sync.rs index ba97a58..dcb4496 100644 --- a/examples/message-board-sync.rs +++ b/examples/message-board-sync.rs @@ -55,7 +55,7 @@ async fn main() { let s = zcash_keys::encoding::decode_extended_full_viewing_key( constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, - &SAPLING_EFVK.trim(), + SAPLING_EFVK.trim(), ) .unwrap(); diff --git a/tests/message-board-sync.rs b/tests/message-board-sync.rs index 752612d..b9079ba 100644 --- a/tests/message-board-sync.rs +++ b/tests/message-board-sync.rs @@ -24,9 +24,9 @@ async fn test_message_board() { let s = zcash_keys::encoding::decode_extended_full_viewing_key( constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, - &SAPLING_EFVK.trim(), + SAPLING_EFVK.trim(), ) - .unwrap(); + .unwrap(); let ufvk = UnifiedFullViewingKey::from_sapling_extended_full_viewing_key(s).unwrap(); let ufvk_str = ufvk.encode(&Network::MainNetwork); @@ -38,8 +38,8 @@ async fn test_message_board() { "scanned_to, tip", "console.log('Scanned: ', scanned_to, '/', tip)", )) - .await - .unwrap(); + .await + .unwrap(); tracing::info!("Syncing complete :)"); let summary = w.get_wallet_summary().unwrap(); From 44d7977a4e1e633b4a8bde9e818b4e47cdd7c12d Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 13:48:21 -0400 Subject: [PATCH 14/16] rustfmt instead of jetbrains formatter --- tests/message-board-sync.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/message-board-sync.rs b/tests/message-board-sync.rs index b9079ba..41ffac2 100644 --- a/tests/message-board-sync.rs +++ b/tests/message-board-sync.rs @@ -26,7 +26,7 @@ async fn test_message_board() { constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, SAPLING_EFVK.trim(), ) - .unwrap(); + .unwrap(); let ufvk = UnifiedFullViewingKey::from_sapling_extended_full_viewing_key(s).unwrap(); let ufvk_str = ufvk.encode(&Network::MainNetwork); @@ -38,8 +38,8 @@ async fn test_message_board() { "scanned_to, tip", "console.log('Scanned: ', scanned_to, '/', tip)", )) - .await - .unwrap(); + .await + .unwrap(); tracing::info!("Syncing complete :)"); let summary = w.get_wallet_summary().unwrap(); From 6f7fc6c7e8818d94ba2233e48e944c68567e81eb Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Mon, 16 Sep 2024 14:35:01 -0400 Subject: [PATCH 15/16] point to latest rev librustzcash --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 18 +++++++++--------- src/init.rs | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20947fc..ae47bf6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -503,7 +503,7 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "equihash" version = "0.2.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "blake2b_simd", "byteorder", @@ -528,7 +528,7 @@ dependencies = [ [[package]] name = "f4jumble" version = "0.1.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "blake2b_simd", ] @@ -2745,7 +2745,7 @@ dependencies = [ [[package]] name = "zcash_address" version = "0.5.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "bech32", "bs58", @@ -2757,7 +2757,7 @@ dependencies = [ [[package]] name = "zcash_client_backend" version = "0.13.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "base64 0.21.7", "bech32", @@ -2801,7 +2801,7 @@ dependencies = [ [[package]] name = "zcash_client_memory" version = "0.1.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "bs58", "byteorder", @@ -2831,7 +2831,7 @@ dependencies = [ [[package]] name = "zcash_client_sqlite" version = "0.11.2" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "bs58", "byteorder", @@ -2867,7 +2867,7 @@ dependencies = [ [[package]] name = "zcash_encoding" version = "0.2.1" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "byteorder", "nonempty", @@ -2876,7 +2876,7 @@ dependencies = [ [[package]] name = "zcash_keys" version = "0.3.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "bech32", "bip32", @@ -2917,7 +2917,7 @@ dependencies = [ [[package]] name = "zcash_primitives" version = "0.17.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "aes", "bip32", @@ -2955,7 +2955,7 @@ dependencies = [ [[package]] name = "zcash_proofs" version = "0.17.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "bellman", "blake2b_simd", @@ -2975,7 +2975,7 @@ dependencies = [ [[package]] name = "zcash_protocol" version = "0.3.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "document-features", "memuse", @@ -3044,7 +3044,7 @@ dependencies = [ [[package]] name = "zip321" version = "0.1.0" -source = "git+https://github.com/ChainSafe/librustzcash?rev=a77e8a0204dab421fdbf5822e585716339567b96#a77e8a0204dab421fdbf5822e585716339567b96" +source = "git+https://github.com/ChainSafe/librustzcash?rev=c97a3f6e60446523fafa63cdf77b6c2584ac9f3b#c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" dependencies = [ "base64 0.21.7", "nom", diff --git a/Cargo.toml b/Cargo.toml index f9065ff..f031c5e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ console_error_panic_hook = ["dep:console_error_panic_hook"] wasm-bindgen = "0.2.84" js-sys = "0.3.69" wasm-bindgen-futures = "0.4.42" -web-sys = { version = "0.3.69", features = ["console"] } +web-sys = { version = "0.3.69", features = ["console"] } # WASM specific dependencies tracing-web = { version = "0.1.3", optional = true } @@ -48,12 +48,12 @@ console_error_panic_hook = { version = "0.1.7", optional = true } tonic-web-wasm-client = "0.6.0" ## Zcash dependencies -zcash_keys = { git = "https://github.com/ChainSafe/librustzcash", rev = "a77e8a0204dab421fdbf5822e585716339567b96", features = ["transparent-inputs", "orchard", "sapling", "unstable"] } -zcash_client_backend = { git = "https://github.com/ChainSafe/librustzcash", rev = "a77e8a0204dab421fdbf5822e585716339567b96", default-features = false, features = ["lightwalletd-tonic", "wasm-bindgen"] } -zcash_client_memory = { git = "https://github.com/ChainSafe/librustzcash", rev = "a77e8a0204dab421fdbf5822e585716339567b96", features = ["orchard"] } -zcash_primitives = { git = "https://github.com/ChainSafe/librustzcash", rev = "a77e8a0204dab421fdbf5822e585716339567b96" } -zcash_address = { git = "https://github.com/ChainSafe/librustzcash", rev = "a77e8a0204dab421fdbf5822e585716339567b96" } -zcash_proofs = { git = "https://github.com/ChainSafe/librustzcash", rev = "a77e8a0204dab421fdbf5822e585716339567b96", default-features = false, features = ["bundled-prover"] } +zcash_keys = { git = "https://github.com/ChainSafe/librustzcash", rev = "c97a3f6e60446523fafa63cdf77b6c2584ac9f3b", features = ["transparent-inputs", "orchard", "sapling", "unstable"] } +zcash_client_backend = { git = "https://github.com/ChainSafe/librustzcash", rev = "c97a3f6e60446523fafa63cdf77b6c2584ac9f3b", default-features = false, features = ["lightwalletd-tonic", "wasm-bindgen"] } +zcash_client_memory = { git = "https://github.com/ChainSafe/librustzcash", rev = "c97a3f6e60446523fafa63cdf77b6c2584ac9f3b", features = ["orchard"] } +zcash_primitives = { git = "https://github.com/ChainSafe/librustzcash", rev = "c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" } +zcash_address = { git = "https://github.com/ChainSafe/librustzcash", rev = "c97a3f6e60446523fafa63cdf77b6c2584ac9f3b" } +zcash_proofs = { git = "https://github.com/ChainSafe/librustzcash", rev = "c97a3f6e60446523fafa63cdf77b6c2584ac9f3b", default-features = false, features = ["bundled-prover"] } ## gRPC Web dependencies prost = { version = "0.12", default-features = false } @@ -63,7 +63,7 @@ tonic = { version = "0.12", default-features = false, features = [ # Used in Native tests tokio = { version = "1.0", features = ["rt", "macros", "rt-multi-thread"], optional = true } -zcash_client_sqlite = { git = "https://github.com/ChainSafe/librustzcash", rev = "a77e8a0204dab421fdbf5822e585716339567b96", default-features = false, features = ["unstable", "orchard"], optional = true } +zcash_client_sqlite = { git = "https://github.com/ChainSafe/librustzcash", rev = "c97a3f6e60446523fafa63cdf77b6c2584ac9f3b", default-features = false, features = ["unstable", "orchard"], optional = true } getrandom = { version = "0.2", features = ["js"] } thiserror = "1.0.63" @@ -84,4 +84,4 @@ wasm-bindgen-test = "0.3.42" tempfile = "3.12" [patch.crates-io] -zip32 = { git = "https://github.com/zcash/zip32.git", branch = "diversifier_index_ord"} +zip32 = { git = "https://github.com/zcash/zip32.git", branch = "diversifier_index_ord" } diff --git a/src/init.rs b/src/init.rs index ecb5429..1467d8e 100644 --- a/src/init.rs +++ b/src/init.rs @@ -25,7 +25,7 @@ fn setup_tracing() { .with_default_directive(LevelFilter::INFO.into()) .from_env() .unwrap(); - let fmt_layer = tracing_subscriber::fmt::layer().with_ansi(true).pretty(); + let fmt_layer = tracing_subscriber::fmt::layer().with_ansi(true); tracing_subscriber::registry() .with(filter_layer) .with(fmt_layer) From bddba7305ee5791693656dcbacb94f584b4c4faf Mon Sep 17 00:00:00 2001 From: Eric Tu Date: Tue, 17 Sep 2024 14:41:28 -0400 Subject: [PATCH 16/16] break up import ufvk and create account --- src/wallet.rs | 48 ++++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/src/wallet.rs b/src/wallet.rs index 1df6572..3cac98f 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -123,43 +123,25 @@ where let usk = usk_from_seed_str(seed_phrase, account_index, &self.network)?; let ufvk = usk.to_unified_full_viewing_key(); - let birthday = match birthday_height { - Some(height) => height, - None => { - let chain_tip: u32 = self - .client - .get_latest_block(service::ChainSpec::default()) - .await? - .into_inner() - .height - .try_into() - .expect("block heights must fit into u32"); - chain_tip - 100 - } - }; - // Construct an `AccountBirthday` for the account's birthday. - let birthday = { - // Fetch the tree state corresponding to the last block prior to the wallet's - // birthday height. NOTE: THIS APPROACH LEAKS THE BIRTHDAY TO THE SERVER! - let request = service::BlockId { - height: (birthday - 1).into(), - ..Default::default() - }; - let treestate = self.client.get_tree_state(request).await?.into_inner(); - AccountBirthday::from_treestate(treestate, None).map_err(|_| Error::BirthdayError)? - }; - - let _account = self - .db - .import_account_ufvk(&ufvk, &birthday, AccountPurpose::Spending)?; - // TOOD: Make this public on account Ok(account.account_id().to_string()) - Ok("0".to_string()) + self.import_account_ufvk(&ufvk, birthday_height, AccountPurpose::Spending) + .await } pub async fn import_ufvk( &mut self, ufvk: &UnifiedFullViewingKey, birthday_height: Option, + ) -> Result { + self.import_account_ufvk(ufvk, birthday_height, AccountPurpose::ViewOnly) + .await + } + + /// Helper method for importing an account directly from a Ufvk or from seed. + async fn import_account_ufvk( + &mut self, + ufvk: &UnifiedFullViewingKey, + birthday_height: Option, + purpose: AccountPurpose, ) -> Result { let birthday = match birthday_height { Some(height) => height, @@ -187,9 +169,7 @@ where AccountBirthday::from_treestate(treestate, None).map_err(|_| Error::BirthdayError)? }; - let _account = self - .db - .import_account_ufvk(ufvk, &birthday, AccountPurpose::ViewOnly)?; + let _account = self.db.import_account_ufvk(ufvk, &birthday, purpose)?; Ok("0".to_string()) }