From 48c5292d96c341cafdf3a53783b8451c137c20f2 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Wed, 11 Feb 2026 13:27:05 +0100 Subject: [PATCH 01/16] gl-plugin: Use call_typed for regular invoice creation Replace call_raw with call_typed when creating a regular invoice in the LSP invoice handler. This provides better type safety by using the generated cln_rpc::model::requests::InvoiceRequest and cln_rpc::model::responses::InvoiceResponse types. Benefits: - Compile-time type checking for request/response fields - No manual hex decoding needed for payment_hash/payment_secret - Access to created_index field from the response - Cleaner code without custom request/response structs --- libs/gl-plugin/src/node/mod.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/libs/gl-plugin/src/node/mod.rs b/libs/gl-plugin/src/node/mod.rs index c865fb70c..f3bbd3cfc 100644 --- a/libs/gl-plugin/src/node/mod.rs +++ b/libs/gl-plugin/src/node/mod.rs @@ -25,6 +25,7 @@ use tokio_stream::wrappers::ReceiverStream; use tonic::{transport::ServerTlsConfig, Code, Request, Response, Status}; mod wrapper; use gl_client::bitcoin; +use std::borrow::Borrow; use std::str::FromStr; pub use wrapper::WrappedNodeServer; @@ -218,7 +219,7 @@ impl Node for PluginNodeServer { ); // Create a regular invoice without JIT channel negotiation - let invreq = crate::requests::Invoice { + let invreq = cln_rpc::model::requests::InvoiceRequest { amount_msat: cln_rpc::primitives::AmountOrAny::Amount( cln_rpc::primitives::Amount::from_msat(req.amount_msat), ), @@ -230,24 +231,19 @@ impl Node for PluginNodeServer { cltv: Some(144), deschashonly: None, exposeprivatechannels: None, - dev_routes: None, }; - let res: crate::responses::Invoice = rpc - .call_raw("invoice", &invreq) + let res = rpc + .call_typed(&invreq) .await .map_err(|e| Status::new(Code::Internal, e.to_string()))?; return Ok(Response::new(pb::LspInvoiceResponse { bolt11: res.bolt11, - created_index: 0, // Not available in our Invoice response - expires_at: res.expiry_time, - payment_hash: hex::decode(&res.payment_hash) - .map_err(|e| Status::new(Code::Internal, format!("Invalid payment_hash: {}", e)))?, - payment_secret: res - .payment_secret - .map(|s| hex::decode(&s).unwrap_or_default()) - .unwrap_or_default(), + created_index: res.created_index.unwrap_or(0) as u32, + expires_at: res.expires_at as u32, + payment_hash: >::borrow(&res.payment_hash).to_vec(), + payment_secret: res.payment_secret.to_vec(), })); } From 17bf4d3c0a232652e6c35ea2d9ad274603e43871 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 12:46:21 +0100 Subject: [PATCH 02/16] gl-sdk: Add get_info, list_peers, list_peer_channels, list_funds methods Add node information query methods to the gl-sdk Node struct: - get_info: Returns basic node information (id, alias, network, etc.) - list_peers: Returns connected peer information - list_peer_channels: Returns channel information with peers - list_funds: Returns on-chain and channel fund information Each method wraps the corresponding CLN gRPC call and converts the response to UniFFI-compatible Record types for cross-language bindings. --- libs/gl-sdk/src/lib.rs | 7 +- libs/gl-sdk/src/node.rs | 340 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 346 insertions(+), 1 deletion(-) diff --git a/libs/gl-sdk/src/lib.rs b/libs/gl-sdk/src/lib.rs index 50d497bdb..8227ea4d5 100644 --- a/libs/gl-sdk/src/lib.rs +++ b/libs/gl-sdk/src/lib.rs @@ -31,7 +31,12 @@ mod util; pub use crate::{ credentials::Credentials, - node::{Node, OnchainReceiveResponse, OnchainSendResponse, PayStatus, ReceiveResponse, SendResponse}, + node::{ + ChannelState, FundChannel, FundOutput, GetInfoResponse, ListFundsResponse, + ListPeerChannelsResponse, ListPeersResponse, Node, OnchainReceiveResponse, + OnchainSendResponse, OutputStatus, PayStatus, Peer, PeerChannel, ReceiveResponse, + SendResponse, + }, scheduler::Scheduler, signer::{Handle, Signer}, }; diff --git a/libs/gl-sdk/src/node.rs b/libs/gl-sdk/src/node.rs index ede5b034a..0683e691e 100644 --- a/libs/gl-sdk/src/node.rs +++ b/libs/gl-sdk/src/node.rs @@ -169,6 +169,69 @@ impl Node { .into_inner(); Ok(res.into()) } + + /// Get information about the node. + /// + /// Returns basic information about the node including its ID, + /// alias, network, and channel counts. + fn get_info(&self) -> Result { + let mut cln_client = exec(self.get_cln_client())?.clone(); + + let req = clnpb::GetinfoRequest {}; + + let res = exec(cln_client.getinfo(req)) + .map_err(|e| Error::Rpc(e.to_string()))? + .into_inner(); + Ok(res.into()) + } + + /// List all peers connected to this node. + /// + /// Returns information about all peers including their connection + /// status. + fn list_peers(&self) -> Result { + let mut cln_client = exec(self.get_cln_client())?.clone(); + + let req = clnpb::ListpeersRequest { + id: None, + level: None, + }; + + let res = exec(cln_client.list_peers(req)) + .map_err(|e| Error::Rpc(e.to_string()))? + .into_inner(); + Ok(res.into()) + } + + /// List all channels with peers. + /// + /// Returns detailed information about all channels including their + /// state, capacity, and balances. + fn list_peer_channels(&self) -> Result { + let mut cln_client = exec(self.get_cln_client())?.clone(); + + let req = clnpb::ListpeerchannelsRequest { id: None }; + + let res = exec(cln_client.list_peer_channels(req)) + .map_err(|e| Error::Rpc(e.to_string()))? + .into_inner(); + Ok(res.into()) + } + + /// List all funds available to the node. + /// + /// Returns information about on-chain outputs and channel funds + /// that are available or pending. + fn list_funds(&self) -> Result { + let mut cln_client = exec(self.get_cln_client())?.clone(); + + let req = clnpb::ListfundsRequest { spent: None }; + + let res = exec(cln_client.list_funds(req)) + .map_err(|e| Error::Rpc(e.to_string()))? + .into_inner(); + Ok(res.into()) + } } // Not exported through uniffi @@ -276,3 +339,280 @@ impl From for PayStatus { } } } + +// ============================================================ +// GetInfo response types +// ============================================================ + +#[allow(unused)] +#[derive(Clone, uniffi::Record)] +pub struct GetInfoResponse { + pub id: Vec, + pub alias: Option, + pub color: Vec, + pub num_peers: u32, + pub num_pending_channels: u32, + pub num_active_channels: u32, + pub num_inactive_channels: u32, + pub version: String, + pub lightning_dir: String, + pub blockheight: u32, + pub network: String, + pub fees_collected_msat: u64, +} + +impl From for GetInfoResponse { + fn from(other: clnpb::GetinfoResponse) -> Self { + Self { + id: other.id, + alias: other.alias, + color: other.color, + num_peers: other.num_peers, + num_pending_channels: other.num_pending_channels, + num_active_channels: other.num_active_channels, + num_inactive_channels: other.num_inactive_channels, + version: other.version, + lightning_dir: other.lightning_dir, + blockheight: other.blockheight, + network: other.network, + fees_collected_msat: other.fees_collected_msat.map(|a| a.msat).unwrap_or(0), + } + } +} + + + +// ============================================================ +// ListPeers response types +// ============================================================ + +#[allow(unused)] +#[derive(Clone, uniffi::Record)] +pub struct ListPeersResponse { + pub peers: Vec, +} + +#[allow(unused)] +#[derive(Clone, uniffi::Record)] +pub struct Peer { + id: Vec, + connected: bool, + num_channels: Option, + netaddr: Vec, + remote_addr: Option, + features: Option>, +} + +impl From for ListPeersResponse { + fn from(other: clnpb::ListpeersResponse) -> Self { + Self { + peers: other.peers.into_iter().map(|p| p.into()).collect(), + } + } +} + +impl From for Peer { + fn from(other: clnpb::ListpeersPeers) -> Self { + Self { + id: other.id, + connected: other.connected, + num_channels: other.num_channels, + netaddr: other.netaddr, + remote_addr: other.remote_addr, + features: other.features, + } + } +} + + + +// ============================================================ +// ListPeerChannels response types +// ============================================================ + +#[allow(unused)] +#[derive(Clone, uniffi::Record)] +pub struct ListPeerChannelsResponse { + pub channels: Vec, +} + +#[allow(unused)] +#[derive(Clone, uniffi::Record)] +pub struct PeerChannel { + peer_id: Vec, + peer_connected: bool, + state: ChannelState, + short_channel_id: Option, + channel_id: Option>, + funding_txid: Option>, + funding_outnum: Option, + to_us_msat: Option, + total_msat: Option, + spendable_msat: Option, + receivable_msat: Option, +} + +#[derive(Clone, uniffi::Enum)] +pub enum ChannelState { + Openingd, + ChanneldAwaitingLockin, + ChanneldNormal, + ChanneldShuttingDown, + ClosingdSigexchange, + ClosingdComplete, + AwaitingUnilateral, + FundingSpendSeen, + Onchain, + DualopendOpenInit, + DualopendAwaitingLockin, + DualopendOpenCommitted, + DualopendOpenCommitReady, +} + +impl ChannelState { + fn from_i32(value: i32) -> Self { + match value { + 0 => ChannelState::Openingd, + 1 => ChannelState::ChanneldAwaitingLockin, + 2 => ChannelState::ChanneldNormal, + 3 => ChannelState::ChanneldShuttingDown, + 4 => ChannelState::ClosingdSigexchange, + 5 => ChannelState::ClosingdComplete, + 6 => ChannelState::AwaitingUnilateral, + 7 => ChannelState::FundingSpendSeen, + 8 => ChannelState::Onchain, + 9 => ChannelState::DualopendOpenInit, + 10 => ChannelState::DualopendAwaitingLockin, + 11 => ChannelState::DualopendOpenCommitted, + 12 => ChannelState::DualopendOpenCommitReady, + _ => ChannelState::Onchain, // Default fallback + } + } +} + +impl From for ListPeerChannelsResponse { + fn from(other: clnpb::ListpeerchannelsResponse) -> Self { + Self { + channels: other.channels.into_iter().map(|c| c.into()).collect(), + } + } +} + +impl From for PeerChannel { + fn from(other: clnpb::ListpeerchannelsChannels) -> Self { + let state = ChannelState::from_i32(other.state); + Self { + peer_id: other.peer_id, + peer_connected: other.peer_connected, + state, + short_channel_id: other.short_channel_id, + channel_id: other.channel_id, + funding_txid: other.funding_txid, + funding_outnum: other.funding_outnum, + to_us_msat: other.to_us_msat.map(|a| a.msat), + total_msat: other.total_msat.map(|a| a.msat), + spendable_msat: other.spendable_msat.map(|a| a.msat), + receivable_msat: other.receivable_msat.map(|a| a.msat), + } + } +} + + + +// ============================================================ +// ListFunds response types +// ============================================================ + +#[allow(unused)] +#[derive(Clone, uniffi::Record)] +pub struct ListFundsResponse { + pub outputs: Vec, + pub channels: Vec, +} + +#[allow(unused)] +#[derive(Clone, uniffi::Record)] +pub struct FundOutput { + txid: Vec, + output: u32, + amount_msat: u64, + status: OutputStatus, + address: Option, + blockheight: Option, +} + +#[derive(Clone, uniffi::Enum)] +pub enum OutputStatus { + Unconfirmed, + Confirmed, + Spent, + Immature, +} + +impl OutputStatus { + fn from_i32(value: i32) -> Self { + match value { + 0 => OutputStatus::Unconfirmed, + 1 => OutputStatus::Confirmed, + 2 => OutputStatus::Spent, + 3 => OutputStatus::Immature, + _ => OutputStatus::Unconfirmed, // Default fallback + } + } +} + +#[allow(unused)] +#[derive(Clone, uniffi::Record)] +pub struct FundChannel { + peer_id: Vec, + our_amount_msat: u64, + amount_msat: u64, + funding_txid: Vec, + funding_output: u32, + connected: bool, + state: ChannelState, + short_channel_id: Option, + channel_id: Option>, +} + +impl From for ListFundsResponse { + fn from(other: clnpb::ListfundsResponse) -> Self { + Self { + outputs: other.outputs.into_iter().map(|o| o.into()).collect(), + channels: other.channels.into_iter().map(|c| c.into()).collect(), + } + } +} + +impl From for FundOutput { + fn from(other: clnpb::ListfundsOutputs) -> Self { + let status = OutputStatus::from_i32(other.status); + Self { + txid: other.txid, + output: other.output, + amount_msat: other.amount_msat.map(|a| a.msat).unwrap_or(0), + status, + address: other.address, + blockheight: other.blockheight, + } + } +} + +impl From for FundChannel { + fn from(other: clnpb::ListfundsChannels) -> Self { + let state = ChannelState::from_i32(other.state); + Self { + peer_id: other.peer_id, + our_amount_msat: other.our_amount_msat.map(|a| a.msat).unwrap_or(0), + amount_msat: other.amount_msat.map(|a| a.msat).unwrap_or(0), + funding_txid: other.funding_txid, + funding_output: other.funding_output, + connected: other.connected, + state, + short_channel_id: other.short_channel_id, + channel_id: other.channel_id, + } + } +} + + From 741b3845ca7ce9459bdb4c045746eaa690f8506f Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 12:46:27 +0100 Subject: [PATCH 03/16] gl-sdk: Regenerate Python bindings with new node methods Regenerate UniFFI Python bindings to include the new node information methods and their response types (GetInfoResponse, ListPeersResponse, ListPeerChannelsResponse, ListFundsResponse) as Python dataclasses. --- libs/gl-sdk/bindings/glsdk.py | 1055 ++++++++++++++++ libs/gl-sdk/glsdk/glsdk.py | 2174 +++++++++++++++++++++++++++++---- 2 files changed, 2971 insertions(+), 258 deletions(-) diff --git a/libs/gl-sdk/bindings/glsdk.py b/libs/gl-sdk/bindings/glsdk.py index 22c6c1b12..39d1e291b 100644 --- a/libs/gl-sdk/bindings/glsdk.py +++ b/libs/gl-sdk/bindings/glsdk.py @@ -464,6 +464,14 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_handle_stop() != 36432: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_get_info() != 39460: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_list_funds() != 21692: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_list_peer_channels() != 35210: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_list_peers() != 29567: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_node_onchain_receive() != 21676: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_node_onchain_send() != 51884: @@ -648,6 +656,26 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_constructor_node_new.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_get_info.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_get_info.restype = _UniffiRustBuffer +_UniffiLib.uniffi_glsdk_fn_method_node_list_funds.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_list_funds.restype = _UniffiRustBuffer +_UniffiLib.uniffi_glsdk_fn_method_node_list_peer_channels.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_list_peer_channels.restype = _UniffiRustBuffer +_UniffiLib.uniffi_glsdk_fn_method_node_list_peers.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_list_peers.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -1053,6 +1081,18 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_glsdk_checksum_method_handle_stop.argtypes = ( ) _UniffiLib.uniffi_glsdk_checksum_method_handle_stop.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_get_info.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_get_info.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_list_funds.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_list_funds.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_list_peer_channels.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_list_peer_channels.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_list_peers.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_list_peers.restype = ctypes.c_uint16 _UniffiLib.uniffi_glsdk_checksum_method_node_onchain_receive.argtypes = ( ) _UniffiLib.uniffi_glsdk_checksum_method_node_onchain_receive.restype = ctypes.c_uint16 @@ -1105,6 +1145,19 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): # Public interface members begin here. +class _UniffiConverterUInt32(_UniffiConverterPrimitiveInt): + CLASS_NAME = "u32" + VALUE_MIN = 0 + VALUE_MAX = 2**32 + + @staticmethod + def read(buf): + return buf.read_u32() + + @staticmethod + def write(value, buf): + buf.write_u32(value) + class _UniffiConverterUInt64(_UniffiConverterPrimitiveInt): CLASS_NAME = "u64" VALUE_MIN = 0 @@ -1118,6 +1171,27 @@ def read(buf): def write(value, buf): buf.write_u64(value) +class _UniffiConverterBool: + @classmethod + def check_lower(cls, value): + return not not value + + @classmethod + def lower(cls, value): + return 1 if value else 0 + + @staticmethod + def lift(value): + return value != 0 + + @classmethod + def read(cls, buf): + return cls.lift(buf.read_u8()) + + @classmethod + def write(cls, value, buf): + buf.write_u8(value) + class _UniffiConverterString: @staticmethod def check_lower(value): @@ -1189,6 +1263,644 @@ def write(value, buf): +class FundChannel: + peer_id: "bytes" + our_amount_msat: "int" + amount_msat: "int" + funding_txid: "bytes" + funding_output: "int" + connected: "bool" + state: "ChannelState" + short_channel_id: "typing.Optional[str]" + channel_id: "typing.Optional[bytes]" + def __init__(self, *, peer_id: "bytes", our_amount_msat: "int", amount_msat: "int", funding_txid: "bytes", funding_output: "int", connected: "bool", state: "ChannelState", short_channel_id: "typing.Optional[str]", channel_id: "typing.Optional[bytes]"): + self.peer_id = peer_id + self.our_amount_msat = our_amount_msat + self.amount_msat = amount_msat + self.funding_txid = funding_txid + self.funding_output = funding_output + self.connected = connected + self.state = state + self.short_channel_id = short_channel_id + self.channel_id = channel_id + + def __str__(self): + return "FundChannel(peer_id={}, our_amount_msat={}, amount_msat={}, funding_txid={}, funding_output={}, connected={}, state={}, short_channel_id={}, channel_id={})".format(self.peer_id, self.our_amount_msat, self.amount_msat, self.funding_txid, self.funding_output, self.connected, self.state, self.short_channel_id, self.channel_id) + + def __eq__(self, other): + if self.peer_id != other.peer_id: + return False + if self.our_amount_msat != other.our_amount_msat: + return False + if self.amount_msat != other.amount_msat: + return False + if self.funding_txid != other.funding_txid: + return False + if self.funding_output != other.funding_output: + return False + if self.connected != other.connected: + return False + if self.state != other.state: + return False + if self.short_channel_id != other.short_channel_id: + return False + if self.channel_id != other.channel_id: + return False + return True + +class _UniffiConverterTypeFundChannel(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return FundChannel( + peer_id=_UniffiConverterBytes.read(buf), + our_amount_msat=_UniffiConverterUInt64.read(buf), + amount_msat=_UniffiConverterUInt64.read(buf), + funding_txid=_UniffiConverterBytes.read(buf), + funding_output=_UniffiConverterUInt32.read(buf), + connected=_UniffiConverterBool.read(buf), + state=_UniffiConverterTypeChannelState.read(buf), + short_channel_id=_UniffiConverterOptionalString.read(buf), + channel_id=_UniffiConverterOptionalBytes.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.peer_id) + _UniffiConverterUInt64.check_lower(value.our_amount_msat) + _UniffiConverterUInt64.check_lower(value.amount_msat) + _UniffiConverterBytes.check_lower(value.funding_txid) + _UniffiConverterUInt32.check_lower(value.funding_output) + _UniffiConverterBool.check_lower(value.connected) + _UniffiConverterTypeChannelState.check_lower(value.state) + _UniffiConverterOptionalString.check_lower(value.short_channel_id) + _UniffiConverterOptionalBytes.check_lower(value.channel_id) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.peer_id, buf) + _UniffiConverterUInt64.write(value.our_amount_msat, buf) + _UniffiConverterUInt64.write(value.amount_msat, buf) + _UniffiConverterBytes.write(value.funding_txid, buf) + _UniffiConverterUInt32.write(value.funding_output, buf) + _UniffiConverterBool.write(value.connected, buf) + _UniffiConverterTypeChannelState.write(value.state, buf) + _UniffiConverterOptionalString.write(value.short_channel_id, buf) + _UniffiConverterOptionalBytes.write(value.channel_id, buf) + + +class FundOutput: + txid: "bytes" + output: "int" + amount_msat: "int" + status: "OutputStatus" + address: "typing.Optional[str]" + blockheight: "typing.Optional[int]" + def __init__(self, *, txid: "bytes", output: "int", amount_msat: "int", status: "OutputStatus", address: "typing.Optional[str]", blockheight: "typing.Optional[int]"): + self.txid = txid + self.output = output + self.amount_msat = amount_msat + self.status = status + self.address = address + self.blockheight = blockheight + + def __str__(self): + return "FundOutput(txid={}, output={}, amount_msat={}, status={}, address={}, blockheight={})".format(self.txid, self.output, self.amount_msat, self.status, self.address, self.blockheight) + + def __eq__(self, other): + if self.txid != other.txid: + return False + if self.output != other.output: + return False + if self.amount_msat != other.amount_msat: + return False + if self.status != other.status: + return False + if self.address != other.address: + return False + if self.blockheight != other.blockheight: + return False + return True + +class _UniffiConverterTypeFundOutput(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return FundOutput( + txid=_UniffiConverterBytes.read(buf), + output=_UniffiConverterUInt32.read(buf), + amount_msat=_UniffiConverterUInt64.read(buf), + status=_UniffiConverterTypeOutputStatus.read(buf), + address=_UniffiConverterOptionalString.read(buf), + blockheight=_UniffiConverterOptionalUInt32.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.txid) + _UniffiConverterUInt32.check_lower(value.output) + _UniffiConverterUInt64.check_lower(value.amount_msat) + _UniffiConverterTypeOutputStatus.check_lower(value.status) + _UniffiConverterOptionalString.check_lower(value.address) + _UniffiConverterOptionalUInt32.check_lower(value.blockheight) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.txid, buf) + _UniffiConverterUInt32.write(value.output, buf) + _UniffiConverterUInt64.write(value.amount_msat, buf) + _UniffiConverterTypeOutputStatus.write(value.status, buf) + _UniffiConverterOptionalString.write(value.address, buf) + _UniffiConverterOptionalUInt32.write(value.blockheight, buf) + + +class GetInfoResponse: + id: "bytes" + alias: "typing.Optional[str]" + color: "bytes" + num_peers: "int" + num_pending_channels: "int" + num_active_channels: "int" + num_inactive_channels: "int" + version: "str" + lightning_dir: "str" + blockheight: "int" + network: "str" + fees_collected_msat: "int" + def __init__(self, *, id: "bytes", alias: "typing.Optional[str]", color: "bytes", num_peers: "int", num_pending_channels: "int", num_active_channels: "int", num_inactive_channels: "int", version: "str", lightning_dir: "str", blockheight: "int", network: "str", fees_collected_msat: "int"): + self.id = id + self.alias = alias + self.color = color + self.num_peers = num_peers + self.num_pending_channels = num_pending_channels + self.num_active_channels = num_active_channels + self.num_inactive_channels = num_inactive_channels + self.version = version + self.lightning_dir = lightning_dir + self.blockheight = blockheight + self.network = network + self.fees_collected_msat = fees_collected_msat + + def __str__(self): + return "GetInfoResponse(id={}, alias={}, color={}, num_peers={}, num_pending_channels={}, num_active_channels={}, num_inactive_channels={}, version={}, lightning_dir={}, blockheight={}, network={}, fees_collected_msat={})".format(self.id, self.alias, self.color, self.num_peers, self.num_pending_channels, self.num_active_channels, self.num_inactive_channels, self.version, self.lightning_dir, self.blockheight, self.network, self.fees_collected_msat) + + def __eq__(self, other): + if self.id != other.id: + return False + if self.alias != other.alias: + return False + if self.color != other.color: + return False + if self.num_peers != other.num_peers: + return False + if self.num_pending_channels != other.num_pending_channels: + return False + if self.num_active_channels != other.num_active_channels: + return False + if self.num_inactive_channels != other.num_inactive_channels: + return False + if self.version != other.version: + return False + if self.lightning_dir != other.lightning_dir: + return False + if self.blockheight != other.blockheight: + return False + if self.network != other.network: + return False + if self.fees_collected_msat != other.fees_collected_msat: + return False + return True + +class _UniffiConverterTypeGetInfoResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return GetInfoResponse( + id=_UniffiConverterBytes.read(buf), + alias=_UniffiConverterOptionalString.read(buf), + color=_UniffiConverterBytes.read(buf), + num_peers=_UniffiConverterUInt32.read(buf), + num_pending_channels=_UniffiConverterUInt32.read(buf), + num_active_channels=_UniffiConverterUInt32.read(buf), + num_inactive_channels=_UniffiConverterUInt32.read(buf), + version=_UniffiConverterString.read(buf), + lightning_dir=_UniffiConverterString.read(buf), + blockheight=_UniffiConverterUInt32.read(buf), + network=_UniffiConverterString.read(buf), + fees_collected_msat=_UniffiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.id) + _UniffiConverterOptionalString.check_lower(value.alias) + _UniffiConverterBytes.check_lower(value.color) + _UniffiConverterUInt32.check_lower(value.num_peers) + _UniffiConverterUInt32.check_lower(value.num_pending_channels) + _UniffiConverterUInt32.check_lower(value.num_active_channels) + _UniffiConverterUInt32.check_lower(value.num_inactive_channels) + _UniffiConverterString.check_lower(value.version) + _UniffiConverterString.check_lower(value.lightning_dir) + _UniffiConverterUInt32.check_lower(value.blockheight) + _UniffiConverterString.check_lower(value.network) + _UniffiConverterUInt64.check_lower(value.fees_collected_msat) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.id, buf) + _UniffiConverterOptionalString.write(value.alias, buf) + _UniffiConverterBytes.write(value.color, buf) + _UniffiConverterUInt32.write(value.num_peers, buf) + _UniffiConverterUInt32.write(value.num_pending_channels, buf) + _UniffiConverterUInt32.write(value.num_active_channels, buf) + _UniffiConverterUInt32.write(value.num_inactive_channels, buf) + _UniffiConverterString.write(value.version, buf) + _UniffiConverterString.write(value.lightning_dir, buf) + _UniffiConverterUInt32.write(value.blockheight, buf) + _UniffiConverterString.write(value.network, buf) + _UniffiConverterUInt64.write(value.fees_collected_msat, buf) + + +class ListFundsResponse: + outputs: "typing.List[FundOutput]" + channels: "typing.List[FundChannel]" + def __init__(self, *, outputs: "typing.List[FundOutput]", channels: "typing.List[FundChannel]"): + self.outputs = outputs + self.channels = channels + + def __str__(self): + return "ListFundsResponse(outputs={}, channels={})".format(self.outputs, self.channels) + + def __eq__(self, other): + if self.outputs != other.outputs: + return False + if self.channels != other.channels: + return False + return True + +class _UniffiConverterTypeListFundsResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ListFundsResponse( + outputs=_UniffiConverterSequenceTypeFundOutput.read(buf), + channels=_UniffiConverterSequenceTypeFundChannel.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterSequenceTypeFundOutput.check_lower(value.outputs) + _UniffiConverterSequenceTypeFundChannel.check_lower(value.channels) + + @staticmethod + def write(value, buf): + _UniffiConverterSequenceTypeFundOutput.write(value.outputs, buf) + _UniffiConverterSequenceTypeFundChannel.write(value.channels, buf) + + +class ListPeerChannelsResponse: + channels: "typing.List[PeerChannel]" + def __init__(self, *, channels: "typing.List[PeerChannel]"): + self.channels = channels + + def __str__(self): + return "ListPeerChannelsResponse(channels={})".format(self.channels) + + def __eq__(self, other): + if self.channels != other.channels: + return False + return True + +class _UniffiConverterTypeListPeerChannelsResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ListPeerChannelsResponse( + channels=_UniffiConverterSequenceTypePeerChannel.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterSequenceTypePeerChannel.check_lower(value.channels) + + @staticmethod + def write(value, buf): + _UniffiConverterSequenceTypePeerChannel.write(value.channels, buf) + + +class ListPeersResponse: + peers: "typing.List[Peer]" + def __init__(self, *, peers: "typing.List[Peer]"): + self.peers = peers + + def __str__(self): + return "ListPeersResponse(peers={})".format(self.peers) + + def __eq__(self, other): + if self.peers != other.peers: + return False + return True + +class _UniffiConverterTypeListPeersResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ListPeersResponse( + peers=_UniffiConverterSequenceTypePeer.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterSequenceTypePeer.check_lower(value.peers) + + @staticmethod + def write(value, buf): + _UniffiConverterSequenceTypePeer.write(value.peers, buf) + + +class Peer: + id: "bytes" + connected: "bool" + num_channels: "typing.Optional[int]" + netaddr: "typing.List[str]" + remote_addr: "typing.Optional[str]" + features: "typing.Optional[bytes]" + def __init__(self, *, id: "bytes", connected: "bool", num_channels: "typing.Optional[int]", netaddr: "typing.List[str]", remote_addr: "typing.Optional[str]", features: "typing.Optional[bytes]"): + self.id = id + self.connected = connected + self.num_channels = num_channels + self.netaddr = netaddr + self.remote_addr = remote_addr + self.features = features + + def __str__(self): + return "Peer(id={}, connected={}, num_channels={}, netaddr={}, remote_addr={}, features={})".format(self.id, self.connected, self.num_channels, self.netaddr, self.remote_addr, self.features) + + def __eq__(self, other): + if self.id != other.id: + return False + if self.connected != other.connected: + return False + if self.num_channels != other.num_channels: + return False + if self.netaddr != other.netaddr: + return False + if self.remote_addr != other.remote_addr: + return False + if self.features != other.features: + return False + return True + +class _UniffiConverterTypePeer(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Peer( + id=_UniffiConverterBytes.read(buf), + connected=_UniffiConverterBool.read(buf), + num_channels=_UniffiConverterOptionalUInt32.read(buf), + netaddr=_UniffiConverterSequenceString.read(buf), + remote_addr=_UniffiConverterOptionalString.read(buf), + features=_UniffiConverterOptionalBytes.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.id) + _UniffiConverterBool.check_lower(value.connected) + _UniffiConverterOptionalUInt32.check_lower(value.num_channels) + _UniffiConverterSequenceString.check_lower(value.netaddr) + _UniffiConverterOptionalString.check_lower(value.remote_addr) + _UniffiConverterOptionalBytes.check_lower(value.features) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.id, buf) + _UniffiConverterBool.write(value.connected, buf) + _UniffiConverterOptionalUInt32.write(value.num_channels, buf) + _UniffiConverterSequenceString.write(value.netaddr, buf) + _UniffiConverterOptionalString.write(value.remote_addr, buf) + _UniffiConverterOptionalBytes.write(value.features, buf) + + +class PeerChannel: + peer_id: "bytes" + peer_connected: "bool" + state: "ChannelState" + short_channel_id: "typing.Optional[str]" + channel_id: "typing.Optional[bytes]" + funding_txid: "typing.Optional[bytes]" + funding_outnum: "typing.Optional[int]" + to_us_msat: "typing.Optional[int]" + total_msat: "typing.Optional[int]" + spendable_msat: "typing.Optional[int]" + receivable_msat: "typing.Optional[int]" + def __init__(self, *, peer_id: "bytes", peer_connected: "bool", state: "ChannelState", short_channel_id: "typing.Optional[str]", channel_id: "typing.Optional[bytes]", funding_txid: "typing.Optional[bytes]", funding_outnum: "typing.Optional[int]", to_us_msat: "typing.Optional[int]", total_msat: "typing.Optional[int]", spendable_msat: "typing.Optional[int]", receivable_msat: "typing.Optional[int]"): + self.peer_id = peer_id + self.peer_connected = peer_connected + self.state = state + self.short_channel_id = short_channel_id + self.channel_id = channel_id + self.funding_txid = funding_txid + self.funding_outnum = funding_outnum + self.to_us_msat = to_us_msat + self.total_msat = total_msat + self.spendable_msat = spendable_msat + self.receivable_msat = receivable_msat + + def __str__(self): + return "PeerChannel(peer_id={}, peer_connected={}, state={}, short_channel_id={}, channel_id={}, funding_txid={}, funding_outnum={}, to_us_msat={}, total_msat={}, spendable_msat={}, receivable_msat={})".format(self.peer_id, self.peer_connected, self.state, self.short_channel_id, self.channel_id, self.funding_txid, self.funding_outnum, self.to_us_msat, self.total_msat, self.spendable_msat, self.receivable_msat) + + def __eq__(self, other): + if self.peer_id != other.peer_id: + return False + if self.peer_connected != other.peer_connected: + return False + if self.state != other.state: + return False + if self.short_channel_id != other.short_channel_id: + return False + if self.channel_id != other.channel_id: + return False + if self.funding_txid != other.funding_txid: + return False + if self.funding_outnum != other.funding_outnum: + return False + if self.to_us_msat != other.to_us_msat: + return False + if self.total_msat != other.total_msat: + return False + if self.spendable_msat != other.spendable_msat: + return False + if self.receivable_msat != other.receivable_msat: + return False + return True + +class _UniffiConverterTypePeerChannel(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PeerChannel( + peer_id=_UniffiConverterBytes.read(buf), + peer_connected=_UniffiConverterBool.read(buf), + state=_UniffiConverterTypeChannelState.read(buf), + short_channel_id=_UniffiConverterOptionalString.read(buf), + channel_id=_UniffiConverterOptionalBytes.read(buf), + funding_txid=_UniffiConverterOptionalBytes.read(buf), + funding_outnum=_UniffiConverterOptionalUInt32.read(buf), + to_us_msat=_UniffiConverterOptionalUInt64.read(buf), + total_msat=_UniffiConverterOptionalUInt64.read(buf), + spendable_msat=_UniffiConverterOptionalUInt64.read(buf), + receivable_msat=_UniffiConverterOptionalUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.peer_id) + _UniffiConverterBool.check_lower(value.peer_connected) + _UniffiConverterTypeChannelState.check_lower(value.state) + _UniffiConverterOptionalString.check_lower(value.short_channel_id) + _UniffiConverterOptionalBytes.check_lower(value.channel_id) + _UniffiConverterOptionalBytes.check_lower(value.funding_txid) + _UniffiConverterOptionalUInt32.check_lower(value.funding_outnum) + _UniffiConverterOptionalUInt64.check_lower(value.to_us_msat) + _UniffiConverterOptionalUInt64.check_lower(value.total_msat) + _UniffiConverterOptionalUInt64.check_lower(value.spendable_msat) + _UniffiConverterOptionalUInt64.check_lower(value.receivable_msat) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.peer_id, buf) + _UniffiConverterBool.write(value.peer_connected, buf) + _UniffiConverterTypeChannelState.write(value.state, buf) + _UniffiConverterOptionalString.write(value.short_channel_id, buf) + _UniffiConverterOptionalBytes.write(value.channel_id, buf) + _UniffiConverterOptionalBytes.write(value.funding_txid, buf) + _UniffiConverterOptionalUInt32.write(value.funding_outnum, buf) + _UniffiConverterOptionalUInt64.write(value.to_us_msat, buf) + _UniffiConverterOptionalUInt64.write(value.total_msat, buf) + _UniffiConverterOptionalUInt64.write(value.spendable_msat, buf) + _UniffiConverterOptionalUInt64.write(value.receivable_msat, buf) + + + + + +class ChannelState(enum.Enum): + OPENINGD = 0 + + CHANNELD_AWAITING_LOCKIN = 1 + + CHANNELD_NORMAL = 2 + + CHANNELD_SHUTTING_DOWN = 3 + + CLOSINGD_SIGEXCHANGE = 4 + + CLOSINGD_COMPLETE = 5 + + AWAITING_UNILATERAL = 6 + + FUNDING_SPEND_SEEN = 7 + + ONCHAIN = 8 + + DUALOPEND_OPEN_INIT = 9 + + DUALOPEND_AWAITING_LOCKIN = 10 + + DUALOPEND_OPEN_COMMITTED = 11 + + DUALOPEND_OPEN_COMMIT_READY = 12 + + + +class _UniffiConverterTypeChannelState(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return ChannelState.OPENINGD + if variant == 2: + return ChannelState.CHANNELD_AWAITING_LOCKIN + if variant == 3: + return ChannelState.CHANNELD_NORMAL + if variant == 4: + return ChannelState.CHANNELD_SHUTTING_DOWN + if variant == 5: + return ChannelState.CLOSINGD_SIGEXCHANGE + if variant == 6: + return ChannelState.CLOSINGD_COMPLETE + if variant == 7: + return ChannelState.AWAITING_UNILATERAL + if variant == 8: + return ChannelState.FUNDING_SPEND_SEEN + if variant == 9: + return ChannelState.ONCHAIN + if variant == 10: + return ChannelState.DUALOPEND_OPEN_INIT + if variant == 11: + return ChannelState.DUALOPEND_AWAITING_LOCKIN + if variant == 12: + return ChannelState.DUALOPEND_OPEN_COMMITTED + if variant == 13: + return ChannelState.DUALOPEND_OPEN_COMMIT_READY + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == ChannelState.OPENINGD: + return + if value == ChannelState.CHANNELD_AWAITING_LOCKIN: + return + if value == ChannelState.CHANNELD_NORMAL: + return + if value == ChannelState.CHANNELD_SHUTTING_DOWN: + return + if value == ChannelState.CLOSINGD_SIGEXCHANGE: + return + if value == ChannelState.CLOSINGD_COMPLETE: + return + if value == ChannelState.AWAITING_UNILATERAL: + return + if value == ChannelState.FUNDING_SPEND_SEEN: + return + if value == ChannelState.ONCHAIN: + return + if value == ChannelState.DUALOPEND_OPEN_INIT: + return + if value == ChannelState.DUALOPEND_AWAITING_LOCKIN: + return + if value == ChannelState.DUALOPEND_OPEN_COMMITTED: + return + if value == ChannelState.DUALOPEND_OPEN_COMMIT_READY: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == ChannelState.OPENINGD: + buf.write_i32(1) + if value == ChannelState.CHANNELD_AWAITING_LOCKIN: + buf.write_i32(2) + if value == ChannelState.CHANNELD_NORMAL: + buf.write_i32(3) + if value == ChannelState.CHANNELD_SHUTTING_DOWN: + buf.write_i32(4) + if value == ChannelState.CLOSINGD_SIGEXCHANGE: + buf.write_i32(5) + if value == ChannelState.CLOSINGD_COMPLETE: + buf.write_i32(6) + if value == ChannelState.AWAITING_UNILATERAL: + buf.write_i32(7) + if value == ChannelState.FUNDING_SPEND_SEEN: + buf.write_i32(8) + if value == ChannelState.ONCHAIN: + buf.write_i32(9) + if value == ChannelState.DUALOPEND_OPEN_INIT: + buf.write_i32(10) + if value == ChannelState.DUALOPEND_AWAITING_LOCKIN: + buf.write_i32(11) + if value == ChannelState.DUALOPEND_OPEN_COMMITTED: + buf.write_i32(12) + if value == ChannelState.DUALOPEND_OPEN_COMMIT_READY: + buf.write_i32(13) + + + + # Error # We want to define each variant as a nested class that's also a subclass, # which is tricky in Python. To accomplish this we're going to create each @@ -1418,6 +2130,60 @@ def write(value, buf): +class OutputStatus(enum.Enum): + UNCONFIRMED = 0 + + CONFIRMED = 1 + + SPENT = 2 + + IMMATURE = 3 + + + +class _UniffiConverterTypeOutputStatus(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return OutputStatus.UNCONFIRMED + if variant == 2: + return OutputStatus.CONFIRMED + if variant == 3: + return OutputStatus.SPENT + if variant == 4: + return OutputStatus.IMMATURE + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == OutputStatus.UNCONFIRMED: + return + if value == OutputStatus.CONFIRMED: + return + if value == OutputStatus.SPENT: + return + if value == OutputStatus.IMMATURE: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == OutputStatus.UNCONFIRMED: + buf.write_i32(1) + if value == OutputStatus.CONFIRMED: + buf.write_i32(2) + if value == OutputStatus.SPENT: + buf.write_i32(3) + if value == OutputStatus.IMMATURE: + buf.write_i32(4) + + + + + + + class PayStatus(enum.Enum): COMPLETE = 0 @@ -1462,6 +2228,33 @@ def write(value, buf): +class _UniffiConverterOptionalUInt32(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterUInt32.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterUInt32.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterUInt32.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + class _UniffiConverterOptionalUInt64(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): @@ -1514,6 +2307,158 @@ def read(cls, buf): else: raise InternalError("Unexpected flag byte for optional type") + + +class _UniffiConverterOptionalBytes(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterBytes.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterBytes.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterBytes.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + +class _UniffiConverterSequenceString(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterString.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterString.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterString.read(buf) for i in range(count) + ] + + + +class _UniffiConverterSequenceTypeFundChannel(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypeFundChannel.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypeFundChannel.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypeFundChannel.read(buf) for i in range(count) + ] + + + +class _UniffiConverterSequenceTypeFundOutput(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypeFundOutput.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypeFundOutput.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypeFundOutput.read(buf) for i in range(count) + ] + + + +class _UniffiConverterSequenceTypePeer(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypePeer.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypePeer.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypePeer.read(buf) for i in range(count) + ] + + + +class _UniffiConverterSequenceTypePeerChannel(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypePeerChannel.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypePeerChannel.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypePeerChannel.read(buf) for i in range(count) + ] + # objects. class CredentialsProtocol(typing.Protocol): """ @@ -1689,6 +2634,42 @@ class NodeProtocol(typing.Protocol): cloud. It is the main entrypoint to interact with the node. """ + def get_info(self, ): + """ + Get information about the node. + + Returns basic information about the node including its ID, + alias, network, and channel counts. + """ + + raise NotImplementedError + def list_funds(self, ): + """ + List all funds available to the node. + + Returns information about on-chain outputs and channel funds + that are available or pending. + """ + + raise NotImplementedError + def list_peer_channels(self, ): + """ + List all channels with peers. + + Returns detailed information about all channels including their + state, capacity, and balances. + """ + + raise NotImplementedError + def list_peers(self, ): + """ + List all peers connected to this node. + + Returns information about all peers including their connection + status. + """ + + raise NotImplementedError def onchain_receive(self, ): raise NotImplementedError def onchain_send(self, destination: "str",amount_or_all: "str"): @@ -1749,6 +2730,70 @@ def _make_instance_(cls, pointer): return inst + def get_info(self, ) -> "GetInfoResponse": + """ + Get information about the node. + + Returns basic information about the node including its ID, + alias, network, and channel counts. + """ + + return _UniffiConverterTypeGetInfoResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_get_info,self._uniffi_clone_pointer(),) + ) + + + + + + def list_funds(self, ) -> "ListFundsResponse": + """ + List all funds available to the node. + + Returns information about on-chain outputs and channel funds + that are available or pending. + """ + + return _UniffiConverterTypeListFundsResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_list_funds,self._uniffi_clone_pointer(),) + ) + + + + + + def list_peer_channels(self, ) -> "ListPeerChannelsResponse": + """ + List all channels with peers. + + Returns detailed information about all channels including their + state, capacity, and balances. + """ + + return _UniffiConverterTypeListPeerChannelsResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_list_peer_channels,self._uniffi_clone_pointer(),) + ) + + + + + + def list_peers(self, ) -> "ListPeersResponse": + """ + List all peers connected to this node. + + Returns information about all peers including their connection + status. + """ + + return _UniffiConverterTypeListPeersResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_list_peers,self._uniffi_clone_pointer(),) + ) + + + + + def onchain_receive(self, ) -> "OnchainReceiveResponse": return _UniffiConverterTypeOnchainReceiveResponse.lift( _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive,self._uniffi_clone_pointer(),) @@ -2274,9 +3319,19 @@ def write(cls, value: SignerProtocol, buf: _UniffiRustBuffer): __all__ = [ "InternalError", + "ChannelState", "Error", "Network", + "OutputStatus", "PayStatus", + "FundChannel", + "FundOutput", + "GetInfoResponse", + "ListFundsResponse", + "ListPeerChannelsResponse", + "ListPeersResponse", + "Peer", + "PeerChannel", "Credentials", "Handle", "Node", diff --git a/libs/gl-sdk/glsdk/glsdk.py b/libs/gl-sdk/glsdk/glsdk.py index 78a9bef28..39d1e291b 100644 --- a/libs/gl-sdk/glsdk/glsdk.py +++ b/libs/gl-sdk/glsdk/glsdk.py @@ -460,8 +460,28 @@ def _uniffi_check_contract_api_version(lib): raise InternalError("UniFFI contract version mismatch: try cleaning and rebuilding your project") def _uniffi_check_api_checksums(lib): + if lib.uniffi_glsdk_checksum_method_credentials_save() != 26677: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_handle_stop() != 36432: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_get_info() != 39460: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_list_funds() != 21692: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_list_peer_channels() != 35210: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_list_peers() != 29567: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_onchain_receive() != 21676: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_onchain_send() != 51884: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_receive() != 24722: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_send() != 30141: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_stop() != 20186: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_scheduler_recover() != 55514: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_scheduler_register() != 20821: @@ -601,6 +621,11 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_constructor_credentials_load.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_credentials_save.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_credentials_save.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_clone_handle.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -631,6 +656,88 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_constructor_node_new.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_get_info.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_get_info.restype = _UniffiRustBuffer +_UniffiLib.uniffi_glsdk_fn_method_node_list_funds.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_list_funds.restype = _UniffiRustBuffer +_UniffiLib.uniffi_glsdk_fn_method_node_list_peer_channels.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_list_peer_channels.restype = _UniffiRustBuffer +_UniffiLib.uniffi_glsdk_fn_method_node_list_peers.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_list_peers.restype = _UniffiRustBuffer +_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_receive.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, + _UniffiRustBuffer, + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_receive.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_send.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_send.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_stop.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_stop.restype = None +_UniffiLib.uniffi_glsdk_fn_clone_onchainreceiveresponse.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_clone_onchainreceiveresponse.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_free_onchainreceiveresponse.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_free_onchainreceiveresponse.restype = None +_UniffiLib.uniffi_glsdk_fn_clone_onchainsendresponse.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_clone_onchainsendresponse.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_free_onchainsendresponse.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_free_onchainsendresponse.restype = None +_UniffiLib.uniffi_glsdk_fn_clone_receiveresponse.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_clone_receiveresponse.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_free_receiveresponse.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_free_receiveresponse.restype = None _UniffiLib.uniffi_glsdk_fn_clone_scheduler.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -659,6 +766,16 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_method_scheduler_register.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_clone_sendresponse.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_clone_sendresponse.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_free_sendresponse.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_free_sendresponse.restype = None _UniffiLib.uniffi_glsdk_fn_clone_signer.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -958,9 +1075,39 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.ffi_glsdk_rust_future_complete_void.restype = None +_UniffiLib.uniffi_glsdk_checksum_method_credentials_save.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_credentials_save.restype = ctypes.c_uint16 _UniffiLib.uniffi_glsdk_checksum_method_handle_stop.argtypes = ( ) _UniffiLib.uniffi_glsdk_checksum_method_handle_stop.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_get_info.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_get_info.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_list_funds.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_list_funds.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_list_peer_channels.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_list_peer_channels.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_list_peers.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_list_peers.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_onchain_receive.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_onchain_receive.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_onchain_send.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_onchain_send.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_receive.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_receive.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_send.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_send.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_stop.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_stop.restype = ctypes.c_uint16 _UniffiLib.uniffi_glsdk_checksum_method_scheduler_recover.argtypes = ( ) _UniffiLib.uniffi_glsdk_checksum_method_scheduler_recover.restype = ctypes.c_uint16 @@ -998,6 +1145,53 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): # Public interface members begin here. +class _UniffiConverterUInt32(_UniffiConverterPrimitiveInt): + CLASS_NAME = "u32" + VALUE_MIN = 0 + VALUE_MAX = 2**32 + + @staticmethod + def read(buf): + return buf.read_u32() + + @staticmethod + def write(value, buf): + buf.write_u32(value) + +class _UniffiConverterUInt64(_UniffiConverterPrimitiveInt): + CLASS_NAME = "u64" + VALUE_MIN = 0 + VALUE_MAX = 2**64 + + @staticmethod + def read(buf): + return buf.read_u64() + + @staticmethod + def write(value, buf): + buf.write_u64(value) + +class _UniffiConverterBool: + @classmethod + def check_lower(cls, value): + return not not value + + @classmethod + def lower(cls, value): + return 1 if value else 0 + + @staticmethod + def lift(value): + return value != 0 + + @classmethod + def read(cls, buf): + return cls.lift(buf.read_u8()) + + @classmethod + def write(cls, value, buf): + buf.write_u8(value) + class _UniffiConverterString: @staticmethod def check_lower(value): @@ -1061,224 +1255,1659 @@ def write(value, buf): -# Error -# We want to define each variant as a nested class that's also a subclass, -# which is tricky in Python. To accomplish this we're going to create each -# class separately, then manually add the child classes to the base class's -# __dict__. All of this happens in dummy class to avoid polluting the module -# namespace. -class Error(Exception): - pass - -_UniffiTempError = Error -class Error: # type: ignore - class DuplicateNode(_UniffiTempError): - def __init__(self, *values): - if len(values) != 1: - raise TypeError(f"Expected 1 arguments, found {len(values)}") - if not isinstance(values[0], str): - raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") - super().__init__(", ".join(map(repr, values))) - self._values = values - def __getitem__(self, index): - return self._values[index] - def __repr__(self): - return "Error.DuplicateNode({})".format(str(self)) - _UniffiTempError.DuplicateNode = DuplicateNode # type: ignore - class NoSuchNode(_UniffiTempError): - def __init__(self, *values): - if len(values) != 1: - raise TypeError(f"Expected 1 arguments, found {len(values)}") - if not isinstance(values[0], str): - raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") - super().__init__(", ".join(map(repr, values))) - self._values = values - def __getitem__(self, index): - return self._values[index] - def __repr__(self): - return "Error.NoSuchNode({})".format(str(self)) - _UniffiTempError.NoSuchNode = NoSuchNode # type: ignore - class UnparseableCreds(_UniffiTempError): - def __init__(self): - pass - def __repr__(self): - return "Error.UnparseableCreds({})".format(str(self)) - _UniffiTempError.UnparseableCreds = UnparseableCreds # type: ignore - class PhraseCorrupted(_UniffiTempError): - def __init__(self): - pass - def __repr__(self): - return "Error.PhraseCorrupted({})".format(str(self)) - _UniffiTempError.PhraseCorrupted = PhraseCorrupted # type: ignore - class Other(_UniffiTempError): - def __init__(self, *values): - if len(values) != 1: - raise TypeError(f"Expected 1 arguments, found {len(values)}") - if not isinstance(values[0], str): - raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") - super().__init__(", ".join(map(repr, values))) - self._values = values - def __getitem__(self, index): - return self._values[index] +class FundChannel: + peer_id: "bytes" + our_amount_msat: "int" + amount_msat: "int" + funding_txid: "bytes" + funding_output: "int" + connected: "bool" + state: "ChannelState" + short_channel_id: "typing.Optional[str]" + channel_id: "typing.Optional[bytes]" + def __init__(self, *, peer_id: "bytes", our_amount_msat: "int", amount_msat: "int", funding_txid: "bytes", funding_output: "int", connected: "bool", state: "ChannelState", short_channel_id: "typing.Optional[str]", channel_id: "typing.Optional[bytes]"): + self.peer_id = peer_id + self.our_amount_msat = our_amount_msat + self.amount_msat = amount_msat + self.funding_txid = funding_txid + self.funding_output = funding_output + self.connected = connected + self.state = state + self.short_channel_id = short_channel_id + self.channel_id = channel_id - def __repr__(self): - return "Error.Other({})".format(str(self)) - _UniffiTempError.Other = Other # type: ignore + def __str__(self): + return "FundChannel(peer_id={}, our_amount_msat={}, amount_msat={}, funding_txid={}, funding_output={}, connected={}, state={}, short_channel_id={}, channel_id={})".format(self.peer_id, self.our_amount_msat, self.amount_msat, self.funding_txid, self.funding_output, self.connected, self.state, self.short_channel_id, self.channel_id) + + def __eq__(self, other): + if self.peer_id != other.peer_id: + return False + if self.our_amount_msat != other.our_amount_msat: + return False + if self.amount_msat != other.amount_msat: + return False + if self.funding_txid != other.funding_txid: + return False + if self.funding_output != other.funding_output: + return False + if self.connected != other.connected: + return False + if self.state != other.state: + return False + if self.short_channel_id != other.short_channel_id: + return False + if self.channel_id != other.channel_id: + return False + return True + +class _UniffiConverterTypeFundChannel(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return FundChannel( + peer_id=_UniffiConverterBytes.read(buf), + our_amount_msat=_UniffiConverterUInt64.read(buf), + amount_msat=_UniffiConverterUInt64.read(buf), + funding_txid=_UniffiConverterBytes.read(buf), + funding_output=_UniffiConverterUInt32.read(buf), + connected=_UniffiConverterBool.read(buf), + state=_UniffiConverterTypeChannelState.read(buf), + short_channel_id=_UniffiConverterOptionalString.read(buf), + channel_id=_UniffiConverterOptionalBytes.read(buf), + ) -Error = _UniffiTempError # type: ignore -del _UniffiTempError + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.peer_id) + _UniffiConverterUInt64.check_lower(value.our_amount_msat) + _UniffiConverterUInt64.check_lower(value.amount_msat) + _UniffiConverterBytes.check_lower(value.funding_txid) + _UniffiConverterUInt32.check_lower(value.funding_output) + _UniffiConverterBool.check_lower(value.connected) + _UniffiConverterTypeChannelState.check_lower(value.state) + _UniffiConverterOptionalString.check_lower(value.short_channel_id) + _UniffiConverterOptionalBytes.check_lower(value.channel_id) + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.peer_id, buf) + _UniffiConverterUInt64.write(value.our_amount_msat, buf) + _UniffiConverterUInt64.write(value.amount_msat, buf) + _UniffiConverterBytes.write(value.funding_txid, buf) + _UniffiConverterUInt32.write(value.funding_output, buf) + _UniffiConverterBool.write(value.connected, buf) + _UniffiConverterTypeChannelState.write(value.state, buf) + _UniffiConverterOptionalString.write(value.short_channel_id, buf) + _UniffiConverterOptionalBytes.write(value.channel_id, buf) + + +class FundOutput: + txid: "bytes" + output: "int" + amount_msat: "int" + status: "OutputStatus" + address: "typing.Optional[str]" + blockheight: "typing.Optional[int]" + def __init__(self, *, txid: "bytes", output: "int", amount_msat: "int", status: "OutputStatus", address: "typing.Optional[str]", blockheight: "typing.Optional[int]"): + self.txid = txid + self.output = output + self.amount_msat = amount_msat + self.status = status + self.address = address + self.blockheight = blockheight -class _UniffiConverterTypeError(_UniffiConverterRustBuffer): + def __str__(self): + return "FundOutput(txid={}, output={}, amount_msat={}, status={}, address={}, blockheight={})".format(self.txid, self.output, self.amount_msat, self.status, self.address, self.blockheight) + + def __eq__(self, other): + if self.txid != other.txid: + return False + if self.output != other.output: + return False + if self.amount_msat != other.amount_msat: + return False + if self.status != other.status: + return False + if self.address != other.address: + return False + if self.blockheight != other.blockheight: + return False + return True + +class _UniffiConverterTypeFundOutput(_UniffiConverterRustBuffer): @staticmethod def read(buf): - variant = buf.read_i32() - if variant == 1: - return Error.DuplicateNode( - _UniffiConverterString.read(buf), - ) - if variant == 2: - return Error.NoSuchNode( - _UniffiConverterString.read(buf), - ) - if variant == 3: - return Error.UnparseableCreds( - ) - if variant == 4: - return Error.PhraseCorrupted( - ) - if variant == 5: - return Error.Other( - _UniffiConverterString.read(buf), - ) - raise InternalError("Raw enum value doesn't match any cases") + return FundOutput( + txid=_UniffiConverterBytes.read(buf), + output=_UniffiConverterUInt32.read(buf), + amount_msat=_UniffiConverterUInt64.read(buf), + status=_UniffiConverterTypeOutputStatus.read(buf), + address=_UniffiConverterOptionalString.read(buf), + blockheight=_UniffiConverterOptionalUInt32.read(buf), + ) @staticmethod def check_lower(value): - if isinstance(value, Error.DuplicateNode): - _UniffiConverterString.check_lower(value._values[0]) - return - if isinstance(value, Error.NoSuchNode): - _UniffiConverterString.check_lower(value._values[0]) - return - if isinstance(value, Error.UnparseableCreds): - return - if isinstance(value, Error.PhraseCorrupted): - return - if isinstance(value, Error.Other): - _UniffiConverterString.check_lower(value._values[0]) - return + _UniffiConverterBytes.check_lower(value.txid) + _UniffiConverterUInt32.check_lower(value.output) + _UniffiConverterUInt64.check_lower(value.amount_msat) + _UniffiConverterTypeOutputStatus.check_lower(value.status) + _UniffiConverterOptionalString.check_lower(value.address) + _UniffiConverterOptionalUInt32.check_lower(value.blockheight) @staticmethod def write(value, buf): - if isinstance(value, Error.DuplicateNode): - buf.write_i32(1) - _UniffiConverterString.write(value._values[0], buf) - if isinstance(value, Error.NoSuchNode): - buf.write_i32(2) - _UniffiConverterString.write(value._values[0], buf) - if isinstance(value, Error.UnparseableCreds): - buf.write_i32(3) - if isinstance(value, Error.PhraseCorrupted): - buf.write_i32(4) - if isinstance(value, Error.Other): - buf.write_i32(5) - _UniffiConverterString.write(value._values[0], buf) - + _UniffiConverterBytes.write(value.txid, buf) + _UniffiConverterUInt32.write(value.output, buf) + _UniffiConverterUInt64.write(value.amount_msat, buf) + _UniffiConverterTypeOutputStatus.write(value.status, buf) + _UniffiConverterOptionalString.write(value.address, buf) + _UniffiConverterOptionalUInt32.write(value.blockheight, buf) + + +class GetInfoResponse: + id: "bytes" + alias: "typing.Optional[str]" + color: "bytes" + num_peers: "int" + num_pending_channels: "int" + num_active_channels: "int" + num_inactive_channels: "int" + version: "str" + lightning_dir: "str" + blockheight: "int" + network: "str" + fees_collected_msat: "int" + def __init__(self, *, id: "bytes", alias: "typing.Optional[str]", color: "bytes", num_peers: "int", num_pending_channels: "int", num_active_channels: "int", num_inactive_channels: "int", version: "str", lightning_dir: "str", blockheight: "int", network: "str", fees_collected_msat: "int"): + self.id = id + self.alias = alias + self.color = color + self.num_peers = num_peers + self.num_pending_channels = num_pending_channels + self.num_active_channels = num_active_channels + self.num_inactive_channels = num_inactive_channels + self.version = version + self.lightning_dir = lightning_dir + self.blockheight = blockheight + self.network = network + self.fees_collected_msat = fees_collected_msat + def __str__(self): + return "GetInfoResponse(id={}, alias={}, color={}, num_peers={}, num_pending_channels={}, num_active_channels={}, num_inactive_channels={}, version={}, lightning_dir={}, blockheight={}, network={}, fees_collected_msat={})".format(self.id, self.alias, self.color, self.num_peers, self.num_pending_channels, self.num_active_channels, self.num_inactive_channels, self.version, self.lightning_dir, self.blockheight, self.network, self.fees_collected_msat) + + def __eq__(self, other): + if self.id != other.id: + return False + if self.alias != other.alias: + return False + if self.color != other.color: + return False + if self.num_peers != other.num_peers: + return False + if self.num_pending_channels != other.num_pending_channels: + return False + if self.num_active_channels != other.num_active_channels: + return False + if self.num_inactive_channels != other.num_inactive_channels: + return False + if self.version != other.version: + return False + if self.lightning_dir != other.lightning_dir: + return False + if self.blockheight != other.blockheight: + return False + if self.network != other.network: + return False + if self.fees_collected_msat != other.fees_collected_msat: + return False + return True + +class _UniffiConverterTypeGetInfoResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return GetInfoResponse( + id=_UniffiConverterBytes.read(buf), + alias=_UniffiConverterOptionalString.read(buf), + color=_UniffiConverterBytes.read(buf), + num_peers=_UniffiConverterUInt32.read(buf), + num_pending_channels=_UniffiConverterUInt32.read(buf), + num_active_channels=_UniffiConverterUInt32.read(buf), + num_inactive_channels=_UniffiConverterUInt32.read(buf), + version=_UniffiConverterString.read(buf), + lightning_dir=_UniffiConverterString.read(buf), + blockheight=_UniffiConverterUInt32.read(buf), + network=_UniffiConverterString.read(buf), + fees_collected_msat=_UniffiConverterUInt64.read(buf), + ) + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.id) + _UniffiConverterOptionalString.check_lower(value.alias) + _UniffiConverterBytes.check_lower(value.color) + _UniffiConverterUInt32.check_lower(value.num_peers) + _UniffiConverterUInt32.check_lower(value.num_pending_channels) + _UniffiConverterUInt32.check_lower(value.num_active_channels) + _UniffiConverterUInt32.check_lower(value.num_inactive_channels) + _UniffiConverterString.check_lower(value.version) + _UniffiConverterString.check_lower(value.lightning_dir) + _UniffiConverterUInt32.check_lower(value.blockheight) + _UniffiConverterString.check_lower(value.network) + _UniffiConverterUInt64.check_lower(value.fees_collected_msat) + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.id, buf) + _UniffiConverterOptionalString.write(value.alias, buf) + _UniffiConverterBytes.write(value.color, buf) + _UniffiConverterUInt32.write(value.num_peers, buf) + _UniffiConverterUInt32.write(value.num_pending_channels, buf) + _UniffiConverterUInt32.write(value.num_active_channels, buf) + _UniffiConverterUInt32.write(value.num_inactive_channels, buf) + _UniffiConverterString.write(value.version, buf) + _UniffiConverterString.write(value.lightning_dir, buf) + _UniffiConverterUInt32.write(value.blockheight, buf) + _UniffiConverterString.write(value.network, buf) + _UniffiConverterUInt64.write(value.fees_collected_msat, buf) + + +class ListFundsResponse: + outputs: "typing.List[FundOutput]" + channels: "typing.List[FundChannel]" + def __init__(self, *, outputs: "typing.List[FundOutput]", channels: "typing.List[FundChannel]"): + self.outputs = outputs + self.channels = channels -class Network(enum.Enum): - BITCOIN = 0 - - REGTEST = 1 - + def __str__(self): + return "ListFundsResponse(outputs={}, channels={})".format(self.outputs, self.channels) + def __eq__(self, other): + if self.outputs != other.outputs: + return False + if self.channels != other.channels: + return False + return True -class _UniffiConverterTypeNetwork(_UniffiConverterRustBuffer): +class _UniffiConverterTypeListFundsResponse(_UniffiConverterRustBuffer): @staticmethod def read(buf): - variant = buf.read_i32() - if variant == 1: - return Network.BITCOIN - if variant == 2: - return Network.REGTEST - raise InternalError("Raw enum value doesn't match any cases") + return ListFundsResponse( + outputs=_UniffiConverterSequenceTypeFundOutput.read(buf), + channels=_UniffiConverterSequenceTypeFundChannel.read(buf), + ) @staticmethod def check_lower(value): - if value == Network.BITCOIN: - return - if value == Network.REGTEST: + _UniffiConverterSequenceTypeFundOutput.check_lower(value.outputs) + _UniffiConverterSequenceTypeFundChannel.check_lower(value.channels) + + @staticmethod + def write(value, buf): + _UniffiConverterSequenceTypeFundOutput.write(value.outputs, buf) + _UniffiConverterSequenceTypeFundChannel.write(value.channels, buf) + + +class ListPeerChannelsResponse: + channels: "typing.List[PeerChannel]" + def __init__(self, *, channels: "typing.List[PeerChannel]"): + self.channels = channels + + def __str__(self): + return "ListPeerChannelsResponse(channels={})".format(self.channels) + + def __eq__(self, other): + if self.channels != other.channels: + return False + return True + +class _UniffiConverterTypeListPeerChannelsResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ListPeerChannelsResponse( + channels=_UniffiConverterSequenceTypePeerChannel.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterSequenceTypePeerChannel.check_lower(value.channels) + + @staticmethod + def write(value, buf): + _UniffiConverterSequenceTypePeerChannel.write(value.channels, buf) + + +class ListPeersResponse: + peers: "typing.List[Peer]" + def __init__(self, *, peers: "typing.List[Peer]"): + self.peers = peers + + def __str__(self): + return "ListPeersResponse(peers={})".format(self.peers) + + def __eq__(self, other): + if self.peers != other.peers: + return False + return True + +class _UniffiConverterTypeListPeersResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ListPeersResponse( + peers=_UniffiConverterSequenceTypePeer.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterSequenceTypePeer.check_lower(value.peers) + + @staticmethod + def write(value, buf): + _UniffiConverterSequenceTypePeer.write(value.peers, buf) + + +class Peer: + id: "bytes" + connected: "bool" + num_channels: "typing.Optional[int]" + netaddr: "typing.List[str]" + remote_addr: "typing.Optional[str]" + features: "typing.Optional[bytes]" + def __init__(self, *, id: "bytes", connected: "bool", num_channels: "typing.Optional[int]", netaddr: "typing.List[str]", remote_addr: "typing.Optional[str]", features: "typing.Optional[bytes]"): + self.id = id + self.connected = connected + self.num_channels = num_channels + self.netaddr = netaddr + self.remote_addr = remote_addr + self.features = features + + def __str__(self): + return "Peer(id={}, connected={}, num_channels={}, netaddr={}, remote_addr={}, features={})".format(self.id, self.connected, self.num_channels, self.netaddr, self.remote_addr, self.features) + + def __eq__(self, other): + if self.id != other.id: + return False + if self.connected != other.connected: + return False + if self.num_channels != other.num_channels: + return False + if self.netaddr != other.netaddr: + return False + if self.remote_addr != other.remote_addr: + return False + if self.features != other.features: + return False + return True + +class _UniffiConverterTypePeer(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Peer( + id=_UniffiConverterBytes.read(buf), + connected=_UniffiConverterBool.read(buf), + num_channels=_UniffiConverterOptionalUInt32.read(buf), + netaddr=_UniffiConverterSequenceString.read(buf), + remote_addr=_UniffiConverterOptionalString.read(buf), + features=_UniffiConverterOptionalBytes.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.id) + _UniffiConverterBool.check_lower(value.connected) + _UniffiConverterOptionalUInt32.check_lower(value.num_channels) + _UniffiConverterSequenceString.check_lower(value.netaddr) + _UniffiConverterOptionalString.check_lower(value.remote_addr) + _UniffiConverterOptionalBytes.check_lower(value.features) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.id, buf) + _UniffiConverterBool.write(value.connected, buf) + _UniffiConverterOptionalUInt32.write(value.num_channels, buf) + _UniffiConverterSequenceString.write(value.netaddr, buf) + _UniffiConverterOptionalString.write(value.remote_addr, buf) + _UniffiConverterOptionalBytes.write(value.features, buf) + + +class PeerChannel: + peer_id: "bytes" + peer_connected: "bool" + state: "ChannelState" + short_channel_id: "typing.Optional[str]" + channel_id: "typing.Optional[bytes]" + funding_txid: "typing.Optional[bytes]" + funding_outnum: "typing.Optional[int]" + to_us_msat: "typing.Optional[int]" + total_msat: "typing.Optional[int]" + spendable_msat: "typing.Optional[int]" + receivable_msat: "typing.Optional[int]" + def __init__(self, *, peer_id: "bytes", peer_connected: "bool", state: "ChannelState", short_channel_id: "typing.Optional[str]", channel_id: "typing.Optional[bytes]", funding_txid: "typing.Optional[bytes]", funding_outnum: "typing.Optional[int]", to_us_msat: "typing.Optional[int]", total_msat: "typing.Optional[int]", spendable_msat: "typing.Optional[int]", receivable_msat: "typing.Optional[int]"): + self.peer_id = peer_id + self.peer_connected = peer_connected + self.state = state + self.short_channel_id = short_channel_id + self.channel_id = channel_id + self.funding_txid = funding_txid + self.funding_outnum = funding_outnum + self.to_us_msat = to_us_msat + self.total_msat = total_msat + self.spendable_msat = spendable_msat + self.receivable_msat = receivable_msat + + def __str__(self): + return "PeerChannel(peer_id={}, peer_connected={}, state={}, short_channel_id={}, channel_id={}, funding_txid={}, funding_outnum={}, to_us_msat={}, total_msat={}, spendable_msat={}, receivable_msat={})".format(self.peer_id, self.peer_connected, self.state, self.short_channel_id, self.channel_id, self.funding_txid, self.funding_outnum, self.to_us_msat, self.total_msat, self.spendable_msat, self.receivable_msat) + + def __eq__(self, other): + if self.peer_id != other.peer_id: + return False + if self.peer_connected != other.peer_connected: + return False + if self.state != other.state: + return False + if self.short_channel_id != other.short_channel_id: + return False + if self.channel_id != other.channel_id: + return False + if self.funding_txid != other.funding_txid: + return False + if self.funding_outnum != other.funding_outnum: + return False + if self.to_us_msat != other.to_us_msat: + return False + if self.total_msat != other.total_msat: + return False + if self.spendable_msat != other.spendable_msat: + return False + if self.receivable_msat != other.receivable_msat: + return False + return True + +class _UniffiConverterTypePeerChannel(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PeerChannel( + peer_id=_UniffiConverterBytes.read(buf), + peer_connected=_UniffiConverterBool.read(buf), + state=_UniffiConverterTypeChannelState.read(buf), + short_channel_id=_UniffiConverterOptionalString.read(buf), + channel_id=_UniffiConverterOptionalBytes.read(buf), + funding_txid=_UniffiConverterOptionalBytes.read(buf), + funding_outnum=_UniffiConverterOptionalUInt32.read(buf), + to_us_msat=_UniffiConverterOptionalUInt64.read(buf), + total_msat=_UniffiConverterOptionalUInt64.read(buf), + spendable_msat=_UniffiConverterOptionalUInt64.read(buf), + receivable_msat=_UniffiConverterOptionalUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.peer_id) + _UniffiConverterBool.check_lower(value.peer_connected) + _UniffiConverterTypeChannelState.check_lower(value.state) + _UniffiConverterOptionalString.check_lower(value.short_channel_id) + _UniffiConverterOptionalBytes.check_lower(value.channel_id) + _UniffiConverterOptionalBytes.check_lower(value.funding_txid) + _UniffiConverterOptionalUInt32.check_lower(value.funding_outnum) + _UniffiConverterOptionalUInt64.check_lower(value.to_us_msat) + _UniffiConverterOptionalUInt64.check_lower(value.total_msat) + _UniffiConverterOptionalUInt64.check_lower(value.spendable_msat) + _UniffiConverterOptionalUInt64.check_lower(value.receivable_msat) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.peer_id, buf) + _UniffiConverterBool.write(value.peer_connected, buf) + _UniffiConverterTypeChannelState.write(value.state, buf) + _UniffiConverterOptionalString.write(value.short_channel_id, buf) + _UniffiConverterOptionalBytes.write(value.channel_id, buf) + _UniffiConverterOptionalBytes.write(value.funding_txid, buf) + _UniffiConverterOptionalUInt32.write(value.funding_outnum, buf) + _UniffiConverterOptionalUInt64.write(value.to_us_msat, buf) + _UniffiConverterOptionalUInt64.write(value.total_msat, buf) + _UniffiConverterOptionalUInt64.write(value.spendable_msat, buf) + _UniffiConverterOptionalUInt64.write(value.receivable_msat, buf) + + + + + +class ChannelState(enum.Enum): + OPENINGD = 0 + + CHANNELD_AWAITING_LOCKIN = 1 + + CHANNELD_NORMAL = 2 + + CHANNELD_SHUTTING_DOWN = 3 + + CLOSINGD_SIGEXCHANGE = 4 + + CLOSINGD_COMPLETE = 5 + + AWAITING_UNILATERAL = 6 + + FUNDING_SPEND_SEEN = 7 + + ONCHAIN = 8 + + DUALOPEND_OPEN_INIT = 9 + + DUALOPEND_AWAITING_LOCKIN = 10 + + DUALOPEND_OPEN_COMMITTED = 11 + + DUALOPEND_OPEN_COMMIT_READY = 12 + + + +class _UniffiConverterTypeChannelState(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return ChannelState.OPENINGD + if variant == 2: + return ChannelState.CHANNELD_AWAITING_LOCKIN + if variant == 3: + return ChannelState.CHANNELD_NORMAL + if variant == 4: + return ChannelState.CHANNELD_SHUTTING_DOWN + if variant == 5: + return ChannelState.CLOSINGD_SIGEXCHANGE + if variant == 6: + return ChannelState.CLOSINGD_COMPLETE + if variant == 7: + return ChannelState.AWAITING_UNILATERAL + if variant == 8: + return ChannelState.FUNDING_SPEND_SEEN + if variant == 9: + return ChannelState.ONCHAIN + if variant == 10: + return ChannelState.DUALOPEND_OPEN_INIT + if variant == 11: + return ChannelState.DUALOPEND_AWAITING_LOCKIN + if variant == 12: + return ChannelState.DUALOPEND_OPEN_COMMITTED + if variant == 13: + return ChannelState.DUALOPEND_OPEN_COMMIT_READY + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == ChannelState.OPENINGD: + return + if value == ChannelState.CHANNELD_AWAITING_LOCKIN: + return + if value == ChannelState.CHANNELD_NORMAL: + return + if value == ChannelState.CHANNELD_SHUTTING_DOWN: + return + if value == ChannelState.CLOSINGD_SIGEXCHANGE: + return + if value == ChannelState.CLOSINGD_COMPLETE: + return + if value == ChannelState.AWAITING_UNILATERAL: + return + if value == ChannelState.FUNDING_SPEND_SEEN: + return + if value == ChannelState.ONCHAIN: + return + if value == ChannelState.DUALOPEND_OPEN_INIT: + return + if value == ChannelState.DUALOPEND_AWAITING_LOCKIN: + return + if value == ChannelState.DUALOPEND_OPEN_COMMITTED: + return + if value == ChannelState.DUALOPEND_OPEN_COMMIT_READY: return raise ValueError(value) - @staticmethod - def write(value, buf): - if value == Network.BITCOIN: - buf.write_i32(1) - if value == Network.REGTEST: - buf.write_i32(2) + @staticmethod + def write(value, buf): + if value == ChannelState.OPENINGD: + buf.write_i32(1) + if value == ChannelState.CHANNELD_AWAITING_LOCKIN: + buf.write_i32(2) + if value == ChannelState.CHANNELD_NORMAL: + buf.write_i32(3) + if value == ChannelState.CHANNELD_SHUTTING_DOWN: + buf.write_i32(4) + if value == ChannelState.CLOSINGD_SIGEXCHANGE: + buf.write_i32(5) + if value == ChannelState.CLOSINGD_COMPLETE: + buf.write_i32(6) + if value == ChannelState.AWAITING_UNILATERAL: + buf.write_i32(7) + if value == ChannelState.FUNDING_SPEND_SEEN: + buf.write_i32(8) + if value == ChannelState.ONCHAIN: + buf.write_i32(9) + if value == ChannelState.DUALOPEND_OPEN_INIT: + buf.write_i32(10) + if value == ChannelState.DUALOPEND_AWAITING_LOCKIN: + buf.write_i32(11) + if value == ChannelState.DUALOPEND_OPEN_COMMITTED: + buf.write_i32(12) + if value == ChannelState.DUALOPEND_OPEN_COMMIT_READY: + buf.write_i32(13) + + + + +# Error +# We want to define each variant as a nested class that's also a subclass, +# which is tricky in Python. To accomplish this we're going to create each +# class separately, then manually add the child classes to the base class's +# __dict__. All of this happens in dummy class to avoid polluting the module +# namespace. +class Error(Exception): + pass + +_UniffiTempError = Error + +class Error: # type: ignore + class DuplicateNode(_UniffiTempError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "Error.DuplicateNode({})".format(str(self)) + _UniffiTempError.DuplicateNode = DuplicateNode # type: ignore + class NoSuchNode(_UniffiTempError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "Error.NoSuchNode({})".format(str(self)) + _UniffiTempError.NoSuchNode = NoSuchNode # type: ignore + class UnparseableCreds(_UniffiTempError): + def __init__(self): + pass + + def __repr__(self): + return "Error.UnparseableCreds({})".format(str(self)) + _UniffiTempError.UnparseableCreds = UnparseableCreds # type: ignore + class PhraseCorrupted(_UniffiTempError): + def __init__(self): + pass + + def __repr__(self): + return "Error.PhraseCorrupted({})".format(str(self)) + _UniffiTempError.PhraseCorrupted = PhraseCorrupted # type: ignore + class Rpc(_UniffiTempError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "Error.Rpc({})".format(str(self)) + _UniffiTempError.Rpc = Rpc # type: ignore + class Argument(_UniffiTempError): + def __init__(self, *values): + if len(values) != 2: + raise TypeError(f"Expected 2 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + if not isinstance(values[1], str): + raise TypeError(f"unexpected type for tuple element 1 - expected 'str', got '{type(values[1])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "Error.Argument({})".format(str(self)) + _UniffiTempError.Argument = Argument # type: ignore + class Other(_UniffiTempError): + def __init__(self, *values): + if len(values) != 1: + raise TypeError(f"Expected 1 arguments, found {len(values)}") + if not isinstance(values[0], str): + raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") + super().__init__(", ".join(map(repr, values))) + self._values = values + + def __getitem__(self, index): + return self._values[index] + + def __repr__(self): + return "Error.Other({})".format(str(self)) + _UniffiTempError.Other = Other # type: ignore + +Error = _UniffiTempError # type: ignore +del _UniffiTempError + + +class _UniffiConverterTypeError(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return Error.DuplicateNode( + _UniffiConverterString.read(buf), + ) + if variant == 2: + return Error.NoSuchNode( + _UniffiConverterString.read(buf), + ) + if variant == 3: + return Error.UnparseableCreds( + ) + if variant == 4: + return Error.PhraseCorrupted( + ) + if variant == 5: + return Error.Rpc( + _UniffiConverterString.read(buf), + ) + if variant == 6: + return Error.Argument( + _UniffiConverterString.read(buf), + _UniffiConverterString.read(buf), + ) + if variant == 7: + return Error.Other( + _UniffiConverterString.read(buf), + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if isinstance(value, Error.DuplicateNode): + _UniffiConverterString.check_lower(value._values[0]) + return + if isinstance(value, Error.NoSuchNode): + _UniffiConverterString.check_lower(value._values[0]) + return + if isinstance(value, Error.UnparseableCreds): + return + if isinstance(value, Error.PhraseCorrupted): + return + if isinstance(value, Error.Rpc): + _UniffiConverterString.check_lower(value._values[0]) + return + if isinstance(value, Error.Argument): + _UniffiConverterString.check_lower(value._values[0]) + _UniffiConverterString.check_lower(value._values[1]) + return + if isinstance(value, Error.Other): + _UniffiConverterString.check_lower(value._values[0]) + return + + @staticmethod + def write(value, buf): + if isinstance(value, Error.DuplicateNode): + buf.write_i32(1) + _UniffiConverterString.write(value._values[0], buf) + if isinstance(value, Error.NoSuchNode): + buf.write_i32(2) + _UniffiConverterString.write(value._values[0], buf) + if isinstance(value, Error.UnparseableCreds): + buf.write_i32(3) + if isinstance(value, Error.PhraseCorrupted): + buf.write_i32(4) + if isinstance(value, Error.Rpc): + buf.write_i32(5) + _UniffiConverterString.write(value._values[0], buf) + if isinstance(value, Error.Argument): + buf.write_i32(6) + _UniffiConverterString.write(value._values[0], buf) + _UniffiConverterString.write(value._values[1], buf) + if isinstance(value, Error.Other): + buf.write_i32(7) + _UniffiConverterString.write(value._values[0], buf) + + + + + +class Network(enum.Enum): + BITCOIN = 0 + + REGTEST = 1 + + + +class _UniffiConverterTypeNetwork(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return Network.BITCOIN + if variant == 2: + return Network.REGTEST + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == Network.BITCOIN: + return + if value == Network.REGTEST: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == Network.BITCOIN: + buf.write_i32(1) + if value == Network.REGTEST: + buf.write_i32(2) + + + + + + + +class OutputStatus(enum.Enum): + UNCONFIRMED = 0 + + CONFIRMED = 1 + + SPENT = 2 + + IMMATURE = 3 + + + +class _UniffiConverterTypeOutputStatus(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return OutputStatus.UNCONFIRMED + if variant == 2: + return OutputStatus.CONFIRMED + if variant == 3: + return OutputStatus.SPENT + if variant == 4: + return OutputStatus.IMMATURE + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == OutputStatus.UNCONFIRMED: + return + if value == OutputStatus.CONFIRMED: + return + if value == OutputStatus.SPENT: + return + if value == OutputStatus.IMMATURE: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == OutputStatus.UNCONFIRMED: + buf.write_i32(1) + if value == OutputStatus.CONFIRMED: + buf.write_i32(2) + if value == OutputStatus.SPENT: + buf.write_i32(3) + if value == OutputStatus.IMMATURE: + buf.write_i32(4) + + + + + + + +class PayStatus(enum.Enum): + COMPLETE = 0 + + PENDING = 1 + + FAILED = 2 + + + +class _UniffiConverterTypePayStatus(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return PayStatus.COMPLETE + if variant == 2: + return PayStatus.PENDING + if variant == 3: + return PayStatus.FAILED + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == PayStatus.COMPLETE: + return + if value == PayStatus.PENDING: + return + if value == PayStatus.FAILED: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == PayStatus.COMPLETE: + buf.write_i32(1) + if value == PayStatus.PENDING: + buf.write_i32(2) + if value == PayStatus.FAILED: + buf.write_i32(3) + + + + + +class _UniffiConverterOptionalUInt32(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterUInt32.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterUInt32.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterUInt32.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + +class _UniffiConverterOptionalUInt64(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterUInt64.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterUInt64.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterUInt64.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + +class _UniffiConverterOptionalString(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterString.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterString.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterString.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + +class _UniffiConverterOptionalBytes(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterBytes.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterBytes.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterBytes.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + +class _UniffiConverterSequenceString(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterString.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterString.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterString.read(buf) for i in range(count) + ] + + + +class _UniffiConverterSequenceTypeFundChannel(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypeFundChannel.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypeFundChannel.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypeFundChannel.read(buf) for i in range(count) + ] + + + +class _UniffiConverterSequenceTypeFundOutput(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypeFundOutput.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypeFundOutput.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypeFundOutput.read(buf) for i in range(count) + ] + + + +class _UniffiConverterSequenceTypePeer(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypePeer.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypePeer.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypePeer.read(buf) for i in range(count) + ] + + + +class _UniffiConverterSequenceTypePeerChannel(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiConverterTypePeerChannel.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiConverterTypePeerChannel.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiConverterTypePeerChannel.read(buf) for i in range(count) + ] + +# objects. +class CredentialsProtocol(typing.Protocol): + """ + `Credentials` is a container for `node_id`, the mTLS client + certificate used to authenticate a client against a node, as well + as the seed secret if present. If no seed is present in the + credentials, then the `Client` will not start a signer in the + background. + """ + + def save(self, ): + raise NotImplementedError +# Credentials is a Rust-only trait - it's a wrapper around a Rust implementation. +class Credentials(): + """ + `Credentials` is a container for `node_id`, the mTLS client + certificate used to authenticate a client against a node, as well + as the seed secret if present. If no seed is present in the + credentials, then the `Client` will not start a signer in the + background. + """ + + _pointer: ctypes.c_void_p + + def __init__(self, *args, **kwargs): + raise ValueError("This class has no default constructor") + + def __del__(self): + # In case of partial initialization of instances. + pointer = getattr(self, "_pointer", None) + if pointer is not None: + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_credentials, pointer) + + def _uniffi_clone_pointer(self): + return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_credentials, self._pointer) + + # Used by alternative constructors or any methods which return this type. + @classmethod + def _make_instance_(cls, pointer): + # Lightly yucky way to bypass the usual __init__ logic + # and just create a new instance with the required pointer. + inst = cls.__new__(cls) + inst._pointer = pointer + return inst + @classmethod + def load(cls, raw: "bytes"): + _UniffiConverterBytes.check_lower(raw) + + # Call the (fallible) function before creating any half-baked object instances. + pointer = _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_constructor_credentials_load, + _UniffiConverterBytes.lower(raw)) + return cls._make_instance_(pointer) + + + + def save(self, ) -> "bytes": + return _UniffiConverterBytes.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_credentials_save,self._uniffi_clone_pointer(),) + ) + + + + + + +class _UniffiConverterTypeCredentials: + + @staticmethod + def lift(value: int): + return Credentials._make_instance_(value) + + @staticmethod + def check_lower(value: Credentials): + if not isinstance(value, Credentials): + raise TypeError("Expected Credentials instance, {} found".format(type(value).__name__)) + + @staticmethod + def lower(value: CredentialsProtocol): + if not isinstance(value, Credentials): + raise TypeError("Expected Credentials instance, {} found".format(type(value).__name__)) + return value._uniffi_clone_pointer() + + @classmethod + def read(cls, buf: _UniffiRustBuffer): + ptr = buf.read_u64() + if ptr == 0: + raise InternalError("Raw pointer value was null") + return cls.lift(ptr) + + @classmethod + def write(cls, value: CredentialsProtocol, buf: _UniffiRustBuffer): + buf.write_u64(cls.lower(value)) +class HandleProtocol(typing.Protocol): + """ + A handle to interact with a signer loop running and processing + requests in the background. Used primarily to stop the loop and + exiting the signer. + """ + + def stop(self, ): + raise NotImplementedError +# Handle is a Rust-only trait - it's a wrapper around a Rust implementation. +class Handle(): + """ + A handle to interact with a signer loop running and processing + requests in the background. Used primarily to stop the loop and + exiting the signer. + """ + + _pointer: ctypes.c_void_p + + def __init__(self, *args, **kwargs): + raise ValueError("This class has no default constructor") + + def __del__(self): + # In case of partial initialization of instances. + pointer = getattr(self, "_pointer", None) + if pointer is not None: + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_handle, pointer) + + def _uniffi_clone_pointer(self): + return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_handle, self._pointer) + + # Used by alternative constructors or any methods which return this type. + @classmethod + def _make_instance_(cls, pointer): + # Lightly yucky way to bypass the usual __init__ logic + # and just create a new instance with the required pointer. + inst = cls.__new__(cls) + inst._pointer = pointer + return inst + + + def stop(self, ) -> None: + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_method_handle_stop,self._uniffi_clone_pointer(),) + + + + + + + +class _UniffiConverterTypeHandle: + + @staticmethod + def lift(value: int): + return Handle._make_instance_(value) + + @staticmethod + def check_lower(value: Handle): + if not isinstance(value, Handle): + raise TypeError("Expected Handle instance, {} found".format(type(value).__name__)) + + @staticmethod + def lower(value: HandleProtocol): + if not isinstance(value, Handle): + raise TypeError("Expected Handle instance, {} found".format(type(value).__name__)) + return value._uniffi_clone_pointer() + + @classmethod + def read(cls, buf: _UniffiRustBuffer): + ptr = buf.read_u64() + if ptr == 0: + raise InternalError("Raw pointer value was null") + return cls.lift(ptr) + + @classmethod + def write(cls, value: HandleProtocol, buf: _UniffiRustBuffer): + buf.write_u64(cls.lower(value)) +class NodeProtocol(typing.Protocol): + """ + The `Node` is an RPC stub representing the node running in the + cloud. It is the main entrypoint to interact with the node. + """ + + def get_info(self, ): + """ + Get information about the node. + + Returns basic information about the node including its ID, + alias, network, and channel counts. + """ + + raise NotImplementedError + def list_funds(self, ): + """ + List all funds available to the node. + + Returns information about on-chain outputs and channel funds + that are available or pending. + """ + + raise NotImplementedError + def list_peer_channels(self, ): + """ + List all channels with peers. + + Returns detailed information about all channels including their + state, capacity, and balances. + """ + + raise NotImplementedError + def list_peers(self, ): + """ + List all peers connected to this node. + + Returns information about all peers including their connection + status. + """ + + raise NotImplementedError + def onchain_receive(self, ): + raise NotImplementedError + def onchain_send(self, destination: "str",amount_or_all: "str"): + raise NotImplementedError + def receive(self, label: "str",description: "str",amount_msat: "typing.Optional[int]"): + """ + Receive an off-chain payment. + + This method generates a request for a payment, also called an + invoice, that encodes all the information, including amount + and destination, for a prospective sender to send a lightning + payment. The invoice includes negotiation of an LSPS2 / JIT + channel, meaning that if there is no channel sufficient to + receive the requested funds, the node will negotiate an + opening, and when/if executed the payment will cause a channel + to be created, and the incoming payment to be forwarded. + """ + + raise NotImplementedError + def send(self, invoice: "str",amount_msat: "typing.Optional[int]"): + raise NotImplementedError + def stop(self, ): + """ + Stop the node if it is currently running. + """ + + raise NotImplementedError +# Node is a Rust-only trait - it's a wrapper around a Rust implementation. +class Node(): + """ + The `Node` is an RPC stub representing the node running in the + cloud. It is the main entrypoint to interact with the node. + """ + + _pointer: ctypes.c_void_p + def __init__(self, credentials: "Credentials"): + _UniffiConverterTypeCredentials.check_lower(credentials) + + self._pointer = _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_constructor_node_new, + _UniffiConverterTypeCredentials.lower(credentials)) + + def __del__(self): + # In case of partial initialization of instances. + pointer = getattr(self, "_pointer", None) + if pointer is not None: + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_node, pointer) + + def _uniffi_clone_pointer(self): + return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_node, self._pointer) + + # Used by alternative constructors or any methods which return this type. + @classmethod + def _make_instance_(cls, pointer): + # Lightly yucky way to bypass the usual __init__ logic + # and just create a new instance with the required pointer. + inst = cls.__new__(cls) + inst._pointer = pointer + return inst + + + def get_info(self, ) -> "GetInfoResponse": + """ + Get information about the node. + + Returns basic information about the node including its ID, + alias, network, and channel counts. + """ + + return _UniffiConverterTypeGetInfoResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_get_info,self._uniffi_clone_pointer(),) + ) + + + + + + def list_funds(self, ) -> "ListFundsResponse": + """ + List all funds available to the node. + + Returns information about on-chain outputs and channel funds + that are available or pending. + """ + + return _UniffiConverterTypeListFundsResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_list_funds,self._uniffi_clone_pointer(),) + ) + + + + + + def list_peer_channels(self, ) -> "ListPeerChannelsResponse": + """ + List all channels with peers. + + Returns detailed information about all channels including their + state, capacity, and balances. + """ + + return _UniffiConverterTypeListPeerChannelsResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_list_peer_channels,self._uniffi_clone_pointer(),) + ) -class _UniffiConverterOptionalString(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - if value is not None: - _UniffiConverterString.check_lower(value) + def list_peers(self, ) -> "ListPeersResponse": + """ + List all peers connected to this node. - @classmethod - def write(cls, value, buf): - if value is None: - buf.write_u8(0) - return + Returns information about all peers including their connection + status. + """ - buf.write_u8(1) - _UniffiConverterString.write(value, buf) + return _UniffiConverterTypeListPeersResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_list_peers,self._uniffi_clone_pointer(),) + ) - @classmethod - def read(cls, buf): - flag = buf.read_u8() - if flag == 0: - return None - elif flag == 1: - return _UniffiConverterString.read(buf) - else: - raise InternalError("Unexpected flag byte for optional type") -# objects. -class CredentialsProtocol(typing.Protocol): - """ - `Credentials` is a container for `node_id`, the mTLS client - certificate used to authenticate a client against a node, as well - as the seed secret if present. If no seed is present in the - credentials, then the `Client` will not start a signer in the - background. - """ - pass -# Credentials is a Rust-only trait - it's a wrapper around a Rust implementation. -class Credentials(): - """ - `Credentials` is a container for `node_id`, the mTLS client - certificate used to authenticate a client against a node, as well - as the seed secret if present. If no seed is present in the - credentials, then the `Client` will not start a signer in the - background. - """ + + def onchain_receive(self, ) -> "OnchainReceiveResponse": + return _UniffiConverterTypeOnchainReceiveResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive,self._uniffi_clone_pointer(),) + ) + + + + + + def onchain_send(self, destination: "str",amount_or_all: "str") -> "OnchainSendResponse": + _UniffiConverterString.check_lower(destination) + + _UniffiConverterString.check_lower(amount_or_all) + + return _UniffiConverterTypeOnchainSendResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send,self._uniffi_clone_pointer(), + _UniffiConverterString.lower(destination), + _UniffiConverterString.lower(amount_or_all)) + ) + + + + + + def receive(self, label: "str",description: "str",amount_msat: "typing.Optional[int]") -> "ReceiveResponse": + """ + Receive an off-chain payment. + + This method generates a request for a payment, also called an + invoice, that encodes all the information, including amount + and destination, for a prospective sender to send a lightning + payment. The invoice includes negotiation of an LSPS2 / JIT + channel, meaning that if there is no channel sufficient to + receive the requested funds, the node will negotiate an + opening, and when/if executed the payment will cause a channel + to be created, and the incoming payment to be forwarded. + """ + + _UniffiConverterString.check_lower(label) + + _UniffiConverterString.check_lower(description) + + _UniffiConverterOptionalUInt64.check_lower(amount_msat) + + return _UniffiConverterTypeReceiveResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_receive,self._uniffi_clone_pointer(), + _UniffiConverterString.lower(label), + _UniffiConverterString.lower(description), + _UniffiConverterOptionalUInt64.lower(amount_msat)) + ) + + + + + + def send(self, invoice: "str",amount_msat: "typing.Optional[int]") -> "SendResponse": + _UniffiConverterString.check_lower(invoice) + + _UniffiConverterOptionalUInt64.check_lower(amount_msat) + + return _UniffiConverterTypeSendResponse.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_send,self._uniffi_clone_pointer(), + _UniffiConverterString.lower(invoice), + _UniffiConverterOptionalUInt64.lower(amount_msat)) + ) + + + + + + def stop(self, ) -> None: + """ + Stop the node if it is currently running. + """ + + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_stop,self._uniffi_clone_pointer(),) + + + + + + + +class _UniffiConverterTypeNode: + + @staticmethod + def lift(value: int): + return Node._make_instance_(value) + + @staticmethod + def check_lower(value: Node): + if not isinstance(value, Node): + raise TypeError("Expected Node instance, {} found".format(type(value).__name__)) + + @staticmethod + def lower(value: NodeProtocol): + if not isinstance(value, Node): + raise TypeError("Expected Node instance, {} found".format(type(value).__name__)) + return value._uniffi_clone_pointer() + + @classmethod + def read(cls, buf: _UniffiRustBuffer): + ptr = buf.read_u64() + if ptr == 0: + raise InternalError("Raw pointer value was null") + return cls.lift(ptr) + + @classmethod + def write(cls, value: NodeProtocol, buf: _UniffiRustBuffer): + buf.write_u64(cls.lower(value)) +class OnchainReceiveResponseProtocol(typing.Protocol): + pass +# OnchainReceiveResponse is a Rust-only trait - it's a wrapper around a Rust implementation. +class OnchainReceiveResponse(): _pointer: ctypes.c_void_p def __init__(self, *args, **kwargs): @@ -1288,10 +2917,10 @@ def __del__(self): # In case of partial initialization of instances. pointer = getattr(self, "_pointer", None) if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_credentials, pointer) + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_onchainreceiveresponse, pointer) def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_credentials, self._pointer) + return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_onchainreceiveresponse, self._pointer) # Used by alternative constructors or any methods which return this type. @classmethod @@ -1301,33 +2930,24 @@ def _make_instance_(cls, pointer): inst = cls.__new__(cls) inst._pointer = pointer return inst - @classmethod - def load(cls, raw: "bytes"): - _UniffiConverterBytes.check_lower(raw) - - # Call the (fallible) function before creating any half-baked object instances. - pointer = _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_constructor_credentials_load, - _UniffiConverterBytes.lower(raw)) - return cls._make_instance_(pointer) - -class _UniffiConverterTypeCredentials: +class _UniffiConverterTypeOnchainReceiveResponse: @staticmethod def lift(value: int): - return Credentials._make_instance_(value) + return OnchainReceiveResponse._make_instance_(value) @staticmethod - def check_lower(value: Credentials): - if not isinstance(value, Credentials): - raise TypeError("Expected Credentials instance, {} found".format(type(value).__name__)) + def check_lower(value: OnchainReceiveResponse): + if not isinstance(value, OnchainReceiveResponse): + raise TypeError("Expected OnchainReceiveResponse instance, {} found".format(type(value).__name__)) @staticmethod - def lower(value: CredentialsProtocol): - if not isinstance(value, Credentials): - raise TypeError("Expected Credentials instance, {} found".format(type(value).__name__)) + def lower(value: OnchainReceiveResponseProtocol): + if not isinstance(value, OnchainReceiveResponse): + raise TypeError("Expected OnchainReceiveResponse instance, {} found".format(type(value).__name__)) return value._uniffi_clone_pointer() @classmethod @@ -1338,25 +2958,12 @@ def read(cls, buf: _UniffiRustBuffer): return cls.lift(ptr) @classmethod - def write(cls, value: CredentialsProtocol, buf: _UniffiRustBuffer): + def write(cls, value: OnchainReceiveResponseProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) -class HandleProtocol(typing.Protocol): - """ - A handle to interact with a signer loop running and processing - requests in the background. Used primarily to stop the loop and - exiting the signer. - """ - - def stop(self, ): - raise NotImplementedError -# Handle is a Rust-only trait - it's a wrapper around a Rust implementation. -class Handle(): - """ - A handle to interact with a signer loop running and processing - requests in the background. Used primarily to stop the loop and - exiting the signer. - """ - +class OnchainSendResponseProtocol(typing.Protocol): + pass +# OnchainSendResponse is a Rust-only trait - it's a wrapper around a Rust implementation. +class OnchainSendResponse(): _pointer: ctypes.c_void_p def __init__(self, *args, **kwargs): @@ -1366,10 +2973,10 @@ def __del__(self): # In case of partial initialization of instances. pointer = getattr(self, "_pointer", None) if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_handle, pointer) + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_onchainsendresponse, pointer) def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_handle, self._pointer) + return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_onchainsendresponse, self._pointer) # Used by alternative constructors or any methods which return this type. @classmethod @@ -1381,30 +2988,22 @@ def _make_instance_(cls, pointer): return inst - def stop(self, ) -> None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_method_handle_stop,self._uniffi_clone_pointer(),) - - - - - - -class _UniffiConverterTypeHandle: +class _UniffiConverterTypeOnchainSendResponse: @staticmethod def lift(value: int): - return Handle._make_instance_(value) + return OnchainSendResponse._make_instance_(value) @staticmethod - def check_lower(value: Handle): - if not isinstance(value, Handle): - raise TypeError("Expected Handle instance, {} found".format(type(value).__name__)) + def check_lower(value: OnchainSendResponse): + if not isinstance(value, OnchainSendResponse): + raise TypeError("Expected OnchainSendResponse instance, {} found".format(type(value).__name__)) @staticmethod - def lower(value: HandleProtocol): - if not isinstance(value, Handle): - raise TypeError("Expected Handle instance, {} found".format(type(value).__name__)) + def lower(value: OnchainSendResponseProtocol): + if not isinstance(value, OnchainSendResponse): + raise TypeError("Expected OnchainSendResponse instance, {} found".format(type(value).__name__)) return value._uniffi_clone_pointer() @classmethod @@ -1415,37 +3014,25 @@ def read(cls, buf: _UniffiRustBuffer): return cls.lift(ptr) @classmethod - def write(cls, value: HandleProtocol, buf: _UniffiRustBuffer): + def write(cls, value: OnchainSendResponseProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) -class NodeProtocol(typing.Protocol): - """ - The `Node` is an RPC stub representing the node running in the - cloud. It is the main entrypoint to interact with the node. - """ - +class ReceiveResponseProtocol(typing.Protocol): pass -# Node is a Rust-only trait - it's a wrapper around a Rust implementation. -class Node(): - """ - The `Node` is an RPC stub representing the node running in the - cloud. It is the main entrypoint to interact with the node. - """ - +# ReceiveResponse is a Rust-only trait - it's a wrapper around a Rust implementation. +class ReceiveResponse(): _pointer: ctypes.c_void_p - def __init__(self, credentials: "Credentials"): - _UniffiConverterTypeCredentials.check_lower(credentials) - - self._pointer = _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_constructor_node_new, - _UniffiConverterTypeCredentials.lower(credentials)) + + def __init__(self, *args, **kwargs): + raise ValueError("This class has no default constructor") def __del__(self): # In case of partial initialization of instances. pointer = getattr(self, "_pointer", None) if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_node, pointer) + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_receiveresponse, pointer) def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_node, self._pointer) + return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_receiveresponse, self._pointer) # Used by alternative constructors or any methods which return this type. @classmethod @@ -1458,21 +3045,21 @@ def _make_instance_(cls, pointer): -class _UniffiConverterTypeNode: +class _UniffiConverterTypeReceiveResponse: @staticmethod def lift(value: int): - return Node._make_instance_(value) + return ReceiveResponse._make_instance_(value) @staticmethod - def check_lower(value: Node): - if not isinstance(value, Node): - raise TypeError("Expected Node instance, {} found".format(type(value).__name__)) + def check_lower(value: ReceiveResponse): + if not isinstance(value, ReceiveResponse): + raise TypeError("Expected ReceiveResponse instance, {} found".format(type(value).__name__)) @staticmethod - def lower(value: NodeProtocol): - if not isinstance(value, Node): - raise TypeError("Expected Node instance, {} found".format(type(value).__name__)) + def lower(value: ReceiveResponseProtocol): + if not isinstance(value, ReceiveResponse): + raise TypeError("Expected ReceiveResponse instance, {} found".format(type(value).__name__)) return value._uniffi_clone_pointer() @classmethod @@ -1483,7 +3070,7 @@ def read(cls, buf: _UniffiRustBuffer): return cls.lift(ptr) @classmethod - def write(cls, value: NodeProtocol, buf: _UniffiRustBuffer): + def write(cls, value: ReceiveResponseProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) class SchedulerProtocol(typing.Protocol): def recover(self, signer: "Signer"): @@ -1578,6 +3165,62 @@ def read(cls, buf: _UniffiRustBuffer): @classmethod def write(cls, value: SchedulerProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) +class SendResponseProtocol(typing.Protocol): + pass +# SendResponse is a Rust-only trait - it's a wrapper around a Rust implementation. +class SendResponse(): + _pointer: ctypes.c_void_p + + def __init__(self, *args, **kwargs): + raise ValueError("This class has no default constructor") + + def __del__(self): + # In case of partial initialization of instances. + pointer = getattr(self, "_pointer", None) + if pointer is not None: + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_sendresponse, pointer) + + def _uniffi_clone_pointer(self): + return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_sendresponse, self._pointer) + + # Used by alternative constructors or any methods which return this type. + @classmethod + def _make_instance_(cls, pointer): + # Lightly yucky way to bypass the usual __init__ logic + # and just create a new instance with the required pointer. + inst = cls.__new__(cls) + inst._pointer = pointer + return inst + + + +class _UniffiConverterTypeSendResponse: + + @staticmethod + def lift(value: int): + return SendResponse._make_instance_(value) + + @staticmethod + def check_lower(value: SendResponse): + if not isinstance(value, SendResponse): + raise TypeError("Expected SendResponse instance, {} found".format(type(value).__name__)) + + @staticmethod + def lower(value: SendResponseProtocol): + if not isinstance(value, SendResponse): + raise TypeError("Expected SendResponse instance, {} found".format(type(value).__name__)) + return value._uniffi_clone_pointer() + + @classmethod + def read(cls, buf: _UniffiRustBuffer): + ptr = buf.read_u64() + if ptr == 0: + raise InternalError("Raw pointer value was null") + return cls.lift(ptr) + + @classmethod + def write(cls, value: SendResponseProtocol, buf: _UniffiRustBuffer): + buf.write_u64(cls.lower(value)) class SignerProtocol(typing.Protocol): def authenticate(self, creds: "Credentials"): raise NotImplementedError @@ -1676,12 +3319,27 @@ def write(cls, value: SignerProtocol, buf: _UniffiRustBuffer): __all__ = [ "InternalError", + "ChannelState", "Error", "Network", + "OutputStatus", + "PayStatus", + "FundChannel", + "FundOutput", + "GetInfoResponse", + "ListFundsResponse", + "ListPeerChannelsResponse", + "ListPeersResponse", + "Peer", + "PeerChannel", "Credentials", "Handle", "Node", + "OnchainReceiveResponse", + "OnchainSendResponse", + "ReceiveResponse", "Scheduler", + "SendResponse", "Signer", ] From 61325fad07c7e33f5e42f3607f326ca368bc74ac Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 12:46:34 +0100 Subject: [PATCH 04/16] gl-sdk: Add tests for node information methods Add pytest tests verifying the new node methods and response types: - Test that all response types exist in bindings - Test that Node class has the expected methods - Test that response type fields are accessible and correctly typed - Test Record types (Peer, PeerChannel, FundOutput, FundChannel) - Test enum types (ChannelState, OutputStatus) Also add pytest-cov dev dependency and configure warning filter to suppress X.509 CN length warnings from gl-testing certificate generation. --- libs/gl-sdk/pyproject.toml | 10 ++ libs/gl-sdk/tests/test_node_methods.py | 188 +++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 libs/gl-sdk/tests/test_node_methods.py diff --git a/libs/gl-sdk/pyproject.toml b/libs/gl-sdk/pyproject.toml index bfc823dea..91bda92f6 100644 --- a/libs/gl-sdk/pyproject.toml +++ b/libs/gl-sdk/pyproject.toml @@ -25,6 +25,7 @@ dev = [ "gl-testing", "pdoc>=15.0.4", "pytest>=7.0", + "pytest-cov>=7.0.0", "pytest-watcher>=0.4.3", "rich>=10.0", ] @@ -37,3 +38,12 @@ testpaths = ["tests"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"] +filterwarnings = [ + # Suppress X.509 CN length warning from gl-testing cert generation. + # The CN field includes the full node_id (66 hex chars), exceeding the + # 64-character limit specified in RFC 5280. This is safe to ignore because: + # - We control both client (gl-client) and server sides of the connection + # - gl-client's TLS implementation doesn't enforce strict X.509 CN length + # - This only affects test infrastructure, not production certificates + "ignore:Attribute's length must be >= 1 and <= 64:UserWarning", +] diff --git a/libs/gl-sdk/tests/test_node_methods.py b/libs/gl-sdk/tests/test_node_methods.py new file mode 100644 index 000000000..009edaadd --- /dev/null +++ b/libs/gl-sdk/tests/test_node_methods.py @@ -0,0 +1,188 @@ +"""Tests for Node methods like get_info, list_peers, list_peer_channels, list_funds. + +These tests verify that the UniFFI bindings correctly expose the new Node methods +and their response types. +""" + +import pytest +import glsdk + + +class TestResponseTypes: + """Test that response types are properly defined in the bindings.""" + + def test_get_info_response_type_exists(self): + """Test that GetInfoResponse type is available.""" + assert hasattr(glsdk, "GetInfoResponse") + + def test_list_peers_response_type_exists(self): + """Test that ListPeersResponse type is available.""" + assert hasattr(glsdk, "ListPeersResponse") + + def test_list_peer_channels_response_type_exists(self): + """Test that ListPeerChannelsResponse type is available.""" + assert hasattr(glsdk, "ListPeerChannelsResponse") + + def test_list_funds_response_type_exists(self): + """Test that ListFundsResponse type is available.""" + assert hasattr(glsdk, "ListFundsResponse") + + def test_peer_type_exists(self): + """Test that Peer type is available.""" + assert hasattr(glsdk, "Peer") + + def test_peer_channel_type_exists(self): + """Test that PeerChannel type is available.""" + assert hasattr(glsdk, "PeerChannel") + + def test_fund_output_type_exists(self): + """Test that FundOutput type is available.""" + assert hasattr(glsdk, "FundOutput") + + def test_fund_channel_type_exists(self): + """Test that FundChannel type is available.""" + assert hasattr(glsdk, "FundChannel") + + def test_channel_state_enum_exists(self): + """Test that ChannelState enum is available.""" + assert hasattr(glsdk, "ChannelState") + # Check some enum variants + assert hasattr(glsdk.ChannelState, "OPENINGD") + assert hasattr(glsdk.ChannelState, "CHANNELD_NORMAL") + assert hasattr(glsdk.ChannelState, "ONCHAIN") + + def test_output_status_enum_exists(self): + """Test that OutputStatus enum is available.""" + assert hasattr(glsdk, "OutputStatus") + # Check enum variants + assert hasattr(glsdk.OutputStatus, "UNCONFIRMED") + assert hasattr(glsdk.OutputStatus, "CONFIRMED") + assert hasattr(glsdk.OutputStatus, "SPENT") + + +class TestNodeMethods: + """Test that Node has the expected methods.""" + + def test_node_has_get_info_method(self): + """Test that Node class has get_info method.""" + assert hasattr(glsdk.Node, "get_info") + + def test_node_has_list_peers_method(self): + """Test that Node class has list_peers method.""" + assert hasattr(glsdk.Node, "list_peers") + + def test_node_has_list_peer_channels_method(self): + """Test that Node class has list_peer_channels method.""" + assert hasattr(glsdk.Node, "list_peer_channels") + + def test_node_has_list_funds_method(self): + """Test that Node class has list_funds method.""" + assert hasattr(glsdk.Node, "list_funds") + + +class TestResponseTypeFields: + """Test that response types have expected fields.""" + + def test_get_info_response_has_expected_fields(self): + """Test GetInfoResponse has expected field attributes.""" + # Create instance to check fields + response = glsdk.GetInfoResponse( + id=b"\x02" * 33, + alias="test-node", + color=b"\xff\x00\x00", + num_peers=0, + num_pending_channels=0, + num_active_channels=0, + num_inactive_channels=0, + version="v24.11", + lightning_dir="/tmp/lightning", + blockheight=100, + network="regtest", + fees_collected_msat=0, + ) + assert response.id == b"\x02" * 33 + assert response.alias == "test-node" + assert response.network == "regtest" + assert response.blockheight == 100 + + def test_list_peers_response_has_peers_field(self): + """Test ListPeersResponse has peers field.""" + response = glsdk.ListPeersResponse(peers=[]) + assert response.peers == [] + + def test_list_peer_channels_response_has_channels_field(self): + """Test ListPeerChannelsResponse has channels field.""" + response = glsdk.ListPeerChannelsResponse(channels=[]) + assert response.channels == [] + + def test_list_funds_response_has_expected_fields(self): + """Test ListFundsResponse has outputs and channels fields.""" + response = glsdk.ListFundsResponse(outputs=[], channels=[]) + assert response.outputs == [] + assert response.channels == [] + + def test_peer_record_has_expected_fields(self): + """Test Peer record has expected fields.""" + peer = glsdk.Peer( + id=b"\x03" * 33, + connected=True, + num_channels=1, + netaddr=["127.0.0.1:9735"], + remote_addr="192.168.1.1:9735", + features=b"\x00", + ) + assert peer.id == b"\x03" * 33 + assert peer.connected is True + assert peer.num_channels == 1 + assert "127.0.0.1:9735" in peer.netaddr + + def test_peer_channel_record_has_expected_fields(self): + """Test PeerChannel record has expected fields.""" + channel = glsdk.PeerChannel( + peer_id=b"\x03" * 33, + peer_connected=True, + state=glsdk.ChannelState.CHANNELD_NORMAL, + short_channel_id="123x1x0", + channel_id=b"\x00" * 32, + funding_txid=b"\xab" * 32, + funding_outnum=0, + to_us_msat=500000000, + total_msat=1000000000, + spendable_msat=400000000, + receivable_msat=400000000, + ) + assert channel.peer_id == b"\x03" * 33 + assert channel.peer_connected is True + assert channel.state == glsdk.ChannelState.CHANNELD_NORMAL + assert channel.total_msat == 1000000000 + + def test_fund_output_record_has_expected_fields(self): + """Test FundOutput record has expected fields.""" + output = glsdk.FundOutput( + txid=b"\xab" * 32, + output=0, + amount_msat=1000000000, + status=glsdk.OutputStatus.CONFIRMED, + address="bcrt1qtest", + blockheight=100, + ) + assert output.txid == b"\xab" * 32 + assert output.amount_msat == 1000000000 + assert output.status == glsdk.OutputStatus.CONFIRMED + + def test_fund_channel_record_has_expected_fields(self): + """Test FundChannel record has expected fields.""" + channel = glsdk.FundChannel( + peer_id=b"\x03" * 33, + our_amount_msat=500000000, + amount_msat=1000000000, + funding_txid=b"\xab" * 32, + funding_output=0, + connected=True, + state=glsdk.ChannelState.CHANNELD_NORMAL, + short_channel_id="123x1x0", + channel_id=b"\x00" * 32, + ) + assert channel.peer_id == b"\x03" * 33 + assert channel.our_amount_msat == 500000000 + assert channel.connected is True From c929e2605d3311d41ae483394199d25c68a846c9 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 12:46:42 +0100 Subject: [PATCH 05/16] gl-testing: Document X.509 CN length warning Add documentation explaining the UserWarning about X.509 CN field length exceeding 64 characters (RFC 5280 limit). The warning occurs because test certificates include the full node_id (66 hex chars) in the CN field. This is safe to ignore because: - We control both client (gl-client) and server sides - gl-client doesn't enforce strict X.509 CN length validation - Only affects test infrastructure, not production certificates Added: - "Known Warnings" section in README.md with suppression instructions - Explanatory comment in certs.py where the warning originates --- libs/gl-testing/README.md | 34 ++++++++++++++++++++++++++++++ libs/gl-testing/gltesting/certs.py | 7 +++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/libs/gl-testing/README.md b/libs/gl-testing/README.md index f4bf892db..d7ac4854d 100644 --- a/libs/gl-testing/README.md +++ b/libs/gl-testing/README.md @@ -145,6 +145,40 @@ TBD scheduled on the first `Scheduler.schedule` call and will run until the test completes. +## Known Warnings + +### X.509 CN Length Warning + +When running tests, you may see warnings like: + +``` +UserWarning: Attribute's length must be >= 1 and <= 64, but it was 81 +``` + +This warning comes from the `cryptography` library when generating +test certificates. The Common Name (CN) field in test certificates +includes the full node_id (a 66-character hex string), which exceeds +the 64-character limit specified in RFC 5280. + +**This warning is safe to ignore** because: + +- We control both the client (`gl-client`) and server sides of all + connections in the test environment +- `gl-client`'s TLS implementation does not enforce strict X.509 CN + length validation +- This only affects test infrastructure certificates, not production + certificates issued by Greenlight + +To suppress this warning in your test suite, add the following to your +`pyproject.toml`: + +```toml +[tool.pytest.ini_options] +filterwarnings = [ + "ignore:Attribute's length must be >= 1 and <= 64:UserWarning", +] +``` + ## Local Setup ### Dependencies diff --git a/libs/gl-testing/gltesting/certs.py b/libs/gl-testing/gltesting/certs.py index 7a7dd966c..ecd030183 100644 --- a/libs/gl-testing/gltesting/certs.py +++ b/libs/gl-testing/gltesting/certs.py @@ -232,7 +232,12 @@ def gencert(idpath): def gencert_from_csr(csr: bytes, recover=False, pairing=False): """Generate a leaf certificate to be used for actual communication from certificate signing request.""" - # Get idpath from CN value in certificate signing request + # Get idpath from CN value in certificate signing request. + # Note: This may trigger a UserWarning about CN length exceeding 64 chars + # (RFC 5280 limit) because the CN includes the full node_id (66 hex chars). + # This is safe to ignore since we control both client (gl-client) and server + # sides, and gl-client doesn't enforce strict X.509 CN length validation. + # See README.md "Known Warnings" section for details. mycsr = x509.load_pem_x509_csr(csr, default_backend) idpath = mycsr.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value From 6d1192c70b1b9ceac33d39056128a366dd32b2dd Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 14:36:09 +0100 Subject: [PATCH 06/16] gl-plugin: Add generic Event enum with EventBus Introduce a flexible event system that supports extension by downstream crates like gl-plugin-internal: - Event is generic over internal payload type I - In gl-plugin, I defaults to () (no internal events) - EventBus uses Arc for type erasure at the boundary - Provides map_internal/try_map_internal for transformations - ErasedEventExt trait for downcasting erased events - Includes unit tests for the event system This prepares for real-time event streaming to gl-sdk clients while allowing gl-plugin-internal to inject its own event types. --- libs/gl-plugin/src/events.rs | 235 +++++++++++++++++++++++++++++++++++ libs/gl-plugin/src/lib.rs | 15 +-- 2 files changed, 239 insertions(+), 11 deletions(-) create mode 100644 libs/gl-plugin/src/events.rs diff --git a/libs/gl-plugin/src/events.rs b/libs/gl-plugin/src/events.rs new file mode 100644 index 000000000..c5e0fd477 --- /dev/null +++ b/libs/gl-plugin/src/events.rs @@ -0,0 +1,235 @@ +//! Event system for gl-plugin with support for internal extensions. +//! +//! This module provides a generic `Event` enum that can be extended +//! by downstream crates (like gl-plugin-internal) with custom internal +//! event types, while keeping the core events defined here. + +use crate::pb; +use crate::stager; +use std::any::Any; +use std::fmt::Debug; +use std::sync::Arc; +use tokio::sync::broadcast; + +/// An event that can be observed during the operation of the plugin. +/// +/// The type parameter `I` allows downstream crates to extend the event +/// system with internal-only event types. In gl-plugin, `I` defaults to +/// `()` (no internal events). In gl-plugin-internal, `I` is set to +/// `InternalPayload` containing events like `NodeMeta`, `Shutdown`, etc. +#[non_exhaustive] +#[derive(Clone, Debug)] +pub enum Event { + /// The plugin is stopping. + Stop(Arc), + + /// A gRPC call was made. The string is the URI of the request. + RpcCall(String), + + /// An incoming payment was received (invoice paid). + IncomingPayment(pb::IncomingPayment), + + /// A custom message was received from a peer. + CustomMsg(pb::Custommsg), + + /// Internal events from gl-plugin-internal or other extensions. + /// This variant is not used when `I = ()`. + Internal(I), +} + +impl Event { + /// Transform the internal payload type using a mapping function. + pub fn map_internal(self, f: F) -> Event + where + F: FnOnce(I) -> J, + { + match self { + Event::Stop(s) => Event::Stop(s), + Event::RpcCall(r) => Event::RpcCall(r), + Event::IncomingPayment(p) => Event::IncomingPayment(p), + Event::CustomMsg(m) => Event::CustomMsg(m), + Event::Internal(i) => Event::Internal(f(i)), + } + } + + /// Try to transform the internal payload, returning None if the + /// transformation fails. + pub fn try_map_internal(self, f: F) -> Option> + where + F: FnOnce(I) -> Option, + { + match self { + Event::Stop(s) => Some(Event::Stop(s)), + Event::RpcCall(r) => Some(Event::RpcCall(r)), + Event::IncomingPayment(p) => Some(Event::IncomingPayment(p)), + Event::CustomMsg(m) => Some(Event::CustomMsg(m)), + Event::Internal(i) => f(i).map(Event::Internal), + } + } +} + +/// Type alias for the erased internal event type used by EventBus. +/// Uses Arc for clonability required by broadcast channel. +pub type ErasedInternal = Arc; + +/// Type alias for events with type-erased internal payload. +pub type ErasedEvent = Event; + +/// An event bus that supports multiple subscribers and type-erased +/// internal events. +/// +/// The bus internally stores `Event>` to +/// allow publishing events with any internal payload type. Subscribers +/// can then downcast back to their expected type. +#[derive(Clone)] +pub struct EventBus { + sender: broadcast::Sender, +} + +impl EventBus { + /// Create a new event bus with the given capacity. + pub fn new(capacity: usize) -> Self { + let (sender, _) = broadcast::channel(capacity); + Self { sender } + } + + /// Publish an event with a typed internal payload. + /// + /// The internal payload is type-erased before being sent on the bus. + pub fn publish(&self, event: Event) + where + I: Send + Sync + 'static, + { + let erased = event.map_internal(|i| Arc::new(i) as ErasedInternal); + // Ignore error if no subscribers + let _ = self.sender.send(erased); + } + + /// Subscribe to receive all events with type-erased internal payloads. + pub fn subscribe(&self) -> broadcast::Receiver { + self.sender.subscribe() + } + + /// Get a clone of the sender for sharing across tasks. + pub fn sender(&self) -> broadcast::Sender { + self.sender.clone() + } +} + +impl Default for EventBus { + fn default() -> Self { + Self::new(16) + } +} + +/// Extension trait for working with erased events. +pub trait ErasedEventExt { + /// Try to downcast the internal payload to a specific type. + /// + /// Returns `Some(&T)` if the event is `Event::Internal` and the + /// payload can be downcast to `T`, otherwise returns `None`. + fn downcast_internal(&self) -> Option<&T>; + + /// Try to convert this erased event back to a typed event. + /// + /// Returns `Some(Event)` if the internal payload (if present) + /// can be downcast to `I`, otherwise returns `None`. + fn try_into_typed(&self) -> Option>; +} + +impl ErasedEventExt for ErasedEvent { + fn downcast_internal(&self) -> Option<&T> { + match self { + Event::Internal(any) => any.downcast_ref::(), + _ => None, + } + } + + fn try_into_typed(&self) -> Option> { + match self { + Event::Stop(s) => Some(Event::Stop(s.clone())), + Event::RpcCall(r) => Some(Event::RpcCall(r.clone())), + Event::IncomingPayment(p) => Some(Event::IncomingPayment(p.clone())), + Event::CustomMsg(m) => Some(Event::CustomMsg(m.clone())), + Event::Internal(any) => any.downcast_ref::().cloned().map(Event::Internal), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[derive(Clone, Debug, PartialEq)] + struct TestInternal { + value: i32, + } + + #[test] + fn test_event_map_internal() { + let event: Event = Event::Internal(42); + let mapped: Event = event.map_internal(|i| i.to_string()); + match mapped { + Event::Internal(s) => assert_eq!(s, "42"), + _ => panic!("Expected Internal variant"), + } + } + + #[test] + fn test_event_map_internal_preserves_other_variants() { + let event: Event = Event::RpcCall("test".to_string()); + let mapped: Event = event.map_internal(|i| i.to_string()); + match mapped { + Event::RpcCall(s) => assert_eq!(s, "test"), + _ => panic!("Expected RpcCall variant"), + } + } + + #[tokio::test] + async fn test_event_bus_publish_subscribe() { + let bus = EventBus::new(8); + let mut rx = bus.subscribe(); + + bus.publish(Event::<()>::RpcCall("test_method".to_string())); + + let received = rx.recv().await.unwrap(); + match received { + Event::RpcCall(method) => assert_eq!(method, "test_method"), + _ => panic!("Expected RpcCall"), + } + } + + #[tokio::test] + async fn test_event_bus_with_internal_payload() { + let bus = EventBus::new(8); + let mut rx = bus.subscribe(); + + let internal = TestInternal { value: 123 }; + bus.publish(Event::Internal(internal.clone())); + + let received = rx.recv().await.unwrap(); + let downcasted = received.downcast_internal::(); + assert_eq!(downcasted, Some(&internal)); + } + + #[test] + fn test_erased_event_try_into_typed() { + let bus = EventBus::new(8); + + // Publish a typed event + let internal = TestInternal { value: 456 }; + let event = Event::Internal(internal.clone()); + let erased = event.map_internal(|i| Arc::new(i) as ErasedInternal); + + // Try to convert back + let typed: Option> = erased.try_into_typed(); + assert!(typed.is_some()); + match typed.unwrap() { + Event::Internal(t) => assert_eq!(t, internal), + _ => panic!("Expected Internal variant"), + } + + // Suppress unused variable warning + let _ = bus; + } +} diff --git a/libs/gl-plugin/src/lib.rs b/libs/gl-plugin/src/lib.rs index 04ed784f0..b940f71c4 100644 --- a/libs/gl-plugin/src/lib.rs +++ b/libs/gl-plugin/src/lib.rs @@ -11,6 +11,7 @@ extern crate gl_util; mod awaitables; pub mod config; +pub mod events; pub mod hsm; mod lsp; pub mod messages; @@ -27,6 +28,9 @@ mod unix; mod context; +// Re-export the event types for convenience and backwards compatibility +pub use events::{ErasedEvent, ErasedEventExt, ErasedInternal, Event, EventBus}; + #[derive(Clone)] pub struct GlPlugin { stage: Arc, @@ -290,15 +294,4 @@ async fn on_invoice_payment(plugin: Plugin, v: serde_json::Value) -> Result), - - /// A grpc call. The first element is the URI of the request. - RpcCall(String), - IncomingPayment(pb::IncomingPayment), - CustomMsg(pb::Custommsg), -} - pub use cln_grpc as grpc; From 1eaf3335dd83777474b08af9c23cc91b140f08af Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 15:03:16 +0100 Subject: [PATCH 07/16] gl-sdk: Regenerate UniFFI Python bindings Sync Python bindings with current Rust library to fix symbol mismatch. --- libs/gl-sdk/bindings/glsdk.py | 461 +++++++++++++--------------------- libs/gl-sdk/glsdk/glsdk.py | 461 +++++++++++++--------------------- 2 files changed, 354 insertions(+), 568 deletions(-) diff --git a/libs/gl-sdk/bindings/glsdk.py b/libs/gl-sdk/bindings/glsdk.py index 39d1e291b..8a564a63c 100644 --- a/libs/gl-sdk/bindings/glsdk.py +++ b/libs/gl-sdk/bindings/glsdk.py @@ -472,13 +472,13 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_node_list_peers() != 29567: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_onchain_receive() != 21676: + if lib.uniffi_glsdk_checksum_method_node_onchain_receive() != 57530: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_onchain_send() != 51884: + if lib.uniffi_glsdk_checksum_method_node_onchain_send() != 44346: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_receive() != 24722: + if lib.uniffi_glsdk_checksum_method_node_receive() != 39761: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_send() != 30141: + if lib.uniffi_glsdk_checksum_method_node_send() != 4348: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_node_stop() != 20186: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") @@ -680,14 +680,14 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), ) -_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.argtypes = ( ctypes.c_void_p, _UniffiRustBuffer, _UniffiRustBuffer, ctypes.POINTER(_UniffiRustCallStatus), ) -_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_method_node_receive.argtypes = ( ctypes.c_void_p, _UniffiRustBuffer, @@ -695,49 +695,19 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiRustBuffer, ctypes.POINTER(_UniffiRustCallStatus), ) -_UniffiLib.uniffi_glsdk_fn_method_node_receive.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_receive.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_method_node_send.argtypes = ( ctypes.c_void_p, _UniffiRustBuffer, _UniffiRustBuffer, ctypes.POINTER(_UniffiRustCallStatus), ) -_UniffiLib.uniffi_glsdk_fn_method_node_send.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_send.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_method_node_stop.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_method_node_stop.restype = None -_UniffiLib.uniffi_glsdk_fn_clone_onchainreceiveresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_onchainreceiveresponse.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_onchainreceiveresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_onchainreceiveresponse.restype = None -_UniffiLib.uniffi_glsdk_fn_clone_onchainsendresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_onchainsendresponse.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_onchainsendresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_onchainsendresponse.restype = None -_UniffiLib.uniffi_glsdk_fn_clone_receiveresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_receiveresponse.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_receiveresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_receiveresponse.restype = None _UniffiLib.uniffi_glsdk_fn_clone_scheduler.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -766,16 +736,6 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_method_scheduler_register.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_clone_sendresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_sendresponse.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_sendresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_sendresponse.restype = None _UniffiLib.uniffi_glsdk_fn_clone_signer.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -1255,14 +1215,6 @@ def write(value, buf): - - - - - - - - class FundChannel: peer_id: "bytes" our_amount_msat: "int" @@ -1612,6 +1564,85 @@ def write(value, buf): _UniffiConverterSequenceTypePeer.write(value.peers, buf) +class OnchainReceiveResponse: + bech32: "str" + p2tr: "str" + def __init__(self, *, bech32: "str", p2tr: "str"): + self.bech32 = bech32 + self.p2tr = p2tr + + def __str__(self): + return "OnchainReceiveResponse(bech32={}, p2tr={})".format(self.bech32, self.p2tr) + + def __eq__(self, other): + if self.bech32 != other.bech32: + return False + if self.p2tr != other.p2tr: + return False + return True + +class _UniffiConverterTypeOnchainReceiveResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return OnchainReceiveResponse( + bech32=_UniffiConverterString.read(buf), + p2tr=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.bech32) + _UniffiConverterString.check_lower(value.p2tr) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.bech32, buf) + _UniffiConverterString.write(value.p2tr, buf) + + +class OnchainSendResponse: + tx: "bytes" + txid: "bytes" + psbt: "str" + def __init__(self, *, tx: "bytes", txid: "bytes", psbt: "str"): + self.tx = tx + self.txid = txid + self.psbt = psbt + + def __str__(self): + return "OnchainSendResponse(tx={}, txid={}, psbt={})".format(self.tx, self.txid, self.psbt) + + def __eq__(self, other): + if self.tx != other.tx: + return False + if self.txid != other.txid: + return False + if self.psbt != other.psbt: + return False + return True + +class _UniffiConverterTypeOnchainSendResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return OnchainSendResponse( + tx=_UniffiConverterBytes.read(buf), + txid=_UniffiConverterBytes.read(buf), + psbt=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.tx) + _UniffiConverterBytes.check_lower(value.txid) + _UniffiConverterString.check_lower(value.psbt) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.tx, buf) + _UniffiConverterBytes.write(value.txid, buf) + _UniffiConverterString.write(value.psbt, buf) + + class Peer: id: "bytes" connected: "bool" @@ -1775,6 +1806,92 @@ def write(value, buf): _UniffiConverterOptionalUInt64.write(value.receivable_msat, buf) +class ReceiveResponse: + bolt11: "str" + def __init__(self, *, bolt11: "str"): + self.bolt11 = bolt11 + + def __str__(self): + return "ReceiveResponse(bolt11={})".format(self.bolt11) + + def __eq__(self, other): + if self.bolt11 != other.bolt11: + return False + return True + +class _UniffiConverterTypeReceiveResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ReceiveResponse( + bolt11=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.bolt11) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.bolt11, buf) + + +class SendResponse: + status: "PayStatus" + preimage: "bytes" + amount_msat: "int" + amount_sent_msat: "int" + parts: "int" + def __init__(self, *, status: "PayStatus", preimage: "bytes", amount_msat: "int", amount_sent_msat: "int", parts: "int"): + self.status = status + self.preimage = preimage + self.amount_msat = amount_msat + self.amount_sent_msat = amount_sent_msat + self.parts = parts + + def __str__(self): + return "SendResponse(status={}, preimage={}, amount_msat={}, amount_sent_msat={}, parts={})".format(self.status, self.preimage, self.amount_msat, self.amount_sent_msat, self.parts) + + def __eq__(self, other): + if self.status != other.status: + return False + if self.preimage != other.preimage: + return False + if self.amount_msat != other.amount_msat: + return False + if self.amount_sent_msat != other.amount_sent_msat: + return False + if self.parts != other.parts: + return False + return True + +class _UniffiConverterTypeSendResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SendResponse( + status=_UniffiConverterTypePayStatus.read(buf), + preimage=_UniffiConverterBytes.read(buf), + amount_msat=_UniffiConverterUInt64.read(buf), + amount_sent_msat=_UniffiConverterUInt64.read(buf), + parts=_UniffiConverterUInt32.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterTypePayStatus.check_lower(value.status) + _UniffiConverterBytes.check_lower(value.preimage) + _UniffiConverterUInt64.check_lower(value.amount_msat) + _UniffiConverterUInt64.check_lower(value.amount_sent_msat) + _UniffiConverterUInt32.check_lower(value.parts) + + @staticmethod + def write(value, buf): + _UniffiConverterTypePayStatus.write(value.status, buf) + _UniffiConverterBytes.write(value.preimage, buf) + _UniffiConverterUInt64.write(value.amount_msat, buf) + _UniffiConverterUInt64.write(value.amount_sent_msat, buf) + _UniffiConverterUInt32.write(value.parts, buf) + + @@ -2904,174 +3021,6 @@ def read(cls, buf: _UniffiRustBuffer): @classmethod def write(cls, value: NodeProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) -class OnchainReceiveResponseProtocol(typing.Protocol): - pass -# OnchainReceiveResponse is a Rust-only trait - it's a wrapper around a Rust implementation. -class OnchainReceiveResponse(): - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_onchainreceiveresponse, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_onchainreceiveresponse, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - -class _UniffiConverterTypeOnchainReceiveResponse: - - @staticmethod - def lift(value: int): - return OnchainReceiveResponse._make_instance_(value) - - @staticmethod - def check_lower(value: OnchainReceiveResponse): - if not isinstance(value, OnchainReceiveResponse): - raise TypeError("Expected OnchainReceiveResponse instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: OnchainReceiveResponseProtocol): - if not isinstance(value, OnchainReceiveResponse): - raise TypeError("Expected OnchainReceiveResponse instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: OnchainReceiveResponseProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) -class OnchainSendResponseProtocol(typing.Protocol): - pass -# OnchainSendResponse is a Rust-only trait - it's a wrapper around a Rust implementation. -class OnchainSendResponse(): - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_onchainsendresponse, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_onchainsendresponse, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - -class _UniffiConverterTypeOnchainSendResponse: - - @staticmethod - def lift(value: int): - return OnchainSendResponse._make_instance_(value) - - @staticmethod - def check_lower(value: OnchainSendResponse): - if not isinstance(value, OnchainSendResponse): - raise TypeError("Expected OnchainSendResponse instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: OnchainSendResponseProtocol): - if not isinstance(value, OnchainSendResponse): - raise TypeError("Expected OnchainSendResponse instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: OnchainSendResponseProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) -class ReceiveResponseProtocol(typing.Protocol): - pass -# ReceiveResponse is a Rust-only trait - it's a wrapper around a Rust implementation. -class ReceiveResponse(): - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_receiveresponse, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_receiveresponse, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - -class _UniffiConverterTypeReceiveResponse: - - @staticmethod - def lift(value: int): - return ReceiveResponse._make_instance_(value) - - @staticmethod - def check_lower(value: ReceiveResponse): - if not isinstance(value, ReceiveResponse): - raise TypeError("Expected ReceiveResponse instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: ReceiveResponseProtocol): - if not isinstance(value, ReceiveResponse): - raise TypeError("Expected ReceiveResponse instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: ReceiveResponseProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) class SchedulerProtocol(typing.Protocol): def recover(self, signer: "Signer"): raise NotImplementedError @@ -3165,62 +3114,6 @@ def read(cls, buf: _UniffiRustBuffer): @classmethod def write(cls, value: SchedulerProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) -class SendResponseProtocol(typing.Protocol): - pass -# SendResponse is a Rust-only trait - it's a wrapper around a Rust implementation. -class SendResponse(): - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_sendresponse, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_sendresponse, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - -class _UniffiConverterTypeSendResponse: - - @staticmethod - def lift(value: int): - return SendResponse._make_instance_(value) - - @staticmethod - def check_lower(value: SendResponse): - if not isinstance(value, SendResponse): - raise TypeError("Expected SendResponse instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: SendResponseProtocol): - if not isinstance(value, SendResponse): - raise TypeError("Expected SendResponse instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: SendResponseProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) class SignerProtocol(typing.Protocol): def authenticate(self, creds: "Credentials"): raise NotImplementedError @@ -3330,16 +3223,16 @@ def write(cls, value: SignerProtocol, buf: _UniffiRustBuffer): "ListFundsResponse", "ListPeerChannelsResponse", "ListPeersResponse", + "OnchainReceiveResponse", + "OnchainSendResponse", "Peer", "PeerChannel", + "ReceiveResponse", + "SendResponse", "Credentials", "Handle", "Node", - "OnchainReceiveResponse", - "OnchainSendResponse", - "ReceiveResponse", "Scheduler", - "SendResponse", "Signer", ] diff --git a/libs/gl-sdk/glsdk/glsdk.py b/libs/gl-sdk/glsdk/glsdk.py index 39d1e291b..8a564a63c 100644 --- a/libs/gl-sdk/glsdk/glsdk.py +++ b/libs/gl-sdk/glsdk/glsdk.py @@ -472,13 +472,13 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_node_list_peers() != 29567: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_onchain_receive() != 21676: + if lib.uniffi_glsdk_checksum_method_node_onchain_receive() != 57530: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_onchain_send() != 51884: + if lib.uniffi_glsdk_checksum_method_node_onchain_send() != 44346: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_receive() != 24722: + if lib.uniffi_glsdk_checksum_method_node_receive() != 39761: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_send() != 30141: + if lib.uniffi_glsdk_checksum_method_node_send() != 4348: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_node_stop() != 20186: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") @@ -680,14 +680,14 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), ) -_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.argtypes = ( ctypes.c_void_p, _UniffiRustBuffer, _UniffiRustBuffer, ctypes.POINTER(_UniffiRustCallStatus), ) -_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_method_node_receive.argtypes = ( ctypes.c_void_p, _UniffiRustBuffer, @@ -695,49 +695,19 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiRustBuffer, ctypes.POINTER(_UniffiRustCallStatus), ) -_UniffiLib.uniffi_glsdk_fn_method_node_receive.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_receive.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_method_node_send.argtypes = ( ctypes.c_void_p, _UniffiRustBuffer, _UniffiRustBuffer, ctypes.POINTER(_UniffiRustCallStatus), ) -_UniffiLib.uniffi_glsdk_fn_method_node_send.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_method_node_send.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_method_node_stop.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_method_node_stop.restype = None -_UniffiLib.uniffi_glsdk_fn_clone_onchainreceiveresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_onchainreceiveresponse.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_onchainreceiveresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_onchainreceiveresponse.restype = None -_UniffiLib.uniffi_glsdk_fn_clone_onchainsendresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_onchainsendresponse.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_onchainsendresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_onchainsendresponse.restype = None -_UniffiLib.uniffi_glsdk_fn_clone_receiveresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_receiveresponse.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_receiveresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_receiveresponse.restype = None _UniffiLib.uniffi_glsdk_fn_clone_scheduler.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -766,16 +736,6 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_method_scheduler_register.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_clone_sendresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_sendresponse.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_sendresponse.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_sendresponse.restype = None _UniffiLib.uniffi_glsdk_fn_clone_signer.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -1255,14 +1215,6 @@ def write(value, buf): - - - - - - - - class FundChannel: peer_id: "bytes" our_amount_msat: "int" @@ -1612,6 +1564,85 @@ def write(value, buf): _UniffiConverterSequenceTypePeer.write(value.peers, buf) +class OnchainReceiveResponse: + bech32: "str" + p2tr: "str" + def __init__(self, *, bech32: "str", p2tr: "str"): + self.bech32 = bech32 + self.p2tr = p2tr + + def __str__(self): + return "OnchainReceiveResponse(bech32={}, p2tr={})".format(self.bech32, self.p2tr) + + def __eq__(self, other): + if self.bech32 != other.bech32: + return False + if self.p2tr != other.p2tr: + return False + return True + +class _UniffiConverterTypeOnchainReceiveResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return OnchainReceiveResponse( + bech32=_UniffiConverterString.read(buf), + p2tr=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.bech32) + _UniffiConverterString.check_lower(value.p2tr) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.bech32, buf) + _UniffiConverterString.write(value.p2tr, buf) + + +class OnchainSendResponse: + tx: "bytes" + txid: "bytes" + psbt: "str" + def __init__(self, *, tx: "bytes", txid: "bytes", psbt: "str"): + self.tx = tx + self.txid = txid + self.psbt = psbt + + def __str__(self): + return "OnchainSendResponse(tx={}, txid={}, psbt={})".format(self.tx, self.txid, self.psbt) + + def __eq__(self, other): + if self.tx != other.tx: + return False + if self.txid != other.txid: + return False + if self.psbt != other.psbt: + return False + return True + +class _UniffiConverterTypeOnchainSendResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return OnchainSendResponse( + tx=_UniffiConverterBytes.read(buf), + txid=_UniffiConverterBytes.read(buf), + psbt=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.tx) + _UniffiConverterBytes.check_lower(value.txid) + _UniffiConverterString.check_lower(value.psbt) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.tx, buf) + _UniffiConverterBytes.write(value.txid, buf) + _UniffiConverterString.write(value.psbt, buf) + + class Peer: id: "bytes" connected: "bool" @@ -1775,6 +1806,92 @@ def write(value, buf): _UniffiConverterOptionalUInt64.write(value.receivable_msat, buf) +class ReceiveResponse: + bolt11: "str" + def __init__(self, *, bolt11: "str"): + self.bolt11 = bolt11 + + def __str__(self): + return "ReceiveResponse(bolt11={})".format(self.bolt11) + + def __eq__(self, other): + if self.bolt11 != other.bolt11: + return False + return True + +class _UniffiConverterTypeReceiveResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ReceiveResponse( + bolt11=_UniffiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterString.check_lower(value.bolt11) + + @staticmethod + def write(value, buf): + _UniffiConverterString.write(value.bolt11, buf) + + +class SendResponse: + status: "PayStatus" + preimage: "bytes" + amount_msat: "int" + amount_sent_msat: "int" + parts: "int" + def __init__(self, *, status: "PayStatus", preimage: "bytes", amount_msat: "int", amount_sent_msat: "int", parts: "int"): + self.status = status + self.preimage = preimage + self.amount_msat = amount_msat + self.amount_sent_msat = amount_sent_msat + self.parts = parts + + def __str__(self): + return "SendResponse(status={}, preimage={}, amount_msat={}, amount_sent_msat={}, parts={})".format(self.status, self.preimage, self.amount_msat, self.amount_sent_msat, self.parts) + + def __eq__(self, other): + if self.status != other.status: + return False + if self.preimage != other.preimage: + return False + if self.amount_msat != other.amount_msat: + return False + if self.amount_sent_msat != other.amount_sent_msat: + return False + if self.parts != other.parts: + return False + return True + +class _UniffiConverterTypeSendResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SendResponse( + status=_UniffiConverterTypePayStatus.read(buf), + preimage=_UniffiConverterBytes.read(buf), + amount_msat=_UniffiConverterUInt64.read(buf), + amount_sent_msat=_UniffiConverterUInt64.read(buf), + parts=_UniffiConverterUInt32.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterTypePayStatus.check_lower(value.status) + _UniffiConverterBytes.check_lower(value.preimage) + _UniffiConverterUInt64.check_lower(value.amount_msat) + _UniffiConverterUInt64.check_lower(value.amount_sent_msat) + _UniffiConverterUInt32.check_lower(value.parts) + + @staticmethod + def write(value, buf): + _UniffiConverterTypePayStatus.write(value.status, buf) + _UniffiConverterBytes.write(value.preimage, buf) + _UniffiConverterUInt64.write(value.amount_msat, buf) + _UniffiConverterUInt64.write(value.amount_sent_msat, buf) + _UniffiConverterUInt32.write(value.parts, buf) + + @@ -2904,174 +3021,6 @@ def read(cls, buf: _UniffiRustBuffer): @classmethod def write(cls, value: NodeProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) -class OnchainReceiveResponseProtocol(typing.Protocol): - pass -# OnchainReceiveResponse is a Rust-only trait - it's a wrapper around a Rust implementation. -class OnchainReceiveResponse(): - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_onchainreceiveresponse, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_onchainreceiveresponse, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - -class _UniffiConverterTypeOnchainReceiveResponse: - - @staticmethod - def lift(value: int): - return OnchainReceiveResponse._make_instance_(value) - - @staticmethod - def check_lower(value: OnchainReceiveResponse): - if not isinstance(value, OnchainReceiveResponse): - raise TypeError("Expected OnchainReceiveResponse instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: OnchainReceiveResponseProtocol): - if not isinstance(value, OnchainReceiveResponse): - raise TypeError("Expected OnchainReceiveResponse instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: OnchainReceiveResponseProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) -class OnchainSendResponseProtocol(typing.Protocol): - pass -# OnchainSendResponse is a Rust-only trait - it's a wrapper around a Rust implementation. -class OnchainSendResponse(): - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_onchainsendresponse, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_onchainsendresponse, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - -class _UniffiConverterTypeOnchainSendResponse: - - @staticmethod - def lift(value: int): - return OnchainSendResponse._make_instance_(value) - - @staticmethod - def check_lower(value: OnchainSendResponse): - if not isinstance(value, OnchainSendResponse): - raise TypeError("Expected OnchainSendResponse instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: OnchainSendResponseProtocol): - if not isinstance(value, OnchainSendResponse): - raise TypeError("Expected OnchainSendResponse instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: OnchainSendResponseProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) -class ReceiveResponseProtocol(typing.Protocol): - pass -# ReceiveResponse is a Rust-only trait - it's a wrapper around a Rust implementation. -class ReceiveResponse(): - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_receiveresponse, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_receiveresponse, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - -class _UniffiConverterTypeReceiveResponse: - - @staticmethod - def lift(value: int): - return ReceiveResponse._make_instance_(value) - - @staticmethod - def check_lower(value: ReceiveResponse): - if not isinstance(value, ReceiveResponse): - raise TypeError("Expected ReceiveResponse instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: ReceiveResponseProtocol): - if not isinstance(value, ReceiveResponse): - raise TypeError("Expected ReceiveResponse instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: ReceiveResponseProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) class SchedulerProtocol(typing.Protocol): def recover(self, signer: "Signer"): raise NotImplementedError @@ -3165,62 +3114,6 @@ def read(cls, buf: _UniffiRustBuffer): @classmethod def write(cls, value: SchedulerProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) -class SendResponseProtocol(typing.Protocol): - pass -# SendResponse is a Rust-only trait - it's a wrapper around a Rust implementation. -class SendResponse(): - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_sendresponse, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_sendresponse, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - -class _UniffiConverterTypeSendResponse: - - @staticmethod - def lift(value: int): - return SendResponse._make_instance_(value) - - @staticmethod - def check_lower(value: SendResponse): - if not isinstance(value, SendResponse): - raise TypeError("Expected SendResponse instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: SendResponseProtocol): - if not isinstance(value, SendResponse): - raise TypeError("Expected SendResponse instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: SendResponseProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) class SignerProtocol(typing.Protocol): def authenticate(self, creds: "Credentials"): raise NotImplementedError @@ -3330,16 +3223,16 @@ def write(cls, value: SignerProtocol, buf: _UniffiRustBuffer): "ListFundsResponse", "ListPeerChannelsResponse", "ListPeersResponse", + "OnchainReceiveResponse", + "OnchainSendResponse", "Peer", "PeerChannel", + "ReceiveResponse", + "SendResponse", "Credentials", "Handle", "Node", - "OnchainReceiveResponse", - "OnchainSendResponse", - "ReceiveResponse", "Scheduler", - "SendResponse", "Signer", ] From f7c7db2ac58a51148283f8f4631600d43649e130 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 15:14:51 +0100 Subject: [PATCH 08/16] gl-plugin: Add StreamNodeEvents gRPC for real-time event streaming Add NodeEvent protobuf messages and StreamNodeEvents RPC method: - NodeEventsRequest: Empty request (extensible for future filters) - NodeEvent: Wrapper with oneof for event discrimination - InvoicePaid: Event emitted when an invoice is paid The stream_node_events method converts internal Event to NodeEvent protobuf, filtering out internal-only events and exposing only client-relevant events like invoice payments. --- .../proto/glclient/greenlight.proto | 43 ++++++++++++++ libs/gl-plugin/src/node/mod.rs | 57 +++++++++++++++++++ libs/gl-plugin/src/node/wrapper.rs | 12 +++- 3 files changed, 110 insertions(+), 2 deletions(-) diff --git a/libs/gl-plugin/.resources/proto/glclient/greenlight.proto b/libs/gl-plugin/.resources/proto/glclient/greenlight.proto index 63dd182c0..94d2cfacd 100644 --- a/libs/gl-plugin/.resources/proto/glclient/greenlight.proto +++ b/libs/gl-plugin/.resources/proto/glclient/greenlight.proto @@ -43,6 +43,14 @@ service Node { // replayed if the stream is interrupted. rpc StreamCustommsg(StreamCustommsgRequest) returns (stream Custommsg) {} + // Stream node events in real-time. + // + // This is a unified event stream that delivers various node events + // as they occur, including invoice updates, peer changes, channel + // state changes, and balance updates. Events are not persisted and + // will not be replayed if the stream is interrupted. + rpc StreamNodeEvents(NodeEventsRequest) returns (stream NodeEvent) {} + //////////////////////////////// HSM Messages //////////////////////// // // The following messages are related to communicating HSM @@ -243,3 +251,38 @@ message LspInvoiceResponse { bytes payment_hash = 4; bytes payment_secret = 5; } + +// Request for streaming node events. Currently empty but defined as +// its own message type to allow adding filters in the future (e.g., +// filter by event type, invoice label, etc.) +message NodeEventsRequest { +} + +// A real-time event from the node. Uses oneof to discriminate between +// different event types. +message NodeEvent { + oneof event { + InvoicePaid invoice_paid = 1; + // Future event types: + // PeerConnected peer_connected = 2; + // PeerDisconnected peer_disconnected = 3; + // ChannelStateChanged channel_state_changed = 4; + // BalanceChanged balance_changed = 5; + } +} + +// Event emitted when an invoice is paid. +message InvoicePaid { + // The payment hash of the paid invoice. + bytes payment_hash = 1; + // The bolt11 invoice string. + string bolt11 = 2; + // The preimage that proves payment. + bytes preimage = 3; + // The label assigned to the invoice. + string label = 4; + // Amount received in millisatoshis. + uint64 amount_msat = 5; + // Extra TLV fields included in the payment. + repeated TlvField extratlvs = 6; +} diff --git a/libs/gl-plugin/src/node/mod.rs b/libs/gl-plugin/src/node/mod.rs index f3bbd3cfc..4c50d76ee 100644 --- a/libs/gl-plugin/src/node/mod.rs +++ b/libs/gl-plugin/src/node/mod.rs @@ -574,6 +574,63 @@ impl Node for PluginNodeServer { return Ok(Response::new(ReceiverStream::new(rx))); } + type StreamNodeEventsStream = ReceiverStream>; + + async fn stream_node_events( + &self, + _req: tonic::Request, + ) -> Result, Status> { + let (tx, rx) = mpsc::channel(1); + let mut bcast = self.events.subscribe(); + tokio::spawn(async move { + while let Ok(event) = bcast.recv().await { + // Convert Event to NodeEvent protobuf, if applicable + let node_event = match &event { + super::Event::IncomingPayment(p) => { + // Extract the offchain payment details + if let Some(crate::pb::incoming_payment::Details::Offchain(offchain)) = + &p.details + { + Some(pb::NodeEvent { + event: Some(pb::node_event::Event::InvoicePaid(pb::InvoicePaid { + payment_hash: offchain.payment_hash.clone(), + bolt11: offchain.bolt11.clone(), + preimage: offchain.preimage.clone(), + label: offchain.label.clone(), + amount_msat: offchain + .amount + .as_ref() + .and_then(|a| a.unit.as_ref()) + .map(|u| match u { + pb::amount::Unit::Millisatoshi(m) => *m, + pb::amount::Unit::Satoshi(s) => s * 1000, + pb::amount::Unit::Bitcoin(b) => b * 100_000_000_000, + _ => 0, + }) + .unwrap_or(0), + extratlvs: offchain.extratlvs.clone(), + })), + }) + } else { + None + } + } + // Other event types are not exposed to clients + _ => None, + }; + + if let Some(event) = node_event { + if tx.send(Ok(event)).await.is_err() { + // Client disconnected + break; + } + } + } + }); + + Ok(Response::new(ReceiverStream::new(rx))) + } + async fn configure( &self, req: tonic::Request, diff --git a/libs/gl-plugin/src/node/wrapper.rs b/libs/gl-plugin/src/node/wrapper.rs index e13a542a4..6c573daea 100644 --- a/libs/gl-plugin/src/node/wrapper.rs +++ b/libs/gl-plugin/src/node/wrapper.rs @@ -1192,8 +1192,8 @@ impl WrappedNodeServer { use crate::pb::{ node_server::Node as GlNode, Custommsg, Empty, HsmRequest, HsmResponse, IncomingPayment, - LogEntry, LspInvoiceRequest, LspInvoiceResponse, StreamCustommsgRequest, StreamIncomingFilter, - StreamLogRequest, + LogEntry, LspInvoiceRequest, LspInvoiceResponse, NodeEvent, NodeEventsRequest, + StreamCustommsgRequest, StreamIncomingFilter, StreamLogRequest, }; #[tonic::async_trait] @@ -1202,6 +1202,7 @@ impl GlNode for WrappedNodeServer { type StreamHsmRequestsStream = ReceiverStream>; type StreamLogStream = ReceiverStream>; type StreamIncomingStream = ReceiverStream>; + type StreamNodeEventsStream = ReceiverStream>; async fn lsp_invoice( &self, @@ -1266,4 +1267,11 @@ impl GlNode for WrappedNodeServer { ) -> Result, Status> { self.node_server.trampoline_pay(request).await } + + async fn stream_node_events( + &self, + req: tonic::Request, + ) -> Result, Status> { + self.node_server.stream_node_events(req).await + } } From b4e781fd0c964e5286d6e7d36794be450a33708d Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 15:18:42 +0100 Subject: [PATCH 09/16] gl-client: Sync greenlight.proto with gl-plugin Add NodeEvent, NodeEventsRequest, InvoicePaid messages and StreamNodeEvents RPC method. --- .../proto/glclient/greenlight.proto | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/libs/gl-client/.resources/proto/glclient/greenlight.proto b/libs/gl-client/.resources/proto/glclient/greenlight.proto index 63dd182c0..94d2cfacd 100644 --- a/libs/gl-client/.resources/proto/glclient/greenlight.proto +++ b/libs/gl-client/.resources/proto/glclient/greenlight.proto @@ -43,6 +43,14 @@ service Node { // replayed if the stream is interrupted. rpc StreamCustommsg(StreamCustommsgRequest) returns (stream Custommsg) {} + // Stream node events in real-time. + // + // This is a unified event stream that delivers various node events + // as they occur, including invoice updates, peer changes, channel + // state changes, and balance updates. Events are not persisted and + // will not be replayed if the stream is interrupted. + rpc StreamNodeEvents(NodeEventsRequest) returns (stream NodeEvent) {} + //////////////////////////////// HSM Messages //////////////////////// // // The following messages are related to communicating HSM @@ -243,3 +251,38 @@ message LspInvoiceResponse { bytes payment_hash = 4; bytes payment_secret = 5; } + +// Request for streaming node events. Currently empty but defined as +// its own message type to allow adding filters in the future (e.g., +// filter by event type, invoice label, etc.) +message NodeEventsRequest { +} + +// A real-time event from the node. Uses oneof to discriminate between +// different event types. +message NodeEvent { + oneof event { + InvoicePaid invoice_paid = 1; + // Future event types: + // PeerConnected peer_connected = 2; + // PeerDisconnected peer_disconnected = 3; + // ChannelStateChanged channel_state_changed = 4; + // BalanceChanged balance_changed = 5; + } +} + +// Event emitted when an invoice is paid. +message InvoicePaid { + // The payment hash of the paid invoice. + bytes payment_hash = 1; + // The bolt11 invoice string. + string bolt11 = 2; + // The preimage that proves payment. + bytes preimage = 3; + // The label assigned to the invoice. + string label = 4; + // Amount received in millisatoshis. + uint64 amount_msat = 5; + // Extra TLV fields included in the payment. + repeated TlvField extratlvs = 6; +} From dd95cda61bdc913ae766bc09059ba66a4fa18905 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 16:22:18 +0100 Subject: [PATCH 10/16] gl-client-py: Add stream_node_events for real-time event streaming Add Python bindings for the StreamNodeEvents gRPC method, enabling clients to receive real-time notifications when events occur on their node (e.g., invoice payments). - Add stream_node_events() method to Node class in Python - Add NodeEventStream wrapper for the streaming response - Sync greenlight.proto with NodeEventsRequest, NodeEvent, InvoicePaid - Regenerate Python protobuf files --- libs/gl-client-py/glclient/__init__.py | 9 + libs/gl-client-py/glclient/greenlight.proto | 43 + libs/gl-client-py/glclient/greenlight_pb2.py | 16 +- libs/gl-client-py/glclient/greenlight_pb2.pyi | 819 ++++++++++-------- .../glclient/greenlight_pb2_grpc.py | 51 +- .../glclient/greenlight_pb2_grpc.pyi | 259 +++--- libs/gl-client-py/src/node.rs | 20 + libs/proto/glclient/greenlight.proto | 43 + 8 files changed, 759 insertions(+), 501 deletions(-) diff --git a/libs/gl-client-py/glclient/__init__.py b/libs/gl-client-py/glclient/__init__.py index ae90422cb..5def639c5 100644 --- a/libs/gl-client-py/glclient/__init__.py +++ b/libs/gl-client-py/glclient/__init__.py @@ -464,6 +464,15 @@ def stream_custommsg(self): break yield nodepb.Custommsg.FromString(bytes(n)) + def stream_node_events(self): + """Stream node events (invoice payments, peer changes, etc.) as they occur.""" + stream = self.inner.stream_node_events(b"") + while True: + n = stream.next() + if n is None: + break + yield nodepb.NodeEvent.FromString(bytes(n)) + def send_custommsg(self, node_id: str, msg: bytes) -> clnpb.SendcustommsgResponse: uri = "/cln.Node/SendCustomMsg" res = clnpb.SendcustommsgResponse diff --git a/libs/gl-client-py/glclient/greenlight.proto b/libs/gl-client-py/glclient/greenlight.proto index 63dd182c0..94d2cfacd 100644 --- a/libs/gl-client-py/glclient/greenlight.proto +++ b/libs/gl-client-py/glclient/greenlight.proto @@ -43,6 +43,14 @@ service Node { // replayed if the stream is interrupted. rpc StreamCustommsg(StreamCustommsgRequest) returns (stream Custommsg) {} + // Stream node events in real-time. + // + // This is a unified event stream that delivers various node events + // as they occur, including invoice updates, peer changes, channel + // state changes, and balance updates. Events are not persisted and + // will not be replayed if the stream is interrupted. + rpc StreamNodeEvents(NodeEventsRequest) returns (stream NodeEvent) {} + //////////////////////////////// HSM Messages //////////////////////// // // The following messages are related to communicating HSM @@ -243,3 +251,38 @@ message LspInvoiceResponse { bytes payment_hash = 4; bytes payment_secret = 5; } + +// Request for streaming node events. Currently empty but defined as +// its own message type to allow adding filters in the future (e.g., +// filter by event type, invoice label, etc.) +message NodeEventsRequest { +} + +// A real-time event from the node. Uses oneof to discriminate between +// different event types. +message NodeEvent { + oneof event { + InvoicePaid invoice_paid = 1; + // Future event types: + // PeerConnected peer_connected = 2; + // PeerDisconnected peer_disconnected = 3; + // ChannelStateChanged channel_state_changed = 4; + // BalanceChanged balance_changed = 5; + } +} + +// Event emitted when an invoice is paid. +message InvoicePaid { + // The payment hash of the paid invoice. + bytes payment_hash = 1; + // The bolt11 invoice string. + string bolt11 = 2; + // The preimage that proves payment. + bytes preimage = 3; + // The label assigned to the invoice. + string label = 4; + // Amount received in millisatoshis. + uint64 amount_msat = 5; + // Extra TLV fields included in the payment. + repeated TlvField extratlvs = 6; +} diff --git a/libs/gl-client-py/glclient/greenlight_pb2.py b/libs/gl-client-py/glclient/greenlight_pb2.py index 3c2ab0bef..1c0619a63 100644 --- a/libs/gl-client-py/glclient/greenlight_pb2.py +++ b/libs/gl-client-py/glclient/greenlight_pb2.py @@ -24,7 +24,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19glclient/greenlight.proto\x12\ngreenlight\"H\n\x11HsmRequestContext\x12\x0f\n\x07node_id\x18\x01 \x01(\x0c\x12\x0c\n\x04\x64\x62id\x18\x02 \x01(\x04\x12\x14\n\x0c\x63\x61pabilities\x18\x03 \x01(\x04\"q\n\x0bHsmResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\r\x12\x0b\n\x03raw\x18\x02 \x01(\x0c\x12\x32\n\x0csigner_state\x18\x05 \x03(\x0b\x32\x1c.greenlight.SignerStateEntry\x12\r\n\x05\x65rror\x18\x06 \x01(\t\"\xbf\x01\n\nHsmRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\r\x12.\n\x07\x63ontext\x18\x02 \x01(\x0b\x32\x1d.greenlight.HsmRequestContext\x12\x0b\n\x03raw\x18\x03 \x01(\x0c\x12\x32\n\x0csigner_state\x18\x04 \x03(\x0b\x32\x1c.greenlight.SignerStateEntry\x12,\n\x08requests\x18\x05 \x03(\x0b\x32\x1a.greenlight.PendingRequest\"\x07\n\x05\x45mpty\"l\n\x06\x41mount\x12\x16\n\x0cmillisatoshi\x18\x01 \x01(\x04H\x00\x12\x11\n\x07satoshi\x18\x02 \x01(\x04H\x00\x12\x11\n\x07\x62itcoin\x18\x03 \x01(\x04H\x00\x12\r\n\x03\x61ll\x18\x04 \x01(\x08H\x00\x12\r\n\x03\x61ny\x18\x05 \x01(\x08H\x00\x42\x06\n\x04unit\"\x16\n\x14StreamIncomingFilter\"\'\n\x08TlvField\x12\x0c\n\x04type\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x0c\"\xa5\x01\n\x0fOffChainPayment\x12\r\n\x05label\x18\x01 \x01(\t\x12\x10\n\x08preimage\x18\x02 \x01(\x0c\x12\"\n\x06\x61mount\x18\x03 \x01(\x0b\x32\x12.greenlight.Amount\x12\'\n\textratlvs\x18\x04 \x03(\x0b\x32\x14.greenlight.TlvField\x12\x14\n\x0cpayment_hash\x18\x05 \x01(\x0c\x12\x0e\n\x06\x62olt11\x18\x06 \x01(\t\"M\n\x0fIncomingPayment\x12/\n\x08offchain\x18\x01 \x01(\x0b\x32\x1b.greenlight.OffChainPaymentH\x00\x42\t\n\x07\x64\x65tails\"\x12\n\x10StreamLogRequest\"\x18\n\x08LogEntry\x12\x0c\n\x04line\x18\x01 \x01(\t\"?\n\x10SignerStateEntry\x12\x0f\n\x07version\x18\x01 \x01(\x04\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x0c\"r\n\x0ePendingRequest\x12\x0f\n\x07request\x18\x01 \x01(\x0c\x12\x0b\n\x03uri\x18\x02 \x01(\t\x12\x11\n\tsignature\x18\x03 \x01(\x0c\x12\x0e\n\x06pubkey\x18\x04 \x01(\x0c\x12\x11\n\ttimestamp\x18\x05 \x01(\x04\x12\x0c\n\x04rune\x18\x06 \x01(\x0c\"=\n\nNodeConfig\x12/\n\x0bstartupmsgs\x18\x01 \x03(\x0b\x32\x1a.greenlight.StartupMessage\"!\n\x08GlConfig\x12\x15\n\rclose_to_addr\x18\x01 \x01(\t\"3\n\x0eStartupMessage\x12\x0f\n\x07request\x18\x01 \x01(\x0c\x12\x10\n\x08response\x18\x02 \x01(\x0c\"\x18\n\x16StreamCustommsgRequest\"-\n\tCustommsg\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"\xa4\x01\n\x14TrampolinePayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x1a\n\x12trampoline_node_id\x18\x02 \x01(\x0c\x12\x13\n\x0b\x61mount_msat\x18\x03 \x01(\x04\x12\r\n\x05label\x18\x04 \x01(\t\x12\x15\n\rmaxfeepercent\x18\x05 \x01(\x02\x12\x10\n\x08maxdelay\x18\x06 \x01(\r\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\"\xd5\x01\n\x15TrampolinePayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\ncreated_at\x18\x03 \x01(\x01\x12\r\n\x05parts\x18\x04 \x01(\r\x12\x13\n\x0b\x61mount_msat\x18\x05 \x01(\x04\x12\x18\n\x10\x61mount_sent_msat\x18\x06 \x01(\x04\x12\x13\n\x0b\x64\x65stination\x18\x07 \x01(\x0c\"%\n\tPayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x02\"k\n\x11LspInvoiceRequest\x12\x0e\n\x06lsp_id\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x03 \x01(\x04\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\r\n\x05label\x18\x05 \x01(\t\"}\n\x12LspInvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x15\n\rcreated_index\x18\x02 \x01(\r\x12\x12\n\nexpires_at\x18\x03 \x01(\r\x12\x14\n\x0cpayment_hash\x18\x04 \x01(\x0c\x12\x16\n\x0epayment_secret\x18\x05 \x01(\x0c\x32\xd8\x04\n\x04Node\x12M\n\nLspInvoice\x12\x1d.greenlight.LspInvoiceRequest\x1a\x1e.greenlight.LspInvoiceResponse\"\x00\x12S\n\x0eStreamIncoming\x12 .greenlight.StreamIncomingFilter\x1a\x1b.greenlight.IncomingPayment\"\x00\x30\x01\x12\x43\n\tStreamLog\x12\x1c.greenlight.StreamLogRequest\x1a\x14.greenlight.LogEntry\"\x00\x30\x01\x12P\n\x0fStreamCustommsg\x12\".greenlight.StreamCustommsgRequest\x1a\x15.greenlight.Custommsg\"\x00\x30\x01\x12\x42\n\x11StreamHsmRequests\x12\x11.greenlight.Empty\x1a\x16.greenlight.HsmRequest\"\x00\x30\x01\x12\x41\n\x11RespondHsmRequest\x12\x17.greenlight.HsmResponse\x1a\x11.greenlight.Empty\"\x00\x12\x36\n\tConfigure\x12\x14.greenlight.GlConfig\x1a\x11.greenlight.Empty\"\x00\x12V\n\rTrampolinePay\x12 .greenlight.TrampolinePayRequest\x1a!.greenlight.TrampolinePayResponse\"\x00\x32s\n\x03Hsm\x12<\n\x07Request\x12\x16.greenlight.HsmRequest\x1a\x17.greenlight.HsmResponse\"\x00\x12.\n\x04Ping\x12\x11.greenlight.Empty\x1a\x11.greenlight.Empty\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19glclient/greenlight.proto\x12\ngreenlight\"H\n\x11HsmRequestContext\x12\x0f\n\x07node_id\x18\x01 \x01(\x0c\x12\x0c\n\x04\x64\x62id\x18\x02 \x01(\x04\x12\x14\n\x0c\x63\x61pabilities\x18\x03 \x01(\x04\"q\n\x0bHsmResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\r\x12\x0b\n\x03raw\x18\x02 \x01(\x0c\x12\x32\n\x0csigner_state\x18\x05 \x03(\x0b\x32\x1c.greenlight.SignerStateEntry\x12\r\n\x05\x65rror\x18\x06 \x01(\t\"\xbf\x01\n\nHsmRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\r\x12.\n\x07\x63ontext\x18\x02 \x01(\x0b\x32\x1d.greenlight.HsmRequestContext\x12\x0b\n\x03raw\x18\x03 \x01(\x0c\x12\x32\n\x0csigner_state\x18\x04 \x03(\x0b\x32\x1c.greenlight.SignerStateEntry\x12,\n\x08requests\x18\x05 \x03(\x0b\x32\x1a.greenlight.PendingRequest\"\x07\n\x05\x45mpty\"l\n\x06\x41mount\x12\x16\n\x0cmillisatoshi\x18\x01 \x01(\x04H\x00\x12\x11\n\x07satoshi\x18\x02 \x01(\x04H\x00\x12\x11\n\x07\x62itcoin\x18\x03 \x01(\x04H\x00\x12\r\n\x03\x61ll\x18\x04 \x01(\x08H\x00\x12\r\n\x03\x61ny\x18\x05 \x01(\x08H\x00\x42\x06\n\x04unit\"\x16\n\x14StreamIncomingFilter\"\'\n\x08TlvField\x12\x0c\n\x04type\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x0c\"\xa5\x01\n\x0fOffChainPayment\x12\r\n\x05label\x18\x01 \x01(\t\x12\x10\n\x08preimage\x18\x02 \x01(\x0c\x12\"\n\x06\x61mount\x18\x03 \x01(\x0b\x32\x12.greenlight.Amount\x12\'\n\textratlvs\x18\x04 \x03(\x0b\x32\x14.greenlight.TlvField\x12\x14\n\x0cpayment_hash\x18\x05 \x01(\x0c\x12\x0e\n\x06\x62olt11\x18\x06 \x01(\t\"M\n\x0fIncomingPayment\x12/\n\x08offchain\x18\x01 \x01(\x0b\x32\x1b.greenlight.OffChainPaymentH\x00\x42\t\n\x07\x64\x65tails\"\x12\n\x10StreamLogRequest\"\x18\n\x08LogEntry\x12\x0c\n\x04line\x18\x01 \x01(\t\"?\n\x10SignerStateEntry\x12\x0f\n\x07version\x18\x01 \x01(\x04\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x0c\"r\n\x0ePendingRequest\x12\x0f\n\x07request\x18\x01 \x01(\x0c\x12\x0b\n\x03uri\x18\x02 \x01(\t\x12\x11\n\tsignature\x18\x03 \x01(\x0c\x12\x0e\n\x06pubkey\x18\x04 \x01(\x0c\x12\x11\n\ttimestamp\x18\x05 \x01(\x04\x12\x0c\n\x04rune\x18\x06 \x01(\x0c\"=\n\nNodeConfig\x12/\n\x0bstartupmsgs\x18\x01 \x03(\x0b\x32\x1a.greenlight.StartupMessage\"!\n\x08GlConfig\x12\x15\n\rclose_to_addr\x18\x01 \x01(\t\"3\n\x0eStartupMessage\x12\x0f\n\x07request\x18\x01 \x01(\x0c\x12\x10\n\x08response\x18\x02 \x01(\x0c\"\x18\n\x16StreamCustommsgRequest\"-\n\tCustommsg\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"\xa4\x01\n\x14TrampolinePayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x1a\n\x12trampoline_node_id\x18\x02 \x01(\x0c\x12\x13\n\x0b\x61mount_msat\x18\x03 \x01(\x04\x12\r\n\x05label\x18\x04 \x01(\t\x12\x15\n\rmaxfeepercent\x18\x05 \x01(\x02\x12\x10\n\x08maxdelay\x18\x06 \x01(\r\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\"\xd5\x01\n\x15TrampolinePayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\ncreated_at\x18\x03 \x01(\x01\x12\r\n\x05parts\x18\x04 \x01(\r\x12\x13\n\x0b\x61mount_msat\x18\x05 \x01(\x04\x12\x18\n\x10\x61mount_sent_msat\x18\x06 \x01(\x04\x12\x13\n\x0b\x64\x65stination\x18\x07 \x01(\x0c\"%\n\tPayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x02\"k\n\x11LspInvoiceRequest\x12\x0e\n\x06lsp_id\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x03 \x01(\x04\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\r\n\x05label\x18\x05 \x01(\t\"}\n\x12LspInvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x15\n\rcreated_index\x18\x02 \x01(\r\x12\x12\n\nexpires_at\x18\x03 \x01(\r\x12\x14\n\x0cpayment_hash\x18\x04 \x01(\x0c\x12\x16\n\x0epayment_secret\x18\x05 \x01(\x0c\"\x13\n\x11NodeEventsRequest\"E\n\tNodeEvent\x12/\n\x0cinvoice_paid\x18\x01 \x01(\x0b\x32\x17.greenlight.InvoicePaidH\x00\x42\x07\n\x05\x65vent\"\x92\x01\n\x0bInvoicePaid\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06\x62olt11\x18\x02 \x01(\t\x12\x10\n\x08preimage\x18\x03 \x01(\x0c\x12\r\n\x05label\x18\x04 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x05 \x01(\x04\x12\'\n\textratlvs\x18\x06 \x03(\x0b\x32\x14.greenlight.TlvField2\xa6\x05\n\x04Node\x12M\n\nLspInvoice\x12\x1d.greenlight.LspInvoiceRequest\x1a\x1e.greenlight.LspInvoiceResponse\"\x00\x12S\n\x0eStreamIncoming\x12 .greenlight.StreamIncomingFilter\x1a\x1b.greenlight.IncomingPayment\"\x00\x30\x01\x12\x43\n\tStreamLog\x12\x1c.greenlight.StreamLogRequest\x1a\x14.greenlight.LogEntry\"\x00\x30\x01\x12P\n\x0fStreamCustommsg\x12\".greenlight.StreamCustommsgRequest\x1a\x15.greenlight.Custommsg\"\x00\x30\x01\x12L\n\x10StreamNodeEvents\x12\x1d.greenlight.NodeEventsRequest\x1a\x15.greenlight.NodeEvent\"\x00\x30\x01\x12\x42\n\x11StreamHsmRequests\x12\x11.greenlight.Empty\x1a\x16.greenlight.HsmRequest\"\x00\x30\x01\x12\x41\n\x11RespondHsmRequest\x12\x17.greenlight.HsmResponse\x1a\x11.greenlight.Empty\"\x00\x12\x36\n\tConfigure\x12\x14.greenlight.GlConfig\x1a\x11.greenlight.Empty\"\x00\x12V\n\rTrampolinePay\x12 .greenlight.TrampolinePayRequest\x1a!.greenlight.TrampolinePayResponse\"\x00\x32s\n\x03Hsm\x12<\n\x07Request\x12\x16.greenlight.HsmRequest\x1a\x17.greenlight.HsmResponse\"\x00\x12.\n\x04Ping\x12\x11.greenlight.Empty\x1a\x11.greenlight.Empty\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -77,8 +77,14 @@ _globals['_LSPINVOICEREQUEST']._serialized_end=1796 _globals['_LSPINVOICERESPONSE']._serialized_start=1798 _globals['_LSPINVOICERESPONSE']._serialized_end=1923 - _globals['_NODE']._serialized_start=1926 - _globals['_NODE']._serialized_end=2526 - _globals['_HSM']._serialized_start=2528 - _globals['_HSM']._serialized_end=2643 + _globals['_NODEEVENTSREQUEST']._serialized_start=1925 + _globals['_NODEEVENTSREQUEST']._serialized_end=1944 + _globals['_NODEEVENT']._serialized_start=1946 + _globals['_NODEEVENT']._serialized_end=2015 + _globals['_INVOICEPAID']._serialized_start=2018 + _globals['_INVOICEPAID']._serialized_end=2164 + _globals['_NODE']._serialized_start=2167 + _globals['_NODE']._serialized_end=2845 + _globals['_HSM']._serialized_start=2847 + _globals['_HSM']._serialized_end=2962 # @@protoc_insertion_point(module_scope) diff --git a/libs/gl-client-py/glclient/greenlight_pb2.pyi b/libs/gl-client-py/glclient/greenlight_pb2.pyi index 78426c3f3..a09488cbf 100644 --- a/libs/gl-client-py/glclient/greenlight_pb2.pyi +++ b/libs/gl-client-py/glclient/greenlight_pb2.pyi @@ -3,61 +3,62 @@ isort:skip_file """ -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.internal.enum_type_wrapper -import google.protobuf.message +from collections import abc as _abc +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +import builtins as _builtins import sys -import typing +import typing as _typing if sys.version_info >= (3, 10): - import typing as typing_extensions + from typing import TypeAlias as _TypeAlias else: - import typing_extensions + from typing_extensions import TypeAlias as _TypeAlias -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor +DESCRIPTOR: _descriptor.FileDescriptor -@typing.final -class HsmRequestContext(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class HsmRequestContext(_message.Message): + DESCRIPTOR: _descriptor.Descriptor - NODE_ID_FIELD_NUMBER: builtins.int - DBID_FIELD_NUMBER: builtins.int - CAPABILITIES_FIELD_NUMBER: builtins.int - node_id: builtins.bytes - dbid: builtins.int - capabilities: builtins.int + NODE_ID_FIELD_NUMBER: _builtins.int + DBID_FIELD_NUMBER: _builtins.int + CAPABILITIES_FIELD_NUMBER: _builtins.int + node_id: _builtins.bytes + dbid: _builtins.int + capabilities: _builtins.int def __init__( self, *, - node_id: builtins.bytes = ..., - dbid: builtins.int = ..., - capabilities: builtins.int = ..., + node_id: _builtins.bytes = ..., + dbid: _builtins.int = ..., + capabilities: _builtins.int = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["capabilities", b"capabilities", "dbid", b"dbid", "node_id", b"node_id"]) -> None: ... - -global___HsmRequestContext = HsmRequestContext - -@typing.final -class HsmResponse(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - REQUEST_ID_FIELD_NUMBER: builtins.int - RAW_FIELD_NUMBER: builtins.int - SIGNER_STATE_FIELD_NUMBER: builtins.int - ERROR_FIELD_NUMBER: builtins.int - request_id: builtins.int - raw: builtins.bytes - error: builtins.str + _ClearFieldArgType: _TypeAlias = _typing.Literal["capabilities", b"capabilities", "dbid", b"dbid", "node_id", b"node_id"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + +Global___HsmRequestContext: _TypeAlias = HsmRequestContext # noqa: Y015 + +@_typing.final +class HsmResponse(_message.Message): + DESCRIPTOR: _descriptor.Descriptor + + REQUEST_ID_FIELD_NUMBER: _builtins.int + RAW_FIELD_NUMBER: _builtins.int + SIGNER_STATE_FIELD_NUMBER: _builtins.int + ERROR_FIELD_NUMBER: _builtins.int + request_id: _builtins.int + raw: _builtins.bytes + error: _builtins.str """If the signer reported an error, and did therefore not include `raw`, this is the stringified error, so we can print it in the logs. This should help us collate policy errors with the changes proposed by CLN """ - @property - def signer_state(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SignerStateEntry]: + @_builtins.property + def signer_state(self) -> _containers.RepeatedCompositeFieldContainer[Global___SignerStateEntry]: """A list of updated key-value-version tuples that is to be merged into the state tracked by the plugin. """ @@ -65,36 +66,37 @@ class HsmResponse(google.protobuf.message.Message): def __init__( self, *, - request_id: builtins.int = ..., - raw: builtins.bytes = ..., - signer_state: collections.abc.Iterable[global___SignerStateEntry] | None = ..., - error: builtins.str = ..., + request_id: _builtins.int = ..., + raw: _builtins.bytes = ..., + signer_state: _abc.Iterable[Global___SignerStateEntry] | None = ..., + error: _builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["error", b"error", "raw", b"raw", "request_id", b"request_id", "signer_state", b"signer_state"]) -> None: ... - -global___HsmResponse = HsmResponse - -@typing.final -class HsmRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - REQUEST_ID_FIELD_NUMBER: builtins.int - CONTEXT_FIELD_NUMBER: builtins.int - RAW_FIELD_NUMBER: builtins.int - SIGNER_STATE_FIELD_NUMBER: builtins.int - REQUESTS_FIELD_NUMBER: builtins.int - request_id: builtins.int - raw: builtins.bytes - @property - def context(self) -> global___HsmRequestContext: ... - @property - def signer_state(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SignerStateEntry]: + _ClearFieldArgType: _TypeAlias = _typing.Literal["error", b"error", "raw", b"raw", "request_id", b"request_id", "signer_state", b"signer_state"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + +Global___HsmResponse: _TypeAlias = HsmResponse # noqa: Y015 + +@_typing.final +class HsmRequest(_message.Message): + DESCRIPTOR: _descriptor.Descriptor + + REQUEST_ID_FIELD_NUMBER: _builtins.int + CONTEXT_FIELD_NUMBER: _builtins.int + RAW_FIELD_NUMBER: _builtins.int + SIGNER_STATE_FIELD_NUMBER: _builtins.int + REQUESTS_FIELD_NUMBER: _builtins.int + request_id: _builtins.int + raw: _builtins.bytes + @_builtins.property + def context(self) -> Global___HsmRequestContext: ... + @_builtins.property + def signer_state(self) -> _containers.RepeatedCompositeFieldContainer[Global___SignerStateEntry]: """A list of key-value-version tuples that the signer should use to update its internal state. """ - @property - def requests(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PendingRequest]: + @_builtins.property + def requests(self) -> _containers.RepeatedCompositeFieldContainer[Global___PendingRequest]: """Currently active requests that are used to justify changes in state. """ @@ -102,188 +104,203 @@ class HsmRequest(google.protobuf.message.Message): def __init__( self, *, - request_id: builtins.int = ..., - context: global___HsmRequestContext | None = ..., - raw: builtins.bytes = ..., - signer_state: collections.abc.Iterable[global___SignerStateEntry] | None = ..., - requests: collections.abc.Iterable[global___PendingRequest] | None = ..., + request_id: _builtins.int = ..., + context: Global___HsmRequestContext | None = ..., + raw: _builtins.bytes = ..., + signer_state: _abc.Iterable[Global___SignerStateEntry] | None = ..., + requests: _abc.Iterable[Global___PendingRequest] | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["context", b"context"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["context", b"context", "raw", b"raw", "request_id", b"request_id", "requests", b"requests", "signer_state", b"signer_state"]) -> None: ... + _HasFieldArgType: _TypeAlias = _typing.Literal["context", b"context"] # noqa: Y015 + def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["context", b"context", "raw", b"raw", "request_id", b"request_id", "requests", b"requests", "signer_state", b"signer_state"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___HsmRequest = HsmRequest +Global___HsmRequest: _TypeAlias = HsmRequest # noqa: Y015 -@typing.final -class Empty(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class Empty(_message.Message): + DESCRIPTOR: _descriptor.Descriptor def __init__( self, ) -> None: ... -global___Empty = Empty - -@typing.final -class Amount(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MILLISATOSHI_FIELD_NUMBER: builtins.int - SATOSHI_FIELD_NUMBER: builtins.int - BITCOIN_FIELD_NUMBER: builtins.int - ALL_FIELD_NUMBER: builtins.int - ANY_FIELD_NUMBER: builtins.int - millisatoshi: builtins.int - satoshi: builtins.int - bitcoin: builtins.int - all: builtins.bool - any: builtins.bool +Global___Empty: _TypeAlias = Empty # noqa: Y015 + +@_typing.final +class Amount(_message.Message): + DESCRIPTOR: _descriptor.Descriptor + + MILLISATOSHI_FIELD_NUMBER: _builtins.int + SATOSHI_FIELD_NUMBER: _builtins.int + BITCOIN_FIELD_NUMBER: _builtins.int + ALL_FIELD_NUMBER: _builtins.int + ANY_FIELD_NUMBER: _builtins.int + millisatoshi: _builtins.int + satoshi: _builtins.int + bitcoin: _builtins.int + all: _builtins.bool + any: _builtins.bool def __init__( self, *, - millisatoshi: builtins.int = ..., - satoshi: builtins.int = ..., - bitcoin: builtins.int = ..., - all: builtins.bool = ..., - any: builtins.bool = ..., + millisatoshi: _builtins.int = ..., + satoshi: _builtins.int = ..., + bitcoin: _builtins.int = ..., + all: _builtins.bool = ..., + any: _builtins.bool = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["all", b"all", "any", b"any", "bitcoin", b"bitcoin", "millisatoshi", b"millisatoshi", "satoshi", b"satoshi", "unit", b"unit"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["all", b"all", "any", b"any", "bitcoin", b"bitcoin", "millisatoshi", b"millisatoshi", "satoshi", b"satoshi", "unit", b"unit"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["unit", b"unit"]) -> typing.Literal["millisatoshi", "satoshi", "bitcoin", "all", "any"] | None: ... - -global___Amount = Amount - -@typing.final -class StreamIncomingFilter(google.protobuf.message.Message): + _HasFieldArgType: _TypeAlias = _typing.Literal["all", b"all", "any", b"any", "bitcoin", b"bitcoin", "millisatoshi", b"millisatoshi", "satoshi", b"satoshi", "unit", b"unit"] # noqa: Y015 + def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["all", b"all", "any", b"any", "bitcoin", b"bitcoin", "millisatoshi", b"millisatoshi", "satoshi", b"satoshi", "unit", b"unit"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType_unit: _TypeAlias = _typing.Literal["millisatoshi", "satoshi", "bitcoin", "all", "any"] # noqa: Y015 + _WhichOneofArgType_unit: _TypeAlias = _typing.Literal["unit", b"unit"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType_unit) -> _WhichOneofReturnType_unit | None: ... + +Global___Amount: _TypeAlias = Amount # noqa: Y015 + +@_typing.final +class StreamIncomingFilter(_message.Message): """Options to stream_incoming to specify what to stream.""" - DESCRIPTOR: google.protobuf.descriptor.Descriptor + DESCRIPTOR: _descriptor.Descriptor def __init__( self, ) -> None: ... -global___StreamIncomingFilter = StreamIncomingFilter +Global___StreamIncomingFilter: _TypeAlias = StreamIncomingFilter # noqa: Y015 -@typing.final -class TlvField(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class TlvField(_message.Message): + DESCRIPTOR: _descriptor.Descriptor - TYPE_FIELD_NUMBER: builtins.int - VALUE_FIELD_NUMBER: builtins.int - type: builtins.int - value: builtins.bytes + TYPE_FIELD_NUMBER: _builtins.int + VALUE_FIELD_NUMBER: _builtins.int + type: _builtins.int + value: _builtins.bytes """length is implied since the value field carries its own length here. """ def __init__( self, *, - type: builtins.int = ..., - value: builtins.bytes = ..., + type: _builtins.int = ..., + value: _builtins.bytes = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["type", b"type", "value", b"value"]) -> None: ... - -global___TlvField = TlvField - -@typing.final -class OffChainPayment(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - LABEL_FIELD_NUMBER: builtins.int - PREIMAGE_FIELD_NUMBER: builtins.int - AMOUNT_FIELD_NUMBER: builtins.int - EXTRATLVS_FIELD_NUMBER: builtins.int - PAYMENT_HASH_FIELD_NUMBER: builtins.int - BOLT11_FIELD_NUMBER: builtins.int - label: builtins.str - preimage: builtins.bytes - payment_hash: builtins.bytes - bolt11: builtins.str - @property - def amount(self) -> global___Amount: ... - @property - def extratlvs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___TlvField]: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["type", b"type", "value", b"value"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + +Global___TlvField: _TypeAlias = TlvField # noqa: Y015 + +@_typing.final +class OffChainPayment(_message.Message): + DESCRIPTOR: _descriptor.Descriptor + + LABEL_FIELD_NUMBER: _builtins.int + PREIMAGE_FIELD_NUMBER: _builtins.int + AMOUNT_FIELD_NUMBER: _builtins.int + EXTRATLVS_FIELD_NUMBER: _builtins.int + PAYMENT_HASH_FIELD_NUMBER: _builtins.int + BOLT11_FIELD_NUMBER: _builtins.int + label: _builtins.str + preimage: _builtins.bytes + payment_hash: _builtins.bytes + bolt11: _builtins.str + @_builtins.property + def amount(self) -> Global___Amount: ... + @_builtins.property + def extratlvs(self) -> _containers.RepeatedCompositeFieldContainer[Global___TlvField]: ... def __init__( self, *, - label: builtins.str = ..., - preimage: builtins.bytes = ..., - amount: global___Amount | None = ..., - extratlvs: collections.abc.Iterable[global___TlvField] | None = ..., - payment_hash: builtins.bytes = ..., - bolt11: builtins.str = ..., + label: _builtins.str = ..., + preimage: _builtins.bytes = ..., + amount: Global___Amount | None = ..., + extratlvs: _abc.Iterable[Global___TlvField] | None = ..., + payment_hash: _builtins.bytes = ..., + bolt11: _builtins.str = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["amount", b"amount"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["amount", b"amount", "bolt11", b"bolt11", "extratlvs", b"extratlvs", "label", b"label", "payment_hash", b"payment_hash", "preimage", b"preimage"]) -> None: ... + _HasFieldArgType: _TypeAlias = _typing.Literal["amount", b"amount"] # noqa: Y015 + def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["amount", b"amount", "bolt11", b"bolt11", "extratlvs", b"extratlvs", "label", b"label", "payment_hash", b"payment_hash", "preimage", b"preimage"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___OffChainPayment = OffChainPayment +Global___OffChainPayment: _TypeAlias = OffChainPayment # noqa: Y015 -@typing.final -class IncomingPayment(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class IncomingPayment(_message.Message): + DESCRIPTOR: _descriptor.Descriptor - OFFCHAIN_FIELD_NUMBER: builtins.int - @property - def offchain(self) -> global___OffChainPayment: ... + OFFCHAIN_FIELD_NUMBER: _builtins.int + @_builtins.property + def offchain(self) -> Global___OffChainPayment: ... def __init__( self, *, - offchain: global___OffChainPayment | None = ..., + offchain: Global___OffChainPayment | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["details", b"details", "offchain", b"offchain"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["details", b"details", "offchain", b"offchain"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["details", b"details"]) -> typing.Literal["offchain"] | None: ... + _HasFieldArgType: _TypeAlias = _typing.Literal["details", b"details", "offchain", b"offchain"] # noqa: Y015 + def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["details", b"details", "offchain", b"offchain"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType_details: _TypeAlias = _typing.Literal["offchain"] # noqa: Y015 + _WhichOneofArgType_details: _TypeAlias = _typing.Literal["details", b"details"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType_details) -> _WhichOneofReturnType_details | None: ... -global___IncomingPayment = IncomingPayment +Global___IncomingPayment: _TypeAlias = IncomingPayment # noqa: Y015 -@typing.final -class StreamLogRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class StreamLogRequest(_message.Message): + DESCRIPTOR: _descriptor.Descriptor def __init__( self, ) -> None: ... -global___StreamLogRequest = StreamLogRequest +Global___StreamLogRequest: _TypeAlias = StreamLogRequest # noqa: Y015 -@typing.final -class LogEntry(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class LogEntry(_message.Message): + DESCRIPTOR: _descriptor.Descriptor - LINE_FIELD_NUMBER: builtins.int - line: builtins.str + LINE_FIELD_NUMBER: _builtins.int + line: _builtins.str def __init__( self, *, - line: builtins.str = ..., + line: _builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["line", b"line"]) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["line", b"line"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___LogEntry = LogEntry +Global___LogEntry: _TypeAlias = LogEntry # noqa: Y015 -@typing.final -class SignerStateEntry(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class SignerStateEntry(_message.Message): + DESCRIPTOR: _descriptor.Descriptor - VERSION_FIELD_NUMBER: builtins.int - KEY_FIELD_NUMBER: builtins.int - VALUE_FIELD_NUMBER: builtins.int - version: builtins.int - key: builtins.str - value: builtins.bytes + VERSION_FIELD_NUMBER: _builtins.int + KEY_FIELD_NUMBER: _builtins.int + VALUE_FIELD_NUMBER: _builtins.int + version: _builtins.int + key: _builtins.str + value: _builtins.bytes def __init__( self, *, - version: builtins.int = ..., - key: builtins.str = ..., - value: builtins.bytes = ..., + version: _builtins.int = ..., + key: _builtins.str = ..., + value: _builtins.bytes = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value", "version", b"version"]) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["key", b"key", "value", b"value", "version", b"version"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___SignerStateEntry = SignerStateEntry +Global___SignerStateEntry: _TypeAlias = SignerStateEntry # noqa: Y015 -@typing.final -class PendingRequest(google.protobuf.message.Message): +@_typing.final +class PendingRequest(_message.Message): """This represents a grpc request that is currently pending, along with the pubkey of the client issuing the request and a matching signature. This allows the signer to verify that the state changes @@ -291,47 +308,48 @@ class PendingRequest(google.protobuf.message.Message): commands, and were not injected somewhere along the way. """ - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - REQUEST_FIELD_NUMBER: builtins.int - URI_FIELD_NUMBER: builtins.int - SIGNATURE_FIELD_NUMBER: builtins.int - PUBKEY_FIELD_NUMBER: builtins.int - TIMESTAMP_FIELD_NUMBER: builtins.int - RUNE_FIELD_NUMBER: builtins.int - request: builtins.bytes - uri: builtins.str - signature: builtins.bytes - pubkey: builtins.bytes - timestamp: builtins.int - rune: builtins.bytes + DESCRIPTOR: _descriptor.Descriptor + + REQUEST_FIELD_NUMBER: _builtins.int + URI_FIELD_NUMBER: _builtins.int + SIGNATURE_FIELD_NUMBER: _builtins.int + PUBKEY_FIELD_NUMBER: _builtins.int + TIMESTAMP_FIELD_NUMBER: _builtins.int + RUNE_FIELD_NUMBER: _builtins.int + request: _builtins.bytes + uri: _builtins.str + signature: _builtins.bytes + pubkey: _builtins.bytes + timestamp: _builtins.int + rune: _builtins.bytes def __init__( self, *, - request: builtins.bytes = ..., - uri: builtins.str = ..., - signature: builtins.bytes = ..., - pubkey: builtins.bytes = ..., - timestamp: builtins.int = ..., - rune: builtins.bytes = ..., + request: _builtins.bytes = ..., + uri: _builtins.str = ..., + signature: _builtins.bytes = ..., + pubkey: _builtins.bytes = ..., + timestamp: _builtins.int = ..., + rune: _builtins.bytes = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["pubkey", b"pubkey", "request", b"request", "rune", b"rune", "signature", b"signature", "timestamp", b"timestamp", "uri", b"uri"]) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["pubkey", b"pubkey", "request", b"request", "rune", b"rune", "signature", b"signature", "timestamp", b"timestamp", "uri", b"uri"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___PendingRequest = PendingRequest +Global___PendingRequest: _TypeAlias = PendingRequest # noqa: Y015 -@typing.final -class NodeConfig(google.protobuf.message.Message): +@_typing.final +class NodeConfig(_message.Message): """The `NodeConfig` is used to pass startup parameters to the node. The `gl-plugin` will look for a file in its directory to load these values from. Please refer to the individual fields to learn what they do. """ - DESCRIPTOR: google.protobuf.descriptor.Descriptor + DESCRIPTOR: _descriptor.Descriptor - STARTUPMSGS_FIELD_NUMBER: builtins.int - @property - def startupmsgs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___StartupMessage]: + STARTUPMSGS_FIELD_NUMBER: _builtins.int + @_builtins.property + def startupmsgs(self) -> _containers.RepeatedCompositeFieldContainer[Global___StartupMessage]: """In order to start without a signer attached we need to stash a couple of canned messages that we'd otherwise ask from the signer. These are just request-response tuples @@ -341,35 +359,37 @@ class NodeConfig(google.protobuf.message.Message): def __init__( self, *, - startupmsgs: collections.abc.Iterable[global___StartupMessage] | None = ..., + startupmsgs: _abc.Iterable[Global___StartupMessage] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["startupmsgs", b"startupmsgs"]) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["startupmsgs", b"startupmsgs"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___NodeConfig = NodeConfig +Global___NodeConfig: _TypeAlias = NodeConfig # noqa: Y015 -@typing.final -class GlConfig(google.protobuf.message.Message): +@_typing.final +class GlConfig(_message.Message): """The `GlConfig` is used to pass greenlight-specific startup parameters to the node. The `gl-plugin` will look for a serialized config object in the node's datastore to load these values from. Please refer to the individual fields to learn what they do. """ - DESCRIPTOR: google.protobuf.descriptor.Descriptor + DESCRIPTOR: _descriptor.Descriptor - CLOSE_TO_ADDR_FIELD_NUMBER: builtins.int - close_to_addr: builtins.str + CLOSE_TO_ADDR_FIELD_NUMBER: _builtins.int + close_to_addr: _builtins.str def __init__( self, *, - close_to_addr: builtins.str = ..., + close_to_addr: _builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["close_to_addr", b"close_to_addr"]) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["close_to_addr", b"close_to_addr"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___GlConfig = GlConfig +Global___GlConfig: _TypeAlias = GlConfig # noqa: Y015 -@typing.final -class StartupMessage(google.protobuf.message.Message): +@_typing.final +class StartupMessage(_message.Message): """A message that we know will be requested by `lightningd` at startup, and that we stash a response to on the scheduler. This allows the scheduler to start a node without requiring the signer @@ -377,93 +397,96 @@ class StartupMessage(google.protobuf.message.Message): prefix, but without the length prefix. """ - DESCRIPTOR: google.protobuf.descriptor.Descriptor + DESCRIPTOR: _descriptor.Descriptor - REQUEST_FIELD_NUMBER: builtins.int - RESPONSE_FIELD_NUMBER: builtins.int - request: builtins.bytes - response: builtins.bytes + REQUEST_FIELD_NUMBER: _builtins.int + RESPONSE_FIELD_NUMBER: _builtins.int + request: _builtins.bytes + response: _builtins.bytes def __init__( self, *, - request: builtins.bytes = ..., - response: builtins.bytes = ..., + request: _builtins.bytes = ..., + response: _builtins.bytes = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["request", b"request", "response", b"response"]) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["request", b"request", "response", b"response"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___StartupMessage = StartupMessage +Global___StartupMessage: _TypeAlias = StartupMessage # noqa: Y015 -@typing.final -class StreamCustommsgRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class StreamCustommsgRequest(_message.Message): + DESCRIPTOR: _descriptor.Descriptor def __init__( self, ) -> None: ... -global___StreamCustommsgRequest = StreamCustommsgRequest +Global___StreamCustommsgRequest: _TypeAlias = StreamCustommsgRequest # noqa: Y015 -@typing.final -class Custommsg(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class Custommsg(_message.Message): + DESCRIPTOR: _descriptor.Descriptor - PEER_ID_FIELD_NUMBER: builtins.int - PAYLOAD_FIELD_NUMBER: builtins.int - peer_id: builtins.bytes - payload: builtins.bytes + PEER_ID_FIELD_NUMBER: _builtins.int + PAYLOAD_FIELD_NUMBER: _builtins.int + peer_id: _builtins.bytes + payload: _builtins.bytes def __init__( self, *, - peer_id: builtins.bytes = ..., - payload: builtins.bytes = ..., + peer_id: _builtins.bytes = ..., + payload: _builtins.bytes = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["payload", b"payload", "peer_id", b"peer_id"]) -> None: ... - -global___Custommsg = Custommsg - -@typing.final -class TrampolinePayRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - BOLT11_FIELD_NUMBER: builtins.int - TRAMPOLINE_NODE_ID_FIELD_NUMBER: builtins.int - AMOUNT_MSAT_FIELD_NUMBER: builtins.int - LABEL_FIELD_NUMBER: builtins.int - MAXFEEPERCENT_FIELD_NUMBER: builtins.int - MAXDELAY_FIELD_NUMBER: builtins.int - DESCRIPTION_FIELD_NUMBER: builtins.int - bolt11: builtins.str - trampoline_node_id: builtins.bytes - amount_msat: builtins.int - label: builtins.str - maxfeepercent: builtins.float - maxdelay: builtins.int - description: builtins.str + _ClearFieldArgType: _TypeAlias = _typing.Literal["payload", b"payload", "peer_id", b"peer_id"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + +Global___Custommsg: _TypeAlias = Custommsg # noqa: Y015 + +@_typing.final +class TrampolinePayRequest(_message.Message): + DESCRIPTOR: _descriptor.Descriptor + + BOLT11_FIELD_NUMBER: _builtins.int + TRAMPOLINE_NODE_ID_FIELD_NUMBER: _builtins.int + AMOUNT_MSAT_FIELD_NUMBER: _builtins.int + LABEL_FIELD_NUMBER: _builtins.int + MAXFEEPERCENT_FIELD_NUMBER: _builtins.int + MAXDELAY_FIELD_NUMBER: _builtins.int + DESCRIPTION_FIELD_NUMBER: _builtins.int + bolt11: _builtins.str + trampoline_node_id: _builtins.bytes + amount_msat: _builtins.int + label: _builtins.str + maxfeepercent: _builtins.float + maxdelay: _builtins.int + description: _builtins.str def __init__( self, *, - bolt11: builtins.str = ..., - trampoline_node_id: builtins.bytes = ..., - amount_msat: builtins.int = ..., - label: builtins.str = ..., - maxfeepercent: builtins.float = ..., - maxdelay: builtins.int = ..., - description: builtins.str = ..., + bolt11: _builtins.str = ..., + trampoline_node_id: _builtins.bytes = ..., + amount_msat: _builtins.int = ..., + label: _builtins.str = ..., + maxfeepercent: _builtins.float = ..., + maxdelay: _builtins.int = ..., + description: _builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["amount_msat", b"amount_msat", "bolt11", b"bolt11", "description", b"description", "label", b"label", "maxdelay", b"maxdelay", "maxfeepercent", b"maxfeepercent", "trampoline_node_id", b"trampoline_node_id"]) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["amount_msat", b"amount_msat", "bolt11", b"bolt11", "description", b"description", "label", b"label", "maxdelay", b"maxdelay", "maxfeepercent", b"maxfeepercent", "trampoline_node_id", b"trampoline_node_id"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___TrampolinePayRequest = TrampolinePayRequest +Global___TrampolinePayRequest: _TypeAlias = TrampolinePayRequest # noqa: Y015 -@typing.final -class TrampolinePayResponse(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class TrampolinePayResponse(_message.Message): + DESCRIPTOR: _descriptor.Descriptor class _PayStatus: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType + ValueType = _typing.NewType("ValueType", _builtins.int) + V: _TypeAlias = ValueType # noqa: Y015 - class _PayStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[TrampolinePayResponse._PayStatus.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + class _PayStatusEnumTypeWrapper(_enum_type_wrapper._EnumTypeWrapper[TrampolinePayResponse._PayStatus.ValueType], _builtins.type): + DESCRIPTOR: _descriptor.EnumDescriptor COMPLETE: TrampolinePayResponse._PayStatus.ValueType # 0 FAILED: TrampolinePayResponse._PayStatus.ValueType # 2 @@ -471,92 +494,184 @@ class TrampolinePayResponse(google.protobuf.message.Message): COMPLETE: TrampolinePayResponse.PayStatus.ValueType # 0 FAILED: TrampolinePayResponse.PayStatus.ValueType # 2 - PAYMENT_PREIMAGE_FIELD_NUMBER: builtins.int - PAYMENT_HASH_FIELD_NUMBER: builtins.int - CREATED_AT_FIELD_NUMBER: builtins.int - PARTS_FIELD_NUMBER: builtins.int - AMOUNT_MSAT_FIELD_NUMBER: builtins.int - AMOUNT_SENT_MSAT_FIELD_NUMBER: builtins.int - DESTINATION_FIELD_NUMBER: builtins.int - payment_preimage: builtins.bytes - payment_hash: builtins.bytes - created_at: builtins.float - parts: builtins.int - amount_msat: builtins.int - amount_sent_msat: builtins.int - destination: builtins.bytes + PAYMENT_PREIMAGE_FIELD_NUMBER: _builtins.int + PAYMENT_HASH_FIELD_NUMBER: _builtins.int + CREATED_AT_FIELD_NUMBER: _builtins.int + PARTS_FIELD_NUMBER: _builtins.int + AMOUNT_MSAT_FIELD_NUMBER: _builtins.int + AMOUNT_SENT_MSAT_FIELD_NUMBER: _builtins.int + DESTINATION_FIELD_NUMBER: _builtins.int + payment_preimage: _builtins.bytes + payment_hash: _builtins.bytes + created_at: _builtins.float + parts: _builtins.int + amount_msat: _builtins.int + amount_sent_msat: _builtins.int + destination: _builtins.bytes def __init__( self, *, - payment_preimage: builtins.bytes = ..., - payment_hash: builtins.bytes = ..., - created_at: builtins.float = ..., - parts: builtins.int = ..., - amount_msat: builtins.int = ..., - amount_sent_msat: builtins.int = ..., - destination: builtins.bytes = ..., + payment_preimage: _builtins.bytes = ..., + payment_hash: _builtins.bytes = ..., + created_at: _builtins.float = ..., + parts: _builtins.int = ..., + amount_msat: _builtins.int = ..., + amount_sent_msat: _builtins.int = ..., + destination: _builtins.bytes = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["amount_msat", b"amount_msat", "amount_sent_msat", b"amount_sent_msat", "created_at", b"created_at", "destination", b"destination", "parts", b"parts", "payment_hash", b"payment_hash", "payment_preimage", b"payment_preimage"]) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["amount_msat", b"amount_msat", "amount_sent_msat", b"amount_sent_msat", "created_at", b"created_at", "destination", b"destination", "parts", b"parts", "payment_hash", b"payment_hash", "payment_preimage", b"payment_preimage"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___TrampolinePayResponse = TrampolinePayResponse +Global___TrampolinePayResponse: _TypeAlias = TrampolinePayResponse # noqa: Y015 -@typing.final -class LspInvoiceRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor +@_typing.final +class LspInvoiceRequest(_message.Message): + DESCRIPTOR: _descriptor.Descriptor - LSP_ID_FIELD_NUMBER: builtins.int - TOKEN_FIELD_NUMBER: builtins.int - AMOUNT_MSAT_FIELD_NUMBER: builtins.int - DESCRIPTION_FIELD_NUMBER: builtins.int - LABEL_FIELD_NUMBER: builtins.int - lsp_id: builtins.str + LSP_ID_FIELD_NUMBER: _builtins.int + TOKEN_FIELD_NUMBER: _builtins.int + AMOUNT_MSAT_FIELD_NUMBER: _builtins.int + DESCRIPTION_FIELD_NUMBER: _builtins.int + LABEL_FIELD_NUMBER: _builtins.int + lsp_id: _builtins.str """len=0 => None, let the server decide.""" - token: builtins.str + token: _builtins.str """Optional: for discounts/API keys len=0 => None """ - amount_msat: builtins.int + amount_msat: _builtins.int """Pass-through of cln invoice rpc params 0 => Any """ - description: builtins.str - label: builtins.str + description: _builtins.str + label: _builtins.str def __init__( self, *, - lsp_id: builtins.str = ..., - token: builtins.str = ..., - amount_msat: builtins.int = ..., - description: builtins.str = ..., - label: builtins.str = ..., + lsp_id: _builtins.str = ..., + token: _builtins.str = ..., + amount_msat: _builtins.int = ..., + description: _builtins.str = ..., + label: _builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["amount_msat", b"amount_msat", "description", b"description", "label", b"label", "lsp_id", b"lsp_id", "token", b"token"]) -> None: ... - -global___LspInvoiceRequest = LspInvoiceRequest - -@typing.final -class LspInvoiceResponse(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - BOLT11_FIELD_NUMBER: builtins.int - CREATED_INDEX_FIELD_NUMBER: builtins.int - EXPIRES_AT_FIELD_NUMBER: builtins.int - PAYMENT_HASH_FIELD_NUMBER: builtins.int - PAYMENT_SECRET_FIELD_NUMBER: builtins.int - bolt11: builtins.str - created_index: builtins.int - expires_at: builtins.int - payment_hash: builtins.bytes - payment_secret: builtins.bytes + _ClearFieldArgType: _TypeAlias = _typing.Literal["amount_msat", b"amount_msat", "description", b"description", "label", b"label", "lsp_id", b"lsp_id", "token", b"token"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + +Global___LspInvoiceRequest: _TypeAlias = LspInvoiceRequest # noqa: Y015 + +@_typing.final +class LspInvoiceResponse(_message.Message): + DESCRIPTOR: _descriptor.Descriptor + + BOLT11_FIELD_NUMBER: _builtins.int + CREATED_INDEX_FIELD_NUMBER: _builtins.int + EXPIRES_AT_FIELD_NUMBER: _builtins.int + PAYMENT_HASH_FIELD_NUMBER: _builtins.int + PAYMENT_SECRET_FIELD_NUMBER: _builtins.int + bolt11: _builtins.str + created_index: _builtins.int + expires_at: _builtins.int + payment_hash: _builtins.bytes + payment_secret: _builtins.bytes + def __init__( + self, + *, + bolt11: _builtins.str = ..., + created_index: _builtins.int = ..., + expires_at: _builtins.int = ..., + payment_hash: _builtins.bytes = ..., + payment_secret: _builtins.bytes = ..., + ) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["bolt11", b"bolt11", "created_index", b"created_index", "expires_at", b"expires_at", "payment_hash", b"payment_hash", "payment_secret", b"payment_secret"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + +Global___LspInvoiceResponse: _TypeAlias = LspInvoiceResponse # noqa: Y015 + +@_typing.final +class NodeEventsRequest(_message.Message): + """Request for streaming node events. Currently empty but defined as + its own message type to allow adding filters in the future (e.g., + filter by event type, invoice label, etc.) + """ + + DESCRIPTOR: _descriptor.Descriptor + + def __init__( + self, + ) -> None: ... + +Global___NodeEventsRequest: _TypeAlias = NodeEventsRequest # noqa: Y015 + +@_typing.final +class NodeEvent(_message.Message): + """A real-time event from the node. Uses oneof to discriminate between + different event types. + """ + + DESCRIPTOR: _descriptor.Descriptor + + INVOICE_PAID_FIELD_NUMBER: _builtins.int + @_builtins.property + def invoice_paid(self) -> Global___InvoicePaid: + """Future event types: + PeerConnected peer_connected = 2; + PeerDisconnected peer_disconnected = 3; + ChannelStateChanged channel_state_changed = 4; + BalanceChanged balance_changed = 5; + """ + + def __init__( + self, + *, + invoice_paid: Global___InvoicePaid | None = ..., + ) -> None: ... + _HasFieldArgType: _TypeAlias = _typing.Literal["event", b"event", "invoice_paid", b"invoice_paid"] # noqa: Y015 + def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["event", b"event", "invoice_paid", b"invoice_paid"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType_event: _TypeAlias = _typing.Literal["invoice_paid"] # noqa: Y015 + _WhichOneofArgType_event: _TypeAlias = _typing.Literal["event", b"event"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType_event) -> _WhichOneofReturnType_event | None: ... + +Global___NodeEvent: _TypeAlias = NodeEvent # noqa: Y015 + +@_typing.final +class InvoicePaid(_message.Message): + """Event emitted when an invoice is paid.""" + + DESCRIPTOR: _descriptor.Descriptor + + PAYMENT_HASH_FIELD_NUMBER: _builtins.int + BOLT11_FIELD_NUMBER: _builtins.int + PREIMAGE_FIELD_NUMBER: _builtins.int + LABEL_FIELD_NUMBER: _builtins.int + AMOUNT_MSAT_FIELD_NUMBER: _builtins.int + EXTRATLVS_FIELD_NUMBER: _builtins.int + payment_hash: _builtins.bytes + """The payment hash of the paid invoice.""" + bolt11: _builtins.str + """The bolt11 invoice string.""" + preimage: _builtins.bytes + """The preimage that proves payment.""" + label: _builtins.str + """The label assigned to the invoice.""" + amount_msat: _builtins.int + """Amount received in millisatoshis.""" + @_builtins.property + def extratlvs(self) -> _containers.RepeatedCompositeFieldContainer[Global___TlvField]: + """Extra TLV fields included in the payment.""" + def __init__( self, *, - bolt11: builtins.str = ..., - created_index: builtins.int = ..., - expires_at: builtins.int = ..., - payment_hash: builtins.bytes = ..., - payment_secret: builtins.bytes = ..., + payment_hash: _builtins.bytes = ..., + bolt11: _builtins.str = ..., + preimage: _builtins.bytes = ..., + label: _builtins.str = ..., + amount_msat: _builtins.int = ..., + extratlvs: _abc.Iterable[Global___TlvField] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["bolt11", b"bolt11", "created_index", b"created_index", "expires_at", b"expires_at", "payment_hash", b"payment_hash", "payment_secret", b"payment_secret"]) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["amount_msat", b"amount_msat", "bolt11", b"bolt11", "extratlvs", b"extratlvs", "label", b"label", "payment_hash", b"payment_hash", "preimage", b"preimage"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... -global___LspInvoiceResponse = LspInvoiceResponse +Global___InvoicePaid: _TypeAlias = InvoicePaid # noqa: Y015 diff --git a/libs/gl-client-py/glclient/greenlight_pb2_grpc.py b/libs/gl-client-py/glclient/greenlight_pb2_grpc.py index 7800c6861..b95e8c9e0 100644 --- a/libs/gl-client-py/glclient/greenlight_pb2_grpc.py +++ b/libs/gl-client-py/glclient/greenlight_pb2_grpc.py @@ -5,7 +5,7 @@ from glclient import greenlight_pb2 as glclient_dot_greenlight__pb2 -GRPC_GENERATED_VERSION = '1.76.0' +GRPC_GENERATED_VERSION = '1.78.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -69,6 +69,11 @@ def __init__(self, channel): request_serializer=glclient_dot_greenlight__pb2.StreamCustommsgRequest.SerializeToString, response_deserializer=glclient_dot_greenlight__pb2.Custommsg.FromString, _registered_method=True) + self.StreamNodeEvents = channel.unary_stream( + '/greenlight.Node/StreamNodeEvents', + request_serializer=glclient_dot_greenlight__pb2.NodeEventsRequest.SerializeToString, + response_deserializer=glclient_dot_greenlight__pb2.NodeEvent.FromString, + _registered_method=True) self.StreamHsmRequests = channel.unary_stream( '/greenlight.Node/StreamHsmRequests', request_serializer=glclient_dot_greenlight__pb2.Empty.SerializeToString, @@ -151,6 +156,18 @@ def StreamCustommsg(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def StreamNodeEvents(self, request, context): + """Stream node events in real-time. + + This is a unified event stream that delivers various node events + as they occur, including invoice updates, peer changes, channel + state changes, and balance updates. Events are not persisted and + will not be replayed if the stream is interrupted. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def StreamHsmRequests(self, request, context): """////////////////////////////// HSM Messages //////////////////////// @@ -208,6 +225,11 @@ def add_NodeServicer_to_server(servicer, server): request_deserializer=glclient_dot_greenlight__pb2.StreamCustommsgRequest.FromString, response_serializer=glclient_dot_greenlight__pb2.Custommsg.SerializeToString, ), + 'StreamNodeEvents': grpc.unary_stream_rpc_method_handler( + servicer.StreamNodeEvents, + request_deserializer=glclient_dot_greenlight__pb2.NodeEventsRequest.FromString, + response_serializer=glclient_dot_greenlight__pb2.NodeEvent.SerializeToString, + ), 'StreamHsmRequests': grpc.unary_stream_rpc_method_handler( servicer.StreamHsmRequests, request_deserializer=glclient_dot_greenlight__pb2.Empty.FromString, @@ -362,6 +384,33 @@ def StreamCustommsg(request, metadata, _registered_method=True) + @staticmethod + def StreamNodeEvents(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream( + request, + target, + '/greenlight.Node/StreamNodeEvents', + glclient_dot_greenlight__pb2.NodeEventsRequest.SerializeToString, + glclient_dot_greenlight__pb2.NodeEvent.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + @staticmethod def StreamHsmRequests(request, target, diff --git a/libs/gl-client-py/glclient/greenlight_pb2_grpc.pyi b/libs/gl-client-py/glclient/greenlight_pb2_grpc.pyi index 7b9dcab23..0ed792eb3 100644 --- a/libs/gl-client-py/glclient/greenlight_pb2_grpc.pyi +++ b/libs/gl-client-py/glclient/greenlight_pb2_grpc.pyi @@ -3,20 +3,29 @@ isort:skip_file """ -import abc -import collections.abc -import glclient.greenlight_pb2 -import grpc -import grpc.aio -import typing +from collections import abc as _abc +from glclient import greenlight_pb2 as _greenlight_pb2 +from grpc import aio as _aio +import abc as _abc_1 +import grpc as _grpc +import sys +import typing as _typing -_T = typing.TypeVar("_T") +if sys.version_info >= (3, 11): + from typing import Self as _Self +else: + from typing_extensions import Self as _Self -class _MaybeAsyncIterator(collections.abc.AsyncIterator[_T], collections.abc.Iterator[_T], metaclass=abc.ABCMeta): ... +_T = _typing.TypeVar("_T") -class _ServicerContext(grpc.ServicerContext, grpc.aio.ServicerContext): # type: ignore[misc, type-arg] +class _MaybeAsyncIterator(_abc.AsyncIterator[_T], _abc.Iterator[_T], metaclass=_abc_1.ABCMeta): ... + +class _ServicerContext(_grpc.ServicerContext, _aio.ServicerContext): # type: ignore[misc, type-arg] ... +GRPC_GENERATED_VERSION: str +GRPC_VERSION: str + class NodeStub: """The node service represents your node running on greenlight's infrastructure. You can use the exposed RPC methods to interact @@ -35,29 +44,21 @@ class NodeStub: Greenlight-specific, and backported functionality. """ - def __init__(self, channel: typing.Union[grpc.Channel, grpc.aio.Channel]) -> None: ... - LspInvoice: grpc.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.LspInvoiceRequest, - glclient.greenlight_pb2.LspInvoiceResponse, - ] + @_typing.overload + def __new__(cls, channel: _grpc.Channel) -> _Self: ... + @_typing.overload + def __new__(cls, channel: _aio.Channel) -> NodeAsyncStub: ... + LspInvoice: _grpc.UnaryUnaryMultiCallable[_greenlight_pb2.LspInvoiceRequest, _greenlight_pb2.LspInvoiceResponse] """Create an invoice to request an incoming payment. Includes LSP negotiation to open a channel on-demand when needed. """ - - StreamIncoming: grpc.UnaryStreamMultiCallable[ - glclient.greenlight_pb2.StreamIncomingFilter, - glclient.greenlight_pb2.IncomingPayment, - ] + StreamIncoming: _grpc.UnaryStreamMultiCallable[_greenlight_pb2.StreamIncomingFilter, _greenlight_pb2.IncomingPayment] """Stream incoming payments Currently includes off-chain payments received matching an invoice or spontaneus paymens through keysend. """ - - StreamLog: grpc.UnaryStreamMultiCallable[ - glclient.greenlight_pb2.StreamLogRequest, - glclient.greenlight_pb2.LogEntry, - ] + StreamLog: _grpc.UnaryStreamMultiCallable[_greenlight_pb2.StreamLogRequest, _greenlight_pb2.LogEntry] """Stream the logs as they are produced by the node Mainly intended for debugging clients by tailing the log as @@ -67,21 +68,21 @@ class NodeStub: be rather large, and should not be streamed onto resource-constrained devices. """ - - StreamCustommsg: grpc.UnaryStreamMultiCallable[ - glclient.greenlight_pb2.StreamCustommsgRequest, - glclient.greenlight_pb2.Custommsg, - ] + StreamCustommsg: _grpc.UnaryStreamMultiCallable[_greenlight_pb2.StreamCustommsgRequest, _greenlight_pb2.Custommsg] """Listen for incoming `custommsg` messages from peers. The messages are forwarded as they come in, and will not be replayed if the stream is interrupted. """ + StreamNodeEvents: _grpc.UnaryStreamMultiCallable[_greenlight_pb2.NodeEventsRequest, _greenlight_pb2.NodeEvent] + """Stream node events in real-time. - StreamHsmRequests: grpc.UnaryStreamMultiCallable[ - glclient.greenlight_pb2.Empty, - glclient.greenlight_pb2.HsmRequest, - ] + This is a unified event stream that delivers various node events + as they occur, including invoice updates, peer changes, channel + state changes, and balance updates. Events are not persisted and + will not be replayed if the stream is interrupted. + """ + StreamHsmRequests: _grpc.UnaryStreamMultiCallable[_greenlight_pb2.Empty, _greenlight_pb2.HsmRequest] """////////////////////////////// HSM Messages //////////////////////// The following messages are related to communicating HSM @@ -93,23 +94,12 @@ class NodeStub: Stream requests from the node to any key device that can respond to them. """ + RespondHsmRequest: _grpc.UnaryUnaryMultiCallable[_greenlight_pb2.HsmResponse, _greenlight_pb2.Empty] + Configure: _grpc.UnaryUnaryMultiCallable[_greenlight_pb2.GlConfig, _greenlight_pb2.Empty] + TrampolinePay: _grpc.UnaryUnaryMultiCallable[_greenlight_pb2.TrampolinePayRequest, _greenlight_pb2.TrampolinePayResponse] - RespondHsmRequest: grpc.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.HsmResponse, - glclient.greenlight_pb2.Empty, - ] - - Configure: grpc.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.GlConfig, - glclient.greenlight_pb2.Empty, - ] - - TrampolinePay: grpc.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.TrampolinePayRequest, - glclient.greenlight_pb2.TrampolinePayResponse, - ] - -class NodeAsyncStub: +@_typing.type_check_only +class NodeAsyncStub(NodeStub): """The node service represents your node running on greenlight's infrastructure. You can use the exposed RPC methods to interact with your node. The URI used to connect to the node depends on @@ -127,28 +117,18 @@ class NodeAsyncStub: Greenlight-specific, and backported functionality. """ - LspInvoice: grpc.aio.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.LspInvoiceRequest, - glclient.greenlight_pb2.LspInvoiceResponse, - ] + def __init__(self, channel: _aio.Channel) -> None: ... + LspInvoice: _aio.UnaryUnaryMultiCallable[_greenlight_pb2.LspInvoiceRequest, _greenlight_pb2.LspInvoiceResponse] # type: ignore[assignment] """Create an invoice to request an incoming payment. Includes LSP negotiation to open a channel on-demand when needed. """ - - StreamIncoming: grpc.aio.UnaryStreamMultiCallable[ - glclient.greenlight_pb2.StreamIncomingFilter, - glclient.greenlight_pb2.IncomingPayment, - ] + StreamIncoming: _aio.UnaryStreamMultiCallable[_greenlight_pb2.StreamIncomingFilter, _greenlight_pb2.IncomingPayment] # type: ignore[assignment] """Stream incoming payments Currently includes off-chain payments received matching an invoice or spontaneus paymens through keysend. """ - - StreamLog: grpc.aio.UnaryStreamMultiCallable[ - glclient.greenlight_pb2.StreamLogRequest, - glclient.greenlight_pb2.LogEntry, - ] + StreamLog: _aio.UnaryStreamMultiCallable[_greenlight_pb2.StreamLogRequest, _greenlight_pb2.LogEntry] # type: ignore[assignment] """Stream the logs as they are produced by the node Mainly intended for debugging clients by tailing the log as @@ -158,21 +138,21 @@ class NodeAsyncStub: be rather large, and should not be streamed onto resource-constrained devices. """ - - StreamCustommsg: grpc.aio.UnaryStreamMultiCallable[ - glclient.greenlight_pb2.StreamCustommsgRequest, - glclient.greenlight_pb2.Custommsg, - ] + StreamCustommsg: _aio.UnaryStreamMultiCallable[_greenlight_pb2.StreamCustommsgRequest, _greenlight_pb2.Custommsg] # type: ignore[assignment] """Listen for incoming `custommsg` messages from peers. The messages are forwarded as they come in, and will not be replayed if the stream is interrupted. """ + StreamNodeEvents: _aio.UnaryStreamMultiCallable[_greenlight_pb2.NodeEventsRequest, _greenlight_pb2.NodeEvent] # type: ignore[assignment] + """Stream node events in real-time. - StreamHsmRequests: grpc.aio.UnaryStreamMultiCallable[ - glclient.greenlight_pb2.Empty, - glclient.greenlight_pb2.HsmRequest, - ] + This is a unified event stream that delivers various node events + as they occur, including invoice updates, peer changes, channel + state changes, and balance updates. Events are not persisted and + will not be replayed if the stream is interrupted. + """ + StreamHsmRequests: _aio.UnaryStreamMultiCallable[_greenlight_pb2.Empty, _greenlight_pb2.HsmRequest] # type: ignore[assignment] """////////////////////////////// HSM Messages //////////////////////// The following messages are related to communicating HSM @@ -184,23 +164,11 @@ class NodeAsyncStub: Stream requests from the node to any key device that can respond to them. """ + RespondHsmRequest: _aio.UnaryUnaryMultiCallable[_greenlight_pb2.HsmResponse, _greenlight_pb2.Empty] # type: ignore[assignment] + Configure: _aio.UnaryUnaryMultiCallable[_greenlight_pb2.GlConfig, _greenlight_pb2.Empty] # type: ignore[assignment] + TrampolinePay: _aio.UnaryUnaryMultiCallable[_greenlight_pb2.TrampolinePayRequest, _greenlight_pb2.TrampolinePayResponse] # type: ignore[assignment] - RespondHsmRequest: grpc.aio.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.HsmResponse, - glclient.greenlight_pb2.Empty, - ] - - Configure: grpc.aio.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.GlConfig, - glclient.greenlight_pb2.Empty, - ] - - TrampolinePay: grpc.aio.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.TrampolinePayRequest, - glclient.greenlight_pb2.TrampolinePayResponse, - ] - -class NodeServicer(metaclass=abc.ABCMeta): +class NodeServicer(metaclass=_abc_1.ABCMeta): """The node service represents your node running on greenlight's infrastructure. You can use the exposed RPC methods to interact with your node. The URI used to connect to the node depends on @@ -218,34 +186,34 @@ class NodeServicer(metaclass=abc.ABCMeta): Greenlight-specific, and backported functionality. """ - @abc.abstractmethod + @_abc_1.abstractmethod def LspInvoice( self, - request: glclient.greenlight_pb2.LspInvoiceRequest, + request: _greenlight_pb2.LspInvoiceRequest, context: _ServicerContext, - ) -> typing.Union[glclient.greenlight_pb2.LspInvoiceResponse, collections.abc.Awaitable[glclient.greenlight_pb2.LspInvoiceResponse]]: + ) -> _typing.Union[_greenlight_pb2.LspInvoiceResponse, _abc.Awaitable[_greenlight_pb2.LspInvoiceResponse]]: """Create an invoice to request an incoming payment. Includes LSP negotiation to open a channel on-demand when needed. """ - @abc.abstractmethod + @_abc_1.abstractmethod def StreamIncoming( self, - request: glclient.greenlight_pb2.StreamIncomingFilter, + request: _greenlight_pb2.StreamIncomingFilter, context: _ServicerContext, - ) -> typing.Union[collections.abc.Iterator[glclient.greenlight_pb2.IncomingPayment], collections.abc.AsyncIterator[glclient.greenlight_pb2.IncomingPayment]]: + ) -> _typing.Union[_abc.Iterator[_greenlight_pb2.IncomingPayment], _abc.AsyncIterator[_greenlight_pb2.IncomingPayment]]: """Stream incoming payments Currently includes off-chain payments received matching an invoice or spontaneus paymens through keysend. """ - @abc.abstractmethod + @_abc_1.abstractmethod def StreamLog( self, - request: glclient.greenlight_pb2.StreamLogRequest, + request: _greenlight_pb2.StreamLogRequest, context: _ServicerContext, - ) -> typing.Union[collections.abc.Iterator[glclient.greenlight_pb2.LogEntry], collections.abc.AsyncIterator[glclient.greenlight_pb2.LogEntry]]: + ) -> _typing.Union[_abc.Iterator[_greenlight_pb2.LogEntry], _abc.AsyncIterator[_greenlight_pb2.LogEntry]]: """Stream the logs as they are produced by the node Mainly intended for debugging clients by tailing the log as @@ -256,24 +224,38 @@ class NodeServicer(metaclass=abc.ABCMeta): resource-constrained devices. """ - @abc.abstractmethod + @_abc_1.abstractmethod def StreamCustommsg( self, - request: glclient.greenlight_pb2.StreamCustommsgRequest, + request: _greenlight_pb2.StreamCustommsgRequest, context: _ServicerContext, - ) -> typing.Union[collections.abc.Iterator[glclient.greenlight_pb2.Custommsg], collections.abc.AsyncIterator[glclient.greenlight_pb2.Custommsg]]: + ) -> _typing.Union[_abc.Iterator[_greenlight_pb2.Custommsg], _abc.AsyncIterator[_greenlight_pb2.Custommsg]]: """Listen for incoming `custommsg` messages from peers. The messages are forwarded as they come in, and will not be replayed if the stream is interrupted. """ - @abc.abstractmethod + @_abc_1.abstractmethod + def StreamNodeEvents( + self, + request: _greenlight_pb2.NodeEventsRequest, + context: _ServicerContext, + ) -> _typing.Union[_abc.Iterator[_greenlight_pb2.NodeEvent], _abc.AsyncIterator[_greenlight_pb2.NodeEvent]]: + """Stream node events in real-time. + + This is a unified event stream that delivers various node events + as they occur, including invoice updates, peer changes, channel + state changes, and balance updates. Events are not persisted and + will not be replayed if the stream is interrupted. + """ + + @_abc_1.abstractmethod def StreamHsmRequests( self, - request: glclient.greenlight_pb2.Empty, + request: _greenlight_pb2.Empty, context: _ServicerContext, - ) -> typing.Union[collections.abc.Iterator[glclient.greenlight_pb2.HsmRequest], collections.abc.AsyncIterator[glclient.greenlight_pb2.HsmRequest]]: + ) -> _typing.Union[_abc.Iterator[_greenlight_pb2.HsmRequest], _abc.AsyncIterator[_greenlight_pb2.HsmRequest]]: """////////////////////////////// HSM Messages //////////////////////// The following messages are related to communicating HSM @@ -286,65 +268,56 @@ class NodeServicer(metaclass=abc.ABCMeta): respond to them. """ - @abc.abstractmethod + @_abc_1.abstractmethod def RespondHsmRequest( self, - request: glclient.greenlight_pb2.HsmResponse, + request: _greenlight_pb2.HsmResponse, context: _ServicerContext, - ) -> typing.Union[glclient.greenlight_pb2.Empty, collections.abc.Awaitable[glclient.greenlight_pb2.Empty]]: ... + ) -> _typing.Union[_greenlight_pb2.Empty, _abc.Awaitable[_greenlight_pb2.Empty]]: ... - @abc.abstractmethod + @_abc_1.abstractmethod def Configure( self, - request: glclient.greenlight_pb2.GlConfig, + request: _greenlight_pb2.GlConfig, context: _ServicerContext, - ) -> typing.Union[glclient.greenlight_pb2.Empty, collections.abc.Awaitable[glclient.greenlight_pb2.Empty]]: ... + ) -> _typing.Union[_greenlight_pb2.Empty, _abc.Awaitable[_greenlight_pb2.Empty]]: ... - @abc.abstractmethod + @_abc_1.abstractmethod def TrampolinePay( self, - request: glclient.greenlight_pb2.TrampolinePayRequest, + request: _greenlight_pb2.TrampolinePayRequest, context: _ServicerContext, - ) -> typing.Union[glclient.greenlight_pb2.TrampolinePayResponse, collections.abc.Awaitable[glclient.greenlight_pb2.TrampolinePayResponse]]: ... + ) -> _typing.Union[_greenlight_pb2.TrampolinePayResponse, _abc.Awaitable[_greenlight_pb2.TrampolinePayResponse]]: ... -def add_NodeServicer_to_server(servicer: NodeServicer, server: typing.Union[grpc.Server, grpc.aio.Server]) -> None: ... +def add_NodeServicer_to_server(servicer: NodeServicer, server: _typing.Union[_grpc.Server, _aio.Server]) -> None: ... class HsmStub: - def __init__(self, channel: typing.Union[grpc.Channel, grpc.aio.Channel]) -> None: ... - Request: grpc.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.HsmRequest, - glclient.greenlight_pb2.HsmResponse, - ] - - Ping: grpc.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.Empty, - glclient.greenlight_pb2.Empty, - ] - -class HsmAsyncStub: - Request: grpc.aio.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.HsmRequest, - glclient.greenlight_pb2.HsmResponse, - ] - - Ping: grpc.aio.UnaryUnaryMultiCallable[ - glclient.greenlight_pb2.Empty, - glclient.greenlight_pb2.Empty, - ] - -class HsmServicer(metaclass=abc.ABCMeta): - @abc.abstractmethod + @_typing.overload + def __new__(cls, channel: _grpc.Channel) -> _Self: ... + @_typing.overload + def __new__(cls, channel: _aio.Channel) -> HsmAsyncStub: ... + Request: _grpc.UnaryUnaryMultiCallable[_greenlight_pb2.HsmRequest, _greenlight_pb2.HsmResponse] + Ping: _grpc.UnaryUnaryMultiCallable[_greenlight_pb2.Empty, _greenlight_pb2.Empty] + +@_typing.type_check_only +class HsmAsyncStub(HsmStub): + def __init__(self, channel: _aio.Channel) -> None: ... + Request: _aio.UnaryUnaryMultiCallable[_greenlight_pb2.HsmRequest, _greenlight_pb2.HsmResponse] # type: ignore[assignment] + Ping: _aio.UnaryUnaryMultiCallable[_greenlight_pb2.Empty, _greenlight_pb2.Empty] # type: ignore[assignment] + +class HsmServicer(metaclass=_abc_1.ABCMeta): + @_abc_1.abstractmethod def Request( self, - request: glclient.greenlight_pb2.HsmRequest, + request: _greenlight_pb2.HsmRequest, context: _ServicerContext, - ) -> typing.Union[glclient.greenlight_pb2.HsmResponse, collections.abc.Awaitable[glclient.greenlight_pb2.HsmResponse]]: ... + ) -> _typing.Union[_greenlight_pb2.HsmResponse, _abc.Awaitable[_greenlight_pb2.HsmResponse]]: ... - @abc.abstractmethod + @_abc_1.abstractmethod def Ping( self, - request: glclient.greenlight_pb2.Empty, + request: _greenlight_pb2.Empty, context: _ServicerContext, - ) -> typing.Union[glclient.greenlight_pb2.Empty, collections.abc.Awaitable[glclient.greenlight_pb2.Empty]]: ... + ) -> _typing.Union[_greenlight_pb2.Empty, _abc.Awaitable[_greenlight_pb2.Empty]]: ... -def add_HsmServicer_to_server(servicer: HsmServicer, server: typing.Union[grpc.Server, grpc.aio.Server]) -> None: ... +def add_HsmServicer_to_server(servicer: HsmServicer, server: _typing.Union[_grpc.Server, _aio.Server]) -> None: ... diff --git a/libs/gl-client-py/src/node.rs b/libs/gl-client-py/src/node.rs index 992a3a491..0fbfc8145 100644 --- a/libs/gl-client-py/src/node.rs +++ b/libs/gl-client-py/src/node.rs @@ -57,6 +57,14 @@ impl Node { Ok(CustommsgStream { inner: stream }) } + fn stream_node_events(&self, args: &[u8]) -> PyResult { + let req = pb::NodeEventsRequest::decode(args).map_err(error_decoding_request)?; + let stream = exec(self.client.clone().stream_node_events(req)) + .map(|x| x.into_inner()) + .map_err(error_starting_stream)?; + Ok(NodeEventStream { inner: stream }) + } + fn trampoline_pay( &self, bolt11: String, @@ -162,6 +170,18 @@ impl CustommsgStream { } } +#[pyclass] +struct NodeEventStream { + inner: tonic::codec::Streaming, +} + +#[pymethods] +impl NodeEventStream { + fn next(&mut self) -> PyResult>> { + convert_stream_entry(exec(async { self.inner.message().await })) + } +} + fn convert_stream_entry(r: Result, Status>) -> PyResult>> { let res = match r { Ok(Some(v)) => v, diff --git a/libs/proto/glclient/greenlight.proto b/libs/proto/glclient/greenlight.proto index 63dd182c0..94d2cfacd 100644 --- a/libs/proto/glclient/greenlight.proto +++ b/libs/proto/glclient/greenlight.proto @@ -43,6 +43,14 @@ service Node { // replayed if the stream is interrupted. rpc StreamCustommsg(StreamCustommsgRequest) returns (stream Custommsg) {} + // Stream node events in real-time. + // + // This is a unified event stream that delivers various node events + // as they occur, including invoice updates, peer changes, channel + // state changes, and balance updates. Events are not persisted and + // will not be replayed if the stream is interrupted. + rpc StreamNodeEvents(NodeEventsRequest) returns (stream NodeEvent) {} + //////////////////////////////// HSM Messages //////////////////////// // // The following messages are related to communicating HSM @@ -243,3 +251,38 @@ message LspInvoiceResponse { bytes payment_hash = 4; bytes payment_secret = 5; } + +// Request for streaming node events. Currently empty but defined as +// its own message type to allow adding filters in the future (e.g., +// filter by event type, invoice label, etc.) +message NodeEventsRequest { +} + +// A real-time event from the node. Uses oneof to discriminate between +// different event types. +message NodeEvent { + oneof event { + InvoicePaid invoice_paid = 1; + // Future event types: + // PeerConnected peer_connected = 2; + // PeerDisconnected peer_disconnected = 3; + // ChannelStateChanged channel_state_changed = 4; + // BalanceChanged balance_changed = 5; + } +} + +// Event emitted when an invoice is paid. +message InvoicePaid { + // The payment hash of the paid invoice. + bytes payment_hash = 1; + // The bolt11 invoice string. + string bolt11 = 2; + // The preimage that proves payment. + bytes preimage = 3; + // The label assigned to the invoice. + string label = 4; + // Amount received in millisatoshis. + uint64 amount_msat = 5; + // Extra TLV fields included in the payment. + repeated TlvField extratlvs = 6; +} From ffa02e693bacd5830f72ca5882a9d3249d53e046 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 19 Feb 2026 17:16:22 +0100 Subject: [PATCH 11/16] gl-plugin: Add comprehensive rustdoc examples to events module Document the event system with examples covering: - Type alias pattern for Event (recommended approach) - Publishing internal events with custom payload types - Subscribing to internal events with downcast_internal - Publishing public events (IncomingPayment, etc.) - Subscribing to public events server-side - Client-side consumption via gl-sdk (Python and Rust) --- libs/gl-plugin/src/events.rs | 188 +++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/libs/gl-plugin/src/events.rs b/libs/gl-plugin/src/events.rs index c5e0fd477..cd0dbeae9 100644 --- a/libs/gl-plugin/src/events.rs +++ b/libs/gl-plugin/src/events.rs @@ -3,6 +3,194 @@ //! This module provides a generic `Event` enum that can be extended //! by downstream crates (like gl-plugin-internal) with custom internal //! event types, while keeping the core events defined here. +//! +//! # Architecture +//! +//! The event system has two layers: +//! +//! - **Internal events** (`Event::Internal(I)`) - Type-erased events for +//! communication within the plugin process. Not exposed to clients. +//! - **Public events** (`Event::IncomingPayment`, etc.) - Automatically +//! converted to `NodeEvent` protobufs and streamed to gl-sdk clients +//! via `StreamNodeEvents`. +//! +//! The [`EventBus`] uses `tokio::sync::broadcast` so multiple subscribers +//! can receive the same events. Events are not persisted - if a client +//! disconnects, it won't receive missed events. +//! +//! # Examples +//! +//! In these examples, we define a type alias for the event type to avoid +//! repeating the generic parameter. This is the recommended pattern: +//! +//! ```ignore +//! use gl_plugin::events::Event; +//! +//! // In gl-plugin (no internal events): +//! type PluginEvent = Event<()>; +//! +//! // In gl-plugin-internal (with internal events): +//! #[derive(Clone, Debug)] +//! pub enum InternalPayload { +//! NodeMeta { node_id: Vec, version: String }, +//! Shutdown { reason: String }, +//! } +//! type PluginEvent = Event; +//! ``` +//! +//! ## Publishing an Internal Event +//! +//! Internal events are for communication within the plugin system and +//! are NOT exposed to clients. Use the `Internal` variant with your payload: +//! +//! ```ignore +//! use gl_plugin::events::{Event, EventBus}; +//! +//! // Define your internal payload type +//! #[derive(Clone, Debug)] +//! pub enum InternalPayload { +//! NodeMeta { node_id: Vec, version: String }, +//! Shutdown { reason: String }, +//! } +//! +//! // Define a type alias for convenience +//! type PluginEvent = Event; +//! +//! fn publish_internal_event(bus: &EventBus) { +//! let payload = InternalPayload::NodeMeta { +//! node_id: vec![0x02; 33], +//! version: "v25.12".to_string(), +//! }; +//! bus.publish(PluginEvent::Internal(payload)); +//! } +//! ``` +//! +//! ## Subscribing to Internal Events +//! +//! Use the [`ErasedEventExt`] trait to downcast internal payloads: +//! +//! ```ignore +//! use gl_plugin::events::{EventBus, ErasedEventExt}; +//! +//! async fn subscribe_to_internal_events(bus: &EventBus) { +//! let mut rx = bus.subscribe(); +//! +//! while let Ok(event) = rx.recv().await { +//! if let Some(payload) = event.downcast_internal::() { +//! match payload { +//! InternalPayload::NodeMeta { node_id, version } => { +//! println!("Node {} running {}", hex::encode(node_id), version); +//! } +//! InternalPayload::Shutdown { reason } => { +//! println!("Shutting down: {}", reason); +//! break; +//! } +//! } +//! } +//! } +//! } +//! ``` +//! +//! ## Publishing a Public Event +//! +//! Public events like `IncomingPayment` are automatically converted to +//! `NodeEvent` protobufs and streamed to clients via `StreamNodeEvents`. +//! Using the type alias, the same code works regardless of whether you +//! have internal events or not: +//! +//! ```ignore +//! use gl_plugin::events::{Event, EventBus}; +//! use gl_plugin::pb; +//! +//! // Use () if you don't need internal events, or your InternalPayload type +//! type PluginEvent = Event<()>; +//! +//! fn on_invoice_payment(bus: &EventBus, payment_hash: Vec, +//! bolt11: String, preimage: Vec, amount_msat: u64) { +//! let payment = pb::IncomingPayment { +//! details: Some(pb::incoming_payment::Details::Offchain(pb::OffChain { +//! payment_hash, +//! bolt11, +//! preimage, +//! label: "my-invoice".to_string(), +//! amount: Some(pb::Amount { +//! unit: Some(pb::amount::Unit::Millisatoshi(amount_msat)), +//! }), +//! extratlvs: vec![], +//! })), +//! }; +//! +//! // This event will be streamed to gl-sdk clients as NodeEvent::InvoicePaid +//! bus.publish(PluginEvent::IncomingPayment(payment)); +//! } +//! ``` +//! +//! ## Subscribing to Public Events (Server-side) +//! +//! When subscribing, you receive `ErasedEvent` which works with any +//! internal type. Pattern match on the public variants directly: +//! +//! ```ignore +//! use gl_plugin::events::{Event, EventBus, ErasedEvent}; +//! +//! async fn monitor_payments(bus: &EventBus) { +//! let mut rx = bus.subscribe(); +//! +//! while let Ok(event) = rx.recv().await { +//! // ErasedEvent can be matched on public variants directly +//! match &event { +//! Event::IncomingPayment(p) => { +//! println!("Payment received!"); +//! } +//! Event::CustomMsg(msg) => { +//! println!("Custom message from peer"); +//! } +//! Event::Stop(_) => { +//! println!("Plugin stopping"); +//! break; +//! } +//! Event::Internal(_) => { +//! // Use downcast_internal::() to access typed payload +//! } +//! _ => {} +//! } +//! } +//! } +//! ``` +//! +//! ## Client-side: Consuming Events via gl-sdk (Python) +//! +//! ```python +//! # Stream events from a Greenlight node +//! for event in node.stream_node_events(): +//! if event.HasField("invoice_paid"): +//! paid = event.invoice_paid +//! print(f"Invoice paid: {paid.amount_msat} msat") +//! print(f" hash: {paid.payment_hash.hex()}") +//! ``` +//! +//! ## Client-side: Consuming Events via gl-sdk (Rust) +//! +//! ```ignore +//! use gl_client::pb::{NodeEventsRequest, node_event::Event}; +//! +//! async fn stream_events(mut client: NodeClient) -> Result<()> { +//! let stream = client +//! .stream_node_events(NodeEventsRequest {}) +//! .await? +//! .into_inner(); +//! +//! while let Some(event) = stream.message().await? { +//! match event.event { +//! Some(Event::InvoicePaid(paid)) => { +//! println!("Invoice paid: {} msat", paid.amount_msat); +//! } +//! _ => {} +//! } +//! } +//! Ok(()) +//! } +//! ``` use crate::pb; use crate::stager; From 5a1d3f6320696c1cf679007af5f2a934ce97a3d7 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Fri, 20 Feb 2026 11:42:58 +0100 Subject: [PATCH 12/16] Remove deprecated StreamIncoming API in favor of StreamNodeEvents StreamIncoming was a specialized streaming RPC that only delivered IncomingPayment events. StreamNodeEvents supersedes it with a unified event streaming API that: - Uses a NodeEvent wrapper with oneof for type discrimination - Supports multiple event types (InvoicePaid, and future events) - Is already exposed via gl-sdk (UniFFI bindings) This removes: - rpc StreamIncoming and StreamIncomingFilter from proto - stream_incoming() from gl-client-py Python and Rust bindings - Server implementation in gl-plugin --- libs/gl-client-py/glclient/__init__.py | 8 -- libs/gl-client-py/glclient/greenlight.proto | 4 - libs/gl-client-py/glclient/greenlight_pb2.py | 92 +++++++++---------- libs/gl-client-py/glclient/greenlight_pb2.pyi | 12 --- .../glclient/greenlight_pb2_grpc.py | 46 +--------- .../glclient/greenlight_pb2_grpc.pyi | 29 ++---- libs/gl-client-py/src/node.rs | 21 ----- .../proto/glclient/greenlight.proto | 4 - .../proto/glclient/greenlight.proto | 10 -- libs/gl-plugin/src/node/mod.rs | 24 ----- libs/gl-plugin/src/node/wrapper.rs | 14 +-- .../proto/glclient/greenlight.proto | 3 - libs/proto/glclient/greenlight.proto | 4 - 13 files changed, 60 insertions(+), 211 deletions(-) diff --git a/libs/gl-client-py/glclient/__init__.py b/libs/gl-client-py/glclient/__init__.py index 5def639c5..247c3a441 100644 --- a/libs/gl-client-py/glclient/__init__.py +++ b/libs/gl-client-py/glclient/__init__.py @@ -448,14 +448,6 @@ def stream_log(self): break yield nodepb.LogEntry.FromString(bytes(n)) - def stream_incoming(self): - stream = self.inner.stream_incoming(b"") - while True: - n = stream.next() - if n is None: - break - yield nodepb.IncomingPayment.FromString(bytes(n)) - def stream_custommsg(self): stream = self.inner.stream_custommsg(b"") while True: diff --git a/libs/gl-client-py/glclient/greenlight.proto b/libs/gl-client-py/glclient/greenlight.proto index 94d2cfacd..ba9528a6d 100644 --- a/libs/gl-client-py/glclient/greenlight.proto +++ b/libs/gl-client-py/glclient/greenlight.proto @@ -25,7 +25,6 @@ service Node { // // Currently includes off-chain payments received matching an // invoice or spontaneus paymens through keysend. - rpc StreamIncoming(StreamIncomingFilter) returns (stream IncomingPayment) {} // Stream the logs as they are produced by the node // @@ -121,9 +120,6 @@ message Amount { } } -// Options to stream_incoming to specify what to stream. -message StreamIncomingFilter { -} message TlvField { uint64 type = 1; diff --git a/libs/gl-client-py/glclient/greenlight_pb2.py b/libs/gl-client-py/glclient/greenlight_pb2.py index 1c0619a63..ebb94eb6c 100644 --- a/libs/gl-client-py/glclient/greenlight_pb2.py +++ b/libs/gl-client-py/glclient/greenlight_pb2.py @@ -24,7 +24,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19glclient/greenlight.proto\x12\ngreenlight\"H\n\x11HsmRequestContext\x12\x0f\n\x07node_id\x18\x01 \x01(\x0c\x12\x0c\n\x04\x64\x62id\x18\x02 \x01(\x04\x12\x14\n\x0c\x63\x61pabilities\x18\x03 \x01(\x04\"q\n\x0bHsmResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\r\x12\x0b\n\x03raw\x18\x02 \x01(\x0c\x12\x32\n\x0csigner_state\x18\x05 \x03(\x0b\x32\x1c.greenlight.SignerStateEntry\x12\r\n\x05\x65rror\x18\x06 \x01(\t\"\xbf\x01\n\nHsmRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\r\x12.\n\x07\x63ontext\x18\x02 \x01(\x0b\x32\x1d.greenlight.HsmRequestContext\x12\x0b\n\x03raw\x18\x03 \x01(\x0c\x12\x32\n\x0csigner_state\x18\x04 \x03(\x0b\x32\x1c.greenlight.SignerStateEntry\x12,\n\x08requests\x18\x05 \x03(\x0b\x32\x1a.greenlight.PendingRequest\"\x07\n\x05\x45mpty\"l\n\x06\x41mount\x12\x16\n\x0cmillisatoshi\x18\x01 \x01(\x04H\x00\x12\x11\n\x07satoshi\x18\x02 \x01(\x04H\x00\x12\x11\n\x07\x62itcoin\x18\x03 \x01(\x04H\x00\x12\r\n\x03\x61ll\x18\x04 \x01(\x08H\x00\x12\r\n\x03\x61ny\x18\x05 \x01(\x08H\x00\x42\x06\n\x04unit\"\x16\n\x14StreamIncomingFilter\"\'\n\x08TlvField\x12\x0c\n\x04type\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x0c\"\xa5\x01\n\x0fOffChainPayment\x12\r\n\x05label\x18\x01 \x01(\t\x12\x10\n\x08preimage\x18\x02 \x01(\x0c\x12\"\n\x06\x61mount\x18\x03 \x01(\x0b\x32\x12.greenlight.Amount\x12\'\n\textratlvs\x18\x04 \x03(\x0b\x32\x14.greenlight.TlvField\x12\x14\n\x0cpayment_hash\x18\x05 \x01(\x0c\x12\x0e\n\x06\x62olt11\x18\x06 \x01(\t\"M\n\x0fIncomingPayment\x12/\n\x08offchain\x18\x01 \x01(\x0b\x32\x1b.greenlight.OffChainPaymentH\x00\x42\t\n\x07\x64\x65tails\"\x12\n\x10StreamLogRequest\"\x18\n\x08LogEntry\x12\x0c\n\x04line\x18\x01 \x01(\t\"?\n\x10SignerStateEntry\x12\x0f\n\x07version\x18\x01 \x01(\x04\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x0c\"r\n\x0ePendingRequest\x12\x0f\n\x07request\x18\x01 \x01(\x0c\x12\x0b\n\x03uri\x18\x02 \x01(\t\x12\x11\n\tsignature\x18\x03 \x01(\x0c\x12\x0e\n\x06pubkey\x18\x04 \x01(\x0c\x12\x11\n\ttimestamp\x18\x05 \x01(\x04\x12\x0c\n\x04rune\x18\x06 \x01(\x0c\"=\n\nNodeConfig\x12/\n\x0bstartupmsgs\x18\x01 \x03(\x0b\x32\x1a.greenlight.StartupMessage\"!\n\x08GlConfig\x12\x15\n\rclose_to_addr\x18\x01 \x01(\t\"3\n\x0eStartupMessage\x12\x0f\n\x07request\x18\x01 \x01(\x0c\x12\x10\n\x08response\x18\x02 \x01(\x0c\"\x18\n\x16StreamCustommsgRequest\"-\n\tCustommsg\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"\xa4\x01\n\x14TrampolinePayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x1a\n\x12trampoline_node_id\x18\x02 \x01(\x0c\x12\x13\n\x0b\x61mount_msat\x18\x03 \x01(\x04\x12\r\n\x05label\x18\x04 \x01(\t\x12\x15\n\rmaxfeepercent\x18\x05 \x01(\x02\x12\x10\n\x08maxdelay\x18\x06 \x01(\r\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\"\xd5\x01\n\x15TrampolinePayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\ncreated_at\x18\x03 \x01(\x01\x12\r\n\x05parts\x18\x04 \x01(\r\x12\x13\n\x0b\x61mount_msat\x18\x05 \x01(\x04\x12\x18\n\x10\x61mount_sent_msat\x18\x06 \x01(\x04\x12\x13\n\x0b\x64\x65stination\x18\x07 \x01(\x0c\"%\n\tPayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x02\"k\n\x11LspInvoiceRequest\x12\x0e\n\x06lsp_id\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x03 \x01(\x04\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\r\n\x05label\x18\x05 \x01(\t\"}\n\x12LspInvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x15\n\rcreated_index\x18\x02 \x01(\r\x12\x12\n\nexpires_at\x18\x03 \x01(\r\x12\x14\n\x0cpayment_hash\x18\x04 \x01(\x0c\x12\x16\n\x0epayment_secret\x18\x05 \x01(\x0c\"\x13\n\x11NodeEventsRequest\"E\n\tNodeEvent\x12/\n\x0cinvoice_paid\x18\x01 \x01(\x0b\x32\x17.greenlight.InvoicePaidH\x00\x42\x07\n\x05\x65vent\"\x92\x01\n\x0bInvoicePaid\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06\x62olt11\x18\x02 \x01(\t\x12\x10\n\x08preimage\x18\x03 \x01(\x0c\x12\r\n\x05label\x18\x04 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x05 \x01(\x04\x12\'\n\textratlvs\x18\x06 \x03(\x0b\x32\x14.greenlight.TlvField2\xa6\x05\n\x04Node\x12M\n\nLspInvoice\x12\x1d.greenlight.LspInvoiceRequest\x1a\x1e.greenlight.LspInvoiceResponse\"\x00\x12S\n\x0eStreamIncoming\x12 .greenlight.StreamIncomingFilter\x1a\x1b.greenlight.IncomingPayment\"\x00\x30\x01\x12\x43\n\tStreamLog\x12\x1c.greenlight.StreamLogRequest\x1a\x14.greenlight.LogEntry\"\x00\x30\x01\x12P\n\x0fStreamCustommsg\x12\".greenlight.StreamCustommsgRequest\x1a\x15.greenlight.Custommsg\"\x00\x30\x01\x12L\n\x10StreamNodeEvents\x12\x1d.greenlight.NodeEventsRequest\x1a\x15.greenlight.NodeEvent\"\x00\x30\x01\x12\x42\n\x11StreamHsmRequests\x12\x11.greenlight.Empty\x1a\x16.greenlight.HsmRequest\"\x00\x30\x01\x12\x41\n\x11RespondHsmRequest\x12\x17.greenlight.HsmResponse\x1a\x11.greenlight.Empty\"\x00\x12\x36\n\tConfigure\x12\x14.greenlight.GlConfig\x1a\x11.greenlight.Empty\"\x00\x12V\n\rTrampolinePay\x12 .greenlight.TrampolinePayRequest\x1a!.greenlight.TrampolinePayResponse\"\x00\x32s\n\x03Hsm\x12<\n\x07Request\x12\x16.greenlight.HsmRequest\x1a\x17.greenlight.HsmResponse\"\x00\x12.\n\x04Ping\x12\x11.greenlight.Empty\x1a\x11.greenlight.Empty\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19glclient/greenlight.proto\x12\ngreenlight\"H\n\x11HsmRequestContext\x12\x0f\n\x07node_id\x18\x01 \x01(\x0c\x12\x0c\n\x04\x64\x62id\x18\x02 \x01(\x04\x12\x14\n\x0c\x63\x61pabilities\x18\x03 \x01(\x04\"q\n\x0bHsmResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\r\x12\x0b\n\x03raw\x18\x02 \x01(\x0c\x12\x32\n\x0csigner_state\x18\x05 \x03(\x0b\x32\x1c.greenlight.SignerStateEntry\x12\r\n\x05\x65rror\x18\x06 \x01(\t\"\xbf\x01\n\nHsmRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\r\x12.\n\x07\x63ontext\x18\x02 \x01(\x0b\x32\x1d.greenlight.HsmRequestContext\x12\x0b\n\x03raw\x18\x03 \x01(\x0c\x12\x32\n\x0csigner_state\x18\x04 \x03(\x0b\x32\x1c.greenlight.SignerStateEntry\x12,\n\x08requests\x18\x05 \x03(\x0b\x32\x1a.greenlight.PendingRequest\"\x07\n\x05\x45mpty\"l\n\x06\x41mount\x12\x16\n\x0cmillisatoshi\x18\x01 \x01(\x04H\x00\x12\x11\n\x07satoshi\x18\x02 \x01(\x04H\x00\x12\x11\n\x07\x62itcoin\x18\x03 \x01(\x04H\x00\x12\r\n\x03\x61ll\x18\x04 \x01(\x08H\x00\x12\r\n\x03\x61ny\x18\x05 \x01(\x08H\x00\x42\x06\n\x04unit\"\'\n\x08TlvField\x12\x0c\n\x04type\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x0c\"\xa5\x01\n\x0fOffChainPayment\x12\r\n\x05label\x18\x01 \x01(\t\x12\x10\n\x08preimage\x18\x02 \x01(\x0c\x12\"\n\x06\x61mount\x18\x03 \x01(\x0b\x32\x12.greenlight.Amount\x12\'\n\textratlvs\x18\x04 \x03(\x0b\x32\x14.greenlight.TlvField\x12\x14\n\x0cpayment_hash\x18\x05 \x01(\x0c\x12\x0e\n\x06\x62olt11\x18\x06 \x01(\t\"M\n\x0fIncomingPayment\x12/\n\x08offchain\x18\x01 \x01(\x0b\x32\x1b.greenlight.OffChainPaymentH\x00\x42\t\n\x07\x64\x65tails\"\x12\n\x10StreamLogRequest\"\x18\n\x08LogEntry\x12\x0c\n\x04line\x18\x01 \x01(\t\"?\n\x10SignerStateEntry\x12\x0f\n\x07version\x18\x01 \x01(\x04\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x0c\"r\n\x0ePendingRequest\x12\x0f\n\x07request\x18\x01 \x01(\x0c\x12\x0b\n\x03uri\x18\x02 \x01(\t\x12\x11\n\tsignature\x18\x03 \x01(\x0c\x12\x0e\n\x06pubkey\x18\x04 \x01(\x0c\x12\x11\n\ttimestamp\x18\x05 \x01(\x04\x12\x0c\n\x04rune\x18\x06 \x01(\x0c\"=\n\nNodeConfig\x12/\n\x0bstartupmsgs\x18\x01 \x03(\x0b\x32\x1a.greenlight.StartupMessage\"!\n\x08GlConfig\x12\x15\n\rclose_to_addr\x18\x01 \x01(\t\"3\n\x0eStartupMessage\x12\x0f\n\x07request\x18\x01 \x01(\x0c\x12\x10\n\x08response\x18\x02 \x01(\x0c\"\x18\n\x16StreamCustommsgRequest\"-\n\tCustommsg\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"\xa4\x01\n\x14TrampolinePayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x1a\n\x12trampoline_node_id\x18\x02 \x01(\x0c\x12\x13\n\x0b\x61mount_msat\x18\x03 \x01(\x04\x12\r\n\x05label\x18\x04 \x01(\t\x12\x15\n\rmaxfeepercent\x18\x05 \x01(\x02\x12\x10\n\x08maxdelay\x18\x06 \x01(\r\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\"\xd5\x01\n\x15TrampolinePayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\ncreated_at\x18\x03 \x01(\x01\x12\r\n\x05parts\x18\x04 \x01(\r\x12\x13\n\x0b\x61mount_msat\x18\x05 \x01(\x04\x12\x18\n\x10\x61mount_sent_msat\x18\x06 \x01(\x04\x12\x13\n\x0b\x64\x65stination\x18\x07 \x01(\x0c\"%\n\tPayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x02\"k\n\x11LspInvoiceRequest\x12\x0e\n\x06lsp_id\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x03 \x01(\x04\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\r\n\x05label\x18\x05 \x01(\t\"}\n\x12LspInvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x15\n\rcreated_index\x18\x02 \x01(\r\x12\x12\n\nexpires_at\x18\x03 \x01(\r\x12\x14\n\x0cpayment_hash\x18\x04 \x01(\x0c\x12\x16\n\x0epayment_secret\x18\x05 \x01(\x0c\"\x13\n\x11NodeEventsRequest\"E\n\tNodeEvent\x12/\n\x0cinvoice_paid\x18\x01 \x01(\x0b\x32\x17.greenlight.InvoicePaidH\x00\x42\x07\n\x05\x65vent\"\x92\x01\n\x0bInvoicePaid\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06\x62olt11\x18\x02 \x01(\t\x12\x10\n\x08preimage\x18\x03 \x01(\x0c\x12\r\n\x05label\x18\x04 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x05 \x01(\x04\x12\'\n\textratlvs\x18\x06 \x03(\x0b\x32\x14.greenlight.TlvField2\xd1\x04\n\x04Node\x12M\n\nLspInvoice\x12\x1d.greenlight.LspInvoiceRequest\x1a\x1e.greenlight.LspInvoiceResponse\"\x00\x12\x43\n\tStreamLog\x12\x1c.greenlight.StreamLogRequest\x1a\x14.greenlight.LogEntry\"\x00\x30\x01\x12P\n\x0fStreamCustommsg\x12\".greenlight.StreamCustommsgRequest\x1a\x15.greenlight.Custommsg\"\x00\x30\x01\x12L\n\x10StreamNodeEvents\x12\x1d.greenlight.NodeEventsRequest\x1a\x15.greenlight.NodeEvent\"\x00\x30\x01\x12\x42\n\x11StreamHsmRequests\x12\x11.greenlight.Empty\x1a\x16.greenlight.HsmRequest\"\x00\x30\x01\x12\x41\n\x11RespondHsmRequest\x12\x17.greenlight.HsmResponse\x1a\x11.greenlight.Empty\"\x00\x12\x36\n\tConfigure\x12\x14.greenlight.GlConfig\x1a\x11.greenlight.Empty\"\x00\x12V\n\rTrampolinePay\x12 .greenlight.TrampolinePayRequest\x1a!.greenlight.TrampolinePayResponse\"\x00\x32s\n\x03Hsm\x12<\n\x07Request\x12\x16.greenlight.HsmRequest\x1a\x17.greenlight.HsmResponse\"\x00\x12.\n\x04Ping\x12\x11.greenlight.Empty\x1a\x11.greenlight.Empty\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -41,50 +41,48 @@ _globals['_EMPTY']._serialized_end=431 _globals['_AMOUNT']._serialized_start=433 _globals['_AMOUNT']._serialized_end=541 - _globals['_STREAMINCOMINGFILTER']._serialized_start=543 - _globals['_STREAMINCOMINGFILTER']._serialized_end=565 - _globals['_TLVFIELD']._serialized_start=567 - _globals['_TLVFIELD']._serialized_end=606 - _globals['_OFFCHAINPAYMENT']._serialized_start=609 - _globals['_OFFCHAINPAYMENT']._serialized_end=774 - _globals['_INCOMINGPAYMENT']._serialized_start=776 - _globals['_INCOMINGPAYMENT']._serialized_end=853 - _globals['_STREAMLOGREQUEST']._serialized_start=855 - _globals['_STREAMLOGREQUEST']._serialized_end=873 - _globals['_LOGENTRY']._serialized_start=875 - _globals['_LOGENTRY']._serialized_end=899 - _globals['_SIGNERSTATEENTRY']._serialized_start=901 - _globals['_SIGNERSTATEENTRY']._serialized_end=964 - _globals['_PENDINGREQUEST']._serialized_start=966 - _globals['_PENDINGREQUEST']._serialized_end=1080 - _globals['_NODECONFIG']._serialized_start=1082 - _globals['_NODECONFIG']._serialized_end=1143 - _globals['_GLCONFIG']._serialized_start=1145 - _globals['_GLCONFIG']._serialized_end=1178 - _globals['_STARTUPMESSAGE']._serialized_start=1180 - _globals['_STARTUPMESSAGE']._serialized_end=1231 - _globals['_STREAMCUSTOMMSGREQUEST']._serialized_start=1233 - _globals['_STREAMCUSTOMMSGREQUEST']._serialized_end=1257 - _globals['_CUSTOMMSG']._serialized_start=1259 - _globals['_CUSTOMMSG']._serialized_end=1304 - _globals['_TRAMPOLINEPAYREQUEST']._serialized_start=1307 - _globals['_TRAMPOLINEPAYREQUEST']._serialized_end=1471 - _globals['_TRAMPOLINEPAYRESPONSE']._serialized_start=1474 - _globals['_TRAMPOLINEPAYRESPONSE']._serialized_end=1687 - _globals['_TRAMPOLINEPAYRESPONSE_PAYSTATUS']._serialized_start=1650 - _globals['_TRAMPOLINEPAYRESPONSE_PAYSTATUS']._serialized_end=1687 - _globals['_LSPINVOICEREQUEST']._serialized_start=1689 - _globals['_LSPINVOICEREQUEST']._serialized_end=1796 - _globals['_LSPINVOICERESPONSE']._serialized_start=1798 - _globals['_LSPINVOICERESPONSE']._serialized_end=1923 - _globals['_NODEEVENTSREQUEST']._serialized_start=1925 - _globals['_NODEEVENTSREQUEST']._serialized_end=1944 - _globals['_NODEEVENT']._serialized_start=1946 - _globals['_NODEEVENT']._serialized_end=2015 - _globals['_INVOICEPAID']._serialized_start=2018 - _globals['_INVOICEPAID']._serialized_end=2164 - _globals['_NODE']._serialized_start=2167 - _globals['_NODE']._serialized_end=2845 - _globals['_HSM']._serialized_start=2847 - _globals['_HSM']._serialized_end=2962 + _globals['_TLVFIELD']._serialized_start=543 + _globals['_TLVFIELD']._serialized_end=582 + _globals['_OFFCHAINPAYMENT']._serialized_start=585 + _globals['_OFFCHAINPAYMENT']._serialized_end=750 + _globals['_INCOMINGPAYMENT']._serialized_start=752 + _globals['_INCOMINGPAYMENT']._serialized_end=829 + _globals['_STREAMLOGREQUEST']._serialized_start=831 + _globals['_STREAMLOGREQUEST']._serialized_end=849 + _globals['_LOGENTRY']._serialized_start=851 + _globals['_LOGENTRY']._serialized_end=875 + _globals['_SIGNERSTATEENTRY']._serialized_start=877 + _globals['_SIGNERSTATEENTRY']._serialized_end=940 + _globals['_PENDINGREQUEST']._serialized_start=942 + _globals['_PENDINGREQUEST']._serialized_end=1056 + _globals['_NODECONFIG']._serialized_start=1058 + _globals['_NODECONFIG']._serialized_end=1119 + _globals['_GLCONFIG']._serialized_start=1121 + _globals['_GLCONFIG']._serialized_end=1154 + _globals['_STARTUPMESSAGE']._serialized_start=1156 + _globals['_STARTUPMESSAGE']._serialized_end=1207 + _globals['_STREAMCUSTOMMSGREQUEST']._serialized_start=1209 + _globals['_STREAMCUSTOMMSGREQUEST']._serialized_end=1233 + _globals['_CUSTOMMSG']._serialized_start=1235 + _globals['_CUSTOMMSG']._serialized_end=1280 + _globals['_TRAMPOLINEPAYREQUEST']._serialized_start=1283 + _globals['_TRAMPOLINEPAYREQUEST']._serialized_end=1447 + _globals['_TRAMPOLINEPAYRESPONSE']._serialized_start=1450 + _globals['_TRAMPOLINEPAYRESPONSE']._serialized_end=1663 + _globals['_TRAMPOLINEPAYRESPONSE_PAYSTATUS']._serialized_start=1626 + _globals['_TRAMPOLINEPAYRESPONSE_PAYSTATUS']._serialized_end=1663 + _globals['_LSPINVOICEREQUEST']._serialized_start=1665 + _globals['_LSPINVOICEREQUEST']._serialized_end=1772 + _globals['_LSPINVOICERESPONSE']._serialized_start=1774 + _globals['_LSPINVOICERESPONSE']._serialized_end=1899 + _globals['_NODEEVENTSREQUEST']._serialized_start=1901 + _globals['_NODEEVENTSREQUEST']._serialized_end=1920 + _globals['_NODEEVENT']._serialized_start=1922 + _globals['_NODEEVENT']._serialized_end=1991 + _globals['_INVOICEPAID']._serialized_start=1994 + _globals['_INVOICEPAID']._serialized_end=2140 + _globals['_NODE']._serialized_start=2143 + _globals['_NODE']._serialized_end=2736 + _globals['_HSM']._serialized_start=2738 + _globals['_HSM']._serialized_end=2853 # @@protoc_insertion_point(module_scope) diff --git a/libs/gl-client-py/glclient/greenlight_pb2.pyi b/libs/gl-client-py/glclient/greenlight_pb2.pyi index a09488cbf..0c58312fb 100644 --- a/libs/gl-client-py/glclient/greenlight_pb2.pyi +++ b/libs/gl-client-py/glclient/greenlight_pb2.pyi @@ -160,18 +160,6 @@ class Amount(_message.Message): Global___Amount: _TypeAlias = Amount # noqa: Y015 -@_typing.final -class StreamIncomingFilter(_message.Message): - """Options to stream_incoming to specify what to stream.""" - - DESCRIPTOR: _descriptor.Descriptor - - def __init__( - self, - ) -> None: ... - -Global___StreamIncomingFilter: _TypeAlias = StreamIncomingFilter # noqa: Y015 - @_typing.final class TlvField(_message.Message): DESCRIPTOR: _descriptor.Descriptor diff --git a/libs/gl-client-py/glclient/greenlight_pb2_grpc.py b/libs/gl-client-py/glclient/greenlight_pb2_grpc.py index b95e8c9e0..d53fa077a 100644 --- a/libs/gl-client-py/glclient/greenlight_pb2_grpc.py +++ b/libs/gl-client-py/glclient/greenlight_pb2_grpc.py @@ -54,11 +54,6 @@ def __init__(self, channel): request_serializer=glclient_dot_greenlight__pb2.LspInvoiceRequest.SerializeToString, response_deserializer=glclient_dot_greenlight__pb2.LspInvoiceResponse.FromString, _registered_method=True) - self.StreamIncoming = channel.unary_stream( - '/greenlight.Node/StreamIncoming', - request_serializer=glclient_dot_greenlight__pb2.StreamIncomingFilter.SerializeToString, - response_deserializer=glclient_dot_greenlight__pb2.IncomingPayment.FromString, - _registered_method=True) self.StreamLog = channel.unary_stream( '/greenlight.Node/StreamLog', request_serializer=glclient_dot_greenlight__pb2.StreamLogRequest.SerializeToString, @@ -122,18 +117,13 @@ def LspInvoice(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') - def StreamIncoming(self, request, context): + def StreamLog(self, request, context): """Stream incoming payments Currently includes off-chain payments received matching an invoice or spontaneus paymens through keysend. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - def StreamLog(self, request, context): - """Stream the logs as they are produced by the node + Stream the logs as they are produced by the node Mainly intended for debugging clients by tailing the log as they are written on the node. The logs start streaming from @@ -210,11 +200,6 @@ def add_NodeServicer_to_server(servicer, server): request_deserializer=glclient_dot_greenlight__pb2.LspInvoiceRequest.FromString, response_serializer=glclient_dot_greenlight__pb2.LspInvoiceResponse.SerializeToString, ), - 'StreamIncoming': grpc.unary_stream_rpc_method_handler( - servicer.StreamIncoming, - request_deserializer=glclient_dot_greenlight__pb2.StreamIncomingFilter.FromString, - response_serializer=glclient_dot_greenlight__pb2.IncomingPayment.SerializeToString, - ), 'StreamLog': grpc.unary_stream_rpc_method_handler( servicer.StreamLog, request_deserializer=glclient_dot_greenlight__pb2.StreamLogRequest.FromString, @@ -303,33 +288,6 @@ def LspInvoice(request, metadata, _registered_method=True) - @staticmethod - def StreamIncoming(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_stream( - request, - target, - '/greenlight.Node/StreamIncoming', - glclient_dot_greenlight__pb2.StreamIncomingFilter.SerializeToString, - glclient_dot_greenlight__pb2.IncomingPayment.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) - @staticmethod def StreamLog(request, target, diff --git a/libs/gl-client-py/glclient/greenlight_pb2_grpc.pyi b/libs/gl-client-py/glclient/greenlight_pb2_grpc.pyi index 0ed792eb3..12f961281 100644 --- a/libs/gl-client-py/glclient/greenlight_pb2_grpc.pyi +++ b/libs/gl-client-py/glclient/greenlight_pb2_grpc.pyi @@ -52,14 +52,13 @@ class NodeStub: """Create an invoice to request an incoming payment. Includes LSP negotiation to open a channel on-demand when needed. """ - StreamIncoming: _grpc.UnaryStreamMultiCallable[_greenlight_pb2.StreamIncomingFilter, _greenlight_pb2.IncomingPayment] + StreamLog: _grpc.UnaryStreamMultiCallable[_greenlight_pb2.StreamLogRequest, _greenlight_pb2.LogEntry] """Stream incoming payments Currently includes off-chain payments received matching an invoice or spontaneus paymens through keysend. - """ - StreamLog: _grpc.UnaryStreamMultiCallable[_greenlight_pb2.StreamLogRequest, _greenlight_pb2.LogEntry] - """Stream the logs as they are produced by the node + + Stream the logs as they are produced by the node Mainly intended for debugging clients by tailing the log as they are written on the node. The logs start streaming from @@ -122,14 +121,13 @@ class NodeAsyncStub(NodeStub): """Create an invoice to request an incoming payment. Includes LSP negotiation to open a channel on-demand when needed. """ - StreamIncoming: _aio.UnaryStreamMultiCallable[_greenlight_pb2.StreamIncomingFilter, _greenlight_pb2.IncomingPayment] # type: ignore[assignment] + StreamLog: _aio.UnaryStreamMultiCallable[_greenlight_pb2.StreamLogRequest, _greenlight_pb2.LogEntry] # type: ignore[assignment] """Stream incoming payments Currently includes off-chain payments received matching an invoice or spontaneus paymens through keysend. - """ - StreamLog: _aio.UnaryStreamMultiCallable[_greenlight_pb2.StreamLogRequest, _greenlight_pb2.LogEntry] # type: ignore[assignment] - """Stream the logs as they are produced by the node + + Stream the logs as they are produced by the node Mainly intended for debugging clients by tailing the log as they are written on the node. The logs start streaming from @@ -197,24 +195,17 @@ class NodeServicer(metaclass=_abc_1.ABCMeta): """ @_abc_1.abstractmethod - def StreamIncoming( + def StreamLog( self, - request: _greenlight_pb2.StreamIncomingFilter, + request: _greenlight_pb2.StreamLogRequest, context: _ServicerContext, - ) -> _typing.Union[_abc.Iterator[_greenlight_pb2.IncomingPayment], _abc.AsyncIterator[_greenlight_pb2.IncomingPayment]]: + ) -> _typing.Union[_abc.Iterator[_greenlight_pb2.LogEntry], _abc.AsyncIterator[_greenlight_pb2.LogEntry]]: """Stream incoming payments Currently includes off-chain payments received matching an invoice or spontaneus paymens through keysend. - """ - @_abc_1.abstractmethod - def StreamLog( - self, - request: _greenlight_pb2.StreamLogRequest, - context: _ServicerContext, - ) -> _typing.Union[_abc.Iterator[_greenlight_pb2.LogEntry], _abc.AsyncIterator[_greenlight_pb2.LogEntry]]: - """Stream the logs as they are produced by the node + Stream the logs as they are produced by the node Mainly intended for debugging clients by tailing the log as they are written on the node. The logs start streaming from diff --git a/libs/gl-client-py/src/node.rs b/libs/gl-client-py/src/node.rs index 0fbfc8145..3a94414cd 100644 --- a/libs/gl-client-py/src/node.rs +++ b/libs/gl-client-py/src/node.rs @@ -40,15 +40,6 @@ impl Node { Ok(LogStream { inner: stream }) } - fn stream_incoming(&self, args: &[u8]) -> PyResult { - let req = pb::StreamIncomingFilter::decode(args).map_err(error_decoding_request)?; - - let stream = exec(self.client.clone().stream_incoming(req)) - .map(|x| x.into_inner()) - .map_err(error_starting_stream)?; - Ok(IncomingStream { inner: stream }) - } - fn stream_custommsg(&self, args: &[u8]) -> PyResult { let req = pb::StreamCustommsgRequest::decode(args).map_err(error_decoding_request)?; let stream = exec(self.client.clone().stream_custommsg(req)) @@ -146,18 +137,6 @@ impl LogStream { } } -#[pyclass] -struct IncomingStream { - inner: tonic::codec::Streaming, -} - -#[pymethods] -impl IncomingStream { - fn next(&mut self) -> PyResult>> { - convert_stream_entry(exec(async { self.inner.message().await })) - } -} - #[pyclass] struct CustommsgStream { inner: tonic::codec::Streaming, diff --git a/libs/gl-client/.resources/proto/glclient/greenlight.proto b/libs/gl-client/.resources/proto/glclient/greenlight.proto index 94d2cfacd..ba9528a6d 100644 --- a/libs/gl-client/.resources/proto/glclient/greenlight.proto +++ b/libs/gl-client/.resources/proto/glclient/greenlight.proto @@ -25,7 +25,6 @@ service Node { // // Currently includes off-chain payments received matching an // invoice or spontaneus paymens through keysend. - rpc StreamIncoming(StreamIncomingFilter) returns (stream IncomingPayment) {} // Stream the logs as they are produced by the node // @@ -121,9 +120,6 @@ message Amount { } } -// Options to stream_incoming to specify what to stream. -message StreamIncomingFilter { -} message TlvField { uint64 type = 1; diff --git a/libs/gl-plugin/.resources/proto/glclient/greenlight.proto b/libs/gl-plugin/.resources/proto/glclient/greenlight.proto index 94d2cfacd..7ed7b145c 100644 --- a/libs/gl-plugin/.resources/proto/glclient/greenlight.proto +++ b/libs/gl-plugin/.resources/proto/glclient/greenlight.proto @@ -21,12 +21,6 @@ service Node { // negotiation to open a channel on-demand when needed. rpc LspInvoice(LspInvoiceRequest) returns (LspInvoiceResponse) {} - // Stream incoming payments - // - // Currently includes off-chain payments received matching an - // invoice or spontaneus paymens through keysend. - rpc StreamIncoming(StreamIncomingFilter) returns (stream IncomingPayment) {} - // Stream the logs as they are produced by the node // // Mainly intended for debugging clients by tailing the log as @@ -121,10 +115,6 @@ message Amount { } } -// Options to stream_incoming to specify what to stream. -message StreamIncomingFilter { -} - message TlvField { uint64 type = 1; // length is implied since the value field carries its own diff --git a/libs/gl-plugin/src/node/mod.rs b/libs/gl-plugin/src/node/mod.rs index 4c50d76ee..70eab90f1 100644 --- a/libs/gl-plugin/src/node/mod.rs +++ b/libs/gl-plugin/src/node/mod.rs @@ -550,30 +550,6 @@ impl Node for PluginNodeServer { Ok(Response::new(pb::Empty::default())) } - type StreamIncomingStream = ReceiverStream>; - - async fn stream_incoming( - &self, - _req: tonic::Request, - ) -> Result, Status> { - // TODO See if we can just return the broadcast::Receiver - // instead of pulling off broadcast and into an mpsc. - let (tx, rx) = mpsc::channel(1); - let mut bcast = self.events.subscribe(); - tokio::spawn(async move { - while let Ok(p) = bcast.recv().await { - match p { - super::Event::IncomingPayment(p) => { - let _ = tx.send(Ok(p)).await; - } - _ => {} - } - } - }); - - return Ok(Response::new(ReceiverStream::new(rx))); - } - type StreamNodeEventsStream = ReceiverStream>; async fn stream_node_events( diff --git a/libs/gl-plugin/src/node/wrapper.rs b/libs/gl-plugin/src/node/wrapper.rs index 6c573daea..a4e125f74 100644 --- a/libs/gl-plugin/src/node/wrapper.rs +++ b/libs/gl-plugin/src/node/wrapper.rs @@ -1191,9 +1191,9 @@ impl WrappedNodeServer { } use crate::pb::{ - node_server::Node as GlNode, Custommsg, Empty, HsmRequest, HsmResponse, IncomingPayment, - LogEntry, LspInvoiceRequest, LspInvoiceResponse, NodeEvent, NodeEventsRequest, - StreamCustommsgRequest, StreamIncomingFilter, StreamLogRequest, + node_server::Node as GlNode, Custommsg, Empty, HsmRequest, HsmResponse, LogEntry, + LspInvoiceRequest, LspInvoiceResponse, NodeEvent, NodeEventsRequest, StreamCustommsgRequest, + StreamLogRequest, }; #[tonic::async_trait] @@ -1201,7 +1201,6 @@ impl GlNode for WrappedNodeServer { type StreamCustommsgStream = ReceiverStream>; type StreamHsmRequestsStream = ReceiverStream>; type StreamLogStream = ReceiverStream>; - type StreamIncomingStream = ReceiverStream>; type StreamNodeEventsStream = ReceiverStream>; async fn lsp_invoice( @@ -1211,13 +1210,6 @@ impl GlNode for WrappedNodeServer { self.node_server.lsp_invoice(req).await } - async fn stream_incoming( - &self, - req: tonic::Request, - ) -> Result, Status> { - self.node_server.stream_incoming(req).await - } - async fn respond_hsm_request( &self, req: Request, diff --git a/libs/gl-signerproxy/.resources/proto/glclient/greenlight.proto b/libs/gl-signerproxy/.resources/proto/glclient/greenlight.proto index a75224793..bc0651ca3 100644 --- a/libs/gl-signerproxy/.resources/proto/glclient/greenlight.proto +++ b/libs/gl-signerproxy/.resources/proto/glclient/greenlight.proto @@ -20,7 +20,6 @@ service Node { // // Currently includes off-chain payments received matching an // invoice or spontaneus paymens through keysend. - rpc StreamIncoming(StreamIncomingFilter) returns (stream IncomingPayment) {} // Stream the logs as they are produced by the node // @@ -109,8 +108,6 @@ message Amount { } // Options to stream_incoming to specify what to stream. -message StreamIncomingFilter { -} message TlvField { uint64 type = 1; diff --git a/libs/proto/glclient/greenlight.proto b/libs/proto/glclient/greenlight.proto index 94d2cfacd..ba9528a6d 100644 --- a/libs/proto/glclient/greenlight.proto +++ b/libs/proto/glclient/greenlight.proto @@ -25,7 +25,6 @@ service Node { // // Currently includes off-chain payments received matching an // invoice or spontaneus paymens through keysend. - rpc StreamIncoming(StreamIncomingFilter) returns (stream IncomingPayment) {} // Stream the logs as they are produced by the node // @@ -121,9 +120,6 @@ message Amount { } } -// Options to stream_incoming to specify what to stream. -message StreamIncomingFilter { -} message TlvField { uint64 type = 1; From b923dac78bdbe4e7bb589f36ca944b8a9e211c14 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 23 Feb 2026 15:29:41 +0100 Subject: [PATCH 13/16] workspace: Add tonic as workspace dependency Move tonic to workspace dependencies for version consistency across crates. Update gl-client to use workspace = true. --- Cargo.lock | 3 +++ Cargo.toml | 1 + libs/gl-client/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index ffe39de1f..39d8c4bd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -429,6 +429,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d193de1f7487df1914d3a568b772458861d33f9c54249612cc2893d6915054" dependencies = [ "bitcoin_hashes 0.13.0", + "rand", "rand_core", "serde", "unicode-normalization", @@ -1434,6 +1435,7 @@ checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" name = "gl-cli" version = "0.1.3" dependencies = [ + "bip39", "clap", "dirs", "env_logger 0.11.8", @@ -1576,6 +1578,7 @@ dependencies = [ "once_cell", "thiserror 2.0.17", "tokio", + "tonic 0.11.0", "tracing", "uniffi", ] diff --git a/Cargo.toml b/Cargo.toml index 2d34add74..52e29dba9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ env_logger = "0.10" cln-grpc = "0.4" cln-rpc = "0.4" cln-plugin = "0.4" +tonic = "0.11" vls-core = "^0.14" vls-persist = "^0.14" diff --git a/libs/gl-client/Cargo.toml b/libs/gl-client/Cargo.toml index 200a8d709..9ac1254fb 100644 --- a/libs/gl-client/Cargo.toml +++ b/libs/gl-client/Cargo.toml @@ -42,7 +42,7 @@ rustls-pemfile = "1.0.4" sha256 = "1.5.0" tokio = { version = "1", features = ["full"] } tokio-stream = "0.1" -tonic = { version = "0.11", features = ["tls", "transport"] } +tonic = { workspace = true, features = ["tls", "transport"] } tower = { version = "0.4" } tempfile = "3.10.1" url = "2.5.0" From e899f1fdb99f0058f20d90d9f60a818f3f05f63b Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 23 Feb 2026 15:29:49 +0100 Subject: [PATCH 14/16] gl-sdk: Add stream_node_events for real-time event streaming Add NodeEventStream iterator interface for streaming node events via UniFFI bindings: - NodeEventStream: Object wrapping gRPC streaming with blocking next() - NodeEvent: Enum with InvoicePaid and Unknown variants - InvoicePaidEvent: Record with payment details The next() method blocks the calling thread but not the tokio runtime, allowing concurrent node operations from other threads. Includes Python binding regeneration and type tests. --- libs/gl-sdk/Cargo.toml | 1 + libs/gl-sdk/bindings/glsdk.py | 384 ++++++++++++++++++++++++++ libs/gl-sdk/glsdk/glsdk.py | 384 ++++++++++++++++++++++++++ libs/gl-sdk/src/lib.rs | 8 +- libs/gl-sdk/src/node.rs | 101 ++++++- libs/gl-sdk/tests/test_node_events.py | 115 ++++++++ 6 files changed, 987 insertions(+), 6 deletions(-) create mode 100644 libs/gl-sdk/tests/test_node_events.py diff --git a/libs/gl-sdk/Cargo.toml b/libs/gl-sdk/Cargo.toml index c64a5a37e..7b02e394d 100644 --- a/libs/gl-sdk/Cargo.toml +++ b/libs/gl-sdk/Cargo.toml @@ -13,6 +13,7 @@ gl-client = { version = "0.3.3", path = "../gl-client" } once_cell = "1.21.3" thiserror = "2.0.17" tokio = { version = "1", features = ["sync"] } +tonic.workspace = true tracing = { version = "0.1.43", features = ["async-await", "log"] } uniffi = { version = "0.29.4" } diff --git a/libs/gl-sdk/bindings/glsdk.py b/libs/gl-sdk/bindings/glsdk.py index 8a564a63c..340fbee8b 100644 --- a/libs/gl-sdk/bindings/glsdk.py +++ b/libs/gl-sdk/bindings/glsdk.py @@ -482,6 +482,10 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_node_stop() != 20186: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_stream_node_events() != 5933: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_nodeeventstream_next() != 12635: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_scheduler_recover() != 55514: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_scheduler_register() != 20821: @@ -708,6 +712,26 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_method_node_stop.restype = None +_UniffiLib.uniffi_glsdk_fn_method_node_stream_node_events.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_stream_node_events.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_clone_nodeeventstream.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_clone_nodeeventstream.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_free_nodeeventstream.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_free_nodeeventstream.restype = None +_UniffiLib.uniffi_glsdk_fn_method_nodeeventstream_next.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_nodeeventstream_next.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_clone_scheduler.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -1068,6 +1092,12 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_glsdk_checksum_method_node_stop.argtypes = ( ) _UniffiLib.uniffi_glsdk_checksum_method_node_stop.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_stream_node_events.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_stream_node_events.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_nodeeventstream_next.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_nodeeventstream_next.restype = ctypes.c_uint16 _UniffiLib.uniffi_glsdk_checksum_method_scheduler_recover.argtypes = ( ) _UniffiLib.uniffi_glsdk_checksum_method_scheduler_recover.restype = ctypes.c_uint16 @@ -1215,6 +1245,8 @@ def write(value, buf): + + class FundChannel: peer_id: "bytes" our_amount_msat: "int" @@ -1470,6 +1502,87 @@ def write(value, buf): _UniffiConverterUInt64.write(value.fees_collected_msat, buf) +class InvoicePaidEvent: + """ + Details of a paid invoice. + """ + + payment_hash: "bytes" + """ + The payment hash of the paid invoice. + """ + + bolt11: "str" + """ + The bolt11 invoice string. + """ + + preimage: "bytes" + """ + The preimage that proves payment. + """ + + label: "str" + """ + The label assigned to the invoice. + """ + + amount_msat: "int" + """ + Amount received in millisatoshis. + """ + + def __init__(self, *, payment_hash: "bytes", bolt11: "str", preimage: "bytes", label: "str", amount_msat: "int"): + self.payment_hash = payment_hash + self.bolt11 = bolt11 + self.preimage = preimage + self.label = label + self.amount_msat = amount_msat + + def __str__(self): + return "InvoicePaidEvent(payment_hash={}, bolt11={}, preimage={}, label={}, amount_msat={})".format(self.payment_hash, self.bolt11, self.preimage, self.label, self.amount_msat) + + def __eq__(self, other): + if self.payment_hash != other.payment_hash: + return False + if self.bolt11 != other.bolt11: + return False + if self.preimage != other.preimage: + return False + if self.label != other.label: + return False + if self.amount_msat != other.amount_msat: + return False + return True + +class _UniffiConverterTypeInvoicePaidEvent(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return InvoicePaidEvent( + payment_hash=_UniffiConverterBytes.read(buf), + bolt11=_UniffiConverterString.read(buf), + preimage=_UniffiConverterBytes.read(buf), + label=_UniffiConverterString.read(buf), + amount_msat=_UniffiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.payment_hash) + _UniffiConverterString.check_lower(value.bolt11) + _UniffiConverterBytes.check_lower(value.preimage) + _UniffiConverterString.check_lower(value.label) + _UniffiConverterUInt64.check_lower(value.amount_msat) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.payment_hash, buf) + _UniffiConverterString.write(value.bolt11, buf) + _UniffiConverterBytes.write(value.preimage, buf) + _UniffiConverterString.write(value.label, buf) + _UniffiConverterUInt64.write(value.amount_msat, buf) + + class ListFundsResponse: outputs: "typing.List[FundOutput]" channels: "typing.List[FundChannel]" @@ -2247,6 +2360,112 @@ def write(value, buf): +class NodeEvent: + """ + A real-time event from the node. + """ + + def __init__(self): + raise RuntimeError("NodeEvent cannot be instantiated directly") + + # Each enum variant is a nested class of the enum itself. + class INVOICE_PAID: + """ + An invoice was paid. + """ + + details: "InvoicePaidEvent" + + def __init__(self,details: "InvoicePaidEvent"): + self.details = details + + def __str__(self): + return "NodeEvent.INVOICE_PAID(details={})".format(self.details) + + def __eq__(self, other): + if not other.is_INVOICE_PAID(): + return False + if self.details != other.details: + return False + return True + + class UNKNOWN: + """ + An unknown event type was received. This can happen if the + server sends a new event type that this client doesn't know about. + """ + + + def __init__(self,): + pass + + def __str__(self): + return "NodeEvent.UNKNOWN()".format() + + def __eq__(self, other): + if not other.is_UNKNOWN(): + return False + return True + + + + # For each variant, we have `is_NAME` and `is_name` methods for easily checking + # whether an instance is that variant. + def is_INVOICE_PAID(self) -> bool: + return isinstance(self, NodeEvent.INVOICE_PAID) + def is_invoice_paid(self) -> bool: + return isinstance(self, NodeEvent.INVOICE_PAID) + def is_UNKNOWN(self) -> bool: + return isinstance(self, NodeEvent.UNKNOWN) + def is_unknown(self) -> bool: + return isinstance(self, NodeEvent.UNKNOWN) + + +# Now, a little trick - we make each nested variant class be a subclass of the main +# enum class, so that method calls and instance checks etc will work intuitively. +# We might be able to do this a little more neatly with a metaclass, but this'll do. +NodeEvent.INVOICE_PAID = type("NodeEvent.INVOICE_PAID", (NodeEvent.INVOICE_PAID, NodeEvent,), {}) # type: ignore +NodeEvent.UNKNOWN = type("NodeEvent.UNKNOWN", (NodeEvent.UNKNOWN, NodeEvent,), {}) # type: ignore + + + + +class _UniffiConverterTypeNodeEvent(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return NodeEvent.INVOICE_PAID( + _UniffiConverterTypeInvoicePaidEvent.read(buf), + ) + if variant == 2: + return NodeEvent.UNKNOWN( + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value.is_INVOICE_PAID(): + _UniffiConverterTypeInvoicePaidEvent.check_lower(value.details) + return + if value.is_UNKNOWN(): + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value.is_INVOICE_PAID(): + buf.write_i32(1) + _UniffiConverterTypeInvoicePaidEvent.write(value.details, buf) + if value.is_UNKNOWN(): + buf.write_i32(2) + + + + + + + class OutputStatus(enum.Enum): UNCONFIRMED = 0 @@ -2453,6 +2672,33 @@ def read(cls, buf): +class _UniffiConverterOptionalTypeNodeEvent(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterTypeNodeEvent.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterTypeNodeEvent.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterTypeNodeEvent.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + class _UniffiConverterSequenceString(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): @@ -2813,6 +3059,20 @@ def stop(self, ): Stop the node if it is currently running. """ + raise NotImplementedError + def stream_node_events(self, ): + """ + Stream real-time events from the node. + + Returns a `NodeEventStream` iterator. Call `next()` repeatedly + to receive events as they occur (e.g., invoice payments). + + The `next()` method blocks the calling thread until an event + is available, but does not block the underlying async runtime, + so other node methods can be called concurrently from other + threads. + """ + raise NotImplementedError # Node is a Rust-only trait - it's a wrapper around a Rust implementation. class Node(): @@ -2993,6 +3253,27 @@ def stop(self, ) -> None: + def stream_node_events(self, ) -> "NodeEventStream": + """ + Stream real-time events from the node. + + Returns a `NodeEventStream` iterator. Call `next()` repeatedly + to receive events as they occur (e.g., invoice payments). + + The `next()` method blocks the calling thread until an event + is available, but does not block the underlying async runtime, + so other node methods can be called concurrently from other + threads. + """ + + return _UniffiConverterTypeNodeEventStream.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_stream_node_events,self._uniffi_clone_pointer(),) + ) + + + + + class _UniffiConverterTypeNode: @@ -3021,6 +3302,106 @@ def read(cls, buf: _UniffiRustBuffer): @classmethod def write(cls, value: NodeProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) +class NodeEventStreamProtocol(typing.Protocol): + """ + A stream of node events. Call `next()` to receive the next event. + + The stream is backed by a gRPC streaming connection to the node. + Each call to `next()` blocks the calling thread until an event is + available, but does not block the tokio runtime - other node + operations can proceed concurrently from other threads. + """ + + def next(self, ): + """ + Get the next event from the stream. + + Blocks the calling thread until an event is available or the + stream ends. Returns `None` when the stream is exhausted or + the connection is lost. + """ + + raise NotImplementedError +# NodeEventStream is a Rust-only trait - it's a wrapper around a Rust implementation. +class NodeEventStream(): + """ + A stream of node events. Call `next()` to receive the next event. + + The stream is backed by a gRPC streaming connection to the node. + Each call to `next()` blocks the calling thread until an event is + available, but does not block the tokio runtime - other node + operations can proceed concurrently from other threads. + """ + + _pointer: ctypes.c_void_p + + def __init__(self, *args, **kwargs): + raise ValueError("This class has no default constructor") + + def __del__(self): + # In case of partial initialization of instances. + pointer = getattr(self, "_pointer", None) + if pointer is not None: + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_nodeeventstream, pointer) + + def _uniffi_clone_pointer(self): + return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_nodeeventstream, self._pointer) + + # Used by alternative constructors or any methods which return this type. + @classmethod + def _make_instance_(cls, pointer): + # Lightly yucky way to bypass the usual __init__ logic + # and just create a new instance with the required pointer. + inst = cls.__new__(cls) + inst._pointer = pointer + return inst + + + def next(self, ) -> "typing.Optional[NodeEvent]": + """ + Get the next event from the stream. + + Blocks the calling thread until an event is available or the + stream ends. Returns `None` when the stream is exhausted or + the connection is lost. + """ + + return _UniffiConverterOptionalTypeNodeEvent.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_nodeeventstream_next,self._uniffi_clone_pointer(),) + ) + + + + + + +class _UniffiConverterTypeNodeEventStream: + + @staticmethod + def lift(value: int): + return NodeEventStream._make_instance_(value) + + @staticmethod + def check_lower(value: NodeEventStream): + if not isinstance(value, NodeEventStream): + raise TypeError("Expected NodeEventStream instance, {} found".format(type(value).__name__)) + + @staticmethod + def lower(value: NodeEventStreamProtocol): + if not isinstance(value, NodeEventStream): + raise TypeError("Expected NodeEventStream instance, {} found".format(type(value).__name__)) + return value._uniffi_clone_pointer() + + @classmethod + def read(cls, buf: _UniffiRustBuffer): + ptr = buf.read_u64() + if ptr == 0: + raise InternalError("Raw pointer value was null") + return cls.lift(ptr) + + @classmethod + def write(cls, value: NodeEventStreamProtocol, buf: _UniffiRustBuffer): + buf.write_u64(cls.lower(value)) class SchedulerProtocol(typing.Protocol): def recover(self, signer: "Signer"): raise NotImplementedError @@ -3215,11 +3596,13 @@ def write(cls, value: SignerProtocol, buf: _UniffiRustBuffer): "ChannelState", "Error", "Network", + "NodeEvent", "OutputStatus", "PayStatus", "FundChannel", "FundOutput", "GetInfoResponse", + "InvoicePaidEvent", "ListFundsResponse", "ListPeerChannelsResponse", "ListPeersResponse", @@ -3232,6 +3615,7 @@ def write(cls, value: SignerProtocol, buf: _UniffiRustBuffer): "Credentials", "Handle", "Node", + "NodeEventStream", "Scheduler", "Signer", ] diff --git a/libs/gl-sdk/glsdk/glsdk.py b/libs/gl-sdk/glsdk/glsdk.py index 8a564a63c..340fbee8b 100644 --- a/libs/gl-sdk/glsdk/glsdk.py +++ b/libs/gl-sdk/glsdk/glsdk.py @@ -482,6 +482,10 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_node_stop() != 20186: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_node_stream_node_events() != 5933: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_glsdk_checksum_method_nodeeventstream_next() != 12635: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_scheduler_recover() != 55514: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_glsdk_checksum_method_scheduler_register() != 20821: @@ -708,6 +712,26 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_glsdk_fn_method_node_stop.restype = None +_UniffiLib.uniffi_glsdk_fn_method_node_stream_node_events.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_node_stream_node_events.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_clone_nodeeventstream.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_clone_nodeeventstream.restype = ctypes.c_void_p +_UniffiLib.uniffi_glsdk_fn_free_nodeeventstream.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_free_nodeeventstream.restype = None +_UniffiLib.uniffi_glsdk_fn_method_nodeeventstream_next.argtypes = ( + ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_glsdk_fn_method_nodeeventstream_next.restype = _UniffiRustBuffer _UniffiLib.uniffi_glsdk_fn_clone_scheduler.argtypes = ( ctypes.c_void_p, ctypes.POINTER(_UniffiRustCallStatus), @@ -1068,6 +1092,12 @@ class _UniffiForeignFutureStructVoid(ctypes.Structure): _UniffiLib.uniffi_glsdk_checksum_method_node_stop.argtypes = ( ) _UniffiLib.uniffi_glsdk_checksum_method_node_stop.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_node_stream_node_events.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_node_stream_node_events.restype = ctypes.c_uint16 +_UniffiLib.uniffi_glsdk_checksum_method_nodeeventstream_next.argtypes = ( +) +_UniffiLib.uniffi_glsdk_checksum_method_nodeeventstream_next.restype = ctypes.c_uint16 _UniffiLib.uniffi_glsdk_checksum_method_scheduler_recover.argtypes = ( ) _UniffiLib.uniffi_glsdk_checksum_method_scheduler_recover.restype = ctypes.c_uint16 @@ -1215,6 +1245,8 @@ def write(value, buf): + + class FundChannel: peer_id: "bytes" our_amount_msat: "int" @@ -1470,6 +1502,87 @@ def write(value, buf): _UniffiConverterUInt64.write(value.fees_collected_msat, buf) +class InvoicePaidEvent: + """ + Details of a paid invoice. + """ + + payment_hash: "bytes" + """ + The payment hash of the paid invoice. + """ + + bolt11: "str" + """ + The bolt11 invoice string. + """ + + preimage: "bytes" + """ + The preimage that proves payment. + """ + + label: "str" + """ + The label assigned to the invoice. + """ + + amount_msat: "int" + """ + Amount received in millisatoshis. + """ + + def __init__(self, *, payment_hash: "bytes", bolt11: "str", preimage: "bytes", label: "str", amount_msat: "int"): + self.payment_hash = payment_hash + self.bolt11 = bolt11 + self.preimage = preimage + self.label = label + self.amount_msat = amount_msat + + def __str__(self): + return "InvoicePaidEvent(payment_hash={}, bolt11={}, preimage={}, label={}, amount_msat={})".format(self.payment_hash, self.bolt11, self.preimage, self.label, self.amount_msat) + + def __eq__(self, other): + if self.payment_hash != other.payment_hash: + return False + if self.bolt11 != other.bolt11: + return False + if self.preimage != other.preimage: + return False + if self.label != other.label: + return False + if self.amount_msat != other.amount_msat: + return False + return True + +class _UniffiConverterTypeInvoicePaidEvent(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return InvoicePaidEvent( + payment_hash=_UniffiConverterBytes.read(buf), + bolt11=_UniffiConverterString.read(buf), + preimage=_UniffiConverterBytes.read(buf), + label=_UniffiConverterString.read(buf), + amount_msat=_UniffiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterBytes.check_lower(value.payment_hash) + _UniffiConverterString.check_lower(value.bolt11) + _UniffiConverterBytes.check_lower(value.preimage) + _UniffiConverterString.check_lower(value.label) + _UniffiConverterUInt64.check_lower(value.amount_msat) + + @staticmethod + def write(value, buf): + _UniffiConverterBytes.write(value.payment_hash, buf) + _UniffiConverterString.write(value.bolt11, buf) + _UniffiConverterBytes.write(value.preimage, buf) + _UniffiConverterString.write(value.label, buf) + _UniffiConverterUInt64.write(value.amount_msat, buf) + + class ListFundsResponse: outputs: "typing.List[FundOutput]" channels: "typing.List[FundChannel]" @@ -2247,6 +2360,112 @@ def write(value, buf): +class NodeEvent: + """ + A real-time event from the node. + """ + + def __init__(self): + raise RuntimeError("NodeEvent cannot be instantiated directly") + + # Each enum variant is a nested class of the enum itself. + class INVOICE_PAID: + """ + An invoice was paid. + """ + + details: "InvoicePaidEvent" + + def __init__(self,details: "InvoicePaidEvent"): + self.details = details + + def __str__(self): + return "NodeEvent.INVOICE_PAID(details={})".format(self.details) + + def __eq__(self, other): + if not other.is_INVOICE_PAID(): + return False + if self.details != other.details: + return False + return True + + class UNKNOWN: + """ + An unknown event type was received. This can happen if the + server sends a new event type that this client doesn't know about. + """ + + + def __init__(self,): + pass + + def __str__(self): + return "NodeEvent.UNKNOWN()".format() + + def __eq__(self, other): + if not other.is_UNKNOWN(): + return False + return True + + + + # For each variant, we have `is_NAME` and `is_name` methods for easily checking + # whether an instance is that variant. + def is_INVOICE_PAID(self) -> bool: + return isinstance(self, NodeEvent.INVOICE_PAID) + def is_invoice_paid(self) -> bool: + return isinstance(self, NodeEvent.INVOICE_PAID) + def is_UNKNOWN(self) -> bool: + return isinstance(self, NodeEvent.UNKNOWN) + def is_unknown(self) -> bool: + return isinstance(self, NodeEvent.UNKNOWN) + + +# Now, a little trick - we make each nested variant class be a subclass of the main +# enum class, so that method calls and instance checks etc will work intuitively. +# We might be able to do this a little more neatly with a metaclass, but this'll do. +NodeEvent.INVOICE_PAID = type("NodeEvent.INVOICE_PAID", (NodeEvent.INVOICE_PAID, NodeEvent,), {}) # type: ignore +NodeEvent.UNKNOWN = type("NodeEvent.UNKNOWN", (NodeEvent.UNKNOWN, NodeEvent,), {}) # type: ignore + + + + +class _UniffiConverterTypeNodeEvent(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return NodeEvent.INVOICE_PAID( + _UniffiConverterTypeInvoicePaidEvent.read(buf), + ) + if variant == 2: + return NodeEvent.UNKNOWN( + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value.is_INVOICE_PAID(): + _UniffiConverterTypeInvoicePaidEvent.check_lower(value.details) + return + if value.is_UNKNOWN(): + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value.is_INVOICE_PAID(): + buf.write_i32(1) + _UniffiConverterTypeInvoicePaidEvent.write(value.details, buf) + if value.is_UNKNOWN(): + buf.write_i32(2) + + + + + + + class OutputStatus(enum.Enum): UNCONFIRMED = 0 @@ -2453,6 +2672,33 @@ def read(cls, buf): +class _UniffiConverterOptionalTypeNodeEvent(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterTypeNodeEvent.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterTypeNodeEvent.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterTypeNodeEvent.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + class _UniffiConverterSequenceString(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): @@ -2813,6 +3059,20 @@ def stop(self, ): Stop the node if it is currently running. """ + raise NotImplementedError + def stream_node_events(self, ): + """ + Stream real-time events from the node. + + Returns a `NodeEventStream` iterator. Call `next()` repeatedly + to receive events as they occur (e.g., invoice payments). + + The `next()` method blocks the calling thread until an event + is available, but does not block the underlying async runtime, + so other node methods can be called concurrently from other + threads. + """ + raise NotImplementedError # Node is a Rust-only trait - it's a wrapper around a Rust implementation. class Node(): @@ -2993,6 +3253,27 @@ def stop(self, ) -> None: + def stream_node_events(self, ) -> "NodeEventStream": + """ + Stream real-time events from the node. + + Returns a `NodeEventStream` iterator. Call `next()` repeatedly + to receive events as they occur (e.g., invoice payments). + + The `next()` method blocks the calling thread until an event + is available, but does not block the underlying async runtime, + so other node methods can be called concurrently from other + threads. + """ + + return _UniffiConverterTypeNodeEventStream.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_stream_node_events,self._uniffi_clone_pointer(),) + ) + + + + + class _UniffiConverterTypeNode: @@ -3021,6 +3302,106 @@ def read(cls, buf: _UniffiRustBuffer): @classmethod def write(cls, value: NodeProtocol, buf: _UniffiRustBuffer): buf.write_u64(cls.lower(value)) +class NodeEventStreamProtocol(typing.Protocol): + """ + A stream of node events. Call `next()` to receive the next event. + + The stream is backed by a gRPC streaming connection to the node. + Each call to `next()` blocks the calling thread until an event is + available, but does not block the tokio runtime - other node + operations can proceed concurrently from other threads. + """ + + def next(self, ): + """ + Get the next event from the stream. + + Blocks the calling thread until an event is available or the + stream ends. Returns `None` when the stream is exhausted or + the connection is lost. + """ + + raise NotImplementedError +# NodeEventStream is a Rust-only trait - it's a wrapper around a Rust implementation. +class NodeEventStream(): + """ + A stream of node events. Call `next()` to receive the next event. + + The stream is backed by a gRPC streaming connection to the node. + Each call to `next()` blocks the calling thread until an event is + available, but does not block the tokio runtime - other node + operations can proceed concurrently from other threads. + """ + + _pointer: ctypes.c_void_p + + def __init__(self, *args, **kwargs): + raise ValueError("This class has no default constructor") + + def __del__(self): + # In case of partial initialization of instances. + pointer = getattr(self, "_pointer", None) + if pointer is not None: + _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_nodeeventstream, pointer) + + def _uniffi_clone_pointer(self): + return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_nodeeventstream, self._pointer) + + # Used by alternative constructors or any methods which return this type. + @classmethod + def _make_instance_(cls, pointer): + # Lightly yucky way to bypass the usual __init__ logic + # and just create a new instance with the required pointer. + inst = cls.__new__(cls) + inst._pointer = pointer + return inst + + + def next(self, ) -> "typing.Optional[NodeEvent]": + """ + Get the next event from the stream. + + Blocks the calling thread until an event is available or the + stream ends. Returns `None` when the stream is exhausted or + the connection is lost. + """ + + return _UniffiConverterOptionalTypeNodeEvent.lift( + _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_nodeeventstream_next,self._uniffi_clone_pointer(),) + ) + + + + + + +class _UniffiConverterTypeNodeEventStream: + + @staticmethod + def lift(value: int): + return NodeEventStream._make_instance_(value) + + @staticmethod + def check_lower(value: NodeEventStream): + if not isinstance(value, NodeEventStream): + raise TypeError("Expected NodeEventStream instance, {} found".format(type(value).__name__)) + + @staticmethod + def lower(value: NodeEventStreamProtocol): + if not isinstance(value, NodeEventStream): + raise TypeError("Expected NodeEventStream instance, {} found".format(type(value).__name__)) + return value._uniffi_clone_pointer() + + @classmethod + def read(cls, buf: _UniffiRustBuffer): + ptr = buf.read_u64() + if ptr == 0: + raise InternalError("Raw pointer value was null") + return cls.lift(ptr) + + @classmethod + def write(cls, value: NodeEventStreamProtocol, buf: _UniffiRustBuffer): + buf.write_u64(cls.lower(value)) class SchedulerProtocol(typing.Protocol): def recover(self, signer: "Signer"): raise NotImplementedError @@ -3215,11 +3596,13 @@ def write(cls, value: SignerProtocol, buf: _UniffiRustBuffer): "ChannelState", "Error", "Network", + "NodeEvent", "OutputStatus", "PayStatus", "FundChannel", "FundOutput", "GetInfoResponse", + "InvoicePaidEvent", "ListFundsResponse", "ListPeerChannelsResponse", "ListPeersResponse", @@ -3232,6 +3615,7 @@ def write(cls, value: SignerProtocol, buf: _UniffiRustBuffer): "Credentials", "Handle", "Node", + "NodeEventStream", "Scheduler", "Signer", ] diff --git a/libs/gl-sdk/src/lib.rs b/libs/gl-sdk/src/lib.rs index 8227ea4d5..8913103da 100644 --- a/libs/gl-sdk/src/lib.rs +++ b/libs/gl-sdk/src/lib.rs @@ -32,10 +32,10 @@ mod util; pub use crate::{ credentials::Credentials, node::{ - ChannelState, FundChannel, FundOutput, GetInfoResponse, ListFundsResponse, - ListPeerChannelsResponse, ListPeersResponse, Node, OnchainReceiveResponse, - OnchainSendResponse, OutputStatus, PayStatus, Peer, PeerChannel, ReceiveResponse, - SendResponse, + ChannelState, FundChannel, FundOutput, GetInfoResponse, InvoicePaidEvent, + ListFundsResponse, ListPeerChannelsResponse, ListPeersResponse, Node, NodeEvent, + NodeEventStream, OnchainReceiveResponse, OnchainSendResponse, OutputStatus, PayStatus, + Peer, PeerChannel, ReceiveResponse, SendResponse, }, scheduler::Scheduler, signer::{Handle, Signer}, diff --git a/libs/gl-sdk/src/node.rs b/libs/gl-sdk/src/node.rs index 0683e691e..11eb69304 100644 --- a/libs/gl-sdk/src/node.rs +++ b/libs/gl-sdk/src/node.rs @@ -1,8 +1,8 @@ use crate::{credentials::Credentials, util::exec, Error}; use gl_client::credentials::NodeIdProvider; use gl_client::node::{Client as GlClient, ClnClient, Node as ClientNode}; - -use gl_client::pb::cln as clnpb; +use gl_client::pb::{self as glpb, cln as clnpb}; +use std::sync::{Arc, Mutex}; use tokio::sync::OnceCell; /// The `Node` is an RPC stub representing the node running in the @@ -232,6 +232,26 @@ impl Node { .into_inner(); Ok(res.into()) } + + /// Stream real-time events from the node. + /// + /// Returns a `NodeEventStream` iterator. Call `next()` repeatedly + /// to receive events as they occur (e.g., invoice payments). + /// + /// The `next()` method blocks the calling thread until an event + /// is available, but does not block the underlying async runtime, + /// so other node methods can be called concurrently from other + /// threads. + pub fn stream_node_events(&self) -> Result, Error> { + let mut gl_client = exec(self.get_gl_client())?.clone(); + let req = glpb::NodeEventsRequest {}; + let stream = exec(gl_client.stream_node_events(req)) + .map_err(|e| Error::Rpc(e.to_string()))? + .into_inner(); + Ok(Arc::new(NodeEventStream { + inner: Mutex::new(stream), + })) + } } // Not exported through uniffi @@ -616,3 +636,80 @@ impl From for FundChannel { } + +// ============================================================ +// NodeEvent streaming types +// ============================================================ + +/// A stream of node events. Call `next()` to receive the next event. +/// +/// The stream is backed by a gRPC streaming connection to the node. +/// Each call to `next()` blocks the calling thread until an event is +/// available, but does not block the tokio runtime - other node +/// operations can proceed concurrently from other threads. +#[derive(uniffi::Object)] +pub struct NodeEventStream { + inner: Mutex>, +} + +#[uniffi::export] +impl NodeEventStream { + /// Get the next event from the stream. + /// + /// Blocks the calling thread until an event is available or the + /// stream ends. Returns `None` when the stream is exhausted or + /// the connection is lost. + pub fn next(&self) -> Result, Error> { + let mut stream = self.inner.lock().map_err(|e| Error::Other(e.to_string()))?; + match exec(stream.message()) { + Ok(Some(event)) => Ok(Some(event.into())), + Ok(None) => Ok(None), + Err(e) if e.code() == tonic::Code::Unknown => Ok(None), + Err(e) => Err(Error::Rpc(e.to_string())), + } + } +} + +/// A real-time event from the node. +#[derive(Clone, uniffi::Enum)] +pub enum NodeEvent { + /// An invoice was paid. + InvoicePaid { details: InvoicePaidEvent }, + /// An unknown event type was received. This can happen if the + /// server sends a new event type that this client doesn't know about. + Unknown, +} + +/// Details of a paid invoice. +#[derive(Clone, uniffi::Record)] +pub struct InvoicePaidEvent { + /// The payment hash of the paid invoice. + pub payment_hash: Vec, + /// The bolt11 invoice string. + pub bolt11: String, + /// The preimage that proves payment. + pub preimage: Vec, + /// The label assigned to the invoice. + pub label: String, + /// Amount received in millisatoshis. + pub amount_msat: u64, +} + +impl From for NodeEvent { + fn from(other: glpb::NodeEvent) -> Self { + match other.event { + Some(glpb::node_event::Event::InvoicePaid(paid)) => NodeEvent::InvoicePaid { + details: InvoicePaidEvent { + payment_hash: paid.payment_hash, + bolt11: paid.bolt11, + preimage: paid.preimage, + label: paid.label, + amount_msat: paid.amount_msat, + }, + }, + None => NodeEvent::Unknown, + } + } +} + + diff --git a/libs/gl-sdk/tests/test_node_events.py b/libs/gl-sdk/tests/test_node_events.py new file mode 100644 index 000000000..6e9b35533 --- /dev/null +++ b/libs/gl-sdk/tests/test_node_events.py @@ -0,0 +1,115 @@ +"""Tests for Node event streaming functionality. + +These tests verify that the UniFFI bindings correctly expose the NodeEventStream +and related types. +""" + +import pytest +import glsdk + + +class TestEventStreamTypes: + """Test that event streaming types are properly defined in the bindings.""" + + def test_node_event_stream_type_exists(self): + """Test that NodeEventStream type is available.""" + assert hasattr(glsdk, "NodeEventStream") + + def test_node_event_type_exists(self): + """Test that NodeEvent type is available.""" + assert hasattr(glsdk, "NodeEvent") + + def test_invoice_paid_event_type_exists(self): + """Test that InvoicePaidEvent type is available.""" + assert hasattr(glsdk, "InvoicePaidEvent") + + def test_node_event_has_invoice_paid_variant(self): + """Test that NodeEvent has INVOICE_PAID variant.""" + assert hasattr(glsdk.NodeEvent, "INVOICE_PAID") + + def test_node_event_has_unknown_variant(self): + """Test that NodeEvent has UNKNOWN variant.""" + assert hasattr(glsdk.NodeEvent, "UNKNOWN") + + def test_node_has_stream_node_events_method(self): + """Test that Node class has stream_node_events method.""" + assert hasattr(glsdk.Node, "stream_node_events") + + def test_node_event_stream_has_next_method(self): + """Test that NodeEventStream class has next method.""" + assert hasattr(glsdk.NodeEventStream, "next") + + +class TestInvoicePaidEventFields: + """Test that InvoicePaidEvent has expected fields.""" + + def test_invoice_paid_event_can_be_constructed(self): + """Test InvoicePaidEvent can be constructed with all fields.""" + event = glsdk.InvoicePaidEvent( + payment_hash=b"\x00" * 32, + bolt11="lnbcrt1...", + preimage=b"\x01" * 32, + label="test-invoice", + amount_msat=100000, + ) + assert event.payment_hash == b"\x00" * 32 + assert event.bolt11 == "lnbcrt1..." + assert event.preimage == b"\x01" * 32 + assert event.label == "test-invoice" + assert event.amount_msat == 100000 + + def test_invoice_paid_event_str(self): + """Test InvoicePaidEvent has a reasonable string representation.""" + event = glsdk.InvoicePaidEvent( + payment_hash=b"\x00" * 32, + bolt11="lnbcrt1...", + preimage=b"\x01" * 32, + label="test-invoice", + amount_msat=100000, + ) + str_repr = str(event) + assert "InvoicePaidEvent" in str_repr + assert "test-invoice" in str_repr + + +class TestNodeEventVariants: + """Test NodeEvent enum variants and their behavior.""" + + def test_invoice_paid_variant_construction(self): + """Test that INVOICE_PAID variant can be constructed.""" + details = glsdk.InvoicePaidEvent( + payment_hash=b"\x00" * 32, + bolt11="lnbcrt1...", + preimage=b"\x01" * 32, + label="test-invoice", + amount_msat=100000, + ) + event = glsdk.NodeEvent.INVOICE_PAID(details=details) + assert event.details == details + + def test_unknown_variant_construction(self): + """Test that UNKNOWN variant can be constructed.""" + event = glsdk.NodeEvent.UNKNOWN() + assert event is not None + + def test_invoice_paid_is_invoice_paid(self): + """Test is_invoice_paid() method on INVOICE_PAID variant.""" + details = glsdk.InvoicePaidEvent( + payment_hash=b"\x00" * 32, + bolt11="lnbcrt1...", + preimage=b"\x01" * 32, + label="test-invoice", + amount_msat=100000, + ) + event = glsdk.NodeEvent.INVOICE_PAID(details=details) + assert event.is_invoice_paid() + assert not event.is_unknown() + + def test_unknown_is_unknown(self): + """Test is_unknown() method on UNKNOWN variant.""" + event = glsdk.NodeEvent.UNKNOWN() + assert event.is_unknown() + assert not event.is_invoice_paid() + + + From 93a6f6ccb6efcc7002180eda0a0890159c1af921 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 23 Feb 2026 15:34:40 +0100 Subject: [PATCH 15/16] gl-sdk: Generate Python bindings directly to glsdk/ package Output uniffi-bindgen Python bindings directly to glsdk/ instead of bindings/, eliminating the duplicate file and manual copy step. --- libs/gl-sdk/.tasks.yml | 2 +- libs/gl-sdk/bindings/glsdk.py | 3622 --------------------------------- 2 files changed, 1 insertion(+), 3623 deletions(-) delete mode 100644 libs/gl-sdk/bindings/glsdk.py diff --git a/libs/gl-sdk/.tasks.yml b/libs/gl-sdk/.tasks.yml index 84880ffa6..b08d1e196 100644 --- a/libs/gl-sdk/.tasks.yml +++ b/libs/gl-sdk/.tasks.yml @@ -43,7 +43,7 @@ tasks: cargo run --bin uniffi-bindgen -- generate \ --library ${CARGO_TARGET_DIR:-target}/{{.PROFILE_DIR}}/libglsdk.{{.LIB_EXT}} \ --language python \ - --out-dir ./libs/gl-sdk/bindings + --out-dir ./libs/gl-sdk/glsdk bindings-kotlin: desc: "Generate Kotlin bindings" diff --git a/libs/gl-sdk/bindings/glsdk.py b/libs/gl-sdk/bindings/glsdk.py deleted file mode 100644 index 340fbee8b..000000000 --- a/libs/gl-sdk/bindings/glsdk.py +++ /dev/null @@ -1,3622 +0,0 @@ - - -# This file was autogenerated by some hot garbage in the `uniffi` crate. -# Trust me, you don't want to mess with it! - -# Common helper code. -# -# Ideally this would live in a separate .py file where it can be unittested etc -# in isolation, and perhaps even published as a re-useable package. -# -# However, it's important that the details of how this helper code works (e.g. the -# way that different builtin types are passed across the FFI) exactly match what's -# expected by the rust code on the other side of the interface. In practice right -# now that means coming from the exact some version of `uniffi` that was used to -# compile the rust component. The easiest way to ensure this is to bundle the Python -# helpers directly inline like we're doing here. - -from __future__ import annotations -import os -import sys -import ctypes -import enum -import struct -import contextlib -import datetime -import threading -import itertools -import traceback -import typing -import platform - -# Used for default argument values -_DEFAULT = object() # type: typing.Any - - -class _UniffiRustBuffer(ctypes.Structure): - _fields_ = [ - ("capacity", ctypes.c_uint64), - ("len", ctypes.c_uint64), - ("data", ctypes.POINTER(ctypes.c_char)), - ] - - @staticmethod - def default(): - return _UniffiRustBuffer(0, 0, None) - - @staticmethod - def alloc(size): - return _uniffi_rust_call(_UniffiLib.ffi_glsdk_rustbuffer_alloc, size) - - @staticmethod - def reserve(rbuf, additional): - return _uniffi_rust_call(_UniffiLib.ffi_glsdk_rustbuffer_reserve, rbuf, additional) - - def free(self): - return _uniffi_rust_call(_UniffiLib.ffi_glsdk_rustbuffer_free, self) - - def __str__(self): - return "_UniffiRustBuffer(capacity={}, len={}, data={})".format( - self.capacity, - self.len, - self.data[0:self.len] - ) - - @contextlib.contextmanager - def alloc_with_builder(*args): - """Context-manger to allocate a buffer using a _UniffiRustBufferBuilder. - - The allocated buffer will be automatically freed if an error occurs, ensuring that - we don't accidentally leak it. - """ - builder = _UniffiRustBufferBuilder() - try: - yield builder - except: - builder.discard() - raise - - @contextlib.contextmanager - def consume_with_stream(self): - """Context-manager to consume a buffer using a _UniffiRustBufferStream. - - The _UniffiRustBuffer will be freed once the context-manager exits, ensuring that we don't - leak it even if an error occurs. - """ - try: - s = _UniffiRustBufferStream.from_rust_buffer(self) - yield s - if s.remaining() != 0: - raise RuntimeError("junk data left in buffer at end of consume_with_stream") - finally: - self.free() - - @contextlib.contextmanager - def read_with_stream(self): - """Context-manager to read a buffer using a _UniffiRustBufferStream. - - This is like consume_with_stream, but doesn't free the buffer afterwards. - It should only be used with borrowed `_UniffiRustBuffer` data. - """ - s = _UniffiRustBufferStream.from_rust_buffer(self) - yield s - if s.remaining() != 0: - raise RuntimeError("junk data left in buffer at end of read_with_stream") - -class _UniffiForeignBytes(ctypes.Structure): - _fields_ = [ - ("len", ctypes.c_int32), - ("data", ctypes.POINTER(ctypes.c_char)), - ] - - def __str__(self): - return "_UniffiForeignBytes(len={}, data={})".format(self.len, self.data[0:self.len]) - - -class _UniffiRustBufferStream: - """ - Helper for structured reading of bytes from a _UniffiRustBuffer - """ - - def __init__(self, data, len): - self.data = data - self.len = len - self.offset = 0 - - @classmethod - def from_rust_buffer(cls, buf): - return cls(buf.data, buf.len) - - def remaining(self): - return self.len - self.offset - - def _unpack_from(self, size, format): - if self.offset + size > self.len: - raise InternalError("read past end of rust buffer") - value = struct.unpack(format, self.data[self.offset:self.offset+size])[0] - self.offset += size - return value - - def read(self, size): - if self.offset + size > self.len: - raise InternalError("read past end of rust buffer") - data = self.data[self.offset:self.offset+size] - self.offset += size - return data - - def read_i8(self): - return self._unpack_from(1, ">b") - - def read_u8(self): - return self._unpack_from(1, ">B") - - def read_i16(self): - return self._unpack_from(2, ">h") - - def read_u16(self): - return self._unpack_from(2, ">H") - - def read_i32(self): - return self._unpack_from(4, ">i") - - def read_u32(self): - return self._unpack_from(4, ">I") - - def read_i64(self): - return self._unpack_from(8, ">q") - - def read_u64(self): - return self._unpack_from(8, ">Q") - - def read_float(self): - v = self._unpack_from(4, ">f") - return v - - def read_double(self): - return self._unpack_from(8, ">d") - -class _UniffiRustBufferBuilder: - """ - Helper for structured writing of bytes into a _UniffiRustBuffer. - """ - - def __init__(self): - self.rbuf = _UniffiRustBuffer.alloc(16) - self.rbuf.len = 0 - - def finalize(self): - rbuf = self.rbuf - self.rbuf = None - return rbuf - - def discard(self): - if self.rbuf is not None: - rbuf = self.finalize() - rbuf.free() - - @contextlib.contextmanager - def _reserve(self, num_bytes): - if self.rbuf.len + num_bytes > self.rbuf.capacity: - self.rbuf = _UniffiRustBuffer.reserve(self.rbuf, num_bytes) - yield None - self.rbuf.len += num_bytes - - def _pack_into(self, size, format, value): - with self._reserve(size): - # XXX TODO: I feel like I should be able to use `struct.pack_into` here but can't figure it out. - for i, byte in enumerate(struct.pack(format, value)): - self.rbuf.data[self.rbuf.len + i] = byte - - def write(self, value): - with self._reserve(len(value)): - for i, byte in enumerate(value): - self.rbuf.data[self.rbuf.len + i] = byte - - def write_i8(self, v): - self._pack_into(1, ">b", v) - - def write_u8(self, v): - self._pack_into(1, ">B", v) - - def write_i16(self, v): - self._pack_into(2, ">h", v) - - def write_u16(self, v): - self._pack_into(2, ">H", v) - - def write_i32(self, v): - self._pack_into(4, ">i", v) - - def write_u32(self, v): - self._pack_into(4, ">I", v) - - def write_i64(self, v): - self._pack_into(8, ">q", v) - - def write_u64(self, v): - self._pack_into(8, ">Q", v) - - def write_float(self, v): - self._pack_into(4, ">f", v) - - def write_double(self, v): - self._pack_into(8, ">d", v) - - def write_c_size_t(self, v): - self._pack_into(ctypes.sizeof(ctypes.c_size_t) , "@N", v) -# A handful of classes and functions to support the generated data structures. -# This would be a good candidate for isolating in its own ffi-support lib. - -class InternalError(Exception): - pass - -class _UniffiRustCallStatus(ctypes.Structure): - """ - Error runtime. - """ - _fields_ = [ - ("code", ctypes.c_int8), - ("error_buf", _UniffiRustBuffer), - ] - - # These match the values from the uniffi::rustcalls module - CALL_SUCCESS = 0 - CALL_ERROR = 1 - CALL_UNEXPECTED_ERROR = 2 - - @staticmethod - def default(): - return _UniffiRustCallStatus(code=_UniffiRustCallStatus.CALL_SUCCESS, error_buf=_UniffiRustBuffer.default()) - - def __str__(self): - if self.code == _UniffiRustCallStatus.CALL_SUCCESS: - return "_UniffiRustCallStatus(CALL_SUCCESS)" - elif self.code == _UniffiRustCallStatus.CALL_ERROR: - return "_UniffiRustCallStatus(CALL_ERROR)" - elif self.code == _UniffiRustCallStatus.CALL_UNEXPECTED_ERROR: - return "_UniffiRustCallStatus(CALL_UNEXPECTED_ERROR)" - else: - return "_UniffiRustCallStatus()" - -def _uniffi_rust_call(fn, *args): - # Call a rust function - return _uniffi_rust_call_with_error(None, fn, *args) - -def _uniffi_rust_call_with_error(error_ffi_converter, fn, *args): - # Call a rust function and handle any errors - # - # This function is used for rust calls that return Result<> and therefore can set the CALL_ERROR status code. - # error_ffi_converter must be set to the _UniffiConverter for the error class that corresponds to the result. - call_status = _UniffiRustCallStatus.default() - - args_with_error = args + (ctypes.byref(call_status),) - result = fn(*args_with_error) - _uniffi_check_call_status(error_ffi_converter, call_status) - return result - -def _uniffi_check_call_status(error_ffi_converter, call_status): - if call_status.code == _UniffiRustCallStatus.CALL_SUCCESS: - pass - elif call_status.code == _UniffiRustCallStatus.CALL_ERROR: - if error_ffi_converter is None: - call_status.error_buf.free() - raise InternalError("_uniffi_rust_call_with_error: CALL_ERROR, but error_ffi_converter is None") - else: - raise error_ffi_converter.lift(call_status.error_buf) - elif call_status.code == _UniffiRustCallStatus.CALL_UNEXPECTED_ERROR: - # When the rust code sees a panic, it tries to construct a _UniffiRustBuffer - # with the message. But if that code panics, then it just sends back - # an empty buffer. - if call_status.error_buf.len > 0: - msg = _UniffiConverterString.lift(call_status.error_buf) - else: - msg = "Unknown rust panic" - raise InternalError(msg) - else: - raise InternalError("Invalid _UniffiRustCallStatus code: {}".format( - call_status.code)) - -def _uniffi_trait_interface_call(call_status, make_call, write_return_value): - try: - return write_return_value(make_call()) - except Exception as e: - call_status.code = _UniffiRustCallStatus.CALL_UNEXPECTED_ERROR - call_status.error_buf = _UniffiConverterString.lower(repr(e)) - -def _uniffi_trait_interface_call_with_error(call_status, make_call, write_return_value, error_type, lower_error): - try: - try: - return write_return_value(make_call()) - except error_type as e: - call_status.code = _UniffiRustCallStatus.CALL_ERROR - call_status.error_buf = lower_error(e) - except Exception as e: - call_status.code = _UniffiRustCallStatus.CALL_UNEXPECTED_ERROR - call_status.error_buf = _UniffiConverterString.lower(repr(e)) -class _UniffiHandleMap: - """ - A map where inserting, getting and removing data is synchronized with a lock. - """ - - def __init__(self): - # type Handle = int - self._map = {} # type: Dict[Handle, Any] - self._lock = threading.Lock() - self._counter = itertools.count() - - def insert(self, obj): - with self._lock: - handle = next(self._counter) - self._map[handle] = obj - return handle - - def get(self, handle): - try: - with self._lock: - return self._map[handle] - except KeyError: - raise InternalError("_UniffiHandleMap.get: Invalid handle") - - def remove(self, handle): - try: - with self._lock: - return self._map.pop(handle) - except KeyError: - raise InternalError("_UniffiHandleMap.remove: Invalid handle") - - def __len__(self): - return len(self._map) -# Types conforming to `_UniffiConverterPrimitive` pass themselves directly over the FFI. -class _UniffiConverterPrimitive: - @classmethod - def lift(cls, value): - return value - - @classmethod - def lower(cls, value): - return value - -class _UniffiConverterPrimitiveInt(_UniffiConverterPrimitive): - @classmethod - def check_lower(cls, value): - try: - value = value.__index__() - except Exception: - raise TypeError("'{}' object cannot be interpreted as an integer".format(type(value).__name__)) - if not isinstance(value, int): - raise TypeError("__index__ returned non-int (type {})".format(type(value).__name__)) - if not cls.VALUE_MIN <= value < cls.VALUE_MAX: - raise ValueError("{} requires {} <= value < {}".format(cls.CLASS_NAME, cls.VALUE_MIN, cls.VALUE_MAX)) - -class _UniffiConverterPrimitiveFloat(_UniffiConverterPrimitive): - @classmethod - def check_lower(cls, value): - try: - value = value.__float__() - except Exception: - raise TypeError("must be real number, not {}".format(type(value).__name__)) - if not isinstance(value, float): - raise TypeError("__float__ returned non-float (type {})".format(type(value).__name__)) - -# Helper class for wrapper types that will always go through a _UniffiRustBuffer. -# Classes should inherit from this and implement the `read` and `write` static methods. -class _UniffiConverterRustBuffer: - @classmethod - def lift(cls, rbuf): - with rbuf.consume_with_stream() as stream: - return cls.read(stream) - - @classmethod - def lower(cls, value): - with _UniffiRustBuffer.alloc_with_builder() as builder: - cls.write(value, builder) - return builder.finalize() - -# Contains loading, initialization code, and the FFI Function declarations. -# Define some ctypes FFI types that we use in the library - -""" -Function pointer for a Rust task, which a callback function that takes a opaque pointer -""" -_UNIFFI_RUST_TASK = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int8) - -def _uniffi_future_callback_t(return_type): - """ - Factory function to create callback function types for async functions - """ - return ctypes.CFUNCTYPE(None, ctypes.c_uint64, return_type, _UniffiRustCallStatus) - -def _uniffi_load_indirect(): - """ - This is how we find and load the dynamic library provided by the component. - For now we just look it up by name. - """ - if sys.platform == "darwin": - libname = "lib{}.dylib" - elif sys.platform.startswith("win"): - # As of python3.8, ctypes does not seem to search $PATH when loading DLLs. - # We could use `os.add_dll_directory` to configure the search path, but - # it doesn't feel right to mess with application-wide settings. Let's - # assume that the `.dll` is next to the `.py` file and load by full path. - libname = os.path.join( - os.path.dirname(__file__), - "{}.dll", - ) - else: - # Anything else must be an ELF platform - Linux, *BSD, Solaris/illumos - libname = "lib{}.so" - - libname = libname.format("glsdk") - path = os.path.join(os.path.dirname(__file__), libname) - lib = ctypes.cdll.LoadLibrary(path) - return lib - -def _uniffi_check_contract_api_version(lib): - # Get the bindings contract version from our ComponentInterface - bindings_contract_version = 29 - # Get the scaffolding contract version by calling the into the dylib - scaffolding_contract_version = lib.ffi_glsdk_uniffi_contract_version() - if bindings_contract_version != scaffolding_contract_version: - raise InternalError("UniFFI contract version mismatch: try cleaning and rebuilding your project") - -def _uniffi_check_api_checksums(lib): - if lib.uniffi_glsdk_checksum_method_credentials_save() != 26677: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_handle_stop() != 36432: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_get_info() != 39460: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_list_funds() != 21692: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_list_peer_channels() != 35210: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_list_peers() != 29567: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_onchain_receive() != 57530: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_onchain_send() != 44346: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_receive() != 39761: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_send() != 4348: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_stop() != 20186: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_node_stream_node_events() != 5933: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_nodeeventstream_next() != 12635: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_scheduler_recover() != 55514: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_scheduler_register() != 20821: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_signer_authenticate() != 55935: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_signer_node_id() != 43931: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_method_signer_start() != 9404: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_constructor_credentials_load() != 25306: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_constructor_node_new() != 7003: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_constructor_scheduler_new() != 15239: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - if lib.uniffi_glsdk_checksum_constructor_signer_new() != 62159: - raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - -# A ctypes library to expose the extern-C FFI definitions. -# This is an implementation detail which will be called internally by the public API. - -_UniffiLib = _uniffi_load_indirect() -_UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK = ctypes.CFUNCTYPE(None,ctypes.c_uint64,ctypes.c_int8, -) -_UNIFFI_FOREIGN_FUTURE_FREE = ctypes.CFUNCTYPE(None,ctypes.c_uint64, -) -_UNIFFI_CALLBACK_INTERFACE_FREE = ctypes.CFUNCTYPE(None,ctypes.c_uint64, -) -class _UniffiForeignFuture(ctypes.Structure): - _fields_ = [ - ("handle", ctypes.c_uint64), - ("free", _UNIFFI_FOREIGN_FUTURE_FREE), - ] -class _UniffiForeignFutureStructU8(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_uint8), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_U8 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructU8, -) -class _UniffiForeignFutureStructI8(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_int8), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_I8 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructI8, -) -class _UniffiForeignFutureStructU16(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_uint16), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_U16 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructU16, -) -class _UniffiForeignFutureStructI16(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_int16), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_I16 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructI16, -) -class _UniffiForeignFutureStructU32(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_uint32), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_U32 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructU32, -) -class _UniffiForeignFutureStructI32(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_int32), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_I32 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructI32, -) -class _UniffiForeignFutureStructU64(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_uint64), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_U64 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructU64, -) -class _UniffiForeignFutureStructI64(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_int64), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_I64 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructI64, -) -class _UniffiForeignFutureStructF32(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_float), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_F32 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructF32, -) -class _UniffiForeignFutureStructF64(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_double), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_F64 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructF64, -) -class _UniffiForeignFutureStructPointer(ctypes.Structure): - _fields_ = [ - ("return_value", ctypes.c_void_p), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_POINTER = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructPointer, -) -class _UniffiForeignFutureStructRustBuffer(ctypes.Structure): - _fields_ = [ - ("return_value", _UniffiRustBuffer), - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructRustBuffer, -) -class _UniffiForeignFutureStructVoid(ctypes.Structure): - _fields_ = [ - ("call_status", _UniffiRustCallStatus), - ] -_UNIFFI_FOREIGN_FUTURE_COMPLETE_VOID = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiForeignFutureStructVoid, -) -_UniffiLib.uniffi_glsdk_fn_clone_credentials.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_credentials.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_credentials.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_credentials.restype = None -_UniffiLib.uniffi_glsdk_fn_constructor_credentials_load.argtypes = ( - _UniffiRustBuffer, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_constructor_credentials_load.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_method_credentials_save.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_credentials_save.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_clone_handle.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_handle.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_handle.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_handle.restype = None -_UniffiLib.uniffi_glsdk_fn_method_handle_stop.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_handle_stop.restype = None -_UniffiLib.uniffi_glsdk_fn_clone_node.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_node.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_node.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_node.restype = None -_UniffiLib.uniffi_glsdk_fn_constructor_node_new.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_constructor_node_new.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_method_node_get_info.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_get_info.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_method_node_list_funds.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_list_funds.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_method_node_list_peer_channels.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_list_peer_channels.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_method_node_list_peers.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_list_peers.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.argtypes = ( - ctypes.c_void_p, - _UniffiRustBuffer, - _UniffiRustBuffer, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_method_node_receive.argtypes = ( - ctypes.c_void_p, - _UniffiRustBuffer, - _UniffiRustBuffer, - _UniffiRustBuffer, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_receive.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_method_node_send.argtypes = ( - ctypes.c_void_p, - _UniffiRustBuffer, - _UniffiRustBuffer, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_send.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_method_node_stop.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_stop.restype = None -_UniffiLib.uniffi_glsdk_fn_method_node_stream_node_events.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_node_stream_node_events.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_clone_nodeeventstream.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_nodeeventstream.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_nodeeventstream.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_nodeeventstream.restype = None -_UniffiLib.uniffi_glsdk_fn_method_nodeeventstream_next.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_nodeeventstream_next.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_clone_scheduler.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_scheduler.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_scheduler.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_scheduler.restype = None -_UniffiLib.uniffi_glsdk_fn_constructor_scheduler_new.argtypes = ( - _UniffiRustBuffer, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_constructor_scheduler_new.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_method_scheduler_recover.argtypes = ( - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_scheduler_recover.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_method_scheduler_register.argtypes = ( - ctypes.c_void_p, - ctypes.c_void_p, - _UniffiRustBuffer, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_scheduler_register.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_clone_signer.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_clone_signer.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_free_signer.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_free_signer.restype = None -_UniffiLib.uniffi_glsdk_fn_constructor_signer_new.argtypes = ( - _UniffiRustBuffer, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_constructor_signer_new.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_method_signer_authenticate.argtypes = ( - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_signer_authenticate.restype = ctypes.c_void_p -_UniffiLib.uniffi_glsdk_fn_method_signer_node_id.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_signer_node_id.restype = _UniffiRustBuffer -_UniffiLib.uniffi_glsdk_fn_method_signer_start.argtypes = ( - ctypes.c_void_p, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.uniffi_glsdk_fn_method_signer_start.restype = ctypes.c_void_p -_UniffiLib.ffi_glsdk_rustbuffer_alloc.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rustbuffer_alloc.restype = _UniffiRustBuffer -_UniffiLib.ffi_glsdk_rustbuffer_from_bytes.argtypes = ( - _UniffiForeignBytes, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rustbuffer_from_bytes.restype = _UniffiRustBuffer -_UniffiLib.ffi_glsdk_rustbuffer_free.argtypes = ( - _UniffiRustBuffer, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rustbuffer_free.restype = None -_UniffiLib.ffi_glsdk_rustbuffer_reserve.argtypes = ( - _UniffiRustBuffer, - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rustbuffer_reserve.restype = _UniffiRustBuffer -_UniffiLib.ffi_glsdk_rust_future_poll_u8.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_u8.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_u8.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_u8.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_u8.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_u8.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_u8.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_u8.restype = ctypes.c_uint8 -_UniffiLib.ffi_glsdk_rust_future_poll_i8.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_i8.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_i8.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_i8.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_i8.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_i8.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_i8.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_i8.restype = ctypes.c_int8 -_UniffiLib.ffi_glsdk_rust_future_poll_u16.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_u16.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_u16.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_u16.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_u16.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_u16.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_u16.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_u16.restype = ctypes.c_uint16 -_UniffiLib.ffi_glsdk_rust_future_poll_i16.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_i16.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_i16.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_i16.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_i16.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_i16.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_i16.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_i16.restype = ctypes.c_int16 -_UniffiLib.ffi_glsdk_rust_future_poll_u32.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_u32.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_u32.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_u32.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_u32.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_u32.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_u32.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_u32.restype = ctypes.c_uint32 -_UniffiLib.ffi_glsdk_rust_future_poll_i32.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_i32.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_i32.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_i32.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_i32.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_i32.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_i32.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_i32.restype = ctypes.c_int32 -_UniffiLib.ffi_glsdk_rust_future_poll_u64.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_u64.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_u64.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_u64.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_u64.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_u64.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_u64.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_u64.restype = ctypes.c_uint64 -_UniffiLib.ffi_glsdk_rust_future_poll_i64.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_i64.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_i64.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_i64.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_i64.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_i64.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_i64.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_i64.restype = ctypes.c_int64 -_UniffiLib.ffi_glsdk_rust_future_poll_f32.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_f32.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_f32.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_f32.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_f32.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_f32.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_f32.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_f32.restype = ctypes.c_float -_UniffiLib.ffi_glsdk_rust_future_poll_f64.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_f64.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_f64.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_f64.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_f64.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_f64.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_f64.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_f64.restype = ctypes.c_double -_UniffiLib.ffi_glsdk_rust_future_poll_pointer.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_pointer.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_pointer.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_pointer.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_pointer.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_pointer.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_pointer.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_pointer.restype = ctypes.c_void_p -_UniffiLib.ffi_glsdk_rust_future_poll_rust_buffer.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_rust_buffer.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_rust_buffer.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_rust_buffer.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_rust_buffer.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_rust_buffer.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_rust_buffer.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_rust_buffer.restype = _UniffiRustBuffer -_UniffiLib.ffi_glsdk_rust_future_poll_void.argtypes = ( - ctypes.c_uint64, - _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_poll_void.restype = None -_UniffiLib.ffi_glsdk_rust_future_cancel_void.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_cancel_void.restype = None -_UniffiLib.ffi_glsdk_rust_future_free_void.argtypes = ( - ctypes.c_uint64, -) -_UniffiLib.ffi_glsdk_rust_future_free_void.restype = None -_UniffiLib.ffi_glsdk_rust_future_complete_void.argtypes = ( - ctypes.c_uint64, - ctypes.POINTER(_UniffiRustCallStatus), -) -_UniffiLib.ffi_glsdk_rust_future_complete_void.restype = None -_UniffiLib.uniffi_glsdk_checksum_method_credentials_save.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_credentials_save.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_handle_stop.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_handle_stop.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_get_info.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_get_info.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_list_funds.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_list_funds.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_list_peer_channels.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_list_peer_channels.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_list_peers.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_list_peers.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_onchain_receive.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_onchain_receive.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_onchain_send.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_onchain_send.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_receive.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_receive.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_send.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_send.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_stop.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_stop.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_node_stream_node_events.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_node_stream_node_events.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_nodeeventstream_next.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_nodeeventstream_next.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_scheduler_recover.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_scheduler_recover.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_scheduler_register.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_scheduler_register.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_signer_authenticate.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_signer_authenticate.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_signer_node_id.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_signer_node_id.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_method_signer_start.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_method_signer_start.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_constructor_credentials_load.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_constructor_credentials_load.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_constructor_node_new.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_constructor_node_new.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_constructor_scheduler_new.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_constructor_scheduler_new.restype = ctypes.c_uint16 -_UniffiLib.uniffi_glsdk_checksum_constructor_signer_new.argtypes = ( -) -_UniffiLib.uniffi_glsdk_checksum_constructor_signer_new.restype = ctypes.c_uint16 -_UniffiLib.ffi_glsdk_uniffi_contract_version.argtypes = ( -) -_UniffiLib.ffi_glsdk_uniffi_contract_version.restype = ctypes.c_uint32 - -_uniffi_check_contract_api_version(_UniffiLib) -# _uniffi_check_api_checksums(_UniffiLib) - -# Public interface members begin here. - - -class _UniffiConverterUInt32(_UniffiConverterPrimitiveInt): - CLASS_NAME = "u32" - VALUE_MIN = 0 - VALUE_MAX = 2**32 - - @staticmethod - def read(buf): - return buf.read_u32() - - @staticmethod - def write(value, buf): - buf.write_u32(value) - -class _UniffiConverterUInt64(_UniffiConverterPrimitiveInt): - CLASS_NAME = "u64" - VALUE_MIN = 0 - VALUE_MAX = 2**64 - - @staticmethod - def read(buf): - return buf.read_u64() - - @staticmethod - def write(value, buf): - buf.write_u64(value) - -class _UniffiConverterBool: - @classmethod - def check_lower(cls, value): - return not not value - - @classmethod - def lower(cls, value): - return 1 if value else 0 - - @staticmethod - def lift(value): - return value != 0 - - @classmethod - def read(cls, buf): - return cls.lift(buf.read_u8()) - - @classmethod - def write(cls, value, buf): - buf.write_u8(value) - -class _UniffiConverterString: - @staticmethod - def check_lower(value): - if not isinstance(value, str): - raise TypeError("argument must be str, not {}".format(type(value).__name__)) - return value - - @staticmethod - def read(buf): - size = buf.read_i32() - if size < 0: - raise InternalError("Unexpected negative string length") - utf8_bytes = buf.read(size) - return utf8_bytes.decode("utf-8") - - @staticmethod - def write(value, buf): - utf8_bytes = value.encode("utf-8") - buf.write_i32(len(utf8_bytes)) - buf.write(utf8_bytes) - - @staticmethod - def lift(buf): - with buf.consume_with_stream() as stream: - return stream.read(stream.remaining()).decode("utf-8") - - @staticmethod - def lower(value): - with _UniffiRustBuffer.alloc_with_builder() as builder: - builder.write(value.encode("utf-8")) - return builder.finalize() - -class _UniffiConverterBytes(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - size = buf.read_i32() - if size < 0: - raise InternalError("Unexpected negative byte string length") - return buf.read(size) - - @staticmethod - def check_lower(value): - try: - memoryview(value) - except TypeError: - raise TypeError("a bytes-like object is required, not {!r}".format(type(value).__name__)) - - @staticmethod - def write(value, buf): - buf.write_i32(len(value)) - buf.write(value) - - - - - - - - - - - - - - -class FundChannel: - peer_id: "bytes" - our_amount_msat: "int" - amount_msat: "int" - funding_txid: "bytes" - funding_output: "int" - connected: "bool" - state: "ChannelState" - short_channel_id: "typing.Optional[str]" - channel_id: "typing.Optional[bytes]" - def __init__(self, *, peer_id: "bytes", our_amount_msat: "int", amount_msat: "int", funding_txid: "bytes", funding_output: "int", connected: "bool", state: "ChannelState", short_channel_id: "typing.Optional[str]", channel_id: "typing.Optional[bytes]"): - self.peer_id = peer_id - self.our_amount_msat = our_amount_msat - self.amount_msat = amount_msat - self.funding_txid = funding_txid - self.funding_output = funding_output - self.connected = connected - self.state = state - self.short_channel_id = short_channel_id - self.channel_id = channel_id - - def __str__(self): - return "FundChannel(peer_id={}, our_amount_msat={}, amount_msat={}, funding_txid={}, funding_output={}, connected={}, state={}, short_channel_id={}, channel_id={})".format(self.peer_id, self.our_amount_msat, self.amount_msat, self.funding_txid, self.funding_output, self.connected, self.state, self.short_channel_id, self.channel_id) - - def __eq__(self, other): - if self.peer_id != other.peer_id: - return False - if self.our_amount_msat != other.our_amount_msat: - return False - if self.amount_msat != other.amount_msat: - return False - if self.funding_txid != other.funding_txid: - return False - if self.funding_output != other.funding_output: - return False - if self.connected != other.connected: - return False - if self.state != other.state: - return False - if self.short_channel_id != other.short_channel_id: - return False - if self.channel_id != other.channel_id: - return False - return True - -class _UniffiConverterTypeFundChannel(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return FundChannel( - peer_id=_UniffiConverterBytes.read(buf), - our_amount_msat=_UniffiConverterUInt64.read(buf), - amount_msat=_UniffiConverterUInt64.read(buf), - funding_txid=_UniffiConverterBytes.read(buf), - funding_output=_UniffiConverterUInt32.read(buf), - connected=_UniffiConverterBool.read(buf), - state=_UniffiConverterTypeChannelState.read(buf), - short_channel_id=_UniffiConverterOptionalString.read(buf), - channel_id=_UniffiConverterOptionalBytes.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterBytes.check_lower(value.peer_id) - _UniffiConverterUInt64.check_lower(value.our_amount_msat) - _UniffiConverterUInt64.check_lower(value.amount_msat) - _UniffiConverterBytes.check_lower(value.funding_txid) - _UniffiConverterUInt32.check_lower(value.funding_output) - _UniffiConverterBool.check_lower(value.connected) - _UniffiConverterTypeChannelState.check_lower(value.state) - _UniffiConverterOptionalString.check_lower(value.short_channel_id) - _UniffiConverterOptionalBytes.check_lower(value.channel_id) - - @staticmethod - def write(value, buf): - _UniffiConverterBytes.write(value.peer_id, buf) - _UniffiConverterUInt64.write(value.our_amount_msat, buf) - _UniffiConverterUInt64.write(value.amount_msat, buf) - _UniffiConverterBytes.write(value.funding_txid, buf) - _UniffiConverterUInt32.write(value.funding_output, buf) - _UniffiConverterBool.write(value.connected, buf) - _UniffiConverterTypeChannelState.write(value.state, buf) - _UniffiConverterOptionalString.write(value.short_channel_id, buf) - _UniffiConverterOptionalBytes.write(value.channel_id, buf) - - -class FundOutput: - txid: "bytes" - output: "int" - amount_msat: "int" - status: "OutputStatus" - address: "typing.Optional[str]" - blockheight: "typing.Optional[int]" - def __init__(self, *, txid: "bytes", output: "int", amount_msat: "int", status: "OutputStatus", address: "typing.Optional[str]", blockheight: "typing.Optional[int]"): - self.txid = txid - self.output = output - self.amount_msat = amount_msat - self.status = status - self.address = address - self.blockheight = blockheight - - def __str__(self): - return "FundOutput(txid={}, output={}, amount_msat={}, status={}, address={}, blockheight={})".format(self.txid, self.output, self.amount_msat, self.status, self.address, self.blockheight) - - def __eq__(self, other): - if self.txid != other.txid: - return False - if self.output != other.output: - return False - if self.amount_msat != other.amount_msat: - return False - if self.status != other.status: - return False - if self.address != other.address: - return False - if self.blockheight != other.blockheight: - return False - return True - -class _UniffiConverterTypeFundOutput(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return FundOutput( - txid=_UniffiConverterBytes.read(buf), - output=_UniffiConverterUInt32.read(buf), - amount_msat=_UniffiConverterUInt64.read(buf), - status=_UniffiConverterTypeOutputStatus.read(buf), - address=_UniffiConverterOptionalString.read(buf), - blockheight=_UniffiConverterOptionalUInt32.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterBytes.check_lower(value.txid) - _UniffiConverterUInt32.check_lower(value.output) - _UniffiConverterUInt64.check_lower(value.amount_msat) - _UniffiConverterTypeOutputStatus.check_lower(value.status) - _UniffiConverterOptionalString.check_lower(value.address) - _UniffiConverterOptionalUInt32.check_lower(value.blockheight) - - @staticmethod - def write(value, buf): - _UniffiConverterBytes.write(value.txid, buf) - _UniffiConverterUInt32.write(value.output, buf) - _UniffiConverterUInt64.write(value.amount_msat, buf) - _UniffiConverterTypeOutputStatus.write(value.status, buf) - _UniffiConverterOptionalString.write(value.address, buf) - _UniffiConverterOptionalUInt32.write(value.blockheight, buf) - - -class GetInfoResponse: - id: "bytes" - alias: "typing.Optional[str]" - color: "bytes" - num_peers: "int" - num_pending_channels: "int" - num_active_channels: "int" - num_inactive_channels: "int" - version: "str" - lightning_dir: "str" - blockheight: "int" - network: "str" - fees_collected_msat: "int" - def __init__(self, *, id: "bytes", alias: "typing.Optional[str]", color: "bytes", num_peers: "int", num_pending_channels: "int", num_active_channels: "int", num_inactive_channels: "int", version: "str", lightning_dir: "str", blockheight: "int", network: "str", fees_collected_msat: "int"): - self.id = id - self.alias = alias - self.color = color - self.num_peers = num_peers - self.num_pending_channels = num_pending_channels - self.num_active_channels = num_active_channels - self.num_inactive_channels = num_inactive_channels - self.version = version - self.lightning_dir = lightning_dir - self.blockheight = blockheight - self.network = network - self.fees_collected_msat = fees_collected_msat - - def __str__(self): - return "GetInfoResponse(id={}, alias={}, color={}, num_peers={}, num_pending_channels={}, num_active_channels={}, num_inactive_channels={}, version={}, lightning_dir={}, blockheight={}, network={}, fees_collected_msat={})".format(self.id, self.alias, self.color, self.num_peers, self.num_pending_channels, self.num_active_channels, self.num_inactive_channels, self.version, self.lightning_dir, self.blockheight, self.network, self.fees_collected_msat) - - def __eq__(self, other): - if self.id != other.id: - return False - if self.alias != other.alias: - return False - if self.color != other.color: - return False - if self.num_peers != other.num_peers: - return False - if self.num_pending_channels != other.num_pending_channels: - return False - if self.num_active_channels != other.num_active_channels: - return False - if self.num_inactive_channels != other.num_inactive_channels: - return False - if self.version != other.version: - return False - if self.lightning_dir != other.lightning_dir: - return False - if self.blockheight != other.blockheight: - return False - if self.network != other.network: - return False - if self.fees_collected_msat != other.fees_collected_msat: - return False - return True - -class _UniffiConverterTypeGetInfoResponse(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return GetInfoResponse( - id=_UniffiConverterBytes.read(buf), - alias=_UniffiConverterOptionalString.read(buf), - color=_UniffiConverterBytes.read(buf), - num_peers=_UniffiConverterUInt32.read(buf), - num_pending_channels=_UniffiConverterUInt32.read(buf), - num_active_channels=_UniffiConverterUInt32.read(buf), - num_inactive_channels=_UniffiConverterUInt32.read(buf), - version=_UniffiConverterString.read(buf), - lightning_dir=_UniffiConverterString.read(buf), - blockheight=_UniffiConverterUInt32.read(buf), - network=_UniffiConverterString.read(buf), - fees_collected_msat=_UniffiConverterUInt64.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterBytes.check_lower(value.id) - _UniffiConverterOptionalString.check_lower(value.alias) - _UniffiConverterBytes.check_lower(value.color) - _UniffiConverterUInt32.check_lower(value.num_peers) - _UniffiConverterUInt32.check_lower(value.num_pending_channels) - _UniffiConverterUInt32.check_lower(value.num_active_channels) - _UniffiConverterUInt32.check_lower(value.num_inactive_channels) - _UniffiConverterString.check_lower(value.version) - _UniffiConverterString.check_lower(value.lightning_dir) - _UniffiConverterUInt32.check_lower(value.blockheight) - _UniffiConverterString.check_lower(value.network) - _UniffiConverterUInt64.check_lower(value.fees_collected_msat) - - @staticmethod - def write(value, buf): - _UniffiConverterBytes.write(value.id, buf) - _UniffiConverterOptionalString.write(value.alias, buf) - _UniffiConverterBytes.write(value.color, buf) - _UniffiConverterUInt32.write(value.num_peers, buf) - _UniffiConverterUInt32.write(value.num_pending_channels, buf) - _UniffiConverterUInt32.write(value.num_active_channels, buf) - _UniffiConverterUInt32.write(value.num_inactive_channels, buf) - _UniffiConverterString.write(value.version, buf) - _UniffiConverterString.write(value.lightning_dir, buf) - _UniffiConverterUInt32.write(value.blockheight, buf) - _UniffiConverterString.write(value.network, buf) - _UniffiConverterUInt64.write(value.fees_collected_msat, buf) - - -class InvoicePaidEvent: - """ - Details of a paid invoice. - """ - - payment_hash: "bytes" - """ - The payment hash of the paid invoice. - """ - - bolt11: "str" - """ - The bolt11 invoice string. - """ - - preimage: "bytes" - """ - The preimage that proves payment. - """ - - label: "str" - """ - The label assigned to the invoice. - """ - - amount_msat: "int" - """ - Amount received in millisatoshis. - """ - - def __init__(self, *, payment_hash: "bytes", bolt11: "str", preimage: "bytes", label: "str", amount_msat: "int"): - self.payment_hash = payment_hash - self.bolt11 = bolt11 - self.preimage = preimage - self.label = label - self.amount_msat = amount_msat - - def __str__(self): - return "InvoicePaidEvent(payment_hash={}, bolt11={}, preimage={}, label={}, amount_msat={})".format(self.payment_hash, self.bolt11, self.preimage, self.label, self.amount_msat) - - def __eq__(self, other): - if self.payment_hash != other.payment_hash: - return False - if self.bolt11 != other.bolt11: - return False - if self.preimage != other.preimage: - return False - if self.label != other.label: - return False - if self.amount_msat != other.amount_msat: - return False - return True - -class _UniffiConverterTypeInvoicePaidEvent(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return InvoicePaidEvent( - payment_hash=_UniffiConverterBytes.read(buf), - bolt11=_UniffiConverterString.read(buf), - preimage=_UniffiConverterBytes.read(buf), - label=_UniffiConverterString.read(buf), - amount_msat=_UniffiConverterUInt64.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterBytes.check_lower(value.payment_hash) - _UniffiConverterString.check_lower(value.bolt11) - _UniffiConverterBytes.check_lower(value.preimage) - _UniffiConverterString.check_lower(value.label) - _UniffiConverterUInt64.check_lower(value.amount_msat) - - @staticmethod - def write(value, buf): - _UniffiConverterBytes.write(value.payment_hash, buf) - _UniffiConverterString.write(value.bolt11, buf) - _UniffiConverterBytes.write(value.preimage, buf) - _UniffiConverterString.write(value.label, buf) - _UniffiConverterUInt64.write(value.amount_msat, buf) - - -class ListFundsResponse: - outputs: "typing.List[FundOutput]" - channels: "typing.List[FundChannel]" - def __init__(self, *, outputs: "typing.List[FundOutput]", channels: "typing.List[FundChannel]"): - self.outputs = outputs - self.channels = channels - - def __str__(self): - return "ListFundsResponse(outputs={}, channels={})".format(self.outputs, self.channels) - - def __eq__(self, other): - if self.outputs != other.outputs: - return False - if self.channels != other.channels: - return False - return True - -class _UniffiConverterTypeListFundsResponse(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return ListFundsResponse( - outputs=_UniffiConverterSequenceTypeFundOutput.read(buf), - channels=_UniffiConverterSequenceTypeFundChannel.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterSequenceTypeFundOutput.check_lower(value.outputs) - _UniffiConverterSequenceTypeFundChannel.check_lower(value.channels) - - @staticmethod - def write(value, buf): - _UniffiConverterSequenceTypeFundOutput.write(value.outputs, buf) - _UniffiConverterSequenceTypeFundChannel.write(value.channels, buf) - - -class ListPeerChannelsResponse: - channels: "typing.List[PeerChannel]" - def __init__(self, *, channels: "typing.List[PeerChannel]"): - self.channels = channels - - def __str__(self): - return "ListPeerChannelsResponse(channels={})".format(self.channels) - - def __eq__(self, other): - if self.channels != other.channels: - return False - return True - -class _UniffiConverterTypeListPeerChannelsResponse(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return ListPeerChannelsResponse( - channels=_UniffiConverterSequenceTypePeerChannel.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterSequenceTypePeerChannel.check_lower(value.channels) - - @staticmethod - def write(value, buf): - _UniffiConverterSequenceTypePeerChannel.write(value.channels, buf) - - -class ListPeersResponse: - peers: "typing.List[Peer]" - def __init__(self, *, peers: "typing.List[Peer]"): - self.peers = peers - - def __str__(self): - return "ListPeersResponse(peers={})".format(self.peers) - - def __eq__(self, other): - if self.peers != other.peers: - return False - return True - -class _UniffiConverterTypeListPeersResponse(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return ListPeersResponse( - peers=_UniffiConverterSequenceTypePeer.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterSequenceTypePeer.check_lower(value.peers) - - @staticmethod - def write(value, buf): - _UniffiConverterSequenceTypePeer.write(value.peers, buf) - - -class OnchainReceiveResponse: - bech32: "str" - p2tr: "str" - def __init__(self, *, bech32: "str", p2tr: "str"): - self.bech32 = bech32 - self.p2tr = p2tr - - def __str__(self): - return "OnchainReceiveResponse(bech32={}, p2tr={})".format(self.bech32, self.p2tr) - - def __eq__(self, other): - if self.bech32 != other.bech32: - return False - if self.p2tr != other.p2tr: - return False - return True - -class _UniffiConverterTypeOnchainReceiveResponse(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return OnchainReceiveResponse( - bech32=_UniffiConverterString.read(buf), - p2tr=_UniffiConverterString.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterString.check_lower(value.bech32) - _UniffiConverterString.check_lower(value.p2tr) - - @staticmethod - def write(value, buf): - _UniffiConverterString.write(value.bech32, buf) - _UniffiConverterString.write(value.p2tr, buf) - - -class OnchainSendResponse: - tx: "bytes" - txid: "bytes" - psbt: "str" - def __init__(self, *, tx: "bytes", txid: "bytes", psbt: "str"): - self.tx = tx - self.txid = txid - self.psbt = psbt - - def __str__(self): - return "OnchainSendResponse(tx={}, txid={}, psbt={})".format(self.tx, self.txid, self.psbt) - - def __eq__(self, other): - if self.tx != other.tx: - return False - if self.txid != other.txid: - return False - if self.psbt != other.psbt: - return False - return True - -class _UniffiConverterTypeOnchainSendResponse(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return OnchainSendResponse( - tx=_UniffiConverterBytes.read(buf), - txid=_UniffiConverterBytes.read(buf), - psbt=_UniffiConverterString.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterBytes.check_lower(value.tx) - _UniffiConverterBytes.check_lower(value.txid) - _UniffiConverterString.check_lower(value.psbt) - - @staticmethod - def write(value, buf): - _UniffiConverterBytes.write(value.tx, buf) - _UniffiConverterBytes.write(value.txid, buf) - _UniffiConverterString.write(value.psbt, buf) - - -class Peer: - id: "bytes" - connected: "bool" - num_channels: "typing.Optional[int]" - netaddr: "typing.List[str]" - remote_addr: "typing.Optional[str]" - features: "typing.Optional[bytes]" - def __init__(self, *, id: "bytes", connected: "bool", num_channels: "typing.Optional[int]", netaddr: "typing.List[str]", remote_addr: "typing.Optional[str]", features: "typing.Optional[bytes]"): - self.id = id - self.connected = connected - self.num_channels = num_channels - self.netaddr = netaddr - self.remote_addr = remote_addr - self.features = features - - def __str__(self): - return "Peer(id={}, connected={}, num_channels={}, netaddr={}, remote_addr={}, features={})".format(self.id, self.connected, self.num_channels, self.netaddr, self.remote_addr, self.features) - - def __eq__(self, other): - if self.id != other.id: - return False - if self.connected != other.connected: - return False - if self.num_channels != other.num_channels: - return False - if self.netaddr != other.netaddr: - return False - if self.remote_addr != other.remote_addr: - return False - if self.features != other.features: - return False - return True - -class _UniffiConverterTypePeer(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return Peer( - id=_UniffiConverterBytes.read(buf), - connected=_UniffiConverterBool.read(buf), - num_channels=_UniffiConverterOptionalUInt32.read(buf), - netaddr=_UniffiConverterSequenceString.read(buf), - remote_addr=_UniffiConverterOptionalString.read(buf), - features=_UniffiConverterOptionalBytes.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterBytes.check_lower(value.id) - _UniffiConverterBool.check_lower(value.connected) - _UniffiConverterOptionalUInt32.check_lower(value.num_channels) - _UniffiConverterSequenceString.check_lower(value.netaddr) - _UniffiConverterOptionalString.check_lower(value.remote_addr) - _UniffiConverterOptionalBytes.check_lower(value.features) - - @staticmethod - def write(value, buf): - _UniffiConverterBytes.write(value.id, buf) - _UniffiConverterBool.write(value.connected, buf) - _UniffiConverterOptionalUInt32.write(value.num_channels, buf) - _UniffiConverterSequenceString.write(value.netaddr, buf) - _UniffiConverterOptionalString.write(value.remote_addr, buf) - _UniffiConverterOptionalBytes.write(value.features, buf) - - -class PeerChannel: - peer_id: "bytes" - peer_connected: "bool" - state: "ChannelState" - short_channel_id: "typing.Optional[str]" - channel_id: "typing.Optional[bytes]" - funding_txid: "typing.Optional[bytes]" - funding_outnum: "typing.Optional[int]" - to_us_msat: "typing.Optional[int]" - total_msat: "typing.Optional[int]" - spendable_msat: "typing.Optional[int]" - receivable_msat: "typing.Optional[int]" - def __init__(self, *, peer_id: "bytes", peer_connected: "bool", state: "ChannelState", short_channel_id: "typing.Optional[str]", channel_id: "typing.Optional[bytes]", funding_txid: "typing.Optional[bytes]", funding_outnum: "typing.Optional[int]", to_us_msat: "typing.Optional[int]", total_msat: "typing.Optional[int]", spendable_msat: "typing.Optional[int]", receivable_msat: "typing.Optional[int]"): - self.peer_id = peer_id - self.peer_connected = peer_connected - self.state = state - self.short_channel_id = short_channel_id - self.channel_id = channel_id - self.funding_txid = funding_txid - self.funding_outnum = funding_outnum - self.to_us_msat = to_us_msat - self.total_msat = total_msat - self.spendable_msat = spendable_msat - self.receivable_msat = receivable_msat - - def __str__(self): - return "PeerChannel(peer_id={}, peer_connected={}, state={}, short_channel_id={}, channel_id={}, funding_txid={}, funding_outnum={}, to_us_msat={}, total_msat={}, spendable_msat={}, receivable_msat={})".format(self.peer_id, self.peer_connected, self.state, self.short_channel_id, self.channel_id, self.funding_txid, self.funding_outnum, self.to_us_msat, self.total_msat, self.spendable_msat, self.receivable_msat) - - def __eq__(self, other): - if self.peer_id != other.peer_id: - return False - if self.peer_connected != other.peer_connected: - return False - if self.state != other.state: - return False - if self.short_channel_id != other.short_channel_id: - return False - if self.channel_id != other.channel_id: - return False - if self.funding_txid != other.funding_txid: - return False - if self.funding_outnum != other.funding_outnum: - return False - if self.to_us_msat != other.to_us_msat: - return False - if self.total_msat != other.total_msat: - return False - if self.spendable_msat != other.spendable_msat: - return False - if self.receivable_msat != other.receivable_msat: - return False - return True - -class _UniffiConverterTypePeerChannel(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return PeerChannel( - peer_id=_UniffiConverterBytes.read(buf), - peer_connected=_UniffiConverterBool.read(buf), - state=_UniffiConverterTypeChannelState.read(buf), - short_channel_id=_UniffiConverterOptionalString.read(buf), - channel_id=_UniffiConverterOptionalBytes.read(buf), - funding_txid=_UniffiConverterOptionalBytes.read(buf), - funding_outnum=_UniffiConverterOptionalUInt32.read(buf), - to_us_msat=_UniffiConverterOptionalUInt64.read(buf), - total_msat=_UniffiConverterOptionalUInt64.read(buf), - spendable_msat=_UniffiConverterOptionalUInt64.read(buf), - receivable_msat=_UniffiConverterOptionalUInt64.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterBytes.check_lower(value.peer_id) - _UniffiConverterBool.check_lower(value.peer_connected) - _UniffiConverterTypeChannelState.check_lower(value.state) - _UniffiConverterOptionalString.check_lower(value.short_channel_id) - _UniffiConverterOptionalBytes.check_lower(value.channel_id) - _UniffiConverterOptionalBytes.check_lower(value.funding_txid) - _UniffiConverterOptionalUInt32.check_lower(value.funding_outnum) - _UniffiConverterOptionalUInt64.check_lower(value.to_us_msat) - _UniffiConverterOptionalUInt64.check_lower(value.total_msat) - _UniffiConverterOptionalUInt64.check_lower(value.spendable_msat) - _UniffiConverterOptionalUInt64.check_lower(value.receivable_msat) - - @staticmethod - def write(value, buf): - _UniffiConverterBytes.write(value.peer_id, buf) - _UniffiConverterBool.write(value.peer_connected, buf) - _UniffiConverterTypeChannelState.write(value.state, buf) - _UniffiConverterOptionalString.write(value.short_channel_id, buf) - _UniffiConverterOptionalBytes.write(value.channel_id, buf) - _UniffiConverterOptionalBytes.write(value.funding_txid, buf) - _UniffiConverterOptionalUInt32.write(value.funding_outnum, buf) - _UniffiConverterOptionalUInt64.write(value.to_us_msat, buf) - _UniffiConverterOptionalUInt64.write(value.total_msat, buf) - _UniffiConverterOptionalUInt64.write(value.spendable_msat, buf) - _UniffiConverterOptionalUInt64.write(value.receivable_msat, buf) - - -class ReceiveResponse: - bolt11: "str" - def __init__(self, *, bolt11: "str"): - self.bolt11 = bolt11 - - def __str__(self): - return "ReceiveResponse(bolt11={})".format(self.bolt11) - - def __eq__(self, other): - if self.bolt11 != other.bolt11: - return False - return True - -class _UniffiConverterTypeReceiveResponse(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return ReceiveResponse( - bolt11=_UniffiConverterString.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterString.check_lower(value.bolt11) - - @staticmethod - def write(value, buf): - _UniffiConverterString.write(value.bolt11, buf) - - -class SendResponse: - status: "PayStatus" - preimage: "bytes" - amount_msat: "int" - amount_sent_msat: "int" - parts: "int" - def __init__(self, *, status: "PayStatus", preimage: "bytes", amount_msat: "int", amount_sent_msat: "int", parts: "int"): - self.status = status - self.preimage = preimage - self.amount_msat = amount_msat - self.amount_sent_msat = amount_sent_msat - self.parts = parts - - def __str__(self): - return "SendResponse(status={}, preimage={}, amount_msat={}, amount_sent_msat={}, parts={})".format(self.status, self.preimage, self.amount_msat, self.amount_sent_msat, self.parts) - - def __eq__(self, other): - if self.status != other.status: - return False - if self.preimage != other.preimage: - return False - if self.amount_msat != other.amount_msat: - return False - if self.amount_sent_msat != other.amount_sent_msat: - return False - if self.parts != other.parts: - return False - return True - -class _UniffiConverterTypeSendResponse(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return SendResponse( - status=_UniffiConverterTypePayStatus.read(buf), - preimage=_UniffiConverterBytes.read(buf), - amount_msat=_UniffiConverterUInt64.read(buf), - amount_sent_msat=_UniffiConverterUInt64.read(buf), - parts=_UniffiConverterUInt32.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiConverterTypePayStatus.check_lower(value.status) - _UniffiConverterBytes.check_lower(value.preimage) - _UniffiConverterUInt64.check_lower(value.amount_msat) - _UniffiConverterUInt64.check_lower(value.amount_sent_msat) - _UniffiConverterUInt32.check_lower(value.parts) - - @staticmethod - def write(value, buf): - _UniffiConverterTypePayStatus.write(value.status, buf) - _UniffiConverterBytes.write(value.preimage, buf) - _UniffiConverterUInt64.write(value.amount_msat, buf) - _UniffiConverterUInt64.write(value.amount_sent_msat, buf) - _UniffiConverterUInt32.write(value.parts, buf) - - - - - -class ChannelState(enum.Enum): - OPENINGD = 0 - - CHANNELD_AWAITING_LOCKIN = 1 - - CHANNELD_NORMAL = 2 - - CHANNELD_SHUTTING_DOWN = 3 - - CLOSINGD_SIGEXCHANGE = 4 - - CLOSINGD_COMPLETE = 5 - - AWAITING_UNILATERAL = 6 - - FUNDING_SPEND_SEEN = 7 - - ONCHAIN = 8 - - DUALOPEND_OPEN_INIT = 9 - - DUALOPEND_AWAITING_LOCKIN = 10 - - DUALOPEND_OPEN_COMMITTED = 11 - - DUALOPEND_OPEN_COMMIT_READY = 12 - - - -class _UniffiConverterTypeChannelState(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - variant = buf.read_i32() - if variant == 1: - return ChannelState.OPENINGD - if variant == 2: - return ChannelState.CHANNELD_AWAITING_LOCKIN - if variant == 3: - return ChannelState.CHANNELD_NORMAL - if variant == 4: - return ChannelState.CHANNELD_SHUTTING_DOWN - if variant == 5: - return ChannelState.CLOSINGD_SIGEXCHANGE - if variant == 6: - return ChannelState.CLOSINGD_COMPLETE - if variant == 7: - return ChannelState.AWAITING_UNILATERAL - if variant == 8: - return ChannelState.FUNDING_SPEND_SEEN - if variant == 9: - return ChannelState.ONCHAIN - if variant == 10: - return ChannelState.DUALOPEND_OPEN_INIT - if variant == 11: - return ChannelState.DUALOPEND_AWAITING_LOCKIN - if variant == 12: - return ChannelState.DUALOPEND_OPEN_COMMITTED - if variant == 13: - return ChannelState.DUALOPEND_OPEN_COMMIT_READY - raise InternalError("Raw enum value doesn't match any cases") - - @staticmethod - def check_lower(value): - if value == ChannelState.OPENINGD: - return - if value == ChannelState.CHANNELD_AWAITING_LOCKIN: - return - if value == ChannelState.CHANNELD_NORMAL: - return - if value == ChannelState.CHANNELD_SHUTTING_DOWN: - return - if value == ChannelState.CLOSINGD_SIGEXCHANGE: - return - if value == ChannelState.CLOSINGD_COMPLETE: - return - if value == ChannelState.AWAITING_UNILATERAL: - return - if value == ChannelState.FUNDING_SPEND_SEEN: - return - if value == ChannelState.ONCHAIN: - return - if value == ChannelState.DUALOPEND_OPEN_INIT: - return - if value == ChannelState.DUALOPEND_AWAITING_LOCKIN: - return - if value == ChannelState.DUALOPEND_OPEN_COMMITTED: - return - if value == ChannelState.DUALOPEND_OPEN_COMMIT_READY: - return - raise ValueError(value) - - @staticmethod - def write(value, buf): - if value == ChannelState.OPENINGD: - buf.write_i32(1) - if value == ChannelState.CHANNELD_AWAITING_LOCKIN: - buf.write_i32(2) - if value == ChannelState.CHANNELD_NORMAL: - buf.write_i32(3) - if value == ChannelState.CHANNELD_SHUTTING_DOWN: - buf.write_i32(4) - if value == ChannelState.CLOSINGD_SIGEXCHANGE: - buf.write_i32(5) - if value == ChannelState.CLOSINGD_COMPLETE: - buf.write_i32(6) - if value == ChannelState.AWAITING_UNILATERAL: - buf.write_i32(7) - if value == ChannelState.FUNDING_SPEND_SEEN: - buf.write_i32(8) - if value == ChannelState.ONCHAIN: - buf.write_i32(9) - if value == ChannelState.DUALOPEND_OPEN_INIT: - buf.write_i32(10) - if value == ChannelState.DUALOPEND_AWAITING_LOCKIN: - buf.write_i32(11) - if value == ChannelState.DUALOPEND_OPEN_COMMITTED: - buf.write_i32(12) - if value == ChannelState.DUALOPEND_OPEN_COMMIT_READY: - buf.write_i32(13) - - - - -# Error -# We want to define each variant as a nested class that's also a subclass, -# which is tricky in Python. To accomplish this we're going to create each -# class separately, then manually add the child classes to the base class's -# __dict__. All of this happens in dummy class to avoid polluting the module -# namespace. -class Error(Exception): - pass - -_UniffiTempError = Error - -class Error: # type: ignore - class DuplicateNode(_UniffiTempError): - def __init__(self, *values): - if len(values) != 1: - raise TypeError(f"Expected 1 arguments, found {len(values)}") - if not isinstance(values[0], str): - raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") - super().__init__(", ".join(map(repr, values))) - self._values = values - - def __getitem__(self, index): - return self._values[index] - - def __repr__(self): - return "Error.DuplicateNode({})".format(str(self)) - _UniffiTempError.DuplicateNode = DuplicateNode # type: ignore - class NoSuchNode(_UniffiTempError): - def __init__(self, *values): - if len(values) != 1: - raise TypeError(f"Expected 1 arguments, found {len(values)}") - if not isinstance(values[0], str): - raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") - super().__init__(", ".join(map(repr, values))) - self._values = values - - def __getitem__(self, index): - return self._values[index] - - def __repr__(self): - return "Error.NoSuchNode({})".format(str(self)) - _UniffiTempError.NoSuchNode = NoSuchNode # type: ignore - class UnparseableCreds(_UniffiTempError): - def __init__(self): - pass - - def __repr__(self): - return "Error.UnparseableCreds({})".format(str(self)) - _UniffiTempError.UnparseableCreds = UnparseableCreds # type: ignore - class PhraseCorrupted(_UniffiTempError): - def __init__(self): - pass - - def __repr__(self): - return "Error.PhraseCorrupted({})".format(str(self)) - _UniffiTempError.PhraseCorrupted = PhraseCorrupted # type: ignore - class Rpc(_UniffiTempError): - def __init__(self, *values): - if len(values) != 1: - raise TypeError(f"Expected 1 arguments, found {len(values)}") - if not isinstance(values[0], str): - raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") - super().__init__(", ".join(map(repr, values))) - self._values = values - - def __getitem__(self, index): - return self._values[index] - - def __repr__(self): - return "Error.Rpc({})".format(str(self)) - _UniffiTempError.Rpc = Rpc # type: ignore - class Argument(_UniffiTempError): - def __init__(self, *values): - if len(values) != 2: - raise TypeError(f"Expected 2 arguments, found {len(values)}") - if not isinstance(values[0], str): - raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") - if not isinstance(values[1], str): - raise TypeError(f"unexpected type for tuple element 1 - expected 'str', got '{type(values[1])}'") - super().__init__(", ".join(map(repr, values))) - self._values = values - - def __getitem__(self, index): - return self._values[index] - - def __repr__(self): - return "Error.Argument({})".format(str(self)) - _UniffiTempError.Argument = Argument # type: ignore - class Other(_UniffiTempError): - def __init__(self, *values): - if len(values) != 1: - raise TypeError(f"Expected 1 arguments, found {len(values)}") - if not isinstance(values[0], str): - raise TypeError(f"unexpected type for tuple element 0 - expected 'str', got '{type(values[0])}'") - super().__init__(", ".join(map(repr, values))) - self._values = values - - def __getitem__(self, index): - return self._values[index] - - def __repr__(self): - return "Error.Other({})".format(str(self)) - _UniffiTempError.Other = Other # type: ignore - -Error = _UniffiTempError # type: ignore -del _UniffiTempError - - -class _UniffiConverterTypeError(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - variant = buf.read_i32() - if variant == 1: - return Error.DuplicateNode( - _UniffiConverterString.read(buf), - ) - if variant == 2: - return Error.NoSuchNode( - _UniffiConverterString.read(buf), - ) - if variant == 3: - return Error.UnparseableCreds( - ) - if variant == 4: - return Error.PhraseCorrupted( - ) - if variant == 5: - return Error.Rpc( - _UniffiConverterString.read(buf), - ) - if variant == 6: - return Error.Argument( - _UniffiConverterString.read(buf), - _UniffiConverterString.read(buf), - ) - if variant == 7: - return Error.Other( - _UniffiConverterString.read(buf), - ) - raise InternalError("Raw enum value doesn't match any cases") - - @staticmethod - def check_lower(value): - if isinstance(value, Error.DuplicateNode): - _UniffiConverterString.check_lower(value._values[0]) - return - if isinstance(value, Error.NoSuchNode): - _UniffiConverterString.check_lower(value._values[0]) - return - if isinstance(value, Error.UnparseableCreds): - return - if isinstance(value, Error.PhraseCorrupted): - return - if isinstance(value, Error.Rpc): - _UniffiConverterString.check_lower(value._values[0]) - return - if isinstance(value, Error.Argument): - _UniffiConverterString.check_lower(value._values[0]) - _UniffiConverterString.check_lower(value._values[1]) - return - if isinstance(value, Error.Other): - _UniffiConverterString.check_lower(value._values[0]) - return - - @staticmethod - def write(value, buf): - if isinstance(value, Error.DuplicateNode): - buf.write_i32(1) - _UniffiConverterString.write(value._values[0], buf) - if isinstance(value, Error.NoSuchNode): - buf.write_i32(2) - _UniffiConverterString.write(value._values[0], buf) - if isinstance(value, Error.UnparseableCreds): - buf.write_i32(3) - if isinstance(value, Error.PhraseCorrupted): - buf.write_i32(4) - if isinstance(value, Error.Rpc): - buf.write_i32(5) - _UniffiConverterString.write(value._values[0], buf) - if isinstance(value, Error.Argument): - buf.write_i32(6) - _UniffiConverterString.write(value._values[0], buf) - _UniffiConverterString.write(value._values[1], buf) - if isinstance(value, Error.Other): - buf.write_i32(7) - _UniffiConverterString.write(value._values[0], buf) - - - - - -class Network(enum.Enum): - BITCOIN = 0 - - REGTEST = 1 - - - -class _UniffiConverterTypeNetwork(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - variant = buf.read_i32() - if variant == 1: - return Network.BITCOIN - if variant == 2: - return Network.REGTEST - raise InternalError("Raw enum value doesn't match any cases") - - @staticmethod - def check_lower(value): - if value == Network.BITCOIN: - return - if value == Network.REGTEST: - return - raise ValueError(value) - - @staticmethod - def write(value, buf): - if value == Network.BITCOIN: - buf.write_i32(1) - if value == Network.REGTEST: - buf.write_i32(2) - - - - - - - -class NodeEvent: - """ - A real-time event from the node. - """ - - def __init__(self): - raise RuntimeError("NodeEvent cannot be instantiated directly") - - # Each enum variant is a nested class of the enum itself. - class INVOICE_PAID: - """ - An invoice was paid. - """ - - details: "InvoicePaidEvent" - - def __init__(self,details: "InvoicePaidEvent"): - self.details = details - - def __str__(self): - return "NodeEvent.INVOICE_PAID(details={})".format(self.details) - - def __eq__(self, other): - if not other.is_INVOICE_PAID(): - return False - if self.details != other.details: - return False - return True - - class UNKNOWN: - """ - An unknown event type was received. This can happen if the - server sends a new event type that this client doesn't know about. - """ - - - def __init__(self,): - pass - - def __str__(self): - return "NodeEvent.UNKNOWN()".format() - - def __eq__(self, other): - if not other.is_UNKNOWN(): - return False - return True - - - - # For each variant, we have `is_NAME` and `is_name` methods for easily checking - # whether an instance is that variant. - def is_INVOICE_PAID(self) -> bool: - return isinstance(self, NodeEvent.INVOICE_PAID) - def is_invoice_paid(self) -> bool: - return isinstance(self, NodeEvent.INVOICE_PAID) - def is_UNKNOWN(self) -> bool: - return isinstance(self, NodeEvent.UNKNOWN) - def is_unknown(self) -> bool: - return isinstance(self, NodeEvent.UNKNOWN) - - -# Now, a little trick - we make each nested variant class be a subclass of the main -# enum class, so that method calls and instance checks etc will work intuitively. -# We might be able to do this a little more neatly with a metaclass, but this'll do. -NodeEvent.INVOICE_PAID = type("NodeEvent.INVOICE_PAID", (NodeEvent.INVOICE_PAID, NodeEvent,), {}) # type: ignore -NodeEvent.UNKNOWN = type("NodeEvent.UNKNOWN", (NodeEvent.UNKNOWN, NodeEvent,), {}) # type: ignore - - - - -class _UniffiConverterTypeNodeEvent(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - variant = buf.read_i32() - if variant == 1: - return NodeEvent.INVOICE_PAID( - _UniffiConverterTypeInvoicePaidEvent.read(buf), - ) - if variant == 2: - return NodeEvent.UNKNOWN( - ) - raise InternalError("Raw enum value doesn't match any cases") - - @staticmethod - def check_lower(value): - if value.is_INVOICE_PAID(): - _UniffiConverterTypeInvoicePaidEvent.check_lower(value.details) - return - if value.is_UNKNOWN(): - return - raise ValueError(value) - - @staticmethod - def write(value, buf): - if value.is_INVOICE_PAID(): - buf.write_i32(1) - _UniffiConverterTypeInvoicePaidEvent.write(value.details, buf) - if value.is_UNKNOWN(): - buf.write_i32(2) - - - - - - - -class OutputStatus(enum.Enum): - UNCONFIRMED = 0 - - CONFIRMED = 1 - - SPENT = 2 - - IMMATURE = 3 - - - -class _UniffiConverterTypeOutputStatus(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - variant = buf.read_i32() - if variant == 1: - return OutputStatus.UNCONFIRMED - if variant == 2: - return OutputStatus.CONFIRMED - if variant == 3: - return OutputStatus.SPENT - if variant == 4: - return OutputStatus.IMMATURE - raise InternalError("Raw enum value doesn't match any cases") - - @staticmethod - def check_lower(value): - if value == OutputStatus.UNCONFIRMED: - return - if value == OutputStatus.CONFIRMED: - return - if value == OutputStatus.SPENT: - return - if value == OutputStatus.IMMATURE: - return - raise ValueError(value) - - @staticmethod - def write(value, buf): - if value == OutputStatus.UNCONFIRMED: - buf.write_i32(1) - if value == OutputStatus.CONFIRMED: - buf.write_i32(2) - if value == OutputStatus.SPENT: - buf.write_i32(3) - if value == OutputStatus.IMMATURE: - buf.write_i32(4) - - - - - - - -class PayStatus(enum.Enum): - COMPLETE = 0 - - PENDING = 1 - - FAILED = 2 - - - -class _UniffiConverterTypePayStatus(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - variant = buf.read_i32() - if variant == 1: - return PayStatus.COMPLETE - if variant == 2: - return PayStatus.PENDING - if variant == 3: - return PayStatus.FAILED - raise InternalError("Raw enum value doesn't match any cases") - - @staticmethod - def check_lower(value): - if value == PayStatus.COMPLETE: - return - if value == PayStatus.PENDING: - return - if value == PayStatus.FAILED: - return - raise ValueError(value) - - @staticmethod - def write(value, buf): - if value == PayStatus.COMPLETE: - buf.write_i32(1) - if value == PayStatus.PENDING: - buf.write_i32(2) - if value == PayStatus.FAILED: - buf.write_i32(3) - - - - - -class _UniffiConverterOptionalUInt32(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - if value is not None: - _UniffiConverterUInt32.check_lower(value) - - @classmethod - def write(cls, value, buf): - if value is None: - buf.write_u8(0) - return - - buf.write_u8(1) - _UniffiConverterUInt32.write(value, buf) - - @classmethod - def read(cls, buf): - flag = buf.read_u8() - if flag == 0: - return None - elif flag == 1: - return _UniffiConverterUInt32.read(buf) - else: - raise InternalError("Unexpected flag byte for optional type") - - - -class _UniffiConverterOptionalUInt64(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - if value is not None: - _UniffiConverterUInt64.check_lower(value) - - @classmethod - def write(cls, value, buf): - if value is None: - buf.write_u8(0) - return - - buf.write_u8(1) - _UniffiConverterUInt64.write(value, buf) - - @classmethod - def read(cls, buf): - flag = buf.read_u8() - if flag == 0: - return None - elif flag == 1: - return _UniffiConverterUInt64.read(buf) - else: - raise InternalError("Unexpected flag byte for optional type") - - - -class _UniffiConverterOptionalString(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - if value is not None: - _UniffiConverterString.check_lower(value) - - @classmethod - def write(cls, value, buf): - if value is None: - buf.write_u8(0) - return - - buf.write_u8(1) - _UniffiConverterString.write(value, buf) - - @classmethod - def read(cls, buf): - flag = buf.read_u8() - if flag == 0: - return None - elif flag == 1: - return _UniffiConverterString.read(buf) - else: - raise InternalError("Unexpected flag byte for optional type") - - - -class _UniffiConverterOptionalBytes(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - if value is not None: - _UniffiConverterBytes.check_lower(value) - - @classmethod - def write(cls, value, buf): - if value is None: - buf.write_u8(0) - return - - buf.write_u8(1) - _UniffiConverterBytes.write(value, buf) - - @classmethod - def read(cls, buf): - flag = buf.read_u8() - if flag == 0: - return None - elif flag == 1: - return _UniffiConverterBytes.read(buf) - else: - raise InternalError("Unexpected flag byte for optional type") - - - -class _UniffiConverterOptionalTypeNodeEvent(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - if value is not None: - _UniffiConverterTypeNodeEvent.check_lower(value) - - @classmethod - def write(cls, value, buf): - if value is None: - buf.write_u8(0) - return - - buf.write_u8(1) - _UniffiConverterTypeNodeEvent.write(value, buf) - - @classmethod - def read(cls, buf): - flag = buf.read_u8() - if flag == 0: - return None - elif flag == 1: - return _UniffiConverterTypeNodeEvent.read(buf) - else: - raise InternalError("Unexpected flag byte for optional type") - - - -class _UniffiConverterSequenceString(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - for item in value: - _UniffiConverterString.check_lower(item) - - @classmethod - def write(cls, value, buf): - items = len(value) - buf.write_i32(items) - for item in value: - _UniffiConverterString.write(item, buf) - - @classmethod - def read(cls, buf): - count = buf.read_i32() - if count < 0: - raise InternalError("Unexpected negative sequence length") - - return [ - _UniffiConverterString.read(buf) for i in range(count) - ] - - - -class _UniffiConverterSequenceTypeFundChannel(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - for item in value: - _UniffiConverterTypeFundChannel.check_lower(item) - - @classmethod - def write(cls, value, buf): - items = len(value) - buf.write_i32(items) - for item in value: - _UniffiConverterTypeFundChannel.write(item, buf) - - @classmethod - def read(cls, buf): - count = buf.read_i32() - if count < 0: - raise InternalError("Unexpected negative sequence length") - - return [ - _UniffiConverterTypeFundChannel.read(buf) for i in range(count) - ] - - - -class _UniffiConverterSequenceTypeFundOutput(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - for item in value: - _UniffiConverterTypeFundOutput.check_lower(item) - - @classmethod - def write(cls, value, buf): - items = len(value) - buf.write_i32(items) - for item in value: - _UniffiConverterTypeFundOutput.write(item, buf) - - @classmethod - def read(cls, buf): - count = buf.read_i32() - if count < 0: - raise InternalError("Unexpected negative sequence length") - - return [ - _UniffiConverterTypeFundOutput.read(buf) for i in range(count) - ] - - - -class _UniffiConverterSequenceTypePeer(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - for item in value: - _UniffiConverterTypePeer.check_lower(item) - - @classmethod - def write(cls, value, buf): - items = len(value) - buf.write_i32(items) - for item in value: - _UniffiConverterTypePeer.write(item, buf) - - @classmethod - def read(cls, buf): - count = buf.read_i32() - if count < 0: - raise InternalError("Unexpected negative sequence length") - - return [ - _UniffiConverterTypePeer.read(buf) for i in range(count) - ] - - - -class _UniffiConverterSequenceTypePeerChannel(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - for item in value: - _UniffiConverterTypePeerChannel.check_lower(item) - - @classmethod - def write(cls, value, buf): - items = len(value) - buf.write_i32(items) - for item in value: - _UniffiConverterTypePeerChannel.write(item, buf) - - @classmethod - def read(cls, buf): - count = buf.read_i32() - if count < 0: - raise InternalError("Unexpected negative sequence length") - - return [ - _UniffiConverterTypePeerChannel.read(buf) for i in range(count) - ] - -# objects. -class CredentialsProtocol(typing.Protocol): - """ - `Credentials` is a container for `node_id`, the mTLS client - certificate used to authenticate a client against a node, as well - as the seed secret if present. If no seed is present in the - credentials, then the `Client` will not start a signer in the - background. - """ - - def save(self, ): - raise NotImplementedError -# Credentials is a Rust-only trait - it's a wrapper around a Rust implementation. -class Credentials(): - """ - `Credentials` is a container for `node_id`, the mTLS client - certificate used to authenticate a client against a node, as well - as the seed secret if present. If no seed is present in the - credentials, then the `Client` will not start a signer in the - background. - """ - - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_credentials, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_credentials, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - @classmethod - def load(cls, raw: "bytes"): - _UniffiConverterBytes.check_lower(raw) - - # Call the (fallible) function before creating any half-baked object instances. - pointer = _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_constructor_credentials_load, - _UniffiConverterBytes.lower(raw)) - return cls._make_instance_(pointer) - - - - def save(self, ) -> "bytes": - return _UniffiConverterBytes.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_credentials_save,self._uniffi_clone_pointer(),) - ) - - - - - - -class _UniffiConverterTypeCredentials: - - @staticmethod - def lift(value: int): - return Credentials._make_instance_(value) - - @staticmethod - def check_lower(value: Credentials): - if not isinstance(value, Credentials): - raise TypeError("Expected Credentials instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: CredentialsProtocol): - if not isinstance(value, Credentials): - raise TypeError("Expected Credentials instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: CredentialsProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) -class HandleProtocol(typing.Protocol): - """ - A handle to interact with a signer loop running and processing - requests in the background. Used primarily to stop the loop and - exiting the signer. - """ - - def stop(self, ): - raise NotImplementedError -# Handle is a Rust-only trait - it's a wrapper around a Rust implementation. -class Handle(): - """ - A handle to interact with a signer loop running and processing - requests in the background. Used primarily to stop the loop and - exiting the signer. - """ - - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_handle, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_handle, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - def stop(self, ) -> None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_method_handle_stop,self._uniffi_clone_pointer(),) - - - - - - - -class _UniffiConverterTypeHandle: - - @staticmethod - def lift(value: int): - return Handle._make_instance_(value) - - @staticmethod - def check_lower(value: Handle): - if not isinstance(value, Handle): - raise TypeError("Expected Handle instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: HandleProtocol): - if not isinstance(value, Handle): - raise TypeError("Expected Handle instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: HandleProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) -class NodeProtocol(typing.Protocol): - """ - The `Node` is an RPC stub representing the node running in the - cloud. It is the main entrypoint to interact with the node. - """ - - def get_info(self, ): - """ - Get information about the node. - - Returns basic information about the node including its ID, - alias, network, and channel counts. - """ - - raise NotImplementedError - def list_funds(self, ): - """ - List all funds available to the node. - - Returns information about on-chain outputs and channel funds - that are available or pending. - """ - - raise NotImplementedError - def list_peer_channels(self, ): - """ - List all channels with peers. - - Returns detailed information about all channels including their - state, capacity, and balances. - """ - - raise NotImplementedError - def list_peers(self, ): - """ - List all peers connected to this node. - - Returns information about all peers including their connection - status. - """ - - raise NotImplementedError - def onchain_receive(self, ): - raise NotImplementedError - def onchain_send(self, destination: "str",amount_or_all: "str"): - raise NotImplementedError - def receive(self, label: "str",description: "str",amount_msat: "typing.Optional[int]"): - """ - Receive an off-chain payment. - - This method generates a request for a payment, also called an - invoice, that encodes all the information, including amount - and destination, for a prospective sender to send a lightning - payment. The invoice includes negotiation of an LSPS2 / JIT - channel, meaning that if there is no channel sufficient to - receive the requested funds, the node will negotiate an - opening, and when/if executed the payment will cause a channel - to be created, and the incoming payment to be forwarded. - """ - - raise NotImplementedError - def send(self, invoice: "str",amount_msat: "typing.Optional[int]"): - raise NotImplementedError - def stop(self, ): - """ - Stop the node if it is currently running. - """ - - raise NotImplementedError - def stream_node_events(self, ): - """ - Stream real-time events from the node. - - Returns a `NodeEventStream` iterator. Call `next()` repeatedly - to receive events as they occur (e.g., invoice payments). - - The `next()` method blocks the calling thread until an event - is available, but does not block the underlying async runtime, - so other node methods can be called concurrently from other - threads. - """ - - raise NotImplementedError -# Node is a Rust-only trait - it's a wrapper around a Rust implementation. -class Node(): - """ - The `Node` is an RPC stub representing the node running in the - cloud. It is the main entrypoint to interact with the node. - """ - - _pointer: ctypes.c_void_p - def __init__(self, credentials: "Credentials"): - _UniffiConverterTypeCredentials.check_lower(credentials) - - self._pointer = _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_constructor_node_new, - _UniffiConverterTypeCredentials.lower(credentials)) - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_node, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_node, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - def get_info(self, ) -> "GetInfoResponse": - """ - Get information about the node. - - Returns basic information about the node including its ID, - alias, network, and channel counts. - """ - - return _UniffiConverterTypeGetInfoResponse.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_get_info,self._uniffi_clone_pointer(),) - ) - - - - - - def list_funds(self, ) -> "ListFundsResponse": - """ - List all funds available to the node. - - Returns information about on-chain outputs and channel funds - that are available or pending. - """ - - return _UniffiConverterTypeListFundsResponse.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_list_funds,self._uniffi_clone_pointer(),) - ) - - - - - - def list_peer_channels(self, ) -> "ListPeerChannelsResponse": - """ - List all channels with peers. - - Returns detailed information about all channels including their - state, capacity, and balances. - """ - - return _UniffiConverterTypeListPeerChannelsResponse.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_list_peer_channels,self._uniffi_clone_pointer(),) - ) - - - - - - def list_peers(self, ) -> "ListPeersResponse": - """ - List all peers connected to this node. - - Returns information about all peers including their connection - status. - """ - - return _UniffiConverterTypeListPeersResponse.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_list_peers,self._uniffi_clone_pointer(),) - ) - - - - - - def onchain_receive(self, ) -> "OnchainReceiveResponse": - return _UniffiConverterTypeOnchainReceiveResponse.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_onchain_receive,self._uniffi_clone_pointer(),) - ) - - - - - - def onchain_send(self, destination: "str",amount_or_all: "str") -> "OnchainSendResponse": - _UniffiConverterString.check_lower(destination) - - _UniffiConverterString.check_lower(amount_or_all) - - return _UniffiConverterTypeOnchainSendResponse.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_onchain_send,self._uniffi_clone_pointer(), - _UniffiConverterString.lower(destination), - _UniffiConverterString.lower(amount_or_all)) - ) - - - - - - def receive(self, label: "str",description: "str",amount_msat: "typing.Optional[int]") -> "ReceiveResponse": - """ - Receive an off-chain payment. - - This method generates a request for a payment, also called an - invoice, that encodes all the information, including amount - and destination, for a prospective sender to send a lightning - payment. The invoice includes negotiation of an LSPS2 / JIT - channel, meaning that if there is no channel sufficient to - receive the requested funds, the node will negotiate an - opening, and when/if executed the payment will cause a channel - to be created, and the incoming payment to be forwarded. - """ - - _UniffiConverterString.check_lower(label) - - _UniffiConverterString.check_lower(description) - - _UniffiConverterOptionalUInt64.check_lower(amount_msat) - - return _UniffiConverterTypeReceiveResponse.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_receive,self._uniffi_clone_pointer(), - _UniffiConverterString.lower(label), - _UniffiConverterString.lower(description), - _UniffiConverterOptionalUInt64.lower(amount_msat)) - ) - - - - - - def send(self, invoice: "str",amount_msat: "typing.Optional[int]") -> "SendResponse": - _UniffiConverterString.check_lower(invoice) - - _UniffiConverterOptionalUInt64.check_lower(amount_msat) - - return _UniffiConverterTypeSendResponse.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_send,self._uniffi_clone_pointer(), - _UniffiConverterString.lower(invoice), - _UniffiConverterOptionalUInt64.lower(amount_msat)) - ) - - - - - - def stop(self, ) -> None: - """ - Stop the node if it is currently running. - """ - - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_stop,self._uniffi_clone_pointer(),) - - - - - - - def stream_node_events(self, ) -> "NodeEventStream": - """ - Stream real-time events from the node. - - Returns a `NodeEventStream` iterator. Call `next()` repeatedly - to receive events as they occur (e.g., invoice payments). - - The `next()` method blocks the calling thread until an event - is available, but does not block the underlying async runtime, - so other node methods can be called concurrently from other - threads. - """ - - return _UniffiConverterTypeNodeEventStream.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_node_stream_node_events,self._uniffi_clone_pointer(),) - ) - - - - - - -class _UniffiConverterTypeNode: - - @staticmethod - def lift(value: int): - return Node._make_instance_(value) - - @staticmethod - def check_lower(value: Node): - if not isinstance(value, Node): - raise TypeError("Expected Node instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: NodeProtocol): - if not isinstance(value, Node): - raise TypeError("Expected Node instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: NodeProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) -class NodeEventStreamProtocol(typing.Protocol): - """ - A stream of node events. Call `next()` to receive the next event. - - The stream is backed by a gRPC streaming connection to the node. - Each call to `next()` blocks the calling thread until an event is - available, but does not block the tokio runtime - other node - operations can proceed concurrently from other threads. - """ - - def next(self, ): - """ - Get the next event from the stream. - - Blocks the calling thread until an event is available or the - stream ends. Returns `None` when the stream is exhausted or - the connection is lost. - """ - - raise NotImplementedError -# NodeEventStream is a Rust-only trait - it's a wrapper around a Rust implementation. -class NodeEventStream(): - """ - A stream of node events. Call `next()` to receive the next event. - - The stream is backed by a gRPC streaming connection to the node. - Each call to `next()` blocks the calling thread until an event is - available, but does not block the tokio runtime - other node - operations can proceed concurrently from other threads. - """ - - _pointer: ctypes.c_void_p - - def __init__(self, *args, **kwargs): - raise ValueError("This class has no default constructor") - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_nodeeventstream, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_nodeeventstream, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - def next(self, ) -> "typing.Optional[NodeEvent]": - """ - Get the next event from the stream. - - Blocks the calling thread until an event is available or the - stream ends. Returns `None` when the stream is exhausted or - the connection is lost. - """ - - return _UniffiConverterOptionalTypeNodeEvent.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_nodeeventstream_next,self._uniffi_clone_pointer(),) - ) - - - - - - -class _UniffiConverterTypeNodeEventStream: - - @staticmethod - def lift(value: int): - return NodeEventStream._make_instance_(value) - - @staticmethod - def check_lower(value: NodeEventStream): - if not isinstance(value, NodeEventStream): - raise TypeError("Expected NodeEventStream instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: NodeEventStreamProtocol): - if not isinstance(value, NodeEventStream): - raise TypeError("Expected NodeEventStream instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: NodeEventStreamProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) -class SchedulerProtocol(typing.Protocol): - def recover(self, signer: "Signer"): - raise NotImplementedError - def register(self, signer: "Signer",code: "typing.Optional[str]"): - raise NotImplementedError -# Scheduler is a Rust-only trait - it's a wrapper around a Rust implementation. -class Scheduler(): - _pointer: ctypes.c_void_p - def __init__(self, network: "Network"): - """ - Create a `Scheduler` instance configured with the Greenlight - production service pre-configured. - """ - - _UniffiConverterTypeNetwork.check_lower(network) - - self._pointer = _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_constructor_scheduler_new, - _UniffiConverterTypeNetwork.lower(network)) - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_scheduler, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_scheduler, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - def recover(self, signer: "Signer") -> "Credentials": - _UniffiConverterTypeSigner.check_lower(signer) - - return _UniffiConverterTypeCredentials.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_scheduler_recover,self._uniffi_clone_pointer(), - _UniffiConverterTypeSigner.lower(signer)) - ) - - - - - - def register(self, signer: "Signer",code: "typing.Optional[str]") -> "Credentials": - _UniffiConverterTypeSigner.check_lower(signer) - - _UniffiConverterOptionalString.check_lower(code) - - return _UniffiConverterTypeCredentials.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_scheduler_register,self._uniffi_clone_pointer(), - _UniffiConverterTypeSigner.lower(signer), - _UniffiConverterOptionalString.lower(code)) - ) - - - - - - -class _UniffiConverterTypeScheduler: - - @staticmethod - def lift(value: int): - return Scheduler._make_instance_(value) - - @staticmethod - def check_lower(value: Scheduler): - if not isinstance(value, Scheduler): - raise TypeError("Expected Scheduler instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: SchedulerProtocol): - if not isinstance(value, Scheduler): - raise TypeError("Expected Scheduler instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: SchedulerProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) -class SignerProtocol(typing.Protocol): - def authenticate(self, creds: "Credentials"): - raise NotImplementedError - def node_id(self, ): - raise NotImplementedError - def start(self, ): - raise NotImplementedError -# Signer is a Rust-only trait - it's a wrapper around a Rust implementation. -class Signer(): - _pointer: ctypes.c_void_p - def __init__(self, phrase: "str"): - _UniffiConverterString.check_lower(phrase) - - self._pointer = _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_constructor_signer_new, - _UniffiConverterString.lower(phrase)) - - def __del__(self): - # In case of partial initialization of instances. - pointer = getattr(self, "_pointer", None) - if pointer is not None: - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_free_signer, pointer) - - def _uniffi_clone_pointer(self): - return _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_clone_signer, self._pointer) - - # Used by alternative constructors or any methods which return this type. - @classmethod - def _make_instance_(cls, pointer): - # Lightly yucky way to bypass the usual __init__ logic - # and just create a new instance with the required pointer. - inst = cls.__new__(cls) - inst._pointer = pointer - return inst - - - def authenticate(self, creds: "Credentials") -> "Signer": - _UniffiConverterTypeCredentials.check_lower(creds) - - return _UniffiConverterTypeSigner.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_signer_authenticate,self._uniffi_clone_pointer(), - _UniffiConverterTypeCredentials.lower(creds)) - ) - - - - - - def node_id(self, ) -> "bytes": - return _UniffiConverterBytes.lift( - _uniffi_rust_call(_UniffiLib.uniffi_glsdk_fn_method_signer_node_id,self._uniffi_clone_pointer(),) - ) - - - - - - def start(self, ) -> "Handle": - return _UniffiConverterTypeHandle.lift( - _uniffi_rust_call_with_error(_UniffiConverterTypeError,_UniffiLib.uniffi_glsdk_fn_method_signer_start,self._uniffi_clone_pointer(),) - ) - - - - - - -class _UniffiConverterTypeSigner: - - @staticmethod - def lift(value: int): - return Signer._make_instance_(value) - - @staticmethod - def check_lower(value: Signer): - if not isinstance(value, Signer): - raise TypeError("Expected Signer instance, {} found".format(type(value).__name__)) - - @staticmethod - def lower(value: SignerProtocol): - if not isinstance(value, Signer): - raise TypeError("Expected Signer instance, {} found".format(type(value).__name__)) - return value._uniffi_clone_pointer() - - @classmethod - def read(cls, buf: _UniffiRustBuffer): - ptr = buf.read_u64() - if ptr == 0: - raise InternalError("Raw pointer value was null") - return cls.lift(ptr) - - @classmethod - def write(cls, value: SignerProtocol, buf: _UniffiRustBuffer): - buf.write_u64(cls.lower(value)) - -# Async support - -__all__ = [ - "InternalError", - "ChannelState", - "Error", - "Network", - "NodeEvent", - "OutputStatus", - "PayStatus", - "FundChannel", - "FundOutput", - "GetInfoResponse", - "InvoicePaidEvent", - "ListFundsResponse", - "ListPeerChannelsResponse", - "ListPeersResponse", - "OnchainReceiveResponse", - "OnchainSendResponse", - "Peer", - "PeerChannel", - "ReceiveResponse", - "SendResponse", - "Credentials", - "Handle", - "Node", - "NodeEventStream", - "Scheduler", - "Signer", -] - From 63a2ec412bb991d6c221d331c123b74bd4c7e68d Mon Sep 17 00:00:00 2001 From: ShahanaFarooqui Date: Mon, 23 Feb 2026 13:13:10 -0800 Subject: [PATCH 16/16] gl-sdk: Expose methods and struct fields publicly Make the new query methods and related struct fields public so downstream crates like `gl-sdk-napi` can access them directly from Rust, rather than only through UniFFI bindings. --- libs/gl-sdk/src/node.rs | 72 ++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/libs/gl-sdk/src/node.rs b/libs/gl-sdk/src/node.rs index 11eb69304..0fb679c48 100644 --- a/libs/gl-sdk/src/node.rs +++ b/libs/gl-sdk/src/node.rs @@ -174,7 +174,7 @@ impl Node { /// /// Returns basic information about the node including its ID, /// alias, network, and channel counts. - fn get_info(&self) -> Result { + pub fn get_info(&self) -> Result { let mut cln_client = exec(self.get_cln_client())?.clone(); let req = clnpb::GetinfoRequest {}; @@ -189,7 +189,7 @@ impl Node { /// /// Returns information about all peers including their connection /// status. - fn list_peers(&self) -> Result { + pub fn list_peers(&self) -> Result { let mut cln_client = exec(self.get_cln_client())?.clone(); let req = clnpb::ListpeersRequest { @@ -207,7 +207,7 @@ impl Node { /// /// Returns detailed information about all channels including their /// state, capacity, and balances. - fn list_peer_channels(&self) -> Result { + pub fn list_peer_channels(&self) -> Result { let mut cln_client = exec(self.get_cln_client())?.clone(); let req = clnpb::ListpeerchannelsRequest { id: None }; @@ -222,7 +222,7 @@ impl Node { /// /// Returns information about on-chain outputs and channel funds /// that are available or pending. - fn list_funds(&self) -> Result { + pub fn list_funds(&self) -> Result { let mut cln_client = exec(self.get_cln_client())?.clone(); let req = clnpb::ListfundsRequest { spent: None }; @@ -415,12 +415,12 @@ pub struct ListPeersResponse { #[allow(unused)] #[derive(Clone, uniffi::Record)] pub struct Peer { - id: Vec, - connected: bool, - num_channels: Option, - netaddr: Vec, - remote_addr: Option, - features: Option>, + pub id: Vec, + pub connected: bool, + pub num_channels: Option, + pub netaddr: Vec, + pub remote_addr: Option, + pub features: Option>, } impl From for ListPeersResponse { @@ -459,17 +459,17 @@ pub struct ListPeerChannelsResponse { #[allow(unused)] #[derive(Clone, uniffi::Record)] pub struct PeerChannel { - peer_id: Vec, - peer_connected: bool, - state: ChannelState, - short_channel_id: Option, - channel_id: Option>, - funding_txid: Option>, - funding_outnum: Option, - to_us_msat: Option, - total_msat: Option, - spendable_msat: Option, - receivable_msat: Option, + pub peer_id: Vec, + pub peer_connected: bool, + pub state: ChannelState, + pub short_channel_id: Option, + pub channel_id: Option>, + pub funding_txid: Option>, + pub funding_outnum: Option, + pub to_us_msat: Option, + pub total_msat: Option, + pub spendable_msat: Option, + pub receivable_msat: Option, } #[derive(Clone, uniffi::Enum)] @@ -553,12 +553,12 @@ pub struct ListFundsResponse { #[allow(unused)] #[derive(Clone, uniffi::Record)] pub struct FundOutput { - txid: Vec, - output: u32, - amount_msat: u64, - status: OutputStatus, - address: Option, - blockheight: Option, + pub txid: Vec, + pub output: u32, + pub amount_msat: u64, + pub status: OutputStatus, + pub address: Option, + pub blockheight: Option, } #[derive(Clone, uniffi::Enum)] @@ -584,15 +584,15 @@ impl OutputStatus { #[allow(unused)] #[derive(Clone, uniffi::Record)] pub struct FundChannel { - peer_id: Vec, - our_amount_msat: u64, - amount_msat: u64, - funding_txid: Vec, - funding_output: u32, - connected: bool, - state: ChannelState, - short_channel_id: Option, - channel_id: Option>, + pub peer_id: Vec, + pub our_amount_msat: u64, + pub amount_msat: u64, + pub funding_txid: Vec, + pub funding_output: u32, + pub connected: bool, + pub state: ChannelState, + pub short_channel_id: Option, + pub channel_id: Option>, } impl From for ListFundsResponse {