Skip to content

Add support for sending to human-readable names (BIP 353) #528

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

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
7e8348a
Add support for sending to human-readable names that resolve to Bolt1…
chuksys Apr 21, 2025
9899a54
fixup! Add support for sending to human-readable names that resolve t…
chuksys May 6, 2025
62284c7
fixup! Add support for sending to human-readable names that resolve t…
chuksys May 6, 2025
7a90e84
Allow setting default DNS resolvers for HRNs
chuksys May 7, 2025
b1efad0
fixup! Allow setting default DNS resolvers for HRNs
chuksys May 7, 2025
1a2341a
fixup! Add support for sending to human-readable names that resolve t…
chuksys May 7, 2025
fa49217
fixup! Allow setting default DNS resolvers for HRNs
chuksys May 13, 2025
f4928ab
fixup! Add support for sending to human-readable names that resolve t…
chuksys May 13, 2025
e2db001
fixup! Add support for sending to human-readable names that resolve t…
chuksys May 13, 2025
8420d3e
fixup! Allow setting default DNS resolvers for HRNs
chuksys May 13, 2025
60578ef
Fix Formattting Issues
chuksys May 13, 2025
5a00c7c
fixup! Add support for sending to human-readable names that resolve t…
chuksys May 28, 2025
0a9379a
fixup! Allow setting default DNS resolvers for HRNs
chuksys May 28, 2025
c69b95f
fixup! Allow setting default DNS resolvers for HRNs
chuksys May 30, 2025
2f13d19
fixup! Add support for sending to human-readable names that resolve t…
chuksys May 30, 2025
6c6741c
fixup! Allow setting default DNS resolvers for HRNs
chuksys May 30, 2025
bac11f4
fixup! Allow setting default DNS resolvers for HRNs
chuksys May 30, 2025
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ panic = 'abort' # Abort on panic
default = []

[dependencies]
lightning = { version = "0.1.0", features = ["std"] }
lightning = { version = "0.1.0", features = ["std", "dnssec"] }
lightning-types = { version = "0.2.0" }
lightning-invoice = { version = "0.33.0", features = ["std"] }
lightning-net-tokio = { version = "0.1.0" }
21 changes: 19 additions & 2 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
@@ -13,6 +13,11 @@ dictionary Config {
u64 probing_liquidity_limit_multiplier;
AnchorChannelsConfig? anchor_channels_config;
SendingParameters? sending_parameters;
HumanReadableNamesConfig? hrn_config;
};

dictionary HumanReadableNamesConfig {
sequence<PublicKey> dns_resolvers_node_ids;
};

