Skip to main content

bark/subsystem/
mod.rs

1//! Contains subsystem-related constants and types for Bark.
2//!
3//! In its current form this has little functionality; however, in the future
4//! it will contain interfaces allowing for developers to add their own
5//! subsystems which Bark can use.
6
7use std::collections::HashMap;
8use std::fmt;
9
10use bitcoin::consensus::encode::serialize_hex;
11use bitcoin::{Amount, OutPoint, Transaction};
12
13use ark::lightning::{PaymentHash, Preimage};
14use ark::vtxo::VtxoRef;
15
16/// A unique identifier for a subsystem.
17#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Deserialize, Serialize)]
18pub struct Subsystem(&'static str);
19
20impl Subsystem {
21	pub const fn new(id: &'static str) -> Self {
22		Subsystem(id)
23	}
24
25	pub fn as_name(&self) -> &'static str {
26		self.0
27	}
28
29	/// The built-in arkoor subsystem
30	pub const ARKOOR: Subsystem = Subsystem::new("bark.arkoor");
31
32	/// The built-in board subsystem
33	pub const BOARD: Subsystem = Subsystem::new("bark.board");
34
35	/// The built-in offboard subsystem
36	pub const OFFBOARD: Subsystem = Subsystem::new("bark.offboard");
37
38	/// The built-in exit subsystem
39	pub const EXIT: Subsystem = Subsystem::new("bark.exit");
40
41	/// The built-in Lightning receive subsystem
42	pub const LIGHTNING_RECEIVE: Subsystem = Subsystem::new("bark.lightning_receive");
43
44	/// The built-in Lightning send subsystem
45	pub const LIGHTNING_SEND: Subsystem = Subsystem::new("bark.lightning_send");
46
47	/// The built-in round subsystem
48	pub const ROUND: Subsystem = Subsystem::new("bark.round");
49}
50
51impl fmt::Display for Subsystem {
52	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53		f.write_str(self.0)
54	}
55}
56
57#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
58pub enum RoundMovement {
59	Refresh,
60}
61
62impl fmt::Display for RoundMovement {
63	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64		match self {
65			RoundMovement::Refresh => f.write_str("refresh"),
66		}
67	}
68}
69
70#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
71pub(crate) enum ArkoorMovement {
72	Receive,
73	Send,
74}
75
76impl fmt::Display for ArkoorMovement {
77	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78		match self {
79			ArkoorMovement::Receive => f.write_str("receive"),
80			ArkoorMovement::Send => f.write_str("send"),
81		}
82	}
83}
84
85#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
86pub(crate) enum BoardMovement {
87	Board,
88}
89
90impl BoardMovement {
91	pub fn metadata(
92		outpoint: OutPoint,
93		onchain_fee: Amount,
94	) -> impl IntoIterator<Item = (String, serde_json::Value)> {
95		[
96			(
97				"chain_anchor".into(),
98				serde_json::to_value(outpoint).expect("outpoint can serde"),
99			),
100			(
101				"onchain_fee_sat".into(),
102				serde_json::to_value(onchain_fee.to_sat()).expect("int can serde"),
103			),
104		]
105	}
106}
107
108impl fmt::Display for BoardMovement {
109	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110		match self {
111			BoardMovement::Board => f.write_str("board"),
112		}
113	}
114}
115
116#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
117pub(crate) enum OffboardMovement {
118	Offboard,
119	SendOnchain,
120}
121
122impl OffboardMovement {
123	pub fn metadata(
124		offboard_tx: &Transaction,
125	) -> impl IntoIterator<Item = (String, serde_json::Value)> {
126		[
127			(
128				"offboard_txid".into(),
129				serde_json::to_value(offboard_tx.compute_txid()).expect("txid can serde"),
130			),
131			(
132				"offboard_tx".into(),
133				serde_json::to_value(serialize_hex(&offboard_tx)).expect("string can serde"),
134			),
135		]
136	}
137}
138
139impl fmt::Display for OffboardMovement {
140	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
141		match self {
142			OffboardMovement::Offboard => f.write_str("offboard"),
143			OffboardMovement::SendOnchain => f.write_str("send_onchain"),
144		}
145	}
146}
147
148#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
149pub(crate) enum ExitMovement {
150	Exit,
151}
152
153impl fmt::Display for ExitMovement {
154	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
155		match self {
156			ExitMovement::Exit => f.write_str("start"),
157		}
158	}
159}
160
161/// Provides helper methods for lightning-related movements.
162pub(crate) struct LightningMovement {}
163
164impl LightningMovement {
165	pub fn metadata(
166		payment_hash: PaymentHash,
167		htlcs: impl IntoIterator<Item = impl VtxoRef>,
168		payment_preimage: Option<Preimage>,
169	) -> impl IntoIterator<Item = (String, serde_json::Value)> {
170		let htlcs = htlcs.into_iter().map(|v| v.vtxo_id()).collect::<Vec<_>>();
171		[
172			(
173				"payment_hash".into(),
174				serde_json::to_value(payment_hash).expect("payment hash can serde"),
175			),
176			(
177				"htlc_vtxos".into(),
178				serde_json::to_value(&htlcs).expect("vtxo ids can serde"),
179			),
180			(
181				"payment_preimage".into(),
182				serde_json::to_value(payment_preimage).expect("payment preimage can serde"),
183			),
184		]
185	}
186
187	/// Extract the payment hash from a movement's metadata
188	pub fn get_payment_hash(metadata: &HashMap<String, serde_json::Value>) -> Option<PaymentHash> {
189		metadata.get("payment_hash").and_then(|v| v.as_str()?.parse().ok())
190	}
191}
192
193#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
194pub(crate) enum LightningReceiveMovement {
195	Receive,
196}
197
198impl fmt::Display for LightningReceiveMovement {
199	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
200		match self {
201			LightningReceiveMovement::Receive => f.write_str("receive"),
202		}
203	}
204}
205
206#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
207pub(crate) enum LightningSendMovement {
208	Send,
209}
210
211impl fmt::Display for LightningSendMovement {
212	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
213		match self {
214			LightningSendMovement::Send => f.write_str("send"),
215		}
216	}
217}