use std::borrow::Borrow;
use std::time::Duration;
use bitcoin::secp256k1::PublicKey;
use bitcoin::{Amount, FeeRate, Txid};
use ark::rounds::RoundId;
use ark::VtxoId;
use bitcoin_ext::BlockHeight;
use crate::exit::ExitState;
use crate::exit::error::ExitError;
use crate::exit::package::ExitTransactionPackage;
use crate::primitives::{UtxoInfo, VtxoInfo, RecipientInfo};
use crate::{serde_utils, WalletVtxoInfo};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ArkInfo {
pub network: bitcoin::Network,
pub server_pubkey: PublicKey,
#[serde(with = "serde_utils::duration")]
pub round_interval: Duration,
pub nb_round_nonces: usize,
pub vtxo_exit_delta: u16,
pub vtxo_expiry_delta: u16,
pub htlc_expiry_delta: u16,
pub max_vtxo_amount: Option<Amount>,
pub max_arkoor_depth: u16,
pub required_board_confirmations: usize,
}
impl<T: Borrow<ark::ArkInfo>> From<T> for ArkInfo {
fn from(v: T) -> Self {
let v = v.borrow();
ArkInfo {
network: v.network,
server_pubkey: v.server_pubkey,
round_interval: v.round_interval,
nb_round_nonces: v.nb_round_nonces,
vtxo_exit_delta: v.vtxo_exit_delta,
vtxo_expiry_delta: v.vtxo_expiry_delta,
htlc_expiry_delta: v.htlc_expiry_delta,
max_vtxo_amount: v.max_vtxo_amount,
max_arkoor_depth: v.max_arkoor_depth,
required_board_confirmations: v.required_board_confirmations,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Balance {
#[serde(rename = "spendable_sat", with = "bitcoin::amount::serde::as_sat")]
pub spendable: Amount,
#[serde(rename = "pending_lightning_send_sat", with = "bitcoin::amount::serde::as_sat")]
pub pending_lightning_send: Amount,
#[serde(rename = "pending_in_round_sat", with = "bitcoin::amount::serde::as_sat")]
pub pending_in_round: Amount,
#[serde(rename = "pending_exit_sat", with = "bitcoin::amount::serde::as_sat")]
pub pending_exit: Amount,
#[serde(rename = "pending_board_sat", with = "bitcoin::amount::serde::as_sat")]
pub pending_board: Amount,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Config {
pub ark: String,
pub bitcoind: Option<String>,
pub bitcoind_cookie: Option<String>,
pub bitcoind_user: Option<String>,
pub bitcoind_pass: Option<String>,
pub esplora: Option<String>,
pub vtxo_refresh_expiry_threshold: BlockHeight,
#[serde(rename = "fallback_fee_rate_kvb", with = "serde_utils::fee_rate_sats_per_kvb")]
pub fallback_fee_rate: Option<FeeRate>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct ExitProgressResponse {
pub exits: Vec<ExitProgressStatus>,
pub done: bool,
pub claimable_height: Option<u32>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct ExitProgressStatus {
pub vtxo_id: VtxoId,
pub state: ExitState,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option<ExitError>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct ExitTransactionStatus {
pub vtxo_id: VtxoId,
pub state: ExitState,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub history: Option<Vec<ExitState>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub transactions: Vec<ExitTransactionPackage>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Board {
pub funding_txid: Txid,
pub vtxos: Vtxos,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Movement {
pub id: u32,
pub fees: Amount,
pub spends: Vtxos,
pub receives: Vtxos,
pub recipients: Vec<RecipientInfo>,
pub created_at: String,
}
pub mod onchain {
use super::*;
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Send {
pub txid: Txid,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Address {
pub address: bitcoin::Address<bitcoin::address::NetworkUnchecked>,
}
pub type Utxos = Vec<UtxoInfo>;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Balance {
#[serde(rename="total_sat", with="bitcoin::amount::serde::as_sat")]
pub total: Amount,
#[serde(rename="trusted_spendable_sat", with="bitcoin::amount::serde::as_sat")]
pub trusted_spendable: Amount,
#[serde(rename="immature_sat", with="bitcoin::amount::serde::as_sat")]
pub immature: Amount,
#[serde(rename="trusted_pending_sat", with="bitcoin::amount::serde::as_sat")]
pub trusted_pending: Amount,
#[serde(rename="untrusted_pending_sat", with="bitcoin::amount::serde::as_sat")]
pub untrusted_pending: Amount,
#[serde(rename="confirmed_sat", with="bitcoin::amount::serde::as_sat")]
pub confirmed: Amount,
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Offboard {
pub round: RoundId,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Refresh {
pub participate_round: bool,
pub round: Option<RoundId>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SendOnchain {
pub round: RoundId,
}
pub type Vtxos = Vec<VtxoInfo>;
pub type WalletVtxos = Vec<WalletVtxoInfo>;
#[cfg(test)]
mod test {
use super::*;
#[test]
fn ark_info_fields() {
#[allow(unused)]
fn convert(j: ArkInfo) -> ark::ArkInfo {
ark::ArkInfo {
network: j.network,
server_pubkey: j.server_pubkey,
round_interval: j.round_interval,
nb_round_nonces: j.nb_round_nonces,
vtxo_exit_delta: j.vtxo_exit_delta,
vtxo_expiry_delta: j.vtxo_expiry_delta,
htlc_expiry_delta: j.htlc_expiry_delta,
max_vtxo_amount: j.max_vtxo_amount,
max_arkoor_depth: j.max_arkoor_depth,
required_board_confirmations: j.required_board_confirmations,
}
}
}
}