Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 7 additions & 0 deletions docs/api-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,18 @@ 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 and requires the node's async-payments role to be set to `Server`.
Comment thread
elnafateh marked this conversation as resolved.
Resolved
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
62 changes: 62 additions & 0 deletions ldk-server-grpc/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,68 @@ 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 and requires the node to be configured as an async server
/// and paths to a static invoice server to have been set.
#[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