use serde::{Deserialize, Serialize};
use thiserror::Error;
#[cfg(feature = "wallet")]
use super::nut00::PreMintSecrets;
use super::nut00::{BlindSignature, BlindedMessage, Proofs};
use super::ProofsMethods;
use crate::Amount;
#[derive(Debug, Error)]
pub enum Error {
#[error(transparent)]
DHKE(#[from] crate::dhke::Error),
#[error(transparent)]
Amount(#[from] crate::amount::Error),
}
#[cfg(feature = "wallet")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct PreSwap {
pub pre_mint_secrets: PreMintSecrets,
pub swap_request: SwapRequest,
pub derived_secret_count: u32,
pub fee: Amount,
pub p2bk_secret_keys: Option<Vec<crate::nuts::nut01::SecretKey>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
pub struct SwapRequest {
#[cfg_attr(feature = "swagger", schema(value_type = Vec<crate::Proof>))]
inputs: Proofs,
outputs: Vec<BlindedMessage>,
}
impl SwapRequest {
pub fn new(inputs: Proofs, outputs: Vec<BlindedMessage>) -> Self {
Self {
inputs: inputs.without_dleqs(),
outputs,
}
}
pub fn inputs(&self) -> &Proofs {
&self.inputs
}
pub fn inputs_mut(&mut self) -> &mut Proofs {
&mut self.inputs
}
pub fn outputs(&self) -> &Vec<BlindedMessage> {
&self.outputs
}
pub fn outputs_mut(&mut self) -> &mut Vec<BlindedMessage> {
&mut self.outputs
}
pub fn input_amount(&self) -> Result<Amount, Error> {
Ok(Amount::try_sum(
self.inputs.iter().map(|proof| proof.amount),
)?)
}
pub fn output_amount(&self) -> Result<Amount, Error> {
Ok(Amount::try_sum(
self.outputs.iter().map(|proof| proof.amount),
)?)
}
}
impl super::nut10::SpendingConditionVerification for SwapRequest {
fn inputs(&self) -> &Proofs {
&self.inputs
}
fn sig_all_msg_to_sign(&self) -> String {
let mut msg = String::new();
for proof in &self.inputs {
msg.push_str(&proof.secret.to_string());
msg.push_str(&proof.c.to_hex());
}
for output in &self.outputs {
msg.push_str(&output.amount.to_string());
msg.push_str(&output.blinded_secret.to_hex());
}
msg
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
pub struct SwapResponse {
pub signatures: Vec<BlindSignature>,
}
impl SwapResponse {
pub fn new(promises: Vec<BlindSignature>) -> Self {
Self {
signatures: promises,
}
}
pub fn promises_amount(&self) -> Result<Amount, Error> {
Ok(Amount::try_sum(
self.signatures
.iter()
.map(|BlindSignature { amount, .. }| *amount),
)?)
}
}