Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit 81bbbea

Browse files
authored
Merge pull request #8 from Srg213/lsps1
LSPS1- Channel request
2 parents e27e804 + f1e259e commit 81bbbea

File tree

9 files changed

+1564
-4
lines changed

9 files changed

+1564
-4
lines changed

src/channel_request/channel_manager.rs

Lines changed: 1075 additions & 0 deletions
Large diffs are not rendered by default.

src/channel_request/event.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#![allow(missing_docs)]
2+
3+
use bitcoin::secp256k1::PublicKey;
4+
5+
use super::msgs::{ChannelInfo, OptionsSupported, Order, OrderId, Payment};
6+
use crate::transport::msgs::RequestId;
7+
8+
/// An "Event" which you should probably take some action in response to.
9+
#[derive(Clone, Debug, PartialEq, Eq)]
10+
pub enum Event {
11+
GetInfoResponse {
12+
id: u128,
13+
request_id: RequestId,
14+
counterparty_node_id: PublicKey,
15+
version: u16,
16+
website: String,
17+
options_supported: OptionsSupported,
18+
},
19+
20+
CreateInvoice {
21+
request_id: RequestId,
22+
counterparty_node_id: PublicKey,
23+
order: Order,
24+
},
25+
26+
DisplayOrder {
27+
id: u128,
28+
counterparty_node_id: PublicKey,
29+
order: Order,
30+
payment: Payment,
31+
channel: Option<ChannelInfo>,
32+
},
33+
34+
PayforChannel {
35+
request_id: RequestId,
36+
counterparty_node_id: PublicKey,
37+
order: Order,
38+
payment: Payment,
39+
channel: Option<ChannelInfo>,
40+
},
41+
42+
CheckPaymentConfirmation {
43+
request_id: RequestId,
44+
counterparty_node_id: PublicKey,
45+
order_id: OrderId,
46+
},
47+
48+
OpenChannel {
49+
request_id: RequestId,
50+
counterparty_node_id: PublicKey,
51+
order_id: OrderId,
52+
},
53+
54+
Refund {
55+
request_id: RequestId,
56+
counterparty_node_id: PublicKey,
57+
order_id: OrderId,
58+
},
59+
}

src/channel_request/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,8 @@
88
// licenses.
99

1010
//! Types and primitives that implement the LSPS1: Channel Request specification.
11+
pub(crate) mod channel_manager;
12+
pub(crate) mod event;
13+
/// Message, request, and other primitive types used to implement LSPS2.
14+
pub mod msgs;
15+
pub(crate) mod utils;

src/channel_request/msgs.rs

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
use chrono::Utc;
2+
use std::convert::TryFrom;
3+
4+
use serde::{Deserialize, Serialize};
5+
6+
use crate::transport::msgs::{LSPSMessage, RequestId, ResponseError};
7+
8+
pub(crate) const LSPS1_GET_INFO_METHOD_NAME: &str = "lsps1.get_info";
9+
pub(crate) const LSPS1_CREATE_ORDER_METHOD_NAME: &str = "lsps1.create_order";
10+
pub(crate) const LSPS1_GET_ORDER_METHOD_NAME: &str = "lsps1.get_order";
11+
12+
pub(crate) const LSPS1_CREATE_ORDER_REQUEST_INVALID_PARAMS_ERROR_CODE: i32 = -32602;
13+
pub(crate) const LSPS1_CREATE_ORDER_REQUEST_ORDER_MISMATCH_ERROR_CODE: i32 = 1000;
14+
pub(crate) const LSPS1_CREATE_ORDER_REQUEST_CLIENT_REJECTED_ERROR_CODE: i32 = 1001;
15+
pub(crate) const LSPS1_CREATE_ORDER_REQUEST_INVALID_VERSION_ERROR_CODE: i32 = 1;
16+
pub(crate) const LSPS1_CREATE_ORDER_REQUEST_INVALID_TOKEN_ERROR_CODE: i32 = 2;
17+
18+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Hash)]
19+
pub struct OrderId(pub String);
20+
21+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
22+
#[serde(default)]
23+
pub struct GetInfoRequest {}
24+
25+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
26+
pub struct OptionsSupported {
27+
pub minimum_channel_confirmations: u8,
28+
pub minimum_onchain_payment_confirmations: u8,
29+
pub supports_zero_channel_reserve: bool,
30+
pub min_onchain_payment_size_sat: Option<u32>,
31+
pub max_channel_expiry_blocks: u32,
32+
pub min_initial_client_balance_sat: u64,
33+
pub max_initial_client_balance_sat: u64,
34+
pub min_initial_lsp_balance_sat: u64,
35+
pub max_initial_lsp_balance_sat: u64,
36+
pub min_channel_balance_sat: u64,
37+
pub max_channel_balance_sat: u64,
38+
}
39+
40+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
41+
pub struct GetInfoResponse {
42+
pub supported_versions: Vec<u16>,
43+
pub website: String,
44+
pub options: OptionsSupported,
45+
}
46+
47+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
48+
pub struct CreateOrderRequest {
49+
pub version: u16,
50+
pub order: Order,
51+
}
52+
53+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
54+
pub struct Order {
55+
pub api_version: u16,
56+
pub lsp_balance_sat: u64,
57+
pub client_balance_sat: u64,
58+
pub confirms_within_blocks: u32,
59+
pub channel_expiry_blocks: u32,
60+
pub token: String,
61+
pub announce_channel: bool,
62+
pub refund_onchain_address: Option<String>,
63+
}
64+
65+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
66+
pub struct CreateOrderResponse {
67+
pub order_id: OrderId,
68+
pub order: Order,
69+
pub order_state: OrderState,
70+
pub created_at: chrono::DateTime<Utc>,
71+
pub expires_at: chrono::DateTime<Utc>,
72+
pub payment: Payment,
73+
pub channel: Option<ChannelInfo>,
74+
}
75+
76+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
77+
pub enum OrderState {
78+
Requested,
79+
Created,
80+
Completed,
81+
Failed,
82+
}
83+
84+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
85+
pub struct Payment {
86+
pub state: PaymentState,
87+
pub fee_total_sat: u64,
88+
pub order_total_sat: u64,
89+
pub onchain_address: String,
90+
pub bolt11_invoice: String,
91+
pub onchain_block_confirmations_required: u8,
92+
pub minimum_fee_for_0conf: u8,
93+
pub onchain_payment: OnchainPayment,
94+
}
95+
96+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
97+
pub enum PaymentState {
98+
ExpectPayment,
99+
Hold,
100+
Paid,
101+
Refunded,
102+
}
103+
104+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
105+
pub struct OnchainPayment {
106+
pub outpoint: String,
107+
pub sat: u64,
108+
pub confirmed: bool,
109+
}
110+
111+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
112+
pub struct ChannelInfo {
113+
pub state: ChannelStatus,
114+
pub funded_at: String,
115+
pub funding_outpoint: String,
116+
pub scid: Option<String>,
117+
pub expires_at: String,
118+
pub closing_transaction: Option<String>,
119+
pub closed_at: Option<String>,
120+
}
121+
122+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
123+
pub enum ChannelStatus {
124+
Opening,
125+
Opened,
126+
Closed,
127+
}
128+
129+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
130+
pub struct GetOrderRequest {
131+
pub order_id: OrderId,
132+
}
133+
134+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
135+
pub struct GetOrderResponse {
136+
pub response: CreateOrderResponse,
137+
}
138+
139+
#[derive(Clone, Debug, PartialEq, Eq)]
140+
pub enum LSPS1Request {
141+
GetInfo(GetInfoRequest),
142+
CreateOrder(CreateOrderRequest),
143+
GetOrder(GetOrderRequest),
144+
}
145+
146+
impl LSPS1Request {
147+
pub fn method(&self) -> &str {
148+
match self {
149+
LSPS1Request::GetInfo(_) => LSPS1_GET_INFO_METHOD_NAME,
150+
LSPS1Request::CreateOrder(_) => LSPS1_CREATE_ORDER_METHOD_NAME,
151+
LSPS1Request::GetOrder(_) => LSPS1_GET_ORDER_METHOD_NAME,
152+
}
153+
}
154+
}
155+
156+
#[derive(Clone, Debug, PartialEq, Eq)]
157+
pub enum LSPS1Response {
158+
GetInfo(GetInfoResponse),
159+
CreateOrder(CreateOrderResponse),
160+
CreateOrderError(ResponseError),
161+
GetOrder(GetOrderResponse),
162+
GetOrderError(ResponseError),
163+
}
164+
165+
#[derive(Clone, Debug, PartialEq, Eq)]
166+
pub enum LSPS1Message {
167+
Request(RequestId, LSPS1Request),
168+
Response(RequestId, LSPS1Response),
169+
}
170+
171+
impl TryFrom<LSPSMessage> for LSPS1Message {
172+
type Error = ();
173+
174+
fn try_from(message: LSPSMessage) -> Result<Self, Self::Error> {
175+
if let LSPSMessage::LSPS1(message) = message {
176+
return Ok(message);
177+
}
178+
179+
Err(())
180+
}
181+
}
182+
183+
impl From<LSPS1Message> for LSPSMessage {
184+
fn from(message: LSPS1Message) -> Self {
185+
LSPSMessage::LSPS1(message)
186+
}
187+
}

src/channel_request/utils.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use super::msgs::{OptionsSupported, Order};
2+
3+
pub fn check_range(min: u64, max: u64, value: u64) -> bool {
4+
(value >= min) && (value <= max)
5+
}
6+
7+
pub fn is_valid(order: &Order, options: &OptionsSupported) -> bool {
8+
let bool = check_range(
9+
options.min_initial_client_balance_sat,
10+
options.max_initial_client_balance_sat,
11+
order.client_balance_sat,
12+
) && check_range(
13+
options.min_initial_lsp_balance_sat,
14+
options.max_initial_lsp_balance_sat,
15+
order.lsp_balance_sat,
16+
) && check_range(
17+
1,
18+
options.max_channel_expiry_blocks.into(),
19+
order.channel_expiry_blocks.into(),
20+
);
21+
22+
bool
23+
}

src/events.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
//! [`LiquidityManager::get_and_clear_pending_events`] to receive events.
1515
//!
1616
//! [`LiquidityManager::get_and_clear_pending_events`]: crate::LiquidityManager::get_and_clear_pending_events
17+
/// [`crate::LiquidityManager::get_and_clear_pending_events()`] to receive events.
18+
use crate::channel_request;
1719
use crate::jit_channel;
1820
use std::collections::VecDeque;
1921
use std::sync::{Condvar, Mutex};
@@ -60,4 +62,6 @@ impl EventQueue {
6062
pub enum Event {
6163
/// An LSPS2 (JIT Channel) protocol event.
6264
LSPS2(jit_channel::LSPS2Event),
65+
/// An LSPS1 protocol event.
66+
LSPS1(channel_request::event::Event),
6367
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub mod jit_channel;
2424
mod transport;
2525
mod utils;
2626

27+
pub use channel_request::event::Event as LSPS1Event;
2728
pub use transport::message_handler::{
2829
JITChannelsConfig, LiquidityManager, LiquidityProviderConfig,
2930
};

0 commit comments

Comments
 (0)