Skip to content

Commit

Permalink
Merge pull request #32 from G8XSU/forwarded-payments
Browse files Browse the repository at this point in the history
Add Api impl for ListForwardedPayments.
  • Loading branch information
G8XSU authored Dec 13, 2024
2 parents 5840bad + 5f34539 commit f28b20d
Show file tree
Hide file tree
Showing 27 changed files with 470 additions and 147 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ jobs:
- name: Pin packages to allow for MSRV
if: matrix.msrv
run: |
cargo update -p hashlink --precise "0.8.2" --verbose # hashlink 0.8.3 requires hashbrown 0.14, requiring 1.64.0
cargo update -p regex --precise "1.9.6" --verbose # regex 1.10.0 requires rustc 1.65.0
cargo update -p home --precise "0.5.5" --verbose # home v0.5.9 requires rustc 1.70 or newer
cargo update -p tokio --precise "1.38.1" --verbose # tokio v1.39.0 requires rustc 1.70 or newer
Expand Down
52 changes: 15 additions & 37 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions ldk-server-protos/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,44 @@ pub struct ListPaymentsResponse {
#[prost(message, repeated, tag = "1")]
pub payments: ::prost::alloc::vec::Vec<super::types::Payment>,
}
/// Retrieves list of all forwarded payments.
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/enum.Event.html#variant.PaymentForwarded>
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListForwardedPaymentsRequest {
/// `page_token` is a pagination token.
///
/// To query for the first page, `page_token` must not be specified.
///
/// For subsequent pages, use the value that was returned as `next_page_token` in the previous
/// page's response.
#[prost(message, optional, tag = "1")]
pub page_token: ::core::option::Option<super::types::PageToken>,
}
/// The response `content` for the `ListForwardedPayments` API, when HttpStatusCode is OK (200).
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListForwardedPaymentsResponse {
/// List of forwarded payments.
#[prost(message, repeated, tag = "1")]
pub forwarded_payments: ::prost::alloc::vec::Vec<super::types::ForwardedPayment>,
/// `next_page_token` is a pagination token, used to retrieve the next page of results.
/// Use this value to query for next-page of paginated operation, by specifying
/// this value as the `page_token` in the next request.
///
/// If `next_page_token` is `None`, then the "last page" of results has been processed and
/// there is no more data to be retrieved.
///
/// If `next_page_token` is not `None`, it does not necessarily mean that there is more data in the
/// result set. The only way to know when you have reached the end of the result set is when
/// `next_page_token` is `None`.
///
/// **Caution**: Clients must not assume a specific number of records to be present in a page for
/// paginated response.
#[prost(message, optional, tag = "2")]
pub next_page_token: ::core::option::Option<super::types::PageToken>,
}
/// Retrieves an overview of all known balances.
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/struct.Node.html#method.list_balances>
#[allow(clippy::derive_partial_eq_without_eq)]
Expand Down
34 changes: 34 additions & 0 deletions ldk-server-protos/src/proto/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,40 @@ message ListPaymentsResponse {
repeated types.Payment payments = 1;
}

// Retrieves list of all forwarded payments.
// See more: https://docs.rs/ldk-node/latest/ldk_node/enum.Event.html#variant.PaymentForwarded
message ListForwardedPaymentsRequest {
// `page_token` is a pagination token.
//
// To query for the first page, `page_token` must not be specified.
//
// For subsequent pages, use the value that was returned as `next_page_token` in the previous
// page's response.
optional types.PageToken page_token = 1;
}

// The response `content` for the `ListForwardedPayments` API, when HttpStatusCode is OK (200).
// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
message ListForwardedPaymentsResponse {
// List of forwarded payments.
repeated types.ForwardedPayment forwarded_payments = 1;

// `next_page_token` is a pagination token, used to retrieve the next page of results.
// Use this value to query for next-page of paginated operation, by specifying
// this value as the `page_token` in the next request.
//
// If `next_page_token` is `None`, then the "last page" of results has been processed and
// there is no more data to be retrieved.
//
// If `next_page_token` is not `None`, it does not necessarily mean that there is more data in the
// result set. The only way to know when you have reached the end of the result set is when
// `next_page_token` is `None`.
//
// **Caution**: Clients must not assume a specific number of records to be present in a page for
// paginated response.
optional types.PageToken next_page_token = 2;
}

