Skip to content

Commit 5194ccc

Browse files
committed
expose a proper newtype wrapper for the PaymentPreimage bindings
1 parent cf1cea0 commit 5194ccc

File tree

13 files changed

+199
-102
lines changed

13 files changed

+199
-102
lines changed

bindings/ldk_node.udl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,11 @@ interface SpontaneousPayment {
212212
[Throws=NodeError]
213213
PaymentId send_with_custom_tlvs(u64 amount_msat, PublicKey node_id, SendingParameters? sending_parameters, sequence<CustomTlvRecord> custom_tlvs);
214214
[Throws=NodeError]
215-
void send_probes(u64 amount_msat, PublicKey node_id);
215+
PaymentId send_with_preimage(u64 amount_msat, PublicKey node_id, PaymentPreimage preimage, SendingParameters? sending_parameters);
216216
[Throws=NodeError]
217-
PaymentId send_with_preimage(u64 amount_msat, PublicKey node_id, SendingParameters? sending_parameters, PaymentPreimage preimage);
217+
PaymentId send_with_preimage_and_custom_tlvs(u64 amount_msat, PublicKey node_id, sequence<CustomTlvRecord> custom_tlvs, PaymentPreimage preimage, SendingParameters? sending_parameters);
218218
[Throws=NodeError]
219-
PaymentId send_with_preimage_and_custom_tlvs(u64 amount_msat, PublicKey node_id, SendingParameters? sending_parameters, sequence<CustomTlvRecord> custom_tlvs, PaymentPreimage preimage);
219+
void send_probes(u64 amount_msat, PublicKey node_id);
220220
};
221221

