Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/api-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,22 @@ a channel just-in-time when the invoice is paid.
| RPC | Description |
|--------------------------|-------------------------------------------------------------------------|
| `Bolt12Receive` | Create a BOLT12 offer (fixed or variable amount) |
| `Bolt12ReceiveAsync` | Retrieve the offer for receiving while this node is offline |
| `Bolt12SetPathsToStaticInvoiceServer` | Configure serialized blinded paths to a static invoice server |
| `Bolt12BlindedPathsForAsyncRecipient` | Create serialized blinded paths for an async recipient |
| `Bolt12Send` | Pay a BOLT12 offer (with optional quantity, payer note, routing config) |
| `Bolt12SendRefund` | Create a BOLT12 refund that this node will pay |
| `Bolt12ReceiveRefund` | Request an incoming payment for a BOLT12 refund |
| `Bolt12CreatePayerProof` | Create a BOLT 12 payer proof from a successful payment |

Async receive is experimental. `Bolt12ReceiveAsync` and `Bolt12SetPathsToStaticInvoiceServer`
require the node's async-payments role to be set to `Client`; configure paths to a static
invoice server before requesting an offer. `Bolt12ReceiveAsync` returns an offer only after the
static invoice server has successfully completed building its static invoice.
`Bolt12BlindedPathsForAsyncRecipient` requires the role to be set to `Server`.
The blinded path fields use LDK's lightning serialization for `Vec<BlindedMessagePath>`; the CLI
accepts and returns these byte values as hex, while gRPC transports them as bytes.

### Spontaneous and Unified Send

