diff --git a/zcash_client_backend/src/keys.rs b/zcash_client_backend/src/keys.rs index 152c12b0a..c43a420ef 100644 --- a/zcash_client_backend/src/keys.rs +++ b/zcash_client_backend/src/keys.rs @@ -2,15 +2,18 @@ use zcash_primitives::zip32::{ChildIndex, ExtendedSpendingKey}; +use crate::wallet::AccountId; + +use zcash_primitives::{legacy::TransparentAddress, zip32::ExtendedFullViewingKey}; + #[cfg(feature = "transparent-inputs")] use { - crate::wallet::AccountId, bs58::{self, decode::Error as Bs58Error}, hdwallet::{ExtendedPrivKey, ExtendedPubKey, KeyIndex}, secp256k1::{key::PublicKey, key::SecretKey, Secp256k1}, sha2::{Digest, Sha256}, std::convert::TryInto, - zcash_primitives::{consensus, legacy::TransparentAddress}, + zcash_primitives::consensus, }; /// Derives the ZIP 32 [`ExtendedSpendingKey`] for a given coin type and account from the @@ -138,9 +141,57 @@ impl<'a> TryInto for &'a Wif { } } +/// A set of viewing keys that are all associated with a single +/// ZIP-0032 account identifier. +#[derive(Clone, Debug)] +pub struct UnifiedFullViewingKey { + account: AccountId, + transparent: Option, + sapling: Option, +} + +impl UnifiedFullViewingKey { + /// Construct a new unified full viewing key, if the required components are present. + pub fn new( + account: AccountId, + transparent: Option, + sapling: Option, + ) -> Option { + if sapling.is_none() { + None + } else { + Some(UnifiedFullViewingKey { + account, + transparent, + sapling, + }) + } + } + + /// Returns the ZIP32 account identifier to which all component + /// keys are related. + pub fn account(&self) -> AccountId { + self.account + } + + /// Returns the transparent component of the unified key. + // TODO: make this the pubkey rather than the address to + // permit child derivation + pub fn transparent(&self) -> Option<&TransparentAddress> { + self.transparent.as_ref() + } + + /// Returns the Sapling extended full viewing key component of this + /// unified key. + pub fn sapling(&self) -> Option<&ExtendedFullViewingKey> { + self.sapling.as_ref() + } +} + #[cfg(test)] mod tests { use super::spending_key; + use crate::wallet::AccountId; #[cfg(feature = "transparent-inputs")] use { @@ -149,12 +200,13 @@ mod tests { derive_transparent_address_from_public_key, derive_transparent_address_from_secret_key, Wif, }, - crate::{encoding::AddressCodec, wallet::AccountId}, + crate::encoding::AddressCodec, secp256k1::key::SecretKey, std::convert::TryInto, zcash_primitives::consensus::MAIN_NETWORK, }; + #[cfg(feature = "transparent-inputs")] fn seed() -> Vec { let seed_hex = "6ef5f84def6f4b9d38f466586a8380a38593bd47c8cda77f091856176da47f26b5bd1c8d097486e5635df5a66e820d28e1d73346f499801c86228d43f390304f"; hex::decode(&seed_hex).unwrap() diff --git a/zcash_client_sqlite/Cargo.toml b/zcash_client_sqlite/Cargo.toml index e9186e956..eaf346dff 100644 --- a/zcash_client_sqlite/Cargo.toml +++ b/zcash_client_sqlite/Cargo.toml @@ -23,8 +23,8 @@ rand_core = "0.6" rusqlite = { version = "0.24", features = ["bundled", "time"] } secp256k1 = { version = "0.20" } time = "0.2" -zcash_client_backend = { version = "0.5", path = "../zcash_client_backend", features = ["transparent-inputs"] } -zcash_primitives = { version = "0.5", path = "../zcash_primitives", features = ["transparent-inputs"] } +zcash_client_backend = { version = "0.5", path = "../zcash_client_backend"} +zcash_primitives = { version = "0.5", path = "../zcash_primitives"} [dev-dependencies] tempfile = "3" @@ -33,6 +33,7 @@ zcash_proofs = { version = "0.5", path = "../zcash_proofs" } [features] mainnet = [] test-dependencies = ["zcash_client_backend/test-dependencies"] +transparent-inputs = ["zcash_client_backend/transparent-inputs", "zcash_primitives/transparent-inputs"] [lib] bench = false diff --git a/zcash_client_sqlite/src/lib.rs b/zcash_client_sqlite/src/lib.rs index a7ccaaac1..bfba66ab9 100644 --- a/zcash_client_sqlite/src/lib.rs +++ b/zcash_client_sqlite/src/lib.rs @@ -60,6 +60,7 @@ use zcash_client_backend::{ use crate::error::SqliteClientError; +#[cfg(feature = "transparent-inputs")] use { zcash_client_backend::wallet::WalletTransparentOutput, zcash_primitives::legacy::TransparentAddress, @@ -148,6 +149,7 @@ impl WalletDb

