Skip to content

Commit 5b97b26

Browse files
committed
Account for Bolt11InvoiceDescription.
1 parent 397b295 commit 5b97b26

7 files changed

Lines changed: 99 additions & 31 deletions

File tree

ldk-server-cli/src/main.rs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use ldk_server_client::ldk_server_protos::api::{
66
GetBalancesRequest, GetNodeInfoRequest, ListChannelsRequest, ListPaymentsRequest,
77
OnchainReceiveRequest, OnchainSendRequest, OpenChannelRequest,
88
};
9+
use ldk_server_client::ldk_server_protos::types::{
10+
bolt11_invoice_description, Bolt11InvoiceDescription,
11+
};
912

1013
#[derive(Parser, Debug)]
1114
#[command(version, about, long_about = None)]
@@ -32,7 +35,9 @@ enum Commands {
3235
},
3336
Bolt11Receive {
3437
#[arg(short, long)]
35-
description: String,
38+
description: Option<String>,
39+
#[arg(short, long)]
40+
description_hash: Option<String>,
3641
#[arg(short, long)]
3742
expiry_secs: u32,
3843
#[arg(long)]
@@ -87,31 +92,47 @@ async fn main() {
8792

8893
match cli.command {
8994
Commands::GetNodeInfo => {
90-
handle_response(client.get_node_info(GetNodeInfoRequest {}).await);
95+
handle_response_result(client.get_node_info(GetNodeInfoRequest {}).await);
9196
},
9297
Commands::GetBalances => {
93-
handle_response(client.get_balances(GetBalancesRequest {}).await);
98+
handle_response_result(client.get_balances(GetBalancesRequest {}).await);
9499
},
95100
Commands::OnchainReceive => {
96-
handle_response(client.onchain_receive(OnchainReceiveRequest {}).await);
101+
handle_response_result(client.onchain_receive(OnchainReceiveRequest {}).await);
97102
},
98103
Commands::OnchainSend { address, amount_sats, send_all } => {
99-
handle_response(
104+
handle_response_result(
100105
client.onchain_send(OnchainSendRequest { address, amount_sats, send_all }).await,
101106
);
102107
},
103-
Commands::Bolt11Receive { description, expiry_secs, amount_msat } => {
104-
handle_response(
105-
client
106-
.bolt11_receive(Bolt11ReceiveRequest { description, expiry_secs, amount_msat })
107-
.await,
108-
);
108+
Commands::Bolt11Receive { description, description_hash, expiry_secs, amount_msat } => {
109+
let invoice_description = match (description, description_hash) {
110+
(Some(desc), None) => Some(Bolt11InvoiceDescription {
111+
kind: Some(bolt11_invoice_description::Kind::Direct(desc)),
112+
}),
113+
(None, Some(hash)) => Some(Bolt11InvoiceDescription {
114+
kind: Some(bolt11_invoice_description::Kind::Hash(hash)),
115+
}),
116+
(Some(_), Some(_)) => {
117+
handle_error(LdkServerError::InternalError(
118+
"Only one of description or description_hash can be set.".to_string(),
119+
));
120+
},
121+
(None, None) => None,
122+
};
123+
124+
let request =
125+
Bolt11ReceiveRequest { description: invoice_description, expiry_secs, amount_msat };
126+
127+
handle_response_result(client.bolt11_receive(request).await);
109128
},
110129
Commands::Bolt11Send { invoice, amount_msat } => {
111-
handle_response(client.bolt11_send(Bolt11SendRequest { invoice, amount_msat }).await);
130+
handle_response_result(
131+
client.bolt11_send(Bolt11SendRequest { invoice, amount_msat }).await,
132+
);
112133
},
113134
Commands::Bolt12Receive { description, amount_msat, expiry_secs, quantity } => {
114-
handle_response(
135+
handle_response_result(
115136
client
116137
.bolt12_receive(Bolt12ReceiveRequest {
117138
description,
@@ -123,7 +144,7 @@ async fn main() {
123144
);
124145
},
125146
Commands::Bolt12Send { offer, amount_msat, quantity, payer_note } => {
126-
handle_response(
147+
handle_response_result(
127148
client
128149
.bolt12_send(Bolt12SendRequest { offer, amount_msat, quantity, payer_note })
129150
.await,
@@ -136,7 +157,7 @@ async fn main() {
136157
push_to_counterparty_msat,
137158
announce_channel,
138159
} => {
139-
handle_response(
160+
handle_response_result(
140161
client
141162
.open_channel(OpenChannelRequest {
142163
node_pubkey,
@@ -150,22 +171,26 @@ async fn main() {
150171
);
151172
},
152173
Commands::ListChannels => {
153-
handle_response(client.list_channels(ListChannelsRequest {}).await);
174+
handle_response_result(client.list_channels(ListChannelsRequest {}).await);
154175
},
155176
Commands::ListPayments => {
156-
handle_response(client.list_payments(ListPaymentsRequest {}).await);
177+
handle_response_result(client.list_payments(ListPaymentsRequest {}).await);
157178
},
158179
}
159180
}
160181

161-
fn handle_response<Rs: ::prost::Message>(response: Result<Rs, LdkServerError>) {
182+
fn handle_response_result<Rs: ::prost::Message>(response: Result<Rs, LdkServerError>) {
162183
match response {
163184
Ok(response) => {
164185
println!("{:?}", response);
165186
},
166187
Err(e) => {
167-
eprintln!("Error executing command: {:?}", e);
168-
std::process::exit(1); // Exit with status code 1 on error.
188+
handle_error(e);
169189
},
170190
};
171191
}
192+
193+
fn handle_error(e: LdkServerError) -> ! {
194+
eprintln!("Error executing command: {:?}", e);
195+
std::process::exit(1); // Exit with status code 1 on error.
196+
}

ldk-server-protos/src/api.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ pub struct Bolt11ReceiveRequest {
107107
pub amount_msat: ::core::option::Option<u64>,
108108
/// An optional description to attach along with the invoice.
109109
/// Will be set in the description field of the encoded payment request.
110-
#[prost(string, tag = "2")]
111-
pub description: ::prost::alloc::string::String,
110+
#[prost(message, optional, tag = "2")]
111+
pub description: ::core::option::Option<super::types::Bolt11InvoiceDescription>,
112112
/// Invoice expiry time in seconds.
113113
#[prost(uint32, tag = "3")]
114114
pub expiry_secs: u32,

ldk-server-protos/src/proto/api.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ message Bolt11ReceiveRequest {
107107

108108
// An optional description to attach along with the invoice.
109109
// Will be set in the description field of the encoded payment request.
110-
string description = 2;
110+
types.Bolt11InvoiceDescription description = 2;
111111

112112
// Invoice expiry time in seconds.
113113
uint32 expiry_secs = 3;

ldk-server-protos/src/proto/types.proto

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,10 @@ message PageToken {
636636
string token = 1;
637637
int64 index = 2;
638638
}
639+
640+
message Bolt11InvoiceDescription {
641+
oneof kind {
642+
string direct = 1;
643+
string hash = 2;
644+
}
645+
}

ldk-server-protos/src/types.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,23 @@ pub struct PageToken {
708708
#[prost(int64, tag = "2")]
709709
pub index: i64,
710710
}
711+
#[allow(clippy::derive_partial_eq_without_eq)]
712+
#[derive(Clone, PartialEq, ::prost::Message)]
713+
pub struct Bolt11InvoiceDescription {
714+
#[prost(oneof = "bolt11_invoice_description::Kind", tags = "1, 2")]
715+
pub kind: ::core::option::Option<bolt11_invoice_description::Kind>,
716+
}
717+
/// Nested message and enum types in `Bolt11InvoiceDescription`.
718+
pub mod bolt11_invoice_description {
719+
#[allow(clippy::derive_partial_eq_without_eq)]
720+
#[derive(Clone, PartialEq, ::prost::Oneof)]
721+
pub enum Kind {
722+
#[prost(string, tag = "1")]
723+
Direct(::prost::alloc::string::String),
724+
#[prost(string, tag = "2")]
725+
Hash(::prost::alloc::string::String),
726+
}
727+
}
711728
/// Represents the direction of a payment.
712729
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
713730
#[repr(i32)]

ldk-server/src/api/bolt11_receive.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
use crate::service::Context;
2+
use crate::util::proto_adapter::proto_to_bolt11_description;
23
use ldk_server_protos::api::{Bolt11ReceiveRequest, Bolt11ReceiveResponse};
34

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

67
pub(crate) fn handle_bolt11_receive_request(
78
context: Context, request: Bolt11ReceiveRequest,
89
) -> Result<Bolt11ReceiveResponse, ldk_node::NodeError> {
10+
let description = proto_to_bolt11_description(request.description)?;
911
let invoice = match request.amount_msat {
10-
Some(amount_msat) => context.node.bolt11_payment().receive(
11-
amount_msat,
12-
&request.description,
13-
request.expiry_secs,
14-
)?,
12+
Some(amount_msat) => {
13+
context.node.bolt11_payment().receive(amount_msat, &description, request.expiry_secs)?
14+
},
1515
None => context
1616
.node
1717
.bolt11_payment()
18-
.receive_variable_amount(&request.description, request.expiry_secs)?,
18+
.receive_variable_amount(&description, request.expiry_secs)?,
1919
};
2020

2121
let response = Bolt11ReceiveResponse { invoice: invoice.to_string() };

ldk-server/src/util/proto_adapter.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use bytes::Bytes;
22
use hex::prelude::*;
3+
use ldk_node::bitcoin::hashes::sha256;
34
use ldk_node::bitcoin::secp256k1::PublicKey;
45
use ldk_node::config::{ChannelConfig, MaxDustHTLCExposure};
56
use ldk_node::lightning::ln::types::ChannelId;
7+
use ldk_node::lightning_invoice::{Bolt11InvoiceDescription, Description, Sha256};
68
use ldk_node::payment::{PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus};
7-
use ldk_node::{ChannelDetails, Event, LightningBalance, PendingSweepBalance, UserChannelId};
9+
use ldk_node::{ChannelDetails, LightningBalance, NodeError, PendingSweepBalance, UserChannelId};
810
use ldk_server_protos::types::lightning_balance::BalanceType::{
911
ClaimableAwaitingConfirmations, ClaimableOnChannelClose, ContentiousClaimable,
1012
CounterpartyRevokedOutputClaimable, MaybePreimageClaimableHtlc, MaybeTimeoutClaimableHtlc,
@@ -15,7 +17,9 @@ use ldk_server_protos::types::payment_kind::Kind::{
1517
use ldk_server_protos::types::pending_sweep_balance::BalanceType::{
1618
AwaitingThresholdConfirmations, BroadcastAwaitingConfirmation, PendingBroadcast,
1719
};
18-
use ldk_server_protos::types::{Channel, ForwardedPayment, LspFeeLimits, OutPoint, Payment};
20+
use ldk_server_protos::types::{
21+
bolt11_invoice_description, Channel, ForwardedPayment, LspFeeLimits, OutPoint, Payment,
22+
};
1923

2024
pub(crate) fn channel_to_proto(channel: ChannelDetails) -> Channel {
2125
Channel {
@@ -346,3 +350,18 @@ pub(crate) fn forwarded_payment_to_proto(
346350
outbound_amount_forwarded_msat,
347351
}
348352
}
353+
354+
pub(crate) fn proto_to_bolt11_description(
355+
description: Option<ldk_server_protos::types::Bolt11InvoiceDescription>,
356+
) -> Result<Bolt11InvoiceDescription, NodeError> {
357+
Ok(match description.and_then(|d| d.kind) {
358+
Some(bolt11_invoice_description::Kind::Direct(s)) => {
359+
Bolt11InvoiceDescription::Direct(Description::new(s).unwrap())
360+
},
361+
Some(bolt11_invoice_description::Kind::Hash(h)) => {
362+
let hash_bytes = <[u8; 32]>::from_hex(&h).map_err(|_| NodeError::InvalidInvoice)?;
363+
Bolt11InvoiceDescription::Hash(Sha256(*sha256::Hash::from_bytes_ref(&hash_bytes)))
364+
},
365+
None => Bolt11InvoiceDescription::Direct(Description::new("".to_string()).unwrap()),
366+
})
367+
}

0 commit comments

Comments
 (0)