Skip to main content

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::movement::MovementId;
13use bark::vtxo::VtxoState;
14use bitcoin_ext::{BlockDelta, BlockHeight};
15
16/// Struct representing information about an Unspent Transaction Output (UTXO).
17///
18/// This structure provides details about a UTXO, which includes the outpoint (transaction ID and
19/// index), the associated amount in satoshis, and the block height at which the transaction was
20/// confirmed (if available).
21///
22/// # Serde Behavior
23///
24/// * The `amount` field is serialized and deserialized with a custom function from the `bitcoin`
25///   crate that ensures the value is interpreted as satoshis with the name `amount_sat`.
26#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
27#[cfg_attr(feature = "utoipa", derive(ToSchema))]
28pub struct UtxoInfo {
29	/// Contains the reference to the specific transaction output via transaction ID and index.
30	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
31	pub outpoint: OutPoint,
32	/// The value of the UTXO in satoshis.
33	#[serde(rename = "amount_sat", with = "bitcoin::amount::serde::as_sat")]
34	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
35	pub amount: Amount,
36	/// An optional field that specifies the block height at which the transaction was confirmed. If
37	/// the transaction is unconfirmed, this value will be `None`.
38	pub confirmation_height: Option<u32>,
39}
40
41impl From<bark::UtxoInfo> for UtxoInfo {
42	fn from(v: bark::UtxoInfo) -> Self {
43		UtxoInfo {
44			outpoint: v.outpoint,
45			amount: v.amount,
46			confirmation_height: v.confirmation_height,
47		}
48	}
49}
50
51impl From<bark::onchain::Utxo> for UtxoInfo {
52
53	fn from(v: bark::onchain::Utxo) -> Self {
54		match v {
55			bark::onchain::Utxo::Local(o) => UtxoInfo {
56				outpoint: o.outpoint,
57				amount: o.amount,
58				confirmation_height: o.confirmation_height,
59			},
60			bark::onchain::Utxo::Exit(e) => UtxoInfo {
61				outpoint: e.vtxo.point(),
62				amount: e.vtxo.amount(),
63				confirmation_height: Some(e.height),
64			},
65		}
66	}
67}
68
69/// Struct representing information about a VTXO.
70#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
71#[cfg_attr(feature = "utoipa", derive(ToSchema))]
72pub struct VtxoInfo {
73	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
74	pub id: VtxoId,
75	#[serde(rename = "amount_sat", with = "bitcoin::amount::serde::as_sat")]
76	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
77	pub amount: Amount,
78	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
79	pub policy_type: VtxoPolicyKind,
80	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
81	pub user_pubkey: PublicKey,
82	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
83	pub server_pubkey: PublicKey,
84	pub expiry_height: BlockHeight,
85	pub exit_delta: BlockDelta,
86	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
87	pub chain_anchor: OutPoint,
88	pub exit_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		}
104	}
105}
106
107impl From<Vtxo> for VtxoInfo {
108	fn from(v: Vtxo) -> VtxoInfo {
109		VtxoInfo::from(&v)
110	}
111}
112
113/// Same as [VtxoInfo], but with the current VTXO state.
114#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
115#[cfg_attr(feature = "utoipa", derive(ToSchema))]
116pub struct WalletVtxoInfo {
117	#[serde(flatten)]
118	pub vtxo: VtxoInfo,
119	pub state: VtxoStateInfo,
120}
121
122impl From<bark::WalletVtxo> for WalletVtxoInfo {
123	fn from(v: bark::WalletVtxo) -> Self {
124		WalletVtxoInfo {
125			vtxo: v.vtxo.into(),
126			state: v.state.into(),
127		}
128	}
129}
130
131impl Deref for WalletVtxoInfo {
132	type Target = VtxoInfo;
133
134	fn deref(&self) -> &Self::Target {
135		&self.vtxo
136	}
137}
138
139/// Describe the state of a [Vtxo] with additional context.
140#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
141#[cfg_attr(feature = "utoipa", derive(ToSchema))]
142#[serde(tag = "type", rename_all = "kebab-case")]
143pub enum VtxoStateInfo {
144	Spendable,
145	Spent,
146	Locked {
147		#[serde(skip_serializing_if = "Option::is_none")]
148		#[cfg_attr(feature = "utoipa", schema(value_type = u32))]
149		movement_id: Option<MovementId>,
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,
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::TransactionInfo> for TransactionInfo {
178	fn from(v: bark::exit::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}