dictionary AnchorChannelsConfig {
@@ -197,6 +202,8 @@ interface Bolt12Payment {
[Throws=NodeError]
PaymentId send_using_amount([ByRef]Offer offer, u64 amount_msat, u64? quantity, string? payer_note);
[Throws=NodeError]
PaymentId send_to_human_readable_name(HumanReadableName hrn, u64 amount_msat);
[Throws=NodeError]
Offer receive(u64 amount_msat, [ByRef]string description, u32? expiry_secs, u64? quantity);
[Throws=NodeError]
Offer receive_variable_amount([ByRef]string description, u32? expiry_secs);
@@ -248,6 +255,13 @@ interface LSPS1Liquidity {
LSPS1OrderStatus check_order_status(OrderId order_id);
};

interface HumanReadableName {
[Throws=NodeError, Name=from_encoded]
constructor([ByRef] string encoded);
string user();
string domain();
};

[Error]
enum NodeError {
"AlreadyRunning",
@@ -302,6 +316,8 @@ enum NodeError {
"InsufficientFunds",
"LiquiditySourceUnavailable",
"LiquidityFeeTooHigh",
"HrnParsingFailed",
"DnsResolversUnavailable",
};

dictionary NodeStatus {
@@ -337,6 +353,7 @@ enum BuildError {
"WalletSetupFailed",
"LoggerSetupFailed",
"NetworkMismatch",
"DnsResolversUnavailable",
};

[Trait]
@@ -402,7 +419,7 @@ interface PaymentKind {
Onchain(Txid txid, ConfirmationStatus status);
Bolt11(PaymentHash hash, PaymentPreimage? preimage, PaymentSecret? secret);
Bolt11Jit(PaymentHash hash, PaymentPreimage? preimage, PaymentSecret? secret, u64? counterparty_skimmed_fee_msat, LSPFeeLimits lsp_fee_limits);
Bolt12Offer(PaymentHash? hash, PaymentPreimage? preimage, PaymentSecret? secret, OfferId offer_id, UntrustedString? payer_note, u64? quantity);
Bolt12Offer(PaymentHash? hash, PaymentPreimage? preimage, PaymentSecret? secret, OfferId? offer_id, UntrustedString? payer_note, u64? quantity);
Bolt12Refund(PaymentHash? hash, PaymentPreimage? preimage, PaymentSecret? secret, UntrustedString? payer_note, u64? quantity);
Spontaneous(PaymentHash hash, PaymentPreimage? preimage);
};
@@ -797,4 +814,4 @@ typedef string NodeAlias;
typedef string OrderId;

[Custom]
typedef string DateTime;
typedef string DateTime;
13 changes: 13 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
@@ -174,6 +174,10 @@ pub enum BuildError {
LoggerSetupFailed,
/// The given network does not match the node's previously configured network.
NetworkMismatch,
/// The [`dns_resolvers_node_ids`] provided for HRN resolution is empty.
///
/// [`dns_resolvers_node_ids`]: crate::config::HumanReadableNamesConfig::dns_resolvers_node_ids
DnsResolversUnavailable,
}

impl fmt::Display for BuildError {
@@ -201,6 +205,9 @@ impl fmt::Display for BuildError {
Self::NetworkMismatch => {
write!(f, "Given network does not match the node's previously configured network.")
},
Self::DnsResolversUnavailable => {
write!(f, "The DNS Resolvers provided for HRN resolution is empty.")
},
}
}
}
@@ -1492,6 +1499,12 @@ fn build_with_store_internal(
},
};

if let Some(hrn_config) = &config.hrn_config {
if hrn_config.dns_resolvers_node_ids.is_empty() {
return Err(BuildError::DnsResolversUnavailable);
}
};

let (stop_sender, _) = tokio::sync::watch::channel(());
let (event_handling_stopped_sender, _) = tokio::sync::watch::channel(());

17 changes: 17 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -103,6 +103,7 @@ pub const WALLET_KEYS_SEED_LEN: usize = 64;
/// | `log_level` | Debug |
/// | `anchor_channels_config` | Some(..) |
/// | `sending_parameters` | None |
/// | `hrn_config` | None |
///
/// See [`AnchorChannelsConfig`] and [`SendingParameters`] for more information regarding their
/// respective default values.
@@ -167,6 +168,10 @@ pub struct Config {
/// **Note:** If unset, default parameters will be used, and you will be able to override the
/// parameters on a per-payment basis in the corresponding method calls.
pub sending_parameters: Option<SendingParameters>,
/// Configuration options for Human-Readable Names ([BIP 353]).
///
/// [BIP 353]: https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki
pub hrn_config: Option<HumanReadableNamesConfig>,
}

impl Default for Config {
@@ -181,10 +186,22 @@ impl Default for Config {
anchor_channels_config: Some(AnchorChannelsConfig::default()),
sending_parameters: None,
node_alias: None,
hrn_config: None,
}
}
}

/// Configuration options for Human-readable Names
#[derive(Debug, Clone)]
pub struct HumanReadableNamesConfig {
/// The DNS resolvers to be used for resolving Human-Readable Names.
///
/// If not empty, the values set will be used as DNS resolvers when sending to HRNs.
///
/// **Note:** If empty, payments to HRNs will fail.
pub dns_resolvers_node_ids: Vec<PublicKey>,
}

/// Configuration options pertaining to 'Anchor' channels, i.e., channels for which the
/// `option_anchors_zero_fee_htlc_tx` channel type is negotiated.
///
10 changes: 10 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -120,6 +120,10 @@ pub enum Error {
LiquiditySourceUnavailable,
/// The given operation failed due to the LSP's required opening fee being too high.
LiquidityFeeTooHigh,
/// Parsing a Human-Readable Name has failed
HrnParsingFailed,
/// The given operation failed due to `dns-resolvers` not being configured in builder.
DnsResolversUnavailable,
}

impl fmt::Display for Error {
@@ -193,6 +197,12 @@ impl fmt::Display for Error {
Self::LiquidityFeeTooHigh => {
write!(f, "The given operation failed due to the LSP's required opening fee being too high.")
},
Self::HrnParsingFailed => {
write!(f, "Failed to parse a human-readable name.")
},
Self::DnsResolversUnavailable => {
write!(f, "The given operation failed due to `dns-resolvers` not being configured in builder.")
},
}
}
}
18 changes: 15 additions & 3 deletions src/event.rs
Original file line number Diff line number Diff line change
@@ -742,7 +742,7 @@ where
hash: Some(payment_hash),
preimage: payment_preimage,
secret: Some(payment_secret),
offer_id,
offer_id: Some(offer_id),
payer_note,
quantity,
};
@@ -1417,8 +1417,20 @@ where
);
}
},
LdkEvent::InvoiceReceived { .. } => {
debug_assert!(false, "We currently don't handle BOLT12 invoices manually, so this event should never be emitted.");
LdkEvent::InvoiceReceived { payment_id, invoice, context: _, responder: _ } => {
let update = PaymentDetailsUpdate {
hash: Some(Some(invoice.payment_hash())),
quantity: invoice.quantity(),
..PaymentDetailsUpdate::new(payment_id)
};

match self.payment_store.update(&update) {
Ok(_) => {},
Err(e) => {
log_error!(self.logger, "Failed to access payment store: {}", e);
return Err(ReplayEvent());
},
};
},
LdkEvent::ConnectionNeeded { node_id, addresses } => {
let runtime_lock = self.runtime.read().unwrap();
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -873,6 +873,7 @@ impl Node {
Arc::clone(&self.channel_manager),
Arc::clone(&self.payment_store),
Arc::clone(&self.logger),
Arc::clone(&self.config),
)
}

@@ -886,6 +887,7 @@ impl Node {
Arc::clone(&self.channel_manager),
Arc::clone(&self.payment_store),
Arc::clone(&self.logger),
Arc::clone(&self.config),
))
}

Loading