{ WHERE prevout_txid = :prevout_txid AND prevout_idx = :prevout_idx" )?, + #[cfg(feature = "transparent-inputs")] stmt_insert_received_transparent_utxo: self.conn.prepare( "INSERT INTO utxos (address, prevout_txid, prevout_idx, script, value_zat, height) VALUES (:address, :prevout_txid, :prevout_idx, :script, :value_zat, :height)" @@ -299,6 +301,7 @@ impl WalletRead for WalletDb

{ ) } + #[cfg(feature = "transparent-inputs")] fn get_unspent_transparent_outputs( &self, address: &TransparentAddress, @@ -329,6 +332,7 @@ pub struct DataConnStmtCache<'a, P> { stmt_mark_sapling_note_spent: Statement<'a>, stmt_mark_transparent_utxo_spent: Statement<'a>, + #[cfg(feature = "transparent-inputs")] stmt_insert_received_transparent_utxo: Statement<'a>, stmt_delete_utxos: Statement<'a>, stmt_insert_received_note: Statement<'a>, @@ -436,6 +440,7 @@ impl<'a, P: consensus::Parameters> WalletRead for DataConnStmtCache<'a, P> { .select_spendable_sapling_notes(account, target_value, anchor_height) } + #[cfg(feature = "transparent-inputs")] fn get_unspent_transparent_outputs( &self, address: &TransparentAddress, @@ -694,15 +699,17 @@ mod tests { use protobuf::Message; use rand_core::{OsRng, RngCore}; use rusqlite::params; - use secp256k1::key::SecretKey; use zcash_client_backend::{ - keys::{ - derive_secret_key_from_seed, derive_transparent_address_from_secret_key, spending_key, - }, + keys::{spending_key, UnifiedFullViewingKey}, proto::compact_formats::{CompactBlock, CompactOutput, CompactSpend, CompactTx}, }; + #[cfg(feature = "transparent-inputs")] + use zcash_client_backend::keys::{ + derive_secret_key_from_seed, derive_transparent_address_from_secret_key, + }; + use zcash_primitives::{ block::BlockHash, consensus::{BlockHeight, Network, NetworkUpgrade, Parameters}, @@ -713,7 +720,7 @@ mod tests { PaymentAddress, }, transaction::components::Amount, - zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}, + zip32::ExtendedFullViewingKey, }; use crate::{wallet::init::init_accounts_table, AccountId, WalletDb}; @@ -744,22 +751,26 @@ mod tests { .unwrap() } - pub(crate) fn derive_test_keys_from_seed( - seed: &[u8], - account: AccountId, - ) -> (ExtendedSpendingKey, SecretKey) { - let extsk = spending_key(seed, network().coin_type(), account); - let tsk = derive_secret_key_from_seed(&network(), seed, account, 0).unwrap(); - (extsk, tsk) - } - pub(crate) fn init_test_accounts_table( db_data: &WalletDb, - ) -> (ExtendedFullViewingKey, TransparentAddress) { - let (extsk, tsk) = derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); + ) -> (ExtendedFullViewingKey, Option) { + let seed = [0u8; 32]; + + let extsk = spending_key(&seed, network().coin_type(), AccountId(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); - let taddr = derive_transparent_address_from_secret_key(&tsk); - init_accounts_table(db_data, &[extfvk.clone()], &[taddr.clone()]).unwrap(); + + #[cfg(feature = "transparent-inputs")] + let taddr = { + let tsk = derive_secret_key_from_seed(&network(), &seed, AccountId(0), 0).unwrap(); + Some(derive_transparent_address_from_secret_key(&tsk)) + }; + + #[cfg(not(feature = "transparent-inputs"))] + let taddr = None; + + let ufvk = + UnifiedFullViewingKey::new(AccountId(0), taddr.clone(), Some(extfvk.clone())).unwrap(); + init_accounts_table(db_data, &[ufvk]).unwrap(); (extfvk, taddr) } diff --git a/zcash_client_sqlite/src/wallet.rs b/zcash_client_sqlite/src/wallet.rs index d064eefba..6c0f87125 100644 --- a/zcash_client_sqlite/src/wallet.rs +++ b/zcash_client_sqlite/src/wallet.rs @@ -37,13 +37,13 @@ use zcash_client_backend::{ use crate::{error::SqliteClientError, DataConnStmtCache, NoteId, WalletDb, PRUNING_HEIGHT}; +use {zcash_client_backend::encoding::AddressCodec, zcash_primitives::legacy::TransparentAddress}; + +#[cfg(feature = "transparent-inputs")] use { crate::UtxoId, - zcash_client_backend::{encoding::AddressCodec, wallet::WalletTransparentOutput}, - zcash_primitives::{ - legacy::{Script, TransparentAddress}, - transaction::components::TxOut, - }, + zcash_client_backend::wallet::WalletTransparentOutput, + zcash_primitives::{legacy::Script, transaction::components::TxOut}, }; pub mod init; @@ -704,6 +704,7 @@ pub fn get_all_nullifiers

