1 package org.ldk.structs;
3 import org.ldk.impl.bindings;
4 import org.ldk.enums.*;
6 import java.util.Arrays;
7 import java.lang.ref.Reference;
8 import javax.annotation.Nullable;
12 * A sender, receiver and forwarder of onion messages. In upcoming releases, this object will be
13 * used to retrieve invoices and fulfill invoice requests from [offers]. Currently, only sending
14 * and receiving custom onion messages is supported.
19 * # extern crate bitcoin;
20 * # use bitcoin::hashes::_export::_core::time::Duration;
21 * # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
22 * # use lightning::blinded_path::BlindedPath;
23 * # use lightning::sign::KeysManager;
24 * # use lightning::ln::peer_handler::IgnoringMessageHandler;
25 * # use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessenger, OnionMessagePath};
26 * # use lightning::onion_message::packet::{CustomOnionMessageContents, OnionMessageContents};
27 * # use lightning::util::logger::{Logger, Record};
28 * # use lightning::util::ser::{Writeable, Writer};
29 * # use lightning::io;
30 * # use std::sync::Arc;
31 * # struct FakeLogger;
32 * # impl Logger for FakeLogger {
33 * # fn log(&self, record: &Record) { unimplemented!() }
35 * # struct FakeMessageRouter {}
36 * # impl MessageRouter for FakeMessageRouter {
37 * # fn find_path(&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination) -> Result<OnionMessagePath, ()> {
41 * # let seed = [42u8; 32];
42 * # let time = Duration::from_secs(123456);
43 * # let keys_manager = KeysManager::new(&seed, time.as_secs(), time.subsec_nanos());
44 * # let logger = Arc::new(FakeLogger {});
45 * # let node_secret = SecretKey::from_slice(&hex::decode(\"0101010101010101010101010101010101010101010101010101010101010101\").unwrap()[..]).unwrap();
46 * # let secp_ctx = Secp256k1::new();
47 * # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
48 * # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1, hop_node_id1);
49 * # let destination_node_id = hop_node_id1;
50 * # let message_router = Arc::new(FakeMessageRouter {});
51 * # let custom_message_handler = IgnoringMessageHandler {};
52 * # let offers_message_handler = IgnoringMessageHandler {};
53 * Create the onion messenger. This must use the same `keys_manager` as is passed to your
55 * let onion_messenger = OnionMessenger::new(
56 * &keys_manager, &keys_manager, logger, message_router, &offers_message_handler,
57 * &custom_message_handler
61 * # struct YourCustomMessage {}
62 * impl Writeable for YourCustomMessage {
63 * \tfn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
65 * \t\t// Write your custom onion message to `w`
68 * impl CustomOnionMessageContents for YourCustomMessage {
69 * \tfn tlv_type(&self) -> u64 {
70 * \t\t# let your_custom_message_type = 42;
71 * \t\tyour_custom_message_type
74 * Send a custom onion message to a node id.
75 * let path = OnionMessagePath {
76 * \tintermediate_nodes: vec![hop_node_id1, hop_node_id2],
77 * \tdestination: Destination::Node(destination_node_id),
79 * let reply_path = None;
80 * # let your_custom_message = YourCustomMessage {};
81 * let message = OnionMessageContents::Custom(your_custom_message);
82 * onion_messenger.send_onion_message(path, message, reply_path);
84 * Create a blinded path to yourself, for someone to send an onion message to.
85 * # let your_node_id = hop_node_id1;
86 * let hops = [hop_node_id3, hop_node_id4, your_node_id];
87 * let blinded_path = BlindedPath::new_for_message(&hops, &keys_manager, &secp_ctx).unwrap();
89 * Send a custom onion message to a blinded path.
90 * let path = OnionMessagePath {
91 * \tintermediate_nodes: vec![hop_node_id1, hop_node_id2],
92 * \tdestination: Destination::BlindedPath(blinded_path),
94 * let reply_path = None;
95 * # let your_custom_message = YourCustomMessage {};
96 * let message = OnionMessageContents::Custom(your_custom_message);
97 * onion_messenger.send_onion_message(path, message, reply_path);
100 * [offers]: <https://github.com/lightning/bolts/pull/798>
101 * [`OnionMessenger`]: crate::onion_message::OnionMessenger
103 @SuppressWarnings("unchecked") // We correctly assign various generic arrays
104 public class OnionMessenger extends CommonBase {
105 OnionMessenger(Object _dummy, long ptr) { super(ptr); }
106 @Override @SuppressWarnings("deprecation")
107 protected void finalize() throws Throwable {
109 if (ptr != 0) { bindings.OnionMessenger_free(ptr); }
113 * Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
114 * their respective handlers.
116 public static OnionMessenger of(org.ldk.structs.EntropySource entropy_source, org.ldk.structs.NodeSigner node_signer, org.ldk.structs.Logger logger, org.ldk.structs.MessageRouter message_router, org.ldk.structs.OffersMessageHandler offers_handler, org.ldk.structs.CustomOnionMessageHandler custom_handler) {
117 long ret = bindings.OnionMessenger_new(entropy_source.ptr, node_signer.ptr, logger.ptr, message_router.ptr, offers_handler.ptr, custom_handler.ptr);
118 Reference.reachabilityFence(entropy_source);
119 Reference.reachabilityFence(node_signer);
120 Reference.reachabilityFence(logger);
121 Reference.reachabilityFence(message_router);
122 Reference.reachabilityFence(offers_handler);
123 Reference.reachabilityFence(custom_handler);
124 if (ret >= 0 && ret <= 4096) { return null; }
125 org.ldk.structs.OnionMessenger ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.OnionMessenger(null, ret); }
126 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
127 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(entropy_source); };
128 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(node_signer); };
129 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(logger); };
130 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(message_router); };
131 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(offers_handler); };
132 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(custom_handler); };
137 * Send an onion message with contents `message` to the destination of `path`.
139 * See [`OnionMessenger`] for example usage.
141 * Note that reply_path (or a relevant inner pointer) may be NULL or all-0s to represent None
143 public Result_NoneSendErrorZ send_onion_message(org.ldk.structs.OnionMessagePath path, org.ldk.structs.OnionMessageContents message, @Nullable org.ldk.structs.BlindedPath reply_path) {
144 long ret = bindings.OnionMessenger_send_onion_message(this.ptr, path == null ? 0 : path.ptr, message.ptr, reply_path == null ? 0 : reply_path.ptr);
145 Reference.reachabilityFence(this);
146 Reference.reachabilityFence(path);
147 Reference.reachabilityFence(message);
148 Reference.reachabilityFence(reply_path);
149 if (ret >= 0 && ret <= 4096) { return null; }
150 Result_NoneSendErrorZ ret_hu_conv = Result_NoneSendErrorZ.constr_from_ptr(ret);
151 if (this != null) { this.ptrs_to.add(path); };
152 if (this != null) { this.ptrs_to.add(message); };
153 if (this != null) { this.ptrs_to.add(reply_path); };
158 * Constructs a new OnionMessageHandler which calls the relevant methods on this_arg.
159 * This copies the `inner` pointer in this_arg and thus the returned OnionMessageHandler must be freed before this_arg is
161 public OnionMessageHandler as_OnionMessageHandler() {
162 long ret = bindings.OnionMessenger_as_OnionMessageHandler(this.ptr);
163 Reference.reachabilityFence(this);
164 if (ret >= 0 && ret <= 4096) { return null; }
165 OnionMessageHandler ret_hu_conv = new OnionMessageHandler(null, ret);
166 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
171 * Constructs a new OnionMessageProvider which calls the relevant methods on this_arg.
172 * This copies the `inner` pointer in this_arg and thus the returned OnionMessageProvider must be freed before this_arg is
174 public OnionMessageProvider as_OnionMessageProvider() {
175 long ret = bindings.OnionMessenger_as_OnionMessageProvider(this.ptr);
176 Reference.reachabilityFence(this);
177 if (ret >= 0 && ret <= 4096) { return null; }
178 OnionMessageProvider ret_hu_conv = new OnionMessageProvider(null, ret);
179 if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };