use std::{
collections::{HashMap, HashSet},
str::FromStr,
};
use iota_client::{
api_types::response::OutputWithMetadataResponse,
block::{
output::{dto::FoundryOutputDto, FoundryId, OutputId},
payload::transaction::{dto::TransactionPayloadDto, TransactionId},
},
};
use serde::{Deserialize, Serialize};
use crate::{
account::{
types::{address::AddressWrapper, AccountAddress, AddressWithUnspentOutputs, TransactionDto},
Account, OutputDataDto,
},
AddressWithAmount, AddressWithMicroAmount,
};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct AddressWithAmountDto {
pub address: String,
pub amount: String,
}
impl TryFrom<&AddressWithAmountDto> for AddressWithAmount {
type Error = crate::Error;
fn try_from(value: &AddressWithAmountDto) -> crate::Result<Self> {
Ok(Self {
address: value.address.clone(),
amount: u64::from_str(&value.amount)
.map_err(|_| iota_client::Error::InvalidAmount(value.amount.clone()))?,
})
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct AddressWithMicroAmountDto {
pub address: String,
pub amount: String,
#[serde(rename = "returnAddress")]
pub return_address: Option<String>,
pub expiration: Option<u32>,
}
impl TryFrom<&AddressWithMicroAmountDto> for AddressWithMicroAmount {
type Error = crate::Error;
fn try_from(value: &AddressWithMicroAmountDto) -> crate::Result<Self> {
Ok(Self {
address: value.address.clone(),
amount: u64::from_str(&value.amount)
.map_err(|_| iota_client::Error::InvalidAmount(value.amount.clone()))?,
return_address: value.return_address.clone(),
expiration: value.expiration,
})
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct AddressWithUnspentOutputsDto {
#[serde(with = "crate::account::types::address_serde")]
pub address: AddressWrapper,
#[serde(rename = "keyIndex")]
pub key_index: u32,
pub internal: bool,
#[serde(rename = "outputIds")]
pub output_ids: Vec<OutputId>,
}
impl From<&AddressWithUnspentOutputs> for AddressWithUnspentOutputsDto {
fn from(value: &AddressWithUnspentOutputs) -> Self {
Self {
address: value.address.clone(),
key_index: value.key_index,
internal: value.internal,
output_ids: value.output_ids.clone(),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountDto {
pub index: u32,
#[serde(rename = "coinType")]
pub coin_type: u32,
pub alias: String,
#[serde(rename = "publicAddresses")]
pub public_addresses: Vec<AccountAddress>,
#[serde(rename = "internalAddresses")]
pub internal_addresses: Vec<AccountAddress>,
#[serde(rename = "addressesWithUnspentOutputs")]
pub addresses_with_unspent_outputs: Vec<AddressWithUnspentOutputsDto>,
pub outputs: HashMap<OutputId, OutputDataDto>,
#[serde(rename = "lockedOutputs")]
pub locked_outputs: HashSet<OutputId>,
#[serde(rename = "unspentOutputs")]
pub unspent_outputs: HashMap<OutputId, OutputDataDto>,
pub transactions: HashMap<TransactionId, TransactionDto>,
#[serde(rename = "pendingTransactions")]
pub pending_transactions: HashSet<TransactionId>,
#[serde(rename = "incomingTransactions")]
pub incoming_transactions: HashMap<TransactionId, (TransactionPayloadDto, Vec<OutputWithMetadataResponse>)>,
#[serde(rename = "nativeTokenFoundries", default)]
pub native_token_foundries: HashMap<FoundryId, FoundryOutputDto>,
}
impl From<&Account> for AccountDto {
fn from(value: &Account) -> Self {
Self {
index: *value.index(),
coin_type: *value.coin_type(),
alias: value.alias().clone(),
public_addresses: value.public_addresses.clone(),
internal_addresses: value.internal_addresses.clone(),
addresses_with_unspent_outputs: value
.addresses_with_unspent_outputs()
.iter()
.map(AddressWithUnspentOutputsDto::from)
.collect(),
outputs: value
.outputs()
.iter()
.map(|(id, output)| (*id, OutputDataDto::from(output)))
.collect(),
locked_outputs: value.locked_outputs().clone(),
unspent_outputs: value
.unspent_outputs()
.iter()
.map(|(id, output)| (*id, OutputDataDto::from(output)))
.collect(),
transactions: value
.transactions()
.iter()
.map(|(id, transaction)| (*id, TransactionDto::from(transaction)))
.collect(),
pending_transactions: value.pending_transactions().clone(),
incoming_transactions: value
.incoming_transactions()
.iter()
.map(|(id, (transaction, inputs))| (*id, (TransactionPayloadDto::from(transaction), inputs.clone())))
.collect(),
native_token_foundries: value
.native_token_foundries()
.iter()
.map(|(id, foundry)| (*id, FoundryOutputDto::from(foundry)))
.collect(),
}
}
}