use zcash_primitives::transaction::TxId;
use zcash_protocol::{PoolType, ShieldedPool};
use zingo_status::confirmation_status::ConfirmationStatus;
use crate::lightclient::LightClient;
use crate::wallet::summary::data::TransactionKind;
pub async fn get_base_address(client: &LightClient, pooltype: PoolType) -> String {
match pooltype {
PoolType::Shielded(ShieldedPool::Ironwood) | PoolType::Shielded(ShieldedPool::Orchard) => {
assert!(
client.unified_addresses_json().await[0]["has_orchard"]
.as_bool()
.unwrap()
);
client.unified_addresses_json().await[0]["encoded_address"]
.clone()
.to_string()
}
PoolType::Shielded(ShieldedPool::Sapling) => {
assert!(
!client.unified_addresses_json().await[1]["has_orchard"]
.as_bool()
.unwrap()
);
assert!(
client.unified_addresses_json().await[1]["has_sapling"]
.as_bool()
.unwrap()
);
client.unified_addresses_json().await[1]["encoded_address"]
.clone()
.to_string()
}
PoolType::Transparent => client.transparent_addresses_json().await[0]["encoded_address"]
.clone()
.to_string(),
}
}
pub async fn get_fees_paid_by_client(client: &LightClient) -> u64 {
client
.transaction_summaries(false)
.await
.unwrap()
.iter()
.filter_map(|summary| {
if matches!(summary.kind, TransactionKind::Sent(_)) && summary.status.is_confirmed() {
summary.fee
} else {
None
}
})
.sum()
}
pub mod from_inputs {
use nonempty::NonEmpty;
use zcash_primitives::transaction::TxId;
use crate::{
data::{proposal::ProportionalFeeProposal, receivers::Receivers},
lightclient::{LightClient, error::LightClientError, send},
wallet::error::ProposeSendError,
};
pub async fn quick_send(
quick_sender: &mut crate::lightclient::LightClient,
raw_receivers: Vec<(&str, u64, Option<&str>)>,
) -> Result<NonEmpty<TxId>, LightClientError> {
let request = transaction_request_from_send_inputs(raw_receivers)
.expect("should be able to create a transaction request as receivers are valid.");
quick_sender
.quick_send(request, zip32::AccountId::ZERO, true)
.await
}
pub async fn quick_send_reported(
quick_sender: &mut crate::lightclient::LightClient,
raw_receivers: Vec<(&str, u64, Option<&str>)>,
) -> Result<NonEmpty<send::TransmitReport>, LightClientError> {
let request = transaction_request_from_send_inputs(raw_receivers)
.expect("should be able to create a transaction request as receivers are valid.");
quick_sender
.quick_send_reported(request, zip32::AccountId::ZERO, true)
.await
}
pub(crate) fn receivers_from_send_inputs(
raw_receivers: Vec<(&str, u64, Option<&str>)>,
) -> Receivers {
raw_receivers
.into_iter()
.map(|(address, amount, memo)| {
let recipient_address = crate::utils::conversion::address_from_str(address)
.expect("should be a valid address");
let amount = crate::utils::conversion::zatoshis_from_u64(amount)
.expect("should be inside the range of valid zatoshis");
let memo = memo.map(|memo| {
crate::wallet::utils::memo_bytes_from_string(memo.to_string())
.expect("should be able to interpret memo")
});
crate::data::receivers::Receiver::new(recipient_address, amount, memo)
})
.collect()
}
pub fn transaction_request_from_send_inputs(
raw_receivers: Vec<(&str, u64, Option<&str>)>,
) -> Result<
zcash_client_backend::zip321::TransactionRequest,
zcash_client_backend::zip321::Zip321Error,
> {
let receivers = receivers_from_send_inputs(raw_receivers);
crate::data::receivers::transaction_request_from_receivers(receivers)
}
pub async fn propose(
proposer: &mut LightClient,
raw_receivers: Vec<(&str, u64, Option<&str>)>,
) -> Result<ProportionalFeeProposal, ProposeSendError> {
let request = transaction_request_from_send_inputs(raw_receivers)
.expect("should be able to create a transaction request as receivers are valid.");
proposer.propose_send(request, zip32::AccountId::ZERO).await
}
}
pub async fn lookup_statuses(
client: &LightClient,
txids: nonempty::NonEmpty<TxId>,
) -> nonempty::NonEmpty<Option<ConfirmationStatus>> {
let wallet = client.wallet().read().await;
txids.map(|txid| {
wallet
.wallet_transactions
.get(&txid)
.map(pepper_sync::wallet::WalletTransaction::status)
})
}