use crypto::keys::bip44::Bip44;
use serde::{Deserialize, Serialize};
use crate::{
client::secret::types::{InputSigningData, InputSigningDataDto},
types::{
block::{
address::{dto::AddressDto, Address},
output::{dto::OutputDto, Output},
payload::{
transaction::{
dto::{TransactionEssenceDto, TransactionPayloadDto},
TransactionEssence,
},
TransactionPayload,
},
Error,
},
TryFromDto, ValidationParams,
},
utils::serde::bip44::option_bip44,
};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PreparedTransactionData {
pub essence: TransactionEssence,
pub inputs_data: Vec<InputSigningData>,
pub remainder: Option<RemainderData>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PreparedTransactionDataDto {
pub essence: TransactionEssenceDto,
pub inputs_data: Vec<InputSigningDataDto>,
pub remainder: Option<RemainderDataDto>,
}
impl From<&PreparedTransactionData> for PreparedTransactionDataDto {
fn from(value: &PreparedTransactionData) -> Self {
Self {
essence: TransactionEssenceDto::from(&value.essence),
inputs_data: value.inputs_data.iter().map(InputSigningDataDto::from).collect(),
remainder: value.remainder.as_ref().map(RemainderDataDto::from),
}
}
}
impl TryFromDto for PreparedTransactionData {
type Dto = PreparedTransactionDataDto;
type Error = Error;
fn try_from_dto_with_params_inner(dto: Self::Dto, params: ValidationParams<'_>) -> Result<Self, Self::Error> {
Ok(Self {
essence: TransactionEssence::try_from_dto_with_params(dto.essence, ¶ms)
.map_err(|_| Error::InvalidField("essence"))?,
inputs_data: dto
.inputs_data
.into_iter()
.map(|i| InputSigningData::try_from_dto_with_params(i, ¶ms))
.collect::<crate::client::Result<Vec<InputSigningData>>>()
.map_err(|_| Error::InvalidField("input_data"))?,
remainder: match dto.remainder {
Some(remainder) => Some(
RemainderData::try_from_dto_with_params(remainder, ¶ms)
.map_err(|_| Error::InvalidField("remainder"))?,
),
None => None,
},
})
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SignedTransactionData {
pub transaction_payload: TransactionPayload,
pub inputs_data: Vec<InputSigningData>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignedTransactionDataDto {
pub transaction_payload: TransactionPayloadDto,
pub inputs_data: Vec<InputSigningDataDto>,
}
impl From<&SignedTransactionData> for SignedTransactionDataDto {
fn from(value: &SignedTransactionData) -> Self {
Self {
transaction_payload: TransactionPayloadDto::from(&value.transaction_payload),
inputs_data: value.inputs_data.iter().map(InputSigningDataDto::from).collect(),
}
}
}
impl TryFromDto for SignedTransactionData {
type Dto = SignedTransactionDataDto;
type Error = Error;
fn try_from_dto_with_params_inner(dto: Self::Dto, params: ValidationParams<'_>) -> Result<Self, Self::Error> {
Ok(Self {
transaction_payload: TransactionPayload::try_from_dto_with_params(dto.transaction_payload, ¶ms)
.map_err(|_| Error::InvalidField("transaction_payload"))?,
inputs_data: dto
.inputs_data
.into_iter()
.map(|i| InputSigningData::try_from_dto_with_params(i, ¶ms))
.collect::<crate::client::Result<Vec<InputSigningData>>>()
.map_err(|_| Error::InvalidField("inputs_data"))?,
})
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RemainderData {
pub output: Output,
pub chain: Option<Bip44>,
pub address: Address,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct RemainderDataDto {
pub output: OutputDto,
#[serde(with = "option_bip44", default)]
pub chain: Option<Bip44>,
pub address: AddressDto,
}
impl TryFromDto for RemainderData {
type Dto = RemainderDataDto;
type Error = Error;
fn try_from_dto_with_params_inner(dto: Self::Dto, params: ValidationParams<'_>) -> Result<Self, Self::Error> {
Ok(Self {
output: Output::try_from_dto_with_params_inner(dto.output, params)?,
chain: dto.chain,
address: Address::try_from(dto.address)?,
})
}
}
impl From<&RemainderData> for RemainderDataDto {
fn from(remainder: &RemainderData) -> Self {
Self {
output: OutputDto::from(&remainder.output),
chain: remainder.chain,
address: AddressDto::from(&remainder.address),
}
}
}