Skip to content

Commit b596731

Browse files
Add Offer wrapper for FFI bindings
Implement Offer struct in ffi/types.rs to provide a wrapper around LDK's Offer for cross-language bindings. Modified payment handling in bolt12.rs to: - Support both native and FFI-compatible types via type aliasing - Implement conditional compilation for transparent FFI support - Update payment functions to handle wrapped types Added testing to verify that properties are preserved when wrapping/unwrapping between native and FFI types.
1 parent 22b21c6 commit b596731

File tree

5 files changed

+442
-24
lines changed

5 files changed

+442
-24
lines changed

bindings/ldk_node.udl

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,29 @@ interface Bolt11Invoice {
736736
PublicKey recover_payee_pub_key();
737737
};
738738

739+
[Enum]
740+
interface OfferAmount {
741+
Bitcoin(u64 amount_msats);
742+
Currency(string iso4217_code, u64 amount);
743+
};
744+
745+
interface Offer {
746+
[Throws=NodeError, Name=from_str]
747+
constructor([ByRef] string offer_str);
748+
OfferId id();
749+
boolean is_expired();
750+
string? description();
751+
string? issuer();
752+
OfferAmount? amount();
753+
boolean is_valid_quantity(u64 quantity);
754+
boolean expects_quantity();
755+
boolean supports_chain(Network chain);
756+
sequence<Network> chains();
757+
sequence<u8>? metadata();
758+
u64? absolute_expiry_seconds();
759+
PublicKey? issuer_signing_pubkey();
760+
};
761+
739762
[Custom]
740763
typedef string Txid;
741764

@@ -754,9 +777,6 @@ typedef string NodeId;
754777
[Custom]
755778
typedef string Address;
756779

757-
[Custom]
758-
typedef string Offer;
759-
760780
[Custom]
761781
typedef string Refund;
762782

src/ffi/conversions.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// This file is Copyright its original authors, visible in version control history.
2+
//
3+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5+
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
6+
// accordance with one or both of these licenses.
7+
8+
mod uniffi_impl {
9+
use std::sync::Arc;
10+
11+
use lightning::offers::offer::Offer as LdkOffer;
12+
use lightning_invoice::{
13+
Bolt11Invoice as LdkBolt11Invoice, Bolt11InvoiceDescription as LdkBolt11InvoiceDescription,
14+
};
15+
16+
use crate::error::Error;
17+
use crate::ffi::{Bolt11Invoice, Bolt11InvoiceDescription, Offer};
18+
19+
pub trait UniffiType {
20+
type LdkType;
21+
22+
fn from_ldk(ldk_value: Self::LdkType) -> Self;
23+
}
24+
25+
pub trait UniffiConversionType: UniffiType {
26+
fn as_ldk(&self) -> Self::LdkType;
27+
}
28+
29+
pub trait UniffiFallibleConversionType: UniffiType {
30+
fn try_as_ldk(&self) -> Result<Self::LdkType, Error>;
31+
}
32+
33+
impl UniffiType for Bolt11InvoiceDescription {
34+
type LdkType = LdkBolt11InvoiceDescription;
35+
36+
fn from_ldk(ldk_value: Self::LdkType) -> Self {
37+
Bolt11InvoiceDescription::from(ldk_value)
38+
}
39+
}
40+
41+
impl UniffiFallibleConversionType for Bolt11InvoiceDescription {
42+
fn try_as_ldk(&self) -> Result<Self::LdkType, Error> {
43+
LdkBolt11InvoiceDescription::try_from(self)
44+
}
45+
}
46+
47+
impl UniffiType for Arc<Bolt11Invoice> {
48+
type LdkType = LdkBolt11Invoice;
49+
50+
fn from_ldk(ldk_value: Self::LdkType) -> Self {
51+
Arc::new(Bolt11Invoice { inner: ldk_value })
52+
}
53+
}
54+
55+
impl UniffiConversionType for Arc<Bolt11Invoice> {
56+
fn as_ldk(&self) -> Self::LdkType {
57+
self.inner.clone()
58+
}
59+
}
60+
61+
impl UniffiType for Arc<Offer> {
62+
type LdkType = LdkOffer;
63+
64+
fn from_ldk(ldk_value: Self::LdkType) -> Self {
65+
Arc::new(Offer { inner: ldk_value })
66+
}
67+
}
68+
69+
impl UniffiConversionType for Arc<Offer> {
70+
fn as_ldk(&self) -> Self::LdkType {
71+
self.inner.clone()
72+
}
73+
}
74+
75+
pub fn maybe_convert<T: UniffiConversionType>(value: &T) -> T::LdkType {
76+
value.as_ldk()
77+
}
78+
79+
pub fn maybe_try_convert<T: UniffiFallibleConversionType>(
80+
value: &T,
81+
) -> Result<T::LdkType, Error> {
82+
value.try_as_ldk()
83+
}
84+
85+
pub fn maybe_wrap<T: UniffiType>(ldk_value: T::LdkType) -> T {
86+
T::from_ldk(ldk_value)
87+
}
88+
}
89+
90+
pub use uniffi_impl::maybe_convert;
91+
pub use uniffi_impl::maybe_try_convert;
92+
pub use uniffi_impl::maybe_wrap;

0 commit comments

Comments
 (0)