Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BIP21 Unified QR Code Support #302

Merged
merged 14 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ reqwest = { version = "0.11", default-features = false, features = ["json", "rus
rusqlite = { version = "0.28.0", features = ["bundled"] }
bitcoin = "0.30.2"
bip39 = "2.0.0"
bip21 = { version = "0.3.1", features = ["std"], default-features = false }

rand = "0.8.5"
chrono = { version = "0.4", default-features = false, features = ["clock"] }
Expand Down
17 changes: 17 additions & 0 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ interface Node {
Bolt12Payment bolt12_payment();
SpontaneousPayment spontaneous_payment();
OnchainPayment onchain_payment();
UnifiedQrPayment unified_qr_payment();
[Throws=NodeError]
void connect(PublicKey node_id, SocketAddress address, boolean persist);
[Throws=NodeError]
Expand Down Expand Up @@ -148,6 +149,13 @@ interface OnchainPayment {
Txid send_all_to_address([ByRef]Address address);
};

interface UnifiedQrPayment {
[Throws=NodeError]
slanesuke marked this conversation as resolved.
Show resolved Hide resolved
string receive(u64 amount_sats, [ByRef]string message, u32 expiry_sec);
[Throws=NodeError]
QrPaymentResult send([ByRef]string uri_str);
};

[Error]
enum NodeError {
"AlreadyRunning",
Expand Down Expand Up @@ -175,6 +183,7 @@ enum NodeError {
"GossipUpdateFailed",
"GossipUpdateTimeout",
"LiquidityRequestFailed",
"UriParameterParsingFailed",
"InvalidAddress",
"InvalidSocketAddress",
"InvalidPublicKey",
Expand All @@ -191,6 +200,7 @@ enum NodeError {
"InvalidRefund",
"InvalidChannelId",
"InvalidNetwork",
"InvalidUri",
"DuplicatePayment",
"UnsupportedCurrency",
"InsufficientFunds",
Expand Down Expand Up @@ -276,6 +286,13 @@ interface PaymentKind {
Spontaneous(PaymentHash hash, PaymentPreimage? preimage);
};

[Enum]
interface QrPaymentResult {
Onchain(Txid txid);
Bolt11(PaymentId payment_id);
Bolt12(PaymentId payment_id);
};

enum PaymentDirection {
"Inbound",
"Outbound",
Expand Down
6 changes: 6 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ pub enum Error {
GossipUpdateTimeout,
/// A liquidity request operation failed.
LiquidityRequestFailed,
/// Parsing a URI parameter has failed.
UriParameterParsingFailed,
/// The given address is invalid.
InvalidAddress,
/// The given network address is invalid.
Expand Down Expand Up @@ -85,6 +87,8 @@ pub enum Error {
InvalidChannelId,
/// The given network is invalid.
InvalidNetwork,
/// The given URI is invalid.
InvalidUri,
/// A payment with the given hash has already been initiated.
DuplicatePayment,
/// The provided offer was denonminated in an unsupported currency.
Expand Down Expand Up @@ -131,6 +135,7 @@ impl fmt::Display for Error {
Self::GossipUpdateFailed => write!(f, "Failed to update gossip data."),
Self::GossipUpdateTimeout => write!(f, "Updating gossip data timed out."),
Self::LiquidityRequestFailed => write!(f, "Failed to request inbound liquidity."),
Self::UriParameterParsingFailed => write!(f, "Failed to parse a URI parameter."),
Self::InvalidAddress => write!(f, "The given address is invalid."),
Self::InvalidSocketAddress => write!(f, "The given network address is invalid."),
Self::InvalidPublicKey => write!(f, "The given public key is invalid."),
Expand All @@ -147,6 +152,7 @@ impl fmt::Display for Error {
Self::InvalidRefund => write!(f, "The given refund is invalid."),
Self::InvalidChannelId => write!(f, "The given channel ID is invalid."),
Self::InvalidNetwork => write!(f, "The given network is invalid."),
Self::InvalidUri => write!(f, "The given URI is invalid."),
Self::DuplicatePayment => {
write!(f, "A payment with the given hash has already been initiated.")
},
Expand Down
39 changes: 38 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ use gossip::GossipSource;
use graph::NetworkGraph;
use liquidity::LiquiditySource;
use payment::store::PaymentStore;
use payment::{Bolt11Payment, Bolt12Payment, OnchainPayment, PaymentDetails, SpontaneousPayment};
use payment::{
Bolt11Payment, Bolt12Payment, OnchainPayment, PaymentDetails, SpontaneousPayment,
UnifiedQrPayment,
};
use peer_store::{PeerInfo, PeerStore};
use types::{
Broadcaster, BumpTransactionEventHandler, ChainMonitor, ChannelManager, DynStore, FeeEstimator,
Expand Down Expand Up @@ -1072,6 +1075,40 @@ impl Node {
))
}

/// Returns a payment handler allowing to create [BIP 21] URIs with an on-chain, [BOLT 11],
/// and [BOLT 12] payment options.
///
/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
/// [BOLT 12]: https://github.com/lightning/bolts/blob/master/12-offer-encoding.md
/// [BIP 21]: https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki
#[cfg(not(feature = "uniffi"))]
pub fn unified_qr_payment(&self) -> UnifiedQrPayment {
UnifiedQrPayment::new(
self.onchain_payment().into(),
self.bolt11_payment().into(),
self.bolt12_payment().into(),
Arc::clone(&self.config),
Arc::clone(&self.logger),
)
}

/// Returns a payment handler allowing to create [BIP 21] URIs with an on-chain, [BOLT 11],
/// and [BOLT 12] payment options.
///
/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
/// [BOLT 12]: https://github.com/lightning/bolts/blob/master/12-offer-encoding.md
/// [BIP 21]: https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki
#[cfg(feature = "uniffi")]
pub fn unified_qr_payment(&self) -> Arc<UnifiedQrPayment> {
Arc::new(UnifiedQrPayment::new(
self.onchain_payment(),
self.bolt11_payment(),
self.bolt12_payment(),
Arc::clone(&self.config),
Arc::clone(&self.logger),
))
}

/// Retrieve a list of known channels.
pub fn list_channels(&self) -> Vec<ChannelDetails> {
self.channel_manager.list_channels().into_iter().map(|c| c.into()).collect()
Expand Down
2 changes: 2 additions & 0 deletions src/payment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ mod bolt12;
mod onchain;
mod spontaneous;
pub(crate) mod store;
mod unified_qr;

pub use bolt11::Bolt11Payment;
pub use bolt12::Bolt12Payment;
pub use onchain::OnchainPayment;
pub use spontaneous::SpontaneousPayment;
pub use store::{LSPFeeLimits, PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus};
pub use unified_qr::{QrPaymentResult, UnifiedQrPayment};
Loading
Loading