pub mod finsight {
pub struct ValuesSentToAddress(pub std::collections::HashMap<String, Vec<u64>>);
pub struct TotalValueToAddress(pub std::collections::HashMap<String, u64>);
pub struct TotalSendsToAddress(pub std::collections::HashMap<String, u64>);
#[derive(Debug)]
pub struct TotalMemoBytesToAddress(pub std::collections::HashMap<String, usize>);
impl From<TotalMemoBytesToAddress> for json::JsonValue {
fn from(value: TotalMemoBytesToAddress) -> Self {
let mut jsonified = json::object!();
let hm = value.0;
for (key, val) in hm.iter() {
jsonified[key] = json::JsonValue::from(*val);
}
jsonified
}
}
impl From<TotalValueToAddress> for json::JsonValue {
fn from(value: TotalValueToAddress) -> Self {
let mut jsonified = json::object!();
let hm = value.0;
for (key, val) in hm.iter() {
jsonified[key] = json::JsonValue::from(*val);
}
jsonified
}
}
impl From<TotalSendsToAddress> for json::JsonValue {
fn from(value: TotalSendsToAddress) -> Self {
let mut jsonified = json::object!();
let hm = value.0;
for (key, val) in hm.iter() {
jsonified[key] = json::JsonValue::from(*val);
}
jsonified
}
}
}
pub mod summaries {
use chrono::DateTime;
use json::JsonValue;
use zcash_primitives::{consensus::BlockHeight, transaction::TxId};
use zingo_status::confirmation_status::ConfirmationStatus;
use crate::{
error::BuildError,
utils::build_method,
wallet::{
output::SpendStatus,
summary::{self, SendType, TransactionKind},
},
};
#[derive(Clone, PartialEq)]
pub struct ValueTransfer {
txid: TxId,
datetime: u32,
status: ConfirmationStatus,
blockheight: BlockHeight,
transaction_fee: Option<u64>,
zec_price: Option<f32>,
kind: ValueTransferKind,
value: u64,
recipient_address: Option<String>,
pool_received: Option<String>,
memos: Vec<String>,
}
impl ValueTransfer {
pub fn txid(&self) -> TxId {
self.txid
}
pub fn datetime(&self) -> u32 {
self.datetime
}
pub fn status(&self) -> ConfirmationStatus {
self.status
}
pub fn blockheight(&self) -> BlockHeight {
self.blockheight
}
pub fn transaction_fee(&self) -> Option<u64> {
self.transaction_fee
}
pub fn zec_price(&self) -> Option<f32> {
self.zec_price
}
pub fn kind(&self) -> ValueTransferKind {
self.kind
}
pub fn value(&self) -> u64 {
self.value
}
pub fn recipient_address(&self) -> Option<&str> {
self.recipient_address.as_deref()
}
pub fn pool_received(&self) -> Option<&str> {
self.pool_received.as_deref()
}
pub fn memos(&self) -> Vec<&str> {
self.memos.iter().map(|s| s.as_str()).collect()
}
}
impl std::fmt::Debug for ValueTransfer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ValueTransfer")
.field("txid", &self.txid)
.field("datetime", &self.datetime)
.field("status", &self.status)
.field("blockheight", &self.blockheight)
.field("transaction_fee", &self.transaction_fee)
.field("zec_price", &self.zec_price)
.field("kind", &self.kind)
.field("value", &self.value)
.field("recipient_address", &self.recipient_address)
.field("pool_received", &self.pool_received)
.field("memos", &self.memos)
.finish()
}
}
impl std::fmt::Display for ValueTransfer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let datetime = if let Some(dt) = DateTime::from_timestamp(self.datetime as i64, 0) {
format!("{}", dt)
} else {
"not available".to_string()
};
let transaction_fee = if let Some(f) = self.transaction_fee() {
f.to_string()
} else {
"not available".to_string()
};
let zec_price = if let Some(price) = self.zec_price() {
price.to_string()
} else {
"not available".to_string()
};
let recipient_address = if let Some(addr) = self.recipient_address() {
addr.to_string()
} else {
"not available".to_string()
};
let pool_received = if let Some(pool) = self.pool_received() {
pool.to_string()
} else {
"not available".to_string()
};
let mut memos = String::new();
for (index, memo) in self.memos().into_iter().enumerate() {
memos.push_str(&format!("\n\tmemo {}: {}", (index + 1), memo));
}
write!(
f,
"{{
txid: {}
datetime: {}
status: {}
blockheight: {}
transaction fee: {}
zec price: {}
kind: {}
value: {}
recipient_address: {}
pool_received: {}
memos: {}
}}",
self.txid,
datetime,
self.status,
u64::from(self.blockheight),
transaction_fee,
zec_price,
self.kind,
self.value,
recipient_address,
pool_received,
memos
)
}
}
impl From<ValueTransfer> for JsonValue {
fn from(value_transfer: ValueTransfer) -> Self {
json::object! {
"txid" => value_transfer.txid.to_string(),
"datetime" => value_transfer.datetime,
"status" => value_transfer.status.to_string(),
"blockheight" => u64::from(value_transfer.blockheight),
"transaction_fee" => value_transfer.transaction_fee,
"zec_price" => value_transfer.zec_price,
"kind" => value_transfer.kind.to_string(),
"value" => value_transfer.value,
"recipient_address" => value_transfer.recipient_address,
"pool_received" => value_transfer.pool_received,
"memos" => value_transfer.memos
}
}
}
#[derive(PartialEq, Debug)]
pub struct ValueTransfers(Vec<ValueTransfer>);
impl<'a> std::iter::IntoIterator for &'a ValueTransfers {
type Item = &'a ValueTransfer;
type IntoIter = std::slice::Iter<'a, ValueTransfer>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl std::ops::Deref for ValueTransfers {
type Target = Vec<ValueTransfer>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::ops::DerefMut for ValueTransfers {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl std::ops::Index<usize> for ValueTransfers {
type Output = ValueTransfer;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index] }
}
impl ValueTransfers {
pub fn new(value_transfers: Vec<ValueTransfer>) -> Self {
ValueTransfers(value_transfers)
}
}
impl std::fmt::Display for ValueTransfers {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for value_transfer in &self.0 {
write!(f, "\n{}", value_transfer)?;
}
Ok(())
}
}
impl From<ValueTransfers> for JsonValue {
fn from(value_transfers: ValueTransfers) -> Self {
let value_transfers: Vec<JsonValue> =
value_transfers.0.into_iter().map(JsonValue::from).collect();
json::object! {
"value_transfers" => value_transfers
}
}
}
pub struct ValueTransferBuilder {
txid: Option<TxId>,
datetime: Option<u32>,
status: Option<ConfirmationStatus>,
blockheight: Option<BlockHeight>,
transaction_fee: Option<Option<u64>>,
zec_price: Option<Option<f32>>,
kind: Option<ValueTransferKind>,
value: Option<u64>,
recipient_address: Option<Option<String>>,
pool_received: Option<Option<String>>,
memos: Option<Vec<String>>,
}
impl ValueTransferBuilder {
pub fn new() -> ValueTransferBuilder {
ValueTransferBuilder {
txid: None,
datetime: None,
status: None,
blockheight: None,
transaction_fee: None,
zec_price: None,
kind: None,
value: None,
recipient_address: None,
pool_received: None,
memos: None,
}
}
build_method!(txid, TxId);
build_method!(datetime, u32);
build_method!(status, ConfirmationStatus);
build_method!(blockheight, BlockHeight);
build_method!(transaction_fee, Option<u64>);
build_method!(zec_price, Option<f32>);
build_method!(kind, ValueTransferKind);
build_method!(value, u64);
build_method!(recipient_address, Option<String>);
build_method!(pool_received, Option<String>);
build_method!(memos, Vec<String>);
pub fn build(&self) -> Result<ValueTransfer, BuildError> {
Ok(ValueTransfer {
txid: self
.txid
.ok_or(BuildError::MissingField("txid".to_string()))?,
datetime: self
.datetime
.ok_or(BuildError::MissingField("datetime".to_string()))?,
status: self
.status
.ok_or(BuildError::MissingField("status".to_string()))?,
blockheight: self
.blockheight
.ok_or(BuildError::MissingField("blockheight".to_string()))?,
transaction_fee: self
.transaction_fee
.ok_or(BuildError::MissingField("transaction_fee".to_string()))?,
zec_price: self
.zec_price
.ok_or(BuildError::MissingField("zec_price".to_string()))?,
kind: self
.kind
.ok_or(BuildError::MissingField("kind".to_string()))?,
value: self
.value
.ok_or(BuildError::MissingField("value".to_string()))?,
recipient_address: self
.recipient_address
.clone()
.ok_or(BuildError::MissingField("recipient_address".to_string()))?,
pool_received: self
.pool_received
.clone()
.ok_or(BuildError::MissingField("pool_received".to_string()))?,
memos: self
.memos
.clone()
.ok_or(BuildError::MissingField("memos".to_string()))?,
})
}
}
impl Default for ValueTransferBuilder {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum ValueTransferKind {
Sent(SentValueTransfer),
Received,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum SentValueTransfer {
Send,
SendToSelf(SelfSendValueTransfer),
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum SelfSendValueTransfer {
Basic,
Shield,
MemoToSelf,
Rejection,
}
impl std::fmt::Display for ValueTransferKind {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ValueTransferKind::Received => write!(f, "received"),
ValueTransferKind::Sent(sent) => match sent {
SentValueTransfer::Send => write!(f, "sent"),
SentValueTransfer::SendToSelf(selfsend) => match selfsend {
SelfSendValueTransfer::Basic => write!(f, "send-to-self"),
SelfSendValueTransfer::Shield => write!(f, "shield"),
SelfSendValueTransfer::MemoToSelf => write!(f, "memo-to-self"),
SelfSendValueTransfer::Rejection => write!(f, "rejection"),
},
},
}
}
}
pub trait TransactionSummaryInterface {
fn txid(&self) -> TxId;
fn datetime(&self) -> u32;
fn status(&self) -> ConfirmationStatus;
fn blockheight(&self) -> BlockHeight;
fn kind(&self) -> TransactionKind;
fn value(&self) -> u64;
fn fee(&self) -> Option<u64>;
fn zec_price(&self) -> Option<f32>;
fn orchard_notes(&self) -> &[BasicNoteSummary];
fn sapling_notes(&self) -> &[BasicNoteSummary];
fn transparent_coins(&self) -> &[BasicCoinSummary];
fn outgoing_orchard_notes(&self) -> &[OutgoingNoteSummary];
fn outgoing_sapling_notes(&self) -> &[OutgoingNoteSummary];
fn outgoing_transparent_coins(&self) -> &[OutgoingCoinSummary];
fn balance_delta(&self) -> Option<i64> {
match self.kind() {
TransactionKind::Sent(SendType::Send) => {
self.fee().map(|fee| -((self.value() + fee) as i64))
}
TransactionKind::Sent(SendType::Shield)
| TransactionKind::Sent(SendType::SendToSelf) => {
self.fee().map(|fee| -(fee as i64))
}
TransactionKind::Received => Some(self.value() as i64),
}
}
fn prepare_for_display(
&self,
) -> (
String,
String,
String,
BasicNoteSummaries,
BasicNoteSummaries,
BasicCoinSummaries,
OutgoingNoteSummaries,
OutgoingNoteSummaries,
OutgoingCoinSummaries,
) {
let datetime = if let Some(dt) = DateTime::from_timestamp(self.datetime() as i64, 0) {
format!("{}", dt)
} else {
"not available".to_string()
};
let fee = if let Some(f) = self.fee() {
f.to_string()
} else {
"not available".to_string()
};
let zec_price = if let Some(price) = self.zec_price() {
price.to_string()
} else {
"not available".to_string()
};
let orchard_notes = BasicNoteSummaries(self.orchard_notes().to_vec());
let sapling_notes = BasicNoteSummaries(self.sapling_notes().to_vec());
let transparent_coins = BasicCoinSummaries(self.transparent_coins().to_vec());
let outgoing_orchard_notes =
OutgoingNoteSummaries(self.outgoing_orchard_notes().to_vec());
let outgoing_sapling_notes =
OutgoingNoteSummaries(self.outgoing_sapling_notes().to_vec());
let outgoing_transparent_coins =
OutgoingCoinSummaries(self.outgoing_transparent_coins().to_vec());
(
datetime,
fee,
zec_price,
orchard_notes,
sapling_notes,
transparent_coins,
outgoing_orchard_notes,
outgoing_sapling_notes,
outgoing_transparent_coins,
)
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct TransactionSummary {
txid: TxId,
datetime: u32,
status: ConfirmationStatus,
blockheight: BlockHeight,
kind: TransactionKind,
value: u64,
fee: Option<u64>,
zec_price: Option<f32>,
orchard_notes: Vec<BasicNoteSummary>,
sapling_notes: Vec<BasicNoteSummary>,
transparent_coins: Vec<BasicCoinSummary>,
outgoing_orchard_notes: Vec<OutgoingNoteSummary>,
outgoing_sapling_notes: Vec<OutgoingNoteSummary>,
outgoing_transparent_coins: Vec<OutgoingCoinSummary>,
}
impl TransactionSummaryInterface for TransactionSummary {
fn txid(&self) -> TxId {
self.txid
}
fn datetime(&self) -> u32 {
self.datetime
}
fn status(&self) -> ConfirmationStatus {
self.status
}
fn blockheight(&self) -> BlockHeight {
self.blockheight
}
fn kind(&self) -> TransactionKind {
self.kind
}
fn value(&self) -> u64 {
self.value
}
fn fee(&self) -> Option<u64> {
self.fee
}
fn zec_price(&self) -> Option<f32> {
self.zec_price
}
fn orchard_notes(&self) -> &[BasicNoteSummary] {
&self.orchard_notes
}
fn sapling_notes(&self) -> &[BasicNoteSummary] {
&self.sapling_notes
}
fn transparent_coins(&self) -> &[BasicCoinSummary] {
&self.transparent_coins
}
fn outgoing_orchard_notes(&self) -> &[OutgoingNoteSummary] {
&self.outgoing_orchard_notes
}
fn outgoing_sapling_notes(&self) -> &[OutgoingNoteSummary] {
&self.outgoing_sapling_notes
}
fn outgoing_transparent_coins(&self) -> &[OutgoingCoinSummary] {
&self.outgoing_transparent_coins
}
}
impl std::fmt::Display for TransactionSummary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let (
datetime,
fee,
zec_price,
orchard_notes,
sapling_notes,
transparent_coins,
outgoing_orchard_notes,
outgoing_sapling_notes,
outgoing_transparent_coins,
) = self.prepare_for_display();
write!(
f,
"{{
txid: {}
datetime: {}
status: {}
blockheight: {}
kind: {}
value: {}
fee: {}
zec price: {}
orchard notes: {}
sapling notes: {}
transparent coins: {}
outgoing orchard notes: {}
outgoing sapling notes: {}
outgoing transparent coins: {}
}}",
self.txid,
datetime,
self.status,
u64::from(self.blockheight),
self.kind,
self.value,
fee,
zec_price,
orchard_notes,
sapling_notes,
transparent_coins,
outgoing_orchard_notes,
outgoing_sapling_notes,
outgoing_transparent_coins,
)
}
}
impl From<TransactionSummary> for JsonValue {
fn from(transaction: TransactionSummary) -> Self {
json::object! {
"txid" => transaction.txid.to_string(),
"datetime" => transaction.datetime,
"status" => transaction.status.to_string(),
"blockheight" => u64::from(transaction.blockheight),
"kind" => transaction.kind.to_string(),
"value" => transaction.value,
"fee" => transaction.fee,
"zec_price" => transaction.zec_price,
"orchard_notes" => JsonValue::from(transaction.orchard_notes),
"sapling_notes" => JsonValue::from(transaction.sapling_notes),
"transparent_coins" => JsonValue::from(transaction.transparent_coins),
"outgoing_orchard_notes" => JsonValue::from(transaction.outgoing_orchard_notes),
"outgoing_sapling_notes" => JsonValue::from(transaction.outgoing_sapling_notes),
"outgoing_transparent_coins" => JsonValue::from(transaction.outgoing_transparent_coins),
}
}
}
#[derive(PartialEq, Debug)]
pub struct TransactionSummaries(pub Vec<TransactionSummary>);
impl TransactionSummaries {
pub fn new(transaction_summaries: Vec<TransactionSummary>) -> Self {
TransactionSummaries(transaction_summaries)
}
pub fn iter(&self) -> std::slice::Iter<TransactionSummary> {
self.0.iter()
}
pub fn paid_fees(&self) -> u64 {
self.iter()
.filter_map(|summary| {
if matches!(summary.kind, TransactionKind::Sent(_))
&& summary.status.is_confirmed()
{
summary.fee()
} else {
None
}
})
.sum()
}
pub fn txids(&self) -> Vec<TxId> {
self.iter().map(|summary| summary.txid()).collect()
}
}
impl std::fmt::Display for TransactionSummaries {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for transaction_summary in &self.0 {
write!(f, "\n{}", transaction_summary)?;
}
Ok(())
}
}
impl From<TransactionSummaries> for JsonValue {
fn from(transaction_summaries: TransactionSummaries) -> Self {
let transaction_summaries: Vec<JsonValue> = transaction_summaries
.0
.into_iter()
.map(JsonValue::from)
.collect();
json::object! {
"transaction_summaries" => transaction_summaries
}
}
}
pub struct TransactionSummaryBuilder {
txid: Option<TxId>,
datetime: Option<u32>,
status: Option<ConfirmationStatus>,
blockheight: Option<BlockHeight>,
kind: Option<TransactionKind>,
value: Option<u64>,
fee: Option<Option<u64>>,
zec_price: Option<Option<f32>>,
orchard_notes: Option<Vec<BasicNoteSummary>>,
sapling_notes: Option<Vec<BasicNoteSummary>>,
transparent_coins: Option<Vec<BasicCoinSummary>>,
outgoing_orchard_notes: Option<Vec<OutgoingNoteSummary>>,
outgoing_sapling_notes: Option<Vec<OutgoingNoteSummary>>,
outgoing_transparent_coins: Option<Vec<OutgoingCoinSummary>>,
}
impl TransactionSummaryBuilder {
pub fn new() -> TransactionSummaryBuilder {
TransactionSummaryBuilder {
txid: None,
datetime: None,
status: None,
blockheight: None,
kind: None,
value: None,
fee: None,
zec_price: None,
orchard_notes: None,
sapling_notes: None,
transparent_coins: None,
outgoing_orchard_notes: None,
outgoing_sapling_notes: None,
outgoing_transparent_coins: None,
}
}
build_method!(txid, TxId);
build_method!(datetime, u32);
build_method!(status, ConfirmationStatus);
build_method!(blockheight, BlockHeight);
build_method!(kind, TransactionKind);
build_method!(value, u64);
build_method!(fee, Option<u64>);
build_method!(zec_price, Option<f32>);
build_method!(orchard_notes, Vec<BasicNoteSummary>);
build_method!(sapling_notes, Vec<BasicNoteSummary>);
build_method!(transparent_coins, Vec<BasicCoinSummary>);
build_method!(outgoing_orchard_notes, Vec<OutgoingNoteSummary>);
build_method!(outgoing_sapling_notes, Vec<OutgoingNoteSummary>);
build_method!(outgoing_transparent_coins, Vec<OutgoingCoinSummary>);
pub fn build(&self) -> Result<TransactionSummary, BuildError> {
Ok(TransactionSummary {
txid: self
.txid
.ok_or(BuildError::MissingField("txid".to_string()))?,
datetime: self
.datetime
.ok_or(BuildError::MissingField("datetime".to_string()))?,
status: self
.status
.ok_or(BuildError::MissingField("status".to_string()))?,
blockheight: self
.blockheight
.ok_or(BuildError::MissingField("blockheight".to_string()))?,
kind: self
.kind
.ok_or(BuildError::MissingField("kind".to_string()))?,
value: self
.value
.ok_or(BuildError::MissingField("value".to_string()))?,
fee: self
.fee
.ok_or(BuildError::MissingField("fee".to_string()))?,
zec_price: self
.zec_price
.ok_or(BuildError::MissingField("zec_price".to_string()))?,
orchard_notes: self
.orchard_notes
.clone()
.ok_or(BuildError::MissingField("orchard_notes".to_string()))?,
sapling_notes: self
.sapling_notes
.clone()
.ok_or(BuildError::MissingField("sapling_notes".to_string()))?,
transparent_coins: self
.transparent_coins
.clone()
.ok_or(BuildError::MissingField("transparent_coins".to_string()))?,
outgoing_orchard_notes: self.outgoing_orchard_notes.clone().ok_or(
BuildError::MissingField("outgoing_orchard_notes".to_string()),
)?,
outgoing_sapling_notes: self.outgoing_sapling_notes.clone().ok_or(
BuildError::MissingField("outgoing_sapling_notes".to_string()),
)?,
outgoing_transparent_coins: self.outgoing_transparent_coins.clone().ok_or(
BuildError::MissingField("outgoing_transparent_coins".to_string()),
)?,
})
}
}
impl Default for TransactionSummaryBuilder {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct BasicNoteSummary {
value: u64,
spend_status: SpendStatus,
output_index: u32,
memo: Option<String>,
}
impl BasicNoteSummary {
pub fn from_parts(
value: u64,
spend_status: SpendStatus,
output_index: u32,
memo: Option<String>,
) -> Self {
BasicNoteSummary {
value,
spend_status,
output_index,
memo,
}
}
pub fn value(&self) -> u64 {
self.value
}
pub fn spend_status(&self) -> SpendStatus {
self.spend_status
}
pub fn output_index(&self) -> u32 {
self.output_index
}
pub fn memo(&self) -> Option<&str> {
self.memo.as_deref()
}
}
impl std::fmt::Display for BasicNoteSummary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let memo = if let Some(m) = self.memo.clone() {
m
} else {
"".to_string()
};
write!(
f,
"\t{{
value: {}
spend status: {}
output index: {}
memo: {}
}}",
self.value, self.spend_status, self.output_index, memo,
)
}
}
impl From<BasicNoteSummary> for JsonValue {
fn from(note: BasicNoteSummary) -> Self {
json::object! {
"value" => note.value,
"spend_status" => note.spend_status.to_string(),
"output_index" => note.output_index,
"memo" => note.memo,
}
}
}
pub struct BasicNoteSummaries(Vec<BasicNoteSummary>);
impl std::fmt::Display for BasicNoteSummaries {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for note in &self.0 {
write!(f, "\n{}", note)?;
}
Ok(())
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct BasicCoinSummary {
value: u64,
spend_summary: SpendStatus,
output_index: u32,
}
impl BasicCoinSummary {
pub fn from_parts(value: u64, spend_status: SpendStatus, output_index: u32) -> Self {
BasicCoinSummary {
value,
spend_summary: spend_status,
output_index,
}
}
pub fn value(&self) -> u64 {
self.value
}
pub fn spend_summary(&self) -> SpendStatus {
self.spend_summary
}
pub fn output_index(&self) -> u32 {
self.output_index
}
}
impl std::fmt::Display for BasicCoinSummary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"\t{{
value: {}
spend status: {}
output index: {}
}}",
self.value, self.spend_summary, self.output_index,
)
}
}
impl From<BasicCoinSummary> for JsonValue {
fn from(note: BasicCoinSummary) -> Self {
json::object! {
"value" => note.value,
"spend_status" => note.spend_summary.to_string(),
"output_index" => note.output_index,
}
}
}
pub struct BasicCoinSummaries(Vec<BasicCoinSummary>);
impl std::fmt::Display for BasicCoinSummaries {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for coin in &self.0 {
write!(f, "\n{}", coin)?;
}
Ok(())
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct OutgoingNoteSummary {
pub value: u64,
pub memo: Option<String>,
pub recipient: String,
pub recipient_unified_address: Option<String>,
pub output_index: u16,
pub account_id: zip32::AccountId,
pub scope: summary::Scope,
}
impl std::fmt::Display for OutgoingNoteSummary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let memo = self.memo.clone().unwrap_or_default();
let recipient_unified_address = self
.recipient_unified_address
.clone()
.unwrap_or_else(|| "not available".to_string());
write!(
f,
"\t{{
value: {}
memo: {}
recipient: {}
recipient unified address: {}
output index: {}
account id: {}
scope: {}
}}",
self.value,
memo,
self.recipient,
recipient_unified_address,
self.output_index,
u32::from(self.account_id),
self.scope,
)
}
}
impl From<OutgoingNoteSummary> for JsonValue {
fn from(note: OutgoingNoteSummary) -> Self {
json::object! {
"value" => note.value,
"memo" => note.memo,
"recipient" => note.recipient,
"recipient_unified_address" => note.recipient_unified_address,
"output_index" => note.output_index,
"account_id" => u32::from(note.account_id),
"scope" => note.scope.to_string(),
}
}
}
pub struct OutgoingNoteSummaries(Vec<OutgoingNoteSummary>);
impl std::fmt::Display for OutgoingNoteSummaries {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for note in &self.0 {
write!(f, "\n{}", note)?;
}
Ok(())
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct OutgoingCoinSummary {
pub value: u64,
pub recipient: String,
pub output_index: u16,
}
impl std::fmt::Display for OutgoingCoinSummary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"\t{{
value: {}
recipient: {}
output index: {}
}}",
self.value, self.recipient, self.output_index,
)
}
}
impl From<OutgoingCoinSummary> for JsonValue {
fn from(note: OutgoingCoinSummary) -> Self {
json::object! {
"value" => note.value,
"recipient" => note.recipient,
"output_index" => note.output_index,
}
}
}
pub struct OutgoingCoinSummaries(Vec<OutgoingCoinSummary>);
impl std::fmt::Display for OutgoingCoinSummaries {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for coin in &self.0 {
write!(f, "\n{}", coin)?;
}
Ok(())
}
}
}