Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a024a76
LSPS1: Add initial integration test
martinsaposnic Jun 16, 2025
9a64a65
Cleanup unused code
tnull Nov 16, 2025
0d7408b
Drop `chain_source` from `LSPS1ServiceHandler`
tnull Dec 9, 2025
8ad5101
Drop `Listen`/`Confirm`/etc from `LiquidityManager`
tnull Dec 9, 2025
c6465f2
Move `PeerState` and related types to `peer_state.rs` module
tnull Nov 16, 2025
fa867c2
Drop bogus channel state handling
tnull Nov 16, 2025
0c8e26a
Replace `insert_outbound_channel` with `PeerState::new_order`
tnull Nov 16, 2025
f0c4b08
Use `PeerState::{get_order, has_active_requests}` instead of map
tnull Nov 16, 2025
f1a22c1
Use `PeerState::{register,remove}_request` instead of map access
tnull Nov 16, 2025
582783e
Drop `OutboundCRChannel`
tnull Nov 16, 2025
05bdad7
Actually remember the order state in `ChannelOrder`
tnull Nov 16, 2025
8de6ad1
`LSPS1ServiceHandler`: Use `TimeProvider` when creating new orders
tnull Dec 10, 2025
3b0edb3
Require `supported_options` in `LSPS1ServiceConfig`
tnull Dec 10, 2025
91d8edc
Respond to `GetOrder` requests from our saved state
tnull Dec 10, 2025
b372d4c
Add serialization logic for LSPS1 `PeerState` types
tnull Dec 11, 2025
81767ab
Implement `LSPS1ServiceHandler` persistence and state pruning
tnull Dec 11, 2025
430c3b7
Read persisted LSPS1ServiceHandler state on startup
tnull Dec 12, 2025
eb53151
Add test case asserting `LSPS1ServiceState` is persisted across restarts
tnull Dec 12, 2025
b5169ed
Add some checks on provided payment details
tnull Dec 12, 2025
abb5b1c
Don't hold write lock in `LSPS{1,2}ServiceHandler::peer_disconnected`
tnull Dec 12, 2025
fab875c
Add `invalid_token_provided` API method
tnull Dec 12, 2025
e54c35d
Add test case for `invalid_token_provided` flow
tnull Dec 12, 2025
b3c45c5
Drop `lsps1_service` cfg flag
tnull Dec 12, 2025
95d192f
Fix clippy lints
tnull Dec 12, 2025
86f5459
Refactor `ChannelOrder` to use `ChannelOrderState` state machine
tnull Feb 5, 2026
65bf49b
Add integration tests for LSPS1 order state transition API
tnull Feb 5, 2026
90c1b47
Add integration test for expired order pruning
tnull Feb 5, 2026
41ed59b
Drop unused `LSPS1OnchainPayment` type
tnull Feb 5, 2026
0759fda
Add `Hold` payment state per bLIP-51 spec
tnull Feb 5, 2026
e82ec52
Drop unused `LSPS1ServiceEvent::Refund` event
tnull Feb 11, 2026
13858e0
Add `onchain_payment_required` method
tnull Feb 11, 2026
761ae26
Limit pending requests and peers in LSPS1 service
tnull Feb 11, 2026
e31b5c8
Reject clients if request registration failed (e.g., duplicative Id)
tnull Feb 11, 2026
37f66f3
feat: add LSPS7 (Channel Lease Extensions) client handler
kaloudis Feb 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions ci/ci-tests-cfg-flags.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,4 @@ RUSTFLAGS="--cfg=taproot" cargo test --quiet --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=simple_close" cargo test --quiet --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=lsps1_service" cargo test --quiet --color always -p lightning-liquidity
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=peer_storage" cargo test --quiet --color always -p lightning
2 changes: 0 additions & 2 deletions fuzz/src/lsps_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ pub fn do_test(data: &[u8]) {
Arc::clone(&keys_manager),
Arc::clone(&keys_manager),
Arc::clone(&manager),
None::<Arc<dyn Filter + Send + Sync>>,
None,
kv_store,
Arc::clone(&tx_broadcaster),
None,
Expand Down
27 changes: 11 additions & 16 deletions lightning-background-processor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@ pub const NO_LIQUIDITY_MANAGER: Option<
NodeSigner = &(dyn lightning::sign::NodeSigner + Send + Sync),
AChannelManager = DynChannelManager,
CM = &DynChannelManager,
C = &(dyn chain::Filter + Send + Sync),
K = &DummyKVStore,
TimeProvider = dyn lightning_liquidity::utils::time::TimeProvider + Send + Sync,
TP = &(dyn lightning_liquidity::utils::time::TimeProvider + Send + Sync),
Expand All @@ -486,7 +485,6 @@ pub const NO_LIQUIDITY_MANAGER_SYNC: Option<
NodeSigner = &(dyn lightning::sign::NodeSigner + Send + Sync),
AChannelManager = DynChannelManager,
CM = &DynChannelManager,
C = &(dyn chain::Filter + Send + Sync),
KVStoreSync = dyn lightning::util::persist::KVStoreSync + Send + Sync,
KS = &(dyn lightning::util::persist::KVStoreSync + Send + Sync),
TimeProvider = dyn lightning_liquidity::utils::time::TimeProvider + Send + Sync,
Expand Down Expand Up @@ -829,7 +827,7 @@ use futures_util::{dummy_waker, Joiner, OptionalSelector, Selector, SelectorOutp
/// # type P2PGossipSync<UL> = lightning::routing::gossip::P2PGossipSync<Arc<NetworkGraph>, Arc<UL>, Arc<Logger>>;
/// # type ChannelManager<B, F, FE> = lightning::ln::channelmanager::SimpleArcChannelManager<ChainMonitor<B, F, FE>, B, FE, Logger>;
/// # type OnionMessenger<B, F, FE> = lightning::onion_message::messenger::OnionMessenger<Arc<lightning::sign::KeysManager>, Arc<lightning::sign::KeysManager>, Arc<Logger>, Arc<ChannelManager<B, F, FE>>, Arc<lightning::onion_message::messenger::DefaultMessageRouter<Arc<NetworkGraph>, Arc<Logger>, Arc<lightning::sign::KeysManager>>>, Arc<ChannelManager<B, F, FE>>, lightning::ln::peer_handler::IgnoringMessageHandler, lightning::ln::peer_handler::IgnoringMessageHandler, lightning::ln::peer_handler::IgnoringMessageHandler>;
/// # type LiquidityManager<B, F, FE> = lightning_liquidity::LiquidityManager<Arc<lightning::sign::KeysManager>, Arc<lightning::sign::KeysManager>, Arc<ChannelManager<B, F, FE>>, Arc<F>, Arc<Store>, Arc<DefaultTimeProvider>, Arc<B>>;
/// # type LiquidityManager<B, F, FE> = lightning_liquidity::LiquidityManager<Arc<lightning::sign::KeysManager>, Arc<lightning::sign::KeysManager>, Arc<ChannelManager<B, F, FE>>, Arc<Store>, Arc<DefaultTimeProvider>, Arc<B>>;
/// # type Scorer = RwLock<lightning::routing::scoring::ProbabilisticScorer<Arc<NetworkGraph>, Arc<Logger>>>;
/// # type PeerManager<B, F, FE, UL> = lightning::ln::peer_handler::SimpleArcPeerManager<SocketDescriptor, ChainMonitor<B, F, FE>, B, FE, Arc<UL>, Logger, F, StoreSync>;
/// # type OutputSweeper<B, D, FE, F, O> = lightning::util::sweep::OutputSweeper<Arc<B>, Arc<D>, Arc<FE>, Arc<F>, Arc<Store>, Arc<Logger>, Arc<O>>;
Expand Down Expand Up @@ -1898,7 +1896,7 @@ mod tests {
use core::sync::atomic::{AtomicBool, Ordering};
use lightning::chain::channelmonitor::ANTI_REORG_DELAY;
use lightning::chain::transaction::OutPoint;
use lightning::chain::{chainmonitor, BestBlock, Confirm, Filter};
use lightning::chain::{chainmonitor, BestBlock, Confirm};
use lightning::events::{Event, PathFailure, ReplayEvent};
use lightning::ln::channelmanager;
use lightning::ln::channelmanager::{
Expand Down Expand Up @@ -2054,7 +2052,6 @@ mod tests {
Arc<KeysManager>,
Arc<KeysManager>,
Arc<ChannelManager>,
Arc<dyn Filter + Sync + Send>,
Arc<Persister>,
DefaultTimeProvider,
Arc<test_utils::TestBroadcaster>,
Expand Down Expand Up @@ -2513,8 +2510,6 @@ mod tests {
Arc::clone(&keys_manager),
Arc::clone(&keys_manager),
Arc::clone(&manager),
None,
None,
Arc::clone(&kv_store),
Arc::clone(&tx_broadcaster),
None,
Expand Down Expand Up @@ -2910,10 +2905,10 @@ mod tests {
let kv_store = KVStoreSyncWrapper(kv_store_sync);

// Yes, you can unsafe { turn off the borrow checker }
let lm_async: &'static LiquidityManager<_, _, _, _, _, _, _> = unsafe {
let lm_async: &'static LiquidityManager<_, _, _, _, _, _> = unsafe {
&*(nodes[0].liquidity_manager.get_lm_async()
as *const LiquidityManager<_, _, _, _, _, _, _>)
as &'static LiquidityManager<_, _, _, _, _, _, _>
as *const LiquidityManager<_, _, _, _, _, _>)
as &'static LiquidityManager<_, _, _, _, _, _>
};
let sweeper_async: &'static OutputSweeper<_, _, _, _, _, _, _> = unsafe {
&*(nodes[0].sweeper.sweeper_async() as *const OutputSweeper<_, _, _, _, _, _, _>)
Expand Down Expand Up @@ -3435,10 +3430,10 @@ mod tests {
let kv_store = KVStoreSyncWrapper(kv_store_sync);

// Yes, you can unsafe { turn off the borrow checker }
let lm_async: &'static LiquidityManager<_, _, _, _, _, _, _> = unsafe {
let lm_async: &'static LiquidityManager<_, _, _, _, _, _> = unsafe {
&*(nodes[0].liquidity_manager.get_lm_async()
as *const LiquidityManager<_, _, _, _, _, _, _>)
as &'static LiquidityManager<_, _, _, _, _, _, _>
as *const LiquidityManager<_, _, _, _, _, _>)
as &'static LiquidityManager<_, _, _, _, _, _>
};
let sweeper_async: &'static OutputSweeper<_, _, _, _, _, _, _> = unsafe {
&*(nodes[0].sweeper.sweeper_async() as *const OutputSweeper<_, _, _, _, _, _, _>)
Expand Down Expand Up @@ -3662,10 +3657,10 @@ mod tests {
let (exit_sender, exit_receiver) = tokio::sync::watch::channel(());

// Yes, you can unsafe { turn off the borrow checker }
let lm_async: &'static LiquidityManager<_, _, _, _, _, _, _> = unsafe {
let lm_async: &'static LiquidityManager<_, _, _, _, _, _> = unsafe {
&*(nodes[0].liquidity_manager.get_lm_async()
as *const LiquidityManager<_, _, _, _, _, _, _>)
as &'static LiquidityManager<_, _, _, _, _, _, _>
as *const LiquidityManager<_, _, _, _, _, _>)
as &'static LiquidityManager<_, _, _, _, _, _>
};
let sweeper_async: &'static OutputSweeper<_, _, _, _, _, _, _> = unsafe {
&*(nodes[0].sweeper.sweeper_async() as *const OutputSweeper<_, _, _, _, _, _, _>)
Expand Down
1 change: 0 additions & 1 deletion lightning-liquidity/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ parking_lot = { version = "0.12", default-features = false }
level = "forbid"
# When adding a new cfg attribute, ensure that it is added to this list.
check-cfg = [
"cfg(lsps1_service)",
"cfg(c_bindings)",
"cfg(backtrace)",
"cfg(ldk_bench)",
Expand Down
11 changes: 9 additions & 2 deletions lightning-liquidity/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::lsps0;
use crate::lsps1;
use crate::lsps2;
use crate::lsps5;
use crate::lsps7;

/// An event which you should probably take some action in response to.
#[derive(Debug, Clone, PartialEq, Eq)]
Expand All @@ -33,7 +34,6 @@ pub enum LiquidityEvent {
/// An LSPS1 (Channel Request) client event.
LSPS1Client(lsps1::event::LSPS1ClientEvent),
/// An LSPS1 (Channel Request) server event.
#[cfg(lsps1_service)]
LSPS1Service(lsps1::event::LSPS1ServiceEvent),
/// An LSPS2 (JIT Channel) client event.
LSPS2Client(lsps2::event::LSPS2ClientEvent),
Expand All @@ -43,6 +43,8 @@ pub enum LiquidityEvent {
LSPS5Client(lsps5::event::LSPS5ClientEvent),
/// An LSPS5 (Webhook) server event.
LSPS5Service(lsps5::event::LSPS5ServiceEvent),
/// An LSPS7 (Channel Lease Extension) client event.
LSPS7Client(lsps7::event::LSPS7ClientEvent),
}

impl From<lsps0::event::LSPS0ClientEvent> for LiquidityEvent {
Expand All @@ -57,7 +59,6 @@ impl From<lsps1::event::LSPS1ClientEvent> for LiquidityEvent {
}
}

#[cfg(lsps1_service)]
impl From<lsps1::event::LSPS1ServiceEvent> for LiquidityEvent {
fn from(event: lsps1::event::LSPS1ServiceEvent) -> Self {
Self::LSPS1Service(event)
Expand Down Expand Up @@ -87,3 +88,9 @@ impl From<lsps5::event::LSPS5ServiceEvent> for LiquidityEvent {
Self::LSPS5Service(event)
}
}

impl From<lsps7::event::LSPS7ClientEvent> for LiquidityEvent {
fn from(event: lsps7::event::LSPS7ClientEvent) -> Self {
Self::LSPS7Client(event)
}
}
1 change: 1 addition & 0 deletions lightning-liquidity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub mod lsps0;
pub mod lsps1;
pub mod lsps2;
pub mod lsps5;
pub mod lsps7;
mod manager;
pub mod message_queue;
pub mod persist;
Expand Down
1 change: 1 addition & 0 deletions lightning-liquidity/src/lsps0/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl TryFrom<LSPSMessage> for LSPS0Message {
LSPSMessage::LSPS1(_) => Err(()),
LSPSMessage::LSPS2(_) => Err(()),
LSPSMessage::LSPS5(_) => Err(()),
LSPSMessage::LSPS7(_) => Err(()),
}
}
}
Expand Down
144 changes: 144 additions & 0 deletions lightning-liquidity/src/lsps0/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ use crate::lsps5::msgs::{
LSPS5Message, LSPS5Request, LSPS5Response, LSPS5_LIST_WEBHOOKS_METHOD_NAME,
LSPS5_REMOVE_WEBHOOK_METHOD_NAME, LSPS5_SET_WEBHOOK_METHOD_NAME,
};
use crate::lsps7::msgs::{
LSPS7Message, LSPS7Request, LSPS7Response, LSPS7_CREATE_ORDER_METHOD_NAME,
LSPS7_GET_EXTENDABLE_CHANNELS_METHOD_NAME, LSPS7_GET_ORDER_METHOD_NAME,
};

use crate::prelude::HashMap;

Expand Down Expand Up @@ -69,6 +73,9 @@ pub(crate) enum LSPSMethod {
LSPS5SetWebhook,
LSPS5ListWebhooks,
LSPS5RemoveWebhook,
LSPS7GetExtendableChannels,
LSPS7CreateOrder,
LSPS7GetOrder,
}

impl LSPSMethod {
Expand All @@ -83,6 +90,9 @@ impl LSPSMethod {
Self::LSPS5SetWebhook => LSPS5_SET_WEBHOOK_METHOD_NAME,
Self::LSPS5ListWebhooks => LSPS5_LIST_WEBHOOKS_METHOD_NAME,
Self::LSPS5RemoveWebhook => LSPS5_REMOVE_WEBHOOK_METHOD_NAME,
Self::LSPS7GetExtendableChannels => LSPS7_GET_EXTENDABLE_CHANNELS_METHOD_NAME,
Self::LSPS7CreateOrder => LSPS7_CREATE_ORDER_METHOD_NAME,
Self::LSPS7GetOrder => LSPS7_GET_ORDER_METHOD_NAME,
}
}
}
Expand All @@ -100,6 +110,9 @@ impl FromStr for LSPSMethod {
LSPS5_SET_WEBHOOK_METHOD_NAME => Ok(Self::LSPS5SetWebhook),
LSPS5_LIST_WEBHOOKS_METHOD_NAME => Ok(Self::LSPS5ListWebhooks),
LSPS5_REMOVE_WEBHOOK_METHOD_NAME => Ok(Self::LSPS5RemoveWebhook),
LSPS7_GET_EXTENDABLE_CHANNELS_METHOD_NAME => Ok(Self::LSPS7GetExtendableChannels),
LSPS7_CREATE_ORDER_METHOD_NAME => Ok(Self::LSPS7CreateOrder),
LSPS7_GET_ORDER_METHOD_NAME => Ok(Self::LSPS7GetOrder),
_ => Err(&"Unknown method name"),
}
}
Expand Down Expand Up @@ -142,6 +155,16 @@ impl From<&LSPS5Request> for LSPSMethod {
}
}

impl From<&LSPS7Request> for LSPSMethod {
fn from(value: &LSPS7Request) -> Self {
match value {
LSPS7Request::GetExtendableChannels(_) => Self::LSPS7GetExtendableChannels,
LSPS7Request::CreateOrder(_) => Self::LSPS7CreateOrder,
LSPS7Request::GetOrder(_) => Self::LSPS7GetOrder,
}
}
}

impl<'de> Deserialize<'de> for LSPSMethod {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand Down Expand Up @@ -326,6 +349,8 @@ pub enum LSPSMessage {
LSPS2(LSPS2Message),
/// An LSPS5 message.
LSPS5(LSPS5Message),
/// An LSPS7 message.
LSPS7(LSPS7Message),
}

impl LSPSMessage {
Expand Down Expand Up @@ -356,6 +381,9 @@ impl LSPSMessage {
LSPSMessage::LSPS5(LSPS5Message::Request(request_id, request)) => {
Some((LSPSRequestId(request_id.0.clone()), request.into()))
},
LSPSMessage::LSPS7(LSPS7Message::Request(request_id, request)) => {
Some((LSPSRequestId(request_id.0.clone()), request.into()))
},
_ => None,
}
}
Expand Down Expand Up @@ -510,6 +538,47 @@ impl Serialize for LSPSMessage {
},
}
},
LSPSMessage::LSPS7(LSPS7Message::Request(request_id, request)) => {
jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
jsonrpc_object
.serialize_field(JSONRPC_METHOD_FIELD_KEY, &LSPSMethod::from(request))?;

match request {
LSPS7Request::GetExtendableChannels(params) => {
jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
},
LSPS7Request::CreateOrder(params) => {
jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
},
LSPS7Request::GetOrder(params) => {
jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
},
}
},
LSPSMessage::LSPS7(LSPS7Message::Response(request_id, response)) => {
jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;

match response {
LSPS7Response::GetExtendableChannels(result) => {
jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
},
LSPS7Response::GetExtendableChannelsError(error) => {
jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
},
LSPS7Response::CreateOrder(result) => {
jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
},
LSPS7Response::CreateOrderError(error) => {
jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
},
LSPS7Response::GetOrder(result) => {
jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
},
LSPS7Response::GetOrderError(error) => {
jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
},
}
},
}