( Ok(res) } +#[cfg(feature = "transparent-inputs")] pub fn get_unspent_transparent_outputs( wdb: &WalletDb

, address: &TransparentAddress, @@ -867,6 +868,7 @@ pub fn mark_transparent_utxo_spent<'a, P>( Ok(()) } +#[cfg(feature = "transparent-inputs")] pub fn put_received_transparent_utxo<'a, P: consensus::Parameters>( stmts: &mut DataConnStmtCache<'a, P>, output: &WalletTransparentOutput, diff --git a/zcash_client_sqlite/src/wallet/init.rs b/zcash_client_sqlite/src/wallet/init.rs index 96e436300..eeb8be965 100644 --- a/zcash_client_sqlite/src/wallet/init.rs +++ b/zcash_client_sqlite/src/wallet/init.rs @@ -1,15 +1,16 @@ //! Functions for initializing the various databases. -use rusqlite::{types::ToSql, NO_PARAMS}; +use rusqlite::{params, types::ToSql, NO_PARAMS}; use zcash_primitives::{ block::BlockHash, consensus::{self, BlockHeight}, - legacy::TransparentAddress, - zip32::ExtendedFullViewingKey, }; -use zcash_client_backend::encoding::{encode_extended_full_viewing_key, AddressCodec}; +use zcash_client_backend::{ + encoding::{encode_extended_full_viewing_key, AddressCodec}, + keys::UnifiedFullViewingKey, +}; use crate::{address_from_extfvk, error::SqliteClientError, WalletDb}; @@ -33,9 +34,9 @@ pub fn init_wallet_db

(wdb: &WalletDb

) -> Result<(), rusqlite::Error> { wdb.conn.execute( "CREATE TABLE IF NOT EXISTS accounts ( account INTEGER PRIMARY KEY, - extfvk TEXT NOT NULL, - address TEXT NOT NULL, - transparent_address TEXT NOT NULL + extfvk TEXT, + address TEXT, + transparent_address TEXT )", NO_PARAMS, )?; @@ -126,11 +127,11 @@ pub fn init_wallet_db

(wdb: &WalletDb

) -> Result<(), rusqlite::Error> { Ok(()) } -/// Initialises the data database with the given [`ExtendedFullViewingKey`]s. +/// Initialises the data database with the given [`UnifiedFullViewingKey`]s. /// -/// The [`ExtendedFullViewingKey`]s are stored internally and used by other APIs such as +/// The [`UnifiedFullViewingKey`]s are stored internally and used by other APIs such as /// [`get_address`], [`scan_cached_blocks`], and [`create_spend_to_address`]. `extfvks` **MUST** -/// be arranged in account-order; that is, the [`ExtendedFullViewingKey`] for ZIP 32 +/// be arranged in account-order; that is, the [`UnifiedFullViewingKey`] for ZIP 32 /// account `i` **MUST** be at `extfvks[i]`. /// /// # Examples @@ -144,7 +145,10 @@ pub fn init_wallet_db

(wdb: &WalletDb

) -> Result<(), rusqlite::Error> { /// }; /// /// use zcash_client_backend::{ -/// keys::{spending_key, derive_transparent_address_from_secret_key, derive_secret_key_from_seed}, +/// keys::{ +/// spending_key, +/// UnifiedFullViewingKey +/// }, /// wallet::AccountId, /// }; /// @@ -160,10 +164,9 @@ pub fn init_wallet_db

(wdb: &WalletDb

) -> Result<(), rusqlite::Error> { /// let seed = [0u8; 32]; /// let account = AccountId(0); /// let extsk = spending_key(&seed, Network::TestNetwork.coin_type(), account); -/// let tsk = derive_secret_key_from_seed(&Network::TestNetwork, &seed, account, 0).unwrap(); /// let extfvk = ExtendedFullViewingKey::from(&extsk); -/// let taddr = derive_transparent_address_from_secret_key(&tsk); -/// init_accounts_table(&db_data, &[extfvk], &[taddr]).unwrap(); +/// let ufvk = UnifiedFullViewingKey::new(account, None, Some(extfvk)).unwrap(); +/// init_accounts_table(&db_data, &[ufvk]).unwrap(); /// ``` /// /// [`get_address`]: crate::wallet::get_address @@ -171,12 +174,8 @@ pub fn init_wallet_db

(wdb: &WalletDb

) -> Result<(), rusqlite::Error> { /// [`create_spend_to_address`]: zcash_client_backend::data_api::wallet::create_spend_to_address pub fn init_accounts_table( wdb: &WalletDb

, - extfvks: &[ExtendedFullViewingKey], - taddrs: &[TransparentAddress], + keys: &[UnifiedFullViewingKey], ) -> Result<(), SqliteClientError> { - //TODO: make this a proper error? - assert!(extfvks.len() == taddrs.len()); - let mut empty_check = wdb.conn.prepare("SELECT * FROM accounts LIMIT 1")?; if empty_check.exists(NO_PARAMS)? { return Err(SqliteClientError::TableNotEmpty); @@ -184,24 +183,23 @@ pub fn init_accounts_table( // Insert accounts atomically wdb.conn.execute("BEGIN IMMEDIATE", NO_PARAMS)?; - for (account, (extfvk, taddr)) in extfvks.iter().zip(taddrs.iter()).enumerate() { - let extfvk_str = encode_extended_full_viewing_key( - wdb.params.hrp_sapling_extended_full_viewing_key(), - extfvk, - ); + for key in keys.iter() { + let extfvk_str: Option = key.sapling().map(|extfvk| { + encode_extended_full_viewing_key( + wdb.params.hrp_sapling_extended_full_viewing_key(), + extfvk, + ) + }); - let address_str = address_from_extfvk(&wdb.params, extfvk); - let taddress_str: String = taddr.encode(&wdb.params); + let address_str: Option = key + .sapling() + .map(|extfvk| address_from_extfvk(&wdb.params, extfvk)); + let taddress_str: Option = key.transparent().map(|taddr| taddr.encode(&wdb.params)); wdb.conn.execute( "INSERT INTO accounts (account, extfvk, address, transparent_address) VALUES (?, ?, ?, ?)", - &[ - (account as u32).to_sql()?, - extfvk_str.to_sql()?, - address_str.to_sql()?, - taddress_str.to_sql()?, - ], + params![key.account().0, extfvk_str, address_str, taddress_str,], )?; } wdb.conn.execute("COMMIT", NO_PARAMS)?; @@ -271,13 +269,24 @@ pub fn init_blocks_table

( mod tests { use tempfile::NamedTempFile; - use zcash_client_backend::keys::derive_transparent_address_from_secret_key; + use zcash_client_backend::keys::{spending_key, UnifiedFullViewingKey}; - use zcash_primitives::{ - block::BlockHash, consensus::BlockHeight, zip32::ExtendedFullViewingKey, + #[cfg(feature = "transparent-inputs")] + use zcash_client_backend::keys::{ + derive_secret_key_from_seed, derive_transparent_address_from_secret_key, }; - use crate::{tests, wallet::get_address, AccountId, WalletDb}; + use zcash_primitives::{ + block::BlockHash, + consensus::{BlockHeight, Parameters}, + zip32::ExtendedFullViewingKey, + }; + + use crate::{ + tests::{self, network}, + wallet::get_address, + AccountId, WalletDb, + }; use super::{init_accounts_table, init_blocks_table, init_wallet_db}; @@ -288,18 +297,34 @@ mod tests { init_wallet_db(&db_data).unwrap(); // We can call the function as many times as we want with no data - init_accounts_table(&db_data, &[], &[]).unwrap(); - init_accounts_table(&db_data, &[], &[]).unwrap(); + init_accounts_table(&db_data, &[]).unwrap(); + init_accounts_table(&db_data, &[]).unwrap(); + + let seed = [0u8; 32]; + let account = AccountId(0); // First call with data should initialise the accounts table - let (extsk, tsk) = tests::derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); + let extsk = spending_key(&seed, network().coin_type(), account); let extfvk = ExtendedFullViewingKey::from(&extsk); - let taddr = derive_transparent_address_from_secret_key(&tsk); - init_accounts_table(&db_data, &[extfvk.clone()], &[taddr.clone()]).unwrap(); + + #[cfg(feature = "transparent-inputs")] + let ufvk = { + let tsk = derive_secret_key_from_seed(&network(), &seed, account, 0).unwrap(); + UnifiedFullViewingKey::new( + account, + Some(derive_transparent_address_from_secret_key(&tsk)), + Some(extfvk), + ) + .unwrap() + }; + #[cfg(not(feature = "transparent-inputs"))] + let ufvk = UnifiedFullViewingKey::new(account, None, Some(extfvk)).unwrap(); + + init_accounts_table(&db_data, &[ufvk.clone()]).unwrap(); // Subsequent calls should return an error - init_accounts_table(&db_data, &[], &[]).unwrap_err(); - init_accounts_table(&db_data, &[extfvk], &[taddr]).unwrap_err(); + init_accounts_table(&db_data, &[]).unwrap_err(); + init_accounts_table(&db_data, &[ufvk]).unwrap_err(); } #[test] @@ -335,11 +360,13 @@ mod tests { let db_data = WalletDb::for_path(data_file.path(), tests::network()).unwrap(); init_wallet_db(&db_data).unwrap(); + let seed = [0u8; 32]; + // Add an account to the wallet - let (extsk, tsk) = tests::derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); + let extsk = spending_key(&seed, network().coin_type(), AccountId(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); - let taddr = derive_transparent_address_from_secret_key(&tsk); - init_accounts_table(&db_data, &[extfvk], &[taddr]).unwrap(); + let ufvk = UnifiedFullViewingKey::new(AccountId(0), None, Some(extfvk)).unwrap(); + init_accounts_table(&db_data, &[ufvk]).unwrap(); // The account's address should be in the data DB let pa = get_address(&db_data, AccountId(0)).unwrap(); diff --git a/zcash_client_sqlite/src/wallet/transact.rs b/zcash_client_sqlite/src/wallet/transact.rs index 25f680efb..d766a4a63 100644 --- a/zcash_client_sqlite/src/wallet/transact.rs +++ b/zcash_client_sqlite/src/wallet/transact.rs @@ -153,7 +153,7 @@ mod tests { use zcash_primitives::{ block::BlockHash, - consensus::{BlockHeight, BranchId}, + consensus::{BlockHeight, BranchId, Parameters}, legacy::TransparentAddress, sapling::{note_encryption::try_sapling_output_recovery, prover::TxProver}, transaction::{components::Amount, Transaction}, @@ -164,16 +164,18 @@ mod tests { use zcash_client_backend::{ data_api::{chain::scan_cached_blocks, wallet::create_spend_to_address, WalletRead}, - keys::derive_transparent_address_from_secret_key, + keys::{spending_key, UnifiedFullViewingKey}, wallet::OvkPolicy, }; + #[cfg(feature = "transparent-inputs")] + use zcash_client_backend::keys::{ + derive_secret_key_from_seed, derive_transparent_address_from_secret_key, + }; + use crate::{ chain::init::init_cache_database, - tests::{ - self, derive_test_keys_from_seed, fake_compact_block, insert_into_cache, - sapling_activation_height, - }, + tests::{self, fake_compact_block, insert_into_cache, network, sapling_activation_height}, wallet::{ get_balance, get_balance_at, init::{init_accounts_table, init_blocks_table, init_wallet_db}, @@ -197,17 +199,39 @@ mod tests { init_wallet_db(&db_data).unwrap(); // Add two accounts to the wallet - let (extsk0, tsk0) = derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); - let (extsk1, tsk1) = derive_test_keys_from_seed(&[1u8; 32], AccountId(1)); - let extfvks = [ - ExtendedFullViewingKey::from(&extsk0), - ExtendedFullViewingKey::from(&extsk1), + let extsk0 = spending_key(&[0u8; 32], network().coin_type(), AccountId(0)); + let extsk1 = spending_key(&[1u8; 32], network().coin_type(), AccountId(1)); + let extfvk0 = ExtendedFullViewingKey::from(&extsk0); + let extfvk1 = ExtendedFullViewingKey::from(&extsk1); + + #[cfg(feature = "transparent-inputs")] + let ufvks = { + let tsk0 = + derive_secret_key_from_seed(&network(), &[0u8; 32], AccountId(0), 0).unwrap(); + let tsk1 = + derive_secret_key_from_seed(&network(), &[1u8; 32], AccountId(1), 0).unwrap(); + [ + UnifiedFullViewingKey::new( + AccountId(0), + Some(derive_transparent_address_from_secret_key(&tsk0)), + Some(extfvk0), + ) + .unwrap(), + UnifiedFullViewingKey::new( + AccountId(1), + Some(derive_transparent_address_from_secret_key(&tsk1)), + Some(extfvk1), + ) + .unwrap(), + ] + }; + #[cfg(not(feature = "transparent-inputs"))] + let ufvks = [ + UnifiedFullViewingKey::new(AccountId(0), None, Some(extfvk0)).unwrap(), + UnifiedFullViewingKey::new(AccountId(1), None, Some(extfvk1)).unwrap(), ]; - let taddrs = [ - derive_transparent_address_from_secret_key(&tsk0), - derive_transparent_address_from_secret_key(&tsk1), - ]; - init_accounts_table(&db_data, &extfvks, &taddrs).unwrap(); + + init_accounts_table(&db_data, &ufvks).unwrap(); let to = extsk0.default_address().unwrap().1.into(); // Invalid extsk for the given account should cause an error @@ -252,10 +276,10 @@ mod tests { init_wallet_db(&db_data).unwrap(); // Add an account to the wallet - let (extsk, tsk) = derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); + let extsk = spending_key(&[0u8; 32], network().coin_type(), AccountId(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); - let taddr = derive_transparent_address_from_secret_key(&tsk); - init_accounts_table(&db_data, &[extfvk], &[taddr]).unwrap(); + let ufvk = UnifiedFullViewingKey::new(AccountId(0), None, Some(extfvk)).unwrap(); + init_accounts_table(&db_data, &[ufvk]).unwrap(); let to = extsk.default_address().unwrap().1.into(); // We cannot do anything if we aren't synchronised @@ -292,10 +316,10 @@ mod tests { .unwrap(); // Add an account to the wallet - let (extsk, tsk) = derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); + let extsk = spending_key(&[0u8; 32], network().coin_type(), AccountId(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); - let taddr = derive_transparent_address_from_secret_key(&tsk); - init_accounts_table(&db_data, &[extfvk], &[taddr]).unwrap(); + let ufvk = UnifiedFullViewingKey::new(AccountId(0), None, Some(extfvk)).unwrap(); + init_accounts_table(&db_data, &[ufvk]).unwrap(); let to = extsk.default_address().unwrap().1.into(); // Account balance should be zero @@ -334,10 +358,10 @@ mod tests { init_wallet_db(&db_data).unwrap(); // Add an account to the wallet - let (extsk, tsk) = derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); + let extsk = spending_key(&[0u8; 32], network().coin_type(), AccountId(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); - let taddr = derive_transparent_address_from_secret_key(&tsk); - init_accounts_table(&db_data, &[extfvk.clone()], &[taddr]).unwrap(); + let ufvk = UnifiedFullViewingKey::new(AccountId(0), None, Some(extfvk.clone())).unwrap(); + init_accounts_table(&db_data, &[ufvk]).unwrap(); // Add funds to the wallet in a single note let value = Amount::from_u64(50000).unwrap(); @@ -474,10 +498,10 @@ mod tests { init_wallet_db(&db_data).unwrap(); // Add an account to the wallet - let (extsk, tsk) = derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); + let extsk = spending_key(&[0u8; 32], network().coin_type(), AccountId(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); - let taddr = derive_transparent_address_from_secret_key(&tsk); - init_accounts_table(&db_data, &[extfvk.clone()], &[taddr]).unwrap(); + let ufvk = UnifiedFullViewingKey::new(AccountId(0), None, Some(extfvk.clone())).unwrap(); + init_accounts_table(&db_data, &[ufvk]).unwrap(); // Add funds to the wallet in a single note let value = Amount::from_u64(50000).unwrap(); @@ -600,10 +624,10 @@ mod tests { init_wallet_db(&db_data).unwrap(); // Add an account to the wallet - let (extsk, tsk) = derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); + let extsk = spending_key(&[0u8; 32], network.coin_type(), AccountId(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); - let taddr = derive_transparent_address_from_secret_key(&tsk); - init_accounts_table(&db_data, &[extfvk.clone()], &[taddr]).unwrap(); + let ufvk = UnifiedFullViewingKey::new(AccountId(0), None, Some(extfvk.clone())).unwrap(); + init_accounts_table(&db_data, &[ufvk]).unwrap(); // Add funds to the wallet in a single note let value = Amount::from_u64(50000).unwrap(); @@ -707,10 +731,10 @@ mod tests { init_wallet_db(&db_data).unwrap(); // Add an account to the wallet - let (extsk, tsk) = derive_test_keys_from_seed(&[0u8; 32], AccountId(0)); + let extsk = spending_key(&[0u8; 32], network().coin_type(), AccountId(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); - let taddr = derive_transparent_address_from_secret_key(&tsk); - init_accounts_table(&db_data, &[extfvk.clone()], &[taddr]).unwrap(); + let ufvk = UnifiedFullViewingKey::new(AccountId(0), None, Some(extfvk.clone())).unwrap(); + init_accounts_table(&db_data, &[ufvk]).unwrap(); // Add funds to the wallet in a single note let value = Amount::from_u64(51000).unwrap();