| RPC | Description |
Expand Down
72 changes: 59 additions & 13 deletions ldk-server-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,24 @@ use ldk_server_client::ldk_server_grpc::api::{
Bolt11ReceiveViaJitChannelForHashResponse, Bolt11ReceiveViaJitChannelRequest,
Bolt11ReceiveViaJitChannelResponse, Bolt11SendProbesRequest, Bolt11SendProbesResponse,
Bolt11SendRequest, Bolt11SendResponse, Bolt11SendUnderpayingRequest,
Bolt11SendUnderpayingResponse, Bolt12CreatePayerProofRequest, Bolt12CreatePayerProofResponse,
Bolt11SendUnderpayingResponse, Bolt12BlindedPathsForAsyncRecipientRequest,
Bolt12BlindedPathsForAsyncRecipientResponse, Bolt12CreatePayerProofRequest,
Bolt12CreatePayerProofResponse, Bolt12ReceiveAsyncRequest, Bolt12ReceiveAsyncResponse,
Bolt12ReceiveRefundRequest, Bolt12ReceiveRefundResponse, Bolt12ReceiveRequest,
Bolt12ReceiveResponse, Bolt12SendRefundRequest, Bolt12SendRefundResponse, Bolt12SendRequest,
Bolt12SendResponse, BumpChannelFundingFeeRequest, BumpChannelFundingFeeResponse,
CloseChannelRequest, CloseChannelResponse, ConnectPeerRequest, ConnectPeerResponse,
CreateMacaroonRequest, CreateMacaroonResponse, DecodeInvoiceRequest, DecodeInvoiceResponse,
DecodeOfferRequest, DecodeOfferResponse, DisconnectPeerRequest, DisconnectPeerResponse,
ExportPathfindingScoresRequest, ForceCloseChannelRequest, ForceCloseChannelResponse,
GetBalancesRequest, GetBalancesResponse, GetChannelForwardingStatsRequest,
GetChannelForwardingStatsResponse, GetForwardedPaymentDetailsRequest,
GetForwardedPaymentDetailsResponse, GetForwardedPaymentTrackingModeRequest,
GetForwardedPaymentTrackingModeResponse, GetNodeInfoRequest, GetNodeInfoResponse,
GetPaymentDetailsRequest, GetPaymentDetailsResponse, GetPermissionsRequest,
GetPermissionsResponse, GraphGetChannelRequest, GraphGetChannelResponse, GraphGetNodeRequest,
GraphGetNodeResponse, GraphListChannelsRequest, GraphListChannelsResponse,
Bolt12SendResponse, Bolt12SetPathsToStaticInvoiceServerRequest,
Bolt12SetPathsToStaticInvoiceServerResponse, BumpChannelFundingFeeRequest,
BumpChannelFundingFeeResponse, CloseChannelRequest, CloseChannelResponse, ConnectPeerRequest,
ConnectPeerResponse, CreateMacaroonRequest, CreateMacaroonResponse, DecodeInvoiceRequest,
DecodeInvoiceResponse, DecodeOfferRequest, DecodeOfferResponse, DisconnectPeerRequest,
DisconnectPeerResponse, ExportPathfindingScoresRequest, ForceCloseChannelRequest,
ForceCloseChannelResponse, GetBalancesRequest, GetBalancesResponse,
GetChannelForwardingStatsRequest, GetChannelForwardingStatsResponse,
GetForwardedPaymentDetailsRequest, GetForwardedPaymentDetailsResponse,
GetForwardedPaymentTrackingModeRequest, GetForwardedPaymentTrackingModeResponse,
GetNodeInfoRequest, GetNodeInfoResponse, GetPaymentDetailsRequest, GetPaymentDetailsResponse,
GetPermissionsRequest, GetPermissionsResponse, GraphGetChannelRequest, GraphGetChannelResponse,
GraphGetNodeRequest, GraphGetNodeResponse, GraphListChannelsRequest, GraphListChannelsResponse,
GraphListNodesRequest, GraphListNodesResponse, ListChannelForwardingStatsRequest,
ListChannelPairForwardingStatsRequest, ListChannelsRequest, ListChannelsResponse,
ListForwardedPaymentsRequest, ListMacaroonsRequest, ListMacaroonsResponse, ListPaymentsRequest,
Expand Down Expand Up @@ -385,6 +388,18 @@ enum Commands {
)]
quantity: Option<u64>,
},
#[command(about = "Retrieve the BOLT12 offer for receiving while this node is offline")]
Bolt12ReceiveAsync,
#[command(about = "Set serialized blinded message paths for the static invoice server")]
Bolt12SetPathsToStaticInvoiceServer {
#[arg(help = "Hex-encoded LDK serialization of Vec<BlindedMessagePath>")]
blinded_paths: String,
},
#[command(about = "Create blinded message paths for an asynchronous recipient")]
Bolt12BlindedPathsForAsyncRecipient {
#[arg(help = "Hex-encoded opaque recipient identifier")]
recipient_id: String,
},
#[command(about = "Send a payment for a BOLT12 offer")]
Bolt12Send {
#[arg(help = "A BOLT12 offer for a payment within the Lightning Network")]
Expand Down Expand Up @@ -1191,6 +1206,37 @@ async fn main() {
.await,
);
},
Commands::Bolt12ReceiveAsync => {
handle_response_result::<_, Bolt12ReceiveAsyncResponse>(
client.bolt12_receive_async(Bolt12ReceiveAsyncRequest {}).await,
);
},
Commands::Bolt12SetPathsToStaticInvoiceServer { blinded_paths } => {
let blinded_paths = Vec::<u8>::from_hex(&blinded_paths)
.unwrap_or_else(|e| handle_error_msg(format!("invalid blinded_paths hex: {e}")));
handle_response_result::<_, Bolt12SetPathsToStaticInvoiceServerResponse>(
client
.bolt12_set_paths_to_static_invoice_server(
Bolt12SetPathsToStaticInvoiceServerRequest {
blinded_paths: blinded_paths.into(),
},
)
.await,
);
},
Commands::Bolt12BlindedPathsForAsyncRecipient { recipient_id } => {
let recipient_id = Vec::<u8>::from_hex(&recipient_id)
.unwrap_or_else(|e| handle_error_msg(format!("invalid recipient_id hex: {e}")));
handle_response_result::<_, Bolt12BlindedPathsForAsyncRecipientResponse>(
client
.bolt12_blinded_paths_for_async_recipient(
Bolt12BlindedPathsForAsyncRecipientRequest {
recipient_id: recipient_id.into(),
},
)
.await,
);
},
Commands::Bolt12Send {
offer,
amount,
Expand Down
67 changes: 46 additions & 21 deletions ldk-server-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ use ldk_server_grpc::api::{
Bolt11ReceiveViaJitChannelForHashResponse, Bolt11ReceiveViaJitChannelRequest,
Bolt11ReceiveViaJitChannelResponse, Bolt11SendProbesRequest, Bolt11SendProbesResponse,
Bolt11SendRequest, Bolt11SendResponse, Bolt11SendUnderpayingRequest,
Bolt11SendUnderpayingResponse, Bolt12CreatePayerProofRequest, Bolt12CreatePayerProofResponse,
Bolt11SendUnderpayingResponse, Bolt12BlindedPathsForAsyncRecipientRequest,
Bolt12BlindedPathsForAsyncRecipientResponse, Bolt12CreatePayerProofRequest,
Bolt12CreatePayerProofResponse, Bolt12ReceiveAsyncRequest, Bolt12ReceiveAsyncResponse,
Bolt12ReceiveRefundRequest, Bolt12ReceiveRefundResponse, Bolt12ReceiveRequest,
Bolt12ReceiveResponse, Bolt12SendRefundRequest, Bolt12SendRefundResponse, Bolt12SendRequest,
Bolt12SendResponse, BumpChannelFundingFeeRequest, BumpChannelFundingFeeResponse,
CloseChannelRequest, CloseChannelResponse, ConnectPeerRequest, ConnectPeerResponse,
CreateMacaroonRequest, CreateMacaroonResponse, DecodeInvoiceRequest, DecodeInvoiceResponse,
DecodeOfferRequest, DecodeOfferResponse, DisconnectPeerRequest, DisconnectPeerResponse,
ExportPathfindingScoresRequest, ExportPathfindingScoresResponse, ForceCloseChannelRequest,
ForceCloseChannelResponse, GetBalancesRequest, GetBalancesResponse,
Bolt12SendResponse, Bolt12SetPathsToStaticInvoiceServerRequest,
Bolt12SetPathsToStaticInvoiceServerResponse, BumpChannelFundingFeeRequest,
BumpChannelFundingFeeResponse, CloseChannelRequest, CloseChannelResponse, ConnectPeerRequest,
ConnectPeerResponse, CreateMacaroonRequest, CreateMacaroonResponse, DecodeInvoiceRequest,
DecodeInvoiceResponse, DecodeOfferRequest, DecodeOfferResponse, DisconnectPeerRequest,
DisconnectPeerResponse, ExportPathfindingScoresRequest, ExportPathfindingScoresResponse,
ForceCloseChannelRequest, ForceCloseChannelResponse, GetBalancesRequest, GetBalancesResponse,
GetChannelForwardingStatsRequest, GetChannelForwardingStatsResponse,
GetForwardedPaymentDetailsRequest, GetForwardedPaymentDetailsResponse,
GetForwardedPaymentTrackingModeRequest, GetForwardedPaymentTrackingModeResponse,
Expand All @@ -57,20 +60,21 @@ use ldk_server_grpc::endpoints::{
BOLT11_RECEIVE_VARIABLE_AMOUNT_VIA_JIT_CHANNEL_PATH,
BOLT11_RECEIVE_VIA_JIT_CHANNEL_FOR_HASH_PATH, BOLT11_RECEIVE_VIA_JIT_CHANNEL_PATH,
BOLT11_SEND_PATH, BOLT11_SEND_PROBES_PATH, BOLT11_SEND_UNDERPAYING_PATH,
BOLT12_CREATE_PAYER_PROOF_PATH, BOLT12_RECEIVE_PATH, BOLT12_RECEIVE_REFUND_PATH,
BOLT12_SEND_PATH, BOLT12_SEND_REFUND_PATH, BUMP_CHANNEL_FUNDING_FEE_PATH, CLOSE_CHANNEL_PATH,
CONNECT_PEER_PATH, CREATE_MACAROON_PATH, DECODE_INVOICE_PATH, DECODE_OFFER_PATH,
DISCONNECT_PEER_PATH, EXPORT_PATHFINDING_SCORES_PATH, FORCE_CLOSE_CHANNEL_PATH,
GET_BALANCES_PATH, GET_CHANNEL_FORWARDING_STATS_PATH, GET_FORWARDED_PAYMENT_DETAILS_PATH,
GET_FORWARDED_PAYMENT_TRACKING_MODE_PATH, GET_METRICS_PATH, GET_NODE_INFO_PATH,
GET_PAYMENT_DETAILS_PATH, GET_PERMISSIONS_PATH, GRAPH_GET_CHANNEL_PATH, GRAPH_GET_NODE_PATH,
GRAPH_LIST_CHANNELS_PATH, GRAPH_LIST_NODES_PATH, GRPC_SERVICE_PREFIX, LIST_CHANNELS_PATH,
LIST_CHANNEL_FORWARDING_STATS_PATH, LIST_CHANNEL_PAIR_FORWARDING_STATS_PATH,
LIST_FORWARDED_PAYMENTS_PATH, LIST_MACAROONS_PATH, LIST_PAYMENTS_PATH, LIST_PEERS_PATH,
ONCHAIN_BUMP_FEE_PATH, ONCHAIN_RECEIVE_PATH, ONCHAIN_SEND_PATH, OPEN_CHANNEL_PATH,
REVOKE_MACAROON_PATH, SIGN_MESSAGE_PATH, SPLICE_IN_PATH, SPLICE_OUT_PATH,
SPONTANEOUS_SEND_PATH, SPONTANEOUS_SEND_PROBES_PATH, SUBSCRIBE_EVENTS_PATH, UNIFIED_SEND_PATH,
UPDATE_CHANNEL_CONFIG_PATH, VERIFY_SIGNATURE_PATH,
BOLT12_BLINDED_PATHS_FOR_ASYNC_RECIPIENT_PATH, BOLT12_CREATE_PAYER_PROOF_PATH,
BOLT12_RECEIVE_ASYNC_PATH, BOLT12_RECEIVE_PATH, BOLT12_RECEIVE_REFUND_PATH, BOLT12_SEND_PATH,
BOLT12_SEND_REFUND_PATH, BOLT12_SET_PATHS_TO_STATIC_INVOICE_SERVER_PATH,
BUMP_CHANNEL_FUNDING_FEE_PATH, CLOSE_CHANNEL_PATH, CONNECT_PEER_PATH, CREATE_MACAROON_PATH,
DECODE_INVOICE_PATH, DECODE_OFFER_PATH, DISCONNECT_PEER_PATH, EXPORT_PATHFINDING_SCORES_PATH,
FORCE_CLOSE_CHANNEL_PATH, GET_BALANCES_PATH, GET_CHANNEL_FORWARDING_STATS_PATH,
GET_FORWARDED_PAYMENT_DETAILS_PATH, GET_FORWARDED_PAYMENT_TRACKING_MODE_PATH, GET_METRICS_PATH,
GET_NODE_INFO_PATH, GET_PAYMENT_DETAILS_PATH, GET_PERMISSIONS_PATH, GRAPH_GET_CHANNEL_PATH,
GRAPH_GET_NODE_PATH, GRAPH_LIST_CHANNELS_PATH, GRAPH_LIST_NODES_PATH, GRPC_SERVICE_PREFIX,
LIST_CHANNELS_PATH, LIST_CHANNEL_FORWARDING_STATS_PATH,
LIST_CHANNEL_PAIR_FORWARDING_STATS_PATH, LIST_FORWARDED_PAYMENTS_PATH, LIST_MACAROONS_PATH,
LIST_PAYMENTS_PATH, LIST_PEERS_PATH, ONCHAIN_BUMP_FEE_PATH, ONCHAIN_RECEIVE_PATH,
ONCHAIN_SEND_PATH, OPEN_CHANNEL_PATH, REVOKE_MACAROON_PATH, SIGN_MESSAGE_PATH, SPLICE_IN_PATH,
SPLICE_OUT_PATH, SPONTANEOUS_SEND_PATH, SPONTANEOUS_SEND_PROBES_PATH, SUBSCRIBE_EVENTS_PATH,
UNIFIED_SEND_PATH, UPDATE_CHANNEL_CONFIG_PATH, VERIFY_SIGNATURE_PATH,
};
use ldk_server_grpc::events::EventEnvelope;
use ldk_server_grpc::grpc::{
Expand Down Expand Up @@ -298,6 +302,27 @@ impl LdkServerClient {
self.grpc_unary(&request, BOLT12_RECEIVE_PATH).await
}

/// Retrieve the BOLT12 offer for receiving payments while this node is offline.
pub async fn bolt12_receive_async(
&self, request: Bolt12ReceiveAsyncRequest,
) -> Result<Bolt12ReceiveAsyncResponse, LdkServerError> {
self.grpc_unary(&request, BOLT12_RECEIVE_ASYNC_PATH).await
}

/// Set the blinded paths used to interact with a static invoice server.
pub async fn bolt12_set_paths_to_static_invoice_server(
&self, request: Bolt12SetPathsToStaticInvoiceServerRequest,
) -> Result<Bolt12SetPathsToStaticInvoiceServerResponse, LdkServerError> {
self.grpc_unary(&request, BOLT12_SET_PATHS_TO_STATIC_INVOICE_SERVER_PATH).await
}

/// Create blinded message paths for an asynchronous recipient.
pub async fn bolt12_blinded_paths_for_async_recipient(
&self, request: Bolt12BlindedPathsForAsyncRecipientRequest,
) -> Result<Bolt12BlindedPathsForAsyncRecipientResponse, LdkServerError> {
self.grpc_unary(&request, BOLT12_BLINDED_PATHS_FOR_ASYNC_RECIPIENT_PATH).await
}

/// Send a payment for a BOLT12 offer.
pub async fn bolt12_send(
&self, request: Bolt12SendRequest,
Expand Down
63 changes: 63 additions & 0 deletions ldk-server-grpc/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,69 @@ pub struct Bolt12ReceiveResponse {
#[prost(string, tag = "2")]
pub offer_id: ::prost::alloc::string::String,
}
/// Retrieve an offer for receiving payments while this node is offline.
/// Async payments support is experimental. The node must be configured as an async client, and
/// paths to a static invoice server must have been set. An offer is returned only after the static
/// invoice server has successfully completed building its static invoice.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
#[cfg_attr(feature = "serde", serde(default))]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Bolt12ReceiveAsyncRequest {}
/// The offer generated for asynchronous payments.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
#[cfg_attr(feature = "serde", serde(default))]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Bolt12ReceiveAsyncResponse {
/// An offer for a payment within the Lightning Network.
#[prost(string, tag = "1")]
pub offer: ::prost::alloc::string::String,
/// The hex-encoded offer id.
#[prost(string, tag = "2")]
pub offer_id: ::prost::alloc::string::String,
}
/// Set the blinded message paths used to interact with a static invoice server.
/// blinded_paths must be encoded using the LDK lightning serialization format for Vec<BlindedMessagePath>.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
#[cfg_attr(feature = "serde", serde(default))]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Bolt12SetPathsToStaticInvoiceServerRequest {
/// Serialized Vec<BlindedMessagePath>.
#[prost(bytes = "bytes", tag = "1")]
pub blinded_paths: ::prost::bytes::Bytes,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
#[cfg_attr(feature = "serde", serde(default))]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Bolt12SetPathsToStaticInvoiceServerResponse {}
/// Create blinded message paths for an asynchronous recipient.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
#[cfg_attr(feature = "serde", serde(default))]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Bolt12BlindedPathsForAsyncRecipientRequest {
/// Opaque recipient identifier used to derive the blinded paths.
#[prost(bytes = "bytes", tag = "1")]
pub recipient_id: ::prost::bytes::Bytes,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
#[cfg_attr(feature = "serde", serde(default))]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Bolt12BlindedPathsForAsyncRecipientResponse {
/// Serialized Vec<BlindedMessagePath> in the LDK lightning serialization format.
#[prost(bytes = "bytes", tag = "1")]
pub blinded_paths: ::prost::bytes::Bytes,
}
/// Send a payment for a BOLT12 offer.
/// See more:
/// - <https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt12Payment.html#method.send>
Expand Down
5 changes: 5 additions & 0 deletions ldk-server-grpc/src/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ pub const BOLT11_SEND_PATH: &str = "Bolt11Send";
pub const BOLT11_SEND_PROBES_PATH: &str = "Bolt11SendProbes";
pub const BOLT11_SEND_UNDERPAYING_PATH: &str = "Bolt11SendUnderpaying";
pub const BOLT12_RECEIVE_PATH: &str = "Bolt12Receive";
pub const BOLT12_RECEIVE_ASYNC_PATH: &str = "Bolt12ReceiveAsync";
pub const BOLT12_SET_PATHS_TO_STATIC_INVOICE_SERVER_PATH: &str =
"Bolt12SetPathsToStaticInvoiceServer";
pub const BOLT12_BLINDED_PATHS_FOR_ASYNC_RECIPIENT_PATH: &str =
"Bolt12BlindedPathsForAsyncRecipient";
pub const BOLT12_SEND_PATH: &str = "Bolt12Send";
pub const BOLT12_SEND_REFUND_PATH: &str = "Bolt12SendRefund";
pub const BOLT12_RECEIVE_REFUND_PATH: &str = "Bolt12ReceiveRefund";
Expand Down
Loading
Loading