// Retrieves an overview of all known balances.
// See more: https://docs.rs/ldk-node/latest/ldk_node/struct.Node.html#method.list_balances
message GetBalancesRequest {}
Expand Down
51 changes: 51 additions & 0 deletions ldk-server-protos/src/proto/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,51 @@ enum PaymentStatus {
FAILED = 2;
}

// A forwarded payment through our node.
// See more: https://docs.rs/ldk-node/latest/ldk_node/enum.Event.html#variant.PaymentForwarded
message ForwardedPayment{
// The channel id of the incoming channel between the previous node and us.
string prev_channel_id = 1;

// The channel id of the outgoing channel between the next node and us.
string next_channel_id = 2;

// The `user_channel_id` of the incoming channel between the previous node and us.
string prev_user_channel_id = 3;

// The `user_channel_id` of the outgoing channel between the next node and us.
// This will be `None` if the payment was settled via an on-chain transaction.
// See the caveat described for the `total_fee_earned_msat` field.
optional string next_user_channel_id = 4;

// The total fee, in milli-satoshis, which was earned as a result of the payment.
//
// Note that if we force-closed the channel over which we forwarded an HTLC while the HTLC was pending, the amount the
// next hop claimed will have been rounded down to the nearest whole satoshi. Thus, the fee calculated here may be
// higher than expected as we still claimed the full value in millisatoshis from the source.
// In this case, `claim_from_onchain_tx` will be set.
//
// If the channel which sent us the payment has been force-closed, we will claim the funds via an on-chain transaction.
// In that case we do not yet know the on-chain transaction fees which we will spend and will instead set this to `None`.
optional uint64 total_fee_earned_msat = 5;

// The share of the total fee, in milli-satoshis, which was withheld in addition to the forwarding fee.
// This will only be set if we forwarded an intercepted HTLC with less than the expected amount. This means our
// counterparty accepted to receive less than the invoice amount.
//
// The caveat described above the `total_fee_earned_msat` field applies here as well.
optional uint64 skimmed_fee_msat = 6;

// If this is true, the forwarded HTLC was claimed by our counterparty via an on-chain transaction.
bool claim_from_onchain_tx = 7;

// The final amount forwarded, in milli-satoshis, after the fee is deducted.
//
// The caveat described above the `total_fee_earned_msat` field applies here as well.
optional uint64 outbound_amount_forwarded_msat = 8;

}

