6 namespace org { namespace ldk { namespace structs {
10 * A sender, receiver and forwarder of [`OnionMessage`]s.
14 * `OnionMessenger` implements [`OnionMessageHandler`], making it responsible for either forwarding
15 * messages to peers or delegating to the appropriate handler for the message type. Currently, the
16 * available handlers are:
17 * [`OffersMessageHandler`], for responding to [`InvoiceRequest`]s and paying [`Bolt12Invoice`]s
18 * [`CustomOnionMessageHandler`], for handling user-defined message types
22 * [`OnionMessage`]s are sent initially using [`OnionMessenger::send_onion_message`]. When handling
23 * a message, the matched handler may return a response message which `OnionMessenger` will send
29 * # extern crate bitcoin;
30 * # use bitcoin::hashes::_export::_core::time::Duration;
31 * # use bitcoin::hashes::hex::FromHex;
32 * # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey, self};
33 * # use lightning::blinded_path::{BlindedPath, EmptyNodeIdLookUp};
34 * # use lightning::sign::{EntropySource, KeysManager};
35 * # use lightning::ln::peer_handler::IgnoringMessageHandler;
36 * # use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath, OnionMessenger};
37 * # use lightning::onion_message::packet::OnionMessageContents;
38 * # use lightning::util::logger::{Logger, Record};
39 * # use lightning::util::ser::{Writeable, Writer};
40 * # use lightning::io;
41 * # use std::sync::Arc;
42 * # struct FakeLogger;
43 * # impl Logger for FakeLogger {
44 * # fn log(&self, record: Record) { println!(\"{:?}\" , record); }
46 * # struct FakeMessageRouter {}
47 * # impl MessageRouter for FakeMessageRouter {
48 * # fn find_path(&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination) -> Result<OnionMessagePath, ()> {
49 * # let secp_ctx = Secp256k1::new();
50 * # let node_secret = SecretKey::from_slice(&<Vec<u8>>::from_hex(\"0101010101010101010101010101010101010101010101010101010101010101\").unwrap()[..]).unwrap();
51 * # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
52 * # let hop_node_id2 = hop_node_id1;
53 * # Ok(OnionMessagePath {
54 * # intermediate_nodes: vec![hop_node_id1, hop_node_id2],
56 * # first_node_addresses: None,
59 * # fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
60 * # &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>
61 * # ) -> Result<Vec<BlindedPath>, ()> {
65 * # let seed = [42u8; 32];
66 * # let time = Duration::from_secs(123456);
67 * # let keys_manager = KeysManager::new(&seed, time.as_secs(), time.subsec_nanos());
68 * # let logger = Arc::new(FakeLogger {});
69 * # let node_secret = SecretKey::from_slice(&<Vec<u8>>::from_hex(\"0101010101010101010101010101010101010101010101010101010101010101\").unwrap()[..]).unwrap();
70 * # let secp_ctx = Secp256k1::new();
71 * # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
72 * # let (hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1);
73 * # let destination_node_id = hop_node_id1;
74 * # let node_id_lookup = EmptyNodeIdLookUp {};
75 * # let message_router = Arc::new(FakeMessageRouter {});
76 * # let custom_message_handler = IgnoringMessageHandler {};
77 * # let offers_message_handler = IgnoringMessageHandler {};
78 * Create the onion messenger. This must use the same `keys_manager` as is passed to your
80 * let onion_messenger = OnionMessenger::new(
81 * &keys_manager, &keys_manager, logger, &node_id_lookup, message_router,
82 * &offers_message_handler, &custom_message_handler
85 * # #[derive(Debug, Clone)]
86 * # struct YourCustomMessage {}
87 * impl Writeable for YourCustomMessage {
88 * \tfn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
90 * \t\t// Write your custom onion message to `w`
93 * impl OnionMessageContents for YourCustomMessage {
94 * \tfn tlv_type(&self) -> u64 {
95 * \t\t# let your_custom_message_type = 42;
96 * \t\tyour_custom_message_type
99 * Send a custom onion message to a node id.
100 * let destination = Destination::Node(destination_node_id);
101 * let reply_path = None;
102 * # let message = YourCustomMessage {};
103 * onion_messenger.send_onion_message(message, destination, reply_path);
105 * Create a blinded path to yourself, for someone to send an onion message to.
106 * # let your_node_id = hop_node_id1;
107 * let hops = [hop_node_id3, hop_node_id4, your_node_id];
108 * let blinded_path = BlindedPath::new_for_message(&hops, &keys_manager, &secp_ctx).unwrap();
110 * Send a custom onion message to a blinded path.
111 * let destination = Destination::BlindedPath(blinded_path);
112 * let reply_path = None;
113 * # let message = YourCustomMessage {};
114 * onion_messenger.send_onion_message(message, destination, reply_path);
117 * [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
118 * [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
120 public class OnionMessenger : CommonBase {
121 internal OnionMessenger(object _dummy, long ptr) : base(ptr) { }
123 if (ptr != 0) { bindings.OnionMessenger_free(ptr); }
127 * Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
128 * their respective handlers.
130 public static OnionMessenger of(org.ldk.structs.EntropySource entropy_source, org.ldk.structs.NodeSigner node_signer, org.ldk.structs.Logger logger, org.ldk.structs.NodeIdLookUp node_id_lookup, org.ldk.structs.MessageRouter message_router, org.ldk.structs.OffersMessageHandler offers_handler, org.ldk.structs.CustomOnionMessageHandler custom_handler) {
131 long ret = bindings.OnionMessenger_new(entropy_source.ptr, node_signer.ptr, logger.ptr, node_id_lookup.ptr, message_router.ptr, offers_handler.ptr, custom_handler.ptr);
132 GC.KeepAlive(entropy_source);
133 GC.KeepAlive(node_signer);
134 GC.KeepAlive(logger);
135 GC.KeepAlive(node_id_lookup);
136 GC.KeepAlive(message_router);
137 GC.KeepAlive(offers_handler);
138 GC.KeepAlive(custom_handler);
139 if (ret >= 0 && ret <= 4096) { return null; }
140 org.ldk.structs.OnionMessenger ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.OnionMessenger(null, ret); }
141 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.AddLast(ret_hu_conv); };
142 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.AddLast(entropy_source); };
143 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.AddLast(node_signer); };
144 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.AddLast(logger); };
145 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.AddLast(node_id_lookup); };
146 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.AddLast(message_router); };
147 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.AddLast(offers_handler); };
148 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.AddLast(custom_handler); };
153 * Sends an [`OnionMessage`] with the given `contents` to `destination`.
155 * See [`OnionMessenger`] for example usage.
157 * Note that reply_path (or a relevant inner pointer) may be NULL or all-0s to represent None
159 public Result_SendSuccessSendErrorZ send_onion_message(org.ldk.structs.OnionMessageContents contents, org.ldk.structs.Destination destination, org.ldk.structs.BlindedPath reply_path) {
160 long ret = bindings.OnionMessenger_send_onion_message(this.ptr, contents.ptr, destination.ptr, reply_path == null ? 0 : reply_path.ptr);
162 GC.KeepAlive(contents);
163 GC.KeepAlive(destination);
164 GC.KeepAlive(reply_path);
165 if (ret >= 0 && ret <= 4096) { return null; }
166 Result_SendSuccessSendErrorZ ret_hu_conv = Result_SendSuccessSendErrorZ.constr_from_ptr(ret);
167 if (this != null) { this.ptrs_to.AddLast(contents); };
168 if (this != null) { this.ptrs_to.AddLast(destination); };
169 if (this != null) { this.ptrs_to.AddLast(reply_path); };
174 * Constructs a new OnionMessageHandler which calls the relevant methods on this_arg.
175 * This copies the `inner` pointer in this_arg and thus the returned OnionMessageHandler must be freed before this_arg is
177 public OnionMessageHandler as_OnionMessageHandler() {
178 long ret = bindings.OnionMessenger_as_OnionMessageHandler(this.ptr);
180 if (ret >= 0 && ret <= 4096) { return null; }
181 OnionMessageHandler ret_hu_conv = new OnionMessageHandler(null, ret);
182 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.AddLast(this); };