Skip to main content

server_rpc/
lib.rs

1//!
2//!
3//! # Note on protocol version
4//!
5//! Whenever anything changes related to the interactions between client and
6//! server, including protocol encoding versions, gRPC data fields, expected
7//! behavior etc, that is not automatically backwards compatible, the protocol
8//! version is bumped.
9//!
10//! Both the server and the client can be implemented so as to support multiple
11//! different protocol versions. This gives maximum flexibility to implement
12//! compatibility for both sides.
13//!
14//! The server advertises the protocol versions it supports and the client picks
15//! one and sets it in the header of each subsequent request.
16//!
17//! However, the server will only check the protocol version in cases where
18//! behavior can be different for different versions. This gives outdated or
19//! exotic clients an extra level of flexibility, as calls that have not
20//! changed since the latest supported protocol version might still work.
21//!
22//! This makes the server maximally flexible and puts all the responsibility
23//! on the client. Our own client implementation bails out if it cannot speak
24//! any of the supported protocol versions the server supports.
25//!
26//! ## Protocol version changelog
27//!
28//! * `1`: initial version
29
30#[cfg(all(any(target_os = "android", target_os = "ios"), feature = "tls-native-roots"))]
31compile_error!("feature `tls-native-roots` can't be used on Android or iOS, use `tls-webpki-roots` instead");
32
33pub extern crate tonic;
34
35// Generated gRPC method lookup from proto files (server-only)
36#[cfg(feature = "server")]
37include!(concat!(env!("OUT_DIR"), "/grpc_methods.rs"));
38
39mod convert;
40pub use crate::convert::{ConvertError, TryFromBytes};
41
42mod error;
43pub use crate::error::StatusExt;
44
45pub mod client;
46pub mod protos {
47	pub mod core {
48		tonic::include_proto!("core");
49	}
50	pub use self::core::*;
51	pub mod bark_server {
52		tonic::include_proto!("bark_server");
53	}
54	pub use self::bark_server::*;
55	pub mod intman {
56		tonic::include_proto!("intman");
57	}
58	pub mod mailbox_server {
59		tonic::include_proto!("mailbox_server");
60	}
61}
62
63pub use client::ServerConnection;
64pub use crate::protos::bark_server::ark_service_client::ArkServiceClient;
65
66pub mod admin {
67	pub use crate::protos::bark_server::wallet_admin_service_client::WalletAdminServiceClient;
68	pub use crate::protos::bark_server::round_admin_service_client::RoundAdminServiceClient;
69	pub use crate::protos::bark_server::lightning_admin_service_client::LightningAdminServiceClient;
70	pub use crate::protos::bark_server::sweep_admin_service_client::SweepAdminServiceClient;
71	pub use crate::protos::bark_server::ban_admin_service_client::BanAdminServiceClient;
72}
73
74#[cfg(feature = "intman")]
75pub mod intman {
76	pub use crate::protos::intman::integration_service_client::IntegrationServiceClient;
77}
78
79#[cfg(feature = "server")]
80pub mod server {
81	pub use crate::protos::bark_server::ark_service_server::{ArkService, ArkServiceServer};
82	pub use crate::protos::bark_server::wallet_admin_service_server::{WalletAdminService, WalletAdminServiceServer};
83	pub use crate::protos::bark_server::round_admin_service_server::{RoundAdminService, RoundAdminServiceServer};
84	pub use crate::protos::bark_server::lightning_admin_service_server::{LightningAdminService, LightningAdminServiceServer};
85	pub use crate::protos::bark_server::sweep_admin_service_server::{SweepAdminService, SweepAdminServiceServer};
86	pub use crate::protos::bark_server::ban_admin_service_server::{BanAdminService, BanAdminServiceServer};
87	pub use crate::protos::intman::integration_service_server::{IntegrationService, IntegrationServiceServer};
88	pub use crate::protos::mailbox_server::mailbox_service_server::{MailboxService, MailboxServiceServer};
89}
90
91pub mod mailbox {
92	pub use crate::protos::mailbox_server::mailbox_service_client::MailboxServiceClient;
93}
94
95
96use std::borrow::BorrowMut;
97use std::str::FromStr;
98
99use bitcoin::{Address, Amount, OutPoint};
100use bitcoin::address::NetworkUnchecked;
101
102/// The string used in the gRPC HTTP header for the protocol version.
103pub const PROTOCOL_VERSION_HEADER: &str = "pver";
104
105#[derive(Debug, Clone)]
106pub struct WalletStatus {
107	pub address: Address<NetworkUnchecked>,
108	pub total_balance: Amount,
109	pub trusted_balance: Amount,
110	pub untrusted_balance: Amount,
111	pub confirmed_utxos: Vec<OutPoint>,
112	pub unconfirmed_utxos: Vec<OutPoint>,
113}
114
115/// Extension trait on [tonic::Request].
116pub trait RequestExt<T>: BorrowMut<tonic::Request<T>> {
117	/// Check for the protocol version header.
118	///
119	/// Returns None in case of missing header.
120	fn try_pver(&self) -> Result<Option<u64>, tonic::Status> {
121		self.borrow().metadata().get(PROTOCOL_VERSION_HEADER).map(|v| {
122			v.to_str().ok().and_then(|s| u64::from_str(s).ok())
123				.ok_or_else(|| tonic::Status::invalid_argument("invalid protocol version header"))
124		}).transpose()
125	}
126
127	/// Check for the protocol version header.
128	///
129	/// Returns error in case of missing header.
130	fn pver(&self) -> Result<u64, tonic::Status> {
131		self.try_pver()?.ok_or_else(|| tonic::Status::invalid_argument("missing pver header"))
132	}
133
134	/// Set the protocol version header.
135	fn set_pver(&mut self, pver: u64) {
136		self.borrow_mut().metadata_mut().insert(PROTOCOL_VERSION_HEADER, pver.into());
137	}
138}
139impl<T> RequestExt<T> for tonic::Request<T> {}