bark_json/
primitives.rs

1
2use std::ops::Deref;
3use std::sync::Arc;
4
5use bitcoin::{Amount, OutPoint, Transaction, Txid};
6use bitcoin::secp256k1::PublicKey;
7#[cfg(feature = "utoipa")]
8use utoipa::ToSchema;
9
10use ark::{Vtxo, VtxoId};
11use ark::vtxo::VtxoPolicyKind;
12use bark::vtxo::state::VtxoState;
13use bitcoin_ext::{BlockDelta, BlockHeight};
14
15/// Struct representing information about an Unspent Transaction Output (UTXO).
16///
17/// This structure provides details about a UTXO, which includes the outpoint (transaction ID and
18/// index), the associated amount in satoshis, and the block height at which the transaction was
19/// confirmed (if available).
20///
21/// # Serde Behavior
22///
23/// * The `amount` field is serialized and deserialized with a custom function from the `bitcoin`
24///   crate that ensures the value is interpreted as satoshis with the name `amount_sat`.
25#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
26#[cfg_attr(feature = "utoipa", derive(ToSchema))]
27pub struct UtxoInfo {
28	/// Contains the reference to the specific transaction output via transaction ID and index.
29	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
30	pub outpoint: OutPoint,
31	/// The value of the UTXO in satoshis.
32	#[serde(rename = "amount_sat", with = "bitcoin::amount::serde::as_sat")]
33	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
34	pub amount: Amount,
35	/// An optional field that specifies the block height at which the transaction was confirmed. If
36	/// the transaction is unconfirmed, this value will be `None`.
37	pub confirmation_height: Option<u32>,
38}
39
40impl From<bark::UtxoInfo> for UtxoInfo {
41	fn from(v: bark::UtxoInfo) -> Self {
42		UtxoInfo {
43			outpoint: v.outpoint,
44			amount: v.amount,
45			confirmation_height: v.confirmation_height,
46		}
47	}
48}
49
50impl From<bark::onchain::Utxo> for UtxoInfo {
51
52	fn from(v: bark::onchain::Utxo) -> Self {
53		match v {
54			bark::onchain::Utxo::Local(o) => UtxoInfo {
55				outpoint: o.outpoint,
56				amount: o.amount,
57				confirmation_height: o.confirmation_height,
58			},
59			bark::onchain::Utxo::Exit(e) => UtxoInfo {
60				outpoint: e.vtxo.point(),
61				amount: e.vtxo.amount(),
62				confirmation_height: Some(e.height),
63			},
64		}
65	}
66}
67
68/// Struct representing information about a VTXO.
69#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
70#[cfg_attr(feature = "utoipa", derive(ToSchema))]
71pub struct VtxoInfo {
72	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
73	pub id: VtxoId,
74	#[serde(rename = "amount_sat", with = "bitcoin::amount::serde::as_sat")]
75	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
76	pub amount: Amount,
77	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
78	pub policy_type: VtxoPolicyKind,
79	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
80	pub user_pubkey: PublicKey,
81	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
82	pub server_pubkey: PublicKey,
83	pub expiry_height: BlockHeight,
84	pub exit_delta: BlockDelta,
85	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
86	pub chain_anchor: OutPoint,
87	pub exit_depth: u16,
88	pub arkoor_depth: u16,
89}
90
91impl<'a> From<&'a Vtxo> for VtxoInfo {
92	fn from(v: &'a Vtxo) -> VtxoInfo {
93		VtxoInfo {
94			id: v.id(),
95			amount: v.amount(),
96			policy_type: v.policy().policy_type(),
97			user_pubkey: v.user_pubkey(),
98			server_pubkey: v.server_pubkey(),
99			expiry_height: v.expiry_height(),
100			exit_delta: v.exit_delta(),
101			chain_anchor: v.chain_anchor(),
102			exit_depth: v.exit_depth(),
103			arkoor_depth: v.arkoor_depth(),
104		}
105	}
106}
107
108impl From<Vtxo> for VtxoInfo {
109	fn from(v: Vtxo) -> VtxoInfo {
110		VtxoInfo::from(&v)
111	}
112}
113
114/// Same as [VtxoInfo], but with the current VTXO state.
115#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
116#[cfg_attr(feature = "utoipa", derive(ToSchema))]
117pub struct WalletVtxoInfo {
118	#[serde(flatten)]
119	pub vtxo: VtxoInfo,
120	pub state: VtxoStateInfo,
121}
122
123impl From<bark::WalletVtxo> for WalletVtxoInfo {
124	fn from(v: bark::WalletVtxo) -> Self {
125		WalletVtxoInfo {
126			vtxo: v.vtxo.into(),
127			state: v.state.into(),
128		}
129	}
130}
131
132impl Deref for WalletVtxoInfo {
133	type Target = VtxoInfo;
134
135	fn deref(&self) -> &Self::Target {
136		&self.vtxo
137	}
138}
139
140/// Describe the state of a [Vtxo] with additional context.
141#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
142#[cfg_attr(feature = "utoipa", derive(ToSchema))]
143#[serde(tag = "type", rename_all = "kebab-case")]
144pub enum VtxoStateInfo {
145	Spendable,
146	Spent,
147	Locked {
148		#[serde(skip_serializing_if = "Option::is_none")]
149		movement_id: Option<String>,
150	},
151}
152
153impl From<VtxoState> for VtxoStateInfo {
154	fn from(state: VtxoState) -> Self {
155		match state {
156			VtxoState::Spendable => VtxoStateInfo::Spendable,
157			VtxoState::Spent => VtxoStateInfo::Spent,
158			VtxoState::Locked { movement_id } => VtxoStateInfo::Locked {
159				movement_id: movement_id.map(|id| id.to_string()),
160			},
161		}
162	}
163}
164
165/// An information struct used to pair the ID of a transaction with the full transaction for ease
166/// of use and readability for the user
167#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
168#[cfg_attr(feature = "utoipa", derive(ToSchema))]
169pub struct TransactionInfo {
170	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
171	pub txid: Txid,
172	#[serde(with = "bitcoin::consensus::serde::With::<bitcoin::consensus::serde::Hex>")]
173	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
174	pub tx: Transaction,
175}
176
177impl From<bark::exit::models::TransactionInfo> for TransactionInfo {
178	fn from(v: bark::exit::models::TransactionInfo) -> Self {
179		TransactionInfo { txid: v.txid, tx: v.tx }
180	}
181}
182
183impl From<Transaction> for TransactionInfo {
184	fn from(v: Transaction) -> Self {
185		TransactionInfo { txid: v.compute_txid(), tx: v }
186	}
187}
188
189impl From<Arc<Transaction>> for TransactionInfo {
190	fn from(v: Arc<Transaction>) -> Self {
191		TransactionInfo { txid: v.compute_txid(), tx: (*v).clone() }
192	}
193}