jsonrpc_object.end()
Expand Down Expand Up @@ -647,6 +716,30 @@ impl<'de, 'a> Visitor<'de> for LSPSMessageVisitor<'a> {
LSPS5Request::RemoveWebhook(request),
)))
},
LSPSMethod::LSPS7GetExtendableChannels => {
let request = serde_json::from_value(params.unwrap_or(json!({})))
.map_err(de::Error::custom)?;
Ok(LSPSMessage::LSPS7(LSPS7Message::Request(
id,
LSPS7Request::GetExtendableChannels(request),
)))
},
LSPSMethod::LSPS7CreateOrder => {
let request = serde_json::from_value(params.unwrap_or(json!({})))
.map_err(de::Error::custom)?;
Ok(LSPSMessage::LSPS7(LSPS7Message::Request(
id,
LSPS7Request::CreateOrder(request),
)))
},
LSPSMethod::LSPS7GetOrder => {
let request = serde_json::from_value(params.unwrap_or(json!({})))
.map_err(de::Error::custom)?;
Ok(LSPSMessage::LSPS7(LSPS7Message::Request(
id,
LSPS7Request::GetOrder(request),
)))
},
},
None => match self.request_id_to_method_map.remove(&id) {
Some(method) => match method {
Expand Down Expand Up @@ -798,6 +891,57 @@ impl<'de, 'a> Visitor<'de> for LSPSMessageVisitor<'a> {
Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
}
},
LSPSMethod::LSPS7GetExtendableChannels => {
if let Some(error) = error {
Ok(LSPSMessage::LSPS7(LSPS7Message::Response(
id,
LSPS7Response::GetExtendableChannelsError(error),
)))
} else if let Some(result) = result {
let response =
serde_json::from_value(result).map_err(de::Error::custom)?;
Ok(LSPSMessage::LSPS7(LSPS7Message::Response(
id,
LSPS7Response::GetExtendableChannels(response),
)))
} else {
Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
}
},
LSPSMethod::LSPS7CreateOrder => {
if let Some(error) = error {
Ok(LSPSMessage::LSPS7(LSPS7Message::Response(
id,
LSPS7Response::CreateOrderError(error),
)))
} else if let Some(result) = result {
let response =
serde_json::from_value(result).map_err(de::Error::custom)?;
Ok(LSPSMessage::LSPS7(LSPS7Message::Response(
id,
LSPS7Response::CreateOrder(response),
)))
} else {
Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
}
},
LSPSMethod::LSPS7GetOrder => {
if let Some(error) = error {
Ok(LSPSMessage::LSPS7(LSPS7Message::Response(
id,
LSPS7Response::GetOrderError(error),
)))
} else if let Some(result) = result {
let response =
serde_json::from_value(result).map_err(de::Error::custom)?;
Ok(LSPSMessage::LSPS7(LSPS7Message::Response(
id,
LSPS7Response::GetOrder(response),
)))
} else {
Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
}
},
},
None => Err(de::Error::custom(format!(
"Received response for unknown request id: {}",
Expand Down
Loading
Loading