222222
interface OnchainPayment {
@@ -450,6 +450,10 @@ dictionary PaymentDetails {
450450
u64 latest_update_timestamp;
451451
};
452452

453+
dictionary PaymentPreimage {
454+
bytes inner;
455+
};
456+
453457
dictionary SendingParameters {
454458
MaxTotalRoutingFeeLimit? max_total_routing_fee_msat;
455459
u32? max_total_cltv_expiry_delta;
@@ -833,9 +837,6 @@ typedef string PaymentId;
833837
[Custom]
834838
typedef string PaymentHash;
835839

836-
[Custom]
837-
typedef string PaymentPreimage;
838-
839840
[Custom]
840841
typedef string PaymentSecret;
841842

src/balance.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66
// accordance with one or both of these licenses.
77

8+
use crate::ffi::maybe_wrap;
9+
use crate::payment::PaymentPreimage;
810
use crate::sweep::value_from_descriptor;
911

1012
use lightning::chain::channelmonitor::Balance as LdkBalance;
1113
use lightning::chain::channelmonitor::BalanceSource;
1214
use lightning::ln::types::ChannelId;
1315
use lightning::util::sweep::{OutputSpendStatus, TrackedSpendableOutput};
1416

15-
use lightning_types::payment::{PaymentHash, PaymentPreimage};
17+
use lightning_types::payment::PaymentHash;
1618

1719
use bitcoin::secp256k1::PublicKey;
1820
use bitcoin::{BlockHash, Txid};
@@ -263,7 +265,7 @@ impl LightningBalance {
263265
amount_satoshis,
264266
timeout_height,
265267
payment_hash,
266-
payment_preimage,
268+
payment_preimage: maybe_wrap(payment_preimage),
267269
},
268270
LdkBalance::MaybeTimeoutClaimableHTLC {
269271
amount_satoshis,

src/event.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66
// accordance with one or both of these licenses.
77

8+
use crate::ffi::maybe_wrap;
89
use crate::types::{CustomTlvRecord, DynStore, PaymentStore, Sweeper, Wallet};
910

1011
use crate::{
@@ -22,6 +23,7 @@ use crate::logger::Logger;
2223
use crate::payment::store::{
2324
PaymentDetails, PaymentDetailsUpdate, PaymentDirection, PaymentKind, PaymentStatus,
2425
};
26+
use crate::payment::PaymentPreimage;
2527

2628
use crate::io::{
2729
EVENT_QUEUE_PERSISTENCE_KEY, EVENT_QUEUE_PERSISTENCE_PRIMARY_NAMESPACE,
@@ -39,7 +41,7 @@ use lightning::routing::gossip::NodeId;
3941
use lightning::util::errors::APIError;
4042
use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer};
4143

42-
use lightning_types::payment::{PaymentHash, PaymentPreimage};
44+
use lightning_types::payment::PaymentHash;
4345

4446
use lightning_liquidity::lsps2::utils::compute_opening_fee;
4547

@@ -740,7 +742,7 @@ where
740742
let quantity = payment_context.invoice_request.quantity;
741743
let kind = PaymentKind::Bolt12Offer {
742744
hash: Some(payment_hash),
743-
preimage: payment_preimage,
745+
preimage: payment_preimage.map(|preimage| maybe_wrap(preimage)),
744746
secret: Some(payment_secret),
745747
offer_id,
746748
payer_note,
@@ -785,7 +787,7 @@ where
785787
// Since it's spontaneous, we insert it now into our store.
786788
let kind = PaymentKind::Spontaneous {
787789
hash: payment_hash,
788-
preimage: Some(preimage),
790+
preimage: Some(maybe_wrap(preimage)),
789791
};
790792

791793
let payment = PaymentDetails::new(
@@ -871,7 +873,7 @@ where
871873
payment_secret,
872874
..
873875
} => PaymentDetailsUpdate {
874-
preimage: Some(payment_preimage),
876+
preimage: Some(payment_preimage.map(|preimage| maybe_wrap(preimage))),
875877
secret: Some(Some(payment_secret)),
876878
amount_msat: Some(Some(amount_msat)),
877879
status: Some(PaymentStatus::Succeeded),
@@ -880,7 +882,7 @@ where
880882
PaymentPurpose::Bolt12OfferPayment {
881883
payment_preimage, payment_secret, ..
882884
} => PaymentDetailsUpdate {
883-
preimage: Some(payment_preimage),
885+
preimage: Some(payment_preimage.map(|preimage| maybe_wrap(preimage))),
884886
secret: Some(Some(payment_secret)),
885887
amount_msat: Some(Some(amount_msat)),
886888
status: Some(PaymentStatus::Succeeded),
@@ -891,14 +893,14 @@ where
891893
payment_secret,
892894
..
893895
} => PaymentDetailsUpdate {
894-
preimage: Some(payment_preimage),
896+
preimage: Some(payment_preimage.map(|preimage| maybe_wrap(preimage))),
895897
secret: Some(Some(payment_secret)),
896898
amount_msat: Some(Some(amount_msat)),
897899
status: Some(PaymentStatus::Succeeded),
898900
..PaymentDetailsUpdate::new(payment_id)
899901
},
900902
PaymentPurpose::SpontaneousPayment(preimage) => PaymentDetailsUpdate {
901-
preimage: Some(Some(preimage)),
903+
preimage: Some(Some(maybe_wrap(preimage))),
902904
amount_msat: Some(Some(amount_msat)),
903905
status: Some(PaymentStatus::Succeeded),
904906
..PaymentDetailsUpdate::new(payment_id)
@@ -960,7 +962,7 @@ where
960962

961963
let update = PaymentDetailsUpdate {
962964
hash: Some(Some(payment_hash)),
963-
preimage: Some(Some(payment_preimage)),
965+
preimage: Some(Some(maybe_wrap(payment_preimage))),
964966
fee_paid_msat: Some(fee_paid_msat),
965967
status: Some(PaymentStatus::Succeeded),
966968
..PaymentDetailsUpdate::new(payment_id)
@@ -992,7 +994,7 @@ where
992994
let event = Event::PaymentSuccessful {
993995
payment_id: Some(payment_id),
994996
payment_hash,
995-
payment_preimage: Some(payment_preimage),
997+
payment_preimage: Some(maybe_wrap(payment_preimage)),
996998
fee_paid_msat,
997999
};
9981000

src/ffi/mod.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ where
1818
wrapped_type.as_ref().as_ref()
1919
}
2020

21+
#[cfg(feature = "uniffi")]
22+
pub fn maybe_extract<T, R>(wrapped_type: T) -> Result<R, crate::error::Error>
23+
where
24+
R: TryFrom<T, Error = crate::error::Error>,
25+
{
26+
R::try_from(wrapped_type)
27+
}
28+
2129
#[cfg(feature = "uniffi")]
2230
pub fn maybe_try_convert_enum<T, R>(wrapped_type: &T) -> Result<R, crate::error::Error>
2331
where
@@ -27,10 +35,15 @@ where
2735
}
2836

2937
#[cfg(feature = "uniffi")]
30-
pub fn maybe_wrap<T>(ldk_type: impl Into<T>) -> std::sync::Arc<T> {
38+
pub fn maybe_wrap_arc<T>(ldk_type: impl Into<T>) -> std::sync::Arc<T> {
3139
std::sync::Arc::new(ldk_type.into())
3240
}
3341

42+
#[cfg(feature = "uniffi")]
43+
pub fn maybe_wrap<T>(ldk_type: impl Into<T>) -> T {
44+
ldk_type.into()
45+
}
46+
3447
#[cfg(not(feature = "uniffi"))]
3548
pub fn maybe_deref<T>(value: &T) -> &T {
3649
value
@@ -41,7 +54,19 @@ pub fn maybe_try_convert_enum<T>(value: &T) -> Result<&T, crate::error::Error> {
4154
Ok(value)
4255
}
4356

57+
#[cfg(not(feature = "uniffi"))]
58+
pub fn maybe_wrap_arc<T>(value: T) -> T {
59+
value
60+
}
61+
4462
#[cfg(not(feature = "uniffi"))]
4563
pub fn maybe_wrap<T>(value: T) -> T {
4664
value
4765
}
66+
67+
#[cfg(not(feature = "uniffi"))]
68+
pub fn maybe_extract<T>(wrapped_type: T) -> Result<T, crate::error::Error>
69+
where
70+
{
71+
Ok(wrapped_type)
72+
}

src/ffi/types.rs

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,18 @@ pub use crate::payment::store::{
2222
};
2323
pub use crate::payment::{MaxTotalRoutingFeeLimit, QrPaymentResult, SendingParameters};
2424

25+
use bitcoin::io::Read;
2526
pub use lightning::chain::channelmonitor::BalanceSource;
2627
pub use lightning::events::{ClosureReason, PaymentFailureReason};
28+
use lightning::ln::msgs::DecodeError;
2729
pub use lightning::ln::types::ChannelId;
2830
pub use lightning::offers::offer::OfferId;
2931
pub use lightning::routing::gossip::{NodeAlias, NodeId, RoutingFees};
3032
pub use lightning::util::string::UntrustedString;
3133

32-
pub use lightning_types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
34+
pub use lightning_types::payment::{
35+
PaymentHash, PaymentPreimage as LdkPaymentPreimage, PaymentSecret,
36+
};
3337

3438
pub use lightning_invoice::{Description, SignedRawBolt11Invoice};
3539

@@ -58,7 +62,7 @@ use lightning::ln::channelmanager::PaymentId;
5862
use lightning::offers::invoice::Bolt12Invoice as LdkBolt12Invoice;
5963
use lightning::offers::offer::{Amount as LdkAmount, Offer as LdkOffer};
6064
use lightning::offers::refund::Refund as LdkRefund;
61-
use lightning::util::ser::Writeable;
65+
use lightning::util::ser::{Readable, Writeable};
6266
use lightning_invoice::{Bolt11Invoice as LdkBolt11Invoice, Bolt11InvoiceDescriptionRef};
6367

6468
use std::convert::TryInto;
@@ -665,21 +669,64 @@ impl UniffiCustomTypeConverter for PaymentHash {
665669
}
666670
}
667671

668-
impl UniffiCustomTypeConverter for PaymentPreimage {
669-
type Builtin = String;
672+
#[derive(Debug, Clone, PartialEq, Eq)]
673+
pub struct PaymentPreimage {
674+
pub(crate) inner: Vec<u8>,
675+
}
670676

671-
fn into_custom(val: Self::Builtin) -> uniffi::Result<Self> {
672-
if let Some(bytes_vec) = hex_utils::to_vec(&val) {
673-
let bytes_res = bytes_vec.try_into();
674-
if let Ok(bytes) = bytes_res {
675-
return Ok(PaymentPreimage(bytes));
677+
impl From<LdkPaymentPreimage> for PaymentPreimage {
678+
fn from(ldk_value: LdkPaymentPreimage) -> Self {
679+
PaymentPreimage { inner: ldk_value.0.to_vec() }
680+
}
681+
}
682+
683+
impl TryFrom<PaymentPreimage> for LdkPaymentPreimage {
684+
type Error = Error;
685+
686+
fn try_from(preimage: PaymentPreimage) -> Result<Self, Self::Error> {
687+
if preimage.inner.len() != 32 {
688+
return Err(Error::InvalidPaymentPreimage);
689+
}
690+
691+
let mut array = [0u8; 32];
692+
array.copy_from_slice(&preimage.inner);
693+
Ok(LdkPaymentPreimage(array))
694+
}
695+
}
696+
697+
impl FromStr for PaymentPreimage {
698+
type Err = Error;
699+
700+
fn from_str(s: &str) -> Result<Self, Self::Err> {
701+
if let Some(bytes) = hex_utils::to_vec(s) {
702+
if let Ok(array) = bytes.try_into() {
703+
return Ok(Self::from(LdkPaymentPreimage(array)));
676704
}
677705
}
678-
Err(Error::InvalidPaymentPreimage.into())
706+
707+
Err(Error::InvalidPaymentPreimage)
679708
}
709+
}
680710

681-
fn from_custom(obj: Self) -> Self::Builtin {
682-
hex_utils::to_string(&obj.0)
711+
impl Writeable for PaymentPreimage {
712+
fn write<W: lightning::util::ser::Writer>(
713+
&self, writer: &mut W,
714+
) -> Result<(), lightning::io::Error> {
715+
let ldk_preimage = LdkPaymentPreimage::try_from(self.clone()).map_err(|_| {
716+
lightning::io::Error::new(
717+
lightning::io::ErrorKind::InvalidData,
718+
"Invalid payment preimage",
719+
)
720+
})?;
721+
722+
ldk_preimage.0.write(writer)
723+
}
724+
}
725+
726+
impl Readable for PaymentPreimage {
727+
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
728+
let buf: [u8; 32] = Readable::read(r)?;
729+
Ok(PaymentPreimage { inner: buf.to_vec() })
683730
}
684731
}
685732

0 commit comments

Comments
 (0)