message Channel {
// The channel ID (prior to funding transaction generation, this is a random 32-byte
// identifier, afterwards this is the transaction ID of the funding transaction XOR the
Expand Down Expand Up @@ -579,3 +624,9 @@ message AwaitingThresholdConfirmations {
// The amount, in satoshis, of the output being swept.
uint64 amount_satoshis = 5;
}

// Token used to determine start of next page in paginated APIs.
message PageToken {
string token = 1;
int64 index = 2;
}
55 changes: 55 additions & 0 deletions ldk-server-protos/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,52 @@ pub struct LspFeeLimits {
#[prost(uint64, optional, tag = "2")]
pub max_proportional_opening_fee_ppm_msat: ::core::option::Option<u64>,
}
/// A forwarded payment through our node.
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/enum.Event.html#variant.PaymentForwarded>
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ForwardedPayment {
/// The channel id of the incoming channel between the previous node and us.
#[prost(string, tag = "1")]
pub prev_channel_id: ::prost::alloc::string::String,
/// The channel id of the outgoing channel between the next node and us.
#[prost(string, tag = "2")]
pub next_channel_id: ::prost::alloc::string::String,
/// The `user_channel_id` of the incoming channel between the previous node and us.
#[prost(string, tag = "3")]
pub prev_user_channel_id: ::prost::alloc::string::String,
/// The `user_channel_id` of the outgoing channel between the next node and us.
/// This will be `None` if the payment was settled via an on-chain transaction.
/// See the caveat described for the `total_fee_earned_msat` field.
#[prost(string, optional, tag = "4")]
pub next_user_channel_id: ::core::option::Option<::prost::alloc::string::String>,
/// The total fee, in milli-satoshis, which was earned as a result of the payment.
///
/// Note that if we force-closed the channel over which we forwarded an HTLC while the HTLC was pending, the amount the
/// next hop claimed will have been rounded down to the nearest whole satoshi. Thus, the fee calculated here may be
/// higher than expected as we still claimed the full value in millisatoshis from the source.
/// In this case, `claim_from_onchain_tx` will be set.
///
/// If the channel which sent us the payment has been force-closed, we will claim the funds via an on-chain transaction.
/// In that case we do not yet know the on-chain transaction fees which we will spend and will instead set this to `None`.
#[prost(uint64, optional, tag = "5")]
pub total_fee_earned_msat: ::core::option::Option<u64>,
/// The share of the total fee, in milli-satoshis, which was withheld in addition to the forwarding fee.
/// This will only be set if we forwarded an intercepted HTLC with less than the expected amount. This means our
/// counterparty accepted to receive less than the invoice amount.
///
/// The caveat described above the `total_fee_earned_msat` field applies here as well.
#[prost(uint64, optional, tag = "6")]
pub skimmed_fee_msat: ::core::option::Option<u64>,
/// If this is true, the forwarded HTLC was claimed by our counterparty via an on-chain transaction.
#[prost(bool, tag = "7")]
pub claim_from_onchain_tx: bool,
/// The final amount forwarded, in milli-satoshis, after the fee is deducted.
///
/// The caveat described above the `total_fee_earned_msat` field applies here as well.
#[prost(uint64, optional, tag = "8")]
pub outbound_amount_forwarded_msat: ::core::option::Option<u64>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Channel {
Expand Down Expand Up @@ -647,6 +693,15 @@ pub struct AwaitingThresholdConfirmations {
#[prost(uint64, tag = "5")]
pub amount_satoshis: u64,
}
/// Token used to determine start of next page in paginated APIs.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PageToken {
#[prost(string, tag = "1")]
pub token: ::prost::alloc::string::String,
#[prost(int64, tag = "2")]
pub index: i64,
}
/// Represents the direction of a payment.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
Expand Down
6 changes: 2 additions & 4 deletions ldk-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"

[dependencies]
ldk-node = { version = "0.4.0", default-features = false }
ldk-node = { git = "https://github.com/lightningdevkit/ldk-node.git", rev = "2095d878be10923845bcdd1dd039ab0e670e723d" }
serde = { version = "1.0.203", default-features = false, features = ["derive"] }
serde_json = { version = "1.0.118", default-features = false }
hyper = { version = "1", default-features = false, features = ["server", "http1"] }
Expand All @@ -15,7 +15,5 @@ prost = { version = "0.11.6", default-features = false, features = ["std"] }
ldk-server-protos = { path = "../ldk-server-protos" }
bytes = "1.4.0"
hex = { package = "hex-conservative", version = "0.2.1", default-features = false }
rusqlite = { version = "0.28.0", features = ["bundled"] }

[dev-dependencies]
rusqlite = { version = "0.31.0", features = ["bundled"] }
rand = "0.8.5"
16 changes: 9 additions & 7 deletions ldk-server/src/api/bolt11_receive.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
use ldk_node::Node;
use crate::service::Context;
use ldk_server_protos::api::{Bolt11ReceiveRequest, Bolt11ReceiveResponse};
use std::sync::Arc;

pub(crate) const BOLT11_RECEIVE_PATH: &str = "Bolt11Receive";

pub(crate) fn handle_bolt11_receive_request(
node: Arc<Node>, request: Bolt11ReceiveRequest,
context: Context, request: Bolt11ReceiveRequest,
) -> Result<Bolt11ReceiveResponse, ldk_node::NodeError> {
let invoice = match request.amount_msat {
Some(amount_msat) => {
node.bolt11_payment().receive(amount_msat, &request.description, request.expiry_secs)?
},
None => node
Some(amount_msat) => context.node.bolt11_payment().receive(
amount_msat,
&request.description,
request.expiry_secs,
)?,
None => context
.node
.bolt11_payment()
.receive_variable_amount(&request.description, request.expiry_secs)?,
};
Expand Down
Loading

0 comments on commit f28b20d

Please sign in to comment.