[Java] Update auto-generated Java files
authorMatt Corallo <git@bluematt.me>
Thu, 29 Sep 2022 23:05:40 +0000 (23:05 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 3 Oct 2022 21:39:09 +0000 (21:39 +0000)
61 files changed:
src/main/java/org/ldk/impl/bindings.java
src/main/java/org/ldk/structs/BackgroundProcessor.java
src/main/java/org/ldk/structs/Balance.java
src/main/java/org/ldk/structs/BigEndianScalar.java [new file with mode: 0644]
src/main/java/org/ldk/structs/BlindedHop.java [new file with mode: 0644]
src/main/java/org/ldk/structs/BlindedRoute.java [new file with mode: 0644]
src/main/java/org/ldk/structs/ChannelHandshakeConfig.java
src/main/java/org/ldk/structs/ChannelManager.java
src/main/java/org/ldk/structs/ChannelMessageHandler.java
src/main/java/org/ldk/structs/ChannelMonitor.java
src/main/java/org/ldk/structs/ChannelMonitorUpdate.java
src/main/java/org/ldk/structs/Confirm.java
src/main/java/org/ldk/structs/DefaultRouter.java
src/main/java/org/ldk/structs/Destination.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Event.java
src/main/java/org/ldk/structs/EventsProvider.java
src/main/java/org/ldk/structs/Filter.java
src/main/java/org/ldk/structs/Future.java [new file with mode: 0644]
src/main/java/org/ldk/structs/FutureCallback.java [new file with mode: 0644]
src/main/java/org/ldk/structs/IgnoringMessageHandler.java
src/main/java/org/ldk/structs/InFlightHtlcs.java [new file with mode: 0644]
src/main/java/org/ldk/structs/InitFeatures.java
src/main/java/org/ldk/structs/Invoice.java
src/main/java/org/ldk/structs/InvoicePayer.java
src/main/java/org/ldk/structs/InvoiceSignature.java
src/main/java/org/ldk/structs/KeysInterface.java
src/main/java/org/ldk/structs/MessageHandler.java
src/main/java/org/ldk/structs/MessageSendEvent.java
src/main/java/org/ldk/structs/MultiThreadedLockableScore.java
src/main/java/org/ldk/structs/MultiThreadedScoreLock.java [new file with mode: 0644]
src/main/java/org/ldk/structs/NodeFeatures.java
src/main/java/org/ldk/structs/OnionMessage.java [new file with mode: 0644]
src/main/java/org/ldk/structs/OnionMessageHandler.java [new file with mode: 0644]
src/main/java/org/ldk/structs/OnionMessageProvider.java [new file with mode: 0644]
src/main/java/org/ldk/structs/OnionMessenger.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Option_C2Tuple_usizeTransactionZZ.java [deleted file]
src/main/java/org/ldk/structs/Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Option_ScalarZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Option_WriteableScoreZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/PeerManager.java
src/main/java/org/ldk/structs/Persister.java
src/main/java/org/ldk/structs/PositiveTimestamp.java
src/main/java/org/ldk/structs/RawDataPart.java
src/main/java/org/ldk/structs/RawInvoice.java
src/main/java/org/ldk/structs/Result_BlindedHopDecodeErrorZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Result_BlindedRouteDecodeErrorZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Result_BlindedRouteNoneZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Result_InFlightHtlcsDecodeErrorZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Result_NoneSendErrorZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Result_OnionMessageDecodeErrorZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Result_SharedSecretNoneZ.java [new file with mode: 0644]
src/main/java/org/ldk/structs/Router.java
src/main/java/org/ldk/structs/RoutingMessageHandler.java
src/main/java/org/ldk/structs/SendError.java [new file with mode: 0644]
src/main/java/org/ldk/structs/SignedRawInvoice.java
src/main/java/org/ldk/structs/WatchedOutput.java
src/main/java/org/ldk/structs/WriteableScore.java [new file with mode: 0644]
src/main/jni/bindings.c
src/main/jni/bindings.c.body
src/main/jni/org_ldk_impl_bindings.h
src/main/jni/org_ldk_impl_bindings_LDKCOption_C2Tuple_usizeTransactionZZ.h [deleted file]

index dffb7e8c7ac78030b63d982e0d4e07cece1bf0e1..443a1a42894199c1a494aaa4bb52e87a0c5fba02 100644 (file)
@@ -79,6 +79,10 @@ public class bindings {
        static { Secp256k1Error.values(); /* Force enum statics to run */ }
        static { SemanticError.values(); /* Force enum statics to run */ }
        static { SiPrefix.values(); /* Force enum statics to run */ }
+       // struct LDKThirtyTwoBytes BigEndianScalar_get_bytes (struct LDKBigEndianScalar* thing)
+       public static native byte[] BigEndianScalar_get_bytes(long thing);
+       // static void BigEndianScalar_free (struct LDKBigEndianScalar thing)
+       public static native void BigEndianScalar_free(long thing);
        public static class LDKBech32Error {
                private LDKBech32Error() {}
                public final static class MissingSeparator extends LDKBech32Error {
@@ -112,6 +116,18 @@ public class bindings {
        public static native byte[] TxOut_get_script_pubkey(long thing);
        // uint64_t TxOut_get_value (struct LDKTxOut* thing)
        public static native long TxOut_get_value(long thing);
+       // struct LDKBlindedRoute CResult_BlindedRouteNoneZ_get_ok(LDKCResult_BlindedRouteNoneZ *NONNULL_PTR owner);
+       public static native long CResult_BlindedRouteNoneZ_get_ok(long owner);
+       // void CResult_BlindedRouteNoneZ_get_err(LDKCResult_BlindedRouteNoneZ *NONNULL_PTR owner);
+       public static native void CResult_BlindedRouteNoneZ_get_err(long owner);
+       // struct LDKBlindedRoute CResult_BlindedRouteDecodeErrorZ_get_ok(LDKCResult_BlindedRouteDecodeErrorZ *NONNULL_PTR owner);
+       public static native long CResult_BlindedRouteDecodeErrorZ_get_ok(long owner);
+       // struct LDKDecodeError CResult_BlindedRouteDecodeErrorZ_get_err(LDKCResult_BlindedRouteDecodeErrorZ *NONNULL_PTR owner);
+       public static native long CResult_BlindedRouteDecodeErrorZ_get_err(long owner);
+       // struct LDKBlindedHop CResult_BlindedHopDecodeErrorZ_get_ok(LDKCResult_BlindedHopDecodeErrorZ *NONNULL_PTR owner);
+       public static native long CResult_BlindedHopDecodeErrorZ_get_ok(long owner);
+       // struct LDKDecodeError CResult_BlindedHopDecodeErrorZ_get_err(LDKCResult_BlindedHopDecodeErrorZ *NONNULL_PTR owner);
+       public static native long CResult_BlindedHopDecodeErrorZ_get_err(long owner);
        // void CResult_NoneNoneZ_get_ok(LDKCResult_NoneNoneZ *NONNULL_PTR owner);
        public static native void CResult_NoneNoneZ_get_ok(long owner);
        // void CResult_NoneNoneZ_get_err(LDKCResult_NoneNoneZ *NONNULL_PTR owner);
@@ -197,6 +213,53 @@ public class bindings {
        public static native long CResult_ShutdownScriptInvalidShutdownScriptZ_get_ok(long owner);
        // struct LDKInvalidShutdownScript CResult_ShutdownScriptInvalidShutdownScriptZ_get_err(LDKCResult_ShutdownScriptInvalidShutdownScriptZ *NONNULL_PTR owner);
        public static native long CResult_ShutdownScriptInvalidShutdownScriptZ_get_err(long owner);
+       public interface LDKScore {
+                long channel_penalty_msat(long short_channel_id, long source, long target, long usage);
+                void payment_path_failed(long[] path, long short_channel_id);
+                void payment_path_successful(long[] path);
+                void probe_failed(long[] path, long short_channel_id);
+                void probe_successful(long[] path);
+                byte[] write();
+       }
+       public static native long LDKScore_new(LDKScore impl);
+       // uint64_t Score_channel_penalty_msat LDKScore *NONNULL_PTR this_arg, uint64_t short_channel_id, const struct LDKNodeId *NONNULL_PTR source, const struct LDKNodeId *NONNULL_PTR target, struct LDKChannelUsage usage
+       public static native long Score_channel_penalty_msat(long this_arg, long short_channel_id, long source, long target, long usage);
+       // void Score_payment_path_failed LDKScore *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path, uint64_t short_channel_id
+       public static native void Score_payment_path_failed(long this_arg, long[] path, long short_channel_id);
+       // void Score_payment_path_successful LDKScore *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path
+       public static native void Score_payment_path_successful(long this_arg, long[] path);
+       // void Score_probe_failed LDKScore *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path, uint64_t short_channel_id
+       public static native void Score_probe_failed(long this_arg, long[] path, long short_channel_id);
+       // void Score_probe_successful LDKScore *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path
+       public static native void Score_probe_successful(long this_arg, long[] path);
+       // LDKCVec_u8Z Score_write LDKScore *NONNULL_PTR this_arg
+       public static native byte[] Score_write(long this_arg);
+       public interface LDKLockableScore {
+                long lock();
+       }
+       public static native long LDKLockableScore_new(LDKLockableScore impl);
+       // LDKScore LockableScore_lock LDKLockableScore *NONNULL_PTR this_arg
+       public static native long LockableScore_lock(long this_arg);
+       public interface LDKWriteableScore {
+                byte[] write();
+       }
+       public static native long LDKWriteableScore_new(LDKWriteableScore impl, LDKLockableScore LockableScore);
+       public static native long LDKWriteableScore_get_LockableScore(long arg);
+       // LDKCVec_u8Z WriteableScore_write LDKWriteableScore *NONNULL_PTR this_arg
+       public static native byte[] WriteableScore_write(long this_arg);
+       public static class LDKCOption_WriteableScoreZ {
+               private LDKCOption_WriteableScoreZ() {}
+               public final static class Some extends LDKCOption_WriteableScoreZ {
+                       public long some;
+                       Some(long some) { this.some = some; }
+               }
+               public final static class None extends LDKCOption_WriteableScoreZ {
+                       None() { }
+               }
+               static native void init();
+       }
+       static { LDKCOption_WriteableScoreZ.init(); }
+       public static native LDKCOption_WriteableScoreZ LDKCOption_WriteableScoreZ_ref_from_ptr(long ptr);
        // void CResult_NoneErrorZ_get_ok(LDKCResult_NoneErrorZ *NONNULL_PTR owner);
        public static native void CResult_NoneErrorZ_get_ok(long owner);
        // enum LDKIOError CResult_NoneErrorZ_get_err(LDKCResult_NoneErrorZ *NONNULL_PTR owner);
@@ -441,13 +504,13 @@ public class bindings {
                public final static class PaymentPathFailed extends LDKEvent {
                        public byte[] payment_id;
                        public byte[] payment_hash;
-                       public boolean rejected_by_dest;
+                       public boolean payment_failed_permanently;
                        public long network_update;
                        public boolean all_paths_failed;
                        public long[] path;
                        public long short_channel_id;
                        public long retry;
-                       PaymentPathFailed(byte[] payment_id, byte[] payment_hash, boolean rejected_by_dest, long network_update, boolean all_paths_failed, long[] path, long short_channel_id, long retry) { this.payment_id = payment_id; this.payment_hash = payment_hash; this.rejected_by_dest = rejected_by_dest; this.network_update = network_update; this.all_paths_failed = all_paths_failed; this.path = path; this.short_channel_id = short_channel_id; this.retry = retry; }
+                       PaymentPathFailed(byte[] payment_id, byte[] payment_hash, boolean payment_failed_permanently, long network_update, boolean all_paths_failed, long[] path, long short_channel_id, long retry) { this.payment_id = payment_id; this.payment_hash = payment_hash; this.payment_failed_permanently = payment_failed_permanently; this.network_update = network_update; this.all_paths_failed = all_paths_failed; this.path = path; this.short_channel_id = short_channel_id; this.retry = retry; }
                }
                public final static class ProbeSuccessful extends LDKEvent {
                        public byte[] payment_id;
@@ -608,14 +671,16 @@ public class bindings {
                        public long msg;
                        SendChannelReestablish(byte[] node_id, long msg) { this.node_id = node_id; this.msg = msg; }
                }
-               public final static class BroadcastChannelAnnouncement extends LDKMessageSendEvent {
+               public final static class SendChannelAnnouncement extends LDKMessageSendEvent {
+                       public byte[] node_id;
                        public long msg;
                        public long update_msg;
-                       BroadcastChannelAnnouncement(long msg, long update_msg) { this.msg = msg; this.update_msg = update_msg; }
+                       SendChannelAnnouncement(byte[] node_id, long msg, long update_msg) { this.node_id = node_id; this.msg = msg; this.update_msg = update_msg; }
                }
-               public final static class BroadcastNodeAnnouncement extends LDKMessageSendEvent {
+               public final static class BroadcastChannelAnnouncement extends LDKMessageSendEvent {
                        public long msg;
-                       BroadcastNodeAnnouncement(long msg) { this.msg = msg; }
+                       public long update_msg;
+                       BroadcastChannelAnnouncement(long msg, long update_msg) { this.msg = msg; this.update_msg = update_msg; }
                }
                public final static class BroadcastChannelUpdate extends LDKMessageSendEvent {
                        public long msg;
@@ -696,19 +761,6 @@ public class bindings {
        public static native long[] C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_get_b(long owner);
        // struct LDKPublicKey C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_get_c(LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ *NONNULL_PTR owner);
        public static native byte[] C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_get_c(long owner);
-       public static class LDKCOption_C2Tuple_usizeTransactionZZ {
-               private LDKCOption_C2Tuple_usizeTransactionZZ() {}
-               public final static class Some extends LDKCOption_C2Tuple_usizeTransactionZZ {
-                       public long some;
-                       Some(long some) { this.some = some; }
-               }
-               public final static class None extends LDKCOption_C2Tuple_usizeTransactionZZ {
-                       None() { }
-               }
-               static native void init();
-       }
-       static { LDKCOption_C2Tuple_usizeTransactionZZ.init(); }
-       public static native LDKCOption_C2Tuple_usizeTransactionZZ LDKCOption_C2Tuple_usizeTransactionZZ_ref_from_ptr(long ptr);
        // struct LDKFixedPenaltyScorer CResult_FixedPenaltyScorerDecodeErrorZ_get_ok(LDKCResult_FixedPenaltyScorerDecodeErrorZ *NONNULL_PTR owner);
        public static native long CResult_FixedPenaltyScorerDecodeErrorZ_get_ok(long owner);
        // struct LDKDecodeError CResult_FixedPenaltyScorerDecodeErrorZ_get_err(LDKCResult_FixedPenaltyScorerDecodeErrorZ *NONNULL_PTR owner);
@@ -795,6 +847,19 @@ public class bindings {
        public static native long C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_get_b(long owner);
        // struct LDKChannelUpdate C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_get_c(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ *NONNULL_PTR owner);
        public static native long C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_get_c(long owner);
+       public static class LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ {
+               private LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ() {}
+               public final static class Some extends LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ {
+                       public long some;
+                       Some(long some) { this.some = some; }
+               }
+               public final static class None extends LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ {
+                       None() { }
+               }
+               static native void init();
+       }
+       static { LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.init(); }
+       public static native LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_ref_from_ptr(long ptr);
        // void CResult_NoneLightningErrorZ_get_ok(LDKCResult_NoneLightningErrorZ *NONNULL_PTR owner);
        public static native void CResult_NoneLightningErrorZ_get_ok(long owner);
        // struct LDKLightningError CResult_NoneLightningErrorZ_get_err(LDKCResult_NoneLightningErrorZ *NONNULL_PTR owner);
@@ -908,6 +973,23 @@ public class bindings {
        public static native byte[] CResult_SecretKeyNoneZ_get_ok(long owner);
        // void CResult_SecretKeyNoneZ_get_err(LDKCResult_SecretKeyNoneZ *NONNULL_PTR owner);
        public static native void CResult_SecretKeyNoneZ_get_err(long owner);
+       public static class LDKCOption_ScalarZ {
+               private LDKCOption_ScalarZ() {}
+               public final static class Some extends LDKCOption_ScalarZ {
+                       public long some;
+                       Some(long some) { this.some = some; }
+               }
+               public final static class None extends LDKCOption_ScalarZ {
+                       None() { }
+               }
+               static native void init();
+       }
+       static { LDKCOption_ScalarZ.init(); }
+       public static native LDKCOption_ScalarZ LDKCOption_ScalarZ_ref_from_ptr(long ptr);
+       // struct LDKThirtyTwoBytes CResult_SharedSecretNoneZ_get_ok(LDKCResult_SharedSecretNoneZ *NONNULL_PTR owner);
+       public static native byte[] CResult_SharedSecretNoneZ_get_ok(long owner);
+       // void CResult_SharedSecretNoneZ_get_err(LDKCResult_SharedSecretNoneZ *NONNULL_PTR owner);
+       public static native void CResult_SharedSecretNoneZ_get_err(long owner);
        public interface LDKBaseSign {
                 byte[] get_per_commitment_point(long idx);
                 byte[] release_commitment_secret(long idx);
@@ -1138,6 +1220,7 @@ public class bindings {
        public static native void BroadcasterInterface_broadcast_transaction(long this_arg, byte[] tx);
        public interface LDKKeysInterface {
                 long get_node_secret(Recipient recipient);
+                long ecdh(Recipient recipient, byte[] other_key, long tweak);
                 byte[] get_destination_script();
                 long get_shutdown_scriptpubkey();
                 long get_channel_signer(boolean inbound, long channel_value_satoshis);
@@ -1149,6 +1232,8 @@ public class bindings {
        public static native long LDKKeysInterface_new(LDKKeysInterface impl);
        // LDKCResult_SecretKeyNoneZ KeysInterface_get_node_secret LDKKeysInterface *NONNULL_PTR this_arg, enum LDKRecipient recipient
        public static native long KeysInterface_get_node_secret(long this_arg, Recipient recipient);
+       // LDKCResult_SharedSecretNoneZ KeysInterface_ecdh LDKKeysInterface *NONNULL_PTR this_arg, enum LDKRecipient recipient, struct LDKPublicKey other_key, struct LDKCOption_ScalarZ tweak
+       public static native long KeysInterface_ecdh(long this_arg, Recipient recipient, byte[] other_key, long tweak);
        // LDKCVec_u8Z KeysInterface_get_destination_script LDKKeysInterface *NONNULL_PTR this_arg
        public static native byte[] KeysInterface_get_destination_script(long this_arg);
        // LDKShutdownScript KeysInterface_get_shutdown_scriptpubkey LDKKeysInterface *NONNULL_PTR this_arg
@@ -1236,6 +1321,10 @@ public class bindings {
        public static native byte[] CResult_PaymentIdPaymentErrorZ_get_ok(long owner);
        // struct LDKPaymentError CResult_PaymentIdPaymentErrorZ_get_err(LDKCResult_PaymentIdPaymentErrorZ *NONNULL_PTR owner);
        public static native long CResult_PaymentIdPaymentErrorZ_get_err(long owner);
+       // struct LDKInFlightHtlcs CResult_InFlightHtlcsDecodeErrorZ_get_ok(LDKCResult_InFlightHtlcsDecodeErrorZ *NONNULL_PTR owner);
+       public static native long CResult_InFlightHtlcsDecodeErrorZ_get_ok(long owner);
+       // struct LDKDecodeError CResult_InFlightHtlcsDecodeErrorZ_get_err(LDKCResult_InFlightHtlcsDecodeErrorZ *NONNULL_PTR owner);
+       public static native long CResult_InFlightHtlcsDecodeErrorZ_get_err(long owner);
        public static class LDKParseError {
                private LDKParseError() {}
                public final static class Bech32Error extends LDKParseError {
@@ -1422,10 +1511,19 @@ public class bindings {
                        public int timeout_height;
                        ContentiousClaimable(long claimable_amount_satoshis, int timeout_height) { this.claimable_amount_satoshis = claimable_amount_satoshis; this.timeout_height = timeout_height; }
                }
-               public final static class MaybeClaimableHTLCAwaitingTimeout extends LDKBalance {
+               public final static class MaybeTimeoutClaimableHTLC extends LDKBalance {
                        public long claimable_amount_satoshis;
                        public int claimable_height;
-                       MaybeClaimableHTLCAwaitingTimeout(long claimable_amount_satoshis, int claimable_height) { this.claimable_amount_satoshis = claimable_amount_satoshis; this.claimable_height = claimable_height; }
+                       MaybeTimeoutClaimableHTLC(long claimable_amount_satoshis, int claimable_height) { this.claimable_amount_satoshis = claimable_amount_satoshis; this.claimable_height = claimable_height; }
+               }
+               public final static class MaybePreimageClaimableHTLC extends LDKBalance {
+                       public long claimable_amount_satoshis;
+                       public int expiry_height;
+                       MaybePreimageClaimableHTLC(long claimable_amount_satoshis, int expiry_height) { this.claimable_amount_satoshis = claimable_amount_satoshis; this.expiry_height = expiry_height; }
+               }
+               public final static class CounterpartyRevokedOutputClaimable extends LDKBalance {
+                       public long claimable_amount_satoshis;
+                       CounterpartyRevokedOutputClaimable(long claimable_amount_satoshis) { this.claimable_amount_satoshis = claimable_amount_satoshis; }
                }
                static native void init();
        }
@@ -1464,6 +1562,32 @@ public class bindings {
        public static native boolean CResult_boolPeerHandleErrorZ_get_ok(long owner);
        // struct LDKPeerHandleError CResult_boolPeerHandleErrorZ_get_err(LDKCResult_boolPeerHandleErrorZ *NONNULL_PTR owner);
        public static native long CResult_boolPeerHandleErrorZ_get_err(long owner);
+       public static class LDKSendError {
+               private LDKSendError() {}
+               public final static class Secp256k1 extends LDKSendError {
+                       public org.ldk.enums.Secp256k1Error secp256k1;
+                       Secp256k1(org.ldk.enums.Secp256k1Error secp256k1) { this.secp256k1 = secp256k1; }
+               }
+               public final static class TooBigPacket extends LDKSendError {
+                       TooBigPacket() { }
+               }
+               public final static class TooFewBlindedHops extends LDKSendError {
+                       TooFewBlindedHops() { }
+               }
+               public final static class InvalidFirstHop extends LDKSendError {
+                       InvalidFirstHop() { }
+               }
+               public final static class BufferFull extends LDKSendError {
+                       BufferFull() { }
+               }
+               static native void init();
+       }
+       static { LDKSendError.init(); }
+       public static native LDKSendError LDKSendError_ref_from_ptr(long ptr);
+       // void CResult_NoneSendErrorZ_get_ok(LDKCResult_NoneSendErrorZ *NONNULL_PTR owner);
+       public static native void CResult_NoneSendErrorZ_get_ok(long owner);
+       // struct LDKSendError CResult_NoneSendErrorZ_get_err(LDKCResult_NoneSendErrorZ *NONNULL_PTR owner);
+       public static native long CResult_NoneSendErrorZ_get_err(long owner);
        public static class LDKGraphSyncError {
                private LDKGraphSyncError() {}
                public final static class DecodeError extends LDKGraphSyncError {
@@ -1558,6 +1682,10 @@ public class bindings {
        public static native long CResult_UpdateAddHTLCDecodeErrorZ_get_ok(long owner);
        // struct LDKDecodeError CResult_UpdateAddHTLCDecodeErrorZ_get_err(LDKCResult_UpdateAddHTLCDecodeErrorZ *NONNULL_PTR owner);
        public static native long CResult_UpdateAddHTLCDecodeErrorZ_get_err(long owner);
+       // struct LDKOnionMessage CResult_OnionMessageDecodeErrorZ_get_ok(LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR owner);
+       public static native long CResult_OnionMessageDecodeErrorZ_get_ok(long owner);
+       // struct LDKDecodeError CResult_OnionMessageDecodeErrorZ_get_err(LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR owner);
+       public static native long CResult_OnionMessageDecodeErrorZ_get_err(long owner);
        // struct LDKPing CResult_PingDecodeErrorZ_get_ok(LDKCResult_PingDecodeErrorZ *NONNULL_PTR owner);
        public static native long CResult_PingDecodeErrorZ_get_ok(long owner);
        // struct LDKDecodeError CResult_PingDecodeErrorZ_get_err(LDKCResult_PingDecodeErrorZ *NONNULL_PTR owner);
@@ -1637,13 +1765,13 @@ public class bindings {
        public static native long CResult_InvoiceSignOrCreationErrorZ_get_err(long owner);
        public interface LDKFilter {
                 void register_tx(byte[] txid, byte[] script_pubkey);
-                long register_output(long output);
+                void register_output(long output);
        }
        public static native long LDKFilter_new(LDKFilter impl);
        // void Filter_register_tx LDKFilter *NONNULL_PTR this_arg, const uint8_t (*txid)[32], struct LDKu8slice script_pubkey
        public static native void Filter_register_tx(long this_arg, byte[] txid, byte[] script_pubkey);
-       // LDKCOption_C2Tuple_usizeTransactionZZ Filter_register_output LDKFilter *NONNULL_PTR this_arg, struct LDKWatchedOutput output
-       public static native long Filter_register_output(long this_arg, long output);
+       // void Filter_register_output LDKFilter *NONNULL_PTR this_arg, struct LDKWatchedOutput output
+       public static native void Filter_register_output(long this_arg, long output);
        public static class LDKCOption_FilterZ {
                private LDKCOption_FilterZ() {}
                public final static class Some extends LDKCOption_FilterZ {
@@ -1667,6 +1795,12 @@ public class bindings {
        public static native long LDKMessageSendEventsProvider_new(LDKMessageSendEventsProvider impl);
        // LDKCVec_MessageSendEventZ MessageSendEventsProvider_get_and_clear_pending_msg_events LDKMessageSendEventsProvider *NONNULL_PTR this_arg
        public static native long[] MessageSendEventsProvider_get_and_clear_pending_msg_events(long this_arg);
+       public interface LDKOnionMessageProvider {
+                long next_onion_message_for_peer(byte[] peer_node_id);
+       }
+       public static native long LDKOnionMessageProvider_new(LDKOnionMessageProvider impl);
+       // LDKOnionMessage OnionMessageProvider_next_onion_message_for_peer LDKOnionMessageProvider *NONNULL_PTR this_arg, struct LDKPublicKey peer_node_id
+       public static native long OnionMessageProvider_next_onion_message_for_peer(long this_arg, byte[] peer_node_id);
        public interface LDKEventHandler {
                 void handle_event(long event);
        }
@@ -1679,27 +1813,6 @@ public class bindings {
        public static native long LDKEventsProvider_new(LDKEventsProvider impl);
        // void EventsProvider_process_pending_events LDKEventsProvider *NONNULL_PTR this_arg, struct LDKEventHandler handler
        public static native void EventsProvider_process_pending_events(long this_arg, long handler);
-       public interface LDKScore {
-                long channel_penalty_msat(long short_channel_id, long source, long target, long usage);
-                void payment_path_failed(long[] path, long short_channel_id);
-                void payment_path_successful(long[] path);
-                void probe_failed(long[] path, long short_channel_id);
-                void probe_successful(long[] path);
-                byte[] write();
-       }
-       public static native long LDKScore_new(LDKScore impl);
-       // uint64_t Score_channel_penalty_msat LDKScore *NONNULL_PTR this_arg, uint64_t short_channel_id, const struct LDKNodeId *NONNULL_PTR source, const struct LDKNodeId *NONNULL_PTR target, struct LDKChannelUsage usage
-       public static native long Score_channel_penalty_msat(long this_arg, long short_channel_id, long source, long target, long usage);
-       // void Score_payment_path_failed LDKScore *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path, uint64_t short_channel_id
-       public static native void Score_payment_path_failed(long this_arg, long[] path, long short_channel_id);
-       // void Score_payment_path_successful LDKScore *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path
-       public static native void Score_payment_path_successful(long this_arg, long[] path);
-       // void Score_probe_failed LDKScore *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path, uint64_t short_channel_id
-       public static native void Score_probe_failed(long this_arg, long[] path, long short_channel_id);
-       // void Score_probe_successful LDKScore *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path
-       public static native void Score_probe_successful(long this_arg, long[] path);
-       // LDKCVec_u8Z Score_write LDKScore *NONNULL_PTR this_arg
-       public static native byte[] Score_write(long this_arg);
        public interface LDKPersister {
                 long persist_manager(long channel_manager);
                 long persist_graph(long network_graph);
@@ -1710,8 +1823,14 @@ public class bindings {
        public static native long Persister_persist_manager(long this_arg, long channel_manager);
        // LDKCResult_NoneErrorZ Persister_persist_graph LDKPersister *NONNULL_PTR this_arg, const struct LDKNetworkGraph *NONNULL_PTR network_graph
        public static native long Persister_persist_graph(long this_arg, long network_graph);
-       // LDKCResult_NoneErrorZ Persister_persist_scorer LDKPersister *NONNULL_PTR this_arg, const struct LDKMultiThreadedLockableScore *NONNULL_PTR scorer
+       // LDKCResult_NoneErrorZ Persister_persist_scorer LDKPersister *NONNULL_PTR this_arg, const struct LDKWriteableScore *NONNULL_PTR scorer
        public static native long Persister_persist_scorer(long this_arg, long scorer);
+       public interface LDKFutureCallback {
+                void call();
+       }
+       public static native long LDKFutureCallback_new(LDKFutureCallback impl);
+       // void FutureCallback_call LDKFutureCallback *NONNULL_PTR this_arg
+       public static native void FutureCallback_call(long this_arg);
        public interface LDKListen {
                 void filtered_block_connected(byte[] header, long[] txdata, int height);
                 void block_connected(byte[] block, int height);
@@ -1769,6 +1888,8 @@ public class bindings {
                 void handle_channel_reestablish(byte[] their_node_id, long msg);
                 void handle_channel_update(byte[] their_node_id, long msg);
                 void handle_error(byte[] their_node_id, long msg);
+                long provided_node_features();
+                long provided_init_features(byte[] their_node_id);
        }
        public static native long LDKChannelMessageHandler_new(LDKChannelMessageHandler impl, LDKMessageSendEventsProvider MessageSendEventsProvider);
        public static native long LDKChannelMessageHandler_get_MessageSendEventsProvider(long arg);
@@ -1812,17 +1933,23 @@ public class bindings {
        public static native void ChannelMessageHandler_handle_channel_update(long this_arg, byte[] their_node_id, long msg);
        // void ChannelMessageHandler_handle_error LDKChannelMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id, const struct LDKErrorMessage *NONNULL_PTR msg
        public static native void ChannelMessageHandler_handle_error(long this_arg, byte[] their_node_id, long msg);
+       // LDKNodeFeatures ChannelMessageHandler_provided_node_features LDKChannelMessageHandler *NONNULL_PTR this_arg
+       public static native long ChannelMessageHandler_provided_node_features(long this_arg);
+       // LDKInitFeatures ChannelMessageHandler_provided_init_features LDKChannelMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id
+       public static native long ChannelMessageHandler_provided_init_features(long this_arg, byte[] their_node_id);
        public interface LDKRoutingMessageHandler {
                 long handle_node_announcement(long msg);
                 long handle_channel_announcement(long msg);
                 long handle_channel_update(long msg);
-                long[] get_next_channel_announcements(long starting_point, byte batch_amount);
-                long[] get_next_node_announcements(byte[] starting_point, byte batch_amount);
+                long get_next_channel_announcement(long starting_point);
+                long get_next_node_announcement(byte[] starting_point);
                 void peer_connected(byte[] their_node_id, long init);
                 long handle_reply_channel_range(byte[] their_node_id, long msg);
                 long handle_reply_short_channel_ids_end(byte[] their_node_id, long msg);
                 long handle_query_channel_range(byte[] their_node_id, long msg);
                 long handle_query_short_channel_ids(byte[] their_node_id, long msg);
+                long provided_node_features();
+                long provided_init_features(byte[] their_node_id);
        }
        public static native long LDKRoutingMessageHandler_new(LDKRoutingMessageHandler impl, LDKMessageSendEventsProvider MessageSendEventsProvider);
        public static native long LDKRoutingMessageHandler_get_MessageSendEventsProvider(long arg);
@@ -1832,10 +1959,10 @@ public class bindings {
        public static native long RoutingMessageHandler_handle_channel_announcement(long this_arg, long msg);
        // LDKCResult_boolLightningErrorZ RoutingMessageHandler_handle_channel_update LDKRoutingMessageHandler *NONNULL_PTR this_arg, const struct LDKChannelUpdate *NONNULL_PTR msg
        public static native long RoutingMessageHandler_handle_channel_update(long this_arg, long msg);
-       // LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ RoutingMessageHandler_get_next_channel_announcements LDKRoutingMessageHandler *NONNULL_PTR this_arg, uint64_t starting_point, uint8_t batch_amount
-       public static native long[] RoutingMessageHandler_get_next_channel_announcements(long this_arg, long starting_point, byte batch_amount);
-       // LDKCVec_NodeAnnouncementZ RoutingMessageHandler_get_next_node_announcements LDKRoutingMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey starting_point, uint8_t batch_amount
-       public static native long[] RoutingMessageHandler_get_next_node_announcements(long this_arg, byte[] starting_point, byte batch_amount);
+       // LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ RoutingMessageHandler_get_next_channel_announcement LDKRoutingMessageHandler *NONNULL_PTR this_arg, uint64_t starting_point
+       public static native long RoutingMessageHandler_get_next_channel_announcement(long this_arg, long starting_point);
+       // LDKNodeAnnouncement RoutingMessageHandler_get_next_node_announcement LDKRoutingMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey starting_point
+       public static native long RoutingMessageHandler_get_next_node_announcement(long this_arg, byte[] starting_point);
        // void RoutingMessageHandler_peer_connected LDKRoutingMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id, const struct LDKInit *NONNULL_PTR init
        public static native void RoutingMessageHandler_peer_connected(long this_arg, byte[] their_node_id, long init);
        // LDKCResult_NoneLightningErrorZ RoutingMessageHandler_handle_reply_channel_range LDKRoutingMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id, struct LDKReplyChannelRange msg
@@ -1846,6 +1973,29 @@ public class bindings {
        public static native long RoutingMessageHandler_handle_query_channel_range(long this_arg, byte[] their_node_id, long msg);
        // LDKCResult_NoneLightningErrorZ RoutingMessageHandler_handle_query_short_channel_ids LDKRoutingMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id, struct LDKQueryShortChannelIds msg
        public static native long RoutingMessageHandler_handle_query_short_channel_ids(long this_arg, byte[] their_node_id, long msg);
+       // LDKNodeFeatures RoutingMessageHandler_provided_node_features LDKRoutingMessageHandler *NONNULL_PTR this_arg
+       public static native long RoutingMessageHandler_provided_node_features(long this_arg);
+       // LDKInitFeatures RoutingMessageHandler_provided_init_features LDKRoutingMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id
+       public static native long RoutingMessageHandler_provided_init_features(long this_arg, byte[] their_node_id);
+       public interface LDKOnionMessageHandler {
+                void handle_onion_message(byte[] peer_node_id, long msg);
+                void peer_connected(byte[] their_node_id, long init);
+                void peer_disconnected(byte[] their_node_id, boolean no_connection_possible);
+                long provided_node_features();
+                long provided_init_features(byte[] their_node_id);
+       }
+       public static native long LDKOnionMessageHandler_new(LDKOnionMessageHandler impl, LDKOnionMessageProvider OnionMessageProvider);
+       public static native long LDKOnionMessageHandler_get_OnionMessageProvider(long arg);
+       // void OnionMessageHandler_handle_onion_message LDKOnionMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey peer_node_id, const struct LDKOnionMessage *NONNULL_PTR msg
+       public static native void OnionMessageHandler_handle_onion_message(long this_arg, byte[] peer_node_id, long msg);
+       // void OnionMessageHandler_peer_connected LDKOnionMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id, const struct LDKInit *NONNULL_PTR init
+       public static native void OnionMessageHandler_peer_connected(long this_arg, byte[] their_node_id, long init);
+       // void OnionMessageHandler_peer_disconnected LDKOnionMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id, bool no_connection_possible
+       public static native void OnionMessageHandler_peer_disconnected(long this_arg, byte[] their_node_id, boolean no_connection_possible);
+       // LDKNodeFeatures OnionMessageHandler_provided_node_features LDKOnionMessageHandler *NONNULL_PTR this_arg
+       public static native long OnionMessageHandler_provided_node_features(long this_arg);
+       // LDKInitFeatures OnionMessageHandler_provided_init_features LDKOnionMessageHandler *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id
+       public static native long OnionMessageHandler_provided_init_features(long this_arg, byte[] their_node_id);
        public interface LDKCustomMessageReader {
                 long read(short message_type, byte[] buffer);
        }
@@ -1900,12 +2050,20 @@ public class bindings {
        }
        static { LDKEffectiveCapacity.init(); }
        public static native LDKEffectiveCapacity LDKEffectiveCapacity_ref_from_ptr(long ptr);
-       public interface LDKLockableScore {
-                long lock();
+       public static class LDKDestination {
+               private LDKDestination() {}
+               public final static class Node extends LDKDestination {
+                       public byte[] node;
+                       Node(byte[] node) { this.node = node; }
+               }
+               public final static class BlindedRoute extends LDKDestination {
+                       public long blinded_route;
+                       BlindedRoute(long blinded_route) { this.blinded_route = blinded_route; }
+               }
+               static native void init();
        }
-       public static native long LDKLockableScore_new(LDKLockableScore impl);
-       // LDKScore LockableScore_lock LDKLockableScore *NONNULL_PTR this_arg
-       public static native long LockableScore_lock(long this_arg);
+       static { LDKDestination.init(); }
+       public static native LDKDestination LDKDestination_ref_from_ptr(long ptr);
        public static class LDKGossipSync {
                private LDKGossipSync() {}
                public final static class P2P extends LDKGossipSync {
@@ -1964,11 +2122,23 @@ public class bindings {
        // void Payer_abandon_payment LDKPayer *NONNULL_PTR this_arg, struct LDKThirtyTwoBytes payment_id
        public static native void Payer_abandon_payment(long this_arg, byte[] payment_id);
        public interface LDKRouter {
-                long find_route(byte[] payer, long route_params, byte[] payment_hash, long[] first_hops, long scorer);
+                long find_route(byte[] payer, long route_params, byte[] payment_hash, long[] first_hops, long inflight_htlcs);
+                void notify_payment_path_failed(long[] path, long short_channel_id);
+                void notify_payment_path_successful(long[] path);
+                void notify_payment_probe_successful(long[] path);
+                void notify_payment_probe_failed(long[] path, long short_channel_id);
        }
        public static native long LDKRouter_new(LDKRouter impl);
-       // LDKCResult_RouteLightningErrorZ Router_find_route LDKRouter *NONNULL_PTR this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, const uint8_t (*payment_hash)[32], struct LDKCVec_ChannelDetailsZ *first_hops, const struct LDKScore *NONNULL_PTR scorer
-       public static native long Router_find_route(long this_arg, byte[] payer, long route_params, byte[] payment_hash, long[] first_hops, long scorer);
+       // LDKCResult_RouteLightningErrorZ Router_find_route LDKRouter *NONNULL_PTR this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, const uint8_t (*payment_hash)[32], struct LDKCVec_ChannelDetailsZ *first_hops, struct LDKInFlightHtlcs inflight_htlcs
+       public static native long Router_find_route(long this_arg, byte[] payer, long route_params, byte[] payment_hash, long[] first_hops, long inflight_htlcs);
+       // void Router_notify_payment_path_failed LDKRouter *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path, uint64_t short_channel_id
+       public static native void Router_notify_payment_path_failed(long this_arg, long[] path, long short_channel_id);
+       // void Router_notify_payment_path_successful LDKRouter *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path
+       public static native void Router_notify_payment_path_successful(long this_arg, long[] path);
+       // void Router_notify_payment_probe_successful LDKRouter *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path
+       public static native void Router_notify_payment_probe_successful(long this_arg, long[] path);
+       // void Router_notify_payment_probe_failed LDKRouter *NONNULL_PTR this_arg, struct LDKCVec_RouteHopZ path, uint64_t short_channel_id
+       public static native void Router_notify_payment_probe_failed(long this_arg, long[] path, long short_channel_id);
        public static class LDKRetry {
                private LDKRetry() {}
                public final static class Attempts extends LDKRetry {
@@ -1987,6 +2157,8 @@ public class bindings {
        public static native String _ldk_get_compiled_version();
        // struct LDKStr _ldk_c_bindings_get_compiled_version(void);
        public static native String _ldk_c_bindings_get_compiled_version();
+       // struct LDKBigEndianScalar BigEndianScalar_new(struct LDKThirtyTwoBytes big_endian_bytes);
+       public static native long BigEndianScalar_new(byte[] big_endian_bytes);
        // uint64_t Bech32Error_clone_ptr(LDKBech32Error *NONNULL_PTR arg);
        public static native long Bech32Error_clone_ptr(long arg);
        // struct LDKBech32Error Bech32Error_clone(const struct LDKBech32Error *NONNULL_PTR orig);
@@ -2005,6 +2177,32 @@ public class bindings {
        public static native long TxOut_clone(long orig);
        // void Str_free(struct LDKStr _res);
        public static native void Str_free(String _res);
+       // void CVec_PublicKeyZ_free(struct LDKCVec_PublicKeyZ _res);
+       public static native void CVec_PublicKeyZ_free(byte[][] _res);
+       // struct LDKCResult_BlindedRouteNoneZ CResult_BlindedRouteNoneZ_ok(struct LDKBlindedRoute o);
+       public static native long CResult_BlindedRouteNoneZ_ok(long o);
+       // struct LDKCResult_BlindedRouteNoneZ CResult_BlindedRouteNoneZ_err(void);
+       public static native long CResult_BlindedRouteNoneZ_err();
+       // bool CResult_BlindedRouteNoneZ_is_ok(const struct LDKCResult_BlindedRouteNoneZ *NONNULL_PTR o);
+       public static native boolean CResult_BlindedRouteNoneZ_is_ok(long o);
+       // void CResult_BlindedRouteNoneZ_free(struct LDKCResult_BlindedRouteNoneZ _res);
+       public static native void CResult_BlindedRouteNoneZ_free(long _res);
+       // struct LDKCResult_BlindedRouteDecodeErrorZ CResult_BlindedRouteDecodeErrorZ_ok(struct LDKBlindedRoute o);
+       public static native long CResult_BlindedRouteDecodeErrorZ_ok(long o);
+       // struct LDKCResult_BlindedRouteDecodeErrorZ CResult_BlindedRouteDecodeErrorZ_err(struct LDKDecodeError e);
+       public static native long CResult_BlindedRouteDecodeErrorZ_err(long e);
+       // bool CResult_BlindedRouteDecodeErrorZ_is_ok(const struct LDKCResult_BlindedRouteDecodeErrorZ *NONNULL_PTR o);
+       public static native boolean CResult_BlindedRouteDecodeErrorZ_is_ok(long o);
+       // void CResult_BlindedRouteDecodeErrorZ_free(struct LDKCResult_BlindedRouteDecodeErrorZ _res);
+       public static native void CResult_BlindedRouteDecodeErrorZ_free(long _res);
+       // struct LDKCResult_BlindedHopDecodeErrorZ CResult_BlindedHopDecodeErrorZ_ok(struct LDKBlindedHop o);
+       public static native long CResult_BlindedHopDecodeErrorZ_ok(long o);
+       // struct LDKCResult_BlindedHopDecodeErrorZ CResult_BlindedHopDecodeErrorZ_err(struct LDKDecodeError e);
+       public static native long CResult_BlindedHopDecodeErrorZ_err(long e);
+       // bool CResult_BlindedHopDecodeErrorZ_is_ok(const struct LDKCResult_BlindedHopDecodeErrorZ *NONNULL_PTR o);
+       public static native boolean CResult_BlindedHopDecodeErrorZ_is_ok(long o);
+       // void CResult_BlindedHopDecodeErrorZ_free(struct LDKCResult_BlindedHopDecodeErrorZ _res);
+       public static native void CResult_BlindedHopDecodeErrorZ_free(long _res);
        // struct LDKCResult_NoneNoneZ CResult_NoneNoneZ_ok(void);
        public static native long CResult_NoneNoneZ_ok();
        // struct LDKCResult_NoneNoneZ CResult_NoneNoneZ_err(void);
@@ -2231,6 +2429,12 @@ public class bindings {
        public static native long CResult_ShutdownScriptInvalidShutdownScriptZ_clone_ptr(long arg);
        // struct LDKCResult_ShutdownScriptInvalidShutdownScriptZ CResult_ShutdownScriptInvalidShutdownScriptZ_clone(const struct LDKCResult_ShutdownScriptInvalidShutdownScriptZ *NONNULL_PTR orig);
        public static native long CResult_ShutdownScriptInvalidShutdownScriptZ_clone(long orig);
+       // struct LDKCOption_WriteableScoreZ COption_WriteableScoreZ_some(struct LDKWriteableScore o);
+       public static native long COption_WriteableScoreZ_some(long o);
+       // struct LDKCOption_WriteableScoreZ COption_WriteableScoreZ_none(void);
+       public static native long COption_WriteableScoreZ_none();
+       // void COption_WriteableScoreZ_free(struct LDKCOption_WriteableScoreZ _res);
+       public static native void COption_WriteableScoreZ_free(long _res);
        // struct LDKCResult_NoneErrorZ CResult_NoneErrorZ_ok(void);
        public static native long CResult_NoneErrorZ_ok();
        // struct LDKCResult_NoneErrorZ CResult_NoneErrorZ_err(enum LDKIOError e);
@@ -2349,8 +2553,6 @@ public class bindings {
        public static native long CResult_RouteLightningErrorZ_clone_ptr(long arg);
        // struct LDKCResult_RouteLightningErrorZ CResult_RouteLightningErrorZ_clone(const struct LDKCResult_RouteLightningErrorZ *NONNULL_PTR orig);
        public static native long CResult_RouteLightningErrorZ_clone(long orig);
-       // void CVec_PublicKeyZ_free(struct LDKCVec_PublicKeyZ _res);
-       public static native void CVec_PublicKeyZ_free(byte[][] _res);
        // struct LDKCResult_PaymentPurposeDecodeErrorZ CResult_PaymentPurposeDecodeErrorZ_ok(struct LDKPaymentPurpose o);
        public static native long CResult_PaymentPurposeDecodeErrorZ_ok(long o);
        // struct LDKCResult_PaymentPurposeDecodeErrorZ CResult_PaymentPurposeDecodeErrorZ_err(struct LDKDecodeError e);
@@ -2491,16 +2693,6 @@ public class bindings {
        public static native void C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_free(long _res);
        // void CVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ_free(struct LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ _res);
        public static native void CVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ_free(long[] _res);
-       // struct LDKCOption_C2Tuple_usizeTransactionZZ COption_C2Tuple_usizeTransactionZZ_some(struct LDKC2Tuple_usizeTransactionZ o);
-       public static native long COption_C2Tuple_usizeTransactionZZ_some(long o);
-       // struct LDKCOption_C2Tuple_usizeTransactionZZ COption_C2Tuple_usizeTransactionZZ_none(void);
-       public static native long COption_C2Tuple_usizeTransactionZZ_none();
-       // void COption_C2Tuple_usizeTransactionZZ_free(struct LDKCOption_C2Tuple_usizeTransactionZZ _res);
-       public static native void COption_C2Tuple_usizeTransactionZZ_free(long _res);
-       // uint64_t COption_C2Tuple_usizeTransactionZZ_clone_ptr(LDKCOption_C2Tuple_usizeTransactionZZ *NONNULL_PTR arg);
-       public static native long COption_C2Tuple_usizeTransactionZZ_clone_ptr(long arg);
-       // struct LDKCOption_C2Tuple_usizeTransactionZZ COption_C2Tuple_usizeTransactionZZ_clone(const struct LDKCOption_C2Tuple_usizeTransactionZZ *NONNULL_PTR orig);
-       public static native long COption_C2Tuple_usizeTransactionZZ_clone(long orig);
        // struct LDKCResult_FixedPenaltyScorerDecodeErrorZ CResult_FixedPenaltyScorerDecodeErrorZ_ok(struct LDKFixedPenaltyScorer o);
        public static native long CResult_FixedPenaltyScorerDecodeErrorZ_ok(long o);
        // struct LDKCResult_FixedPenaltyScorerDecodeErrorZ CResult_FixedPenaltyScorerDecodeErrorZ_err(struct LDKDecodeError e);
@@ -2651,10 +2843,16 @@ public class bindings {
        public static native long C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_new(long a, long b, long c);
        // void C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free(struct LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ _res);
        public static native void C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free(long _res);
-       // void CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free(struct LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ _res);
-       public static native void CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free(long[] _res);
-       // void CVec_NodeAnnouncementZ_free(struct LDKCVec_NodeAnnouncementZ _res);
-       public static native void CVec_NodeAnnouncementZ_free(long[] _res);
+       // struct LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_some(struct LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ o);
+       public static native long COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_some(long o);
+       // struct LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_none(void);
+       public static native long COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_none();
+       // void COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free(struct LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ _res);
+       public static native void COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free(long _res);
+       // uint64_t COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone_ptr(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *NONNULL_PTR arg);
+       public static native long COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone_ptr(long arg);
+       // struct LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(const struct LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *NONNULL_PTR orig);
+       public static native long COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(long orig);
        // struct LDKCResult_NoneLightningErrorZ CResult_NoneLightningErrorZ_ok(void);
        public static native long CResult_NoneLightningErrorZ_ok();
        // struct LDKCResult_NoneLightningErrorZ CResult_NoneLightningErrorZ_err(struct LDKLightningError e);
@@ -2861,6 +3059,24 @@ public class bindings {
        public static native long CResult_SecretKeyNoneZ_clone_ptr(long arg);
        // struct LDKCResult_SecretKeyNoneZ CResult_SecretKeyNoneZ_clone(const struct LDKCResult_SecretKeyNoneZ *NONNULL_PTR orig);
        public static native long CResult_SecretKeyNoneZ_clone(long orig);
+       // struct LDKCOption_ScalarZ COption_ScalarZ_some(struct LDKBigEndianScalar o);
+       public static native long COption_ScalarZ_some(long o);
+       // struct LDKCOption_ScalarZ COption_ScalarZ_none(void);
+       public static native long COption_ScalarZ_none();
+       // void COption_ScalarZ_free(struct LDKCOption_ScalarZ _res);
+       public static native void COption_ScalarZ_free(long _res);
+       // struct LDKCResult_SharedSecretNoneZ CResult_SharedSecretNoneZ_ok(struct LDKThirtyTwoBytes o);
+       public static native long CResult_SharedSecretNoneZ_ok(byte[] o);
+       // struct LDKCResult_SharedSecretNoneZ CResult_SharedSecretNoneZ_err(void);
+       public static native long CResult_SharedSecretNoneZ_err();
+       // bool CResult_SharedSecretNoneZ_is_ok(const struct LDKCResult_SharedSecretNoneZ *NONNULL_PTR o);
+       public static native boolean CResult_SharedSecretNoneZ_is_ok(long o);
+       // void CResult_SharedSecretNoneZ_free(struct LDKCResult_SharedSecretNoneZ _res);
+       public static native void CResult_SharedSecretNoneZ_free(long _res);
+       // uint64_t CResult_SharedSecretNoneZ_clone_ptr(LDKCResult_SharedSecretNoneZ *NONNULL_PTR arg);
+       public static native long CResult_SharedSecretNoneZ_clone_ptr(long arg);
+       // struct LDKCResult_SharedSecretNoneZ CResult_SharedSecretNoneZ_clone(const struct LDKCResult_SharedSecretNoneZ *NONNULL_PTR orig);
+       public static native long CResult_SharedSecretNoneZ_clone(long orig);
        // struct LDKCResult_SignDecodeErrorZ CResult_SignDecodeErrorZ_ok(struct LDKSign o);
        public static native long CResult_SignDecodeErrorZ_ok(long o);
        // struct LDKCResult_SignDecodeErrorZ CResult_SignDecodeErrorZ_err(struct LDKDecodeError e);
@@ -3223,6 +3439,14 @@ public class bindings {
        public static native long CResult_PaymentIdPaymentErrorZ_clone_ptr(long arg);
        // struct LDKCResult_PaymentIdPaymentErrorZ CResult_PaymentIdPaymentErrorZ_clone(const struct LDKCResult_PaymentIdPaymentErrorZ *NONNULL_PTR orig);
        public static native long CResult_PaymentIdPaymentErrorZ_clone(long orig);
+       // struct LDKCResult_InFlightHtlcsDecodeErrorZ CResult_InFlightHtlcsDecodeErrorZ_ok(struct LDKInFlightHtlcs o);
+       public static native long CResult_InFlightHtlcsDecodeErrorZ_ok(long o);
+       // struct LDKCResult_InFlightHtlcsDecodeErrorZ CResult_InFlightHtlcsDecodeErrorZ_err(struct LDKDecodeError e);
+       public static native long CResult_InFlightHtlcsDecodeErrorZ_err(long e);
+       // bool CResult_InFlightHtlcsDecodeErrorZ_is_ok(const struct LDKCResult_InFlightHtlcsDecodeErrorZ *NONNULL_PTR o);
+       public static native boolean CResult_InFlightHtlcsDecodeErrorZ_is_ok(long o);
+       // void CResult_InFlightHtlcsDecodeErrorZ_free(struct LDKCResult_InFlightHtlcsDecodeErrorZ _res);
+       public static native void CResult_InFlightHtlcsDecodeErrorZ_free(long _res);
        // struct LDKCResult_SiPrefixParseErrorZ CResult_SiPrefixParseErrorZ_ok(enum LDKSiPrefix o);
        public static native long CResult_SiPrefixParseErrorZ_ok(SiPrefix o);
        // struct LDKCResult_SiPrefixParseErrorZ CResult_SiPrefixParseErrorZ_err(struct LDKParseError e);
@@ -3521,6 +3745,14 @@ public class bindings {
        public static native long CResult_boolPeerHandleErrorZ_clone_ptr(long arg);
        // struct LDKCResult_boolPeerHandleErrorZ CResult_boolPeerHandleErrorZ_clone(const struct LDKCResult_boolPeerHandleErrorZ *NONNULL_PTR orig);
        public static native long CResult_boolPeerHandleErrorZ_clone(long orig);
+       // struct LDKCResult_NoneSendErrorZ CResult_NoneSendErrorZ_ok(void);
+       public static native long CResult_NoneSendErrorZ_ok();
+       // struct LDKCResult_NoneSendErrorZ CResult_NoneSendErrorZ_err(struct LDKSendError e);
+       public static native long CResult_NoneSendErrorZ_err(long e);
+       // bool CResult_NoneSendErrorZ_is_ok(const struct LDKCResult_NoneSendErrorZ *NONNULL_PTR o);
+       public static native boolean CResult_NoneSendErrorZ_is_ok(long o);
+       // void CResult_NoneSendErrorZ_free(struct LDKCResult_NoneSendErrorZ _res);
+       public static native void CResult_NoneSendErrorZ_free(long _res);
        // struct LDKCResult_u32GraphSyncErrorZ CResult_u32GraphSyncErrorZ_ok(uint32_t o);
        public static native long CResult_u32GraphSyncErrorZ_ok(int o);
        // struct LDKCResult_u32GraphSyncErrorZ CResult_u32GraphSyncErrorZ_err(struct LDKGraphSyncError e);
@@ -3765,6 +3997,18 @@ public class bindings {
        public static native long CResult_UpdateAddHTLCDecodeErrorZ_clone_ptr(long arg);
        // struct LDKCResult_UpdateAddHTLCDecodeErrorZ CResult_UpdateAddHTLCDecodeErrorZ_clone(const struct LDKCResult_UpdateAddHTLCDecodeErrorZ *NONNULL_PTR orig);
        public static native long CResult_UpdateAddHTLCDecodeErrorZ_clone(long orig);
+       // struct LDKCResult_OnionMessageDecodeErrorZ CResult_OnionMessageDecodeErrorZ_ok(struct LDKOnionMessage o);
+       public static native long CResult_OnionMessageDecodeErrorZ_ok(long o);
+       // struct LDKCResult_OnionMessageDecodeErrorZ CResult_OnionMessageDecodeErrorZ_err(struct LDKDecodeError e);
+       public static native long CResult_OnionMessageDecodeErrorZ_err(long e);
+       // bool CResult_OnionMessageDecodeErrorZ_is_ok(const struct LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR o);
+       public static native boolean CResult_OnionMessageDecodeErrorZ_is_ok(long o);
+       // void CResult_OnionMessageDecodeErrorZ_free(struct LDKCResult_OnionMessageDecodeErrorZ _res);
+       public static native void CResult_OnionMessageDecodeErrorZ_free(long _res);
+       // uint64_t CResult_OnionMessageDecodeErrorZ_clone_ptr(LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR arg);
+       public static native long CResult_OnionMessageDecodeErrorZ_clone_ptr(long arg);
+       // struct LDKCResult_OnionMessageDecodeErrorZ CResult_OnionMessageDecodeErrorZ_clone(const struct LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR orig);
+       public static native long CResult_OnionMessageDecodeErrorZ_clone(long orig);
        // struct LDKCResult_PingDecodeErrorZ CResult_PingDecodeErrorZ_ok(struct LDKPing o);
        public static native long CResult_PingDecodeErrorZ_ok(long o);
        // struct LDKCResult_PingDecodeErrorZ CResult_PingDecodeErrorZ_err(struct LDKDecodeError e);
@@ -4049,8 +4293,8 @@ public class bindings {
        public static native long Event_payment_failed(byte[] payment_id, byte[] payment_hash);
        // struct LDKEvent Event_payment_path_successful(struct LDKThirtyTwoBytes payment_id, struct LDKThirtyTwoBytes payment_hash, struct LDKCVec_RouteHopZ path);
        public static native long Event_payment_path_successful(byte[] payment_id, byte[] payment_hash, long[] path);
-       // struct LDKEvent Event_payment_path_failed(struct LDKThirtyTwoBytes payment_id, struct LDKThirtyTwoBytes payment_hash, bool rejected_by_dest, struct LDKCOption_NetworkUpdateZ network_update, bool all_paths_failed, struct LDKCVec_RouteHopZ path, struct LDKCOption_u64Z short_channel_id, struct LDKRouteParameters retry);
-       public static native long Event_payment_path_failed(byte[] payment_id, byte[] payment_hash, boolean rejected_by_dest, long network_update, boolean all_paths_failed, long[] path, long short_channel_id, long retry);
+       // struct LDKEvent Event_payment_path_failed(struct LDKThirtyTwoBytes payment_id, struct LDKThirtyTwoBytes payment_hash, bool payment_failed_permanently, struct LDKCOption_NetworkUpdateZ network_update, bool all_paths_failed, struct LDKCVec_RouteHopZ path, struct LDKCOption_u64Z short_channel_id, struct LDKRouteParameters retry);
+       public static native long Event_payment_path_failed(byte[] payment_id, byte[] payment_hash, boolean payment_failed_permanently, long network_update, boolean all_paths_failed, long[] path, long short_channel_id, long retry);
        // struct LDKEvent Event_probe_successful(struct LDKThirtyTwoBytes payment_id, struct LDKThirtyTwoBytes payment_hash, struct LDKCVec_RouteHopZ path);
        public static native long Event_probe_successful(byte[] payment_id, byte[] payment_hash, long[] path);
        // struct LDKEvent Event_probe_failed(struct LDKThirtyTwoBytes payment_id, struct LDKThirtyTwoBytes payment_hash, struct LDKCVec_RouteHopZ path, struct LDKCOption_u64Z short_channel_id);
@@ -4101,10 +4345,10 @@ public class bindings {
        public static native long MessageSendEvent_send_shutdown(byte[] node_id, long msg);
        // struct LDKMessageSendEvent MessageSendEvent_send_channel_reestablish(struct LDKPublicKey node_id, struct LDKChannelReestablish msg);
        public static native long MessageSendEvent_send_channel_reestablish(byte[] node_id, long msg);
+       // struct LDKMessageSendEvent MessageSendEvent_send_channel_announcement(struct LDKPublicKey node_id, struct LDKChannelAnnouncement msg, struct LDKChannelUpdate update_msg);
+       public static native long MessageSendEvent_send_channel_announcement(byte[] node_id, long msg, long update_msg);
        // struct LDKMessageSendEvent MessageSendEvent_broadcast_channel_announcement(struct LDKChannelAnnouncement msg, struct LDKChannelUpdate update_msg);
        public static native long MessageSendEvent_broadcast_channel_announcement(long msg, long update_msg);
-       // struct LDKMessageSendEvent MessageSendEvent_broadcast_node_announcement(struct LDKNodeAnnouncement msg);
-       public static native long MessageSendEvent_broadcast_node_announcement(long msg);
        // struct LDKMessageSendEvent MessageSendEvent_broadcast_channel_update(struct LDKChannelUpdate msg);
        public static native long MessageSendEvent_broadcast_channel_update(long msg);
        // struct LDKMessageSendEvent MessageSendEvent_send_channel_update(struct LDKPublicKey node_id, struct LDKChannelUpdate msg);
@@ -4121,6 +4365,8 @@ public class bindings {
        public static native long MessageSendEvent_send_gossip_timestamp_filter(byte[] node_id, long msg);
        // void MessageSendEventsProvider_free(struct LDKMessageSendEventsProvider this_ptr);
        public static native void MessageSendEventsProvider_free(long this_ptr);
+       // void OnionMessageProvider_free(struct LDKOnionMessageProvider this_ptr);
+       public static native void OnionMessageProvider_free(long this_ptr);
        // void EventsProvider_free(struct LDKEventsProvider this_ptr);
        public static native void EventsProvider_free(long this_ptr);
        // void EventHandler_free(struct LDKEventHandler this_ptr);
@@ -4169,6 +4415,12 @@ public class bindings {
        public static native byte[] construct_invoice_preimage(byte[] hrp_bytes, byte[] data_without_signature);
        // void Persister_free(struct LDKPersister this_ptr);
        public static native void Persister_free(long this_ptr);
+       // void FutureCallback_free(struct LDKFutureCallback this_ptr);
+       public static native void FutureCallback_free(long this_ptr);
+       // void Future_free(struct LDKFuture this_obj);
+       public static native void Future_free(long this_obj);
+       // void Future_register_callback_fn(const struct LDKFuture *NONNULL_PTR this_arg, struct LDKFutureCallback callback);
+       public static native void Future_register_callback_fn(long this_arg, long callback);
        // enum LDKLevel Level_clone(const enum LDKLevel *NONNULL_PTR orig);
        public static native Level Level_clone(long orig);
        // enum LDKLevel Level_gossip(void);
@@ -4247,8 +4499,12 @@ public class bindings {
        public static native boolean ChannelHandshakeConfig_get_commit_upfront_shutdown_pubkey(long this_ptr);
        // void ChannelHandshakeConfig_set_commit_upfront_shutdown_pubkey(struct LDKChannelHandshakeConfig *NONNULL_PTR this_ptr, bool val);
        public static native void ChannelHandshakeConfig_set_commit_upfront_shutdown_pubkey(long this_ptr, boolean val);
-       // MUST_USE_RES struct LDKChannelHandshakeConfig ChannelHandshakeConfig_new(uint32_t minimum_depth_arg, uint16_t our_to_self_delay_arg, uint64_t our_htlc_minimum_msat_arg, uint8_t max_inbound_htlc_value_in_flight_percent_of_channel_arg, bool negotiate_scid_privacy_arg, bool announced_channel_arg, bool commit_upfront_shutdown_pubkey_arg);
-       public static native long ChannelHandshakeConfig_new(int minimum_depth_arg, short our_to_self_delay_arg, long our_htlc_minimum_msat_arg, byte max_inbound_htlc_value_in_flight_percent_of_channel_arg, boolean negotiate_scid_privacy_arg, boolean announced_channel_arg, boolean commit_upfront_shutdown_pubkey_arg);
+       // uint32_t ChannelHandshakeConfig_get_their_channel_reserve_proportional_millionths(const struct LDKChannelHandshakeConfig *NONNULL_PTR this_ptr);
+       public static native int ChannelHandshakeConfig_get_their_channel_reserve_proportional_millionths(long this_ptr);
+       // void ChannelHandshakeConfig_set_their_channel_reserve_proportional_millionths(struct LDKChannelHandshakeConfig *NONNULL_PTR this_ptr, uint32_t val);
+       public static native void ChannelHandshakeConfig_set_their_channel_reserve_proportional_millionths(long this_ptr, int val);
+       // MUST_USE_RES struct LDKChannelHandshakeConfig ChannelHandshakeConfig_new(uint32_t minimum_depth_arg, uint16_t our_to_self_delay_arg, uint64_t our_htlc_minimum_msat_arg, uint8_t max_inbound_htlc_value_in_flight_percent_of_channel_arg, bool negotiate_scid_privacy_arg, bool announced_channel_arg, bool commit_upfront_shutdown_pubkey_arg, uint32_t their_channel_reserve_proportional_millionths_arg);
+       public static native long ChannelHandshakeConfig_new(int minimum_depth_arg, short our_to_self_delay_arg, long our_htlc_minimum_msat_arg, byte max_inbound_htlc_value_in_flight_percent_of_channel_arg, boolean negotiate_scid_privacy_arg, boolean announced_channel_arg, boolean commit_upfront_shutdown_pubkey_arg, int their_channel_reserve_proportional_millionths_arg);
        // uint64_t ChannelHandshakeConfig_clone_ptr(LDKChannelHandshakeConfig *NONNULL_PTR arg);
        public static native long ChannelHandshakeConfig_clone_ptr(long arg);
        // struct LDKChannelHandshakeConfig ChannelHandshakeConfig_clone(const struct LDKChannelHandshakeConfig *NONNULL_PTR orig);
@@ -4533,8 +4789,12 @@ public class bindings {
        public static native long Balance_claimable_awaiting_confirmations(long claimable_amount_satoshis, int confirmation_height);
        // struct LDKBalance Balance_contentious_claimable(uint64_t claimable_amount_satoshis, uint32_t timeout_height);
        public static native long Balance_contentious_claimable(long claimable_amount_satoshis, int timeout_height);
-       // struct LDKBalance Balance_maybe_claimable_htlcawaiting_timeout(uint64_t claimable_amount_satoshis, uint32_t claimable_height);
-       public static native long Balance_maybe_claimable_htlcawaiting_timeout(long claimable_amount_satoshis, int claimable_height);
+       // struct LDKBalance Balance_maybe_timeout_claimable_htlc(uint64_t claimable_amount_satoshis, uint32_t claimable_height);
+       public static native long Balance_maybe_timeout_claimable_htlc(long claimable_amount_satoshis, int claimable_height);
+       // struct LDKBalance Balance_maybe_preimage_claimable_htlc(uint64_t claimable_amount_satoshis, uint32_t expiry_height);
+       public static native long Balance_maybe_preimage_claimable_htlc(long claimable_amount_satoshis, int expiry_height);
+       // struct LDKBalance Balance_counterparty_revoked_output_claimable(uint64_t claimable_amount_satoshis);
+       public static native long Balance_counterparty_revoked_output_claimable(long claimable_amount_satoshis);
        // bool Balance_eq(const struct LDKBalance *NONNULL_PTR a, const struct LDKBalance *NONNULL_PTR b);
        public static native boolean Balance_eq(long a, long b);
        // void ChannelMonitor_free(struct LDKChannelMonitor this_obj);
@@ -5027,8 +5287,6 @@ public class bindings {
        public static native long ChannelManager_send_probe(long this_arg, long[] hops);
        // MUST_USE_RES struct LDKCResult_NoneAPIErrorZ ChannelManager_funding_transaction_generated(const struct LDKChannelManager *NONNULL_PTR this_arg, const uint8_t (*temporary_channel_id)[32], struct LDKPublicKey counterparty_node_id, struct LDKTransaction funding_transaction);
        public static native long ChannelManager_funding_transaction_generated(long this_arg, byte[] temporary_channel_id, byte[] counterparty_node_id, byte[] funding_transaction);
-       // void ChannelManager_broadcast_node_announcement(const struct LDKChannelManager *NONNULL_PTR this_arg, struct LDKThreeBytes rgb, struct LDKThirtyTwoBytes alias, struct LDKCVec_NetAddressZ addresses);
-       public static native void ChannelManager_broadcast_node_announcement(long this_arg, byte[] rgb, byte[] alias, long[] addresses);
        // MUST_USE_RES struct LDKCResult_NoneAPIErrorZ ChannelManager_update_channel_config(const struct LDKChannelManager *NONNULL_PTR this_arg, struct LDKPublicKey counterparty_node_id, struct LDKCVec_ThirtyTwoBytesZ channel_ids, const struct LDKChannelConfig *NONNULL_PTR config);
        public static native long ChannelManager_update_channel_config(long this_arg, byte[] counterparty_node_id, byte[][] channel_ids, long config);
        // void ChannelManager_process_pending_htlc_forwards(const struct LDKChannelManager *NONNULL_PTR this_arg);
@@ -5071,6 +5329,8 @@ public class bindings {
        public static native boolean ChannelManager_await_persistable_update_timeout(long this_arg, long max_wait);
        // void ChannelManager_await_persistable_update(const struct LDKChannelManager *NONNULL_PTR this_arg);
        public static native void ChannelManager_await_persistable_update(long this_arg);
+       // MUST_USE_RES struct LDKFuture ChannelManager_get_persistable_update_future(const struct LDKChannelManager *NONNULL_PTR this_arg);
+       public static native long ChannelManager_get_persistable_update_future(long this_arg);
        // MUST_USE_RES struct LDKBestBlock ChannelManager_current_best_block(const struct LDKChannelManager *NONNULL_PTR this_arg);
        public static native long ChannelManager_current_best_block(long this_arg);
        // struct LDKChannelMessageHandler ChannelManager_as_ChannelMessageHandler(const struct LDKChannelManager *NONNULL_PTR this_arg);
@@ -5503,6 +5763,16 @@ public class bindings {
        public static native long UpdateAddHTLC_clone_ptr(long arg);
        // struct LDKUpdateAddHTLC UpdateAddHTLC_clone(const struct LDKUpdateAddHTLC *NONNULL_PTR orig);
        public static native long UpdateAddHTLC_clone(long orig);
+       // void OnionMessage_free(struct LDKOnionMessage this_obj);
+       public static native void OnionMessage_free(long this_obj);
+       // struct LDKPublicKey OnionMessage_get_blinding_point(const struct LDKOnionMessage *NONNULL_PTR this_ptr);
+       public static native byte[] OnionMessage_get_blinding_point(long this_ptr);
+       // void OnionMessage_set_blinding_point(struct LDKOnionMessage *NONNULL_PTR this_ptr, struct LDKPublicKey val);
+       public static native void OnionMessage_set_blinding_point(long this_ptr, byte[] val);
+       // uint64_t OnionMessage_clone_ptr(LDKOnionMessage *NONNULL_PTR arg);
+       public static native long OnionMessage_clone_ptr(long arg);
+       // struct LDKOnionMessage OnionMessage_clone(const struct LDKOnionMessage *NONNULL_PTR orig);
+       public static native long OnionMessage_clone(long orig);
        // void UpdateFulfillHTLC_free(struct LDKUpdateFulfillHTLC this_obj);
        public static native void UpdateFulfillHTLC_free(long this_obj);
        // const uint8_t (*UpdateFulfillHTLC_get_channel_id(const struct LDKUpdateFulfillHTLC *NONNULL_PTR this_ptr))[32];
@@ -6031,6 +6301,8 @@ public class bindings {
        public static native void ChannelMessageHandler_free(long this_ptr);
        // void RoutingMessageHandler_free(struct LDKRoutingMessageHandler this_ptr);
        public static native void RoutingMessageHandler_free(long this_ptr);
+       // void OnionMessageHandler_free(struct LDKOnionMessageHandler this_ptr);
+       public static native void OnionMessageHandler_free(long this_ptr);
        // struct LDKCVec_u8Z AcceptChannel_write(const struct LDKAcceptChannel *NONNULL_PTR obj);
        public static native byte[] AcceptChannel_write(long obj);
        // struct LDKCResult_AcceptChannelDecodeErrorZ AcceptChannel_read(struct LDKu8slice ser);
@@ -6103,6 +6375,10 @@ public class bindings {
        public static native byte[] UpdateAddHTLC_write(long obj);
        // struct LDKCResult_UpdateAddHTLCDecodeErrorZ UpdateAddHTLC_read(struct LDKu8slice ser);
        public static native long UpdateAddHTLC_read(byte[] ser);
+       // struct LDKCResult_OnionMessageDecodeErrorZ OnionMessage_read(struct LDKu8slice ser);
+       public static native long OnionMessage_read(byte[] ser);
+       // struct LDKCVec_u8Z OnionMessage_write(const struct LDKOnionMessage *NONNULL_PTR obj);
+       public static native byte[] OnionMessage_write(long obj);
        // struct LDKCVec_u8Z Ping_write(const struct LDKPing *NONNULL_PTR obj);
        public static native byte[] Ping_write(long obj);
        // struct LDKCResult_PingDecodeErrorZ Ping_read(struct LDKu8slice ser);
@@ -6175,6 +6451,10 @@ public class bindings {
        public static native long IgnoringMessageHandler_as_MessageSendEventsProvider(long this_arg);
        // struct LDKRoutingMessageHandler IgnoringMessageHandler_as_RoutingMessageHandler(const struct LDKIgnoringMessageHandler *NONNULL_PTR this_arg);
        public static native long IgnoringMessageHandler_as_RoutingMessageHandler(long this_arg);
+       // struct LDKOnionMessageProvider IgnoringMessageHandler_as_OnionMessageProvider(const struct LDKIgnoringMessageHandler *NONNULL_PTR this_arg);
+       public static native long IgnoringMessageHandler_as_OnionMessageProvider(long this_arg);
+       // struct LDKOnionMessageHandler IgnoringMessageHandler_as_OnionMessageHandler(const struct LDKIgnoringMessageHandler *NONNULL_PTR this_arg);
+       public static native long IgnoringMessageHandler_as_OnionMessageHandler(long this_arg);
        // struct LDKCustomMessageReader IgnoringMessageHandler_as_CustomMessageReader(const struct LDKIgnoringMessageHandler *NONNULL_PTR this_arg);
        public static native long IgnoringMessageHandler_as_CustomMessageReader(long this_arg);
        // struct LDKCustomMessageHandler IgnoringMessageHandler_as_CustomMessageHandler(const struct LDKIgnoringMessageHandler *NONNULL_PTR this_arg);
@@ -6197,8 +6477,12 @@ public class bindings {
        public static native long MessageHandler_get_route_handler(long this_ptr);
        // void MessageHandler_set_route_handler(struct LDKMessageHandler *NONNULL_PTR this_ptr, struct LDKRoutingMessageHandler val);
        public static native void MessageHandler_set_route_handler(long this_ptr, long val);
-       // MUST_USE_RES struct LDKMessageHandler MessageHandler_new(struct LDKChannelMessageHandler chan_handler_arg, struct LDKRoutingMessageHandler route_handler_arg);
-       public static native long MessageHandler_new(long chan_handler_arg, long route_handler_arg);
+       // const struct LDKOnionMessageHandler *MessageHandler_get_onion_message_handler(const struct LDKMessageHandler *NONNULL_PTR this_ptr);
+       public static native long MessageHandler_get_onion_message_handler(long this_ptr);
+       // void MessageHandler_set_onion_message_handler(struct LDKMessageHandler *NONNULL_PTR this_ptr, struct LDKOnionMessageHandler val);
+       public static native void MessageHandler_set_onion_message_handler(long this_ptr, long val);
+       // MUST_USE_RES struct LDKMessageHandler MessageHandler_new(struct LDKChannelMessageHandler chan_handler_arg, struct LDKRoutingMessageHandler route_handler_arg, struct LDKOnionMessageHandler onion_message_handler_arg);
+       public static native long MessageHandler_new(long chan_handler_arg, long route_handler_arg, long onion_message_handler_arg);
        // uint64_t SocketDescriptor_clone_ptr(LDKSocketDescriptor *NONNULL_PTR arg);
        public static native long SocketDescriptor_clone_ptr(long arg);
        // struct LDKSocketDescriptor SocketDescriptor_clone(const struct LDKSocketDescriptor *NONNULL_PTR orig);
@@ -6219,8 +6503,8 @@ public class bindings {
        public static native long PeerHandleError_clone(long orig);
        // void PeerManager_free(struct LDKPeerManager this_obj);
        public static native void PeerManager_free(long this_obj);
-       // MUST_USE_RES struct LDKPeerManager PeerManager_new(struct LDKMessageHandler message_handler, struct LDKSecretKey our_node_secret, const uint8_t (*ephemeral_random_data)[32], struct LDKLogger logger, struct LDKCustomMessageHandler custom_message_handler);
-       public static native long PeerManager_new(long message_handler, byte[] our_node_secret, byte[] ephemeral_random_data, long logger, long custom_message_handler);
+       // MUST_USE_RES struct LDKPeerManager PeerManager_new(struct LDKMessageHandler message_handler, struct LDKSecretKey our_node_secret, uint64_t current_time, const uint8_t (*ephemeral_random_data)[32], struct LDKLogger logger, struct LDKCustomMessageHandler custom_message_handler);
+       public static native long PeerManager_new(long message_handler, byte[] our_node_secret, long current_time, byte[] ephemeral_random_data, long logger, long custom_message_handler);
        // MUST_USE_RES struct LDKCVec_PublicKeyZ PeerManager_get_peer_node_ids(const struct LDKPeerManager *NONNULL_PTR this_arg);
        public static native byte[][] PeerManager_get_peer_node_ids(long this_arg);
        // MUST_USE_RES struct LDKCResult_CVec_u8ZPeerHandleErrorZ PeerManager_new_outbound_connection(const struct LDKPeerManager *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id, struct LDKSocketDescriptor descriptor, struct LDKCOption_NetAddressZ remote_network_address);
@@ -6241,6 +6525,8 @@ public class bindings {
        public static native void PeerManager_disconnect_all_peers(long this_arg);
        // void PeerManager_timer_tick_occurred(const struct LDKPeerManager *NONNULL_PTR this_arg);
        public static native void PeerManager_timer_tick_occurred(long this_arg);
+       // void PeerManager_broadcast_node_announcement(const struct LDKPeerManager *NONNULL_PTR this_arg, struct LDKThreeBytes rgb, struct LDKThirtyTwoBytes alias, struct LDKCVec_NetAddressZ addresses);
+       public static native void PeerManager_broadcast_node_announcement(long this_arg, byte[] rgb, byte[] alias, long[] addresses);
        // uint64_t htlc_success_tx_weight(bool opt_anchors);
        public static native long htlc_success_tx_weight(boolean opt_anchors);
        // uint64_t htlc_timeout_tx_weight(bool opt_anchors);
@@ -6611,6 +6897,10 @@ public class bindings {
        public static native void InvoiceFeatures_free(long this_obj);
        // void ChannelTypeFeatures_free(struct LDKChannelTypeFeatures this_obj);
        public static native void ChannelTypeFeatures_free(long this_obj);
+       // MUST_USE_RES struct LDKInitFeatures InitFeatures_known_channel_features(void);
+       public static native long InitFeatures_known_channel_features();
+       // MUST_USE_RES struct LDKNodeFeatures NodeFeatures_known_channel_features(void);
+       public static native long NodeFeatures_known_channel_features();
        // MUST_USE_RES struct LDKInitFeatures InitFeatures_empty(void);
        public static native long InitFeatures_empty();
        // MUST_USE_RES struct LDKInitFeatures InitFeatures_known(void);
@@ -6843,6 +7133,22 @@ public class bindings {
        public static native boolean InitFeatures_requires_shutdown_anysegwit(long this_arg);
        // MUST_USE_RES bool NodeFeatures_requires_shutdown_anysegwit(const struct LDKNodeFeatures *NONNULL_PTR this_arg);
        public static native boolean NodeFeatures_requires_shutdown_anysegwit(long this_arg);
+       // void InitFeatures_set_onion_messages_optional(struct LDKInitFeatures *NONNULL_PTR this_arg);
+       public static native void InitFeatures_set_onion_messages_optional(long this_arg);
+       // void InitFeatures_set_onion_messages_required(struct LDKInitFeatures *NONNULL_PTR this_arg);
+       public static native void InitFeatures_set_onion_messages_required(long this_arg);
+       // MUST_USE_RES bool InitFeatures_supports_onion_messages(const struct LDKInitFeatures *NONNULL_PTR this_arg);
+       public static native boolean InitFeatures_supports_onion_messages(long this_arg);
+       // void NodeFeatures_set_onion_messages_optional(struct LDKNodeFeatures *NONNULL_PTR this_arg);
+       public static native void NodeFeatures_set_onion_messages_optional(long this_arg);
+       // void NodeFeatures_set_onion_messages_required(struct LDKNodeFeatures *NONNULL_PTR this_arg);
+       public static native void NodeFeatures_set_onion_messages_required(long this_arg);
+       // MUST_USE_RES bool NodeFeatures_supports_onion_messages(const struct LDKNodeFeatures *NONNULL_PTR this_arg);
+       public static native boolean NodeFeatures_supports_onion_messages(long this_arg);
+       // MUST_USE_RES bool InitFeatures_requires_onion_messages(const struct LDKInitFeatures *NONNULL_PTR this_arg);
+       public static native boolean InitFeatures_requires_onion_messages(long this_arg);
+       // MUST_USE_RES bool NodeFeatures_requires_onion_messages(const struct LDKNodeFeatures *NONNULL_PTR this_arg);
+       public static native boolean NodeFeatures_requires_onion_messages(long this_arg);
        // void InitFeatures_set_channel_type_optional(struct LDKInitFeatures *NONNULL_PTR this_arg);
        public static native void InitFeatures_set_channel_type_optional(long this_arg);
        // void InitFeatures_set_channel_type_required(struct LDKInitFeatures *NONNULL_PTR this_arg);
@@ -7473,10 +7779,22 @@ public class bindings {
        public static native void Score_free(long this_ptr);
        // void LockableScore_free(struct LDKLockableScore this_ptr);
        public static native void LockableScore_free(long this_ptr);
+       // void WriteableScore_free(struct LDKWriteableScore this_ptr);
+       public static native void WriteableScore_free(long this_ptr);
        // void MultiThreadedLockableScore_free(struct LDKMultiThreadedLockableScore this_obj);
        public static native void MultiThreadedLockableScore_free(long this_obj);
+       // void MultiThreadedScoreLock_free(struct LDKMultiThreadedScoreLock this_obj);
+       public static native void MultiThreadedScoreLock_free(long this_obj);
+       // struct LDKScore MultiThreadedScoreLock_as_Score(const struct LDKMultiThreadedScoreLock *NONNULL_PTR this_arg);
+       public static native long MultiThreadedScoreLock_as_Score(long this_arg);
+       // struct LDKCVec_u8Z MultiThreadedScoreLock_write(const struct LDKMultiThreadedScoreLock *NONNULL_PTR obj);
+       public static native byte[] MultiThreadedScoreLock_write(long obj);
+       // struct LDKLockableScore MultiThreadedLockableScore_as_LockableScore(const struct LDKMultiThreadedLockableScore *NONNULL_PTR this_arg);
+       public static native long MultiThreadedLockableScore_as_LockableScore(long this_arg);
        // struct LDKCVec_u8Z MultiThreadedLockableScore_write(const struct LDKMultiThreadedLockableScore *NONNULL_PTR obj);
        public static native byte[] MultiThreadedLockableScore_write(long obj);
+       // struct LDKWriteableScore MultiThreadedLockableScore_as_WriteableScore(const struct LDKMultiThreadedLockableScore *NONNULL_PTR this_arg);
+       public static native long MultiThreadedLockableScore_as_WriteableScore(long this_arg);
        // MUST_USE_RES struct LDKMultiThreadedLockableScore MultiThreadedLockableScore_new(struct LDKScore score);
        public static native long MultiThreadedLockableScore_new(long score);
        // void ChannelUsage_free(struct LDKChannelUsage this_obj);
@@ -7575,6 +7893,52 @@ public class bindings {
        public static native byte[] ProbabilisticScorer_write(long obj);
        // struct LDKCResult_ProbabilisticScorerDecodeErrorZ ProbabilisticScorer_read(struct LDKu8slice ser, struct LDKProbabilisticScoringParameters arg_a, const struct LDKNetworkGraph *NONNULL_PTR arg_b, struct LDKLogger arg_c);
        public static native long ProbabilisticScorer_read(byte[] ser, long arg_a, long arg_b, long arg_c);
+       // void BlindedRoute_free(struct LDKBlindedRoute this_obj);
+       public static native void BlindedRoute_free(long this_obj);
+       // void BlindedHop_free(struct LDKBlindedHop this_obj);
+       public static native void BlindedHop_free(long this_obj);
+       // MUST_USE_RES struct LDKCResult_BlindedRouteNoneZ BlindedRoute_new(struct LDKCVec_PublicKeyZ node_pks, const struct LDKKeysInterface *NONNULL_PTR keys_manager);
+       public static native long BlindedRoute_new(byte[][] node_pks, long keys_manager);
+       // struct LDKCVec_u8Z BlindedRoute_write(const struct LDKBlindedRoute *NONNULL_PTR obj);
+       public static native byte[] BlindedRoute_write(long obj);
+       // struct LDKCResult_BlindedRouteDecodeErrorZ BlindedRoute_read(struct LDKu8slice ser);
+       public static native long BlindedRoute_read(byte[] ser);
+       // struct LDKCVec_u8Z BlindedHop_write(const struct LDKBlindedHop *NONNULL_PTR obj);
+       public static native byte[] BlindedHop_write(long obj);
+       // struct LDKCResult_BlindedHopDecodeErrorZ BlindedHop_read(struct LDKu8slice ser);
+       public static native long BlindedHop_read(byte[] ser);
+       // void OnionMessenger_free(struct LDKOnionMessenger this_obj);
+       public static native void OnionMessenger_free(long this_obj);
+       // void Destination_free(struct LDKDestination this_ptr);
+       public static native void Destination_free(long this_ptr);
+       // struct LDKDestination Destination_node(struct LDKPublicKey a);
+       public static native long Destination_node(byte[] a);
+       // struct LDKDestination Destination_blinded_route(struct LDKBlindedRoute a);
+       public static native long Destination_blinded_route(long a);
+       // void SendError_free(struct LDKSendError this_ptr);
+       public static native void SendError_free(long this_ptr);
+       // uint64_t SendError_clone_ptr(LDKSendError *NONNULL_PTR arg);
+       public static native long SendError_clone_ptr(long arg);
+       // struct LDKSendError SendError_clone(const struct LDKSendError *NONNULL_PTR orig);
+       public static native long SendError_clone(long orig);
+       // struct LDKSendError SendError_secp256k1(enum LDKSecp256k1Error a);
+       public static native long SendError_secp256k1(Secp256k1Error a);
+       // struct LDKSendError SendError_too_big_packet(void);
+       public static native long SendError_too_big_packet();
+       // struct LDKSendError SendError_too_few_blinded_hops(void);
+       public static native long SendError_too_few_blinded_hops();
+       // struct LDKSendError SendError_invalid_first_hop(void);
+       public static native long SendError_invalid_first_hop();
+       // struct LDKSendError SendError_buffer_full(void);
+       public static native long SendError_buffer_full();
+       // MUST_USE_RES struct LDKOnionMessenger OnionMessenger_new(struct LDKKeysInterface keys_manager, struct LDKLogger logger);
+       public static native long OnionMessenger_new(long keys_manager, long logger);
+       // MUST_USE_RES struct LDKCResult_NoneSendErrorZ OnionMessenger_send_onion_message(const struct LDKOnionMessenger *NONNULL_PTR this_arg, struct LDKCVec_PublicKeyZ intermediate_nodes, struct LDKDestination destination, struct LDKBlindedRoute reply_path);
+       public static native long OnionMessenger_send_onion_message(long this_arg, byte[][] intermediate_nodes, long destination, long reply_path);
+       // struct LDKOnionMessageHandler OnionMessenger_as_OnionMessageHandler(const struct LDKOnionMessenger *NONNULL_PTR this_arg);
+       public static native long OnionMessenger_as_OnionMessageHandler(long this_arg);
+       // struct LDKOnionMessageProvider OnionMessenger_as_OnionMessageProvider(const struct LDKOnionMessenger *NONNULL_PTR this_arg);
+       public static native long OnionMessenger_as_OnionMessageProvider(long this_arg);
        // void FilesystemPersister_free(struct LDKFilesystemPersister this_obj);
        public static native void FilesystemPersister_free(long this_obj);
        // MUST_USE_RES struct LDKFilesystemPersister FilesystemPersister_new(struct LDKStr path_to_channel_data);
@@ -7593,7 +7957,7 @@ public class bindings {
        public static native long GossipSync_rapid(long a);
        // struct LDKGossipSync GossipSync_none(void);
        public static native long GossipSync_none();
-       // MUST_USE_RES struct LDKBackgroundProcessor BackgroundProcessor_start(struct LDKPersister persister, struct LDKEventHandler event_handler, const struct LDKChainMonitor *NONNULL_PTR chain_monitor, const struct LDKChannelManager *NONNULL_PTR channel_manager, struct LDKGossipSync gossip_sync, const struct LDKPeerManager *NONNULL_PTR peer_manager, struct LDKLogger logger, struct LDKMultiThreadedLockableScore scorer);
+       // MUST_USE_RES struct LDKBackgroundProcessor BackgroundProcessor_start(struct LDKPersister persister, struct LDKEventHandler event_handler, const struct LDKChainMonitor *NONNULL_PTR chain_monitor, const struct LDKChannelManager *NONNULL_PTR channel_manager, struct LDKGossipSync gossip_sync, const struct LDKPeerManager *NONNULL_PTR peer_manager, struct LDKLogger logger, struct LDKCOption_WriteableScoreZ scorer);
        public static native long BackgroundProcessor_start(long persister, long event_handler, long chain_monitor, long channel_manager, long gossip_sync, long peer_manager, long logger, long scorer);
        // MUST_USE_RES struct LDKCResult_NoneErrorZ BackgroundProcessor_join(struct LDKBackgroundProcessor this_arg);
        public static native long BackgroundProcessor_join(long this_arg);
@@ -7659,6 +8023,8 @@ public class bindings {
        public static native long Invoice_clone_ptr(long arg);
        // struct LDKInvoice Invoice_clone(const struct LDKInvoice *NONNULL_PTR orig);
        public static native long Invoice_clone(long orig);
+       // uint64_t Invoice_hash(const struct LDKInvoice *NONNULL_PTR o);
+       public static native long Invoice_hash(long o);
        // void SignedRawInvoice_free(struct LDKSignedRawInvoice this_obj);
        public static native void SignedRawInvoice_free(long this_obj);
        // bool SignedRawInvoice_eq(const struct LDKSignedRawInvoice *NONNULL_PTR a, const struct LDKSignedRawInvoice *NONNULL_PTR b);
@@ -7667,6 +8033,8 @@ public class bindings {
        public static native long SignedRawInvoice_clone_ptr(long arg);
        // struct LDKSignedRawInvoice SignedRawInvoice_clone(const struct LDKSignedRawInvoice *NONNULL_PTR orig);
        public static native long SignedRawInvoice_clone(long orig);
+       // uint64_t SignedRawInvoice_hash(const struct LDKSignedRawInvoice *NONNULL_PTR o);
+       public static native long SignedRawInvoice_hash(long o);
        // void RawInvoice_free(struct LDKRawInvoice this_obj);
        public static native void RawInvoice_free(long this_obj);
        // struct LDKRawDataPart RawInvoice_get_data(const struct LDKRawInvoice *NONNULL_PTR this_ptr);
@@ -7679,6 +8047,8 @@ public class bindings {
        public static native long RawInvoice_clone_ptr(long arg);
        // struct LDKRawInvoice RawInvoice_clone(const struct LDKRawInvoice *NONNULL_PTR orig);
        public static native long RawInvoice_clone(long orig);
+       // uint64_t RawInvoice_hash(const struct LDKRawInvoice *NONNULL_PTR o);
+       public static native long RawInvoice_hash(long o);
        // void RawDataPart_free(struct LDKRawDataPart this_obj);
        public static native void RawDataPart_free(long this_obj);
        // struct LDKPositiveTimestamp RawDataPart_get_timestamp(const struct LDKRawDataPart *NONNULL_PTR this_ptr);
@@ -7691,6 +8061,8 @@ public class bindings {
        public static native long RawDataPart_clone_ptr(long arg);
        // struct LDKRawDataPart RawDataPart_clone(const struct LDKRawDataPart *NONNULL_PTR orig);
        public static native long RawDataPart_clone(long orig);
+       // uint64_t RawDataPart_hash(const struct LDKRawDataPart *NONNULL_PTR o);
+       public static native long RawDataPart_hash(long o);
        // void PositiveTimestamp_free(struct LDKPositiveTimestamp this_obj);
        public static native void PositiveTimestamp_free(long this_obj);
        // bool PositiveTimestamp_eq(const struct LDKPositiveTimestamp *NONNULL_PTR a, const struct LDKPositiveTimestamp *NONNULL_PTR b);
@@ -7699,6 +8071,8 @@ public class bindings {
        public static native long PositiveTimestamp_clone_ptr(long arg);
        // struct LDKPositiveTimestamp PositiveTimestamp_clone(const struct LDKPositiveTimestamp *NONNULL_PTR orig);
        public static native long PositiveTimestamp_clone(long orig);
+       // uint64_t PositiveTimestamp_hash(const struct LDKPositiveTimestamp *NONNULL_PTR o);
+       public static native long PositiveTimestamp_hash(long o);
        // enum LDKSiPrefix SiPrefix_clone(const enum LDKSiPrefix *NONNULL_PTR orig);
        public static native SiPrefix SiPrefix_clone(long orig);
        // enum LDKSiPrefix SiPrefix_milli(void);
@@ -7711,6 +8085,8 @@ public class bindings {
        public static native SiPrefix SiPrefix_pico();
        // bool SiPrefix_eq(const enum LDKSiPrefix *NONNULL_PTR a, const enum LDKSiPrefix *NONNULL_PTR b);
        public static native boolean SiPrefix_eq(long a, long b);
+       // uint64_t SiPrefix_hash(const enum LDKSiPrefix *NONNULL_PTR o);
+       public static native long SiPrefix_hash(long o);
        // MUST_USE_RES uint64_t SiPrefix_multiplier(const enum LDKSiPrefix *NONNULL_PTR this_arg);
        public static native long SiPrefix_multiplier(long this_arg);
        // enum LDKCurrency Currency_clone(const enum LDKCurrency *NONNULL_PTR orig);
@@ -7813,6 +8189,8 @@ public class bindings {
        public static native long InvoiceSignature_clone_ptr(long arg);
        // struct LDKInvoiceSignature InvoiceSignature_clone(const struct LDKInvoiceSignature *NONNULL_PTR orig);
        public static native long InvoiceSignature_clone(long orig);
+       // uint64_t InvoiceSignature_hash(const struct LDKInvoiceSignature *NONNULL_PTR o);
+       public static native long InvoiceSignature_hash(long o);
        // bool InvoiceSignature_eq(const struct LDKInvoiceSignature *NONNULL_PTR a, const struct LDKInvoiceSignature *NONNULL_PTR b);
        public static native boolean InvoiceSignature_eq(long a, long b);
        // void PrivateRoute_free(struct LDKPrivateRoute this_obj);
@@ -7829,16 +8207,16 @@ public class bindings {
        public static native long SignedRawInvoice_into_parts(long this_arg);
        // MUST_USE_RES struct LDKRawInvoice SignedRawInvoice_raw_invoice(const struct LDKSignedRawInvoice *NONNULL_PTR this_arg);
        public static native long SignedRawInvoice_raw_invoice(long this_arg);
-       // MUST_USE_RES const uint8_t (*SignedRawInvoice_hash(const struct LDKSignedRawInvoice *NONNULL_PTR this_arg))[32];
-       public static native byte[] SignedRawInvoice_hash(long this_arg);
+       // MUST_USE_RES const uint8_t (*SignedRawInvoice_signable_hash(const struct LDKSignedRawInvoice *NONNULL_PTR this_arg))[32];
+       public static native byte[] SignedRawInvoice_signable_hash(long this_arg);
        // MUST_USE_RES struct LDKInvoiceSignature SignedRawInvoice_signature(const struct LDKSignedRawInvoice *NONNULL_PTR this_arg);
        public static native long SignedRawInvoice_signature(long this_arg);
        // MUST_USE_RES struct LDKCResult_PayeePubKeyErrorZ SignedRawInvoice_recover_payee_pub_key(const struct LDKSignedRawInvoice *NONNULL_PTR this_arg);
        public static native long SignedRawInvoice_recover_payee_pub_key(long this_arg);
        // MUST_USE_RES bool SignedRawInvoice_check_signature(const struct LDKSignedRawInvoice *NONNULL_PTR this_arg);
        public static native boolean SignedRawInvoice_check_signature(long this_arg);
-       // MUST_USE_RES struct LDKThirtyTwoBytes RawInvoice_hash(const struct LDKRawInvoice *NONNULL_PTR this_arg);
-       public static native byte[] RawInvoice_hash(long this_arg);
+       // MUST_USE_RES struct LDKThirtyTwoBytes RawInvoice_signable_hash(const struct LDKRawInvoice *NONNULL_PTR this_arg);
+       public static native byte[] RawInvoice_signable_hash(long this_arg);
        // MUST_USE_RES struct LDKSha256 RawInvoice_payment_hash(const struct LDKRawInvoice *NONNULL_PTR this_arg);
        public static native long RawInvoice_payment_hash(long this_arg);
        // MUST_USE_RES struct LDKDescription RawInvoice_description(const struct LDKRawInvoice *NONNULL_PTR this_arg);
@@ -8013,8 +8391,8 @@ public class bindings {
        public static native long PaymentError_routing(long a);
        // struct LDKPaymentError PaymentError_sending(struct LDKPaymentSendFailure a);
        public static native long PaymentError_sending(long a);
-       // MUST_USE_RES struct LDKInvoicePayer InvoicePayer_new(struct LDKPayer payer, struct LDKRouter router, const struct LDKMultiThreadedLockableScore *NONNULL_PTR scorer, struct LDKLogger logger, struct LDKEventHandler event_handler, struct LDKRetry retry);
-       public static native long InvoicePayer_new(long payer, long router, long scorer, long logger, long event_handler, long retry);
+       // MUST_USE_RES struct LDKInvoicePayer InvoicePayer_new(struct LDKPayer payer, struct LDKRouter router, struct LDKLogger logger, struct LDKEventHandler event_handler, struct LDKRetry retry);
+       public static native long InvoicePayer_new(long payer, long router, long logger, long event_handler, long retry);
        // MUST_USE_RES struct LDKCResult_PaymentIdPaymentErrorZ InvoicePayer_pay_invoice(const struct LDKInvoicePayer *NONNULL_PTR this_arg, const struct LDKInvoice *NONNULL_PTR invoice);
        public static native long InvoicePayer_pay_invoice(long this_arg, long invoice);
        // MUST_USE_RES struct LDKCResult_PaymentIdPaymentErrorZ InvoicePayer_pay_zero_value_invoice(const struct LDKInvoicePayer *NONNULL_PTR this_arg, const struct LDKInvoice *NONNULL_PTR invoice, uint64_t amount_msats);
@@ -8025,6 +8403,14 @@ public class bindings {
        public static native void InvoicePayer_remove_cached_payment(long this_arg, byte[] payment_hash);
        // struct LDKEventHandler InvoicePayer_as_EventHandler(const struct LDKInvoicePayer *NONNULL_PTR this_arg);
        public static native long InvoicePayer_as_EventHandler(long this_arg);
+       // void InFlightHtlcs_free(struct LDKInFlightHtlcs this_obj);
+       public static native void InFlightHtlcs_free(long this_obj);
+       // MUST_USE_RES struct LDKCOption_u64Z InFlightHtlcs_used_liquidity_msat(const struct LDKInFlightHtlcs *NONNULL_PTR this_arg, const struct LDKNodeId *NONNULL_PTR source, const struct LDKNodeId *NONNULL_PTR target, uint64_t channel_scid);
+       public static native long InFlightHtlcs_used_liquidity_msat(long this_arg, long source, long target, long channel_scid);
+       // struct LDKCVec_u8Z InFlightHtlcs_write(const struct LDKInFlightHtlcs *NONNULL_PTR obj);
+       public static native byte[] InFlightHtlcs_write(long obj);
+       // struct LDKCResult_InFlightHtlcsDecodeErrorZ InFlightHtlcs_read(struct LDKu8slice ser);
+       public static native long InFlightHtlcs_read(byte[] ser);
        // struct LDKCResult_InvoiceSignOrCreationErrorZ create_phantom_invoice(struct LDKCOption_u64Z amt_msat, struct LDKThirtyTwoBytes payment_hash, struct LDKStr description, uint32_t invoice_expiry_delta_secs, struct LDKCVec_PhantomRouteHintsZ phantom_route_hints, struct LDKKeysInterface keys_manager, enum LDKCurrency network);
        public static native long create_phantom_invoice(long amt_msat, byte[] payment_hash, String description, int invoice_expiry_delta_secs, long[] phantom_route_hints, long keys_manager, Currency network);
        // struct LDKCResult_InvoiceSignOrCreationErrorZ create_phantom_invoice_with_description_hash(struct LDKCOption_u64Z amt_msat, struct LDKThirtyTwoBytes payment_hash, uint32_t invoice_expiry_delta_secs, struct LDKSha256 description_hash, struct LDKCVec_PhantomRouteHintsZ phantom_route_hints, struct LDKKeysInterface keys_manager, enum LDKCurrency network);
@@ -8039,8 +8425,8 @@ public class bindings {
        public static native long create_invoice_from_channelmanager_and_duration_since_epoch(long channelmanager, long keys_manager, Currency network, long amt_msat, String description, long duration_since_epoch, int invoice_expiry_delta_secs);
        // void DefaultRouter_free(struct LDKDefaultRouter this_obj);
        public static native void DefaultRouter_free(long this_obj);
-       // MUST_USE_RES struct LDKDefaultRouter DefaultRouter_new(const struct LDKNetworkGraph *NONNULL_PTR network_graph, struct LDKLogger logger, struct LDKThirtyTwoBytes random_seed_bytes);
-       public static native long DefaultRouter_new(long network_graph, long logger, byte[] random_seed_bytes);
+       // MUST_USE_RES struct LDKDefaultRouter DefaultRouter_new(const struct LDKNetworkGraph *NONNULL_PTR network_graph, struct LDKLogger logger, struct LDKThirtyTwoBytes random_seed_bytes, struct LDKLockableScore scorer);
+       public static native long DefaultRouter_new(long network_graph, long logger, byte[] random_seed_bytes, long scorer);
        // struct LDKRouter DefaultRouter_as_Router(const struct LDKDefaultRouter *NONNULL_PTR this_arg);
        public static native long DefaultRouter_as_Router(long this_arg);
        // struct LDKPayer ChannelManager_as_Payer(const struct LDKChannelManager *NONNULL_PTR this_arg);
index 698f9fb827644ecbf77cf79fbd43be70ffc326bb..fbb0a917919fe07dd2955a3e3c92cdf63ed746ec 100644 (file)
@@ -89,11 +89,9 @@ public class BackgroundProcessor extends CommonBase {
         * [`Persister::persist_graph`]: lightning::util::persist::Persister::persist_graph
         * [`NetworkGraph`]: lightning::routing::gossip::NetworkGraph
         * [`NetworkGraph::write`]: lightning::routing::gossip::NetworkGraph#impl-Writeable
-        * 
-        * Note that scorer (or a relevant inner pointer) may be NULL or all-0s to represent None
         */
-       public static BackgroundProcessor start(Persister persister, EventHandler event_handler, ChainMonitor chain_monitor, ChannelManager channel_manager, GossipSync gossip_sync, PeerManager peer_manager, Logger logger, @Nullable MultiThreadedLockableScore scorer) {
-               long ret = bindings.BackgroundProcessor_start(persister == null ? 0 : persister.ptr, event_handler == null ? 0 : event_handler.ptr, chain_monitor == null ? 0 : chain_monitor.ptr, channel_manager == null ? 0 : channel_manager.ptr, gossip_sync.ptr, peer_manager == null ? 0 : peer_manager.ptr, logger == null ? 0 : logger.ptr, scorer == null ? 0 : scorer.ptr);
+       public static BackgroundProcessor start(Persister persister, EventHandler event_handler, ChainMonitor chain_monitor, ChannelManager channel_manager, GossipSync gossip_sync, PeerManager peer_manager, Logger logger, Option_WriteableScoreZ scorer) {
+               long ret = bindings.BackgroundProcessor_start(persister == null ? 0 : persister.ptr, event_handler == null ? 0 : event_handler.ptr, chain_monitor == null ? 0 : chain_monitor.ptr, channel_manager == null ? 0 : channel_manager.ptr, gossip_sync.ptr, peer_manager == null ? 0 : peer_manager.ptr, logger == null ? 0 : logger.ptr, scorer.ptr);
                Reference.reachabilityFence(persister);
                Reference.reachabilityFence(event_handler);
                Reference.reachabilityFence(chain_monitor);
index c2106e76cca9839e4e87e36fec9ab0bf37118118..1e59ef230b68c90633900f79bcde99723b967e49 100644 (file)
@@ -33,8 +33,14 @@ public class Balance extends CommonBase {
                if (raw_val.getClass() == bindings.LDKBalance.ContentiousClaimable.class) {
                        return new ContentiousClaimable(ptr, (bindings.LDKBalance.ContentiousClaimable)raw_val);
                }
-               if (raw_val.getClass() == bindings.LDKBalance.MaybeClaimableHTLCAwaitingTimeout.class) {
-                       return new MaybeClaimableHTLCAwaitingTimeout(ptr, (bindings.LDKBalance.MaybeClaimableHTLCAwaitingTimeout)raw_val);
+               if (raw_val.getClass() == bindings.LDKBalance.MaybeTimeoutClaimableHTLC.class) {
+                       return new MaybeTimeoutClaimableHTLC(ptr, (bindings.LDKBalance.MaybeTimeoutClaimableHTLC)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKBalance.MaybePreimageClaimableHTLC.class) {
+                       return new MaybePreimageClaimableHTLC(ptr, (bindings.LDKBalance.MaybePreimageClaimableHTLC)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKBalance.CounterpartyRevokedOutputClaimable.class) {
+                       return new CounterpartyRevokedOutputClaimable(ptr, (bindings.LDKBalance.CounterpartyRevokedOutputClaimable)raw_val);
                }
                assert false; return null; // Unreachable without extending the (internal) bindings interface
        }
@@ -107,10 +113,10 @@ public class Balance extends CommonBase {
         * fees) if the counterparty does not know the preimage for the HTLCs. These are somewhat
         * likely to be claimed by our counterparty before we do.
         */
-       public final static class MaybeClaimableHTLCAwaitingTimeout extends Balance {
+       public final static class MaybeTimeoutClaimableHTLC extends Balance {
                /**
-                * The amount available to claim, in satoshis, excluding the on-chain fees which will be
-                * required to do so.
+                * The amount potentially available to claim, in satoshis, excluding the on-chain fees
+                * which will be required to do so.
                */
                public final long claimable_amount_satoshis;
                /**
@@ -118,12 +124,54 @@ public class Balance extends CommonBase {
                 * done so.
                */
                public final int claimable_height;
-               private MaybeClaimableHTLCAwaitingTimeout(long ptr, bindings.LDKBalance.MaybeClaimableHTLCAwaitingTimeout obj) {
+               private MaybeTimeoutClaimableHTLC(long ptr, bindings.LDKBalance.MaybeTimeoutClaimableHTLC obj) {
                        super(null, ptr);
                        this.claimable_amount_satoshis = obj.claimable_amount_satoshis;
                        this.claimable_height = obj.claimable_height;
                }
        }
+       /**
+        * HTLCs which we received from our counterparty which are claimable with a preimage which we
+        * do not currently have. This will only be claimable if we receive the preimage from the node
+        * to which we forwarded this HTLC before the timeout.
+        */
+       public final static class MaybePreimageClaimableHTLC extends Balance {
+               /**
+                * The amount potentially available to claim, in satoshis, excluding the on-chain fees
+                * which will be required to do so.
+               */
+               public final long claimable_amount_satoshis;
+               /**
+                * The height at which our counterparty will be able to claim the balance if we have not
+                * yet received the preimage and claimed it ourselves.
+               */
+               public final int expiry_height;
+               private MaybePreimageClaimableHTLC(long ptr, bindings.LDKBalance.MaybePreimageClaimableHTLC obj) {
+                       super(null, ptr);
+                       this.claimable_amount_satoshis = obj.claimable_amount_satoshis;
+                       this.expiry_height = obj.expiry_height;
+               }
+       }
+       /**
+        * The channel has been closed, and our counterparty broadcasted a revoked commitment
+        * transaction.
+        * 
+        * Thus, we're able to claim all outputs in the commitment transaction, one of which has the
+        * following amount.
+        */
+       public final static class CounterpartyRevokedOutputClaimable extends Balance {
+               /**
+                * The amount, in satoshis, of the output which we can claim.
+                * 
+                * Note that for outputs from HTLC balances this may be excluding some on-chain fees that
+                * were already spent.
+               */
+               public final long claimable_amount_satoshis;
+               private CounterpartyRevokedOutputClaimable(long ptr, bindings.LDKBalance.CounterpartyRevokedOutputClaimable obj) {
+                       super(null, ptr);
+                       this.claimable_amount_satoshis = obj.claimable_amount_satoshis;
+               }
+       }
        long clone_ptr() {
                long ret = bindings.Balance_clone_ptr(this.ptr);
                Reference.reachabilityFence(this);
@@ -181,10 +229,10 @@ public class Balance extends CommonBase {
        }
 
        /**
-        * Utility method to constructs a new MaybeClaimableHTLCAwaitingTimeout-variant Balance
+        * Utility method to constructs a new MaybeTimeoutClaimableHTLC-variant Balance
         */
-       public static Balance maybe_claimable_htlcawaiting_timeout(long claimable_amount_satoshis, int claimable_height) {
-               long ret = bindings.Balance_maybe_claimable_htlcawaiting_timeout(claimable_amount_satoshis, claimable_height);
+       public static Balance maybe_timeout_claimable_htlc(long claimable_amount_satoshis, int claimable_height) {
+               long ret = bindings.Balance_maybe_timeout_claimable_htlc(claimable_amount_satoshis, claimable_height);
                Reference.reachabilityFence(claimable_amount_satoshis);
                Reference.reachabilityFence(claimable_height);
                if (ret >= 0 && ret <= 4096) { return null; }
@@ -193,6 +241,31 @@ public class Balance extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Utility method to constructs a new MaybePreimageClaimableHTLC-variant Balance
+        */
+       public static Balance maybe_preimage_claimable_htlc(long claimable_amount_satoshis, int expiry_height) {
+               long ret = bindings.Balance_maybe_preimage_claimable_htlc(claimable_amount_satoshis, expiry_height);
+               Reference.reachabilityFence(claimable_amount_satoshis);
+               Reference.reachabilityFence(expiry_height);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Balance ret_hu_conv = org.ldk.structs.Balance.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Utility method to constructs a new CounterpartyRevokedOutputClaimable-variant Balance
+        */
+       public static Balance counterparty_revoked_output_claimable(long claimable_amount_satoshis) {
+               long ret = bindings.Balance_counterparty_revoked_output_claimable(claimable_amount_satoshis);
+               Reference.reachabilityFence(claimable_amount_satoshis);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Balance ret_hu_conv = org.ldk.structs.Balance.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
        /**
         * Checks if two Balances contain equal inner contents.
         * This ignores pointers and is_owned flags and looks at the values in fields.
diff --git a/src/main/java/org/ldk/structs/BigEndianScalar.java b/src/main/java/org/ldk/structs/BigEndianScalar.java
new file mode 100644 (file)
index 0000000..101544f
--- /dev/null
@@ -0,0 +1,28 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+public class BigEndianScalar extends CommonBase {
+       /** The bytes of the scalar value, in big endian */
+       public final byte[] scalar_bytes;
+
+       BigEndianScalar(java.lang.Object _dummy, long ptr) {
+               super(ptr);
+               this.scalar_bytes = bindings.BigEndianScalar_get_bytes(ptr);
+       }
+       public BigEndianScalar(byte[] scalar_bytes) {
+               super(bindings.BigEndianScalar_new(scalar_bytes));
+               this.scalar_bytes = bindings.BigEndianScalar_get_bytes(ptr);
+       }
+
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.BigEndianScalar_free(ptr); }
+       }
+}
\ No newline at end of file
diff --git a/src/main/java/org/ldk/structs/BlindedHop.java b/src/main/java/org/ldk/structs/BlindedHop.java
new file mode 100644 (file)
index 0000000..5432512
--- /dev/null
@@ -0,0 +1,44 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * Used to construct the blinded hops portion of a blinded route. These hops cannot be identified
+ * by outside observers and thus can be used to hide the identity of the recipient.
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class BlindedHop extends CommonBase {
+       BlindedHop(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.BlindedHop_free(ptr); }
+       }
+
+       /**
+        * Serialize the BlindedHop object into a byte array which can be read by BlindedHop_read
+        */
+       public byte[] write() {
+               byte[] ret = bindings.BlindedHop_write(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Read a BlindedHop from a byte array, created by BlindedHop_write
+        */
+       public static Result_BlindedHopDecodeErrorZ read(byte[] ser) {
+               long ret = bindings.BlindedHop_read(ser);
+               Reference.reachabilityFence(ser);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_BlindedHopDecodeErrorZ ret_hu_conv = Result_BlindedHopDecodeErrorZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/BlindedRoute.java b/src/main/java/org/ldk/structs/BlindedRoute.java
new file mode 100644 (file)
index 0000000..d35db03
--- /dev/null
@@ -0,0 +1,60 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * Onion messages can be sent and received to blinded routes, which serve to hide the identity of
+ * the recipient.
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class BlindedRoute extends CommonBase {
+       BlindedRoute(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.BlindedRoute_free(ptr); }
+       }
+
+       /**
+        * Create a blinded route to be forwarded along `node_pks`. The last node pubkey in `node_pks`
+        * will be the destination node.
+        * 
+        * Errors if less than two hops are provided or if `node_pk`(s) are invalid.
+        */
+       public static Result_BlindedRouteNoneZ of(byte[][] node_pks, KeysInterface keys_manager) {
+               long ret = bindings.BlindedRoute_new(node_pks != null ? Arrays.stream(node_pks).map(node_pks_conv_8 -> InternalUtils.check_arr_len(node_pks_conv_8, 33)).toArray(byte[][]::new) : null, keys_manager == null ? 0 : keys_manager.ptr);
+               Reference.reachabilityFence(node_pks);
+               Reference.reachabilityFence(keys_manager);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_BlindedRouteNoneZ ret_hu_conv = Result_BlindedRouteNoneZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(keys_manager); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Serialize the BlindedRoute object into a byte array which can be read by BlindedRoute_read
+        */
+       public byte[] write() {
+               byte[] ret = bindings.BlindedRoute_write(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Read a BlindedRoute from a byte array, created by BlindedRoute_write
+        */
+       public static Result_BlindedRouteDecodeErrorZ read(byte[] ser) {
+               long ret = bindings.BlindedRoute_read(ser);
+               Reference.reachabilityFence(ser);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_BlindedRouteDecodeErrorZ ret_hu_conv = Result_BlindedRouteDecodeErrorZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+}
index 8cf0198634e5830c4eeb1467c22e6a6937f544d5..0dce840d34edac6b55e40cbac308c7f4dff66886 100644 (file)
@@ -336,11 +336,71 @@ public class ChannelHandshakeConfig extends CommonBase {
                Reference.reachabilityFence(val);
        }
 
+       /**
+        * The Proportion of the channel value to configure as counterparty's channel reserve,
+        * i.e., `their_channel_reserve_satoshis` for both outbound and inbound channels.
+        * 
+        * `their_channel_reserve_satoshis` is the minimum balance that the other node has to maintain
+        * on their side, at all times.
+        * This ensures that if our counterparty broadcasts a revoked state, we can punish them by
+        * claiming at least this value on chain.
+        * 
+        * Channel reserve values greater than 30% could be considered highly unreasonable, since that
+        * amount can never be used for payments.
+        * Also, if our selected channel reserve for counterparty and counterparty's selected
+        * channel reserve for us sum up to equal or greater than channel value, channel negotiations
+        * will fail.
+        * 
+        * Note: Versions of LDK earlier than v0.0.104 will fail to read channels with any channel reserve
+        * other than the default value.
+        * 
+        * Default value: 1% of channel value, i.e., configured as 10,000 millionths.
+        * Minimum value: If the calculated proportional value is less than 1000 sats, it will be treated
+        * as 1000 sats instead, which is a safe implementation-specific lower bound.
+        * Maximum value: 1,000,000, any values larger than 1 Million will be treated as 1 Million (or 100%)
+        * instead, although channel negotiations will fail in that case.
+        */
+       public int get_their_channel_reserve_proportional_millionths() {
+               int ret = bindings.ChannelHandshakeConfig_get_their_channel_reserve_proportional_millionths(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * The Proportion of the channel value to configure as counterparty's channel reserve,
+        * i.e., `their_channel_reserve_satoshis` for both outbound and inbound channels.
+        * 
+        * `their_channel_reserve_satoshis` is the minimum balance that the other node has to maintain
+        * on their side, at all times.
+        * This ensures that if our counterparty broadcasts a revoked state, we can punish them by
+        * claiming at least this value on chain.
+        * 
+        * Channel reserve values greater than 30% could be considered highly unreasonable, since that
+        * amount can never be used for payments.
+        * Also, if our selected channel reserve for counterparty and counterparty's selected
+        * channel reserve for us sum up to equal or greater than channel value, channel negotiations
+        * will fail.
+        * 
+        * Note: Versions of LDK earlier than v0.0.104 will fail to read channels with any channel reserve
+        * other than the default value.
+        * 
+        * Default value: 1% of channel value, i.e., configured as 10,000 millionths.
+        * Minimum value: If the calculated proportional value is less than 1000 sats, it will be treated
+        * as 1000 sats instead, which is a safe implementation-specific lower bound.
+        * Maximum value: 1,000,000, any values larger than 1 Million will be treated as 1 Million (or 100%)
+        * instead, although channel negotiations will fail in that case.
+        */
+       public void set_their_channel_reserve_proportional_millionths(int val) {
+               bindings.ChannelHandshakeConfig_set_their_channel_reserve_proportional_millionths(this.ptr, val);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(val);
+       }
+
        /**
         * Constructs a new ChannelHandshakeConfig given each field
         */
-       public static ChannelHandshakeConfig of(int minimum_depth_arg, short our_to_self_delay_arg, long our_htlc_minimum_msat_arg, byte max_inbound_htlc_value_in_flight_percent_of_channel_arg, boolean negotiate_scid_privacy_arg, boolean announced_channel_arg, boolean commit_upfront_shutdown_pubkey_arg) {
-               long ret = bindings.ChannelHandshakeConfig_new(minimum_depth_arg, our_to_self_delay_arg, our_htlc_minimum_msat_arg, max_inbound_htlc_value_in_flight_percent_of_channel_arg, negotiate_scid_privacy_arg, announced_channel_arg, commit_upfront_shutdown_pubkey_arg);
+       public static ChannelHandshakeConfig of(int minimum_depth_arg, short our_to_self_delay_arg, long our_htlc_minimum_msat_arg, byte max_inbound_htlc_value_in_flight_percent_of_channel_arg, boolean negotiate_scid_privacy_arg, boolean announced_channel_arg, boolean commit_upfront_shutdown_pubkey_arg, int their_channel_reserve_proportional_millionths_arg) {
+               long ret = bindings.ChannelHandshakeConfig_new(minimum_depth_arg, our_to_self_delay_arg, our_htlc_minimum_msat_arg, max_inbound_htlc_value_in_flight_percent_of_channel_arg, negotiate_scid_privacy_arg, announced_channel_arg, commit_upfront_shutdown_pubkey_arg, their_channel_reserve_proportional_millionths_arg);
                Reference.reachabilityFence(minimum_depth_arg);
                Reference.reachabilityFence(our_to_self_delay_arg);
                Reference.reachabilityFence(our_htlc_minimum_msat_arg);
@@ -348,6 +408,7 @@ public class ChannelHandshakeConfig extends CommonBase {
                Reference.reachabilityFence(negotiate_scid_privacy_arg);
                Reference.reachabilityFence(announced_channel_arg);
                Reference.reachabilityFence(commit_upfront_shutdown_pubkey_arg);
+               Reference.reachabilityFence(their_channel_reserve_proportional_millionths_arg);
                if (ret >= 0 && ret <= 4096) { return null; }
                org.ldk.structs.ChannelHandshakeConfig ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.ChannelHandshakeConfig(null, ret); }
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
index e8560640d2b8fda371e23b8a5aa58c58e2dc9cbd..883234c20afbe9ab91322b0ce1470af6a65e2da4 100644 (file)
@@ -90,7 +90,7 @@ public class ChannelManager extends CommonBase {
        }
 
        /**
-        * Gets the current configuration applied to all new channels,  as
+        * Gets the current configuration applied to all new channels.
         */
        public UserConfig get_current_default_configuration() {
                long ret = bindings.ChannelManager_get_current_default_configuration(this.ptr);
@@ -487,34 +487,6 @@ public class ChannelManager extends CommonBase {
                return ret_hu_conv;
        }
 
-       /**
-        * Regenerates channel_announcements and generates a signed node_announcement from the given
-        * arguments, providing them in corresponding events via
-        * [`get_and_clear_pending_msg_events`], if at least one public channel has been confirmed
-        * on-chain. This effectively re-broadcasts all channel announcements and sends our node
-        * announcement to ensure that the lightning P2P network is aware of the channels we have and
-        * our network addresses.
-        * 
-        * `rgb` is a node \"color\" and `alias` is a printable human-readable string to describe this
-        * node to humans. They carry no in-protocol meaning.
-        * 
-        * `addresses` represent the set (possibly empty) of socket addresses on which this node
-        * accepts incoming connections. These will be included in the node_announcement, publicly
-        * tying these addresses together and to this node. If you wish to preserve user privacy,
-        * addresses should likely contain only Tor Onion addresses.
-        * 
-        * Panics if `addresses` is absurdly large (more than 100).
-        * 
-        * [`get_and_clear_pending_msg_events`]: MessageSendEventsProvider::get_and_clear_pending_msg_events
-        */
-       public void broadcast_node_announcement(byte[] rgb, byte[] alias, NetAddress[] addresses) {
-               bindings.ChannelManager_broadcast_node_announcement(this.ptr, InternalUtils.check_arr_len(rgb, 3), InternalUtils.check_arr_len(alias, 32), addresses != null ? Arrays.stream(addresses).mapToLong(addresses_conv_12 -> addresses_conv_12.ptr).toArray() : null);
-               Reference.reachabilityFence(this);
-               Reference.reachabilityFence(rgb);
-               Reference.reachabilityFence(alias);
-               Reference.reachabilityFence(addresses);
-       }
-
        /**
         * Atomically updates the [`ChannelConfig`] for the given channels.
         * 
@@ -953,6 +925,20 @@ public class ChannelManager extends CommonBase {
                Reference.reachabilityFence(this);
        }
 
+       /**
+        * Gets a [`Future`] that completes when a persistable update is available. Note that
+        * callbacks registered on the [`Future`] MUST NOT call back into this [`ChannelManager`] and
+        * should instead register actions to be taken later.
+        */
+       public Future get_persistable_update_future() {
+               long ret = bindings.ChannelManager_get_persistable_update_future(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Future ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.Future(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
        /**
         * Gets the latest best block which was connected either via the [`chain::Listen`] or
         * [`chain::Confirm`] interfaces.
index ccb88fc764da249053177db91bfc37f1a667e0bc..73d0ca172a3e26e54d33e93e15abdc2326dd33f1 100644 (file)
@@ -112,6 +112,20 @@ public class ChannelMessageHandler extends CommonBase {
                 * Handle an incoming error message from the given peer.
                 */
                void handle_error(byte[] their_node_id, ErrorMessage msg);
+               /**
+                * Gets the node feature flags which this handler itself supports. All available handlers are
+                * queried similarly and their feature flags are OR'd together to form the [`NodeFeatures`]
+                * which are broadcasted in our [`NodeAnnouncement`] message.
+                */
+               NodeFeatures provided_node_features();
+               /**
+                * Gets the init feature flags which should be sent to the given peer. All available handlers
+                * are queried similarly and their feature flags are OR'd together to form the [`InitFeatures`]
+                * which are sent in our [`Init`] message.
+                * 
+                * Note that this method is called before [`Self::peer_connected`].
+                */
+               InitFeatures provided_init_features(byte[] their_node_id);
        }
        private static class LDKChannelMessageHandlerHolder { ChannelMessageHandler held; }
        public static ChannelMessageHandler new_impl(ChannelMessageHandlerInterface arg, MessageSendEventsProvider.MessageSendEventsProviderInterface MessageSendEventsProvider_impl) {
@@ -221,6 +235,18 @@ public class ChannelMessageHandler extends CommonBase {
                                arg.handle_error(their_node_id, msg_hu_conv);
                                Reference.reachabilityFence(arg);
                        }
+                       @Override public long provided_node_features() {
+                               NodeFeatures ret = arg.provided_node_features();
+                               Reference.reachabilityFence(arg);
+                               long result = ret == null ? 0 : ret.clone_ptr();
+                               return result;
+                       }
+                       @Override public long provided_init_features(byte[] their_node_id) {
+                               InitFeatures ret = arg.provided_init_features(their_node_id);
+                               Reference.reachabilityFence(arg);
+                               long result = ret == null ? 0 : ret.clone_ptr();
+                               return result;
+                       }
                }, MessageSendEventsProvider.new_impl(MessageSendEventsProvider_impl).bindings_instance);
                return impl_holder.held;
        }
@@ -462,4 +488,35 @@ public class ChannelMessageHandler extends CommonBase {
                if (this != null) { this.ptrs_to.add(msg); };
        }
 
+       /**
+        * Gets the node feature flags which this handler itself supports. All available handlers are
+        * queried similarly and their feature flags are OR'd together to form the [`NodeFeatures`]
+        * which are broadcasted in our [`NodeAnnouncement`] message.
+        */
+       public NodeFeatures provided_node_features() {
+               long ret = bindings.ChannelMessageHandler_provided_node_features(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.NodeFeatures ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.NodeFeatures(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Gets the init feature flags which should be sent to the given peer. All available handlers
+        * are queried similarly and their feature flags are OR'd together to form the [`InitFeatures`]
+        * which are sent in our [`Init`] message.
+        * 
+        * Note that this method is called before [`Self::peer_connected`].
+        */
+       public InitFeatures provided_init_features(byte[] their_node_id) {
+               long ret = bindings.ChannelMessageHandler_provided_init_features(this.ptr, InternalUtils.check_arr_len(their_node_id, 33));
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(their_node_id);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.InitFeatures ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.InitFeatures(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
 }
index 9284814f0760008245011281a6833b11c841225f..80a97f3491565b34d3f9c1bf662e27c9b81e2a55 100644 (file)
@@ -378,8 +378,9 @@ public class ChannelMonitor extends CommonBase {
         * balance, or until our counterparty has claimed the balance and accrued several
         * confirmations on the claim transaction.
         * 
-        * Note that the balances available when you or your counterparty have broadcasted revoked
-        * state(s) may not be fully captured here.
+        * Note that for `ChannelMonitors` which track a channel which went on-chain with versions of
+        * LDK prior to 0.0.111, balances may not be fully captured if our counterparty broadcasted
+        * a revoked state.
         * 
         * See [`Balance`] for additional details on the types of claimable balances which
         * may be returned here and their meanings.
index 8d311b29be3fc644912b971a8057d795d1f983e0..876049c44a1d9f617b0408bc4317f641ba55da39 100644 (file)
@@ -9,8 +9,13 @@ import javax.annotation.Nullable;
 
 
 /**
- * An update generated by the underlying Channel itself which contains some new information the
- * ChannelMonitor should be made aware of.
+ * An update generated by the underlying channel itself which contains some new information the
+ * [`ChannelMonitor`] should be made aware of.
+ * 
+ * Because this represents only a small number of updates to the underlying state, it is generally
+ * much smaller than a full [`ChannelMonitor`]. However, for large single commitment transaction
+ * updates (e.g. ones during which there are hundreds of HTLCs pending on the commitment
+ * transaction), a single update may reach upwards of 1 MiB in serialized size.
  */
 @SuppressWarnings("unchecked") // We correctly assign various generic arrays
 public class ChannelMonitorUpdate extends CommonBase {
index 99955fa33e2e6476da0d58916bb6194e425ab6a1..4ecf6a8c3e4132c627ce55e746a220310ec4084f 100644 (file)
@@ -68,7 +68,7 @@ public class Confirm extends CommonBase {
                 * in the event of a chain reorganization, it must not be called with a `header` that is no
                 * longer in the chain as of the last call to [`best_block_updated`].
                 * 
-                * [chain order]: Confirm#Order
+                * [chain order]: Confirm#order
                 * [`best_block_updated`]: Self::best_block_updated
                 */
                void transactions_confirmed(byte[] header, TwoTuple_usizeTransactionZ[] txdata, int height);
@@ -76,8 +76,8 @@ public class Confirm extends CommonBase {
                 * Processes a transaction that is no longer confirmed as result of a chain reorganization.
                 * 
                 * Should be called for any transaction returned by [`get_relevant_txids`] if it has been
-                * reorganized out of the best chain. Once called, the given transaction should not be returned
-                * by [`get_relevant_txids`] unless it has been reconfirmed via [`transactions_confirmed`].
+                * reorganized out of the best chain. Once called, the given transaction will not be returned
+                * by [`get_relevant_txids`], unless it has been reconfirmed via [`transactions_confirmed`].
                 * 
                 * [`get_relevant_txids`]: Self::get_relevant_txids
                 * [`transactions_confirmed`]: Self::transactions_confirmed
@@ -93,9 +93,9 @@ public class Confirm extends CommonBase {
                /**
                 * Returns transactions that should be monitored for reorganization out of the chain.
                 * 
-                * Should include any transactions passed to [`transactions_confirmed`] that have insufficient
-                * confirmations to be safe from a chain reorganization. Should not include any transactions
-                * passed to [`transaction_unconfirmed`] unless later reconfirmed.
+                * Will include any transactions passed to [`transactions_confirmed`] that have insufficient
+                * confirmations to be safe from a chain reorganization. Will not include any transactions
+                * passed to [`transaction_unconfirmed`], unless later reconfirmed.
                 * 
                 * May be called to determine the subset of transactions that must still be monitored for
                 * reorganization. Will be idempotent between calls but may change as a result of calls to the
@@ -152,7 +152,7 @@ public class Confirm extends CommonBase {
         * in the event of a chain reorganization, it must not be called with a `header` that is no
         * longer in the chain as of the last call to [`best_block_updated`].
         * 
-        * [chain order]: Confirm#Order
+        * [chain order]: Confirm#order
         * [`best_block_updated`]: Self::best_block_updated
         */
        public void transactions_confirmed(byte[] header, TwoTuple_usizeTransactionZ[] txdata, int height) {
@@ -167,8 +167,8 @@ public class Confirm extends CommonBase {
         * Processes a transaction that is no longer confirmed as result of a chain reorganization.
         * 
         * Should be called for any transaction returned by [`get_relevant_txids`] if it has been
-        * reorganized out of the best chain. Once called, the given transaction should not be returned
-        * by [`get_relevant_txids`] unless it has been reconfirmed via [`transactions_confirmed`].
+        * reorganized out of the best chain. Once called, the given transaction will not be returned
+        * by [`get_relevant_txids`], unless it has been reconfirmed via [`transactions_confirmed`].
         * 
         * [`get_relevant_txids`]: Self::get_relevant_txids
         * [`transactions_confirmed`]: Self::transactions_confirmed
@@ -195,9 +195,9 @@ public class Confirm extends CommonBase {
        /**
         * Returns transactions that should be monitored for reorganization out of the chain.
         * 
-        * Should include any transactions passed to [`transactions_confirmed`] that have insufficient
-        * confirmations to be safe from a chain reorganization. Should not include any transactions
-        * passed to [`transaction_unconfirmed`] unless later reconfirmed.
+        * Will include any transactions passed to [`transactions_confirmed`] that have insufficient
+        * confirmations to be safe from a chain reorganization. Will not include any transactions
+        * passed to [`transaction_unconfirmed`], unless later reconfirmed.
         * 
         * May be called to determine the subset of transactions that must still be monitored for
         * reorganization. Will be idempotent between calls but may change as a result of calls to the
index 92769fd9983b609377ee01c973651469ff23973d..248af1b3c59e02a4b5283f5035aad18f50206434 100644 (file)
@@ -24,16 +24,18 @@ public class DefaultRouter extends CommonBase {
         * Creates a new router using the given [`NetworkGraph`], a [`Logger`], and a randomness source
         * `random_seed_bytes`.
         */
-       public static DefaultRouter of(NetworkGraph network_graph, Logger logger, byte[] random_seed_bytes) {
-               long ret = bindings.DefaultRouter_new(network_graph == null ? 0 : network_graph.ptr, logger == null ? 0 : logger.ptr, InternalUtils.check_arr_len(random_seed_bytes, 32));
+       public static DefaultRouter of(NetworkGraph network_graph, Logger logger, byte[] random_seed_bytes, LockableScore scorer) {
+               long ret = bindings.DefaultRouter_new(network_graph == null ? 0 : network_graph.ptr, logger == null ? 0 : logger.ptr, InternalUtils.check_arr_len(random_seed_bytes, 32), scorer == null ? 0 : scorer.ptr);
                Reference.reachabilityFence(network_graph);
                Reference.reachabilityFence(logger);
                Reference.reachabilityFence(random_seed_bytes);
+               Reference.reachabilityFence(scorer);
                if (ret >= 0 && ret <= 4096) { return null; }
                org.ldk.structs.DefaultRouter ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.DefaultRouter(null, ret); }
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(network_graph); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(logger); };
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(scorer); };
                return ret_hu_conv;
        }
 
diff --git a/src/main/java/org/ldk/structs/Destination.java b/src/main/java/org/ldk/structs/Destination.java
new file mode 100644 (file)
index 0000000..8ff6799
--- /dev/null
@@ -0,0 +1,89 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * The destination of an onion message.
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class Destination extends CommonBase {
+       private Destination(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.Destination_free(ptr); }
+       }
+       static Destination constr_from_ptr(long ptr) {
+               bindings.LDKDestination raw_val = bindings.LDKDestination_ref_from_ptr(ptr);
+               if (raw_val.getClass() == bindings.LDKDestination.Node.class) {
+                       return new Node(ptr, (bindings.LDKDestination.Node)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKDestination.BlindedRoute.class) {
+                       return new BlindedRoute(ptr, (bindings.LDKDestination.BlindedRoute)raw_val);
+               }
+               assert false; return null; // Unreachable without extending the (internal) bindings interface
+       }
+
+       /**
+        * We're sending this onion message to a node.
+        */
+       public final static class Node extends Destination {
+               public final byte[] node;
+               private Node(long ptr, bindings.LDKDestination.Node obj) {
+                       super(null, ptr);
+                       this.node = obj.node;
+               }
+       }
+       /**
+        * We're sending this onion message to a blinded route.
+        */
+       public final static class BlindedRoute extends Destination {
+               public final org.ldk.structs.BlindedRoute blinded_route;
+               private BlindedRoute(long ptr, bindings.LDKDestination.BlindedRoute obj) {
+                       super(null, ptr);
+                       long blinded_route = obj.blinded_route;
+                       org.ldk.structs.BlindedRoute blinded_route_hu_conv = null; if (blinded_route < 0 || blinded_route > 4096) { blinded_route_hu_conv = new org.ldk.structs.BlindedRoute(null, blinded_route); }
+                       if (blinded_route_hu_conv != null) { blinded_route_hu_conv.ptrs_to.add(this); };
+                       this.blinded_route = blinded_route_hu_conv;
+               }
+       }
+       /**
+        * Utility method to constructs a new Node-variant Destination
+        */
+       public static Destination node(byte[] a) {
+               long ret = bindings.Destination_node(InternalUtils.check_arr_len(a, 33));
+               Reference.reachabilityFence(a);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Destination ret_hu_conv = org.ldk.structs.Destination.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Utility method to constructs a new BlindedRoute-variant Destination
+        */
+       public static Destination blinded_route(BlindedRoute a) {
+               long ret = bindings.Destination_blinded_route(a == null ? 0 : a.ptr);
+               Reference.reachabilityFence(a);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Destination ret_hu_conv = org.ldk.structs.Destination.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(a); };
+               // Due to rust's strict-ownership memory model, in some cases we need to "move"
+               // an object to pass exclusive ownership to the function being called.
+               // In most cases, we avoid ret_hu_conv being visible in GC'd languages by cloning the object
+               // at the FFI layer, creating a new object which Rust can claim ownership of
+               // However, in some cases (eg here), there is no way to clone an object, and thus
+               // we actually have to pass full ownership to Rust.
+               // Thus, after ret_hu_conv call, a is reset to null and is now a dummy object.
+               a.ptr = 0;;
+               return ret_hu_conv;
+       }
+
+}
index 52659eb1cbfcfa7b117ea037e60fdaa4fd88b0eb..8663e761b6baa87d1aed6729eb8f62247cdc5ed4 100644 (file)
@@ -371,7 +371,7 @@ public class Event extends CommonBase {
                 * the payment has failed, not just the route in question. If this is not set, you may
                 * retry the payment via a different route.
                */
-               public final boolean rejected_by_dest;
+               public final boolean payment_failed_permanently;
                /**
                 * Any failure information conveyed via the Onion return packet by a node along the failed
                 * payment route.
@@ -432,7 +432,7 @@ public class Event extends CommonBase {
                        super(null, ptr);
                        this.payment_id = obj.payment_id;
                        this.payment_hash = obj.payment_hash;
-                       this.rejected_by_dest = obj.rejected_by_dest;
+                       this.payment_failed_permanently = obj.payment_failed_permanently;
                        long network_update = obj.network_update;
                        org.ldk.structs.Option_NetworkUpdateZ network_update_hu_conv = org.ldk.structs.Option_NetworkUpdateZ.constr_from_ptr(network_update);
                        if (network_update_hu_conv != null) { network_update_hu_conv.ptrs_to.add(this); };
@@ -908,11 +908,11 @@ public class Event extends CommonBase {
        /**
         * Utility method to constructs a new PaymentPathFailed-variant Event
         */
-       public static Event payment_path_failed(byte[] payment_id, byte[] payment_hash, boolean rejected_by_dest, Option_NetworkUpdateZ network_update, boolean all_paths_failed, RouteHop[] path, Option_u64Z short_channel_id, RouteParameters retry) {
-               long ret = bindings.Event_payment_path_failed(InternalUtils.check_arr_len(payment_id, 32), InternalUtils.check_arr_len(payment_hash, 32), rejected_by_dest, network_update.ptr, all_paths_failed, path != null ? Arrays.stream(path).mapToLong(path_conv_10 -> path_conv_10 == null ? 0 : path_conv_10.ptr).toArray() : null, short_channel_id.ptr, retry == null ? 0 : retry.ptr);
+       public static Event payment_path_failed(byte[] payment_id, byte[] payment_hash, boolean payment_failed_permanently, Option_NetworkUpdateZ network_update, boolean all_paths_failed, RouteHop[] path, Option_u64Z short_channel_id, RouteParameters retry) {
+               long ret = bindings.Event_payment_path_failed(InternalUtils.check_arr_len(payment_id, 32), InternalUtils.check_arr_len(payment_hash, 32), payment_failed_permanently, network_update.ptr, all_paths_failed, path != null ? Arrays.stream(path).mapToLong(path_conv_10 -> path_conv_10 == null ? 0 : path_conv_10.ptr).toArray() : null, short_channel_id.ptr, retry == null ? 0 : retry.ptr);
                Reference.reachabilityFence(payment_id);
                Reference.reachabilityFence(payment_hash);
-               Reference.reachabilityFence(rejected_by_dest);
+               Reference.reachabilityFence(payment_failed_permanently);
                Reference.reachabilityFence(network_update);
                Reference.reachabilityFence(all_paths_failed);
                Reference.reachabilityFence(path);
index a53de7b532647ffccb19165ee3e1845694b86728..f4f22f3933eeacb55f7d063b04a14d2def807a35 100644 (file)
@@ -14,11 +14,17 @@ import javax.annotation.Nullable;
  * 
  * # Requirements
  * 
- * See [`process_pending_events`] for requirements around event processing.
- * 
  * When using this trait, [`process_pending_events`] will call [`handle_event`] for each pending
- * event since the last invocation. The handler must either act upon the event immediately
- * or preserve it for later handling.
+ * event since the last invocation.
+ * 
+ * In order to ensure no [`Event`]s are lost, implementors of this trait will persist [`Event`]s
+ * and replay any unhandled events on startup. An [`Event`] is considered handled when
+ * [`process_pending_events`] returns, thus handlers MUST fully handle [`Event`]s and persist any
+ * relevant changes to disk *before* returning.
+ * 
+ * Further, because an application may crash between an [`Event`] being handled and the
+ * implementor of this trait being re-serialized, [`Event`] handling must be idempotent - in
+ * effect, [`Event`]s may be replayed.
  * 
  * Note, handlers may call back into the provider and thus deadlocking must be avoided. Be sure to
  * consult the provider's documentation on the implication of processing events and how a handler
@@ -51,9 +57,7 @@ public class EventsProvider extends CommonBase {
                /**
                 * Processes any events generated since the last call using the given event handler.
                 * 
-                * Subsequent calls must only process new events. However, handlers must be capable of handling
-                * duplicate events across process restarts. This may occur if the provider was recovered from
-                * an old state (i.e., it hadn't been successfully persisted after processing pending events).
+                * See the trait-level documentation for requirements.
                 */
                void process_pending_events(EventHandler handler);
        }
@@ -73,9 +77,7 @@ public class EventsProvider extends CommonBase {
        /**
         * Processes any events generated since the last call using the given event handler.
         * 
-        * Subsequent calls must only process new events. However, handlers must be capable of handling
-        * duplicate events across process restarts. This may occur if the provider was recovered from
-        * an old state (i.e., it hadn't been successfully persisted after processing pending events).
+        * See the trait-level documentation for requirements.
         */
        public void process_pending_events(EventHandler handler) {
                bindings.EventsProvider_process_pending_events(this.ptr, handler == null ? 0 : handler.ptr);
index 561caaed6807728e05fac983aaa44a016bf11e45..9a418d46a9023b6ef9528f921757f5e57f54bffd 100644 (file)
@@ -52,15 +52,12 @@ public class Filter extends CommonBase {
                /**
                 * Registers interest in spends of a transaction output.
                 * 
-                * Optionally, when `output.block_hash` is set, should return any transaction spending the
-                * output that is found in the corresponding block along with its index.
-                * 
-                * This return value is useful for Electrum clients in order to supply in-block descendant
-                * transactions which otherwise were not included. This is not necessary for other clients if
-                * such descendant transactions were already included (e.g., when a BIP 157 client provides the
-                * full block).
+                * Note that this method might be called during processing of a new block. You therefore need
+                * to ensure that also dependent output spents within an already connected block are correctly
+                * handled, e.g., by re-scanning the block in question whenever new outputs have been
+                * registered mid-processing.
                 */
-               Option_C2Tuple_usizeTransactionZZ register_output(WatchedOutput output);
+               void register_output(WatchedOutput output);
        }
        private static class LDKFilterHolder { Filter held; }
        public static Filter new_impl(FilterInterface arg) {
@@ -70,13 +67,11 @@ public class Filter extends CommonBase {
                                arg.register_tx(txid, script_pubkey);
                                Reference.reachabilityFence(arg);
                        }
-                       @Override public long register_output(long output) {
+                       @Override public void register_output(long output) {
                                org.ldk.structs.WatchedOutput output_hu_conv = null; if (output < 0 || output > 4096) { output_hu_conv = new org.ldk.structs.WatchedOutput(null, output); }
                                if (output_hu_conv != null) { output_hu_conv.ptrs_to.add(this); };
-                               Option_C2Tuple_usizeTransactionZZ ret = arg.register_output(output_hu_conv);
+                               arg.register_output(output_hu_conv);
                                Reference.reachabilityFence(arg);
-                               long result = ret == null ? 0 : ret.clone_ptr();
-                               return result;
                        }
                });
                return impl_holder.held;
@@ -95,23 +90,16 @@ public class Filter extends CommonBase {
        /**
         * Registers interest in spends of a transaction output.
         * 
-        * Optionally, when `output.block_hash` is set, should return any transaction spending the
-        * output that is found in the corresponding block along with its index.
-        * 
-        * This return value is useful for Electrum clients in order to supply in-block descendant
-        * transactions which otherwise were not included. This is not necessary for other clients if
-        * such descendant transactions were already included (e.g., when a BIP 157 client provides the
-        * full block).
+        * Note that this method might be called during processing of a new block. You therefore need
+        * to ensure that also dependent output spents within an already connected block are correctly
+        * handled, e.g., by re-scanning the block in question whenever new outputs have been
+        * registered mid-processing.
         */
-       public Option_C2Tuple_usizeTransactionZZ register_output(WatchedOutput output) {
-               long ret = bindings.Filter_register_output(this.ptr, output == null ? 0 : output.ptr);
+       public void register_output(WatchedOutput output) {
+               bindings.Filter_register_output(this.ptr, output == null ? 0 : output.ptr);
                Reference.reachabilityFence(this);
                Reference.reachabilityFence(output);
-               if (ret >= 0 && ret <= 4096) { return null; }
-               org.ldk.structs.Option_C2Tuple_usizeTransactionZZ ret_hu_conv = org.ldk.structs.Option_C2Tuple_usizeTransactionZZ.constr_from_ptr(ret);
-               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
                if (this != null) { this.ptrs_to.add(output); };
-               return ret_hu_conv;
        }
 
 }
diff --git a/src/main/java/org/ldk/structs/Future.java b/src/main/java/org/ldk/structs/Future.java
new file mode 100644 (file)
index 0000000..b59563a
--- /dev/null
@@ -0,0 +1,34 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * A simple future which can complete once, and calls some callback(s) when it does so.
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class Future extends CommonBase {
+       Future(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.Future_free(ptr); }
+       }
+
+       /**
+        * Registers a callback to be called upon completion of this future. If the future has already
+        * completed, the callback will be called immediately.
+        */
+       public void register_callback_fn(FutureCallback callback) {
+               bindings.Future_register_callback_fn(this.ptr, callback == null ? 0 : callback.ptr);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(callback);
+               if (this != null) { this.ptrs_to.add(callback); };
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/FutureCallback.java b/src/main/java/org/ldk/structs/FutureCallback.java
new file mode 100644 (file)
index 0000000..b21cea9
--- /dev/null
@@ -0,0 +1,59 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+/**
+ * A callback which is called when a [`Future`] completes.
+ * 
+ * Note that this MUST NOT call back into LDK directly, it must instead schedule actions to be
+ * taken later. Rust users should use the [`std::future::Future`] implementation for [`Future`]
+ * instead.
+ * 
+ * Note that the [`std::future::Future`] implementation may only work for runtimes which schedule
+ * futures when they receive a wake, rather than immediately executing them.
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class FutureCallback extends CommonBase {
+       final bindings.LDKFutureCallback bindings_instance;
+       FutureCallback(Object _dummy, long ptr) { super(ptr); bindings_instance = null; }
+       private FutureCallback(bindings.LDKFutureCallback arg) {
+               super(bindings.LDKFutureCallback_new(arg));
+               this.ptrs_to.add(arg);
+               this.bindings_instance = arg;
+       }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.FutureCallback_free(ptr); } super.finalize();
+       }
+
+       public static interface FutureCallbackInterface {
+               /**
+                * The method which is called.
+                */
+               void call();
+       }
+       private static class LDKFutureCallbackHolder { FutureCallback held; }
+       public static FutureCallback new_impl(FutureCallbackInterface arg) {
+               final LDKFutureCallbackHolder impl_holder = new LDKFutureCallbackHolder();
+               impl_holder.held = new FutureCallback(new bindings.LDKFutureCallback() {
+                       @Override public void call() {
+                               arg.call();
+                               Reference.reachabilityFence(arg);
+                       }
+               });
+               return impl_holder.held;
+       }
+       /**
+        * The method which is called.
+        */
+       public void call() {
+               bindings.FutureCallback_call(this.ptr);
+               Reference.reachabilityFence(this);
+       }
+
+}
index 5125ab0c36b2ad693fc9ee41546fe783924c9179..4acc9c5d9538d2a9a60afcf5a60f389a920cfda7 100644 (file)
@@ -58,6 +58,32 @@ public class IgnoringMessageHandler extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Constructs a new OnionMessageProvider which calls the relevant methods on this_arg.
+        * This copies the `inner` pointer in this_arg and thus the returned OnionMessageProvider must be freed before this_arg is
+        */
+       public OnionMessageProvider as_OnionMessageProvider() {
+               long ret = bindings.IgnoringMessageHandler_as_OnionMessageProvider(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               OnionMessageProvider ret_hu_conv = new OnionMessageProvider(null, ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Constructs a new OnionMessageHandler which calls the relevant methods on this_arg.
+        * This copies the `inner` pointer in this_arg and thus the returned OnionMessageHandler must be freed before this_arg is
+        */
+       public OnionMessageHandler as_OnionMessageHandler() {
+               long ret = bindings.IgnoringMessageHandler_as_OnionMessageHandler(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               OnionMessageHandler ret_hu_conv = new OnionMessageHandler(null, ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
        /**
         * Constructs a new CustomMessageReader which calls the relevant methods on this_arg.
         * This copies the `inner` pointer in this_arg and thus the returned CustomMessageReader must be freed before this_arg is
diff --git a/src/main/java/org/ldk/structs/InFlightHtlcs.java b/src/main/java/org/ldk/structs/InFlightHtlcs.java
new file mode 100644 (file)
index 0000000..d19c712
--- /dev/null
@@ -0,0 +1,64 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * A map with liquidity value (in msat) keyed by a short channel id and the direction the HTLC
+ * is traveling in. The direction boolean is determined by checking if the HTLC source's public
+ * key is less than its destination. See [`InFlightHtlcs::used_liquidity_msat`] for more
+ * details.
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class InFlightHtlcs extends CommonBase {
+       InFlightHtlcs(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.InFlightHtlcs_free(ptr); }
+       }
+
+       /**
+        * Returns liquidity in msat given the public key of the HTLC source, target, and short channel
+        * id.
+        */
+       public Option_u64Z used_liquidity_msat(NodeId source, NodeId target, long channel_scid) {
+               long ret = bindings.InFlightHtlcs_used_liquidity_msat(this.ptr, source == null ? 0 : source.ptr, target == null ? 0 : target.ptr, channel_scid);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(source);
+               Reference.reachabilityFence(target);
+               Reference.reachabilityFence(channel_scid);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Option_u64Z ret_hu_conv = org.ldk.structs.Option_u64Z.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               if (this != null) { this.ptrs_to.add(source); };
+               if (this != null) { this.ptrs_to.add(target); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Serialize the InFlightHtlcs object into a byte array which can be read by InFlightHtlcs_read
+        */
+       public byte[] write() {
+               byte[] ret = bindings.InFlightHtlcs_write(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Read a InFlightHtlcs from a byte array, created by InFlightHtlcs_write
+        */
+       public static Result_InFlightHtlcsDecodeErrorZ read(byte[] ser) {
+               long ret = bindings.InFlightHtlcs_read(ser);
+               Reference.reachabilityFence(ser);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_InFlightHtlcsDecodeErrorZ ret_hu_conv = Result_InFlightHtlcsDecodeErrorZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+}
index 92a6256f47ebb24a5b754eecbde0d5ad5cbbd450..b6d59fdaaea27a7f1812dc562e78f464336765f3 100644 (file)
@@ -55,6 +55,18 @@ public class InitFeatures extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Returns the set of known init features that are related to channels. At least some of
+        * these features are likely required for peers to talk to us.
+        */
+       public static InitFeatures known_channel_features() {
+               long ret = bindings.InitFeatures_known_channel_features();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.InitFeatures ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.InitFeatures(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
        /**
         * Create a blank Features with no features set
         */
@@ -438,6 +450,40 @@ public class InitFeatures extends CommonBase {
                return ret;
        }
 
+       /**
+        * Set this feature as optional.
+        */
+       public void set_onion_messages_optional() {
+               bindings.InitFeatures_set_onion_messages_optional(this.ptr);
+               Reference.reachabilityFence(this);
+       }
+
+       /**
+        * Set this feature as required.
+        */
+       public void set_onion_messages_required() {
+               bindings.InitFeatures_set_onion_messages_required(this.ptr);
+               Reference.reachabilityFence(this);
+       }
+
+       /**
+        * Checks if this feature is supported.
+        */
+       public boolean supports_onion_messages() {
+               boolean ret = bindings.InitFeatures_supports_onion_messages(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Checks if this feature is required.
+        */
+       public boolean requires_onion_messages() {
+               boolean ret = bindings.InitFeatures_requires_onion_messages(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
        /**
         * Set this feature as optional.
         */
index 6faacbd0cc475cb4495ef2100744ecc41e71df2d..5bc61db4056b895b4fd35f03c5c2be39e9f545aa 100644 (file)
@@ -60,6 +60,18 @@ public class Invoice extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Checks if two Invoices contain equal inner contents.
+        */
+       public long hash() {
+               long ret = bindings.Invoice_hash(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       @Override public int hashCode() {
+               return (int)this.hash();
+       }
        /**
         * Transform the `Invoice` into it's unchecked version
         */
index 4a9c94ca7a546dae9386dadd5e6d0f8fe0c618c1..a7add5e8ec3e86d71c56d3d9bfbd72081f1a4819 100644 (file)
@@ -30,11 +30,10 @@ public class InvoicePayer extends CommonBase {
         * Will forward any [`Event::PaymentPathFailed`] events to the decorated `event_handler` once
         * `retry` has been exceeded for a given [`Invoice`].
         */
-       public static InvoicePayer of(Payer payer, Router router, MultiThreadedLockableScore scorer, Logger logger, EventHandler event_handler, Retry retry) {
-               long ret = bindings.InvoicePayer_new(payer == null ? 0 : payer.ptr, router == null ? 0 : router.ptr, scorer == null ? 0 : scorer.ptr, logger == null ? 0 : logger.ptr, event_handler == null ? 0 : event_handler.ptr, retry.ptr);
+       public static InvoicePayer of(Payer payer, Router router, Logger logger, EventHandler event_handler, Retry retry) {
+               long ret = bindings.InvoicePayer_new(payer == null ? 0 : payer.ptr, router == null ? 0 : router.ptr, logger == null ? 0 : logger.ptr, event_handler == null ? 0 : event_handler.ptr, retry.ptr);
                Reference.reachabilityFence(payer);
                Reference.reachabilityFence(router);
-               Reference.reachabilityFence(scorer);
                Reference.reachabilityFence(logger);
                Reference.reachabilityFence(event_handler);
                Reference.reachabilityFence(retry);
@@ -43,7 +42,6 @@ public class InvoicePayer extends CommonBase {
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(payer); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(router); };
-               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(scorer); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(logger); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(event_handler); };
                return ret_hu_conv;
index 63a4a581255e6818fc781ec64f62a29f0fe277f5..3f9c50ada6862099d1a511c0dba90f86198c7716 100644 (file)
@@ -38,6 +38,18 @@ public class InvoiceSignature extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Checks if two InvoiceSignatures contain equal inner contents.
+        */
+       public long hash() {
+               long ret = bindings.InvoiceSignature_hash(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       @Override public int hashCode() {
+               return (int)this.hash();
+       }
        /**
         * Checks if two InvoiceSignatures contain equal inner contents.
         * This ignores pointers and is_owned flags and looks at the values in fields.
index 5d30628b9f44701bcff59a99e650caa71c828135..bc3aaf5645d7f62d67a373c0e2ffbd8a33a22d2c 100644 (file)
@@ -34,6 +34,14 @@ public class KeysInterface extends CommonBase {
                 * parameter.
                 */
                Result_SecretKeyNoneZ get_node_secret(Recipient recipient);
+               /**
+                * Gets the ECDH shared secret of our [`node secret`] and `other_key`, multiplying by `tweak` if
+                * one is provided. Note that this tweak can be applied to `other_key` instead of our node
+                * secret, though this is less efficient.
+                * 
+                * [`node secret`]: Self::get_node_secret
+                */
+               Result_SharedSecretNoneZ ecdh(Recipient recipient, byte[] other_key, Option_ScalarZ tweak);
                /**
                 * Get a script pubkey which we send funds to when claiming on-chain contestable outputs.
                 * 
@@ -105,6 +113,14 @@ public class KeysInterface extends CommonBase {
                                long result = ret == null ? 0 : ret.clone_ptr();
                                return result;
                        }
+                       @Override public long ecdh(Recipient recipient, byte[] other_key, long tweak) {
+                               org.ldk.structs.Option_ScalarZ tweak_hu_conv = org.ldk.structs.Option_ScalarZ.constr_from_ptr(tweak);
+                               if (tweak_hu_conv != null) { tweak_hu_conv.ptrs_to.add(this); };
+                               Result_SharedSecretNoneZ ret = arg.ecdh(recipient, other_key, tweak_hu_conv);
+                               Reference.reachabilityFence(arg);
+                               long result = ret == null ? 0 : ret.clone_ptr();
+                               return result;
+                       }
                        @Override public byte[] get_destination_script() {
                                byte[] ret = arg.get_destination_script();
                                Reference.reachabilityFence(arg);
@@ -174,6 +190,24 @@ public class KeysInterface extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Gets the ECDH shared secret of our [`node secret`] and `other_key`, multiplying by `tweak` if
+        * one is provided. Note that this tweak can be applied to `other_key` instead of our node
+        * secret, though this is less efficient.
+        * 
+        * [`node secret`]: Self::get_node_secret
+        */
+       public Result_SharedSecretNoneZ ecdh(org.ldk.enums.Recipient recipient, byte[] other_key, Option_ScalarZ tweak) {
+               long ret = bindings.KeysInterface_ecdh(this.ptr, recipient, InternalUtils.check_arr_len(other_key, 33), tweak.ptr);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(recipient);
+               Reference.reachabilityFence(other_key);
+               Reference.reachabilityFence(tweak);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_SharedSecretNoneZ ret_hu_conv = Result_SharedSecretNoneZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
        /**
         * Get a script pubkey which we send funds to when claiming on-chain contestable outputs.
         * 
index 511b0b4017da9c5d38fdc12f9a78e386bf8206e3..aeb3d04fc517aceccdae0442d038239f31cb76b4 100644 (file)
@@ -76,18 +76,44 @@ public class MessageHandler extends CommonBase {
                if (this != null) { this.ptrs_to.add(val); };
        }
 
+       /**
+        * A message handler which handles onion messages. For now, this can only be an
+        * [`IgnoringMessageHandler`].
+        */
+       public OnionMessageHandler get_onion_message_handler() {
+               long ret = bindings.MessageHandler_get_onion_message_handler(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               OnionMessageHandler ret_hu_conv = new OnionMessageHandler(null, ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * A message handler which handles onion messages. For now, this can only be an
+        * [`IgnoringMessageHandler`].
+        */
+       public void set_onion_message_handler(OnionMessageHandler val) {
+               bindings.MessageHandler_set_onion_message_handler(this.ptr, val == null ? 0 : val.ptr);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(val);
+               if (this != null) { this.ptrs_to.add(val); };
+       }
+
        /**
         * Constructs a new MessageHandler given each field
         */
-       public static MessageHandler of(ChannelMessageHandler chan_handler_arg, RoutingMessageHandler route_handler_arg) {
-               long ret = bindings.MessageHandler_new(chan_handler_arg == null ? 0 : chan_handler_arg.ptr, route_handler_arg == null ? 0 : route_handler_arg.ptr);
+       public static MessageHandler of(ChannelMessageHandler chan_handler_arg, RoutingMessageHandler route_handler_arg, OnionMessageHandler onion_message_handler_arg) {
+               long ret = bindings.MessageHandler_new(chan_handler_arg == null ? 0 : chan_handler_arg.ptr, route_handler_arg == null ? 0 : route_handler_arg.ptr, onion_message_handler_arg == null ? 0 : onion_message_handler_arg.ptr);
                Reference.reachabilityFence(chan_handler_arg);
                Reference.reachabilityFence(route_handler_arg);
+               Reference.reachabilityFence(onion_message_handler_arg);
                if (ret >= 0 && ret <= 4096) { return null; }
                org.ldk.structs.MessageHandler ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.MessageHandler(null, ret); }
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(chan_handler_arg); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(route_handler_arg); };
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(onion_message_handler_arg); };
                return ret_hu_conv;
        }
 
index ff26147f36ff4920d3ae5e8c5569a452cbd23473..c7be3256c887fe7187d757252a496886ebf990b8 100644 (file)
@@ -56,12 +56,12 @@ public class MessageSendEvent extends CommonBase {
                if (raw_val.getClass() == bindings.LDKMessageSendEvent.SendChannelReestablish.class) {
                        return new SendChannelReestablish(ptr, (bindings.LDKMessageSendEvent.SendChannelReestablish)raw_val);
                }
+               if (raw_val.getClass() == bindings.LDKMessageSendEvent.SendChannelAnnouncement.class) {
+                       return new SendChannelAnnouncement(ptr, (bindings.LDKMessageSendEvent.SendChannelAnnouncement)raw_val);
+               }
                if (raw_val.getClass() == bindings.LDKMessageSendEvent.BroadcastChannelAnnouncement.class) {
                        return new BroadcastChannelAnnouncement(ptr, (bindings.LDKMessageSendEvent.BroadcastChannelAnnouncement)raw_val);
                }
-               if (raw_val.getClass() == bindings.LDKMessageSendEvent.BroadcastNodeAnnouncement.class) {
-                       return new BroadcastNodeAnnouncement(ptr, (bindings.LDKMessageSendEvent.BroadcastNodeAnnouncement)raw_val);
-               }
                if (raw_val.getClass() == bindings.LDKMessageSendEvent.BroadcastChannelUpdate.class) {
                        return new BroadcastChannelUpdate(ptr, (bindings.LDKMessageSendEvent.BroadcastChannelUpdate)raw_val);
                }
@@ -321,16 +321,14 @@ public class MessageSendEvent extends CommonBase {
                }
        }
        /**
-        * Used to indicate that a channel_announcement and channel_update should be broadcast to all
-        * peers (except the peer with node_id either msg.contents.node_id_1 or msg.contents.node_id_2).
-        * 
-        * Note that after doing so, you very likely (unless you did so very recently) want to call
-        * ChannelManager::broadcast_node_announcement to trigger a BroadcastNodeAnnouncement event.
-        * This ensures that any nodes which see our channel_announcement also have a relevant
-        * node_announcement, including relevant feature flags which may be important for routing
-        * through or to us.
+        * Used to send a channel_announcement and channel_update to a specific peer, likely on
+        * initial connection to ensure our peers know about our channels.
         */
-       public final static class BroadcastChannelAnnouncement extends MessageSendEvent {
+       public final static class SendChannelAnnouncement extends MessageSendEvent {
+               /**
+                * The node_id of the node which should receive this message
+               */
+               public final byte[] node_id;
                /**
                 * The channel_announcement which should be sent.
                */
@@ -339,8 +337,9 @@ public class MessageSendEvent extends CommonBase {
                 * The followup channel_update which should be sent.
                */
                public final org.ldk.structs.ChannelUpdate update_msg;
-               private BroadcastChannelAnnouncement(long ptr, bindings.LDKMessageSendEvent.BroadcastChannelAnnouncement obj) {
+               private SendChannelAnnouncement(long ptr, bindings.LDKMessageSendEvent.SendChannelAnnouncement obj) {
                        super(null, ptr);
+                       this.node_id = obj.node_id;
                        long msg = obj.msg;
                        org.ldk.structs.ChannelAnnouncement msg_hu_conv = null; if (msg < 0 || msg > 4096) { msg_hu_conv = new org.ldk.structs.ChannelAnnouncement(null, msg); }
                        if (msg_hu_conv != null) { msg_hu_conv.ptrs_to.add(this); };
@@ -352,19 +351,36 @@ public class MessageSendEvent extends CommonBase {
                }
        }
        /**
-        * Used to indicate that a node_announcement should be broadcast to all peers.
+        * Used to indicate that a channel_announcement and channel_update should be broadcast to all
+        * peers (except the peer with node_id either msg.contents.node_id_1 or msg.contents.node_id_2).
+        * 
+        * Note that after doing so, you very likely (unless you did so very recently) want to
+        * broadcast a node_announcement (e.g. via [`PeerManager::broadcast_node_announcement`]). This
+        * ensures that any nodes which see our channel_announcement also have a relevant
+        * node_announcement, including relevant feature flags which may be important for routing
+        * through or to us.
+        * 
+        * [`PeerManager::broadcast_node_announcement`]: crate::ln::peer_handler::PeerManager::broadcast_node_announcement
         */
-       public final static class BroadcastNodeAnnouncement extends MessageSendEvent {
+       public final static class BroadcastChannelAnnouncement extends MessageSendEvent {
                /**
-                * The node_announcement which should be sent.
+                * The channel_announcement which should be sent.
+               */
+               public final org.ldk.structs.ChannelAnnouncement msg;
+               /**
+                * The followup channel_update which should be sent.
                */
-               public final org.ldk.structs.NodeAnnouncement msg;
-               private BroadcastNodeAnnouncement(long ptr, bindings.LDKMessageSendEvent.BroadcastNodeAnnouncement obj) {
+               public final org.ldk.structs.ChannelUpdate update_msg;
+               private BroadcastChannelAnnouncement(long ptr, bindings.LDKMessageSendEvent.BroadcastChannelAnnouncement obj) {
                        super(null, ptr);
                        long msg = obj.msg;
-                       org.ldk.structs.NodeAnnouncement msg_hu_conv = null; if (msg < 0 || msg > 4096) { msg_hu_conv = new org.ldk.structs.NodeAnnouncement(null, msg); }
+                       org.ldk.structs.ChannelAnnouncement msg_hu_conv = null; if (msg < 0 || msg > 4096) { msg_hu_conv = new org.ldk.structs.ChannelAnnouncement(null, msg); }
                        if (msg_hu_conv != null) { msg_hu_conv.ptrs_to.add(this); };
                        this.msg = msg_hu_conv;
+                       long update_msg = obj.update_msg;
+                       org.ldk.structs.ChannelUpdate update_msg_hu_conv = null; if (update_msg < 0 || update_msg > 4096) { update_msg_hu_conv = new org.ldk.structs.ChannelUpdate(null, update_msg); }
+                       if (update_msg_hu_conv != null) { update_msg_hu_conv.ptrs_to.add(this); };
+                       this.update_msg = update_msg_hu_conv;
                }
        }
        /**
@@ -687,10 +703,11 @@ public class MessageSendEvent extends CommonBase {
        }
 
        /**
-        * Utility method to constructs a new BroadcastChannelAnnouncement-variant MessageSendEvent
+        * Utility method to constructs a new SendChannelAnnouncement-variant MessageSendEvent
         */
-       public static MessageSendEvent broadcast_channel_announcement(ChannelAnnouncement msg, ChannelUpdate update_msg) {
-               long ret = bindings.MessageSendEvent_broadcast_channel_announcement(msg == null ? 0 : msg.ptr, update_msg == null ? 0 : update_msg.ptr);
+       public static MessageSendEvent send_channel_announcement(byte[] node_id, ChannelAnnouncement msg, ChannelUpdate update_msg) {
+               long ret = bindings.MessageSendEvent_send_channel_announcement(InternalUtils.check_arr_len(node_id, 33), msg == null ? 0 : msg.ptr, update_msg == null ? 0 : update_msg.ptr);
+               Reference.reachabilityFence(node_id);
                Reference.reachabilityFence(msg);
                Reference.reachabilityFence(update_msg);
                if (ret >= 0 && ret <= 4096) { return null; }
@@ -702,15 +719,17 @@ public class MessageSendEvent extends CommonBase {
        }
 
        /**
-        * Utility method to constructs a new BroadcastNodeAnnouncement-variant MessageSendEvent
+        * Utility method to constructs a new BroadcastChannelAnnouncement-variant MessageSendEvent
         */
-       public static MessageSendEvent broadcast_node_announcement(NodeAnnouncement msg) {
-               long ret = bindings.MessageSendEvent_broadcast_node_announcement(msg == null ? 0 : msg.ptr);
+       public static MessageSendEvent broadcast_channel_announcement(ChannelAnnouncement msg, ChannelUpdate update_msg) {
+               long ret = bindings.MessageSendEvent_broadcast_channel_announcement(msg == null ? 0 : msg.ptr, update_msg == null ? 0 : update_msg.ptr);
                Reference.reachabilityFence(msg);
+               Reference.reachabilityFence(update_msg);
                if (ret >= 0 && ret <= 4096) { return null; }
                org.ldk.structs.MessageSendEvent ret_hu_conv = org.ldk.structs.MessageSendEvent.constr_from_ptr(ret);
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(msg); };
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(update_msg); };
                return ret_hu_conv;
        }
 
index cc4666eb9e96808b51794de1d6312a4832d52d2f..b23d1b40aca80ead9a810ee4184656c1827d5a0d 100644 (file)
@@ -20,6 +20,19 @@ public class MultiThreadedLockableScore extends CommonBase {
                if (ptr != 0) { bindings.MultiThreadedLockableScore_free(ptr); }
        }
 
+       /**
+        * Constructs a new LockableScore which calls the relevant methods on this_arg.
+        * This copies the `inner` pointer in this_arg and thus the returned LockableScore must be freed before this_arg is
+        */
+       public LockableScore as_LockableScore() {
+               long ret = bindings.MultiThreadedLockableScore_as_LockableScore(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               LockableScore ret_hu_conv = new LockableScore(null, ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
        /**
         * Serialize the MultiThreadedLockableScore object into a byte array which can be read by MultiThreadedLockableScore_read
         */
@@ -29,6 +42,19 @@ public class MultiThreadedLockableScore extends CommonBase {
                return ret;
        }
 
+       /**
+        * Constructs a new WriteableScore which calls the relevant methods on this_arg.
+        * This copies the `inner` pointer in this_arg and thus the returned WriteableScore must be freed before this_arg is
+        */
+       public WriteableScore as_WriteableScore() {
+               long ret = bindings.MultiThreadedLockableScore_as_WriteableScore(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               WriteableScore ret_hu_conv = new WriteableScore(null, ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
        /**
         * Creates a new [`MultiThreadedLockableScore`] given an underlying [`Score`].
         */
diff --git a/src/main/java/org/ldk/structs/MultiThreadedScoreLock.java b/src/main/java/org/ldk/structs/MultiThreadedScoreLock.java
new file mode 100644 (file)
index 0000000..3927177
--- /dev/null
@@ -0,0 +1,45 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * A locked `MultiThreadedLockableScore`.
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class MultiThreadedScoreLock extends CommonBase {
+       MultiThreadedScoreLock(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.MultiThreadedScoreLock_free(ptr); }
+       }
+
+       /**
+        * Constructs a new Score which calls the relevant methods on this_arg.
+        * This copies the `inner` pointer in this_arg and thus the returned Score must be freed before this_arg is
+        */
+       public Score as_Score() {
+               long ret = bindings.MultiThreadedScoreLock_as_Score(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Score ret_hu_conv = new Score(null, ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Serialize the MultiThreadedScoreLock object into a byte array which can be read by MultiThreadedScoreLock_read
+        */
+       public byte[] write() {
+               byte[] ret = bindings.MultiThreadedScoreLock_write(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+}
index 7f6c696022562c2b65ad3dc80f8f5b657e9550ba..e79460ab63eb0137d5284120bd00ef25663d67bb 100644 (file)
@@ -55,6 +55,17 @@ public class NodeFeatures extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Returns the set of known node features that are related to channels.
+        */
+       public static NodeFeatures known_channel_features() {
+               long ret = bindings.NodeFeatures_known_channel_features();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.NodeFeatures ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.NodeFeatures(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
        /**
         * Create a blank Features with no features set
         */
@@ -413,6 +424,40 @@ public class NodeFeatures extends CommonBase {
                return ret;
        }
 
+       /**
+        * Set this feature as optional.
+        */
+       public void set_onion_messages_optional() {
+               bindings.NodeFeatures_set_onion_messages_optional(this.ptr);
+               Reference.reachabilityFence(this);
+       }
+
+       /**
+        * Set this feature as required.
+        */
+       public void set_onion_messages_required() {
+               bindings.NodeFeatures_set_onion_messages_required(this.ptr);
+               Reference.reachabilityFence(this);
+       }
+
+       /**
+        * Checks if this feature is supported.
+        */
+       public boolean supports_onion_messages() {
+               boolean ret = bindings.NodeFeatures_supports_onion_messages(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Checks if this feature is required.
+        */
+       public boolean requires_onion_messages() {
+               boolean ret = bindings.NodeFeatures_requires_onion_messages(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
        /**
         * Set this feature as optional.
         */
diff --git a/src/main/java/org/ldk/structs/OnionMessage.java b/src/main/java/org/ldk/structs/OnionMessage.java
new file mode 100644 (file)
index 0000000..c091a26
--- /dev/null
@@ -0,0 +1,79 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * An onion message to be sent or received from a peer
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class OnionMessage extends CommonBase {
+       OnionMessage(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.OnionMessage_free(ptr); }
+       }
+
+       /**
+        * Used in decrypting the onion packet's payload.
+        */
+       public byte[] get_blinding_point() {
+               byte[] ret = bindings.OnionMessage_get_blinding_point(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Used in decrypting the onion packet's payload.
+        */
+       public void set_blinding_point(byte[] val) {
+               bindings.OnionMessage_set_blinding_point(this.ptr, InternalUtils.check_arr_len(val, 33));
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(val);
+       }
+
+       long clone_ptr() {
+               long ret = bindings.OnionMessage_clone_ptr(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Creates a copy of the OnionMessage
+        */
+       public OnionMessage clone() {
+               long ret = bindings.OnionMessage_clone(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.OnionMessage ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.OnionMessage(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Read a OnionMessage from a byte array, created by OnionMessage_write
+        */
+       public static Result_OnionMessageDecodeErrorZ read(byte[] ser) {
+               long ret = bindings.OnionMessage_read(ser);
+               Reference.reachabilityFence(ser);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_OnionMessageDecodeErrorZ ret_hu_conv = Result_OnionMessageDecodeErrorZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+       /**
+        * Serialize the OnionMessage object into a byte array which can be read by OnionMessage_read
+        */
+       public byte[] write() {
+               byte[] ret = bindings.OnionMessage_write(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/OnionMessageHandler.java b/src/main/java/org/ldk/structs/OnionMessageHandler.java
new file mode 100644 (file)
index 0000000..418f2a6
--- /dev/null
@@ -0,0 +1,166 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+/**
+ * A trait to describe an object that can receive onion messages.
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class OnionMessageHandler extends CommonBase {
+       final bindings.LDKOnionMessageHandler bindings_instance;
+       OnionMessageHandler(Object _dummy, long ptr) { super(ptr); bindings_instance = null; }
+       private OnionMessageHandler(bindings.LDKOnionMessageHandler arg, bindings.LDKOnionMessageProvider OnionMessageProvider) {
+               super(bindings.LDKOnionMessageHandler_new(arg, OnionMessageProvider));
+               this.ptrs_to.add(arg);
+               this.ptrs_to.add(OnionMessageProvider);
+               this.bindings_instance = arg;
+       }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.OnionMessageHandler_free(ptr); } super.finalize();
+       }
+
+       public static interface OnionMessageHandlerInterface {
+               /**
+                * Handle an incoming onion_message message from the given peer.
+                */
+               void handle_onion_message(byte[] peer_node_id, OnionMessage msg);
+               /**
+                * Called when a connection is established with a peer. Can be used to track which peers
+                * advertise onion message support and are online.
+                */
+               void peer_connected(byte[] their_node_id, Init init);
+               /**
+                * Indicates a connection to the peer failed/an existing connection was lost. Allows handlers to
+                * drop and refuse to forward onion messages to this peer.
+                */
+               void peer_disconnected(byte[] their_node_id, boolean no_connection_possible);
+               /**
+                * Gets the node feature flags which this handler itself supports. All available handlers are
+                * queried similarly and their feature flags are OR'd together to form the [`NodeFeatures`]
+                * which are broadcasted in our [`NodeAnnouncement`] message.
+                */
+               NodeFeatures provided_node_features();
+               /**
+                * Gets the init feature flags which should be sent to the given peer. All available handlers
+                * are queried similarly and their feature flags are OR'd together to form the [`InitFeatures`]
+                * which are sent in our [`Init`] message.
+                * 
+                * Note that this method is called before [`Self::peer_connected`].
+                */
+               InitFeatures provided_init_features(byte[] their_node_id);
+       }
+       private static class LDKOnionMessageHandlerHolder { OnionMessageHandler held; }
+       public static OnionMessageHandler new_impl(OnionMessageHandlerInterface arg, OnionMessageProvider.OnionMessageProviderInterface OnionMessageProvider_impl) {
+               final LDKOnionMessageHandlerHolder impl_holder = new LDKOnionMessageHandlerHolder();
+               impl_holder.held = new OnionMessageHandler(new bindings.LDKOnionMessageHandler() {
+                       @Override public void handle_onion_message(byte[] peer_node_id, long msg) {
+                               org.ldk.structs.OnionMessage msg_hu_conv = null; if (msg < 0 || msg > 4096) { msg_hu_conv = new org.ldk.structs.OnionMessage(null, msg); }
+                               arg.handle_onion_message(peer_node_id, msg_hu_conv);
+                               Reference.reachabilityFence(arg);
+                       }
+                       @Override public void peer_connected(byte[] their_node_id, long init) {
+                               org.ldk.structs.Init init_hu_conv = null; if (init < 0 || init > 4096) { init_hu_conv = new org.ldk.structs.Init(null, init); }
+                               arg.peer_connected(their_node_id, init_hu_conv);
+                               Reference.reachabilityFence(arg);
+                       }
+                       @Override public void peer_disconnected(byte[] their_node_id, boolean no_connection_possible) {
+                               arg.peer_disconnected(their_node_id, no_connection_possible);
+                               Reference.reachabilityFence(arg);
+                       }
+                       @Override public long provided_node_features() {
+                               NodeFeatures ret = arg.provided_node_features();
+                               Reference.reachabilityFence(arg);
+                               long result = ret == null ? 0 : ret.clone_ptr();
+                               return result;
+                       }
+                       @Override public long provided_init_features(byte[] their_node_id) {
+                               InitFeatures ret = arg.provided_init_features(their_node_id);
+                               Reference.reachabilityFence(arg);
+                               long result = ret == null ? 0 : ret.clone_ptr();
+                               return result;
+                       }
+               }, OnionMessageProvider.new_impl(OnionMessageProvider_impl).bindings_instance);
+               return impl_holder.held;
+       }
+
+       /**
+        * Gets the underlying OnionMessageProvider.
+        */
+       public OnionMessageProvider get_onion_message_provider() {
+               OnionMessageProvider res = new OnionMessageProvider(null, bindings.LDKOnionMessageHandler_get_OnionMessageProvider(this.ptr));
+               this.ptrs_to.add(res);
+               return res;
+       }
+
+       /**
+        * Handle an incoming onion_message message from the given peer.
+        */
+       public void handle_onion_message(byte[] peer_node_id, OnionMessage msg) {
+               bindings.OnionMessageHandler_handle_onion_message(this.ptr, InternalUtils.check_arr_len(peer_node_id, 33), msg == null ? 0 : msg.ptr);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(peer_node_id);
+               Reference.reachabilityFence(msg);
+               if (this != null) { this.ptrs_to.add(msg); };
+       }
+
+       /**
+        * Called when a connection is established with a peer. Can be used to track which peers
+        * advertise onion message support and are online.
+        */
+       public void peer_connected(byte[] their_node_id, Init init) {
+               bindings.OnionMessageHandler_peer_connected(this.ptr, InternalUtils.check_arr_len(their_node_id, 33), init == null ? 0 : init.ptr);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(their_node_id);
+               Reference.reachabilityFence(init);
+               if (this != null) { this.ptrs_to.add(init); };
+       }
+
+       /**
+        * Indicates a connection to the peer failed/an existing connection was lost. Allows handlers to
+        * drop and refuse to forward onion messages to this peer.
+        */
+       public void peer_disconnected(byte[] their_node_id, boolean no_connection_possible) {
+               bindings.OnionMessageHandler_peer_disconnected(this.ptr, InternalUtils.check_arr_len(their_node_id, 33), no_connection_possible);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(their_node_id);
+               Reference.reachabilityFence(no_connection_possible);
+       }
+
+       /**
+        * Gets the node feature flags which this handler itself supports. All available handlers are
+        * queried similarly and their feature flags are OR'd together to form the [`NodeFeatures`]
+        * which are broadcasted in our [`NodeAnnouncement`] message.
+        */
+       public NodeFeatures provided_node_features() {
+               long ret = bindings.OnionMessageHandler_provided_node_features(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.NodeFeatures ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.NodeFeatures(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Gets the init feature flags which should be sent to the given peer. All available handlers
+        * are queried similarly and their feature flags are OR'd together to form the [`InitFeatures`]
+        * which are sent in our [`Init`] message.
+        * 
+        * Note that this method is called before [`Self::peer_connected`].
+        */
+       public InitFeatures provided_init_features(byte[] their_node_id) {
+               long ret = bindings.OnionMessageHandler_provided_init_features(this.ptr, InternalUtils.check_arr_len(their_node_id, 33));
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(their_node_id);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.InitFeatures ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.InitFeatures(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/OnionMessageProvider.java b/src/main/java/org/ldk/structs/OnionMessageProvider.java
new file mode 100644 (file)
index 0000000..b04e64d
--- /dev/null
@@ -0,0 +1,64 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+/**
+ * A trait indicating an object may generate onion messages to send
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class OnionMessageProvider extends CommonBase {
+       final bindings.LDKOnionMessageProvider bindings_instance;
+       OnionMessageProvider(Object _dummy, long ptr) { super(ptr); bindings_instance = null; }
+       private OnionMessageProvider(bindings.LDKOnionMessageProvider arg) {
+               super(bindings.LDKOnionMessageProvider_new(arg));
+               this.ptrs_to.add(arg);
+               this.bindings_instance = arg;
+       }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.OnionMessageProvider_free(ptr); } super.finalize();
+       }
+
+       public static interface OnionMessageProviderInterface {
+               /**
+                * Gets the next pending onion message for the peer with the given node id.
+                * 
+                * Note that the return value (or a relevant inner pointer) may be NULL or all-0s to represent None
+                */
+               OnionMessage next_onion_message_for_peer(byte[] peer_node_id);
+       }
+       private static class LDKOnionMessageProviderHolder { OnionMessageProvider held; }
+       public static OnionMessageProvider new_impl(OnionMessageProviderInterface arg) {
+               final LDKOnionMessageProviderHolder impl_holder = new LDKOnionMessageProviderHolder();
+               impl_holder.held = new OnionMessageProvider(new bindings.LDKOnionMessageProvider() {
+                       @Override public long next_onion_message_for_peer(byte[] peer_node_id) {
+                               OnionMessage ret = arg.next_onion_message_for_peer(peer_node_id);
+                               Reference.reachabilityFence(arg);
+                               long result = ret == null ? 0 : ret.clone_ptr();
+                               return result;
+                       }
+               });
+               return impl_holder.held;
+       }
+       /**
+        * Gets the next pending onion message for the peer with the given node id.
+        * 
+        * Note that the return value (or a relevant inner pointer) may be NULL or all-0s to represent None
+        */
+       @Nullable
+       public OnionMessage next_onion_message_for_peer(byte[] peer_node_id) {
+               long ret = bindings.OnionMessageProvider_next_onion_message_for_peer(this.ptr, InternalUtils.check_arr_len(peer_node_id, 33));
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(peer_node_id);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.OnionMessage ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.OnionMessage(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/OnionMessenger.java b/src/main/java/org/ldk/structs/OnionMessenger.java
new file mode 100644 (file)
index 0000000..1c2f889
--- /dev/null
@@ -0,0 +1,134 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * A sender, receiver and forwarder of onion messages. In upcoming releases, this object will be
+ * used to retrieve invoices and fulfill invoice requests from [offers]. Currently, only sending
+ * and receiving empty onion messages is supported.
+ * 
+ * # Example
+ * 
+ * ```
+ * # extern crate bitcoin;
+ * # use bitcoin::hashes::_export::_core::time::Duration;
+ * # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
+ * # use lightning::chain::keysinterface::{InMemorySigner, KeysManager, KeysInterface};
+ * # use lightning::onion_message::messenger::{Destination, OnionMessenger};
+ * # use lightning::onion_message::blinded_route::BlindedRoute;
+ * # use lightning::util::logger::{Logger, Record};
+ * # use std::sync::Arc;
+ * # struct FakeLogger {};
+ * # impl Logger for FakeLogger {
+ * #     fn log(&self, record: &Record) { unimplemented!() }
+ * # }
+ * # let seed = [42u8; 32];
+ * # let time = Duration::from_secs(123456);
+ * # let keys_manager = KeysManager::new(&seed, time.as_secs(), time.subsec_nanos());
+ * # let logger = Arc::new(FakeLogger {});
+ * # let node_secret = SecretKey::from_slice(&hex::decode(\"0101010101010101010101010101010101010101010101010101010101010101\").unwrap()[..]).unwrap();
+ * # let secp_ctx = Secp256k1::new();
+ * # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
+ * # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1,
+ * hop_node_id1);
+ * # let destination_node_id = hop_node_id1;
+ * #
+ * Create the onion messenger. This must use the same `keys_manager` as is passed to your
+ * ChannelManager.
+ * let onion_messenger = OnionMessenger::new(&keys_manager, logger);
+ * 
+ * Send an empty onion message to a node id.
+ * let intermediate_hops = [hop_node_id1, hop_node_id2];
+ * let reply_path = None;
+ * onion_messenger.send_onion_message(&intermediate_hops, Destination::Node(destination_node_id), reply_path);
+ * 
+ * Create a blinded route to yourself, for someone to send an onion message to.
+ * # let your_node_id = hop_node_id1;
+ * let hops = [hop_node_id3, hop_node_id4, your_node_id];
+ * let blinded_route = BlindedRoute::new(&hops, &keys_manager, &secp_ctx).unwrap();
+ * 
+ * Send an empty onion message to a blinded route.
+ * # let intermediate_hops = [hop_node_id1, hop_node_id2];
+ * let reply_path = None;
+ * onion_messenger.send_onion_message(&intermediate_hops, Destination::BlindedRoute(blinded_route), reply_path);
+ * ```
+ * 
+ * [offers]: <https://github.com/lightning/bolts/pull/798>
+ * [`OnionMessenger`]: crate::onion_message::OnionMessenger
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class OnionMessenger extends CommonBase {
+       OnionMessenger(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.OnionMessenger_free(ptr); }
+       }
+
+       /**
+        * Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
+        * their respective handlers.
+        */
+       public static OnionMessenger of(KeysInterface keys_manager, Logger logger) {
+               long ret = bindings.OnionMessenger_new(keys_manager == null ? 0 : keys_manager.ptr, logger == null ? 0 : logger.ptr);
+               Reference.reachabilityFence(keys_manager);
+               Reference.reachabilityFence(logger);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.OnionMessenger ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.OnionMessenger(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(keys_manager); };
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(logger); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Send an empty onion message to `destination`, routing it through `intermediate_nodes`.
+        * See [`OnionMessenger`] for example usage.
+        * 
+        * Note that reply_path (or a relevant inner pointer) may be NULL or all-0s to represent None
+        */
+       public Result_NoneSendErrorZ send_onion_message(byte[][] intermediate_nodes, Destination destination, @Nullable BlindedRoute reply_path) {
+               long ret = bindings.OnionMessenger_send_onion_message(this.ptr, intermediate_nodes != null ? Arrays.stream(intermediate_nodes).map(intermediate_nodes_conv_8 -> InternalUtils.check_arr_len(intermediate_nodes_conv_8, 33)).toArray(byte[][]::new) : null, destination.ptr, reply_path == null ? 0 : reply_path.ptr);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(intermediate_nodes);
+               Reference.reachabilityFence(destination);
+               Reference.reachabilityFence(reply_path);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_NoneSendErrorZ ret_hu_conv = Result_NoneSendErrorZ.constr_from_ptr(ret);
+               if (this != null) { this.ptrs_to.add(reply_path); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Constructs a new OnionMessageHandler which calls the relevant methods on this_arg.
+        * This copies the `inner` pointer in this_arg and thus the returned OnionMessageHandler must be freed before this_arg is
+        */
+       public OnionMessageHandler as_OnionMessageHandler() {
+               long ret = bindings.OnionMessenger_as_OnionMessageHandler(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               OnionMessageHandler ret_hu_conv = new OnionMessageHandler(null, ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Constructs a new OnionMessageProvider which calls the relevant methods on this_arg.
+        * This copies the `inner` pointer in this_arg and thus the returned OnionMessageProvider must be freed before this_arg is
+        */
+       public OnionMessageProvider as_OnionMessageProvider() {
+               long ret = bindings.OnionMessenger_as_OnionMessageProvider(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               OnionMessageProvider ret_hu_conv = new OnionMessageProvider(null, ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/Option_C2Tuple_usizeTransactionZZ.java b/src/main/java/org/ldk/structs/Option_C2Tuple_usizeTransactionZZ.java
deleted file mode 100644 (file)
index b57b1ab..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-package org.ldk.structs;
-
-import org.ldk.impl.bindings;
-import org.ldk.enums.*;
-import org.ldk.util.*;
-import java.util.Arrays;
-import java.lang.ref.Reference;
-import javax.annotation.Nullable;
-
-
-/**
- * An enum which can either contain a crate::c_types::derived::C2Tuple_usizeTransactionZ or not
- */
-@SuppressWarnings("unchecked") // We correctly assign various generic arrays
-public class Option_C2Tuple_usizeTransactionZZ extends CommonBase {
-       private Option_C2Tuple_usizeTransactionZZ(Object _dummy, long ptr) { super(ptr); }
-       @Override @SuppressWarnings("deprecation")
-       protected void finalize() throws Throwable {
-               super.finalize();
-               if (ptr != 0) { bindings.COption_C2Tuple_usizeTransactionZZ_free(ptr); }
-       }
-       static Option_C2Tuple_usizeTransactionZZ constr_from_ptr(long ptr) {
-               bindings.LDKCOption_C2Tuple_usizeTransactionZZ raw_val = bindings.LDKCOption_C2Tuple_usizeTransactionZZ_ref_from_ptr(ptr);
-               if (raw_val.getClass() == bindings.LDKCOption_C2Tuple_usizeTransactionZZ.Some.class) {
-                       return new Some(ptr, (bindings.LDKCOption_C2Tuple_usizeTransactionZZ.Some)raw_val);
-               }
-               if (raw_val.getClass() == bindings.LDKCOption_C2Tuple_usizeTransactionZZ.None.class) {
-                       return new None(ptr, (bindings.LDKCOption_C2Tuple_usizeTransactionZZ.None)raw_val);
-               }
-               assert false; return null; // Unreachable without extending the (internal) bindings interface
-       }
-
-       /**
-        * When we're in this state, this COption_C2Tuple_usizeTransactionZZ contains a crate::c_types::derived::C2Tuple_usizeTransactionZ
-        */
-       public final static class Some extends Option_C2Tuple_usizeTransactionZZ {
-               public final org.ldk.structs.TwoTuple_usizeTransactionZ some;
-               private Some(long ptr, bindings.LDKCOption_C2Tuple_usizeTransactionZZ.Some obj) {
-                       super(null, ptr);
-                       long some = obj.some;
-                       TwoTuple_usizeTransactionZ some_hu_conv = new TwoTuple_usizeTransactionZ(null, some);
-                       if (some_hu_conv != null) { some_hu_conv.ptrs_to.add(this); };
-                       this.some = some_hu_conv;
-               }
-       }
-       /**
-        * When we're in this state, this COption_C2Tuple_usizeTransactionZZ contains nothing
-        */
-       public final static class None extends Option_C2Tuple_usizeTransactionZZ {
-               private None(long ptr, bindings.LDKCOption_C2Tuple_usizeTransactionZZ.None obj) {
-                       super(null, ptr);
-               }
-       }
-       /**
-        * Constructs a new COption_C2Tuple_usizeTransactionZZ containing a crate::c_types::derived::C2Tuple_usizeTransactionZ
-        */
-       public static Option_C2Tuple_usizeTransactionZZ some(TwoTuple_usizeTransactionZ o) {
-               long ret = bindings.COption_C2Tuple_usizeTransactionZZ_some(o != null ? o.ptr : 0);
-               Reference.reachabilityFence(o);
-               if (ret >= 0 && ret <= 4096) { return null; }
-               org.ldk.structs.Option_C2Tuple_usizeTransactionZZ ret_hu_conv = org.ldk.structs.Option_C2Tuple_usizeTransactionZZ.constr_from_ptr(ret);
-               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
-               return ret_hu_conv;
-       }
-
-       /**
-        * Constructs a new COption_C2Tuple_usizeTransactionZZ containing nothing
-        */
-       public static Option_C2Tuple_usizeTransactionZZ none() {
-               long ret = bindings.COption_C2Tuple_usizeTransactionZZ_none();
-               if (ret >= 0 && ret <= 4096) { return null; }
-               org.ldk.structs.Option_C2Tuple_usizeTransactionZZ ret_hu_conv = org.ldk.structs.Option_C2Tuple_usizeTransactionZZ.constr_from_ptr(ret);
-               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
-               return ret_hu_conv;
-       }
-
-       long clone_ptr() {
-               long ret = bindings.COption_C2Tuple_usizeTransactionZZ_clone_ptr(this.ptr);
-               Reference.reachabilityFence(this);
-               return ret;
-       }
-
-       /**
-        * Creates a new COption_C2Tuple_usizeTransactionZZ which has the same data as `orig`
-        * but with all dynamically-allocated buffers duplicated in new buffers.
-        */
-       public Option_C2Tuple_usizeTransactionZZ clone() {
-               long ret = bindings.COption_C2Tuple_usizeTransactionZZ_clone(this.ptr);
-               Reference.reachabilityFence(this);
-               if (ret >= 0 && ret <= 4096) { return null; }
-               org.ldk.structs.Option_C2Tuple_usizeTransactionZZ ret_hu_conv = org.ldk.structs.Option_C2Tuple_usizeTransactionZZ.constr_from_ptr(ret);
-               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
-               return ret_hu_conv;
-       }
-
-}
diff --git a/src/main/java/org/ldk/structs/Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.java b/src/main/java/org/ldk/structs/Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.java
new file mode 100644 (file)
index 0000000..6b3443e
--- /dev/null
@@ -0,0 +1,96 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * An enum which can either contain a crate::c_types::derived::C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ or not
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ extends CommonBase {
+       private Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free(ptr); }
+       }
+       static Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ constr_from_ptr(long ptr) {
+               bindings.LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ raw_val = bindings.LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_ref_from_ptr(ptr);
+               if (raw_val.getClass() == bindings.LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.Some.class) {
+                       return new Some(ptr, (bindings.LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.Some)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.None.class) {
+                       return new None(ptr, (bindings.LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.None)raw_val);
+               }
+               assert false; return null; // Unreachable without extending the (internal) bindings interface
+       }
+
+       /**
+        * When we're in this state, this COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ contains a crate::c_types::derived::C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ
+        */
+       public final static class Some extends Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ {
+               public final org.ldk.structs.ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ some;
+               private Some(long ptr, bindings.LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.Some obj) {
+                       super(null, ptr);
+                       long some = obj.some;
+                       ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ some_hu_conv = new ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ(null, some);
+                       if (some_hu_conv != null) { some_hu_conv.ptrs_to.add(this); };
+                       this.some = some_hu_conv;
+               }
+       }
+       /**
+        * When we're in this state, this COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ contains nothing
+        */
+       public final static class None extends Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ {
+               private None(long ptr, bindings.LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.None obj) {
+                       super(null, ptr);
+               }
+       }
+       /**
+        * Constructs a new COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ containing a crate::c_types::derived::C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ
+        */
+       public static Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ some(ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ o) {
+               long ret = bindings.COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_some(o != null ? o.ptr : 0);
+               Reference.reachabilityFence(o);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_hu_conv = org.ldk.structs.Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Constructs a new COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ containing nothing
+        */
+       public static Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ none() {
+               long ret = bindings.COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_none();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_hu_conv = org.ldk.structs.Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+       long clone_ptr() {
+               long ret = bindings.COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone_ptr(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Creates a new COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ which has the same data as `orig`
+        * but with all dynamically-allocated buffers duplicated in new buffers.
+        */
+       public Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ clone() {
+               long ret = bindings.COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_hu_conv = org.ldk.structs.Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/Option_ScalarZ.java b/src/main/java/org/ldk/structs/Option_ScalarZ.java
new file mode 100644 (file)
index 0000000..eb553b9
--- /dev/null
@@ -0,0 +1,77 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * An enum which can either contain a crate::c_types::BigEndianScalar or not
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class Option_ScalarZ extends CommonBase {
+       private Option_ScalarZ(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.COption_ScalarZ_free(ptr); }
+       }
+       static Option_ScalarZ constr_from_ptr(long ptr) {
+               bindings.LDKCOption_ScalarZ raw_val = bindings.LDKCOption_ScalarZ_ref_from_ptr(ptr);
+               if (raw_val.getClass() == bindings.LDKCOption_ScalarZ.Some.class) {
+                       return new Some(ptr, (bindings.LDKCOption_ScalarZ.Some)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKCOption_ScalarZ.None.class) {
+                       return new None(ptr, (bindings.LDKCOption_ScalarZ.None)raw_val);
+               }
+               assert false; return null; // Unreachable without extending the (internal) bindings interface
+       }
+
+       /**
+        * When we're in this state, this COption_ScalarZ contains a crate::c_types::BigEndianScalar
+        */
+       public final static class Some extends Option_ScalarZ {
+               public final org.ldk.structs.BigEndianScalar some;
+               private Some(long ptr, bindings.LDKCOption_ScalarZ.Some obj) {
+                       super(null, ptr);
+                       long some = obj.some;
+                       BigEndianScalar some_conv = new BigEndianScalar(null, some);
+                       this.some = some_conv;
+               }
+       }
+       /**
+        * When we're in this state, this COption_ScalarZ contains nothing
+        */
+       public final static class None extends Option_ScalarZ {
+               private None(long ptr, bindings.LDKCOption_ScalarZ.None obj) {
+                       super(null, ptr);
+               }
+       }
+       /**
+        * Constructs a new COption_ScalarZ containing a crate::c_types::BigEndianScalar
+        */
+       public static Option_ScalarZ some(byte[] o_big_endian_bytes) {
+               long ret = bindings.COption_ScalarZ_some(bindings.BigEndianScalar_new(InternalUtils.check_arr_len(o_big_endian_bytes, 32)));
+               Reference.reachabilityFence(o_big_endian_bytes);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Option_ScalarZ ret_hu_conv = org.ldk.structs.Option_ScalarZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               ;
+               return ret_hu_conv;
+       }
+
+       /**
+        * Constructs a new COption_ScalarZ containing nothing
+        */
+       public static Option_ScalarZ none() {
+               long ret = bindings.COption_ScalarZ_none();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Option_ScalarZ ret_hu_conv = org.ldk.structs.Option_ScalarZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/Option_WriteableScoreZ.java b/src/main/java/org/ldk/structs/Option_WriteableScoreZ.java
new file mode 100644 (file)
index 0000000..4310e16
--- /dev/null
@@ -0,0 +1,78 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * An enum which can either contain a crate::lightning::routing::scoring::WriteableScore or not
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class Option_WriteableScoreZ extends CommonBase {
+       private Option_WriteableScoreZ(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.COption_WriteableScoreZ_free(ptr); }
+       }
+       static Option_WriteableScoreZ constr_from_ptr(long ptr) {
+               bindings.LDKCOption_WriteableScoreZ raw_val = bindings.LDKCOption_WriteableScoreZ_ref_from_ptr(ptr);
+               if (raw_val.getClass() == bindings.LDKCOption_WriteableScoreZ.Some.class) {
+                       return new Some(ptr, (bindings.LDKCOption_WriteableScoreZ.Some)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKCOption_WriteableScoreZ.None.class) {
+                       return new None(ptr, (bindings.LDKCOption_WriteableScoreZ.None)raw_val);
+               }
+               assert false; return null; // Unreachable without extending the (internal) bindings interface
+       }
+
+       /**
+        * When we're in this state, this COption_WriteableScoreZ contains a crate::lightning::routing::scoring::WriteableScore
+        */
+       public final static class Some extends Option_WriteableScoreZ {
+               public final org.ldk.structs.WriteableScore some;
+               private Some(long ptr, bindings.LDKCOption_WriteableScoreZ.Some obj) {
+                       super(null, ptr);
+                       long some = obj.some;
+                       WriteableScore ret_hu_conv = new WriteableScore(null, some);
+                       if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+                       this.some = ret_hu_conv;
+               }
+       }
+       /**
+        * When we're in this state, this COption_WriteableScoreZ contains nothing
+        */
+       public final static class None extends Option_WriteableScoreZ {
+               private None(long ptr, bindings.LDKCOption_WriteableScoreZ.None obj) {
+                       super(null, ptr);
+               }
+       }
+       /**
+        * Constructs a new COption_WriteableScoreZ containing a crate::lightning::routing::scoring::WriteableScore
+        */
+       public static Option_WriteableScoreZ some(WriteableScore o) {
+               long ret = bindings.COption_WriteableScoreZ_some(o == null ? 0 : o.ptr);
+               Reference.reachabilityFence(o);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Option_WriteableScoreZ ret_hu_conv = org.ldk.structs.Option_WriteableScoreZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(o); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Constructs a new COption_WriteableScoreZ containing nothing
+        */
+       public static Option_WriteableScoreZ none() {
+               long ret = bindings.COption_WriteableScoreZ_none();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Option_WriteableScoreZ ret_hu_conv = org.ldk.structs.Option_WriteableScoreZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+}
index 70591023eecf3ae63b3077cf61c8973505991651..23ef8e347870666b845be8932e6d14acc24b7e46 100644 (file)
@@ -42,12 +42,19 @@ public class PeerManager extends CommonBase {
         * Constructs a new PeerManager with the given message handlers and node_id secret key
         * ephemeral_random_data is used to derive per-connection ephemeral keys and must be
         * cryptographically secure random bytes.
+        * 
+        * `current_time` is used as an always-increasing counter that survives across restarts and is
+        * incremented irregularly internally. In general it is best to simply use the current UNIX
+        * timestamp, however if it is not available a persistent counter that increases once per
+        * minute should suffice.
         */
-       public static PeerManager of(ChannelMessageHandler message_handler_chan_handler_arg, RoutingMessageHandler message_handler_route_handler_arg, byte[] our_node_secret, byte[] ephemeral_random_data, Logger logger, CustomMessageHandler custom_message_handler) {
-               long ret = bindings.PeerManager_new(bindings.MessageHandler_new(message_handler_chan_handler_arg == null ? 0 : message_handler_chan_handler_arg.ptr, message_handler_route_handler_arg == null ? 0 : message_handler_route_handler_arg.ptr), InternalUtils.check_arr_len(our_node_secret, 32), InternalUtils.check_arr_len(ephemeral_random_data, 32), logger == null ? 0 : logger.ptr, custom_message_handler == null ? 0 : custom_message_handler.ptr);
+       public static PeerManager of(ChannelMessageHandler message_handler_chan_handler_arg, RoutingMessageHandler message_handler_route_handler_arg, OnionMessageHandler message_handler_onion_message_handler_arg, byte[] our_node_secret, long current_time, byte[] ephemeral_random_data, Logger logger, CustomMessageHandler custom_message_handler) {
+               long ret = bindings.PeerManager_new(bindings.MessageHandler_new(message_handler_chan_handler_arg == null ? 0 : message_handler_chan_handler_arg.ptr, message_handler_route_handler_arg == null ? 0 : message_handler_route_handler_arg.ptr, message_handler_onion_message_handler_arg == null ? 0 : message_handler_onion_message_handler_arg.ptr), InternalUtils.check_arr_len(our_node_secret, 32), current_time, InternalUtils.check_arr_len(ephemeral_random_data, 32), logger == null ? 0 : logger.ptr, custom_message_handler == null ? 0 : custom_message_handler.ptr);
                Reference.reachabilityFence(message_handler_chan_handler_arg);
                Reference.reachabilityFence(message_handler_route_handler_arg);
+               Reference.reachabilityFence(message_handler_onion_message_handler_arg);
                Reference.reachabilityFence(our_node_secret);
+               Reference.reachabilityFence(current_time);
                Reference.reachabilityFence(ephemeral_random_data);
                Reference.reachabilityFence(logger);
                Reference.reachabilityFence(custom_message_handler);
@@ -56,6 +63,7 @@ public class PeerManager extends CommonBase {
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(message_handler_chan_handler_arg); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(message_handler_route_handler_arg); };
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(message_handler_onion_message_handler_arg); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(logger); };
                if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(custom_message_handler); };
                return ret_hu_conv;
@@ -259,4 +267,29 @@ public class PeerManager extends CommonBase {
                Reference.reachabilityFence(this);
        }
 
+       /**
+        * Generates a signed node_announcement from the given arguments, sending it to all connected
+        * peers. Note that peers will likely ignore this message unless we have at least one public
+        * channel which has at least six confirmations on-chain.
+        * 
+        * `rgb` is a node \"color\" and `alias` is a printable human-readable string to describe this
+        * node to humans. They carry no in-protocol meaning.
+        * 
+        * `addresses` represent the set (possibly empty) of socket addresses on which this node
+        * accepts incoming connections. These will be included in the node_announcement, publicly
+        * tying these addresses together and to this node. If you wish to preserve user privacy,
+        * addresses should likely contain only Tor Onion addresses.
+        * 
+        * Panics if `addresses` is absurdly large (more than 100).
+        * 
+        * [`get_and_clear_pending_msg_events`]: MessageSendEventsProvider::get_and_clear_pending_msg_events
+        */
+       public void broadcast_node_announcement(byte[] rgb, byte[] alias, NetAddress[] addresses) {
+               bindings.PeerManager_broadcast_node_announcement(this.ptr, InternalUtils.check_arr_len(rgb, 3), InternalUtils.check_arr_len(alias, 32), addresses != null ? Arrays.stream(addresses).mapToLong(addresses_conv_12 -> addresses_conv_12.ptr).toArray() : null);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(rgb);
+               Reference.reachabilityFence(alias);
+               Reference.reachabilityFence(addresses);
+       }
+
 }
index 172a7bbd6db970f97609e949fd8e55f4fe3673a8..96f93b56e9115a1bb5efd3174a8beb912e3b9c05 100644 (file)
@@ -8,7 +8,7 @@ import java.lang.ref.Reference;
 import javax.annotation.Nullable;
 
 /**
- * Trait that handles persisting a [`ChannelManager`], [`NetworkGraph`], and [`MultiThreadedLockableScore`] to disk.
+ * Trait that handles persisting a [`ChannelManager`], [`NetworkGraph`], and [`WriteableScore`] to disk.
  */
 @SuppressWarnings("unchecked") // We correctly assign various generic arrays
 public class Persister extends CommonBase {
@@ -34,9 +34,9 @@ public class Persister extends CommonBase {
                 */
                Result_NoneErrorZ persist_graph(NetworkGraph network_graph);
                /**
-                * Persist the given [`MultiThreadedLockableScore`] to disk, returning an error if persistence failed.
+                * Persist the given [`WriteableScore`] to disk, returning an error if persistence failed.
                 */
-               Result_NoneErrorZ persist_scorer(MultiThreadedLockableScore scorer);
+               Result_NoneErrorZ persist_scorer(WriteableScore scorer);
        }
        private static class LDKPersisterHolder { Persister held; }
        public static Persister new_impl(PersisterInterface arg) {
@@ -57,8 +57,9 @@ public class Persister extends CommonBase {
                                return result;
                        }
                        @Override public long persist_scorer(long scorer) {
-                               org.ldk.structs.MultiThreadedLockableScore scorer_hu_conv = null; if (scorer < 0 || scorer > 4096) { scorer_hu_conv = new org.ldk.structs.MultiThreadedLockableScore(null, scorer); }
-                               Result_NoneErrorZ ret = arg.persist_scorer(scorer_hu_conv);
+                               WriteableScore ret_hu_conv = new WriteableScore(null, scorer);
+                               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+                               Result_NoneErrorZ ret = arg.persist_scorer(ret_hu_conv);
                                Reference.reachabilityFence(arg);
                                long result = ret == null ? 0 : ret.clone_ptr();
                                return result;
@@ -93,9 +94,9 @@ public class Persister extends CommonBase {
        }
 
        /**
-        * Persist the given [`MultiThreadedLockableScore`] to disk, returning an error if persistence failed.
+        * Persist the given [`WriteableScore`] to disk, returning an error if persistence failed.
         */
-       public Result_NoneErrorZ persist_scorer(MultiThreadedLockableScore scorer) {
+       public Result_NoneErrorZ persist_scorer(WriteableScore scorer) {
                long ret = bindings.Persister_persist_scorer(this.ptr, scorer == null ? 0 : scorer.ptr);
                Reference.reachabilityFence(this);
                Reference.reachabilityFence(scorer);
index cb2de852cbdd16e5d66b54e35f26fbe53c79fef2..03b0cbd1a08ed8865ecec8d2e3fd59c543b2e0bb 100644 (file)
@@ -60,6 +60,18 @@ public class PositiveTimestamp extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Checks if two PositiveTimestamps contain equal inner contents.
+        */
+       public long hash() {
+               long ret = bindings.PositiveTimestamp_hash(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       @Override public int hashCode() {
+               return (int)this.hash();
+       }
        /**
         * Creates a `PositiveTimestamp` from a Unix timestamp in the range `0..=MAX_TIMESTAMP`.
         * 
index 1f9d3f0a8d6c63084c8bc5e2efaa8a83f81ff3f7..5f68e05609232d4aaab102cc700442356c99ed62 100644 (file)
@@ -77,4 +77,16 @@ public class RawDataPart extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Checks if two RawDataParts contain equal inner contents.
+        */
+       public long hash() {
+               long ret = bindings.RawDataPart_hash(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       @Override public int hashCode() {
+               return (int)this.hash();
+       }
 }
index fea24f2d06055789d69bd1d605c166ecd2aca399..107e6c0e1d9bd54221c727945ac5233875827909 100644 (file)
@@ -82,10 +82,22 @@ public class RawInvoice extends CommonBase {
        }
 
        /**
-        * Calculate the hash of the encoded `RawInvoice`
+        * Checks if two RawInvoices contain equal inner contents.
+        */
+       public long hash() {
+               long ret = bindings.RawInvoice_hash(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       @Override public int hashCode() {
+               return (int)this.hash();
+       }
+       /**
+        * Calculate the hash of the encoded `RawInvoice` which should be signed.
         */
-       public byte[] hash() {
-               byte[] ret = bindings.RawInvoice_hash(this.ptr);
+       public byte[] signable_hash() {
+               byte[] ret = bindings.RawInvoice_signable_hash(this.ptr);
                Reference.reachabilityFence(this);
                return ret;
        }
diff --git a/src/main/java/org/ldk/structs/Result_BlindedHopDecodeErrorZ.java b/src/main/java/org/ldk/structs/Result_BlindedHopDecodeErrorZ.java
new file mode 100644 (file)
index 0000000..c8991f4
--- /dev/null
@@ -0,0 +1,86 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+public class Result_BlindedHopDecodeErrorZ extends CommonBase {
+       private Result_BlindedHopDecodeErrorZ(Object _dummy, long ptr) { super(ptr); }
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.CResult_BlindedHopDecodeErrorZ_free(ptr); } super.finalize();
+       }
+
+       static Result_BlindedHopDecodeErrorZ constr_from_ptr(long ptr) {
+               if (bindings.CResult_BlindedHopDecodeErrorZ_is_ok(ptr)) {
+                       return new Result_BlindedHopDecodeErrorZ_OK(null, ptr);
+               } else {
+                       return new Result_BlindedHopDecodeErrorZ_Err(null, ptr);
+               }
+       }
+       public static final class Result_BlindedHopDecodeErrorZ_OK extends Result_BlindedHopDecodeErrorZ {
+               public final BlindedHop res;
+               private Result_BlindedHopDecodeErrorZ_OK(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long res = bindings.CResult_BlindedHopDecodeErrorZ_get_ok(ptr);
+                       org.ldk.structs.BlindedHop res_hu_conv = null; if (res < 0 || res > 4096) { res_hu_conv = new org.ldk.structs.BlindedHop(null, res); }
+                       if (res_hu_conv != null) { res_hu_conv.ptrs_to.add(this); };
+                       this.res = res_hu_conv;
+               }
+       }
+
+       public static final class Result_BlindedHopDecodeErrorZ_Err extends Result_BlindedHopDecodeErrorZ {
+               public final DecodeError err;
+               private Result_BlindedHopDecodeErrorZ_Err(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long err = bindings.CResult_BlindedHopDecodeErrorZ_get_err(ptr);
+                       org.ldk.structs.DecodeError err_hu_conv = null; if (err < 0 || err > 4096) { err_hu_conv = new org.ldk.structs.DecodeError(null, err); }
+                       if (err_hu_conv != null) { err_hu_conv.ptrs_to.add(this); };
+                       this.err = err_hu_conv;
+               }
+       }
+
+       /**
+        * Creates a new CResult_BlindedHopDecodeErrorZ in the success state.
+        */
+       public static Result_BlindedHopDecodeErrorZ ok(BlindedHop o) {
+               long ret = bindings.CResult_BlindedHopDecodeErrorZ_ok(o == null ? 0 : o.ptr);
+               Reference.reachabilityFence(o);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_BlindedHopDecodeErrorZ ret_hu_conv = Result_BlindedHopDecodeErrorZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(o); };
+               // Due to rust's strict-ownership memory model, in some cases we need to "move"
+               // an object to pass exclusive ownership to the function being called.
+               // In most cases, we avoid ret_hu_conv being visible in GC'd languages by cloning the object
+               // at the FFI layer, creating a new object which Rust can claim ownership of
+               // However, in some cases (eg here), there is no way to clone an object, and thus
+               // we actually have to pass full ownership to Rust.
+               // Thus, after ret_hu_conv call, o is reset to null and is now a dummy object.
+               o.ptr = 0;;
+               return ret_hu_conv;
+       }
+
+       /**
+        * Creates a new CResult_BlindedHopDecodeErrorZ in the error state.
+        */
+       public static Result_BlindedHopDecodeErrorZ err(DecodeError e) {
+               long ret = bindings.CResult_BlindedHopDecodeErrorZ_err(e == null ? 0 : e.ptr);
+               Reference.reachabilityFence(e);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_BlindedHopDecodeErrorZ ret_hu_conv = Result_BlindedHopDecodeErrorZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(e); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Checks if the given object is currently in the success state
+        */
+       public boolean is_ok() {
+               boolean ret = bindings.CResult_BlindedHopDecodeErrorZ_is_ok(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/Result_BlindedRouteDecodeErrorZ.java b/src/main/java/org/ldk/structs/Result_BlindedRouteDecodeErrorZ.java
new file mode 100644 (file)
index 0000000..bfa512b
--- /dev/null
@@ -0,0 +1,86 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+public class Result_BlindedRouteDecodeErrorZ extends CommonBase {
+       private Result_BlindedRouteDecodeErrorZ(Object _dummy, long ptr) { super(ptr); }
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.CResult_BlindedRouteDecodeErrorZ_free(ptr); } super.finalize();
+       }
+
+       static Result_BlindedRouteDecodeErrorZ constr_from_ptr(long ptr) {
+               if (bindings.CResult_BlindedRouteDecodeErrorZ_is_ok(ptr)) {
+                       return new Result_BlindedRouteDecodeErrorZ_OK(null, ptr);
+               } else {
+                       return new Result_BlindedRouteDecodeErrorZ_Err(null, ptr);
+               }
+       }
+       public static final class Result_BlindedRouteDecodeErrorZ_OK extends Result_BlindedRouteDecodeErrorZ {
+               public final BlindedRoute res;
+               private Result_BlindedRouteDecodeErrorZ_OK(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long res = bindings.CResult_BlindedRouteDecodeErrorZ_get_ok(ptr);
+                       org.ldk.structs.BlindedRoute res_hu_conv = null; if (res < 0 || res > 4096) { res_hu_conv = new org.ldk.structs.BlindedRoute(null, res); }
+                       if (res_hu_conv != null) { res_hu_conv.ptrs_to.add(this); };
+                       this.res = res_hu_conv;
+               }
+       }
+
+       public static final class Result_BlindedRouteDecodeErrorZ_Err extends Result_BlindedRouteDecodeErrorZ {
+               public final DecodeError err;
+               private Result_BlindedRouteDecodeErrorZ_Err(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long err = bindings.CResult_BlindedRouteDecodeErrorZ_get_err(ptr);
+                       org.ldk.structs.DecodeError err_hu_conv = null; if (err < 0 || err > 4096) { err_hu_conv = new org.ldk.structs.DecodeError(null, err); }
+                       if (err_hu_conv != null) { err_hu_conv.ptrs_to.add(this); };
+                       this.err = err_hu_conv;
+               }
+       }
+
+       /**
+        * Creates a new CResult_BlindedRouteDecodeErrorZ in the success state.
+        */
+       public static Result_BlindedRouteDecodeErrorZ ok(BlindedRoute o) {
+               long ret = bindings.CResult_BlindedRouteDecodeErrorZ_ok(o == null ? 0 : o.ptr);
+               Reference.reachabilityFence(o);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_BlindedRouteDecodeErrorZ ret_hu_conv = Result_BlindedRouteDecodeErrorZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(o); };
+               // Due to rust's strict-ownership memory model, in some cases we need to "move"
+               // an object to pass exclusive ownership to the function being called.
+               // In most cases, we avoid ret_hu_conv being visible in GC'd languages by cloning the object
+               // at the FFI layer, creating a new object which Rust can claim ownership of
+               // However, in some cases (eg here), there is no way to clone an object, and thus
+               // we actually have to pass full ownership to Rust.
+               // Thus, after ret_hu_conv call, o is reset to null and is now a dummy object.
+               o.ptr = 0;;
+               return ret_hu_conv;
+       }
+
+       /**
+        * Creates a new CResult_BlindedRouteDecodeErrorZ in the error state.
+        */
+       public static Result_BlindedRouteDecodeErrorZ err(DecodeError e) {
+               long ret = bindings.CResult_BlindedRouteDecodeErrorZ_err(e == null ? 0 : e.ptr);
+               Reference.reachabilityFence(e);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_BlindedRouteDecodeErrorZ ret_hu_conv = Result_BlindedRouteDecodeErrorZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(e); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Checks if the given object is currently in the success state
+        */
+       public boolean is_ok() {
+               boolean ret = bindings.CResult_BlindedRouteDecodeErrorZ_is_ok(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/Result_BlindedRouteNoneZ.java b/src/main/java/org/ldk/structs/Result_BlindedRouteNoneZ.java
new file mode 100644 (file)
index 0000000..f644834
--- /dev/null
@@ -0,0 +1,79 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+public class Result_BlindedRouteNoneZ extends CommonBase {
+       private Result_BlindedRouteNoneZ(Object _dummy, long ptr) { super(ptr); }
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.CResult_BlindedRouteNoneZ_free(ptr); } super.finalize();
+       }
+
+       static Result_BlindedRouteNoneZ constr_from_ptr(long ptr) {
+               if (bindings.CResult_BlindedRouteNoneZ_is_ok(ptr)) {
+                       return new Result_BlindedRouteNoneZ_OK(null, ptr);
+               } else {
+                       return new Result_BlindedRouteNoneZ_Err(null, ptr);
+               }
+       }
+       public static final class Result_BlindedRouteNoneZ_OK extends Result_BlindedRouteNoneZ {
+               public final BlindedRoute res;
+               private Result_BlindedRouteNoneZ_OK(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long res = bindings.CResult_BlindedRouteNoneZ_get_ok(ptr);
+                       org.ldk.structs.BlindedRoute res_hu_conv = null; if (res < 0 || res > 4096) { res_hu_conv = new org.ldk.structs.BlindedRoute(null, res); }
+                       if (res_hu_conv != null) { res_hu_conv.ptrs_to.add(this); };
+                       this.res = res_hu_conv;
+               }
+       }
+
+       public static final class Result_BlindedRouteNoneZ_Err extends Result_BlindedRouteNoneZ {
+               private Result_BlindedRouteNoneZ_Err(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+               }
+       }
+
+       /**
+        * Creates a new CResult_BlindedRouteNoneZ in the success state.
+        */
+       public static Result_BlindedRouteNoneZ ok(BlindedRoute o) {
+               long ret = bindings.CResult_BlindedRouteNoneZ_ok(o == null ? 0 : o.ptr);
+               Reference.reachabilityFence(o);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_BlindedRouteNoneZ ret_hu_conv = Result_BlindedRouteNoneZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(o); };
+               // Due to rust's strict-ownership memory model, in some cases we need to "move"
+               // an object to pass exclusive ownership to the function being called.
+               // In most cases, we avoid ret_hu_conv being visible in GC'd languages by cloning the object
+               // at the FFI layer, creating a new object which Rust can claim ownership of
+               // However, in some cases (eg here), there is no way to clone an object, and thus
+               // we actually have to pass full ownership to Rust.
+               // Thus, after ret_hu_conv call, o is reset to null and is now a dummy object.
+               o.ptr = 0;;
+               return ret_hu_conv;
+       }
+
+       /**
+        * Creates a new CResult_BlindedRouteNoneZ in the error state.
+        */
+       public static Result_BlindedRouteNoneZ err() {
+               long ret = bindings.CResult_BlindedRouteNoneZ_err();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_BlindedRouteNoneZ ret_hu_conv = Result_BlindedRouteNoneZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+       /**
+        * Checks if the given object is currently in the success state
+        */
+       public boolean is_ok() {
+               boolean ret = bindings.CResult_BlindedRouteNoneZ_is_ok(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/Result_InFlightHtlcsDecodeErrorZ.java b/src/main/java/org/ldk/structs/Result_InFlightHtlcsDecodeErrorZ.java
new file mode 100644 (file)
index 0000000..12f95bd
--- /dev/null
@@ -0,0 +1,86 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+public class Result_InFlightHtlcsDecodeErrorZ extends CommonBase {
+       private Result_InFlightHtlcsDecodeErrorZ(Object _dummy, long ptr) { super(ptr); }
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.CResult_InFlightHtlcsDecodeErrorZ_free(ptr); } super.finalize();
+       }
+
+       static Result_InFlightHtlcsDecodeErrorZ constr_from_ptr(long ptr) {
+               if (bindings.CResult_InFlightHtlcsDecodeErrorZ_is_ok(ptr)) {
+                       return new Result_InFlightHtlcsDecodeErrorZ_OK(null, ptr);
+               } else {
+                       return new Result_InFlightHtlcsDecodeErrorZ_Err(null, ptr);
+               }
+       }
+       public static final class Result_InFlightHtlcsDecodeErrorZ_OK extends Result_InFlightHtlcsDecodeErrorZ {
+               public final InFlightHtlcs res;
+               private Result_InFlightHtlcsDecodeErrorZ_OK(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long res = bindings.CResult_InFlightHtlcsDecodeErrorZ_get_ok(ptr);
+                       org.ldk.structs.InFlightHtlcs res_hu_conv = null; if (res < 0 || res > 4096) { res_hu_conv = new org.ldk.structs.InFlightHtlcs(null, res); }
+                       if (res_hu_conv != null) { res_hu_conv.ptrs_to.add(this); };
+                       this.res = res_hu_conv;
+               }
+       }
+
+       public static final class Result_InFlightHtlcsDecodeErrorZ_Err extends Result_InFlightHtlcsDecodeErrorZ {
+               public final DecodeError err;
+               private Result_InFlightHtlcsDecodeErrorZ_Err(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long err = bindings.CResult_InFlightHtlcsDecodeErrorZ_get_err(ptr);
+                       org.ldk.structs.DecodeError err_hu_conv = null; if (err < 0 || err > 4096) { err_hu_conv = new org.ldk.structs.DecodeError(null, err); }
+                       if (err_hu_conv != null) { err_hu_conv.ptrs_to.add(this); };
+                       this.err = err_hu_conv;
+               }
+       }
+
+       /**
+        * Creates a new CResult_InFlightHtlcsDecodeErrorZ in the success state.
+        */
+       public static Result_InFlightHtlcsDecodeErrorZ ok(InFlightHtlcs o) {
+               long ret = bindings.CResult_InFlightHtlcsDecodeErrorZ_ok(o == null ? 0 : o.ptr);
+               Reference.reachabilityFence(o);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_InFlightHtlcsDecodeErrorZ ret_hu_conv = Result_InFlightHtlcsDecodeErrorZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(o); };
+               // Due to rust's strict-ownership memory model, in some cases we need to "move"
+               // an object to pass exclusive ownership to the function being called.
+               // In most cases, we avoid ret_hu_conv being visible in GC'd languages by cloning the object
+               // at the FFI layer, creating a new object which Rust can claim ownership of
+               // However, in some cases (eg here), there is no way to clone an object, and thus
+               // we actually have to pass full ownership to Rust.
+               // Thus, after ret_hu_conv call, o is reset to null and is now a dummy object.
+               o.ptr = 0;;
+               return ret_hu_conv;
+       }
+
+       /**
+        * Creates a new CResult_InFlightHtlcsDecodeErrorZ in the error state.
+        */
+       public static Result_InFlightHtlcsDecodeErrorZ err(DecodeError e) {
+               long ret = bindings.CResult_InFlightHtlcsDecodeErrorZ_err(e == null ? 0 : e.ptr);
+               Reference.reachabilityFence(e);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_InFlightHtlcsDecodeErrorZ ret_hu_conv = Result_InFlightHtlcsDecodeErrorZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(e); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Checks if the given object is currently in the success state
+        */
+       public boolean is_ok() {
+               boolean ret = bindings.CResult_InFlightHtlcsDecodeErrorZ_is_ok(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/Result_NoneSendErrorZ.java b/src/main/java/org/ldk/structs/Result_NoneSendErrorZ.java
new file mode 100644 (file)
index 0000000..9aed423
--- /dev/null
@@ -0,0 +1,70 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+public class Result_NoneSendErrorZ extends CommonBase {
+       private Result_NoneSendErrorZ(Object _dummy, long ptr) { super(ptr); }
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.CResult_NoneSendErrorZ_free(ptr); } super.finalize();
+       }
+
+       static Result_NoneSendErrorZ constr_from_ptr(long ptr) {
+               if (bindings.CResult_NoneSendErrorZ_is_ok(ptr)) {
+                       return new Result_NoneSendErrorZ_OK(null, ptr);
+               } else {
+                       return new Result_NoneSendErrorZ_Err(null, ptr);
+               }
+       }
+       public static final class Result_NoneSendErrorZ_OK extends Result_NoneSendErrorZ {
+               private Result_NoneSendErrorZ_OK(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+               }
+       }
+
+       public static final class Result_NoneSendErrorZ_Err extends Result_NoneSendErrorZ {
+               public final SendError err;
+               private Result_NoneSendErrorZ_Err(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long err = bindings.CResult_NoneSendErrorZ_get_err(ptr);
+                       org.ldk.structs.SendError err_hu_conv = org.ldk.structs.SendError.constr_from_ptr(err);
+                       if (err_hu_conv != null) { err_hu_conv.ptrs_to.add(this); };
+                       this.err = err_hu_conv;
+               }
+       }
+
+       /**
+        * Creates a new CResult_NoneSendErrorZ in the success state.
+        */
+       public static Result_NoneSendErrorZ ok() {
+               long ret = bindings.CResult_NoneSendErrorZ_ok();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_NoneSendErrorZ ret_hu_conv = Result_NoneSendErrorZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+       /**
+        * Creates a new CResult_NoneSendErrorZ in the error state.
+        */
+       public static Result_NoneSendErrorZ err(SendError e) {
+               long ret = bindings.CResult_NoneSendErrorZ_err(e.ptr);
+               Reference.reachabilityFence(e);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_NoneSendErrorZ ret_hu_conv = Result_NoneSendErrorZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+       /**
+        * Checks if the given object is currently in the success state
+        */
+       public boolean is_ok() {
+               boolean ret = bindings.CResult_NoneSendErrorZ_is_ok(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/Result_OnionMessageDecodeErrorZ.java b/src/main/java/org/ldk/structs/Result_OnionMessageDecodeErrorZ.java
new file mode 100644 (file)
index 0000000..f239ae3
--- /dev/null
@@ -0,0 +1,96 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+public class Result_OnionMessageDecodeErrorZ extends CommonBase {
+       private Result_OnionMessageDecodeErrorZ(Object _dummy, long ptr) { super(ptr); }
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.CResult_OnionMessageDecodeErrorZ_free(ptr); } super.finalize();
+       }
+
+       static Result_OnionMessageDecodeErrorZ constr_from_ptr(long ptr) {
+               if (bindings.CResult_OnionMessageDecodeErrorZ_is_ok(ptr)) {
+                       return new Result_OnionMessageDecodeErrorZ_OK(null, ptr);
+               } else {
+                       return new Result_OnionMessageDecodeErrorZ_Err(null, ptr);
+               }
+       }
+       public static final class Result_OnionMessageDecodeErrorZ_OK extends Result_OnionMessageDecodeErrorZ {
+               public final OnionMessage res;
+               private Result_OnionMessageDecodeErrorZ_OK(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long res = bindings.CResult_OnionMessageDecodeErrorZ_get_ok(ptr);
+                       org.ldk.structs.OnionMessage res_hu_conv = null; if (res < 0 || res > 4096) { res_hu_conv = new org.ldk.structs.OnionMessage(null, res); }
+                       if (res_hu_conv != null) { res_hu_conv.ptrs_to.add(this); };
+                       this.res = res_hu_conv;
+               }
+       }
+
+       public static final class Result_OnionMessageDecodeErrorZ_Err extends Result_OnionMessageDecodeErrorZ {
+               public final DecodeError err;
+               private Result_OnionMessageDecodeErrorZ_Err(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       long err = bindings.CResult_OnionMessageDecodeErrorZ_get_err(ptr);
+                       org.ldk.structs.DecodeError err_hu_conv = null; if (err < 0 || err > 4096) { err_hu_conv = new org.ldk.structs.DecodeError(null, err); }
+                       if (err_hu_conv != null) { err_hu_conv.ptrs_to.add(this); };
+                       this.err = err_hu_conv;
+               }
+       }
+
+       /**
+        * Creates a new CResult_OnionMessageDecodeErrorZ in the success state.
+        */
+       public static Result_OnionMessageDecodeErrorZ ok(OnionMessage o) {
+               long ret = bindings.CResult_OnionMessageDecodeErrorZ_ok(o == null ? 0 : o.ptr);
+               Reference.reachabilityFence(o);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_OnionMessageDecodeErrorZ ret_hu_conv = Result_OnionMessageDecodeErrorZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(o); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Creates a new CResult_OnionMessageDecodeErrorZ in the error state.
+        */
+       public static Result_OnionMessageDecodeErrorZ err(DecodeError e) {
+               long ret = bindings.CResult_OnionMessageDecodeErrorZ_err(e == null ? 0 : e.ptr);
+               Reference.reachabilityFence(e);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_OnionMessageDecodeErrorZ ret_hu_conv = Result_OnionMessageDecodeErrorZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(e); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Checks if the given object is currently in the success state
+        */
+       public boolean is_ok() {
+               boolean ret = bindings.CResult_OnionMessageDecodeErrorZ_is_ok(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       long clone_ptr() {
+               long ret = bindings.CResult_OnionMessageDecodeErrorZ_clone_ptr(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Creates a new CResult_OnionMessageDecodeErrorZ which has the same data as `orig`
+        * but with all dynamically-allocated buffers duplicated in new buffers.
+        */
+       public Result_OnionMessageDecodeErrorZ clone() {
+               long ret = bindings.CResult_OnionMessageDecodeErrorZ_clone(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_OnionMessageDecodeErrorZ ret_hu_conv = Result_OnionMessageDecodeErrorZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+}
diff --git a/src/main/java/org/ldk/structs/Result_SharedSecretNoneZ.java b/src/main/java/org/ldk/structs/Result_SharedSecretNoneZ.java
new file mode 100644 (file)
index 0000000..f310bb7
--- /dev/null
@@ -0,0 +1,85 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+public class Result_SharedSecretNoneZ extends CommonBase {
+       private Result_SharedSecretNoneZ(Object _dummy, long ptr) { super(ptr); }
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.CResult_SharedSecretNoneZ_free(ptr); } super.finalize();
+       }
+
+       static Result_SharedSecretNoneZ constr_from_ptr(long ptr) {
+               if (bindings.CResult_SharedSecretNoneZ_is_ok(ptr)) {
+                       return new Result_SharedSecretNoneZ_OK(null, ptr);
+               } else {
+                       return new Result_SharedSecretNoneZ_Err(null, ptr);
+               }
+       }
+       public static final class Result_SharedSecretNoneZ_OK extends Result_SharedSecretNoneZ {
+               public final byte[] res;
+               private Result_SharedSecretNoneZ_OK(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+                       this.res = bindings.CResult_SharedSecretNoneZ_get_ok(ptr);
+               }
+       }
+
+       public static final class Result_SharedSecretNoneZ_Err extends Result_SharedSecretNoneZ {
+               private Result_SharedSecretNoneZ_Err(Object _dummy, long ptr) {
+                       super(_dummy, ptr);
+               }
+       }
+
+       /**
+        * Creates a new CResult_SharedSecretNoneZ in the success state.
+        */
+       public static Result_SharedSecretNoneZ ok(byte[] o) {
+               long ret = bindings.CResult_SharedSecretNoneZ_ok(InternalUtils.check_arr_len(o, 32));
+               Reference.reachabilityFence(o);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_SharedSecretNoneZ ret_hu_conv = Result_SharedSecretNoneZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+       /**
+        * Creates a new CResult_SharedSecretNoneZ in the error state.
+        */
+       public static Result_SharedSecretNoneZ err() {
+               long ret = bindings.CResult_SharedSecretNoneZ_err();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_SharedSecretNoneZ ret_hu_conv = Result_SharedSecretNoneZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+       /**
+        * Checks if the given object is currently in the success state
+        */
+       public boolean is_ok() {
+               boolean ret = bindings.CResult_SharedSecretNoneZ_is_ok(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       long clone_ptr() {
+               long ret = bindings.CResult_SharedSecretNoneZ_clone_ptr(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Creates a new CResult_SharedSecretNoneZ which has the same data as `orig`
+        * but with all dynamically-allocated buffers duplicated in new buffers.
+        */
+       public Result_SharedSecretNoneZ clone() {
+               long ret = bindings.CResult_SharedSecretNoneZ_clone(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               Result_SharedSecretNoneZ ret_hu_conv = Result_SharedSecretNoneZ.constr_from_ptr(ret);
+               return ret_hu_conv;
+       }
+
+}
index 294fc2545f794d5385f666d56d7e520b8021b173..856b73d76a7c65661703e6eb2625c4345e34f87f 100644 (file)
@@ -30,13 +30,29 @@ public class Router extends CommonBase {
                 * 
                 * Note that first_hops (or a relevant inner pointer) may be NULL or all-0s to represent None
                 */
-               Result_RouteLightningErrorZ find_route(byte[] payer, RouteParameters route_params, byte[] payment_hash, ChannelDetails[] first_hops, Score scorer);
+               Result_RouteLightningErrorZ find_route(byte[] payer, RouteParameters route_params, byte[] payment_hash, ChannelDetails[] first_hops, InFlightHtlcs inflight_htlcs);
+               /**
+                * Lets the router know that payment through a specific path has failed.
+                */
+               void notify_payment_path_failed(RouteHop[] path, long short_channel_id);
+               /**
+                * Lets the router know that payment through a specific path was successful.
+                */
+               void notify_payment_path_successful(RouteHop[] path);
+               /**
+                * Lets the router know that a payment probe was successful.
+                */
+               void notify_payment_probe_successful(RouteHop[] path);
+               /**
+                * Lets the router know that a payment probe failed.
+                */
+               void notify_payment_probe_failed(RouteHop[] path, long short_channel_id);
        }
        private static class LDKRouterHolder { Router held; }
        public static Router new_impl(RouterInterface arg) {
                final LDKRouterHolder impl_holder = new LDKRouterHolder();
                impl_holder.held = new Router(new bindings.LDKRouter() {
-                       @Override public long find_route(byte[] payer, long route_params, byte[] payment_hash, long[] first_hops, long scorer) {
+                       @Override public long find_route(byte[] payer, long route_params, byte[] payment_hash, long[] first_hops, long inflight_htlcs) {
                                org.ldk.structs.RouteParameters route_params_hu_conv = null; if (route_params < 0 || route_params > 4096) { route_params_hu_conv = new org.ldk.structs.RouteParameters(null, route_params); }
                                int first_hops_conv_16_len = first_hops.length;
                                ChannelDetails[] first_hops_conv_16_arr = new ChannelDetails[first_hops_conv_16_len];
@@ -46,13 +62,61 @@ public class Router extends CommonBase {
                                        if (first_hops_conv_16_hu_conv != null) { first_hops_conv_16_hu_conv.ptrs_to.add(this); };
                                        first_hops_conv_16_arr[q] = first_hops_conv_16_hu_conv;
                                }
-                               Score ret_hu_conv = new Score(null, scorer);
-                               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
-                               Result_RouteLightningErrorZ ret = arg.find_route(payer, route_params_hu_conv, payment_hash, first_hops_conv_16_arr, ret_hu_conv);
+                               org.ldk.structs.InFlightHtlcs inflight_htlcs_hu_conv = null; if (inflight_htlcs < 0 || inflight_htlcs > 4096) { inflight_htlcs_hu_conv = new org.ldk.structs.InFlightHtlcs(null, inflight_htlcs); }
+                               if (inflight_htlcs_hu_conv != null) { inflight_htlcs_hu_conv.ptrs_to.add(this); };
+                               Result_RouteLightningErrorZ ret = arg.find_route(payer, route_params_hu_conv, payment_hash, first_hops_conv_16_arr, inflight_htlcs_hu_conv);
                                Reference.reachabilityFence(arg);
                                long result = ret == null ? 0 : ret.clone_ptr();
                                return result;
                        }
+                       @Override public void notify_payment_path_failed(long[] path, long short_channel_id) {
+                               int path_conv_10_len = path.length;
+                               RouteHop[] path_conv_10_arr = new RouteHop[path_conv_10_len];
+                               for (int k = 0; k < path_conv_10_len; k++) {
+                                       long path_conv_10 = path[k];
+                                       org.ldk.structs.RouteHop path_conv_10_hu_conv = null; if (path_conv_10 < 0 || path_conv_10 > 4096) { path_conv_10_hu_conv = new org.ldk.structs.RouteHop(null, path_conv_10); }
+                                       if (path_conv_10_hu_conv != null) { path_conv_10_hu_conv.ptrs_to.add(this); };
+                                       path_conv_10_arr[k] = path_conv_10_hu_conv;
+                               }
+                               arg.notify_payment_path_failed(path_conv_10_arr, short_channel_id);
+                               Reference.reachabilityFence(arg);
+                       }
+                       @Override public void notify_payment_path_successful(long[] path) {
+                               int path_conv_10_len = path.length;
+                               RouteHop[] path_conv_10_arr = new RouteHop[path_conv_10_len];
+                               for (int k = 0; k < path_conv_10_len; k++) {
+                                       long path_conv_10 = path[k];
+                                       org.ldk.structs.RouteHop path_conv_10_hu_conv = null; if (path_conv_10 < 0 || path_conv_10 > 4096) { path_conv_10_hu_conv = new org.ldk.structs.RouteHop(null, path_conv_10); }
+                                       if (path_conv_10_hu_conv != null) { path_conv_10_hu_conv.ptrs_to.add(this); };
+                                       path_conv_10_arr[k] = path_conv_10_hu_conv;
+                               }
+                               arg.notify_payment_path_successful(path_conv_10_arr);
+                               Reference.reachabilityFence(arg);
+                       }
+                       @Override public void notify_payment_probe_successful(long[] path) {
+                               int path_conv_10_len = path.length;
+                               RouteHop[] path_conv_10_arr = new RouteHop[path_conv_10_len];
+                               for (int k = 0; k < path_conv_10_len; k++) {
+                                       long path_conv_10 = path[k];
+                                       org.ldk.structs.RouteHop path_conv_10_hu_conv = null; if (path_conv_10 < 0 || path_conv_10 > 4096) { path_conv_10_hu_conv = new org.ldk.structs.RouteHop(null, path_conv_10); }
+                                       if (path_conv_10_hu_conv != null) { path_conv_10_hu_conv.ptrs_to.add(this); };
+                                       path_conv_10_arr[k] = path_conv_10_hu_conv;
+                               }
+                               arg.notify_payment_probe_successful(path_conv_10_arr);
+                               Reference.reachabilityFence(arg);
+                       }
+                       @Override public void notify_payment_probe_failed(long[] path, long short_channel_id) {
+                               int path_conv_10_len = path.length;
+                               RouteHop[] path_conv_10_arr = new RouteHop[path_conv_10_len];
+                               for (int k = 0; k < path_conv_10_len; k++) {
+                                       long path_conv_10 = path[k];
+                                       org.ldk.structs.RouteHop path_conv_10_hu_conv = null; if (path_conv_10 < 0 || path_conv_10 > 4096) { path_conv_10_hu_conv = new org.ldk.structs.RouteHop(null, path_conv_10); }
+                                       if (path_conv_10_hu_conv != null) { path_conv_10_hu_conv.ptrs_to.add(this); };
+                                       path_conv_10_arr[k] = path_conv_10_hu_conv;
+                               }
+                               arg.notify_payment_probe_failed(path_conv_10_arr, short_channel_id);
+                               Reference.reachabilityFence(arg);
+                       }
                });
                return impl_holder.held;
        }
@@ -61,20 +125,70 @@ public class Router extends CommonBase {
         * 
         * Note that first_hops (or a relevant inner pointer) may be NULL or all-0s to represent None
         */
-       public Result_RouteLightningErrorZ find_route(byte[] payer, RouteParameters route_params, byte[] payment_hash, @Nullable ChannelDetails[] first_hops, Score scorer) {
-               long ret = bindings.Router_find_route(this.ptr, InternalUtils.check_arr_len(payer, 33), route_params == null ? 0 : route_params.ptr, InternalUtils.check_arr_len(payment_hash, 32), first_hops != null ? Arrays.stream(first_hops).mapToLong(first_hops_conv_16 -> first_hops_conv_16 == null ? 0 : first_hops_conv_16.ptr).toArray() : null, scorer == null ? 0 : scorer.ptr);
+       public Result_RouteLightningErrorZ find_route(byte[] payer, RouteParameters route_params, byte[] payment_hash, @Nullable ChannelDetails[] first_hops, InFlightHtlcs inflight_htlcs) {
+               long ret = bindings.Router_find_route(this.ptr, InternalUtils.check_arr_len(payer, 33), route_params == null ? 0 : route_params.ptr, InternalUtils.check_arr_len(payment_hash, 32), first_hops != null ? Arrays.stream(first_hops).mapToLong(first_hops_conv_16 -> first_hops_conv_16 == null ? 0 : first_hops_conv_16.ptr).toArray() : null, inflight_htlcs == null ? 0 : inflight_htlcs.ptr);
                Reference.reachabilityFence(this);
                Reference.reachabilityFence(payer);
                Reference.reachabilityFence(route_params);
                Reference.reachabilityFence(payment_hash);
                Reference.reachabilityFence(first_hops);
-               Reference.reachabilityFence(scorer);
+               Reference.reachabilityFence(inflight_htlcs);
                if (ret >= 0 && ret <= 4096) { return null; }
                Result_RouteLightningErrorZ ret_hu_conv = Result_RouteLightningErrorZ.constr_from_ptr(ret);
                if (this != null) { this.ptrs_to.add(route_params); };
                for (ChannelDetails first_hops_conv_16: first_hops) { if (this != null) { this.ptrs_to.add(first_hops_conv_16); }; };
-               if (this != null) { this.ptrs_to.add(scorer); };
+               if (this != null) { this.ptrs_to.add(inflight_htlcs); };
+               // Due to rust's strict-ownership memory model, in some cases we need to "move"
+               // an object to pass exclusive ownership to the function being called.
+               // In most cases, we avoid this being visible in GC'd languages by cloning the object
+               // at the FFI layer, creating a new object which Rust can claim ownership of
+               // However, in some cases (eg here), there is no way to clone an object, and thus
+               // we actually have to pass full ownership to Rust.
+               // Thus, after this call, inflight_htlcs is reset to null and is now a dummy object.
+               inflight_htlcs.ptr = 0;;
                return ret_hu_conv;
        }
 
+       /**
+        * Lets the router know that payment through a specific path has failed.
+        */
+       public void notify_payment_path_failed(RouteHop[] path, long short_channel_id) {
+               bindings.Router_notify_payment_path_failed(this.ptr, path != null ? Arrays.stream(path).mapToLong(path_conv_10 -> path_conv_10 == null ? 0 : path_conv_10.ptr).toArray() : null, short_channel_id);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(path);
+               Reference.reachabilityFence(short_channel_id);
+               for (RouteHop path_conv_10: path) { if (this != null) { this.ptrs_to.add(path_conv_10); }; };
+       }
+
+       /**
+        * Lets the router know that payment through a specific path was successful.
+        */
+       public void notify_payment_path_successful(RouteHop[] path) {
+               bindings.Router_notify_payment_path_successful(this.ptr, path != null ? Arrays.stream(path).mapToLong(path_conv_10 -> path_conv_10 == null ? 0 : path_conv_10.ptr).toArray() : null);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(path);
+               for (RouteHop path_conv_10: path) { if (this != null) { this.ptrs_to.add(path_conv_10); }; };
+       }
+
+       /**
+        * Lets the router know that a payment probe was successful.
+        */
+       public void notify_payment_probe_successful(RouteHop[] path) {
+               bindings.Router_notify_payment_probe_successful(this.ptr, path != null ? Arrays.stream(path).mapToLong(path_conv_10 -> path_conv_10 == null ? 0 : path_conv_10.ptr).toArray() : null);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(path);
+               for (RouteHop path_conv_10: path) { if (this != null) { this.ptrs_to.add(path_conv_10); }; };
+       }
+
+       /**
+        * Lets the router know that a payment probe failed.
+        */
+       public void notify_payment_probe_failed(RouteHop[] path, long short_channel_id) {
+               bindings.Router_notify_payment_probe_failed(this.ptr, path != null ? Arrays.stream(path).mapToLong(path_conv_10 -> path_conv_10 == null ? 0 : path_conv_10.ptr).toArray() : null, short_channel_id);
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(path);
+               Reference.reachabilityFence(short_channel_id);
+               for (RouteHop path_conv_10: path) { if (this != null) { this.ptrs_to.add(path_conv_10); }; };
+       }
+
 }
index 942238f5bceb91e5f24c2a123a8effaa52e2c900..aacd7daa095ba7092727e5ddb5b3c5684aed99f4 100644 (file)
@@ -48,20 +48,21 @@ public class RoutingMessageHandler extends CommonBase {
                 */
                Result_boolLightningErrorZ handle_channel_update(ChannelUpdate msg);
                /**
-                * Gets a subset of the channel announcements and updates required to dump our routing table
-                * to a remote node, starting at the short_channel_id indicated by starting_point and
-                * including the batch_amount entries immediately higher in numerical value than starting_point.
+                * Gets channel announcements and updates required to dump our routing table to a remote node,
+                * starting at the short_channel_id indicated by starting_point and including announcements
+                * for a single channel.
                 */
-               ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ[] get_next_channel_announcements(long starting_point, byte batch_amount);
+               Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ get_next_channel_announcement(long starting_point);
                /**
-                * Gets a subset of the node announcements required to dump our routing table to a remote node,
-                * starting at the node *after* the provided publickey and including batch_amount entries
-                * immediately higher (as defined by <PublicKey as Ord>::cmp) than starting_point.
+                * Gets a node announcement required to dump our routing table to a remote node, starting at
+                * the node *after* the provided pubkey and including up to one announcement immediately
+                * higher (as defined by <PublicKey as Ord>::cmp) than starting_point.
                 * If None is provided for starting_point, we start at the first node.
                 * 
                 * Note that starting_point (or a relevant inner pointer) may be NULL or all-0s to represent None
+                * Note that the return value (or a relevant inner pointer) may be NULL or all-0s to represent None
                 */
-               NodeAnnouncement[] get_next_node_announcements(byte[] starting_point, byte batch_amount);
+               NodeAnnouncement get_next_node_announcement(byte[] starting_point);
                /**
                 * Called when a connection is established with a peer. This can be used to
                 * perform routing table synchronization using a strategy defined by the
@@ -91,6 +92,20 @@ public class RoutingMessageHandler extends CommonBase {
                 * list of short_channel_ids.
                 */
                Result_NoneLightningErrorZ handle_query_short_channel_ids(byte[] their_node_id, QueryShortChannelIds msg);
+               /**
+                * Gets the node feature flags which this handler itself supports. All available handlers are
+                * queried similarly and their feature flags are OR'd together to form the [`NodeFeatures`]
+                * which are broadcasted in our [`NodeAnnouncement`] message.
+                */
+               NodeFeatures provided_node_features();
+               /**
+                * Gets the init feature flags which should be sent to the given peer. All available handlers
+                * are queried similarly and their feature flags are OR'd together to form the [`InitFeatures`]
+                * which are sent in our [`Init`] message.
+                * 
+                * Note that this method is called before [`Self::peer_connected`].
+                */
+               InitFeatures provided_init_features(byte[] their_node_id);
        }
        private static class LDKRoutingMessageHandlerHolder { RoutingMessageHandler held; }
        public static RoutingMessageHandler new_impl(RoutingMessageHandlerInterface arg, MessageSendEventsProvider.MessageSendEventsProviderInterface MessageSendEventsProvider_impl) {
@@ -117,16 +132,16 @@ public class RoutingMessageHandler extends CommonBase {
                                long result = ret == null ? 0 : ret.clone_ptr();
                                return result;
                        }
-                       @Override public long[] get_next_channel_announcements(long starting_point, byte batch_amount) {
-                               ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ[] ret = arg.get_next_channel_announcements(starting_point, batch_amount);
+                       @Override public long get_next_channel_announcement(long starting_point) {
+                               Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret = arg.get_next_channel_announcement(starting_point);
                                Reference.reachabilityFence(arg);
-                               long[] result = ret != null ? Arrays.stream(ret).mapToLong(ret_conv_59 -> ret_conv_59 == null ? 0 : ret_conv_59.clone_ptr()).toArray() : null;
+                               long result = ret == null ? 0 : ret.clone_ptr();
                                return result;
                        }
-                       @Override public long[] get_next_node_announcements(byte[] starting_point, byte batch_amount) {
-                               NodeAnnouncement[] ret = arg.get_next_node_announcements(starting_point, batch_amount);
+                       @Override public long get_next_node_announcement(byte[] starting_point) {
+                               NodeAnnouncement ret = arg.get_next_node_announcement(starting_point);
                                Reference.reachabilityFence(arg);
-                               long[] result = ret != null ? Arrays.stream(ret).mapToLong(ret_conv_18 -> ret_conv_18 == null ? 0 : ret_conv_18.clone_ptr()).toArray() : null;
+                               long result = ret == null ? 0 : ret.clone_ptr();
                                return result;
                        }
                        @Override public void peer_connected(byte[] their_node_id, long init) {
@@ -166,6 +181,18 @@ public class RoutingMessageHandler extends CommonBase {
                                long result = ret == null ? 0 : ret.clone_ptr();
                                return result;
                        }
+                       @Override public long provided_node_features() {
+                               NodeFeatures ret = arg.provided_node_features();
+                               Reference.reachabilityFence(arg);
+                               long result = ret == null ? 0 : ret.clone_ptr();
+                               return result;
+                       }
+                       @Override public long provided_init_features(byte[] their_node_id) {
+                               InitFeatures ret = arg.provided_init_features(their_node_id);
+                               Reference.reachabilityFence(arg);
+                               long result = ret == null ? 0 : ret.clone_ptr();
+                               return result;
+                       }
                }, MessageSendEventsProvider.new_impl(MessageSendEventsProvider_impl).bindings_instance);
                return impl_holder.held;
        }
@@ -222,48 +249,38 @@ public class RoutingMessageHandler extends CommonBase {
        }
 
        /**
-        * Gets a subset of the channel announcements and updates required to dump our routing table
-        * to a remote node, starting at the short_channel_id indicated by starting_point and
-        * including the batch_amount entries immediately higher in numerical value than starting_point.
+        * Gets channel announcements and updates required to dump our routing table to a remote node,
+        * starting at the short_channel_id indicated by starting_point and including announcements
+        * for a single channel.
         */
-       public ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ[] get_next_channel_announcements(long starting_point, byte batch_amount) {
-               long[] ret = bindings.RoutingMessageHandler_get_next_channel_announcements(this.ptr, starting_point, batch_amount);
+       public Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ get_next_channel_announcement(long starting_point) {
+               long ret = bindings.RoutingMessageHandler_get_next_channel_announcement(this.ptr, starting_point);
                Reference.reachabilityFence(this);
                Reference.reachabilityFence(starting_point);
-               Reference.reachabilityFence(batch_amount);
-               int ret_conv_59_len = ret.length;
-               ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ[] ret_conv_59_arr = new ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ[ret_conv_59_len];
-               for (int h = 0; h < ret_conv_59_len; h++) {
-                       long ret_conv_59 = ret[h];
-                       ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ ret_conv_59_hu_conv = new ThreeTuple_ChannelAnnouncementChannelUpdateChannelUpdateZ(null, ret_conv_59);
-                       if (ret_conv_59_hu_conv != null) { ret_conv_59_hu_conv.ptrs_to.add(this); };
-                       ret_conv_59_arr[h] = ret_conv_59_hu_conv;
-               }
-               return ret_conv_59_arr;
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_hu_conv = org.ldk.structs.Option_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
        }
 
        /**
-        * Gets a subset of the node announcements required to dump our routing table to a remote node,
-        * starting at the node *after* the provided publickey and including batch_amount entries
-        * immediately higher (as defined by <PublicKey as Ord>::cmp) than starting_point.
+        * Gets a node announcement required to dump our routing table to a remote node, starting at
+        * the node *after* the provided pubkey and including up to one announcement immediately
+        * higher (as defined by <PublicKey as Ord>::cmp) than starting_point.
         * If None is provided for starting_point, we start at the first node.
         * 
         * Note that starting_point (or a relevant inner pointer) may be NULL or all-0s to represent None
+        * Note that the return value (or a relevant inner pointer) may be NULL or all-0s to represent None
         */
-       public NodeAnnouncement[] get_next_node_announcements(@Nullable byte[] starting_point, byte batch_amount) {
-               long[] ret = bindings.RoutingMessageHandler_get_next_node_announcements(this.ptr, InternalUtils.check_arr_len(starting_point, 33), batch_amount);
+       @Nullable
+       public NodeAnnouncement get_next_node_announcement(@Nullable byte[] starting_point) {
+               long ret = bindings.RoutingMessageHandler_get_next_node_announcement(this.ptr, InternalUtils.check_arr_len(starting_point, 33));
                Reference.reachabilityFence(this);
                Reference.reachabilityFence(starting_point);
-               Reference.reachabilityFence(batch_amount);
-               int ret_conv_18_len = ret.length;
-               NodeAnnouncement[] ret_conv_18_arr = new NodeAnnouncement[ret_conv_18_len];
-               for (int s = 0; s < ret_conv_18_len; s++) {
-                       long ret_conv_18 = ret[s];
-                       org.ldk.structs.NodeAnnouncement ret_conv_18_hu_conv = null; if (ret_conv_18 < 0 || ret_conv_18 > 4096) { ret_conv_18_hu_conv = new org.ldk.structs.NodeAnnouncement(null, ret_conv_18); }
-                       if (ret_conv_18_hu_conv != null) { ret_conv_18_hu_conv.ptrs_to.add(this); };
-                       ret_conv_18_arr[s] = ret_conv_18_hu_conv;
-               }
-               return ret_conv_18_arr;
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.NodeAnnouncement ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.NodeAnnouncement(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
        }
 
        /**
@@ -342,4 +359,35 @@ public class RoutingMessageHandler extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Gets the node feature flags which this handler itself supports. All available handlers are
+        * queried similarly and their feature flags are OR'd together to form the [`NodeFeatures`]
+        * which are broadcasted in our [`NodeAnnouncement`] message.
+        */
+       public NodeFeatures provided_node_features() {
+               long ret = bindings.RoutingMessageHandler_provided_node_features(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.NodeFeatures ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.NodeFeatures(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Gets the init feature flags which should be sent to the given peer. All available handlers
+        * are queried similarly and their feature flags are OR'd together to form the [`InitFeatures`]
+        * which are sent in our [`Init`] message.
+        * 
+        * Note that this method is called before [`Self::peer_connected`].
+        */
+       public InitFeatures provided_init_features(byte[] their_node_id) {
+               long ret = bindings.RoutingMessageHandler_provided_init_features(this.ptr, InternalUtils.check_arr_len(their_node_id, 33));
+               Reference.reachabilityFence(this);
+               Reference.reachabilityFence(their_node_id);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.InitFeatures ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.InitFeatures(null, ret); }
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
 }
diff --git a/src/main/java/org/ldk/structs/SendError.java b/src/main/java/org/ldk/structs/SendError.java
new file mode 100644 (file)
index 0000000..573aea9
--- /dev/null
@@ -0,0 +1,162 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+
+/**
+ * Errors that may occur when [sending an onion message].
+ * 
+ * [sending an onion message]: OnionMessenger::send_onion_message
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class SendError extends CommonBase {
+       private SendError(Object _dummy, long ptr) { super(ptr); }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.SendError_free(ptr); }
+       }
+       static SendError constr_from_ptr(long ptr) {
+               bindings.LDKSendError raw_val = bindings.LDKSendError_ref_from_ptr(ptr);
+               if (raw_val.getClass() == bindings.LDKSendError.Secp256k1.class) {
+                       return new Secp256k1(ptr, (bindings.LDKSendError.Secp256k1)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKSendError.TooBigPacket.class) {
+                       return new TooBigPacket(ptr, (bindings.LDKSendError.TooBigPacket)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKSendError.TooFewBlindedHops.class) {
+                       return new TooFewBlindedHops(ptr, (bindings.LDKSendError.TooFewBlindedHops)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKSendError.InvalidFirstHop.class) {
+                       return new InvalidFirstHop(ptr, (bindings.LDKSendError.InvalidFirstHop)raw_val);
+               }
+               if (raw_val.getClass() == bindings.LDKSendError.BufferFull.class) {
+                       return new BufferFull(ptr, (bindings.LDKSendError.BufferFull)raw_val);
+               }
+               assert false; return null; // Unreachable without extending the (internal) bindings interface
+       }
+
+       /**
+        * Errored computing onion message packet keys.
+        */
+       public final static class Secp256k1 extends SendError {
+               public final org.ldk.enums.Secp256k1Error secp256k1;
+               private Secp256k1(long ptr, bindings.LDKSendError.Secp256k1 obj) {
+                       super(null, ptr);
+                       this.secp256k1 = obj.secp256k1;
+               }
+       }
+       /**
+        * Because implementations such as Eclair will drop onion messages where the message packet
+        * exceeds 32834 bytes, we refuse to send messages where the packet exceeds this size.
+        */
+       public final static class TooBigPacket extends SendError {
+               private TooBigPacket(long ptr, bindings.LDKSendError.TooBigPacket obj) {
+                       super(null, ptr);
+               }
+       }
+       /**
+        * The provided [`Destination`] was an invalid [`BlindedRoute`], due to having fewer than two
+        * blinded hops.
+        */
+       public final static class TooFewBlindedHops extends SendError {
+               private TooFewBlindedHops(long ptr, bindings.LDKSendError.TooFewBlindedHops obj) {
+                       super(null, ptr);
+               }
+       }
+       /**
+        * Our next-hop peer was offline or does not support onion message forwarding.
+        */
+       public final static class InvalidFirstHop extends SendError {
+               private InvalidFirstHop(long ptr, bindings.LDKSendError.InvalidFirstHop obj) {
+                       super(null, ptr);
+               }
+       }
+       /**
+        * Our next-hop peer's buffer was full or our total outbound buffer was full.
+        */
+       public final static class BufferFull extends SendError {
+               private BufferFull(long ptr, bindings.LDKSendError.BufferFull obj) {
+                       super(null, ptr);
+               }
+       }
+       long clone_ptr() {
+               long ret = bindings.SendError_clone_ptr(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       /**
+        * Creates a copy of the SendError
+        */
+       public SendError clone() {
+               long ret = bindings.SendError_clone(this.ptr);
+               Reference.reachabilityFence(this);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.SendError ret_hu_conv = org.ldk.structs.SendError.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Utility method to constructs a new Secp256k1-variant SendError
+        */
+       public static SendError secp256k1(org.ldk.enums.Secp256k1Error a) {
+               long ret = bindings.SendError_secp256k1(a);
+               Reference.reachabilityFence(a);
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.SendError ret_hu_conv = org.ldk.structs.SendError.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Utility method to constructs a new TooBigPacket-variant SendError
+        */
+       public static SendError too_big_packet() {
+               long ret = bindings.SendError_too_big_packet();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.SendError ret_hu_conv = org.ldk.structs.SendError.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Utility method to constructs a new TooFewBlindedHops-variant SendError
+        */
+       public static SendError too_few_blinded_hops() {
+               long ret = bindings.SendError_too_few_blinded_hops();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.SendError ret_hu_conv = org.ldk.structs.SendError.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Utility method to constructs a new InvalidFirstHop-variant SendError
+        */
+       public static SendError invalid_first_hop() {
+               long ret = bindings.SendError_invalid_first_hop();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.SendError ret_hu_conv = org.ldk.structs.SendError.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+       /**
+        * Utility method to constructs a new BufferFull-variant SendError
+        */
+       public static SendError buffer_full() {
+               long ret = bindings.SendError_buffer_full();
+               if (ret >= 0 && ret <= 4096) { return null; }
+               org.ldk.structs.SendError ret_hu_conv = org.ldk.structs.SendError.constr_from_ptr(ret);
+               if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(ret_hu_conv); };
+               return ret_hu_conv;
+       }
+
+}
index d5a17cb941fd90c9de60a4a90d15e11d2106bcdf..b8e833004de65dce5f5afaf4de114b871b5050dc 100644 (file)
@@ -59,6 +59,18 @@ public class SignedRawInvoice extends CommonBase {
                return ret_hu_conv;
        }
 
+       /**
+        * Checks if two SignedRawInvoices contain equal inner contents.
+        */
+       public long hash() {
+               long ret = bindings.SignedRawInvoice_hash(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+       @Override public int hashCode() {
+               return (int)this.hash();
+       }
        /**
         * Disassembles the `SignedRawInvoice` into its three parts:
         * 1. raw invoice
@@ -90,8 +102,8 @@ public class SignedRawInvoice extends CommonBase {
        /**
         * The hash of the `RawInvoice` that was signed.
         */
-       public byte[] hash() {
-               byte[] ret = bindings.SignedRawInvoice_hash(this.ptr);
+       public byte[] signable_hash() {
+               byte[] ret = bindings.SignedRawInvoice_signable_hash(this.ptr);
                Reference.reachabilityFence(this);
                return ret;
        }
index f94a9b071e98f3c7dbd395f842d7a6691d7b794f..f745678a41efa5fb4f86638ca66a5c87778a566c 100644 (file)
@@ -13,7 +13,7 @@ import javax.annotation.Nullable;
  * 
  * Used to convey to a [`Filter`] such an output with a given spending condition. Any transaction
  * spending the output must be given to [`ChannelMonitor::block_connected`] either directly or via
- * the return value of [`Filter::register_output`].
+ * [`Confirm::transactions_confirmed`].
  * 
  * If `block_hash` is `Some`, this indicates the output was created in the corresponding block and
  * may have been spent there. See [`Filter::register_output`] for details.
diff --git a/src/main/java/org/ldk/structs/WriteableScore.java b/src/main/java/org/ldk/structs/WriteableScore.java
new file mode 100644 (file)
index 0000000..4e54310
--- /dev/null
@@ -0,0 +1,68 @@
+package org.ldk.structs;
+
+import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
+import java.util.Arrays;
+import java.lang.ref.Reference;
+import javax.annotation.Nullable;
+
+/**
+ * Refers to a scorer that is accessible under lock and also writeable to disk
+ * 
+ * We need this trait to be able to pass in a scorer to `lightning-background-processor` that will enable us to
+ * use the Persister to persist it.
+ */
+@SuppressWarnings("unchecked") // We correctly assign various generic arrays
+public class WriteableScore extends CommonBase {
+       final bindings.LDKWriteableScore bindings_instance;
+       WriteableScore(Object _dummy, long ptr) { super(ptr); bindings_instance = null; }
+       private WriteableScore(bindings.LDKWriteableScore arg, bindings.LDKLockableScore LockableScore) {
+               super(bindings.LDKWriteableScore_new(arg, LockableScore));
+               this.ptrs_to.add(arg);
+               this.ptrs_to.add(LockableScore);
+               this.bindings_instance = arg;
+       }
+       @Override @SuppressWarnings("deprecation")
+       protected void finalize() throws Throwable {
+               if (ptr != 0) { bindings.WriteableScore_free(ptr); } super.finalize();
+       }
+
+       public static interface WriteableScoreInterface {
+               /**
+                * Serialize the object into a byte array
+                */
+               byte[] write();
+       }
+       private static class LDKWriteableScoreHolder { WriteableScore held; }
+       public static WriteableScore new_impl(WriteableScoreInterface arg, LockableScore.LockableScoreInterface LockableScore_impl) {
+               final LDKWriteableScoreHolder impl_holder = new LDKWriteableScoreHolder();
+               impl_holder.held = new WriteableScore(new bindings.LDKWriteableScore() {
+                       @Override public byte[] write() {
+                               byte[] ret = arg.write();
+                               Reference.reachabilityFence(arg);
+                               return ret;
+                       }
+               }, LockableScore.new_impl(LockableScore_impl).bindings_instance);
+               return impl_holder.held;
+       }
+
+       /**
+        * Gets the underlying LockableScore.
+        */
+       public LockableScore get_lockable_score() {
+               LockableScore res = new LockableScore(null, bindings.LDKWriteableScore_get_LockableScore(this.ptr));
+               this.ptrs_to.add(res);
+               return res;
+       }
+
+       /**
+        * Serialize the object into a byte array
+        */
+       public byte[] write() {
+               byte[] ret = bindings.WriteableScore_write(this.ptr);
+               Reference.reachabilityFence(this);
+               return ret;
+       }
+
+}
index d62c42c7fff502fd5223d72c63c88ea6a2790257..feb725437b2217eb6d8dea5c267cb5240de4ce43 100644 (file)
@@ -941,6 +941,27 @@ static inline jclass LDKSiPrefix_to_java(JNIEnv *env, LDKSiPrefix val) {
        }
 }
 
+struct LDKThirtyTwoBytes BigEndianScalar_get_bytes (struct LDKBigEndianScalar* thing) {
+       LDKThirtyTwoBytes ret = { .data = *thing->big_endian_bytes };
+       return ret;
+}
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_BigEndianScalar_1get_1bytes(JNIEnv *env, jclass clz, int64_t thing) {
+       LDKBigEndianScalar* thing_conv = (LDKBigEndianScalar*)untag_ptr(thing);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, 32);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, BigEndianScalar_get_bytes(thing_conv).data);
+       return ret_arr;
+}
+
+static void BigEndianScalar_free (struct LDKBigEndianScalar thing) {}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BigEndianScalar_1free(JNIEnv *env, jclass clz, int64_t thing) {
+       if (!ptr_is_owned(thing)) return;
+       void* thing_ptr = untag_ptr(thing);
+       CHECK_ACCESS(thing_ptr);
+       LDKBigEndianScalar thing_conv = *(LDKBigEndianScalar*)(thing_ptr);
+       FREE(untag_ptr(thing));
+       BigEndianScalar_free(thing_conv);
+}
+
 static jclass LDKBech32Error_MissingSeparator_class = NULL;
 static jmethodID LDKBech32Error_MissingSeparator_meth = NULL;
 static jclass LDKBech32Error_InvalidChecksum_class = NULL;
@@ -1041,6 +1062,85 @@ uint64_t TxOut_get_value (struct LDKTxOut* thing) {      return thing->value;}JNIEXPO
        return ret_conv;
 }
 
+static inline struct LDKBlindedRoute CResult_BlindedRouteNoneZ_get_ok(LDKCResult_BlindedRouteNoneZ *NONNULL_PTR owner){
+       LDKBlindedRoute ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedRouteNoneZ* owner_conv = (LDKCResult_BlindedRouteNoneZ*)untag_ptr(owner);
+       LDKBlindedRoute ret_var = CResult_BlindedRouteNoneZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline void CResult_BlindedRouteNoneZ_get_err(LDKCResult_BlindedRouteNoneZ *NONNULL_PTR owner){
+CHECK(!owner->result_ok);
+       return *owner->contents.err;
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedRouteNoneZ* owner_conv = (LDKCResult_BlindedRouteNoneZ*)untag_ptr(owner);
+       CResult_BlindedRouteNoneZ_get_err(owner_conv);
+}
+
+static inline struct LDKBlindedRoute CResult_BlindedRouteDecodeErrorZ_get_ok(LDKCResult_BlindedRouteDecodeErrorZ *NONNULL_PTR owner){
+       LDKBlindedRoute ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedRouteDecodeErrorZ* owner_conv = (LDKCResult_BlindedRouteDecodeErrorZ*)untag_ptr(owner);
+       LDKBlindedRoute ret_var = CResult_BlindedRouteDecodeErrorZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKDecodeError CResult_BlindedRouteDecodeErrorZ_get_err(LDKCResult_BlindedRouteDecodeErrorZ *NONNULL_PTR owner){
+       LDKDecodeError ret = *owner->contents.err;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedRouteDecodeErrorZ* owner_conv = (LDKCResult_BlindedRouteDecodeErrorZ*)untag_ptr(owner);
+       LDKDecodeError ret_var = CResult_BlindedRouteDecodeErrorZ_get_err(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKBlindedHop CResult_BlindedHopDecodeErrorZ_get_ok(LDKCResult_BlindedHopDecodeErrorZ *NONNULL_PTR owner){
+       LDKBlindedHop ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedHopDecodeErrorZ* owner_conv = (LDKCResult_BlindedHopDecodeErrorZ*)untag_ptr(owner);
+       LDKBlindedHop ret_var = CResult_BlindedHopDecodeErrorZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKDecodeError CResult_BlindedHopDecodeErrorZ_get_err(LDKCResult_BlindedHopDecodeErrorZ *NONNULL_PTR owner){
+       LDKDecodeError ret = *owner->contents.err;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedHopDecodeErrorZ* owner_conv = (LDKCResult_BlindedHopDecodeErrorZ*)untag_ptr(owner);
+       LDKDecodeError ret_var = CResult_BlindedHopDecodeErrorZ_get_err(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 static inline void CResult_NoneNoneZ_get_ok(LDKCResult_NoneNoneZ *NONNULL_PTR owner){
 CHECK(owner->result_ok);
        return *owner->contents.result;
@@ -1536,6 +1636,622 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ShutdownScriptInva
        return ret_ref;
 }
 
+static inline LDKCVec_RouteHopZ CVec_RouteHopZ_clone(const LDKCVec_RouteHopZ *orig) {
+       LDKCVec_RouteHopZ ret = { .data = MALLOC(sizeof(LDKRouteHop) * orig->datalen, "LDKCVec_RouteHopZ clone bytes"), .datalen = orig->datalen };
+       for (size_t i = 0; i < ret.datalen; i++) {
+               ret.data[i] = RouteHop_clone(&orig->data[i]);
+       }
+       return ret;
+}
+typedef struct LDKScore_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       jmethodID channel_penalty_msat_meth;
+       jmethodID payment_path_failed_meth;
+       jmethodID payment_path_successful_meth;
+       jmethodID probe_failed_meth;
+       jmethodID probe_successful_meth;
+       jmethodID write_meth;
+} LDKScore_JCalls;
+static void LDKScore_JCalls_free(void* this_arg) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+uint64_t channel_penalty_msat_LDKScore_jcall(const void* this_arg, uint64_t short_channel_id, const LDKNodeId * source, const LDKNodeId * target, LDKChannelUsage usage) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int64_t short_channel_id_conv = short_channel_id;
+       LDKNodeId source_var = *source;
+       int64_t source_ref = 0;
+       source_var = NodeId_clone(&source_var);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_var);
+       source_ref = tag_ptr(source_var.inner, source_var.is_owned);
+       LDKNodeId target_var = *target;
+       int64_t target_ref = 0;
+       target_var = NodeId_clone(&target_var);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_var);
+       target_ref = tag_ptr(target_var.inner, target_var.is_owned);
+       LDKChannelUsage usage_var = usage;
+       int64_t usage_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(usage_var);
+       usage_ref = tag_ptr(usage_var.inner, usage_var.is_owned);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       int64_t ret = (*env)->CallLongMethod(env, obj, j_calls->channel_penalty_msat_meth, short_channel_id_conv, source_ref, target_ref, usage_ref);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to channel_penalty_msat in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret;
+}
+void payment_path_failed_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       int64_t short_channel_id_conv = short_channel_id;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->payment_path_failed_meth, path_arr, short_channel_id_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to payment_path_failed in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void payment_path_successful_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->payment_path_successful_meth, path_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to payment_path_successful in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void probe_failed_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       int64_t short_channel_id_conv = short_channel_id;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->probe_failed_meth, path_arr, short_channel_id_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to probe_failed in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void probe_successful_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->probe_successful_meth, path_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to probe_successful in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+LDKCVec_u8Z write_LDKScore_jcall(const void* this_arg) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       int8_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->write_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to write in LDKScore from rust threw an exception.");
+       }
+       LDKCVec_u8Z ret_ref;
+       ret_ref.datalen = (*env)->GetArrayLength(env, ret);
+       ret_ref.data = MALLOC(ret_ref.datalen, "LDKCVec_u8Z Bytes");
+       (*env)->GetByteArrayRegion(env, ret, 0, ret_ref.datalen, ret_ref.data);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_ref;
+}
+static void LDKScore_JCalls_cloned(LDKScore* new_obj) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+}
+static inline LDKScore LDKScore_init (JNIEnv *env, jclass clz, jobject o) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKScore_JCalls *calls = MALLOC(sizeof(LDKScore_JCalls), "LDKScore_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->channel_penalty_msat_meth = (*env)->GetMethodID(env, c, "channel_penalty_msat", "(JJJJ)J");
+       CHECK(calls->channel_penalty_msat_meth != NULL);
+       calls->payment_path_failed_meth = (*env)->GetMethodID(env, c, "payment_path_failed", "([JJ)V");
+       CHECK(calls->payment_path_failed_meth != NULL);
+       calls->payment_path_successful_meth = (*env)->GetMethodID(env, c, "payment_path_successful", "([J)V");
+       CHECK(calls->payment_path_successful_meth != NULL);
+       calls->probe_failed_meth = (*env)->GetMethodID(env, c, "probe_failed", "([JJ)V");
+       CHECK(calls->probe_failed_meth != NULL);
+       calls->probe_successful_meth = (*env)->GetMethodID(env, c, "probe_successful", "([J)V");
+       CHECK(calls->probe_successful_meth != NULL);
+       calls->write_meth = (*env)->GetMethodID(env, c, "write", "()[B");
+       CHECK(calls->write_meth != NULL);
+
+       LDKScore ret = {
+               .this_arg = (void*) calls,
+               .channel_penalty_msat = channel_penalty_msat_LDKScore_jcall,
+               .payment_path_failed = payment_path_failed_LDKScore_jcall,
+               .payment_path_successful = payment_path_successful_LDKScore_jcall,
+               .probe_failed = probe_failed_LDKScore_jcall,
+               .probe_successful = probe_successful_LDKScore_jcall,
+               .write = write_LDKScore_jcall,
+               .free = LDKScore_JCalls_free,
+       };
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKScore_1new(JNIEnv *env, jclass clz, jobject o) {
+       LDKScore *res_ptr = MALLOC(sizeof(LDKScore), "LDKScore");
+       *res_ptr = LDKScore_init(env, clz, o);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Score_1channel_1penalty_1msat(JNIEnv *env, jclass clz, int64_t this_arg, int64_t short_channel_id, int64_t source, int64_t target, int64_t usage) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKNodeId source_conv;
+       source_conv.inner = untag_ptr(source);
+       source_conv.is_owned = ptr_is_owned(source);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_conv);
+       source_conv.is_owned = false;
+       LDKNodeId target_conv;
+       target_conv.inner = untag_ptr(target);
+       target_conv.is_owned = ptr_is_owned(target);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_conv);
+       target_conv.is_owned = false;
+       LDKChannelUsage usage_conv;
+       usage_conv.inner = untag_ptr(usage);
+       usage_conv.is_owned = ptr_is_owned(usage);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(usage_conv);
+       usage_conv = ChannelUsage_clone(&usage_conv);
+       int64_t ret_conv = (this_arg_conv->channel_penalty_msat)(this_arg_conv->this_arg, short_channel_id, &source_conv, &target_conv, usage_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->payment_path_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->payment_path_successful)(this_arg_conv->this_arg, path_constr);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->probe_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->probe_successful)(this_arg_conv->this_arg, path_constr);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_Score_1write(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_u8Z ret_var = (this_arg_conv->write)(this_arg_conv->this_arg);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+typedef struct LDKLockableScore_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       jmethodID lock_meth;
+} LDKLockableScore_JCalls;
+static void LDKLockableScore_JCalls_free(void* this_arg) {
+       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+LDKScore lock_LDKLockableScore_jcall(const void* this_arg) {
+       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->lock_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to lock in LDKLockableScore from rust threw an exception.");
+       }
+       void* ret_ptr = untag_ptr(ret);
+       CHECK_ACCESS(ret_ptr);
+       LDKScore ret_conv = *(LDKScore*)(ret_ptr);
+       if (ret_conv.free == LDKScore_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKScore_JCalls_cloned(&ret_conv);
+       }// WARNING: we may need a move here but no clone is available for LDKScore
+       
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+static void LDKLockableScore_JCalls_cloned(LDKLockableScore* new_obj) {
+       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+}
+static inline LDKLockableScore LDKLockableScore_init (JNIEnv *env, jclass clz, jobject o) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKLockableScore_JCalls *calls = MALLOC(sizeof(LDKLockableScore_JCalls), "LDKLockableScore_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->lock_meth = (*env)->GetMethodID(env, c, "lock", "()J");
+       CHECK(calls->lock_meth != NULL);
+
+       LDKLockableScore ret = {
+               .this_arg = (void*) calls,
+               .lock = lock_LDKLockableScore_jcall,
+               .free = LDKLockableScore_JCalls_free,
+       };
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKLockableScore_1new(JNIEnv *env, jclass clz, jobject o) {
+       LDKLockableScore *res_ptr = MALLOC(sizeof(LDKLockableScore), "LDKLockableScore");
+       *res_ptr = LDKLockableScore_init(env, clz, o);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LockableScore_1lock(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKLockableScore* this_arg_conv = (LDKLockableScore*)this_arg_ptr;
+       LDKScore* ret_ret = MALLOC(sizeof(LDKScore), "LDKScore");
+       *ret_ret = (this_arg_conv->lock)(this_arg_conv->this_arg);
+       return tag_ptr(ret_ret, true);
+}
+
+typedef struct LDKWriteableScore_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       LDKLockableScore_JCalls* LockableScore;
+       jmethodID write_meth;
+} LDKWriteableScore_JCalls;
+static void LDKWriteableScore_JCalls_free(void* this_arg) {
+       LDKWriteableScore_JCalls *j_calls = (LDKWriteableScore_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+LDKCVec_u8Z write_LDKWriteableScore_jcall(const void* this_arg) {
+       LDKWriteableScore_JCalls *j_calls = (LDKWriteableScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       int8_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->write_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to write in LDKWriteableScore from rust threw an exception.");
+       }
+       LDKCVec_u8Z ret_ref;
+       ret_ref.datalen = (*env)->GetArrayLength(env, ret);
+       ret_ref.data = MALLOC(ret_ref.datalen, "LDKCVec_u8Z Bytes");
+       (*env)->GetByteArrayRegion(env, ret, 0, ret_ref.datalen, ret_ref.data);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_ref;
+}
+static void LDKWriteableScore_JCalls_cloned(LDKWriteableScore* new_obj) {
+       LDKWriteableScore_JCalls *j_calls = (LDKWriteableScore_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+       atomic_fetch_add_explicit(&j_calls->LockableScore->refcnt, 1, memory_order_release);
+}
+static inline LDKWriteableScore LDKWriteableScore_init (JNIEnv *env, jclass clz, jobject o, jobject LockableScore) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKWriteableScore_JCalls *calls = MALLOC(sizeof(LDKWriteableScore_JCalls), "LDKWriteableScore_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->write_meth = (*env)->GetMethodID(env, c, "write", "()[B");
+       CHECK(calls->write_meth != NULL);
+
+       LDKWriteableScore ret = {
+               .this_arg = (void*) calls,
+               .write = write_LDKWriteableScore_jcall,
+               .free = LDKWriteableScore_JCalls_free,
+               .LockableScore = LDKLockableScore_init(env, clz, LockableScore),
+       };
+       calls->LockableScore = ret.LockableScore.this_arg;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKWriteableScore_1new(JNIEnv *env, jclass clz, jobject o, jobject LockableScore) {
+       LDKWriteableScore *res_ptr = MALLOC(sizeof(LDKWriteableScore), "LDKWriteableScore");
+       *res_ptr = LDKWriteableScore_init(env, clz, o, LockableScore);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKWriteableScore_1get_1LockableScore(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKWriteableScore *inp = (LDKWriteableScore *)untag_ptr(arg);
+       return tag_ptr(&inp->LockableScore, false);
+}
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_WriteableScore_1write(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKWriteableScore* this_arg_conv = (LDKWriteableScore*)this_arg_ptr;
+       LDKCVec_u8Z ret_var = (this_arg_conv->write)(this_arg_conv->this_arg);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+static jclass LDKCOption_WriteableScoreZ_Some_class = NULL;
+static jmethodID LDKCOption_WriteableScoreZ_Some_meth = NULL;
+static jclass LDKCOption_WriteableScoreZ_None_class = NULL;
+static jmethodID LDKCOption_WriteableScoreZ_None_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKCOption_1WriteableScoreZ_init (JNIEnv *env, jclass clz) {
+       LDKCOption_WriteableScoreZ_Some_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_WriteableScoreZ$Some"));
+       CHECK(LDKCOption_WriteableScoreZ_Some_class != NULL);
+       LDKCOption_WriteableScoreZ_Some_meth = (*env)->GetMethodID(env, LDKCOption_WriteableScoreZ_Some_class, "<init>", "(J)V");
+       CHECK(LDKCOption_WriteableScoreZ_Some_meth != NULL);
+       LDKCOption_WriteableScoreZ_None_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_WriteableScoreZ$None"));
+       CHECK(LDKCOption_WriteableScoreZ_None_class != NULL);
+       LDKCOption_WriteableScoreZ_None_meth = (*env)->GetMethodID(env, LDKCOption_WriteableScoreZ_None_class, "<init>", "()V");
+       CHECK(LDKCOption_WriteableScoreZ_None_meth != NULL);
+}
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1WriteableScoreZ_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKCOption_WriteableScoreZ *obj = (LDKCOption_WriteableScoreZ*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKCOption_WriteableScoreZ_Some: {
+                       LDKWriteableScore* some_ret = MALLOC(sizeof(LDKWriteableScore), "LDKWriteableScore");
+                       *some_ret = obj->some;
+                       // WARNING: We likely need to clone here, but no clone is available, so we just do it for Java instances
+                       if ((*some_ret).free == LDKWriteableScore_JCalls_free) {
+                               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+                               LDKWriteableScore_JCalls_cloned(&(*some_ret));
+                       }
+                       return (*env)->NewObject(env, LDKCOption_WriteableScoreZ_Some_class, LDKCOption_WriteableScoreZ_Some_meth, tag_ptr(some_ret, true));
+               }
+               case LDKCOption_WriteableScoreZ_None: {
+                       return (*env)->NewObject(env, LDKCOption_WriteableScoreZ_None_class, LDKCOption_WriteableScoreZ_None_meth);
+               }
+               default: abort();
+       }
+}
 static inline void CResult_NoneErrorZ_get_ok(LDKCResult_NoneErrorZ *NONNULL_PTR owner){
 CHECK(owner->result_ok);
        return *owner->contents.result;
@@ -1583,13 +2299,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RouteHopDecodeErro
        return ret_ref;
 }
 
-static inline LDKCVec_RouteHopZ CVec_RouteHopZ_clone(const LDKCVec_RouteHopZ *orig) {
-       LDKCVec_RouteHopZ ret = { .data = MALLOC(sizeof(LDKRouteHop) * orig->datalen, "LDKCVec_RouteHopZ clone bytes"), .datalen = orig->datalen };
-       for (size_t i = 0; i < ret.datalen; i++) {
-               ret.data[i] = RouteHop_clone(&orig->data[i]);
-       }
-       return ret;
-}
 static inline LDKCVec_CVec_RouteHopZZ CVec_CVec_RouteHopZZ_clone(const LDKCVec_CVec_RouteHopZZ *orig) {
        LDKCVec_CVec_RouteHopZZ ret = { .data = MALLOC(sizeof(LDKCVec_RouteHopZ) * orig->datalen, "LDKCVec_CVec_RouteHopZZ clone bytes"), .datalen = orig->datalen };
        for (size_t i = 0; i < ret.datalen; i++) {
@@ -2445,7 +3154,7 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKEvent_1ref_1from_1ptr(JN
                        (*env)->SetByteArrayRegion(env, payment_id_arr, 0, 32, obj->payment_path_failed.payment_id.data);
                        int8_tArray payment_hash_arr = (*env)->NewByteArray(env, 32);
                        (*env)->SetByteArrayRegion(env, payment_hash_arr, 0, 32, obj->payment_path_failed.payment_hash.data);
-                       jboolean rejected_by_dest_conv = obj->payment_path_failed.rejected_by_dest;
+                       jboolean payment_failed_permanently_conv = obj->payment_path_failed.payment_failed_permanently;
                        int64_t network_update_ref = tag_ptr(&obj->payment_path_failed.network_update, false);
                        jboolean all_paths_failed_conv = obj->payment_path_failed.all_paths_failed;
                        LDKCVec_RouteHopZ path_var = obj->payment_path_failed.path;
@@ -2465,7 +3174,7 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKEvent_1ref_1from_1ptr(JN
                        int64_t retry_ref = 0;
                        CHECK_INNER_FIELD_ACCESS_OR_NULL(retry_var);
                        retry_ref = tag_ptr(retry_var.inner, false);
-                       return (*env)->NewObject(env, LDKEvent_PaymentPathFailed_class, LDKEvent_PaymentPathFailed_meth, payment_id_arr, payment_hash_arr, rejected_by_dest_conv, network_update_ref, all_paths_failed_conv, path_arr, short_channel_id_ref, retry_ref);
+                       return (*env)->NewObject(env, LDKEvent_PaymentPathFailed_class, LDKEvent_PaymentPathFailed_meth, payment_id_arr, payment_hash_arr, payment_failed_permanently_conv, network_update_ref, all_paths_failed_conv, path_arr, short_channel_id_ref, retry_ref);
                }
                case LDKEvent_ProbeSuccessful: {
                        int8_tArray payment_id_arr = (*env)->NewByteArray(env, 32);
@@ -2727,10 +3436,10 @@ static jclass LDKMessageSendEvent_SendShutdown_class = NULL;
 static jmethodID LDKMessageSendEvent_SendShutdown_meth = NULL;
 static jclass LDKMessageSendEvent_SendChannelReestablish_class = NULL;
 static jmethodID LDKMessageSendEvent_SendChannelReestablish_meth = NULL;
+static jclass LDKMessageSendEvent_SendChannelAnnouncement_class = NULL;
+static jmethodID LDKMessageSendEvent_SendChannelAnnouncement_meth = NULL;
 static jclass LDKMessageSendEvent_BroadcastChannelAnnouncement_class = NULL;
 static jmethodID LDKMessageSendEvent_BroadcastChannelAnnouncement_meth = NULL;
-static jclass LDKMessageSendEvent_BroadcastNodeAnnouncement_class = NULL;
-static jmethodID LDKMessageSendEvent_BroadcastNodeAnnouncement_meth = NULL;
 static jclass LDKMessageSendEvent_BroadcastChannelUpdate_class = NULL;
 static jmethodID LDKMessageSendEvent_BroadcastChannelUpdate_meth = NULL;
 static jclass LDKMessageSendEvent_SendChannelUpdate_class = NULL;
@@ -2801,16 +3510,16 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKMessageSendEvent_init
        CHECK(LDKMessageSendEvent_SendChannelReestablish_class != NULL);
        LDKMessageSendEvent_SendChannelReestablish_meth = (*env)->GetMethodID(env, LDKMessageSendEvent_SendChannelReestablish_class, "<init>", "([BJ)V");
        CHECK(LDKMessageSendEvent_SendChannelReestablish_meth != NULL);
+       LDKMessageSendEvent_SendChannelAnnouncement_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKMessageSendEvent$SendChannelAnnouncement"));
+       CHECK(LDKMessageSendEvent_SendChannelAnnouncement_class != NULL);
+       LDKMessageSendEvent_SendChannelAnnouncement_meth = (*env)->GetMethodID(env, LDKMessageSendEvent_SendChannelAnnouncement_class, "<init>", "([BJJ)V");
+       CHECK(LDKMessageSendEvent_SendChannelAnnouncement_meth != NULL);
        LDKMessageSendEvent_BroadcastChannelAnnouncement_class =
                (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKMessageSendEvent$BroadcastChannelAnnouncement"));
        CHECK(LDKMessageSendEvent_BroadcastChannelAnnouncement_class != NULL);
        LDKMessageSendEvent_BroadcastChannelAnnouncement_meth = (*env)->GetMethodID(env, LDKMessageSendEvent_BroadcastChannelAnnouncement_class, "<init>", "(JJ)V");
        CHECK(LDKMessageSendEvent_BroadcastChannelAnnouncement_meth != NULL);
-       LDKMessageSendEvent_BroadcastNodeAnnouncement_class =
-               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKMessageSendEvent$BroadcastNodeAnnouncement"));
-       CHECK(LDKMessageSendEvent_BroadcastNodeAnnouncement_class != NULL);
-       LDKMessageSendEvent_BroadcastNodeAnnouncement_meth = (*env)->GetMethodID(env, LDKMessageSendEvent_BroadcastNodeAnnouncement_class, "<init>", "(J)V");
-       CHECK(LDKMessageSendEvent_BroadcastNodeAnnouncement_meth != NULL);
        LDKMessageSendEvent_BroadcastChannelUpdate_class =
                (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKMessageSendEvent$BroadcastChannelUpdate"));
        CHECK(LDKMessageSendEvent_BroadcastChannelUpdate_class != NULL);
@@ -2949,23 +3658,29 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKMessageSendEvent_1ref_1f
                        msg_ref = tag_ptr(msg_var.inner, false);
                        return (*env)->NewObject(env, LDKMessageSendEvent_SendChannelReestablish_class, LDKMessageSendEvent_SendChannelReestablish_meth, node_id_arr, msg_ref);
                }
-               case LDKMessageSendEvent_BroadcastChannelAnnouncement: {
-                       LDKChannelAnnouncement msg_var = obj->broadcast_channel_announcement.msg;
+               case LDKMessageSendEvent_SendChannelAnnouncement: {
+                       int8_tArray node_id_arr = (*env)->NewByteArray(env, 33);
+                       (*env)->SetByteArrayRegion(env, node_id_arr, 0, 33, obj->send_channel_announcement.node_id.compressed_form);
+                       LDKChannelAnnouncement msg_var = obj->send_channel_announcement.msg;
                        int64_t msg_ref = 0;
                        CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_var);
                        msg_ref = tag_ptr(msg_var.inner, false);
-                       LDKChannelUpdate update_msg_var = obj->broadcast_channel_announcement.update_msg;
+                       LDKChannelUpdate update_msg_var = obj->send_channel_announcement.update_msg;
                        int64_t update_msg_ref = 0;
                        CHECK_INNER_FIELD_ACCESS_OR_NULL(update_msg_var);
                        update_msg_ref = tag_ptr(update_msg_var.inner, false);
-                       return (*env)->NewObject(env, LDKMessageSendEvent_BroadcastChannelAnnouncement_class, LDKMessageSendEvent_BroadcastChannelAnnouncement_meth, msg_ref, update_msg_ref);
+                       return (*env)->NewObject(env, LDKMessageSendEvent_SendChannelAnnouncement_class, LDKMessageSendEvent_SendChannelAnnouncement_meth, node_id_arr, msg_ref, update_msg_ref);
                }
-               case LDKMessageSendEvent_BroadcastNodeAnnouncement: {
-                       LDKNodeAnnouncement msg_var = obj->broadcast_node_announcement.msg;
+               case LDKMessageSendEvent_BroadcastChannelAnnouncement: {
+                       LDKChannelAnnouncement msg_var = obj->broadcast_channel_announcement.msg;
                        int64_t msg_ref = 0;
                        CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_var);
                        msg_ref = tag_ptr(msg_var.inner, false);
-                       return (*env)->NewObject(env, LDKMessageSendEvent_BroadcastNodeAnnouncement_class, LDKMessageSendEvent_BroadcastNodeAnnouncement_meth, msg_ref);
+                       LDKChannelUpdate update_msg_var = obj->broadcast_channel_announcement.update_msg;
+                       int64_t update_msg_ref = 0;
+                       CHECK_INNER_FIELD_ACCESS_OR_NULL(update_msg_var);
+                       update_msg_ref = tag_ptr(update_msg_var.inner, false);
+                       return (*env)->NewObject(env, LDKMessageSendEvent_BroadcastChannelAnnouncement_class, LDKMessageSendEvent_BroadcastChannelAnnouncement_meth, msg_ref, update_msg_ref);
                }
                case LDKMessageSendEvent_BroadcastChannelUpdate: {
                        LDKChannelUpdate msg_var = obj->broadcast_channel_update.msg;
@@ -3232,37 +3947,6 @@ static inline LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ CVec_C3Tuple
        }
        return ret;
 }
-static jclass LDKCOption_C2Tuple_usizeTransactionZZ_Some_class = NULL;
-static jmethodID LDKCOption_C2Tuple_usizeTransactionZZ_Some_meth = NULL;
-static jclass LDKCOption_C2Tuple_usizeTransactionZZ_None_class = NULL;
-static jmethodID LDKCOption_C2Tuple_usizeTransactionZZ_None_meth = NULL;
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKCOption_1C2Tuple_1usizeTransactionZZ_init (JNIEnv *env, jclass clz) {
-       LDKCOption_C2Tuple_usizeTransactionZZ_Some_class =
-               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_C2Tuple_usizeTransactionZZ$Some"));
-       CHECK(LDKCOption_C2Tuple_usizeTransactionZZ_Some_class != NULL);
-       LDKCOption_C2Tuple_usizeTransactionZZ_Some_meth = (*env)->GetMethodID(env, LDKCOption_C2Tuple_usizeTransactionZZ_Some_class, "<init>", "(J)V");
-       CHECK(LDKCOption_C2Tuple_usizeTransactionZZ_Some_meth != NULL);
-       LDKCOption_C2Tuple_usizeTransactionZZ_None_class =
-               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_C2Tuple_usizeTransactionZZ$None"));
-       CHECK(LDKCOption_C2Tuple_usizeTransactionZZ_None_class != NULL);
-       LDKCOption_C2Tuple_usizeTransactionZZ_None_meth = (*env)->GetMethodID(env, LDKCOption_C2Tuple_usizeTransactionZZ_None_class, "<init>", "()V");
-       CHECK(LDKCOption_C2Tuple_usizeTransactionZZ_None_meth != NULL);
-}
-JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1C2Tuple_1usizeTransactionZZ_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKCOption_C2Tuple_usizeTransactionZZ *obj = (LDKCOption_C2Tuple_usizeTransactionZZ*)untag_ptr(ptr);
-       switch(obj->tag) {
-               case LDKCOption_C2Tuple_usizeTransactionZZ_Some: {
-                       LDKC2Tuple_usizeTransactionZ* some_conv = MALLOC(sizeof(LDKC2Tuple_usizeTransactionZ), "LDKC2Tuple_usizeTransactionZ");
-                       *some_conv = obj->some;
-                       *some_conv = C2Tuple_usizeTransactionZ_clone(some_conv);
-                       return (*env)->NewObject(env, LDKCOption_C2Tuple_usizeTransactionZZ_Some_class, LDKCOption_C2Tuple_usizeTransactionZZ_Some_meth, tag_ptr(some_conv, true));
-               }
-               case LDKCOption_C2Tuple_usizeTransactionZZ_None: {
-                       return (*env)->NewObject(env, LDKCOption_C2Tuple_usizeTransactionZZ_None_class, LDKCOption_C2Tuple_usizeTransactionZZ_None_meth);
-               }
-               default: abort();
-       }
-}
 static inline struct LDKFixedPenaltyScorer CResult_FixedPenaltyScorerDecodeErrorZ_get_ok(LDKCResult_FixedPenaltyScorerDecodeErrorZ *NONNULL_PTR owner){
        LDKFixedPenaltyScorer ret = *owner->contents.result;
        ret.is_owned = false;
@@ -3834,19 +4518,36 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C3Tuple_1ChannelAnnouncemen
        return ret_ref;
 }
 
-static inline LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(const LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *orig) {
-       LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret = { .data = MALLOC(sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ) * orig->datalen, "LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ clone bytes"), .datalen = orig->datalen };
-       for (size_t i = 0; i < ret.datalen; i++) {
-               ret.data[i] = C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_clone(&orig->data[i]);
-       }
-       return ret;
+static jclass LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class = NULL;
+static jmethodID LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_meth = NULL;
+static jclass LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class = NULL;
+static jmethodID LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKCOption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_init (JNIEnv *env, jclass clz) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ$Some"));
+       CHECK(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class != NULL);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_meth = (*env)->GetMethodID(env, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class, "<init>", "(J)V");
+       CHECK(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_meth != NULL);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ$None"));
+       CHECK(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class != NULL);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_meth = (*env)->GetMethodID(env, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class, "<init>", "()V");
+       CHECK(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_meth != NULL);
 }
-static inline LDKCVec_NodeAnnouncementZ CVec_NodeAnnouncementZ_clone(const LDKCVec_NodeAnnouncementZ *orig) {
-       LDKCVec_NodeAnnouncementZ ret = { .data = MALLOC(sizeof(LDKNodeAnnouncement) * orig->datalen, "LDKCVec_NodeAnnouncementZ clone bytes"), .datalen = orig->datalen };
-       for (size_t i = 0; i < ret.datalen; i++) {
-               ret.data[i] = NodeAnnouncement_clone(&orig->data[i]);
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *obj = (LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some: {
+                       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ* some_conv = MALLOC(sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ");
+                       *some_conv = obj->some;
+                       *some_conv = C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_clone(some_conv);
+                       return (*env)->NewObject(env, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_meth, tag_ptr(some_conv, true));
+               }
+               case LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None: {
+                       return (*env)->NewObject(env, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_meth);
+               }
+               default: abort();
        }
-       return ret;
 }
 static inline void CResult_NoneLightningErrorZ_get_ok(LDKCResult_NoneLightningErrorZ *NONNULL_PTR owner){
 CHECK(owner->result_ok);
@@ -4404,6 +5105,55 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeyNoneZ_1get_1
        CResult_SecretKeyNoneZ_get_err(owner_conv);
 }
 
+static jclass LDKCOption_ScalarZ_Some_class = NULL;
+static jmethodID LDKCOption_ScalarZ_Some_meth = NULL;
+static jclass LDKCOption_ScalarZ_None_class = NULL;
+static jmethodID LDKCOption_ScalarZ_None_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKCOption_1ScalarZ_init (JNIEnv *env, jclass clz) {
+       LDKCOption_ScalarZ_Some_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_ScalarZ$Some"));
+       CHECK(LDKCOption_ScalarZ_Some_class != NULL);
+       LDKCOption_ScalarZ_Some_meth = (*env)->GetMethodID(env, LDKCOption_ScalarZ_Some_class, "<init>", "(J)V");
+       CHECK(LDKCOption_ScalarZ_Some_meth != NULL);
+       LDKCOption_ScalarZ_None_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_ScalarZ$None"));
+       CHECK(LDKCOption_ScalarZ_None_class != NULL);
+       LDKCOption_ScalarZ_None_meth = (*env)->GetMethodID(env, LDKCOption_ScalarZ_None_class, "<init>", "()V");
+       CHECK(LDKCOption_ScalarZ_None_meth != NULL);
+}
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1ScalarZ_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKCOption_ScalarZ *obj = (LDKCOption_ScalarZ*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKCOption_ScalarZ_Some: {
+                       LDKBigEndianScalar* some_ref = &obj->some;
+                       return (*env)->NewObject(env, LDKCOption_ScalarZ_Some_class, LDKCOption_ScalarZ_Some_meth, tag_ptr(some_ref, false));
+               }
+               case LDKCOption_ScalarZ_None: {
+                       return (*env)->NewObject(env, LDKCOption_ScalarZ_None_class, LDKCOption_ScalarZ_None_meth);
+               }
+               default: abort();
+       }
+}
+static inline struct LDKThirtyTwoBytes CResult_SharedSecretNoneZ_get_ok(LDKCResult_SharedSecretNoneZ *NONNULL_PTR owner){
+CHECK(owner->result_ok);
+       return ThirtyTwoBytes_clone(&*owner->contents.result);
+}
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_SharedSecretNoneZ* owner_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(owner);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, 32);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, CResult_SharedSecretNoneZ_get_ok(owner_conv).data);
+       return ret_arr;
+}
+
+static inline void CResult_SharedSecretNoneZ_get_err(LDKCResult_SharedSecretNoneZ *NONNULL_PTR owner){
+CHECK(!owner->result_ok);
+       return *owner->contents.err;
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_SharedSecretNoneZ* owner_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(owner);
+       CResult_SharedSecretNoneZ_get_err(owner_conv);
+}
+
 typedef struct LDKBaseSign_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -6340,6 +7090,7 @@ typedef struct LDKKeysInterface_JCalls {
        JavaVM *vm;
        jweak o;
        jmethodID get_node_secret_meth;
+       jmethodID ecdh_meth;
        jmethodID get_destination_script_meth;
        jmethodID get_shutdown_scriptpubkey_meth;
        jmethodID get_channel_signer_meth;
@@ -6391,6 +7142,37 @@ LDKCResult_SecretKeyNoneZ get_node_secret_LDKKeysInterface_jcall(const void* thi
        }
        return ret_conv;
 }
+LDKCResult_SharedSecretNoneZ ecdh_LDKKeysInterface_jcall(const void* this_arg, LDKRecipient recipient, LDKPublicKey other_key, LDKCOption_ScalarZ tweak) {
+       LDKKeysInterface_JCalls *j_calls = (LDKKeysInterface_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jclass recipient_conv = LDKRecipient_to_java(env, recipient);
+       int8_tArray other_key_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, other_key_arr, 0, 33, other_key.compressed_form);
+       LDKCOption_ScalarZ *tweak_copy = MALLOC(sizeof(LDKCOption_ScalarZ), "LDKCOption_ScalarZ");
+       *tweak_copy = tweak;
+       int64_t tweak_ref = tag_ptr(tweak_copy, true);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->ecdh_meth, recipient_conv, other_key_arr, tweak_ref);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to ecdh in LDKKeysInterface from rust threw an exception.");
+       }
+       void* ret_ptr = untag_ptr(ret);
+       CHECK_ACCESS(ret_ptr);
+       LDKCResult_SharedSecretNoneZ ret_conv = *(LDKCResult_SharedSecretNoneZ*)(ret_ptr);
+       FREE(untag_ptr(ret));
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
 LDKCVec_u8Z get_destination_script_LDKKeysInterface_jcall(const void* this_arg) {
        LDKKeysInterface_JCalls *j_calls = (LDKKeysInterface_JCalls*) this_arg;
        JNIEnv *env;
@@ -6596,6 +7378,8 @@ static inline LDKKeysInterface LDKKeysInterface_init (JNIEnv *env, jclass clz, j
        calls->o = (*env)->NewWeakGlobalRef(env, o);
        calls->get_node_secret_meth = (*env)->GetMethodID(env, c, "get_node_secret", "(Lorg/ldk/enums/Recipient;)J");
        CHECK(calls->get_node_secret_meth != NULL);
+       calls->ecdh_meth = (*env)->GetMethodID(env, c, "ecdh", "(Lorg/ldk/enums/Recipient;[BJ)J");
+       CHECK(calls->ecdh_meth != NULL);
        calls->get_destination_script_meth = (*env)->GetMethodID(env, c, "get_destination_script", "()[B");
        CHECK(calls->get_destination_script_meth != NULL);
        calls->get_shutdown_scriptpubkey_meth = (*env)->GetMethodID(env, c, "get_shutdown_scriptpubkey", "()J");
@@ -6614,6 +7398,7 @@ static inline LDKKeysInterface LDKKeysInterface_init (JNIEnv *env, jclass clz, j
        LDKKeysInterface ret = {
                .this_arg = (void*) calls,
                .get_node_secret = get_node_secret_LDKKeysInterface_jcall,
+               .ecdh = ecdh_LDKKeysInterface_jcall,
                .get_destination_script = get_destination_script_LDKKeysInterface_jcall,
                .get_shutdown_scriptpubkey = get_shutdown_scriptpubkey_LDKKeysInterface_jcall,
                .get_channel_signer = get_channel_signer_LDKKeysInterface_jcall,
@@ -6640,6 +7425,23 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_KeysInterface_1get_1node_1s
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_KeysInterface_1ecdh(JNIEnv *env, jclass clz, int64_t this_arg, jclass recipient, int8_tArray other_key, int64_t tweak) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKKeysInterface* this_arg_conv = (LDKKeysInterface*)this_arg_ptr;
+       LDKRecipient recipient_conv = LDKRecipient_from_java(env, recipient);
+       LDKPublicKey other_key_ref;
+       CHECK((*env)->GetArrayLength(env, other_key) == 33);
+       (*env)->GetByteArrayRegion(env, other_key, 0, 33, other_key_ref.compressed_form);
+       void* tweak_ptr = untag_ptr(tweak);
+       CHECK_ACCESS(tweak_ptr);
+       LDKCOption_ScalarZ tweak_conv = *(LDKCOption_ScalarZ*)(tweak_ptr);
+       // WARNING: we may need a move here but no clone is available for LDKCOption_ScalarZ
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = (this_arg_conv->ecdh)(this_arg_conv->this_arg, recipient_conv, other_key_ref, tweak_conv);
+       return tag_ptr(ret_conv, true);
+}
+
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_KeysInterface_1get_1destination_1script(JNIEnv *env, jclass clz, int64_t this_arg) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
@@ -7192,6 +7994,34 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentIdPaymentEr
        return ret_ref;
 }
 
+static inline struct LDKInFlightHtlcs CResult_InFlightHtlcsDecodeErrorZ_get_ok(LDKCResult_InFlightHtlcsDecodeErrorZ *NONNULL_PTR owner){
+       LDKInFlightHtlcs ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_InFlightHtlcsDecodeErrorZ* owner_conv = (LDKCResult_InFlightHtlcsDecodeErrorZ*)untag_ptr(owner);
+       LDKInFlightHtlcs ret_var = CResult_InFlightHtlcsDecodeErrorZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKDecodeError CResult_InFlightHtlcsDecodeErrorZ_get_err(LDKCResult_InFlightHtlcsDecodeErrorZ *NONNULL_PTR owner){
+       LDKDecodeError ret = *owner->contents.err;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_InFlightHtlcsDecodeErrorZ* owner_conv = (LDKCResult_InFlightHtlcsDecodeErrorZ*)untag_ptr(owner);
+       LDKDecodeError ret_var = CResult_InFlightHtlcsDecodeErrorZ_get_err(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 static jclass LDKParseError_Bech32Error_class = NULL;
 static jmethodID LDKParseError_Bech32Error_meth = NULL;
 static jclass LDKParseError_ParseAmountError_class = NULL;
@@ -7971,8 +8801,12 @@ static jclass LDKBalance_ClaimableAwaitingConfirmations_class = NULL;
 static jmethodID LDKBalance_ClaimableAwaitingConfirmations_meth = NULL;
 static jclass LDKBalance_ContentiousClaimable_class = NULL;
 static jmethodID LDKBalance_ContentiousClaimable_meth = NULL;
-static jclass LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class = NULL;
-static jmethodID LDKBalance_MaybeClaimableHTLCAwaitingTimeout_meth = NULL;
+static jclass LDKBalance_MaybeTimeoutClaimableHTLC_class = NULL;
+static jmethodID LDKBalance_MaybeTimeoutClaimableHTLC_meth = NULL;
+static jclass LDKBalance_MaybePreimageClaimableHTLC_class = NULL;
+static jmethodID LDKBalance_MaybePreimageClaimableHTLC_meth = NULL;
+static jclass LDKBalance_CounterpartyRevokedOutputClaimable_class = NULL;
+static jmethodID LDKBalance_CounterpartyRevokedOutputClaimable_meth = NULL;
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKBalance_init (JNIEnv *env, jclass clz) {
        LDKBalance_ClaimableOnChannelClose_class =
                (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$ClaimableOnChannelClose"));
@@ -7989,11 +8823,21 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKBalance_init (JNIEnv *
        CHECK(LDKBalance_ContentiousClaimable_class != NULL);
        LDKBalance_ContentiousClaimable_meth = (*env)->GetMethodID(env, LDKBalance_ContentiousClaimable_class, "<init>", "(JI)V");
        CHECK(LDKBalance_ContentiousClaimable_meth != NULL);
-       LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class =
-               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$MaybeClaimableHTLCAwaitingTimeout"));
-       CHECK(LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class != NULL);
-       LDKBalance_MaybeClaimableHTLCAwaitingTimeout_meth = (*env)->GetMethodID(env, LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class, "<init>", "(JI)V");
-       CHECK(LDKBalance_MaybeClaimableHTLCAwaitingTimeout_meth != NULL);
+       LDKBalance_MaybeTimeoutClaimableHTLC_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$MaybeTimeoutClaimableHTLC"));
+       CHECK(LDKBalance_MaybeTimeoutClaimableHTLC_class != NULL);
+       LDKBalance_MaybeTimeoutClaimableHTLC_meth = (*env)->GetMethodID(env, LDKBalance_MaybeTimeoutClaimableHTLC_class, "<init>", "(JI)V");
+       CHECK(LDKBalance_MaybeTimeoutClaimableHTLC_meth != NULL);
+       LDKBalance_MaybePreimageClaimableHTLC_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$MaybePreimageClaimableHTLC"));
+       CHECK(LDKBalance_MaybePreimageClaimableHTLC_class != NULL);
+       LDKBalance_MaybePreimageClaimableHTLC_meth = (*env)->GetMethodID(env, LDKBalance_MaybePreimageClaimableHTLC_class, "<init>", "(JI)V");
+       CHECK(LDKBalance_MaybePreimageClaimableHTLC_meth != NULL);
+       LDKBalance_CounterpartyRevokedOutputClaimable_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$CounterpartyRevokedOutputClaimable"));
+       CHECK(LDKBalance_CounterpartyRevokedOutputClaimable_class != NULL);
+       LDKBalance_CounterpartyRevokedOutputClaimable_meth = (*env)->GetMethodID(env, LDKBalance_CounterpartyRevokedOutputClaimable_class, "<init>", "(J)V");
+       CHECK(LDKBalance_CounterpartyRevokedOutputClaimable_meth != NULL);
 }
 JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKBalance_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
        LDKBalance *obj = (LDKBalance*)untag_ptr(ptr);
@@ -8012,10 +8856,19 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKBalance_1ref_1from_1ptr(
                        int32_t timeout_height_conv = obj->contentious_claimable.timeout_height;
                        return (*env)->NewObject(env, LDKBalance_ContentiousClaimable_class, LDKBalance_ContentiousClaimable_meth, claimable_amount_satoshis_conv, timeout_height_conv);
                }
-               case LDKBalance_MaybeClaimableHTLCAwaitingTimeout: {
-                       int64_t claimable_amount_satoshis_conv = obj->maybe_claimable_htlc_awaiting_timeout.claimable_amount_satoshis;
-                       int32_t claimable_height_conv = obj->maybe_claimable_htlc_awaiting_timeout.claimable_height;
-                       return (*env)->NewObject(env, LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class, LDKBalance_MaybeClaimableHTLCAwaitingTimeout_meth, claimable_amount_satoshis_conv, claimable_height_conv);
+               case LDKBalance_MaybeTimeoutClaimableHTLC: {
+                       int64_t claimable_amount_satoshis_conv = obj->maybe_timeout_claimable_htlc.claimable_amount_satoshis;
+                       int32_t claimable_height_conv = obj->maybe_timeout_claimable_htlc.claimable_height;
+                       return (*env)->NewObject(env, LDKBalance_MaybeTimeoutClaimableHTLC_class, LDKBalance_MaybeTimeoutClaimableHTLC_meth, claimable_amount_satoshis_conv, claimable_height_conv);
+               }
+               case LDKBalance_MaybePreimageClaimableHTLC: {
+                       int64_t claimable_amount_satoshis_conv = obj->maybe_preimage_claimable_htlc.claimable_amount_satoshis;
+                       int32_t expiry_height_conv = obj->maybe_preimage_claimable_htlc.expiry_height;
+                       return (*env)->NewObject(env, LDKBalance_MaybePreimageClaimableHTLC_class, LDKBalance_MaybePreimageClaimableHTLC_meth, claimable_amount_satoshis_conv, expiry_height_conv);
+               }
+               case LDKBalance_CounterpartyRevokedOutputClaimable: {
+                       int64_t claimable_amount_satoshis_conv = obj->counterparty_revoked_output_claimable.claimable_amount_satoshis;
+                       return (*env)->NewObject(env, LDKBalance_CounterpartyRevokedOutputClaimable_class, LDKBalance_CounterpartyRevokedOutputClaimable_meth, claimable_amount_satoshis_conv);
                }
                default: abort();
        }
@@ -8182,6 +9035,86 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErro
        return ret_ref;
 }
 
+static jclass LDKSendError_Secp256k1_class = NULL;
+static jmethodID LDKSendError_Secp256k1_meth = NULL;
+static jclass LDKSendError_TooBigPacket_class = NULL;
+static jmethodID LDKSendError_TooBigPacket_meth = NULL;
+static jclass LDKSendError_TooFewBlindedHops_class = NULL;
+static jmethodID LDKSendError_TooFewBlindedHops_meth = NULL;
+static jclass LDKSendError_InvalidFirstHop_class = NULL;
+static jmethodID LDKSendError_InvalidFirstHop_meth = NULL;
+static jclass LDKSendError_BufferFull_class = NULL;
+static jmethodID LDKSendError_BufferFull_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKSendError_init (JNIEnv *env, jclass clz) {
+       LDKSendError_Secp256k1_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$Secp256k1"));
+       CHECK(LDKSendError_Secp256k1_class != NULL);
+       LDKSendError_Secp256k1_meth = (*env)->GetMethodID(env, LDKSendError_Secp256k1_class, "<init>", "(Lorg/ldk/enums/Secp256k1Error;)V");
+       CHECK(LDKSendError_Secp256k1_meth != NULL);
+       LDKSendError_TooBigPacket_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$TooBigPacket"));
+       CHECK(LDKSendError_TooBigPacket_class != NULL);
+       LDKSendError_TooBigPacket_meth = (*env)->GetMethodID(env, LDKSendError_TooBigPacket_class, "<init>", "()V");
+       CHECK(LDKSendError_TooBigPacket_meth != NULL);
+       LDKSendError_TooFewBlindedHops_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$TooFewBlindedHops"));
+       CHECK(LDKSendError_TooFewBlindedHops_class != NULL);
+       LDKSendError_TooFewBlindedHops_meth = (*env)->GetMethodID(env, LDKSendError_TooFewBlindedHops_class, "<init>", "()V");
+       CHECK(LDKSendError_TooFewBlindedHops_meth != NULL);
+       LDKSendError_InvalidFirstHop_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$InvalidFirstHop"));
+       CHECK(LDKSendError_InvalidFirstHop_class != NULL);
+       LDKSendError_InvalidFirstHop_meth = (*env)->GetMethodID(env, LDKSendError_InvalidFirstHop_class, "<init>", "()V");
+       CHECK(LDKSendError_InvalidFirstHop_meth != NULL);
+       LDKSendError_BufferFull_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$BufferFull"));
+       CHECK(LDKSendError_BufferFull_class != NULL);
+       LDKSendError_BufferFull_meth = (*env)->GetMethodID(env, LDKSendError_BufferFull_class, "<init>", "()V");
+       CHECK(LDKSendError_BufferFull_meth != NULL);
+}
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKSendError_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKSendError *obj = (LDKSendError*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKSendError_Secp256k1: {
+                       jclass secp256k1_conv = LDKSecp256k1Error_to_java(env, obj->secp256k1);
+                       return (*env)->NewObject(env, LDKSendError_Secp256k1_class, LDKSendError_Secp256k1_meth, secp256k1_conv);
+               }
+               case LDKSendError_TooBigPacket: {
+                       return (*env)->NewObject(env, LDKSendError_TooBigPacket_class, LDKSendError_TooBigPacket_meth);
+               }
+               case LDKSendError_TooFewBlindedHops: {
+                       return (*env)->NewObject(env, LDKSendError_TooFewBlindedHops_class, LDKSendError_TooFewBlindedHops_meth);
+               }
+               case LDKSendError_InvalidFirstHop: {
+                       return (*env)->NewObject(env, LDKSendError_InvalidFirstHop_class, LDKSendError_InvalidFirstHop_meth);
+               }
+               case LDKSendError_BufferFull: {
+                       return (*env)->NewObject(env, LDKSendError_BufferFull_class, LDKSendError_BufferFull_meth);
+               }
+               default: abort();
+       }
+}
+static inline void CResult_NoneSendErrorZ_get_ok(LDKCResult_NoneSendErrorZ *NONNULL_PTR owner){
+CHECK(owner->result_ok);
+       return *owner->contents.result;
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_NoneSendErrorZ* owner_conv = (LDKCResult_NoneSendErrorZ*)untag_ptr(owner);
+       CResult_NoneSendErrorZ_get_ok(owner_conv);
+}
+
+static inline struct LDKSendError CResult_NoneSendErrorZ_get_err(LDKCResult_NoneSendErrorZ *NONNULL_PTR owner){
+CHECK(!owner->result_ok);
+       return SendError_clone(&*owner->contents.err);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_NoneSendErrorZ* owner_conv = (LDKCResult_NoneSendErrorZ*)untag_ptr(owner);
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = CResult_NoneSendErrorZ_get_err(owner_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
 static jclass LDKGraphSyncError_DecodeError_class = NULL;
 static jmethodID LDKGraphSyncError_DecodeError_meth = NULL;
 static jclass LDKGraphSyncError_LightningError_class = NULL;
@@ -8798,6 +9731,34 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecod
        return ret_ref;
 }
 
+static inline struct LDKOnionMessage CResult_OnionMessageDecodeErrorZ_get_ok(LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR owner){
+       LDKOnionMessage ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_OnionMessageDecodeErrorZ* owner_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(owner);
+       LDKOnionMessage ret_var = CResult_OnionMessageDecodeErrorZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKDecodeError CResult_OnionMessageDecodeErrorZ_get_err(LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR owner){
+       LDKDecodeError ret = *owner->contents.err;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_OnionMessageDecodeErrorZ* owner_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(owner);
+       LDKDecodeError ret_var = CResult_OnionMessageDecodeErrorZ_get_err(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 static inline struct LDKPing CResult_PingDecodeErrorZ_get_ok(LDKCResult_PingDecodeErrorZ *NONNULL_PTR owner){
        LDKPing ret = *owner->contents.result;
        ret.is_owned = false;
@@ -9329,7 +10290,7 @@ void register_tx_LDKFilter_jcall(const void* this_arg, const uint8_t (* txid)[32
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
 }
-LDKCOption_C2Tuple_usizeTransactionZZ register_output_LDKFilter_jcall(const void* this_arg, LDKWatchedOutput output) {
+void register_output_LDKFilter_jcall(const void* this_arg, LDKWatchedOutput output) {
        LDKFilter_JCalls *j_calls = (LDKFilter_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -9344,19 +10305,14 @@ LDKCOption_C2Tuple_usizeTransactionZZ register_output_LDKFilter_jcall(const void
        output_ref = tag_ptr(output_var.inner, output_var.is_owned);
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->register_output_meth, output_ref);
+       (*env)->CallVoidMethod(env, obj, j_calls->register_output_meth, output_ref);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
                (*env)->FatalError(env, "A call to register_output in LDKFilter from rust threw an exception.");
        }
-       void* ret_ptr = untag_ptr(ret);
-       CHECK_ACCESS(ret_ptr);
-       LDKCOption_C2Tuple_usizeTransactionZZ ret_conv = *(LDKCOption_C2Tuple_usizeTransactionZZ*)(ret_ptr);
-       FREE(untag_ptr(ret));
        if (get_jenv_res == JNI_EDETACHED) {
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
-       return ret_conv;
 }
 static void LDKFilter_JCalls_cloned(LDKFilter* new_obj) {
        LDKFilter_JCalls *j_calls = (LDKFilter_JCalls*) new_obj->this_arg;
@@ -9371,7 +10327,7 @@ static inline LDKFilter LDKFilter_init (JNIEnv *env, jclass clz, jobject o) {
        calls->o = (*env)->NewWeakGlobalRef(env, o);
        calls->register_tx_meth = (*env)->GetMethodID(env, c, "register_tx", "([B[B)V");
        CHECK(calls->register_tx_meth != NULL);
-       calls->register_output_meth = (*env)->GetMethodID(env, c, "register_output", "(J)J");
+       calls->register_output_meth = (*env)->GetMethodID(env, c, "register_output", "(J)V");
        CHECK(calls->register_output_meth != NULL);
 
        LDKFilter ret = {
@@ -9402,7 +10358,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Filter_1register_1tx(JNIEnv *e
        (*env)->ReleaseByteArrayElements(env, script_pubkey, (int8_t*)script_pubkey_ref.data, 0);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Filter_1register_1output(JNIEnv *env, jclass clz, int64_t this_arg, int64_t output) {
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Filter_1register_1output(JNIEnv *env, jclass clz, int64_t this_arg, int64_t output) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKFilter* this_arg_conv = (LDKFilter*)this_arg_ptr;
@@ -9411,10 +10367,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Filter_1register_1output(JN
        output_conv.is_owned = ptr_is_owned(output);
        CHECK_INNER_FIELD_ACCESS_OR_NULL(output_conv);
        output_conv = WatchedOutput_clone(&output_conv);
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = (this_arg_conv->register_output)(this_arg_conv->this_arg, output_conv);
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
+       (this_arg_conv->register_output)(this_arg_conv->this_arg, output_conv);
 }
 
 static jclass LDKCOption_FilterZ_Some_class = NULL;
@@ -9587,6 +10540,96 @@ JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_MessageSendEventsProvi
        return ret_arr;
 }
 
+typedef struct LDKOnionMessageProvider_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       jmethodID next_onion_message_for_peer_meth;
+} LDKOnionMessageProvider_JCalls;
+static void LDKOnionMessageProvider_JCalls_free(void* this_arg) {
+       LDKOnionMessageProvider_JCalls *j_calls = (LDKOnionMessageProvider_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+LDKOnionMessage next_onion_message_for_peer_LDKOnionMessageProvider_jcall(const void* this_arg, LDKPublicKey peer_node_id) {
+       LDKOnionMessageProvider_JCalls *j_calls = (LDKOnionMessageProvider_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray peer_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, peer_node_id_arr, 0, 33, peer_node_id.compressed_form);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->next_onion_message_for_peer_meth, peer_node_id_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to next_onion_message_for_peer in LDKOnionMessageProvider from rust threw an exception.");
+       }
+       LDKOnionMessage ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+static void LDKOnionMessageProvider_JCalls_cloned(LDKOnionMessageProvider* new_obj) {
+       LDKOnionMessageProvider_JCalls *j_calls = (LDKOnionMessageProvider_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+}
+static inline LDKOnionMessageProvider LDKOnionMessageProvider_init (JNIEnv *env, jclass clz, jobject o) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKOnionMessageProvider_JCalls *calls = MALLOC(sizeof(LDKOnionMessageProvider_JCalls), "LDKOnionMessageProvider_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->next_onion_message_for_peer_meth = (*env)->GetMethodID(env, c, "next_onion_message_for_peer", "([B)J");
+       CHECK(calls->next_onion_message_for_peer_meth != NULL);
+
+       LDKOnionMessageProvider ret = {
+               .this_arg = (void*) calls,
+               .next_onion_message_for_peer = next_onion_message_for_peer_LDKOnionMessageProvider_jcall,
+               .free = LDKOnionMessageProvider_JCalls_free,
+       };
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKOnionMessageProvider_1new(JNIEnv *env, jclass clz, jobject o) {
+       LDKOnionMessageProvider *res_ptr = MALLOC(sizeof(LDKOnionMessageProvider), "LDKOnionMessageProvider");
+       *res_ptr = LDKOnionMessageProvider_init(env, clz, o);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessageProvider_1next_1onion_1message_1for_1peer(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray peer_node_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageProvider* this_arg_conv = (LDKOnionMessageProvider*)this_arg_ptr;
+       LDKPublicKey peer_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, peer_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, peer_node_id, 0, 33, peer_node_id_ref.compressed_form);
+       LDKOnionMessage ret_var = (this_arg_conv->next_onion_message_for_peer)(this_arg_conv->this_arg, peer_node_id_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 typedef struct LDKEventHandler_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -9752,400 +10795,6 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_EventsProvider_1process_1pendi
        (this_arg_conv->process_pending_events)(this_arg_conv->this_arg, handler_conv);
 }
 
-typedef struct LDKScore_JCalls {
-       atomic_size_t refcnt;
-       JavaVM *vm;
-       jweak o;
-       jmethodID channel_penalty_msat_meth;
-       jmethodID payment_path_failed_meth;
-       jmethodID payment_path_successful_meth;
-       jmethodID probe_failed_meth;
-       jmethodID probe_successful_meth;
-       jmethodID write_meth;
-} LDKScore_JCalls;
-static void LDKScore_JCalls_free(void* this_arg) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
-               JNIEnv *env;
-               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-               if (get_jenv_res == JNI_EDETACHED) {
-                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-               } else {
-                       DO_ASSERT(get_jenv_res == JNI_OK);
-               }
-               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
-               if (get_jenv_res == JNI_EDETACHED) {
-                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-               }
-               FREE(j_calls);
-       }
-}
-uint64_t channel_penalty_msat_LDKScore_jcall(const void* this_arg, uint64_t short_channel_id, const LDKNodeId * source, const LDKNodeId * target, LDKChannelUsage usage) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       int64_t short_channel_id_conv = short_channel_id;
-       LDKNodeId source_var = *source;
-       int64_t source_ref = 0;
-       source_var = NodeId_clone(&source_var);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_var);
-       source_ref = tag_ptr(source_var.inner, source_var.is_owned);
-       LDKNodeId target_var = *target;
-       int64_t target_ref = 0;
-       target_var = NodeId_clone(&target_var);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_var);
-       target_ref = tag_ptr(target_var.inner, target_var.is_owned);
-       LDKChannelUsage usage_var = usage;
-       int64_t usage_ref = 0;
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(usage_var);
-       usage_ref = tag_ptr(usage_var.inner, usage_var.is_owned);
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       int64_t ret = (*env)->CallLongMethod(env, obj, j_calls->channel_penalty_msat_meth, short_channel_id_conv, source_ref, target_ref, usage_ref);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to channel_penalty_msat in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-       return ret;
-}
-void payment_path_failed_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       LDKCVec_RouteHopZ path_var = path;
-       int64_tArray path_arr = NULL;
-       path_arr = (*env)->NewLongArray(env, path_var.datalen);
-       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
-       for (size_t k = 0; k < path_var.datalen; k++) {
-               LDKRouteHop path_conv_10_var = path_var.data[k];
-               int64_t path_conv_10_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
-               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
-               path_arr_ptr[k] = path_conv_10_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
-       FREE(path_var.data);
-       int64_t short_channel_id_conv = short_channel_id;
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       (*env)->CallVoidMethod(env, obj, j_calls->payment_path_failed_meth, path_arr, short_channel_id_conv);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to payment_path_failed in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-}
-void payment_path_successful_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       LDKCVec_RouteHopZ path_var = path;
-       int64_tArray path_arr = NULL;
-       path_arr = (*env)->NewLongArray(env, path_var.datalen);
-       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
-       for (size_t k = 0; k < path_var.datalen; k++) {
-               LDKRouteHop path_conv_10_var = path_var.data[k];
-               int64_t path_conv_10_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
-               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
-               path_arr_ptr[k] = path_conv_10_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
-       FREE(path_var.data);
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       (*env)->CallVoidMethod(env, obj, j_calls->payment_path_successful_meth, path_arr);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to payment_path_successful in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-}
-void probe_failed_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       LDKCVec_RouteHopZ path_var = path;
-       int64_tArray path_arr = NULL;
-       path_arr = (*env)->NewLongArray(env, path_var.datalen);
-       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
-       for (size_t k = 0; k < path_var.datalen; k++) {
-               LDKRouteHop path_conv_10_var = path_var.data[k];
-               int64_t path_conv_10_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
-               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
-               path_arr_ptr[k] = path_conv_10_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
-       FREE(path_var.data);
-       int64_t short_channel_id_conv = short_channel_id;
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       (*env)->CallVoidMethod(env, obj, j_calls->probe_failed_meth, path_arr, short_channel_id_conv);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to probe_failed in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-}
-void probe_successful_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       LDKCVec_RouteHopZ path_var = path;
-       int64_tArray path_arr = NULL;
-       path_arr = (*env)->NewLongArray(env, path_var.datalen);
-       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
-       for (size_t k = 0; k < path_var.datalen; k++) {
-               LDKRouteHop path_conv_10_var = path_var.data[k];
-               int64_t path_conv_10_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
-               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
-               path_arr_ptr[k] = path_conv_10_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
-       FREE(path_var.data);
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       (*env)->CallVoidMethod(env, obj, j_calls->probe_successful_meth, path_arr);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to probe_successful in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-}
-LDKCVec_u8Z write_LDKScore_jcall(const void* this_arg) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       int8_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->write_meth);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to write in LDKScore from rust threw an exception.");
-       }
-       LDKCVec_u8Z ret_ref;
-       ret_ref.datalen = (*env)->GetArrayLength(env, ret);
-       ret_ref.data = MALLOC(ret_ref.datalen, "LDKCVec_u8Z Bytes");
-       (*env)->GetByteArrayRegion(env, ret, 0, ret_ref.datalen, ret_ref.data);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-       return ret_ref;
-}
-static void LDKScore_JCalls_cloned(LDKScore* new_obj) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) new_obj->this_arg;
-       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
-}
-static inline LDKScore LDKScore_init (JNIEnv *env, jclass clz, jobject o) {
-       jclass c = (*env)->GetObjectClass(env, o);
-       CHECK(c != NULL);
-       LDKScore_JCalls *calls = MALLOC(sizeof(LDKScore_JCalls), "LDKScore_JCalls");
-       atomic_init(&calls->refcnt, 1);
-       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
-       calls->o = (*env)->NewWeakGlobalRef(env, o);
-       calls->channel_penalty_msat_meth = (*env)->GetMethodID(env, c, "channel_penalty_msat", "(JJJJ)J");
-       CHECK(calls->channel_penalty_msat_meth != NULL);
-       calls->payment_path_failed_meth = (*env)->GetMethodID(env, c, "payment_path_failed", "([JJ)V");
-       CHECK(calls->payment_path_failed_meth != NULL);
-       calls->payment_path_successful_meth = (*env)->GetMethodID(env, c, "payment_path_successful", "([J)V");
-       CHECK(calls->payment_path_successful_meth != NULL);
-       calls->probe_failed_meth = (*env)->GetMethodID(env, c, "probe_failed", "([JJ)V");
-       CHECK(calls->probe_failed_meth != NULL);
-       calls->probe_successful_meth = (*env)->GetMethodID(env, c, "probe_successful", "([J)V");
-       CHECK(calls->probe_successful_meth != NULL);
-       calls->write_meth = (*env)->GetMethodID(env, c, "write", "()[B");
-       CHECK(calls->write_meth != NULL);
-
-       LDKScore ret = {
-               .this_arg = (void*) calls,
-               .channel_penalty_msat = channel_penalty_msat_LDKScore_jcall,
-               .payment_path_failed = payment_path_failed_LDKScore_jcall,
-               .payment_path_successful = payment_path_successful_LDKScore_jcall,
-               .probe_failed = probe_failed_LDKScore_jcall,
-               .probe_successful = probe_successful_LDKScore_jcall,
-               .write = write_LDKScore_jcall,
-               .free = LDKScore_JCalls_free,
-       };
-       return ret;
-}
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKScore_1new(JNIEnv *env, jclass clz, jobject o) {
-       LDKScore *res_ptr = MALLOC(sizeof(LDKScore), "LDKScore");
-       *res_ptr = LDKScore_init(env, clz, o);
-       return tag_ptr(res_ptr, true);
-}
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Score_1channel_1penalty_1msat(JNIEnv *env, jclass clz, int64_t this_arg, int64_t short_channel_id, int64_t source, int64_t target, int64_t usage) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKNodeId source_conv;
-       source_conv.inner = untag_ptr(source);
-       source_conv.is_owned = ptr_is_owned(source);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_conv);
-       source_conv.is_owned = false;
-       LDKNodeId target_conv;
-       target_conv.inner = untag_ptr(target);
-       target_conv.is_owned = ptr_is_owned(target);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_conv);
-       target_conv.is_owned = false;
-       LDKChannelUsage usage_conv;
-       usage_conv.inner = untag_ptr(usage);
-       usage_conv.is_owned = ptr_is_owned(usage);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(usage_conv);
-       usage_conv = ChannelUsage_clone(&usage_conv);
-       int64_t ret_conv = (this_arg_conv->channel_penalty_msat)(this_arg_conv->this_arg, short_channel_id, &source_conv, &target_conv, usage_conv);
-       return ret_conv;
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_RouteHopZ path_constr;
-       path_constr.datalen = (*env)->GetArrayLength(env, path);
-       if (path_constr.datalen > 0)
-               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
-       else
-               path_constr.data = NULL;
-       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
-       for (size_t k = 0; k < path_constr.datalen; k++) {
-               int64_t path_conv_10 = path_vals[k];
-               LDKRouteHop path_conv_10_conv;
-               path_conv_10_conv.inner = untag_ptr(path_conv_10);
-               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
-               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
-               path_constr.data[k] = path_conv_10_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
-       (this_arg_conv->payment_path_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_RouteHopZ path_constr;
-       path_constr.datalen = (*env)->GetArrayLength(env, path);
-       if (path_constr.datalen > 0)
-               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
-       else
-               path_constr.data = NULL;
-       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
-       for (size_t k = 0; k < path_constr.datalen; k++) {
-               int64_t path_conv_10 = path_vals[k];
-               LDKRouteHop path_conv_10_conv;
-               path_conv_10_conv.inner = untag_ptr(path_conv_10);
-               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
-               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
-               path_constr.data[k] = path_conv_10_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
-       (this_arg_conv->payment_path_successful)(this_arg_conv->this_arg, path_constr);
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_RouteHopZ path_constr;
-       path_constr.datalen = (*env)->GetArrayLength(env, path);
-       if (path_constr.datalen > 0)
-               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
-       else
-               path_constr.data = NULL;
-       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
-       for (size_t k = 0; k < path_constr.datalen; k++) {
-               int64_t path_conv_10 = path_vals[k];
-               LDKRouteHop path_conv_10_conv;
-               path_conv_10_conv.inner = untag_ptr(path_conv_10);
-               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
-               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
-               path_constr.data[k] = path_conv_10_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
-       (this_arg_conv->probe_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_RouteHopZ path_constr;
-       path_constr.datalen = (*env)->GetArrayLength(env, path);
-       if (path_constr.datalen > 0)
-               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
-       else
-               path_constr.data = NULL;
-       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
-       for (size_t k = 0; k < path_constr.datalen; k++) {
-               int64_t path_conv_10 = path_vals[k];
-               LDKRouteHop path_conv_10_conv;
-               path_conv_10_conv.inner = untag_ptr(path_conv_10);
-               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
-               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
-               path_constr.data[k] = path_conv_10_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
-       (this_arg_conv->probe_successful)(this_arg_conv->this_arg, path_constr);
-}
-
-JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_Score_1write(JNIEnv *env, jclass clz, int64_t this_arg) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_u8Z ret_var = (this_arg_conv->write)(this_arg_conv->this_arg);
-       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
-       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
-       CVec_u8Z_free(ret_var);
-       return ret_arr;
-}
-
 typedef struct LDKPersister_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -10231,7 +10880,7 @@ LDKCResult_NoneErrorZ persist_graph_LDKPersister_jcall(const void* this_arg, con
        }
        return ret_conv;
 }
-LDKCResult_NoneErrorZ persist_scorer_LDKPersister_jcall(const void* this_arg, const LDKMultiThreadedLockableScore * scorer) {
+LDKCResult_NoneErrorZ persist_scorer_LDKPersister_jcall(const void* this_arg, const LDKWriteableScore * scorer) {
        LDKPersister_JCalls *j_calls = (LDKPersister_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -10240,14 +10889,11 @@ LDKCResult_NoneErrorZ persist_scorer_LDKPersister_jcall(const void* this_arg, co
        } else {
                DO_ASSERT(get_jenv_res == JNI_OK);
        }
-       LDKMultiThreadedLockableScore scorer_var = *scorer;
-       int64_t scorer_ref = 0;
-       // WARNING: we may need a move here but no clone is available for LDKMultiThreadedLockableScore
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(scorer_var);
-       scorer_ref = tag_ptr(scorer_var.inner, scorer_var.is_owned);
+       // WARNING: This object doesn't live past this scope, needs clone!
+       int64_t ret_scorer = tag_ptr(scorer, false);
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->persist_scorer_meth, scorer_ref);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->persist_scorer_meth, ret_scorer);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
                (*env)->FatalError(env, "A call to persist_scorer in LDKPersister from rust threw an exception.");
@@ -10325,16 +10971,90 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Persister_1persist_1scorer(
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKPersister* this_arg_conv = (LDKPersister*)this_arg_ptr;
-       LDKMultiThreadedLockableScore scorer_conv;
-       scorer_conv.inner = untag_ptr(scorer);
-       scorer_conv.is_owned = ptr_is_owned(scorer);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(scorer_conv);
-       scorer_conv.is_owned = false;
+       void* scorer_ptr = untag_ptr(scorer);
+       if (ptr_is_owned(scorer)) { CHECK_ACCESS(scorer_ptr); }
+       LDKWriteableScore* scorer_conv = (LDKWriteableScore*)scorer_ptr;
        LDKCResult_NoneErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneErrorZ), "LDKCResult_NoneErrorZ");
-       *ret_conv = (this_arg_conv->persist_scorer)(this_arg_conv->this_arg, &scorer_conv);
+       *ret_conv = (this_arg_conv->persist_scorer)(this_arg_conv->this_arg, scorer_conv);
        return tag_ptr(ret_conv, true);
 }
 
+typedef struct LDKFutureCallback_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       jmethodID call_meth;
+} LDKFutureCallback_JCalls;
+static void LDKFutureCallback_JCalls_free(void* this_arg) {
+       LDKFutureCallback_JCalls *j_calls = (LDKFutureCallback_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+void call_LDKFutureCallback_jcall(const void* this_arg) {
+       LDKFutureCallback_JCalls *j_calls = (LDKFutureCallback_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->call_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to call in LDKFutureCallback from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+static void LDKFutureCallback_JCalls_cloned(LDKFutureCallback* new_obj) {
+       LDKFutureCallback_JCalls *j_calls = (LDKFutureCallback_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+}
+static inline LDKFutureCallback LDKFutureCallback_init (JNIEnv *env, jclass clz, jobject o) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKFutureCallback_JCalls *calls = MALLOC(sizeof(LDKFutureCallback_JCalls), "LDKFutureCallback_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->call_meth = (*env)->GetMethodID(env, c, "call", "()V");
+       CHECK(calls->call_meth != NULL);
+
+       LDKFutureCallback ret = {
+               .this_arg = (void*) calls,
+               .call = call_LDKFutureCallback_jcall,
+               .free = LDKFutureCallback_JCalls_free,
+       };
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKFutureCallback_1new(JNIEnv *env, jclass clz, jobject o) {
+       LDKFutureCallback *res_ptr = MALLOC(sizeof(LDKFutureCallback), "LDKFutureCallback");
+       *res_ptr = LDKFutureCallback_init(env, clz, o);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_FutureCallback_1call(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKFutureCallback* this_arg_conv = (LDKFutureCallback*)this_arg_ptr;
+       (this_arg_conv->call)(this_arg_conv->this_arg);
+}
+
 typedef struct LDKListen_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -10975,6 +11695,8 @@ typedef struct LDKChannelMessageHandler_JCalls {
        jmethodID handle_channel_reestablish_meth;
        jmethodID handle_channel_update_meth;
        jmethodID handle_error_meth;
+       jmethodID provided_node_features_meth;
+       jmethodID provided_init_features_meth;
 } LDKChannelMessageHandler_JCalls;
 static void LDKChannelMessageHandler_JCalls_free(void* this_arg) {
        LDKChannelMessageHandler_JCalls *j_calls = (LDKChannelMessageHandler_JCalls*) this_arg;
@@ -11542,6 +12264,58 @@ void handle_error_LDKChannelMessageHandler_jcall(const void* this_arg, LDKPublic
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
 }
+LDKNodeFeatures provided_node_features_LDKChannelMessageHandler_jcall(const void* this_arg) {
+       LDKChannelMessageHandler_JCalls *j_calls = (LDKChannelMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_node_features_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_node_features in LDKChannelMessageHandler from rust threw an exception.");
+       }
+       LDKNodeFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+LDKInitFeatures provided_init_features_LDKChannelMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id) {
+       LDKChannelMessageHandler_JCalls *j_calls = (LDKChannelMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_init_features_meth, their_node_id_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_init_features in LDKChannelMessageHandler from rust threw an exception.");
+       }
+       LDKInitFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
 static void LDKChannelMessageHandler_JCalls_cloned(LDKChannelMessageHandler* new_obj) {
        LDKChannelMessageHandler_JCalls *j_calls = (LDKChannelMessageHandler_JCalls*) new_obj->this_arg;
        atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
@@ -11594,6 +12368,10 @@ static inline LDKChannelMessageHandler LDKChannelMessageHandler_init (JNIEnv *en
        CHECK(calls->handle_channel_update_meth != NULL);
        calls->handle_error_meth = (*env)->GetMethodID(env, c, "handle_error", "([BJ)V");
        CHECK(calls->handle_error_meth != NULL);
+       calls->provided_node_features_meth = (*env)->GetMethodID(env, c, "provided_node_features", "()J");
+       CHECK(calls->provided_node_features_meth != NULL);
+       calls->provided_init_features_meth = (*env)->GetMethodID(env, c, "provided_init_features", "([B)J");
+       CHECK(calls->provided_init_features_meth != NULL);
 
        LDKChannelMessageHandler ret = {
                .this_arg = (void*) calls,
@@ -11617,6 +12395,8 @@ static inline LDKChannelMessageHandler LDKChannelMessageHandler_init (JNIEnv *en
                .handle_channel_reestablish = handle_channel_reestablish_LDKChannelMessageHandler_jcall,
                .handle_channel_update = handle_channel_update_LDKChannelMessageHandler_jcall,
                .handle_error = handle_error_LDKChannelMessageHandler_jcall,
+               .provided_node_features = provided_node_features_LDKChannelMessageHandler_jcall,
+               .provided_init_features = provided_init_features_LDKChannelMessageHandler_jcall,
                .free = LDKChannelMessageHandler_JCalls_free,
                .MessageSendEventsProvider = LDKMessageSendEventsProvider_init(env, clz, MessageSendEventsProvider),
        };
@@ -11942,6 +12722,31 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1handle_
        (this_arg_conv->handle_error)(this_arg_conv->this_arg, their_node_id_ref, &msg_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1provided_1node_1features(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKChannelMessageHandler* this_arg_conv = (LDKChannelMessageHandler*)this_arg_ptr;
+       LDKNodeFeatures ret_var = (this_arg_conv->provided_node_features)(this_arg_conv->this_arg);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1provided_1init_1features(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKChannelMessageHandler* this_arg_conv = (LDKChannelMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       LDKInitFeatures ret_var = (this_arg_conv->provided_init_features)(this_arg_conv->this_arg, their_node_id_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 typedef struct LDKRoutingMessageHandler_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -11950,13 +12755,15 @@ typedef struct LDKRoutingMessageHandler_JCalls {
        jmethodID handle_node_announcement_meth;
        jmethodID handle_channel_announcement_meth;
        jmethodID handle_channel_update_meth;
-       jmethodID get_next_channel_announcements_meth;
-       jmethodID get_next_node_announcements_meth;
+       jmethodID get_next_channel_announcement_meth;
+       jmethodID get_next_node_announcement_meth;
        jmethodID peer_connected_meth;
        jmethodID handle_reply_channel_range_meth;
        jmethodID handle_reply_short_channel_ids_end_meth;
        jmethodID handle_query_channel_range_meth;
        jmethodID handle_query_short_channel_ids_meth;
+       jmethodID provided_node_features_meth;
+       jmethodID provided_init_features_meth;
 } LDKRoutingMessageHandler_JCalls;
 static void LDKRoutingMessageHandler_JCalls_free(void* this_arg) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
@@ -12065,7 +12872,7 @@ LDKCResult_boolLightningErrorZ handle_channel_update_LDKRoutingMessageHandler_jc
        }
        return ret_conv;
 }
-LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ get_next_channel_announcements_LDKRoutingMessageHandler_jcall(const void* this_arg, uint64_t starting_point, uint8_t batch_amount) {
+LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ get_next_channel_announcement_LDKRoutingMessageHandler_jcall(const void* this_arg, uint64_t starting_point) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -12075,36 +12882,23 @@ LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ get_next_channel
                DO_ASSERT(get_jenv_res == JNI_OK);
        }
        int64_t starting_point_conv = starting_point;
-       int8_t batch_amount_conv = batch_amount;
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       int64_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->get_next_channel_announcements_meth, starting_point_conv, batch_amount_conv);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->get_next_channel_announcement_meth, starting_point_conv);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to get_next_channel_announcements in LDKRoutingMessageHandler from rust threw an exception.");
+               (*env)->FatalError(env, "A call to get_next_channel_announcement in LDKRoutingMessageHandler from rust threw an exception.");
        }
-       LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_constr;
-       ret_constr.datalen = (*env)->GetArrayLength(env, ret);
-       if (ret_constr.datalen > 0)
-               ret_constr.data = MALLOC(ret_constr.datalen * sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ Elements");
-       else
-               ret_constr.data = NULL;
-       int64_t* ret_vals = (*env)->GetLongArrayElements (env, ret, NULL);
-       for (size_t h = 0; h < ret_constr.datalen; h++) {
-               int64_t ret_conv_59 = ret_vals[h];
-               void* ret_conv_59_ptr = untag_ptr(ret_conv_59);
-               CHECK_ACCESS(ret_conv_59_ptr);
-               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ ret_conv_59_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(ret_conv_59_ptr);
-               FREE(untag_ptr(ret_conv_59));
-               ret_constr.data[h] = ret_conv_59_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, ret, ret_vals, 0);
+       void* ret_ptr = untag_ptr(ret);
+       CHECK_ACCESS(ret_ptr);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_conv = *(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)(ret_ptr);
+       FREE(untag_ptr(ret));
        if (get_jenv_res == JNI_EDETACHED) {
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
-       return ret_constr;
+       return ret_conv;
 }
-LDKCVec_NodeAnnouncementZ get_next_node_announcements_LDKRoutingMessageHandler_jcall(const void* this_arg, LDKPublicKey starting_point, uint8_t batch_amount) {
+LDKNodeAnnouncement get_next_node_announcement_LDKRoutingMessageHandler_jcall(const void* this_arg, LDKPublicKey starting_point) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -12115,34 +12909,21 @@ LDKCVec_NodeAnnouncementZ get_next_node_announcements_LDKRoutingMessageHandler_j
        }
        int8_tArray starting_point_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, starting_point_arr, 0, 33, starting_point.compressed_form);
-       int8_t batch_amount_conv = batch_amount;
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       int64_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->get_next_node_announcements_meth, starting_point_arr, batch_amount_conv);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->get_next_node_announcement_meth, starting_point_arr);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to get_next_node_announcements in LDKRoutingMessageHandler from rust threw an exception.");
-       }
-       LDKCVec_NodeAnnouncementZ ret_constr;
-       ret_constr.datalen = (*env)->GetArrayLength(env, ret);
-       if (ret_constr.datalen > 0)
-               ret_constr.data = MALLOC(ret_constr.datalen * sizeof(LDKNodeAnnouncement), "LDKCVec_NodeAnnouncementZ Elements");
-       else
-               ret_constr.data = NULL;
-       int64_t* ret_vals = (*env)->GetLongArrayElements (env, ret, NULL);
-       for (size_t s = 0; s < ret_constr.datalen; s++) {
-               int64_t ret_conv_18 = ret_vals[s];
-               LDKNodeAnnouncement ret_conv_18_conv;
-               ret_conv_18_conv.inner = untag_ptr(ret_conv_18);
-               ret_conv_18_conv.is_owned = ptr_is_owned(ret_conv_18);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv_18_conv);
-               ret_constr.data[s] = ret_conv_18_conv;
+               (*env)->FatalError(env, "A call to get_next_node_announcement in LDKRoutingMessageHandler from rust threw an exception.");
        }
-       (*env)->ReleaseLongArrayElements(env, ret, ret_vals, 0);
+       LDKNodeAnnouncement ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
        if (get_jenv_res == JNI_EDETACHED) {
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
-       return ret_constr;
+       return ret_conv;
 }
 void peer_connected_LDKRoutingMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id, const LDKInit * init) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
@@ -12295,6 +13076,58 @@ LDKCResult_NoneLightningErrorZ handle_query_short_channel_ids_LDKRoutingMessageH
        }
        return ret_conv;
 }
+LDKNodeFeatures provided_node_features_LDKRoutingMessageHandler_jcall(const void* this_arg) {
+       LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_node_features_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_node_features in LDKRoutingMessageHandler from rust threw an exception.");
+       }
+       LDKNodeFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+LDKInitFeatures provided_init_features_LDKRoutingMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id) {
+       LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_init_features_meth, their_node_id_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_init_features in LDKRoutingMessageHandler from rust threw an exception.");
+       }
+       LDKInitFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
 static void LDKRoutingMessageHandler_JCalls_cloned(LDKRoutingMessageHandler* new_obj) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) new_obj->this_arg;
        atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
@@ -12313,10 +13146,10 @@ static inline LDKRoutingMessageHandler LDKRoutingMessageHandler_init (JNIEnv *en
        CHECK(calls->handle_channel_announcement_meth != NULL);
        calls->handle_channel_update_meth = (*env)->GetMethodID(env, c, "handle_channel_update", "(J)J");
        CHECK(calls->handle_channel_update_meth != NULL);
-       calls->get_next_channel_announcements_meth = (*env)->GetMethodID(env, c, "get_next_channel_announcements", "(JB)[J");
-       CHECK(calls->get_next_channel_announcements_meth != NULL);
-       calls->get_next_node_announcements_meth = (*env)->GetMethodID(env, c, "get_next_node_announcements", "([BB)[J");
-       CHECK(calls->get_next_node_announcements_meth != NULL);
+       calls->get_next_channel_announcement_meth = (*env)->GetMethodID(env, c, "get_next_channel_announcement", "(J)J");
+       CHECK(calls->get_next_channel_announcement_meth != NULL);
+       calls->get_next_node_announcement_meth = (*env)->GetMethodID(env, c, "get_next_node_announcement", "([B)J");
+       CHECK(calls->get_next_node_announcement_meth != NULL);
        calls->peer_connected_meth = (*env)->GetMethodID(env, c, "peer_connected", "([BJ)V");
        CHECK(calls->peer_connected_meth != NULL);
        calls->handle_reply_channel_range_meth = (*env)->GetMethodID(env, c, "handle_reply_channel_range", "([BJ)J");
@@ -12327,19 +13160,25 @@ static inline LDKRoutingMessageHandler LDKRoutingMessageHandler_init (JNIEnv *en
        CHECK(calls->handle_query_channel_range_meth != NULL);
        calls->handle_query_short_channel_ids_meth = (*env)->GetMethodID(env, c, "handle_query_short_channel_ids", "([BJ)J");
        CHECK(calls->handle_query_short_channel_ids_meth != NULL);
+       calls->provided_node_features_meth = (*env)->GetMethodID(env, c, "provided_node_features", "()J");
+       CHECK(calls->provided_node_features_meth != NULL);
+       calls->provided_init_features_meth = (*env)->GetMethodID(env, c, "provided_init_features", "([B)J");
+       CHECK(calls->provided_init_features_meth != NULL);
 
        LDKRoutingMessageHandler ret = {
                .this_arg = (void*) calls,
                .handle_node_announcement = handle_node_announcement_LDKRoutingMessageHandler_jcall,
                .handle_channel_announcement = handle_channel_announcement_LDKRoutingMessageHandler_jcall,
                .handle_channel_update = handle_channel_update_LDKRoutingMessageHandler_jcall,
-               .get_next_channel_announcements = get_next_channel_announcements_LDKRoutingMessageHandler_jcall,
-               .get_next_node_announcements = get_next_node_announcements_LDKRoutingMessageHandler_jcall,
+               .get_next_channel_announcement = get_next_channel_announcement_LDKRoutingMessageHandler_jcall,
+               .get_next_node_announcement = get_next_node_announcement_LDKRoutingMessageHandler_jcall,
                .peer_connected = peer_connected_LDKRoutingMessageHandler_jcall,
                .handle_reply_channel_range = handle_reply_channel_range_LDKRoutingMessageHandler_jcall,
                .handle_reply_short_channel_ids_end = handle_reply_short_channel_ids_end_LDKRoutingMessageHandler_jcall,
                .handle_query_channel_range = handle_query_channel_range_LDKRoutingMessageHandler_jcall,
                .handle_query_short_channel_ids = handle_query_short_channel_ids_LDKRoutingMessageHandler_jcall,
+               .provided_node_features = provided_node_features_LDKRoutingMessageHandler_jcall,
+               .provided_init_features = provided_init_features_LDKRoutingMessageHandler_jcall,
                .free = LDKRoutingMessageHandler_JCalls_free,
                .MessageSendEventsProvider = LDKMessageSendEventsProvider_init(env, clz, MessageSendEventsProvider),
        };
@@ -12397,45 +13236,28 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1hand
        return tag_ptr(ret_conv, true);
 }
 
-JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1channel_1announcements(JNIEnv *env, jclass clz, int64_t this_arg, int64_t starting_point, int8_t batch_amount) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1channel_1announcement(JNIEnv *env, jclass clz, int64_t this_arg, int64_t starting_point) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKRoutingMessageHandler* this_arg_conv = (LDKRoutingMessageHandler*)this_arg_ptr;
-       LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_var = (this_arg_conv->get_next_channel_announcements)(this_arg_conv->this_arg, starting_point, batch_amount);
-       int64_tArray ret_arr = NULL;
-       ret_arr = (*env)->NewLongArray(env, ret_var.datalen);
-       int64_t *ret_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, ret_arr, NULL);
-       for (size_t h = 0; h < ret_var.datalen; h++) {
-               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ* ret_conv_59_conv = MALLOC(sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ");
-               *ret_conv_59_conv = ret_var.data[h];
-               ret_arr_ptr[h] = tag_ptr(ret_conv_59_conv, true);
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, ret_arr, ret_arr_ptr, 0);
-       FREE(ret_var.data);
-       return ret_arr;
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = (this_arg_conv->get_next_channel_announcement)(this_arg_conv->this_arg, starting_point);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
 }
 
-JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1node_1announcements(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray starting_point, int8_t batch_amount) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1node_1announcement(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray starting_point) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKRoutingMessageHandler* this_arg_conv = (LDKRoutingMessageHandler*)this_arg_ptr;
        LDKPublicKey starting_point_ref;
        CHECK((*env)->GetArrayLength(env, starting_point) == 33);
        (*env)->GetByteArrayRegion(env, starting_point, 0, 33, starting_point_ref.compressed_form);
-       LDKCVec_NodeAnnouncementZ ret_var = (this_arg_conv->get_next_node_announcements)(this_arg_conv->this_arg, starting_point_ref, batch_amount);
-       int64_tArray ret_arr = NULL;
-       ret_arr = (*env)->NewLongArray(env, ret_var.datalen);
-       int64_t *ret_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, ret_arr, NULL);
-       for (size_t s = 0; s < ret_var.datalen; s++) {
-               LDKNodeAnnouncement ret_conv_18_var = ret_var.data[s];
-               int64_t ret_conv_18_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv_18_var);
-               ret_conv_18_ref = tag_ptr(ret_conv_18_var.inner, ret_conv_18_var.is_owned);
-               ret_arr_ptr[s] = ret_conv_18_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, ret_arr, ret_arr_ptr, 0);
-       FREE(ret_var.data);
-       return ret_arr;
+       LDKNodeAnnouncement ret_var = (this_arg_conv->get_next_node_announcement)(this_arg_conv->this_arg, starting_point_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1peer_1connected(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id, int64_t init) {
@@ -12521,6 +13343,298 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1hand
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1provided_1node_1features(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRoutingMessageHandler* this_arg_conv = (LDKRoutingMessageHandler*)this_arg_ptr;
+       LDKNodeFeatures ret_var = (this_arg_conv->provided_node_features)(this_arg_conv->this_arg);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1provided_1init_1features(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRoutingMessageHandler* this_arg_conv = (LDKRoutingMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       LDKInitFeatures ret_var = (this_arg_conv->provided_init_features)(this_arg_conv->this_arg, their_node_id_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+typedef struct LDKOnionMessageHandler_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       LDKOnionMessageProvider_JCalls* OnionMessageProvider;
+       jmethodID handle_onion_message_meth;
+       jmethodID peer_connected_meth;
+       jmethodID peer_disconnected_meth;
+       jmethodID provided_node_features_meth;
+       jmethodID provided_init_features_meth;
+} LDKOnionMessageHandler_JCalls;
+static void LDKOnionMessageHandler_JCalls_free(void* this_arg) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+void handle_onion_message_LDKOnionMessageHandler_jcall(const void* this_arg, LDKPublicKey peer_node_id, const LDKOnionMessage * msg) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray peer_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, peer_node_id_arr, 0, 33, peer_node_id.compressed_form);
+       LDKOnionMessage msg_var = *msg;
+       int64_t msg_ref = 0;
+       msg_var = OnionMessage_clone(&msg_var);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_var);
+       msg_ref = tag_ptr(msg_var.inner, msg_var.is_owned);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->handle_onion_message_meth, peer_node_id_arr, msg_ref);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to handle_onion_message in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void peer_connected_LDKOnionMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id, const LDKInit * init) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       LDKInit init_var = *init;
+       int64_t init_ref = 0;
+       init_var = Init_clone(&init_var);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(init_var);
+       init_ref = tag_ptr(init_var.inner, init_var.is_owned);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->peer_connected_meth, their_node_id_arr, init_ref);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to peer_connected in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void peer_disconnected_LDKOnionMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id, bool no_connection_possible) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       jboolean no_connection_possible_conv = no_connection_possible;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->peer_disconnected_meth, their_node_id_arr, no_connection_possible_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to peer_disconnected in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+LDKNodeFeatures provided_node_features_LDKOnionMessageHandler_jcall(const void* this_arg) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_node_features_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_node_features in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       LDKNodeFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+LDKInitFeatures provided_init_features_LDKOnionMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_init_features_meth, their_node_id_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_init_features in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       LDKInitFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+static void LDKOnionMessageHandler_JCalls_cloned(LDKOnionMessageHandler* new_obj) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+       atomic_fetch_add_explicit(&j_calls->OnionMessageProvider->refcnt, 1, memory_order_release);
+}
+static inline LDKOnionMessageHandler LDKOnionMessageHandler_init (JNIEnv *env, jclass clz, jobject o, jobject OnionMessageProvider) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKOnionMessageHandler_JCalls *calls = MALLOC(sizeof(LDKOnionMessageHandler_JCalls), "LDKOnionMessageHandler_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->handle_onion_message_meth = (*env)->GetMethodID(env, c, "handle_onion_message", "([BJ)V");
+       CHECK(calls->handle_onion_message_meth != NULL);
+       calls->peer_connected_meth = (*env)->GetMethodID(env, c, "peer_connected", "([BJ)V");
+       CHECK(calls->peer_connected_meth != NULL);
+       calls->peer_disconnected_meth = (*env)->GetMethodID(env, c, "peer_disconnected", "([BZ)V");
+       CHECK(calls->peer_disconnected_meth != NULL);
+       calls->provided_node_features_meth = (*env)->GetMethodID(env, c, "provided_node_features", "()J");
+       CHECK(calls->provided_node_features_meth != NULL);
+       calls->provided_init_features_meth = (*env)->GetMethodID(env, c, "provided_init_features", "([B)J");
+       CHECK(calls->provided_init_features_meth != NULL);
+
+       LDKOnionMessageHandler ret = {
+               .this_arg = (void*) calls,
+               .handle_onion_message = handle_onion_message_LDKOnionMessageHandler_jcall,
+               .peer_connected = peer_connected_LDKOnionMessageHandler_jcall,
+               .peer_disconnected = peer_disconnected_LDKOnionMessageHandler_jcall,
+               .provided_node_features = provided_node_features_LDKOnionMessageHandler_jcall,
+               .provided_init_features = provided_init_features_LDKOnionMessageHandler_jcall,
+               .free = LDKOnionMessageHandler_JCalls_free,
+               .OnionMessageProvider = LDKOnionMessageProvider_init(env, clz, OnionMessageProvider),
+       };
+       calls->OnionMessageProvider = ret.OnionMessageProvider.this_arg;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKOnionMessageHandler_1new(JNIEnv *env, jclass clz, jobject o, jobject OnionMessageProvider) {
+       LDKOnionMessageHandler *res_ptr = MALLOC(sizeof(LDKOnionMessageHandler), "LDKOnionMessageHandler");
+       *res_ptr = LDKOnionMessageHandler_init(env, clz, o, OnionMessageProvider);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKOnionMessageHandler_1get_1OnionMessageProvider(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKOnionMessageHandler *inp = (LDKOnionMessageHandler *)untag_ptr(arg);
+       return tag_ptr(&inp->OnionMessageProvider, false);
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1handle_1onion_1message(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray peer_node_id, int64_t msg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKPublicKey peer_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, peer_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, peer_node_id, 0, 33, peer_node_id_ref.compressed_form);
+       LDKOnionMessage msg_conv;
+       msg_conv.inner = untag_ptr(msg);
+       msg_conv.is_owned = ptr_is_owned(msg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_conv);
+       msg_conv.is_owned = false;
+       (this_arg_conv->handle_onion_message)(this_arg_conv->this_arg, peer_node_id_ref, &msg_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1peer_1connected(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id, int64_t init) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       LDKInit init_conv;
+       init_conv.inner = untag_ptr(init);
+       init_conv.is_owned = ptr_is_owned(init);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(init_conv);
+       init_conv.is_owned = false;
+       (this_arg_conv->peer_connected)(this_arg_conv->this_arg, their_node_id_ref, &init_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1peer_1disconnected(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id, jboolean no_connection_possible) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       (this_arg_conv->peer_disconnected)(this_arg_conv->this_arg, their_node_id_ref, no_connection_possible);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1provided_1node_1features(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKNodeFeatures ret_var = (this_arg_conv->provided_node_features)(this_arg_conv->this_arg);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1provided_1init_1features(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       LDKInitFeatures ret_var = (this_arg_conv->provided_init_features)(this_arg_conv->this_arg, their_node_id_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 typedef struct LDKCustomMessageReader_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -13016,93 +14130,40 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKEffectiveCapacity_1ref_1
                default: abort();
        }
 }
-typedef struct LDKLockableScore_JCalls {
-       atomic_size_t refcnt;
-       JavaVM *vm;
-       jweak o;
-       jmethodID lock_meth;
-} LDKLockableScore_JCalls;
-static void LDKLockableScore_JCalls_free(void* this_arg) {
-       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) this_arg;
-       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
-               JNIEnv *env;
-               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-               if (get_jenv_res == JNI_EDETACHED) {
-                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-               } else {
-                       DO_ASSERT(get_jenv_res == JNI_OK);
+static jclass LDKDestination_Node_class = NULL;
+static jmethodID LDKDestination_Node_meth = NULL;
+static jclass LDKDestination_BlindedRoute_class = NULL;
+static jmethodID LDKDestination_BlindedRoute_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKDestination_init (JNIEnv *env, jclass clz) {
+       LDKDestination_Node_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKDestination$Node"));
+       CHECK(LDKDestination_Node_class != NULL);
+       LDKDestination_Node_meth = (*env)->GetMethodID(env, LDKDestination_Node_class, "<init>", "([B)V");
+       CHECK(LDKDestination_Node_meth != NULL);
+       LDKDestination_BlindedRoute_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKDestination$BlindedRoute"));
+       CHECK(LDKDestination_BlindedRoute_class != NULL);
+       LDKDestination_BlindedRoute_meth = (*env)->GetMethodID(env, LDKDestination_BlindedRoute_class, "<init>", "(J)V");
+       CHECK(LDKDestination_BlindedRoute_meth != NULL);
+}
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKDestination_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKDestination *obj = (LDKDestination*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKDestination_Node: {
+                       int8_tArray node_arr = (*env)->NewByteArray(env, 33);
+                       (*env)->SetByteArrayRegion(env, node_arr, 0, 33, obj->node.compressed_form);
+                       return (*env)->NewObject(env, LDKDestination_Node_class, LDKDestination_Node_meth, node_arr);
                }
-               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
-               if (get_jenv_res == JNI_EDETACHED) {
-                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               case LDKDestination_BlindedRoute: {
+                       LDKBlindedRoute blinded_route_var = obj->blinded_route;
+                       int64_t blinded_route_ref = 0;
+                       CHECK_INNER_FIELD_ACCESS_OR_NULL(blinded_route_var);
+                       blinded_route_ref = tag_ptr(blinded_route_var.inner, false);
+                       return (*env)->NewObject(env, LDKDestination_BlindedRoute_class, LDKDestination_BlindedRoute_meth, blinded_route_ref);
                }
-               FREE(j_calls);
-       }
-}
-LDKScore lock_LDKLockableScore_jcall(const void* this_arg) {
-       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->lock_meth);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to lock in LDKLockableScore from rust threw an exception.");
-       }
-       void* ret_ptr = untag_ptr(ret);
-       CHECK_ACCESS(ret_ptr);
-       LDKScore ret_conv = *(LDKScore*)(ret_ptr);
-       if (ret_conv.free == LDKScore_JCalls_free) {
-               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
-               LDKScore_JCalls_cloned(&ret_conv);
-       }// WARNING: we may need a move here but no clone is available for LDKScore
-       
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               default: abort();
        }
-       return ret_conv;
-}
-static void LDKLockableScore_JCalls_cloned(LDKLockableScore* new_obj) {
-       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) new_obj->this_arg;
-       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
-}
-static inline LDKLockableScore LDKLockableScore_init (JNIEnv *env, jclass clz, jobject o) {
-       jclass c = (*env)->GetObjectClass(env, o);
-       CHECK(c != NULL);
-       LDKLockableScore_JCalls *calls = MALLOC(sizeof(LDKLockableScore_JCalls), "LDKLockableScore_JCalls");
-       atomic_init(&calls->refcnt, 1);
-       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
-       calls->o = (*env)->NewWeakGlobalRef(env, o);
-       calls->lock_meth = (*env)->GetMethodID(env, c, "lock", "()J");
-       CHECK(calls->lock_meth != NULL);
-
-       LDKLockableScore ret = {
-               .this_arg = (void*) calls,
-               .lock = lock_LDKLockableScore_jcall,
-               .free = LDKLockableScore_JCalls_free,
-       };
-       return ret;
-}
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKLockableScore_1new(JNIEnv *env, jclass clz, jobject o) {
-       LDKLockableScore *res_ptr = MALLOC(sizeof(LDKLockableScore), "LDKLockableScore");
-       *res_ptr = LDKLockableScore_init(env, clz, o);
-       return tag_ptr(res_ptr, true);
 }
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LockableScore_1lock(JNIEnv *env, jclass clz, int64_t this_arg) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKLockableScore* this_arg_conv = (LDKLockableScore*)this_arg_ptr;
-       LDKScore* ret_ret = MALLOC(sizeof(LDKScore), "LDKScore");
-       *ret_ret = (this_arg_conv->lock)(this_arg_conv->this_arg);
-       return tag_ptr(ret_ret, true);
-}
-
 static jclass LDKGossipSync_P2P_class = NULL;
 static jmethodID LDKGossipSync_P2P_meth = NULL;
 static jclass LDKGossipSync_Rapid_class = NULL;
@@ -13543,6 +14604,10 @@ typedef struct LDKRouter_JCalls {
        JavaVM *vm;
        jweak o;
        jmethodID find_route_meth;
+       jmethodID notify_payment_path_failed_meth;
+       jmethodID notify_payment_path_successful_meth;
+       jmethodID notify_payment_probe_successful_meth;
+       jmethodID notify_payment_probe_failed_meth;
 } LDKRouter_JCalls;
 static void LDKRouter_JCalls_free(void* this_arg) {
        LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
@@ -13561,7 +14626,7 @@ static void LDKRouter_JCalls_free(void* this_arg) {
                FREE(j_calls);
        }
 }
-LDKCResult_RouteLightningErrorZ find_route_LDKRouter_jcall(const void* this_arg, LDKPublicKey payer, const LDKRouteParameters * route_params, const uint8_t (* payment_hash)[32], LDKCVec_ChannelDetailsZ * first_hops, const LDKScore * scorer) {
+LDKCResult_RouteLightningErrorZ find_route_LDKRouter_jcall(const void* this_arg, LDKPublicKey payer, const LDKRouteParameters * route_params, const uint8_t (* payment_hash)[32], LDKCVec_ChannelDetailsZ * first_hops, LDKInFlightHtlcs inflight_htlcs) {
        LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -13594,11 +14659,13 @@ LDKCResult_RouteLightningErrorZ find_route_LDKRouter_jcall(const void* this_arg,
                }
                (*env)->ReleasePrimitiveArrayCritical(env, first_hops_arr, first_hops_arr_ptr, 0);
        }
-       // WARNING: This object doesn't live past this scope, needs clone!
-       int64_t ret_scorer = tag_ptr(scorer, false);
+       LDKInFlightHtlcs inflight_htlcs_var = inflight_htlcs;
+       int64_t inflight_htlcs_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(inflight_htlcs_var);
+       inflight_htlcs_ref = tag_ptr(inflight_htlcs_var.inner, inflight_htlcs_var.is_owned);
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->find_route_meth, payer_arr, route_params_ref, payment_hash_arr, first_hops_arr, ret_scorer);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->find_route_meth, payer_arr, route_params_ref, payment_hash_arr, first_hops_arr, inflight_htlcs_ref);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
                (*env)->FatalError(env, "A call to find_route in LDKRouter from rust threw an exception.");
@@ -13612,6 +14679,140 @@ LDKCResult_RouteLightningErrorZ find_route_LDKRouter_jcall(const void* this_arg,
        }
        return ret_conv;
 }
+void notify_payment_path_failed_LDKRouter_jcall(const void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
+       LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       int64_t short_channel_id_conv = short_channel_id;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->notify_payment_path_failed_meth, path_arr, short_channel_id_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to notify_payment_path_failed in LDKRouter from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void notify_payment_path_successful_LDKRouter_jcall(const void* this_arg, LDKCVec_RouteHopZ path) {
+       LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->notify_payment_path_successful_meth, path_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to notify_payment_path_successful in LDKRouter from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void notify_payment_probe_successful_LDKRouter_jcall(const void* this_arg, LDKCVec_RouteHopZ path) {
+       LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->notify_payment_probe_successful_meth, path_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to notify_payment_probe_successful in LDKRouter from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void notify_payment_probe_failed_LDKRouter_jcall(const void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
+       LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       int64_t short_channel_id_conv = short_channel_id;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->notify_payment_probe_failed_meth, path_arr, short_channel_id_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to notify_payment_probe_failed in LDKRouter from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
 static void LDKRouter_JCalls_cloned(LDKRouter* new_obj) {
        LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) new_obj->this_arg;
        atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
@@ -13625,10 +14826,22 @@ static inline LDKRouter LDKRouter_init (JNIEnv *env, jclass clz, jobject o) {
        calls->o = (*env)->NewWeakGlobalRef(env, o);
        calls->find_route_meth = (*env)->GetMethodID(env, c, "find_route", "([BJ[B[JJ)J");
        CHECK(calls->find_route_meth != NULL);
+       calls->notify_payment_path_failed_meth = (*env)->GetMethodID(env, c, "notify_payment_path_failed", "([JJ)V");
+       CHECK(calls->notify_payment_path_failed_meth != NULL);
+       calls->notify_payment_path_successful_meth = (*env)->GetMethodID(env, c, "notify_payment_path_successful", "([J)V");
+       CHECK(calls->notify_payment_path_successful_meth != NULL);
+       calls->notify_payment_probe_successful_meth = (*env)->GetMethodID(env, c, "notify_payment_probe_successful", "([J)V");
+       CHECK(calls->notify_payment_probe_successful_meth != NULL);
+       calls->notify_payment_probe_failed_meth = (*env)->GetMethodID(env, c, "notify_payment_probe_failed", "([JJ)V");
+       CHECK(calls->notify_payment_probe_failed_meth != NULL);
 
        LDKRouter ret = {
                .this_arg = (void*) calls,
                .find_route = find_route_LDKRouter_jcall,
+               .notify_payment_path_failed = notify_payment_path_failed_LDKRouter_jcall,
+               .notify_payment_path_successful = notify_payment_path_successful_LDKRouter_jcall,
+               .notify_payment_probe_successful = notify_payment_probe_successful_LDKRouter_jcall,
+               .notify_payment_probe_failed = notify_payment_probe_failed_LDKRouter_jcall,
                .free = LDKRouter_JCalls_free,
        };
        return ret;
@@ -13638,7 +14851,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKRouter_1new(JNIEnv *env,
        *res_ptr = LDKRouter_init(env, clz, o);
        return tag_ptr(res_ptr, true);
 }
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Router_1find_1route(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray payer, int64_t route_params, int8_tArray payment_hash, int64_tArray first_hops, int64_t scorer) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Router_1find_1route(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray payer, int64_t route_params, int8_tArray payment_hash, int64_tArray first_hops, int64_t inflight_htlcs) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
@@ -13675,15 +14888,114 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Router_1find_1route(JNIEnv
                (*env)->ReleaseLongArrayElements(env, first_hops, first_hops_vals, 0);
                first_hops_ptr = &first_hops_constr;
        }
-       void* scorer_ptr = untag_ptr(scorer);
-       if (ptr_is_owned(scorer)) { CHECK_ACCESS(scorer_ptr); }
-       LDKScore* scorer_conv = (LDKScore*)scorer_ptr;
+       LDKInFlightHtlcs inflight_htlcs_conv;
+       inflight_htlcs_conv.inner = untag_ptr(inflight_htlcs);
+       inflight_htlcs_conv.is_owned = ptr_is_owned(inflight_htlcs);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(inflight_htlcs_conv);
+       // WARNING: we need a move here but no clone is available for LDKInFlightHtlcs
+       
        LDKCResult_RouteLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_RouteLightningErrorZ), "LDKCResult_RouteLightningErrorZ");
-       *ret_conv = (this_arg_conv->find_route)(this_arg_conv->this_arg, payer_ref, &route_params_conv, payment_hash_ref, first_hops_ptr, scorer_conv);
+       *ret_conv = (this_arg_conv->find_route)(this_arg_conv->this_arg, payer_ref, &route_params_conv, payment_hash_ref, first_hops_ptr, inflight_htlcs_conv);
        if (first_hops_ptr != NULL) { FREE(first_hops_constr.data); }
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1path_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->notify_payment_path_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1path_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->notify_payment_path_successful)(this_arg_conv->this_arg, path_constr);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1probe_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->notify_payment_probe_successful)(this_arg_conv->this_arg, path_constr);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1probe_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->notify_payment_probe_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
+}
+
 static jclass LDKRetry_Attempts_class = NULL;
 static jmethodID LDKRetry_Attempts_meth = NULL;
 static jclass LDKRetry_Timeout_class = NULL;
@@ -13728,6 +15040,15 @@ JNIEXPORT jstring JNICALL Java_org_ldk_impl_bindings__1ldk_1c_1bindings_1get_1co
        return ret_conv;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BigEndianScalar_1new(JNIEnv *env, jclass clz, int8_tArray big_endian_bytes) {
+       LDKThirtyTwoBytes big_endian_bytes_ref;
+       CHECK((*env)->GetArrayLength(env, big_endian_bytes) == 32);
+       (*env)->GetByteArrayRegion(env, big_endian_bytes, 0, 32, big_endian_bytes_ref.data);
+       LDKBigEndianScalar* ret_ref = MALLOC(sizeof(LDKBigEndianScalar), "LDKBigEndianScalar");
+       *ret_ref = BigEndianScalar_new(big_endian_bytes_ref);
+       return tag_ptr(ret_ref, true);
+}
+
 static inline uint64_t Bech32Error_clone_ptr(LDKBech32Error *NONNULL_PTR arg) {
        LDKBech32Error *ret_copy = MALLOC(sizeof(LDKBech32Error), "LDKBech32Error");
        *ret_copy = Bech32Error_clone(arg);
@@ -13808,6 +15129,132 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Str_1free(JNIEnv *env, jclass
        Str_free(dummy);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1PublicKeyZ_1free(JNIEnv *env, jclass clz, jobjectArray _res) {
+       LDKCVec_PublicKeyZ _res_constr;
+       _res_constr.datalen = (*env)->GetArrayLength(env, _res);
+       if (_res_constr.datalen > 0)
+               _res_constr.data = MALLOC(_res_constr.datalen * sizeof(LDKPublicKey), "LDKCVec_PublicKeyZ Elements");
+       else
+               _res_constr.data = NULL;
+       for (size_t i = 0; i < _res_constr.datalen; i++) {
+               int8_tArray _res_conv_8 = (*env)->GetObjectArrayElement(env, _res, i);
+               LDKPublicKey _res_conv_8_ref;
+               CHECK((*env)->GetArrayLength(env, _res_conv_8) == 33);
+               (*env)->GetByteArrayRegion(env, _res_conv_8, 0, 33, _res_conv_8_ref.compressed_form);
+               _res_constr.data[i] = _res_conv_8_ref;
+       }
+       CVec_PublicKeyZ_free(_res_constr);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKBlindedRoute o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       // WARNING: we need a move here but no clone is available for LDKBlindedRoute
+       
+       LDKCResult_BlindedRouteNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteNoneZ), "LDKCResult_BlindedRouteNoneZ");
+       *ret_conv = CResult_BlindedRouteNoneZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1err(JNIEnv *env, jclass clz) {
+       LDKCResult_BlindedRouteNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteNoneZ), "LDKCResult_BlindedRouteNoneZ");
+       *ret_conv = CResult_BlindedRouteNoneZ_err();
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_BlindedRouteNoneZ* o_conv = (LDKCResult_BlindedRouteNoneZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_BlindedRouteNoneZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_BlindedRouteNoneZ _res_conv = *(LDKCResult_BlindedRouteNoneZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_BlindedRouteNoneZ_free(_res_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKBlindedRoute o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       // WARNING: we need a move here but no clone is available for LDKBlindedRoute
+       
+       LDKCResult_BlindedRouteDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteDecodeErrorZ), "LDKCResult_BlindedRouteDecodeErrorZ");
+       *ret_conv = CResult_BlindedRouteDecodeErrorZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       LDKDecodeError e_conv;
+       e_conv.inner = untag_ptr(e);
+       e_conv.is_owned = ptr_is_owned(e);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(e_conv);
+       e_conv = DecodeError_clone(&e_conv);
+       LDKCResult_BlindedRouteDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteDecodeErrorZ), "LDKCResult_BlindedRouteDecodeErrorZ");
+       *ret_conv = CResult_BlindedRouteDecodeErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_BlindedRouteDecodeErrorZ* o_conv = (LDKCResult_BlindedRouteDecodeErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_BlindedRouteDecodeErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_BlindedRouteDecodeErrorZ _res_conv = *(LDKCResult_BlindedRouteDecodeErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_BlindedRouteDecodeErrorZ_free(_res_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKBlindedHop o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       // WARNING: we need a move here but no clone is available for LDKBlindedHop
+       
+       LDKCResult_BlindedHopDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedHopDecodeErrorZ), "LDKCResult_BlindedHopDecodeErrorZ");
+       *ret_conv = CResult_BlindedHopDecodeErrorZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       LDKDecodeError e_conv;
+       e_conv.inner = untag_ptr(e);
+       e_conv.is_owned = ptr_is_owned(e);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(e_conv);
+       e_conv = DecodeError_clone(&e_conv);
+       LDKCResult_BlindedHopDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedHopDecodeErrorZ), "LDKCResult_BlindedHopDecodeErrorZ");
+       *ret_conv = CResult_BlindedHopDecodeErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_BlindedHopDecodeErrorZ* o_conv = (LDKCResult_BlindedHopDecodeErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_BlindedHopDecodeErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_BlindedHopDecodeErrorZ _res_conv = *(LDKCResult_BlindedHopDecodeErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_BlindedHopDecodeErrorZ_free(_res_conv);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneNoneZ_1ok(JNIEnv *env, jclass clz) {
        LDKCResult_NoneNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneNoneZ), "LDKCResult_NoneNoneZ");
        *ret_conv = CResult_NoneNoneZ_ok();
@@ -14806,6 +16253,36 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ShutdownScriptInva
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1WriteableScoreZ_1some(JNIEnv *env, jclass clz, int64_t o) {
+       void* o_ptr = untag_ptr(o);
+       CHECK_ACCESS(o_ptr);
+       LDKWriteableScore o_conv = *(LDKWriteableScore*)(o_ptr);
+       if (o_conv.free == LDKWriteableScore_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKWriteableScore_JCalls_cloned(&o_conv);
+       }
+       LDKCOption_WriteableScoreZ *ret_copy = MALLOC(sizeof(LDKCOption_WriteableScoreZ), "LDKCOption_WriteableScoreZ");
+       *ret_copy = COption_WriteableScoreZ_some(o_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1WriteableScoreZ_1none(JNIEnv *env, jclass clz) {
+       LDKCOption_WriteableScoreZ *ret_copy = MALLOC(sizeof(LDKCOption_WriteableScoreZ), "LDKCOption_WriteableScoreZ");
+       *ret_copy = COption_WriteableScoreZ_none();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1WriteableScoreZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCOption_WriteableScoreZ _res_conv = *(LDKCOption_WriteableScoreZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       COption_WriteableScoreZ_free(_res_conv);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneErrorZ_1ok(JNIEnv *env, jclass clz) {
        LDKCResult_NoneErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneErrorZ), "LDKCResult_NoneErrorZ");
        *ret_conv = CResult_NoneErrorZ_ok();
@@ -15406,23 +16883,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RouteLightningErro
        return tag_ptr(ret_conv, true);
 }
 
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1PublicKeyZ_1free(JNIEnv *env, jclass clz, jobjectArray _res) {
-       LDKCVec_PublicKeyZ _res_constr;
-       _res_constr.datalen = (*env)->GetArrayLength(env, _res);
-       if (_res_constr.datalen > 0)
-               _res_constr.data = MALLOC(_res_constr.datalen * sizeof(LDKPublicKey), "LDKCVec_PublicKeyZ Elements");
-       else
-               _res_constr.data = NULL;
-       for (size_t i = 0; i < _res_constr.datalen; i++) {
-               int8_tArray _res_conv_8 = (*env)->GetObjectArrayElement(env, _res, i);
-               LDKPublicKey _res_conv_8_ref;
-               CHECK((*env)->GetArrayLength(env, _res_conv_8) == 33);
-               (*env)->GetByteArrayRegion(env, _res_conv_8, 0, 33, _res_conv_8_ref.compressed_form);
-               _res_constr.data[i] = _res_conv_8_ref;
-       }
-       CVec_PublicKeyZ_free(_res_constr);
-}
-
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentPurposeDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        void* o_ptr = untag_ptr(o);
        CHECK_ACCESS(o_ptr);
@@ -16135,53 +17595,6 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C3Tuple_1OutPointCVec_1M
        CVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ_free(_res_constr);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1some(JNIEnv *env, jclass clz, int64_t o) {
-       void* o_ptr = untag_ptr(o);
-       CHECK_ACCESS(o_ptr);
-       LDKC2Tuple_usizeTransactionZ o_conv = *(LDKC2Tuple_usizeTransactionZ*)(o_ptr);
-       o_conv = C2Tuple_usizeTransactionZ_clone((LDKC2Tuple_usizeTransactionZ*)untag_ptr(o));
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = COption_C2Tuple_usizeTransactionZZ_some(o_conv);
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
-}
-
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1none(JNIEnv *env, jclass clz) {
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = COption_C2Tuple_usizeTransactionZZ_none();
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       if (!ptr_is_owned(_res)) return;
-       void* _res_ptr = untag_ptr(_res);
-       CHECK_ACCESS(_res_ptr);
-       LDKCOption_C2Tuple_usizeTransactionZZ _res_conv = *(LDKCOption_C2Tuple_usizeTransactionZZ*)(_res_ptr);
-       FREE(untag_ptr(_res));
-       COption_C2Tuple_usizeTransactionZZ_free(_res_conv);
-}
-
-static inline uint64_t COption_C2Tuple_usizeTransactionZZ_clone_ptr(LDKCOption_C2Tuple_usizeTransactionZZ *NONNULL_PTR arg) {
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = COption_C2Tuple_usizeTransactionZZ_clone(arg);
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
-}
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCOption_C2Tuple_usizeTransactionZZ* arg_conv = (LDKCOption_C2Tuple_usizeTransactionZZ*)untag_ptr(arg);
-       int64_t ret_conv = COption_C2Tuple_usizeTransactionZZ_clone_ptr(arg_conv);
-       return ret_conv;
-}
-
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKCOption_C2Tuple_usizeTransactionZZ* orig_conv = (LDKCOption_C2Tuple_usizeTransactionZZ*)untag_ptr(orig);
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = COption_C2Tuple_usizeTransactionZZ_clone(orig_conv);
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
-}
-
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1FixedPenaltyScorerDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        LDKFixedPenaltyScorer o_conv;
        o_conv.inner = untag_ptr(o);
@@ -16887,44 +18300,51 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C3Tuple_1ChannelAnnouncementCh
        C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free(_res_conv);
 }
 
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1free(JNIEnv *env, jclass clz, int64_tArray _res) {
-       LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ _res_constr;
-       _res_constr.datalen = (*env)->GetArrayLength(env, _res);
-       if (_res_constr.datalen > 0)
-               _res_constr.data = MALLOC(_res_constr.datalen * sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ Elements");
-       else
-               _res_constr.data = NULL;
-       int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
-       for (size_t h = 0; h < _res_constr.datalen; h++) {
-               int64_t _res_conv_59 = _res_vals[h];
-               void* _res_conv_59_ptr = untag_ptr(_res_conv_59);
-               CHECK_ACCESS(_res_conv_59_ptr);
-               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ _res_conv_59_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(_res_conv_59_ptr);
-               FREE(untag_ptr(_res_conv_59));
-               _res_constr.data[h] = _res_conv_59_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, _res, _res_vals, 0);
-       CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free(_res_constr);
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1some(JNIEnv *env, jclass clz, int64_t o) {
+       void* o_ptr = untag_ptr(o);
+       CHECK_ACCESS(o_ptr);
+       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ o_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(o_ptr);
+       o_conv = C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_clone((LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)untag_ptr(o));
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_some(o_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
 }
 
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1NodeAnnouncementZ_1free(JNIEnv *env, jclass clz, int64_tArray _res) {
-       LDKCVec_NodeAnnouncementZ _res_constr;
-       _res_constr.datalen = (*env)->GetArrayLength(env, _res);
-       if (_res_constr.datalen > 0)
-               _res_constr.data = MALLOC(_res_constr.datalen * sizeof(LDKNodeAnnouncement), "LDKCVec_NodeAnnouncementZ Elements");
-       else
-               _res_constr.data = NULL;
-       int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
-       for (size_t s = 0; s < _res_constr.datalen; s++) {
-               int64_t _res_conv_18 = _res_vals[s];
-               LDKNodeAnnouncement _res_conv_18_conv;
-               _res_conv_18_conv.inner = untag_ptr(_res_conv_18);
-               _res_conv_18_conv.is_owned = ptr_is_owned(_res_conv_18);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(_res_conv_18_conv);
-               _res_constr.data[s] = _res_conv_18_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, _res, _res_vals, 0);
-       CVec_NodeAnnouncementZ_free(_res_constr);
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1none(JNIEnv *env, jclass clz) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_none();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ _res_conv = *(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free(_res_conv);
+}
+
+static inline uint64_t COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone_ptr(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *NONNULL_PTR arg) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(arg);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ* arg_conv = (LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)untag_ptr(arg);
+       int64_t ret_conv = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone_ptr(arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ* orig_conv = (LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)untag_ptr(orig);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(orig_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneLightningErrorZ_1ok(JNIEnv *env, jclass clz) {
@@ -17887,6 +19307,81 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeyNoneZ_1cl
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1ScalarZ_1some(JNIEnv *env, jclass clz, int64_t o) {
+       void* o_ptr = untag_ptr(o);
+       CHECK_ACCESS(o_ptr);
+       LDKBigEndianScalar o_conv = *(LDKBigEndianScalar*)(o_ptr);
+       // WARNING: we may need a move here but no clone is available for LDKBigEndianScalar
+       LDKCOption_ScalarZ *ret_copy = MALLOC(sizeof(LDKCOption_ScalarZ), "LDKCOption_ScalarZ");
+       *ret_copy = COption_ScalarZ_some(o_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1ScalarZ_1none(JNIEnv *env, jclass clz) {
+       LDKCOption_ScalarZ *ret_copy = MALLOC(sizeof(LDKCOption_ScalarZ), "LDKCOption_ScalarZ");
+       *ret_copy = COption_ScalarZ_none();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1ScalarZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCOption_ScalarZ _res_conv = *(LDKCOption_ScalarZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       COption_ScalarZ_free(_res_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1ok(JNIEnv *env, jclass clz, int8_tArray o) {
+       LDKThirtyTwoBytes o_ref;
+       CHECK((*env)->GetArrayLength(env, o) == 32);
+       (*env)->GetByteArrayRegion(env, o, 0, 32, o_ref.data);
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = CResult_SharedSecretNoneZ_ok(o_ref);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1err(JNIEnv *env, jclass clz) {
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = CResult_SharedSecretNoneZ_err();
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_SharedSecretNoneZ* o_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_SharedSecretNoneZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_SharedSecretNoneZ _res_conv = *(LDKCResult_SharedSecretNoneZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_SharedSecretNoneZ_free(_res_conv);
+}
+
+static inline uint64_t CResult_SharedSecretNoneZ_clone_ptr(LDKCResult_SharedSecretNoneZ *NONNULL_PTR arg) {
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = CResult_SharedSecretNoneZ_clone(arg);
+       return tag_ptr(ret_conv, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKCResult_SharedSecretNoneZ* arg_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(arg);
+       int64_t ret_conv = CResult_SharedSecretNoneZ_clone_ptr(arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_SharedSecretNoneZ* orig_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(orig);
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = CResult_SharedSecretNoneZ_clone(orig_conv);
+       return tag_ptr(ret_conv, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SignDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        void* o_ptr = untag_ptr(o);
        CHECK_ACCESS(o_ptr);
@@ -19595,6 +21090,44 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentIdPaymentEr
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKInFlightHtlcs o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       // WARNING: we need a move here but no clone is available for LDKInFlightHtlcs
+       
+       LDKCResult_InFlightHtlcsDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InFlightHtlcsDecodeErrorZ), "LDKCResult_InFlightHtlcsDecodeErrorZ");
+       *ret_conv = CResult_InFlightHtlcsDecodeErrorZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       LDKDecodeError e_conv;
+       e_conv.inner = untag_ptr(e);
+       e_conv.is_owned = ptr_is_owned(e);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(e_conv);
+       e_conv = DecodeError_clone(&e_conv);
+       LDKCResult_InFlightHtlcsDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InFlightHtlcsDecodeErrorZ), "LDKCResult_InFlightHtlcsDecodeErrorZ");
+       *ret_conv = CResult_InFlightHtlcsDecodeErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_InFlightHtlcsDecodeErrorZ* o_conv = (LDKCResult_InFlightHtlcsDecodeErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_InFlightHtlcsDecodeErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_InFlightHtlcsDecodeErrorZ _res_conv = *(LDKCResult_InFlightHtlcsDecodeErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_InFlightHtlcsDecodeErrorZ_free(_res_conv);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SiPrefixParseErrorZ_1ok(JNIEnv *env, jclass clz, jclass o) {
        LDKSiPrefix o_conv = LDKSiPrefix_from_java(env, o);
        LDKCResult_SiPrefixParseErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_SiPrefixParseErrorZ), "LDKCResult_SiPrefixParseErrorZ");
@@ -21055,6 +22588,37 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErro
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1ok(JNIEnv *env, jclass clz) {
+       LDKCResult_NoneSendErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneSendErrorZ), "LDKCResult_NoneSendErrorZ");
+       *ret_conv = CResult_NoneSendErrorZ_ok();
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       void* e_ptr = untag_ptr(e);
+       CHECK_ACCESS(e_ptr);
+       LDKSendError e_conv = *(LDKSendError*)(e_ptr);
+       e_conv = SendError_clone((LDKSendError*)untag_ptr(e));
+       LDKCResult_NoneSendErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneSendErrorZ), "LDKCResult_NoneSendErrorZ");
+       *ret_conv = CResult_NoneSendErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_NoneSendErrorZ* o_conv = (LDKCResult_NoneSendErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_NoneSendErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_NoneSendErrorZ _res_conv = *(LDKCResult_NoneSendErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_NoneSendErrorZ_free(_res_conv);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1u32GraphSyncErrorZ_1ok(JNIEnv *env, jclass clz, int32_t o) {
        LDKCResult_u32GraphSyncErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_u32GraphSyncErrorZ), "LDKCResult_u32GraphSyncErrorZ");
        *ret_conv = CResult_u32GraphSyncErrorZ_ok(o);
@@ -22210,6 +23774,61 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecod
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKOnionMessage o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv = OnionMessage_clone(&o_conv);
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = CResult_OnionMessageDecodeErrorZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       LDKDecodeError e_conv;
+       e_conv.inner = untag_ptr(e);
+       e_conv.is_owned = ptr_is_owned(e);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(e_conv);
+       e_conv = DecodeError_clone(&e_conv);
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = CResult_OnionMessageDecodeErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_OnionMessageDecodeErrorZ* o_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_OnionMessageDecodeErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_OnionMessageDecodeErrorZ _res_conv = *(LDKCResult_OnionMessageDecodeErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_OnionMessageDecodeErrorZ_free(_res_conv);
+}
+
+static inline uint64_t CResult_OnionMessageDecodeErrorZ_clone_ptr(LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR arg) {
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = CResult_OnionMessageDecodeErrorZ_clone(arg);
+       return tag_ptr(ret_conv, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKCResult_OnionMessageDecodeErrorZ* arg_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(arg);
+       int64_t ret_conv = CResult_OnionMessageDecodeErrorZ_clone_ptr(arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_OnionMessageDecodeErrorZ* orig_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(orig);
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = CResult_OnionMessageDecodeErrorZ_clone(orig_conv);
+       return tag_ptr(ret_conv, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PingDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        LDKPing o_conv;
        o_conv.inner = untag_ptr(o);
@@ -23584,7 +25203,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Event_1payment_1path_1succe
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Event_1payment_1path_1failed(JNIEnv *env, jclass clz, int8_tArray payment_id, int8_tArray payment_hash, jboolean rejected_by_dest, int64_t network_update, jboolean all_paths_failed, int64_tArray path, int64_t short_channel_id, int64_t retry) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Event_1payment_1path_1failed(JNIEnv *env, jclass clz, int8_tArray payment_id, int8_tArray payment_hash, jboolean payment_failed_permanently, int64_t network_update, jboolean all_paths_failed, int64_tArray path, int64_t short_channel_id, int64_t retry) {
        LDKThirtyTwoBytes payment_id_ref;
        CHECK((*env)->GetArrayLength(env, payment_id) == 32);
        (*env)->GetByteArrayRegion(env, payment_id, 0, 32, payment_id_ref.data);
@@ -23622,7 +25241,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Event_1payment_1path_1faile
        CHECK_INNER_FIELD_ACCESS_OR_NULL(retry_conv);
        retry_conv = RouteParameters_clone(&retry_conv);
        LDKEvent *ret_copy = MALLOC(sizeof(LDKEvent), "LDKEvent");
-       *ret_copy = Event_payment_path_failed(payment_id_ref, payment_hash_ref, rejected_by_dest, network_update_conv, all_paths_failed, path_constr, short_channel_id_conv, retry_conv);
+       *ret_copy = Event_payment_path_failed(payment_id_ref, payment_hash_ref, payment_failed_permanently, network_update_conv, all_paths_failed, path_constr, short_channel_id_conv, retry_conv);
        int64_t ret_ref = tag_ptr(ret_copy, true);
        return ret_ref;
 }
@@ -24012,7 +25631,10 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1send_1cha
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast_1channel_1announcement(JNIEnv *env, jclass clz, int64_t msg, int64_t update_msg) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1send_1channel_1announcement(JNIEnv *env, jclass clz, int8_tArray node_id, int64_t msg, int64_t update_msg) {
+       LDKPublicKey node_id_ref;
+       CHECK((*env)->GetArrayLength(env, node_id) == 33);
+       (*env)->GetByteArrayRegion(env, node_id, 0, 33, node_id_ref.compressed_form);
        LDKChannelAnnouncement msg_conv;
        msg_conv.inner = untag_ptr(msg);
        msg_conv.is_owned = ptr_is_owned(msg);
@@ -24024,19 +25646,24 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast
        CHECK_INNER_FIELD_ACCESS_OR_NULL(update_msg_conv);
        update_msg_conv = ChannelUpdate_clone(&update_msg_conv);
        LDKMessageSendEvent *ret_copy = MALLOC(sizeof(LDKMessageSendEvent), "LDKMessageSendEvent");
-       *ret_copy = MessageSendEvent_broadcast_channel_announcement(msg_conv, update_msg_conv);
+       *ret_copy = MessageSendEvent_send_channel_announcement(node_id_ref, msg_conv, update_msg_conv);
        int64_t ret_ref = tag_ptr(ret_copy, true);
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast_1node_1announcement(JNIEnv *env, jclass clz, int64_t msg) {
-       LDKNodeAnnouncement msg_conv;
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast_1channel_1announcement(JNIEnv *env, jclass clz, int64_t msg, int64_t update_msg) {
+       LDKChannelAnnouncement msg_conv;
        msg_conv.inner = untag_ptr(msg);
        msg_conv.is_owned = ptr_is_owned(msg);
        CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_conv);
-       msg_conv = NodeAnnouncement_clone(&msg_conv);
+       msg_conv = ChannelAnnouncement_clone(&msg_conv);
+       LDKChannelUpdate update_msg_conv;
+       update_msg_conv.inner = untag_ptr(update_msg);
+       update_msg_conv.is_owned = ptr_is_owned(update_msg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(update_msg_conv);
+       update_msg_conv = ChannelUpdate_clone(&update_msg_conv);
        LDKMessageSendEvent *ret_copy = MALLOC(sizeof(LDKMessageSendEvent), "LDKMessageSendEvent");
-       *ret_copy = MessageSendEvent_broadcast_node_announcement(msg_conv);
+       *ret_copy = MessageSendEvent_broadcast_channel_announcement(msg_conv, update_msg_conv);
        int64_t ret_ref = tag_ptr(ret_copy, true);
        return ret_ref;
 }
@@ -24151,6 +25778,15 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageSendEventsProvider_1fre
        MessageSendEventsProvider_free(this_ptr_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageProvider_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKOnionMessageProvider this_ptr_conv = *(LDKOnionMessageProvider*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       OnionMessageProvider_free(this_ptr_conv);
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_EventsProvider_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
        if (!ptr_is_owned(this_ptr)) return;
        void* this_ptr_ptr = untag_ptr(this_ptr);
@@ -24404,6 +26040,39 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Persister_1free(JNIEnv *env, j
        Persister_free(this_ptr_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_FutureCallback_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKFutureCallback this_ptr_conv = *(LDKFutureCallback*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       FutureCallback_free(this_ptr_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Future_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKFuture this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       Future_free(this_obj_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Future_1register_1callback_1fn(JNIEnv *env, jclass clz, int64_t this_arg, int64_t callback) {
+       LDKFuture this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       void* callback_ptr = untag_ptr(callback);
+       CHECK_ACCESS(callback_ptr);
+       LDKFutureCallback callback_conv = *(LDKFutureCallback*)(callback_ptr);
+       if (callback_conv.free == LDKFutureCallback_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKFutureCallback_JCalls_cloned(&callback_conv);
+       }
+       Future_register_callback_fn(&this_arg_conv, callback_conv);
+}
+
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_Level_1clone(JNIEnv *env, jclass clz, int64_t orig) {
        LDKLevel* orig_conv = (LDKLevel*)untag_ptr(orig);
        jclass ret_conv = LDKLevel_to_java(env, Level_clone(orig_conv));
@@ -24751,8 +26420,27 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1set_1c
        ChannelHandshakeConfig_set_commit_upfront_shutdown_pubkey(&this_ptr_conv, val);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1new(JNIEnv *env, jclass clz, int32_t minimum_depth_arg, int16_t our_to_self_delay_arg, int64_t our_htlc_minimum_msat_arg, int8_t max_inbound_htlc_value_in_flight_percent_of_channel_arg, jboolean negotiate_scid_privacy_arg, jboolean announced_channel_arg, jboolean commit_upfront_shutdown_pubkey_arg) {
-       LDKChannelHandshakeConfig ret_var = ChannelHandshakeConfig_new(minimum_depth_arg, our_to_self_delay_arg, our_htlc_minimum_msat_arg, max_inbound_htlc_value_in_flight_percent_of_channel_arg, negotiate_scid_privacy_arg, announced_channel_arg, commit_upfront_shutdown_pubkey_arg);
+JNIEXPORT int32_t JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1get_1their_1channel_1reserve_1proportional_1millionths(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       LDKChannelHandshakeConfig this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       int32_t ret_conv = ChannelHandshakeConfig_get_their_channel_reserve_proportional_millionths(&this_ptr_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1set_1their_1channel_1reserve_1proportional_1millionths(JNIEnv *env, jclass clz, int64_t this_ptr, int32_t val) {
+       LDKChannelHandshakeConfig this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       ChannelHandshakeConfig_set_their_channel_reserve_proportional_millionths(&this_ptr_conv, val);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1new(JNIEnv *env, jclass clz, int32_t minimum_depth_arg, int16_t our_to_self_delay_arg, int64_t our_htlc_minimum_msat_arg, int8_t max_inbound_htlc_value_in_flight_percent_of_channel_arg, jboolean negotiate_scid_privacy_arg, jboolean announced_channel_arg, jboolean commit_upfront_shutdown_pubkey_arg, int32_t their_channel_reserve_proportional_millionths_arg) {
+       LDKChannelHandshakeConfig ret_var = ChannelHandshakeConfig_new(minimum_depth_arg, our_to_self_delay_arg, our_htlc_minimum_msat_arg, max_inbound_htlc_value_in_flight_percent_of_channel_arg, negotiate_scid_privacy_arg, announced_channel_arg, commit_upfront_shutdown_pubkey_arg, their_channel_reserve_proportional_millionths_arg);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
@@ -26328,9 +28016,23 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1contentious_1claim
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1maybe_1claimable_1htlcawaiting_1timeout(JNIEnv *env, jclass clz, int64_t claimable_amount_satoshis, int32_t claimable_height) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1maybe_1timeout_1claimable_1htlc(JNIEnv *env, jclass clz, int64_t claimable_amount_satoshis, int32_t claimable_height) {
+       LDKBalance *ret_copy = MALLOC(sizeof(LDKBalance), "LDKBalance");
+       *ret_copy = Balance_maybe_timeout_claimable_htlc(claimable_amount_satoshis, claimable_height);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1maybe_1preimage_1claimable_1htlc(JNIEnv *env, jclass clz, int64_t claimable_amount_satoshis, int32_t expiry_height) {
        LDKBalance *ret_copy = MALLOC(sizeof(LDKBalance), "LDKBalance");
-       *ret_copy = Balance_maybe_claimable_htlcawaiting_timeout(claimable_amount_satoshis, claimable_height);
+       *ret_copy = Balance_maybe_preimage_claimable_htlc(claimable_amount_satoshis, expiry_height);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1counterparty_1revoked_1output_1claimable(JNIEnv *env, jclass clz, int64_t claimable_amount_satoshis) {
+       LDKBalance *ret_copy = MALLOC(sizeof(LDKBalance), "LDKBalance");
+       *ret_copy = Balance_counterparty_revoked_output_claimable(claimable_amount_satoshis);
        int64_t ret_ref = tag_ptr(ret_copy, true);
        return ret_ref;
 }
@@ -29830,36 +31532,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1funding_1tr
        return tag_ptr(ret_conv, true);
 }
 
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1broadcast_1node_1announcement(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray rgb, int8_tArray alias, int64_tArray addresses) {
-       LDKChannelManager this_arg_conv;
-       this_arg_conv.inner = untag_ptr(this_arg);
-       this_arg_conv.is_owned = ptr_is_owned(this_arg);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
-       this_arg_conv.is_owned = false;
-       LDKThreeBytes rgb_ref;
-       CHECK((*env)->GetArrayLength(env, rgb) == 3);
-       (*env)->GetByteArrayRegion(env, rgb, 0, 3, rgb_ref.data);
-       LDKThirtyTwoBytes alias_ref;
-       CHECK((*env)->GetArrayLength(env, alias) == 32);
-       (*env)->GetByteArrayRegion(env, alias, 0, 32, alias_ref.data);
-       LDKCVec_NetAddressZ addresses_constr;
-       addresses_constr.datalen = (*env)->GetArrayLength(env, addresses);
-       if (addresses_constr.datalen > 0)
-               addresses_constr.data = MALLOC(addresses_constr.datalen * sizeof(LDKNetAddress), "LDKCVec_NetAddressZ Elements");
-       else
-               addresses_constr.data = NULL;
-       int64_t* addresses_vals = (*env)->GetLongArrayElements (env, addresses, NULL);
-       for (size_t m = 0; m < addresses_constr.datalen; m++) {
-               int64_t addresses_conv_12 = addresses_vals[m];
-               void* addresses_conv_12_ptr = untag_ptr(addresses_conv_12);
-               CHECK_ACCESS(addresses_conv_12_ptr);
-               LDKNetAddress addresses_conv_12_conv = *(LDKNetAddress*)(addresses_conv_12_ptr);
-               addresses_constr.data[m] = addresses_conv_12_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, addresses, addresses_vals, 0);
-       ChannelManager_broadcast_node_announcement(&this_arg_conv, rgb_ref, alias_ref, addresses_constr);
-}
-
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1update_1channel_1config(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray counterparty_node_id, jobjectArray channel_ids, int64_t config) {
        LDKChannelManager this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
@@ -30151,6 +31823,19 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1await_1persist
        ChannelManager_await_persistable_update(&this_arg_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1get_1persistable_1update_1future(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKChannelManager this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKFuture ret_var = ChannelManager_get_persistable_update_future(&this_arg_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1current_1best_1block(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKChannelManager this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
@@ -32711,6 +34396,67 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_UpdateAddHTLC_1clone(JNIEnv
        return ret_ref;
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessage_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKOnionMessage this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       OnionMessage_free(this_obj_conv);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_OnionMessage_1get_1blinding_1point(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       LDKOnionMessage this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       int8_tArray ret_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 33, OnionMessage_get_blinding_point(&this_ptr_conv).compressed_form);
+       return ret_arr;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessage_1set_1blinding_1point(JNIEnv *env, jclass clz, int64_t this_ptr, int8_tArray val) {
+       LDKOnionMessage this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       LDKPublicKey val_ref;
+       CHECK((*env)->GetArrayLength(env, val) == 33);
+       (*env)->GetByteArrayRegion(env, val, 0, 33, val_ref.compressed_form);
+       OnionMessage_set_blinding_point(&this_ptr_conv, val_ref);
+}
+
+static inline uint64_t OnionMessage_clone_ptr(LDKOnionMessage *NONNULL_PTR arg) {
+       LDKOnionMessage ret_var = OnionMessage_clone(arg);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessage_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKOnionMessage arg_conv;
+       arg_conv.inner = untag_ptr(arg);
+       arg_conv.is_owned = ptr_is_owned(arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(arg_conv);
+       arg_conv.is_owned = false;
+       int64_t ret_conv = OnionMessage_clone_ptr(&arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessage_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKOnionMessage orig_conv;
+       orig_conv.inner = untag_ptr(orig);
+       orig_conv.is_owned = ptr_is_owned(orig);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(orig_conv);
+       orig_conv.is_owned = false;
+       LDKOnionMessage ret_var = OnionMessage_clone(&orig_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_UpdateFulfillHTLC_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKUpdateFulfillHTLC this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -36047,6 +37793,15 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1free(JN
        RoutingMessageHandler_free(this_ptr_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKOnionMessageHandler this_ptr_conv = *(LDKOnionMessageHandler*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       OnionMessageHandler_free(this_ptr_conv);
+}
+
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_AcceptChannel_1write(JNIEnv *env, jclass clz, int64_t obj) {
        LDKAcceptChannel obj_conv;
        obj_conv.inner = untag_ptr(obj);
@@ -36461,6 +38216,29 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_UpdateAddHTLC_1read(JNIEnv
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessage_1read(JNIEnv *env, jclass clz, int8_tArray ser) {
+       LDKu8slice ser_ref;
+       ser_ref.datalen = (*env)->GetArrayLength(env, ser);
+       ser_ref.data = (*env)->GetByteArrayElements (env, ser, NULL);
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = OnionMessage_read(ser_ref);
+       (*env)->ReleaseByteArrayElements(env, ser, (int8_t*)ser_ref.data, 0);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_OnionMessage_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKOnionMessage obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = OnionMessage_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_Ping_1write(JNIEnv *env, jclass clz, int64_t obj) {
        LDKPing obj_conv;
        obj_conv.inner = untag_ptr(obj);
@@ -36863,6 +38641,28 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_
        return tag_ptr(ret_ret, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1OnionMessageProvider(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKIgnoringMessageHandler this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKOnionMessageProvider* ret_ret = MALLOC(sizeof(LDKOnionMessageProvider), "LDKOnionMessageProvider");
+       *ret_ret = IgnoringMessageHandler_as_OnionMessageProvider(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1OnionMessageHandler(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKIgnoringMessageHandler this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKOnionMessageHandler* ret_ret = MALLOC(sizeof(LDKOnionMessageHandler), "LDKOnionMessageHandler");
+       *ret_ret = IgnoringMessageHandler_as_OnionMessageHandler(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1CustomMessageReader(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKIgnoringMessageHandler this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
@@ -36985,7 +38785,34 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageHandler_1set_1route_1ha
        MessageHandler_set_route_handler(&this_ptr_conv, val_conv);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageHandler_1new(JNIEnv *env, jclass clz, int64_t chan_handler_arg, int64_t route_handler_arg) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageHandler_1get_1onion_1message_1handler(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       LDKMessageHandler this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       // WARNING: This object doesn't live past this scope, needs clone!
+       int64_t ret_ret = tag_ptr(MessageHandler_get_onion_message_handler(&this_ptr_conv), false);
+       return ret_ret;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageHandler_1set_1onion_1message_1handler(JNIEnv *env, jclass clz, int64_t this_ptr, int64_t val) {
+       LDKMessageHandler this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       void* val_ptr = untag_ptr(val);
+       CHECK_ACCESS(val_ptr);
+       LDKOnionMessageHandler val_conv = *(LDKOnionMessageHandler*)(val_ptr);
+       if (val_conv.free == LDKOnionMessageHandler_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKOnionMessageHandler_JCalls_cloned(&val_conv);
+       }
+       MessageHandler_set_onion_message_handler(&this_ptr_conv, val_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageHandler_1new(JNIEnv *env, jclass clz, int64_t chan_handler_arg, int64_t route_handler_arg, int64_t onion_message_handler_arg) {
        void* chan_handler_arg_ptr = untag_ptr(chan_handler_arg);
        CHECK_ACCESS(chan_handler_arg_ptr);
        LDKChannelMessageHandler chan_handler_arg_conv = *(LDKChannelMessageHandler*)(chan_handler_arg_ptr);
@@ -37000,7 +38827,14 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageHandler_1new(JNIEnv
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKRoutingMessageHandler_JCalls_cloned(&route_handler_arg_conv);
        }
-       LDKMessageHandler ret_var = MessageHandler_new(chan_handler_arg_conv, route_handler_arg_conv);
+       void* onion_message_handler_arg_ptr = untag_ptr(onion_message_handler_arg);
+       CHECK_ACCESS(onion_message_handler_arg_ptr);
+       LDKOnionMessageHandler onion_message_handler_arg_conv = *(LDKOnionMessageHandler*)(onion_message_handler_arg_ptr);
+       if (onion_message_handler_arg_conv.free == LDKOnionMessageHandler_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKOnionMessageHandler_JCalls_cloned(&onion_message_handler_arg_conv);
+       }
+       LDKMessageHandler ret_var = MessageHandler_new(chan_handler_arg_conv, route_handler_arg_conv, onion_message_handler_arg_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
@@ -37111,7 +38945,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1free(JNIEnv *env,
        PeerManager_free(this_obj_conv);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new(JNIEnv *env, jclass clz, int64_t message_handler, int8_tArray our_node_secret, int8_tArray ephemeral_random_data, int64_t logger, int64_t custom_message_handler) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new(JNIEnv *env, jclass clz, int64_t message_handler, int8_tArray our_node_secret, int64_t current_time, int8_tArray ephemeral_random_data, int64_t logger, int64_t custom_message_handler) {
        LDKMessageHandler message_handler_conv;
        message_handler_conv.inner = untag_ptr(message_handler);
        message_handler_conv.is_owned = ptr_is_owned(message_handler);
@@ -37139,7 +38973,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new(JNIEnv *en
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKCustomMessageHandler_JCalls_cloned(&custom_message_handler_conv);
        }
-       LDKPeerManager ret_var = PeerManager_new(message_handler_conv, our_node_secret_ref, ephemeral_random_data_ref, logger_conv, custom_message_handler_conv);
+       LDKPeerManager ret_var = PeerManager_new(message_handler_conv, our_node_secret_ref, current_time, ephemeral_random_data_ref, logger_conv, custom_message_handler_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
@@ -37294,6 +39128,36 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1timer_1tick_1occu
        PeerManager_timer_tick_occurred(&this_arg_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1broadcast_1node_1announcement(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray rgb, int8_tArray alias, int64_tArray addresses) {
+       LDKPeerManager this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKThreeBytes rgb_ref;
+       CHECK((*env)->GetArrayLength(env, rgb) == 3);
+       (*env)->GetByteArrayRegion(env, rgb, 0, 3, rgb_ref.data);
+       LDKThirtyTwoBytes alias_ref;
+       CHECK((*env)->GetArrayLength(env, alias) == 32);
+       (*env)->GetByteArrayRegion(env, alias, 0, 32, alias_ref.data);
+       LDKCVec_NetAddressZ addresses_constr;
+       addresses_constr.datalen = (*env)->GetArrayLength(env, addresses);
+       if (addresses_constr.datalen > 0)
+               addresses_constr.data = MALLOC(addresses_constr.datalen * sizeof(LDKNetAddress), "LDKCVec_NetAddressZ Elements");
+       else
+               addresses_constr.data = NULL;
+       int64_t* addresses_vals = (*env)->GetLongArrayElements (env, addresses, NULL);
+       for (size_t m = 0; m < addresses_constr.datalen; m++) {
+               int64_t addresses_conv_12 = addresses_vals[m];
+               void* addresses_conv_12_ptr = untag_ptr(addresses_conv_12);
+               CHECK_ACCESS(addresses_conv_12_ptr);
+               LDKNetAddress addresses_conv_12_conv = *(LDKNetAddress*)(addresses_conv_12_ptr);
+               addresses_constr.data[m] = addresses_conv_12_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, addresses, addresses_vals, 0);
+       PeerManager_broadcast_node_announcement(&this_arg_conv, rgb_ref, alias_ref, addresses_constr);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_htlc_1success_1tx_1weight(JNIEnv *env, jclass clz, jboolean opt_anchors) {
        int64_t ret_conv = htlc_success_tx_weight(opt_anchors);
        return ret_conv;
@@ -39656,6 +41520,22 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelTypeFeatures_1free(JNIE
        ChannelTypeFeatures_free(this_obj_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InitFeatures_1known_1channel_1features(JNIEnv *env, jclass clz) {
+       LDKInitFeatures ret_var = InitFeatures_known_channel_features();
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1known_1channel_1features(JNIEnv *env, jclass clz) {
+       LDKNodeFeatures ret_var = NodeFeatures_known_channel_features();
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InitFeatures_1empty(JNIEnv *env, jclass clz) {
        LDKInitFeatures ret_var = InitFeatures_empty();
        int64_t ret_ref = 0;
@@ -40765,6 +42645,82 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1requires_1sh
        return ret_conv;
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InitFeatures_1set_1onion_1messages_1optional(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKInitFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       InitFeatures_set_onion_messages_optional(&this_arg_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InitFeatures_1set_1onion_1messages_1required(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKInitFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       InitFeatures_set_onion_messages_required(&this_arg_conv);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InitFeatures_1supports_1onion_1messages(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKInitFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       jboolean ret_conv = InitFeatures_supports_onion_messages(&this_arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1onion_1messages_1optional(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKNodeFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       NodeFeatures_set_onion_messages_optional(&this_arg_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1onion_1messages_1required(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKNodeFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       NodeFeatures_set_onion_messages_required(&this_arg_conv);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1supports_1onion_1messages(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKNodeFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       jboolean ret_conv = NodeFeatures_supports_onion_messages(&this_arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InitFeatures_1requires_1onion_1messages(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKInitFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       jboolean ret_conv = InitFeatures_requires_onion_messages(&this_arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1requires_1onion_1messages(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKNodeFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       jboolean ret_conv = NodeFeatures_requires_onion_messages(&this_arg_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InitFeatures_1set_1channel_1type_1optional(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKInitFeatures this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
@@ -44836,6 +46792,15 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LockableScore_1free(JNIEnv *en
        LockableScore_free(this_ptr_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_WriteableScore_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKWriteableScore this_ptr_conv = *(LDKWriteableScore*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       WriteableScore_free(this_ptr_conv);
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKMultiThreadedLockableScore this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -44844,6 +46809,49 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1fr
        MultiThreadedLockableScore_free(this_obj_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MultiThreadedScoreLock_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKMultiThreadedScoreLock this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       MultiThreadedScoreLock_free(this_obj_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MultiThreadedScoreLock_1as_1Score(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKMultiThreadedScoreLock this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKScore* ret_ret = MALLOC(sizeof(LDKScore), "LDKScore");
+       *ret_ret = MultiThreadedScoreLock_as_Score(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_MultiThreadedScoreLock_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKMultiThreadedScoreLock obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = MultiThreadedScoreLock_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1as_1LockableScore(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKMultiThreadedLockableScore this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKLockableScore* ret_ret = MALLOC(sizeof(LDKLockableScore), "LDKLockableScore");
+       *ret_ret = MultiThreadedLockableScore_as_LockableScore(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1write(JNIEnv *env, jclass clz, int64_t obj) {
        LDKMultiThreadedLockableScore obj_conv;
        obj_conv.inner = untag_ptr(obj);
@@ -44857,6 +46865,17 @@ JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableSc
        return ret_arr;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1as_1WriteableScore(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKMultiThreadedLockableScore this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKWriteableScore* ret_ret = MALLOC(sizeof(LDKWriteableScore), "LDKWriteableScore");
+       *ret_ret = MultiThreadedLockableScore_as_WriteableScore(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1new(JNIEnv *env, jclass clz, int64_t score) {
        void* score_ptr = untag_ptr(score);
        CHECK_ACCESS(score_ptr);
@@ -45445,6 +47464,272 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ProbabilisticScorer_1read(J
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKBlindedRoute this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       BlindedRoute_free(this_obj_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BlindedHop_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKBlindedHop this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       BlindedHop_free(this_obj_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1new(JNIEnv *env, jclass clz, jobjectArray node_pks, int64_t keys_manager) {
+       LDKCVec_PublicKeyZ node_pks_constr;
+       node_pks_constr.datalen = (*env)->GetArrayLength(env, node_pks);
+       if (node_pks_constr.datalen > 0)
+               node_pks_constr.data = MALLOC(node_pks_constr.datalen * sizeof(LDKPublicKey), "LDKCVec_PublicKeyZ Elements");
+       else
+               node_pks_constr.data = NULL;
+       for (size_t i = 0; i < node_pks_constr.datalen; i++) {
+               int8_tArray node_pks_conv_8 = (*env)->GetObjectArrayElement(env, node_pks, i);
+               LDKPublicKey node_pks_conv_8_ref;
+               CHECK((*env)->GetArrayLength(env, node_pks_conv_8) == 33);
+               (*env)->GetByteArrayRegion(env, node_pks_conv_8, 0, 33, node_pks_conv_8_ref.compressed_form);
+               node_pks_constr.data[i] = node_pks_conv_8_ref;
+       }
+       void* keys_manager_ptr = untag_ptr(keys_manager);
+       if (ptr_is_owned(keys_manager)) { CHECK_ACCESS(keys_manager_ptr); }
+       LDKKeysInterface* keys_manager_conv = (LDKKeysInterface*)keys_manager_ptr;
+       LDKCResult_BlindedRouteNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteNoneZ), "LDKCResult_BlindedRouteNoneZ");
+       *ret_conv = BlindedRoute_new(node_pks_constr, keys_manager_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKBlindedRoute obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = BlindedRoute_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1read(JNIEnv *env, jclass clz, int8_tArray ser) {
+       LDKu8slice ser_ref;
+       ser_ref.datalen = (*env)->GetArrayLength(env, ser);
+       ser_ref.data = (*env)->GetByteArrayElements (env, ser, NULL);
+       LDKCResult_BlindedRouteDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteDecodeErrorZ), "LDKCResult_BlindedRouteDecodeErrorZ");
+       *ret_conv = BlindedRoute_read(ser_ref);
+       (*env)->ReleaseByteArrayElements(env, ser, (int8_t*)ser_ref.data, 0);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_BlindedHop_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKBlindedHop obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = BlindedHop_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BlindedHop_1read(JNIEnv *env, jclass clz, int8_tArray ser) {
+       LDKu8slice ser_ref;
+       ser_ref.datalen = (*env)->GetArrayLength(env, ser);
+       ser_ref.data = (*env)->GetByteArrayElements (env, ser, NULL);
+       LDKCResult_BlindedHopDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedHopDecodeErrorZ), "LDKCResult_BlindedHopDecodeErrorZ");
+       *ret_conv = BlindedHop_read(ser_ref);
+       (*env)->ReleaseByteArrayElements(env, ser, (int8_t*)ser_ref.data, 0);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKOnionMessenger this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       OnionMessenger_free(this_obj_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Destination_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKDestination this_ptr_conv = *(LDKDestination*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       Destination_free(this_ptr_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Destination_1node(JNIEnv *env, jclass clz, int8_tArray a) {
+       LDKPublicKey a_ref;
+       CHECK((*env)->GetArrayLength(env, a) == 33);
+       (*env)->GetByteArrayRegion(env, a, 0, 33, a_ref.compressed_form);
+       LDKDestination *ret_copy = MALLOC(sizeof(LDKDestination), "LDKDestination");
+       *ret_copy = Destination_node(a_ref);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Destination_1blinded_1route(JNIEnv *env, jclass clz, int64_t a) {
+       LDKBlindedRoute a_conv;
+       a_conv.inner = untag_ptr(a);
+       a_conv.is_owned = ptr_is_owned(a);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(a_conv);
+       // WARNING: we need a move here but no clone is available for LDKBlindedRoute
+       
+       LDKDestination *ret_copy = MALLOC(sizeof(LDKDestination), "LDKDestination");
+       *ret_copy = Destination_blinded_route(a_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_SendError_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKSendError this_ptr_conv = *(LDKSendError*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       SendError_free(this_ptr_conv);
+}
+
+static inline uint64_t SendError_clone_ptr(LDKSendError *NONNULL_PTR arg) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_clone(arg);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKSendError* arg_conv = (LDKSendError*)untag_ptr(arg);
+       int64_t ret_conv = SendError_clone_ptr(arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKSendError* orig_conv = (LDKSendError*)untag_ptr(orig);
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_clone(orig_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1secp256k1(JNIEnv *env, jclass clz, jclass a) {
+       LDKSecp256k1Error a_conv = LDKSecp256k1Error_from_java(env, a);
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_secp256k1(a_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1too_1big_1packet(JNIEnv *env, jclass clz) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_too_big_packet();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1too_1few_1blinded_1hops(JNIEnv *env, jclass clz) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_too_few_blinded_hops();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1invalid_1first_1hop(JNIEnv *env, jclass clz) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_invalid_first_hop();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1buffer_1full(JNIEnv *env, jclass clz) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_buffer_full();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1new(JNIEnv *env, jclass clz, int64_t keys_manager, int64_t logger) {
+       void* keys_manager_ptr = untag_ptr(keys_manager);
+       CHECK_ACCESS(keys_manager_ptr);
+       LDKKeysInterface keys_manager_conv = *(LDKKeysInterface*)(keys_manager_ptr);
+       if (keys_manager_conv.free == LDKKeysInterface_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKKeysInterface_JCalls_cloned(&keys_manager_conv);
+       }
+       void* logger_ptr = untag_ptr(logger);
+       CHECK_ACCESS(logger_ptr);
+       LDKLogger logger_conv = *(LDKLogger*)(logger_ptr);
+       if (logger_conv.free == LDKLogger_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKLogger_JCalls_cloned(&logger_conv);
+       }
+       LDKOnionMessenger ret_var = OnionMessenger_new(keys_manager_conv, logger_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1send_1onion_1message(JNIEnv *env, jclass clz, int64_t this_arg, jobjectArray intermediate_nodes, int64_t destination, int64_t reply_path) {
+       LDKOnionMessenger this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKCVec_PublicKeyZ intermediate_nodes_constr;
+       intermediate_nodes_constr.datalen = (*env)->GetArrayLength(env, intermediate_nodes);
+       if (intermediate_nodes_constr.datalen > 0)
+               intermediate_nodes_constr.data = MALLOC(intermediate_nodes_constr.datalen * sizeof(LDKPublicKey), "LDKCVec_PublicKeyZ Elements");
+       else
+               intermediate_nodes_constr.data = NULL;
+       for (size_t i = 0; i < intermediate_nodes_constr.datalen; i++) {
+               int8_tArray intermediate_nodes_conv_8 = (*env)->GetObjectArrayElement(env, intermediate_nodes, i);
+               LDKPublicKey intermediate_nodes_conv_8_ref;
+               CHECK((*env)->GetArrayLength(env, intermediate_nodes_conv_8) == 33);
+               (*env)->GetByteArrayRegion(env, intermediate_nodes_conv_8, 0, 33, intermediate_nodes_conv_8_ref.compressed_form);
+               intermediate_nodes_constr.data[i] = intermediate_nodes_conv_8_ref;
+       }
+       void* destination_ptr = untag_ptr(destination);
+       CHECK_ACCESS(destination_ptr);
+       LDKDestination destination_conv = *(LDKDestination*)(destination_ptr);
+       // WARNING: we may need a move here but no clone is available for LDKDestination
+       LDKBlindedRoute reply_path_conv;
+       reply_path_conv.inner = untag_ptr(reply_path);
+       reply_path_conv.is_owned = ptr_is_owned(reply_path);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(reply_path_conv);
+       reply_path_conv.is_owned = false;
+       LDKCResult_NoneSendErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneSendErrorZ), "LDKCResult_NoneSendErrorZ");
+       *ret_conv = OnionMessenger_send_onion_message(&this_arg_conv, intermediate_nodes_constr, destination_conv, reply_path_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1as_1OnionMessageHandler(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKOnionMessenger this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKOnionMessageHandler* ret_ret = MALLOC(sizeof(LDKOnionMessageHandler), "LDKOnionMessageHandler");
+       *ret_ret = OnionMessenger_as_OnionMessageHandler(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1as_1OnionMessageProvider(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKOnionMessenger this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKOnionMessageProvider* ret_ret = MALLOC(sizeof(LDKOnionMessageProvider), "LDKOnionMessageProvider");
+       *ret_ret = OnionMessenger_as_OnionMessageProvider(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_FilesystemPersister_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKFilesystemPersister this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -45581,11 +47866,17 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BackgroundProcessor_1start(
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_cloned(&logger_conv);
        }
-       LDKMultiThreadedLockableScore scorer_conv;
-       scorer_conv.inner = untag_ptr(scorer);
-       scorer_conv.is_owned = ptr_is_owned(scorer);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(scorer_conv);
-       scorer_conv.is_owned = false;
+       void* scorer_ptr = untag_ptr(scorer);
+       CHECK_ACCESS(scorer_ptr);
+       LDKCOption_WriteableScoreZ scorer_conv = *(LDKCOption_WriteableScoreZ*)(scorer_ptr);
+       // WARNING: we may need a move here but no clone is available for LDKCOption_WriteableScoreZ
+       if (scorer_conv.tag == LDKCOption_WriteableScoreZ_Some) {
+               // Manually implement clone for Java trait instances
+               if (scorer_conv.some.free == LDKWriteableScore_JCalls_free) {
+                       // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+                       LDKWriteableScore_JCalls_cloned(&scorer_conv.some);
+               }
+       }
        LDKBackgroundProcessor ret_var = BackgroundProcessor_start(persister_conv, event_handler_conv, &chain_monitor_conv, &channel_manager_conv, gossip_sync_conv, &peer_manager_conv, logger_conv, scorer_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
@@ -45881,6 +48172,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Invoice_1clone(JNIEnv *env,
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Invoice_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKInvoice o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = Invoice_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKSignedRawInvoice this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -45934,6 +48235,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1clone(JNI
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKSignedRawInvoice o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = SignedRawInvoice_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RawInvoice_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKRawInvoice this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -46014,6 +48325,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RawInvoice_1clone(JNIEnv *e
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RawInvoice_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKRawInvoice o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = RawInvoice_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RawDataPart_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKRawDataPart this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -46094,6 +48415,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RawDataPart_1clone(JNIEnv *
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RawDataPart_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKRawDataPart o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = RawDataPart_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PositiveTimestamp_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKPositiveTimestamp this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -46147,6 +48478,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PositiveTimestamp_1clone(JN
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PositiveTimestamp_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKPositiveTimestamp o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = PositiveTimestamp_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_SiPrefix_1clone(JNIEnv *env, jclass clz, int64_t orig) {
        LDKSiPrefix* orig_conv = (LDKSiPrefix*)untag_ptr(orig);
        jclass ret_conv = LDKSiPrefix_to_java(env, SiPrefix_clone(orig_conv));
@@ -46180,6 +48521,12 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_SiPrefix_1eq(JNIEnv *env,
        return ret_conv;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SiPrefix_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKSiPrefix* o_conv = (LDKSiPrefix*)untag_ptr(o);
+       int64_t ret_conv = SiPrefix_hash(o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SiPrefix_1multiplier(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKSiPrefix* this_arg_conv = (LDKSiPrefix*)untag_ptr(this_arg);
        int64_t ret_conv = SiPrefix_multiplier(this_arg_conv);
@@ -46718,6 +49065,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoiceSignature_1clone(JNI
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoiceSignature_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKInvoiceSignature o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = InvoiceSignature_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InvoiceSignature_1eq(JNIEnv *env, jclass clz, int64_t a, int64_t b) {
        LDKInvoiceSignature a_conv;
        a_conv.inner = untag_ptr(a);
@@ -46820,14 +49177,14 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1raw_1invo
        return ret_ref;
 }
 
-JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1hash(JNIEnv *env, jclass clz, int64_t this_arg) {
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1signable_1hash(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKSignedRawInvoice this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
        this_arg_conv.is_owned = ptr_is_owned(this_arg);
        CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
        this_arg_conv.is_owned = false;
        int8_tArray ret_arr = (*env)->NewByteArray(env, 32);
-       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, *SignedRawInvoice_hash(&this_arg_conv));
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, *SignedRawInvoice_signable_hash(&this_arg_conv));
        return ret_arr;
 }
 
@@ -46865,14 +49222,14 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1check_1s
        return ret_conv;
 }
 
-JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_RawInvoice_1hash(JNIEnv *env, jclass clz, int64_t this_arg) {
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_RawInvoice_1signable_1hash(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKRawInvoice this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
        this_arg_conv.is_owned = ptr_is_owned(this_arg);
        CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
        this_arg_conv.is_owned = false;
        int8_tArray ret_arr = (*env)->NewByteArray(env, 32);
-       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, RawInvoice_hash(&this_arg_conv).data);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, RawInvoice_signable_hash(&this_arg_conv).data);
        return ret_arr;
 }
 
@@ -47685,7 +50042,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PaymentError_1sending(JNIEn
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1new(JNIEnv *env, jclass clz, int64_t payer, int64_t router, int64_t scorer, int64_t logger, int64_t event_handler, int64_t retry) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1new(JNIEnv *env, jclass clz, int64_t payer, int64_t router, int64_t logger, int64_t event_handler, int64_t retry) {
        void* payer_ptr = untag_ptr(payer);
        CHECK_ACCESS(payer_ptr);
        LDKPayer payer_conv = *(LDKPayer*)(payer_ptr);
@@ -47700,11 +50057,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1new(JNIEnv *e
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKRouter_JCalls_cloned(&router_conv);
        }
-       LDKMultiThreadedLockableScore scorer_conv;
-       scorer_conv.inner = untag_ptr(scorer);
-       scorer_conv.is_owned = ptr_is_owned(scorer);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(scorer_conv);
-       scorer_conv.is_owned = false;
        void* logger_ptr = untag_ptr(logger);
        CHECK_ACCESS(logger_ptr);
        LDKLogger logger_conv = *(LDKLogger*)(logger_ptr);
@@ -47723,7 +50075,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1new(JNIEnv *e
        CHECK_ACCESS(retry_ptr);
        LDKRetry retry_conv = *(LDKRetry*)(retry_ptr);
        retry_conv = Retry_clone((LDKRetry*)untag_ptr(retry));
-       LDKInvoicePayer ret_var = InvoicePayer_new(payer_conv, router_conv, &scorer_conv, logger_conv, event_handler_conv, retry_conv);
+       LDKInvoicePayer ret_var = InvoicePayer_new(payer_conv, router_conv, logger_conv, event_handler_conv, retry_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
@@ -47803,6 +50155,59 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1as_1EventHand
        return tag_ptr(ret_ret, true);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKInFlightHtlcs this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       InFlightHtlcs_free(this_obj_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1used_1liquidity_1msat(JNIEnv *env, jclass clz, int64_t this_arg, int64_t source, int64_t target, int64_t channel_scid) {
+       LDKInFlightHtlcs this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKNodeId source_conv;
+       source_conv.inner = untag_ptr(source);
+       source_conv.is_owned = ptr_is_owned(source);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_conv);
+       source_conv.is_owned = false;
+       LDKNodeId target_conv;
+       target_conv.inner = untag_ptr(target);
+       target_conv.is_owned = ptr_is_owned(target);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_conv);
+       target_conv.is_owned = false;
+       LDKCOption_u64Z *ret_copy = MALLOC(sizeof(LDKCOption_u64Z), "LDKCOption_u64Z");
+       *ret_copy = InFlightHtlcs_used_liquidity_msat(&this_arg_conv, &source_conv, &target_conv, channel_scid);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKInFlightHtlcs obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = InFlightHtlcs_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1read(JNIEnv *env, jclass clz, int8_tArray ser) {
+       LDKu8slice ser_ref;
+       ser_ref.datalen = (*env)->GetArrayLength(env, ser);
+       ser_ref.data = (*env)->GetByteArrayElements (env, ser, NULL);
+       LDKCResult_InFlightHtlcsDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InFlightHtlcsDecodeErrorZ), "LDKCResult_InFlightHtlcsDecodeErrorZ");
+       *ret_conv = InFlightHtlcs_read(ser_ref);
+       (*env)->ReleaseByteArrayElements(env, ser, (int8_t*)ser_ref.data, 0);
+       return tag_ptr(ret_conv, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_create_1phantom_1invoice(JNIEnv *env, jclass clz, int64_t amt_msat, int8_tArray payment_hash, jstring description, int32_t invoice_expiry_delta_secs, int64_tArray phantom_route_hints, int64_t keys_manager, jclass network) {
        void* amt_msat_ptr = untag_ptr(amt_msat);
        CHECK_ACCESS(amt_msat_ptr);
@@ -47997,7 +50402,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1free(JNIEnv *en
        DefaultRouter_free(this_obj_conv);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1new(JNIEnv *env, jclass clz, int64_t network_graph, int64_t logger, int8_tArray random_seed_bytes) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1new(JNIEnv *env, jclass clz, int64_t network_graph, int64_t logger, int8_tArray random_seed_bytes, int64_t scorer) {
        LDKNetworkGraph network_graph_conv;
        network_graph_conv.inner = untag_ptr(network_graph);
        network_graph_conv.is_owned = ptr_is_owned(network_graph);
@@ -48013,7 +50418,14 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1new(JNIEnv *
        LDKThirtyTwoBytes random_seed_bytes_ref;
        CHECK((*env)->GetArrayLength(env, random_seed_bytes) == 32);
        (*env)->GetByteArrayRegion(env, random_seed_bytes, 0, 32, random_seed_bytes_ref.data);
-       LDKDefaultRouter ret_var = DefaultRouter_new(&network_graph_conv, logger_conv, random_seed_bytes_ref);
+       void* scorer_ptr = untag_ptr(scorer);
+       CHECK_ACCESS(scorer_ptr);
+       LDKLockableScore scorer_conv = *(LDKLockableScore*)(scorer_ptr);
+       if (scorer_conv.free == LDKLockableScore_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKLockableScore_JCalls_cloned(&scorer_conv);
+       }
+       LDKDefaultRouter ret_var = DefaultRouter_new(&network_graph_conv, logger_conv, random_seed_bytes_ref, scorer_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
index 0adbfe3a11ab5b8f3420d4116cbddba92a5987e3..313b459ad84ab8264f6dbb11c2fec09abf640147 100644 (file)
@@ -939,6 +939,27 @@ static inline jclass LDKSiPrefix_to_java(JNIEnv *env, LDKSiPrefix val) {
        }
 }
 
+struct LDKThirtyTwoBytes BigEndianScalar_get_bytes (struct LDKBigEndianScalar* thing) {
+       LDKThirtyTwoBytes ret = { .data = *thing->big_endian_bytes };
+       return ret;
+}
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_BigEndianScalar_1get_1bytes(JNIEnv *env, jclass clz, int64_t thing) {
+       LDKBigEndianScalar* thing_conv = (LDKBigEndianScalar*)untag_ptr(thing);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, 32);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, BigEndianScalar_get_bytes(thing_conv).data);
+       return ret_arr;
+}
+
+static void BigEndianScalar_free (struct LDKBigEndianScalar thing) {}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BigEndianScalar_1free(JNIEnv *env, jclass clz, int64_t thing) {
+       if (!ptr_is_owned(thing)) return;
+       void* thing_ptr = untag_ptr(thing);
+       CHECK_ACCESS(thing_ptr);
+       LDKBigEndianScalar thing_conv = *(LDKBigEndianScalar*)(thing_ptr);
+       FREE(untag_ptr(thing));
+       BigEndianScalar_free(thing_conv);
+}
+
 static jclass LDKBech32Error_MissingSeparator_class = NULL;
 static jmethodID LDKBech32Error_MissingSeparator_meth = NULL;
 static jclass LDKBech32Error_InvalidChecksum_class = NULL;
@@ -1039,6 +1060,85 @@ uint64_t TxOut_get_value (struct LDKTxOut* thing) {      return thing->value;}JNIEXPO
        return ret_conv;
 }
 
+static inline struct LDKBlindedRoute CResult_BlindedRouteNoneZ_get_ok(LDKCResult_BlindedRouteNoneZ *NONNULL_PTR owner){
+       LDKBlindedRoute ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedRouteNoneZ* owner_conv = (LDKCResult_BlindedRouteNoneZ*)untag_ptr(owner);
+       LDKBlindedRoute ret_var = CResult_BlindedRouteNoneZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline void CResult_BlindedRouteNoneZ_get_err(LDKCResult_BlindedRouteNoneZ *NONNULL_PTR owner){
+CHECK(!owner->result_ok);
+       return *owner->contents.err;
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedRouteNoneZ* owner_conv = (LDKCResult_BlindedRouteNoneZ*)untag_ptr(owner);
+       CResult_BlindedRouteNoneZ_get_err(owner_conv);
+}
+
+static inline struct LDKBlindedRoute CResult_BlindedRouteDecodeErrorZ_get_ok(LDKCResult_BlindedRouteDecodeErrorZ *NONNULL_PTR owner){
+       LDKBlindedRoute ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedRouteDecodeErrorZ* owner_conv = (LDKCResult_BlindedRouteDecodeErrorZ*)untag_ptr(owner);
+       LDKBlindedRoute ret_var = CResult_BlindedRouteDecodeErrorZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKDecodeError CResult_BlindedRouteDecodeErrorZ_get_err(LDKCResult_BlindedRouteDecodeErrorZ *NONNULL_PTR owner){
+       LDKDecodeError ret = *owner->contents.err;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedRouteDecodeErrorZ* owner_conv = (LDKCResult_BlindedRouteDecodeErrorZ*)untag_ptr(owner);
+       LDKDecodeError ret_var = CResult_BlindedRouteDecodeErrorZ_get_err(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKBlindedHop CResult_BlindedHopDecodeErrorZ_get_ok(LDKCResult_BlindedHopDecodeErrorZ *NONNULL_PTR owner){
+       LDKBlindedHop ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedHopDecodeErrorZ* owner_conv = (LDKCResult_BlindedHopDecodeErrorZ*)untag_ptr(owner);
+       LDKBlindedHop ret_var = CResult_BlindedHopDecodeErrorZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKDecodeError CResult_BlindedHopDecodeErrorZ_get_err(LDKCResult_BlindedHopDecodeErrorZ *NONNULL_PTR owner){
+       LDKDecodeError ret = *owner->contents.err;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_BlindedHopDecodeErrorZ* owner_conv = (LDKCResult_BlindedHopDecodeErrorZ*)untag_ptr(owner);
+       LDKDecodeError ret_var = CResult_BlindedHopDecodeErrorZ_get_err(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 static inline void CResult_NoneNoneZ_get_ok(LDKCResult_NoneNoneZ *NONNULL_PTR owner){
 CHECK(owner->result_ok);
        return *owner->contents.result;
@@ -1534,6 +1634,622 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ShutdownScriptInva
        return ret_ref;
 }
 
+static inline LDKCVec_RouteHopZ CVec_RouteHopZ_clone(const LDKCVec_RouteHopZ *orig) {
+       LDKCVec_RouteHopZ ret = { .data = MALLOC(sizeof(LDKRouteHop) * orig->datalen, "LDKCVec_RouteHopZ clone bytes"), .datalen = orig->datalen };
+       for (size_t i = 0; i < ret.datalen; i++) {
+               ret.data[i] = RouteHop_clone(&orig->data[i]);
+       }
+       return ret;
+}
+typedef struct LDKScore_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       jmethodID channel_penalty_msat_meth;
+       jmethodID payment_path_failed_meth;
+       jmethodID payment_path_successful_meth;
+       jmethodID probe_failed_meth;
+       jmethodID probe_successful_meth;
+       jmethodID write_meth;
+} LDKScore_JCalls;
+static void LDKScore_JCalls_free(void* this_arg) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+uint64_t channel_penalty_msat_LDKScore_jcall(const void* this_arg, uint64_t short_channel_id, const LDKNodeId * source, const LDKNodeId * target, LDKChannelUsage usage) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int64_t short_channel_id_conv = short_channel_id;
+       LDKNodeId source_var = *source;
+       int64_t source_ref = 0;
+       source_var = NodeId_clone(&source_var);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_var);
+       source_ref = tag_ptr(source_var.inner, source_var.is_owned);
+       LDKNodeId target_var = *target;
+       int64_t target_ref = 0;
+       target_var = NodeId_clone(&target_var);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_var);
+       target_ref = tag_ptr(target_var.inner, target_var.is_owned);
+       LDKChannelUsage usage_var = usage;
+       int64_t usage_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(usage_var);
+       usage_ref = tag_ptr(usage_var.inner, usage_var.is_owned);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       int64_t ret = (*env)->CallLongMethod(env, obj, j_calls->channel_penalty_msat_meth, short_channel_id_conv, source_ref, target_ref, usage_ref);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to channel_penalty_msat in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret;
+}
+void payment_path_failed_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       int64_t short_channel_id_conv = short_channel_id;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->payment_path_failed_meth, path_arr, short_channel_id_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to payment_path_failed in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void payment_path_successful_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->payment_path_successful_meth, path_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to payment_path_successful in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void probe_failed_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       int64_t short_channel_id_conv = short_channel_id;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->probe_failed_meth, path_arr, short_channel_id_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to probe_failed in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void probe_successful_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->probe_successful_meth, path_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to probe_successful in LDKScore from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+LDKCVec_u8Z write_LDKScore_jcall(const void* this_arg) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       int8_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->write_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to write in LDKScore from rust threw an exception.");
+       }
+       LDKCVec_u8Z ret_ref;
+       ret_ref.datalen = (*env)->GetArrayLength(env, ret);
+       ret_ref.data = MALLOC(ret_ref.datalen, "LDKCVec_u8Z Bytes");
+       (*env)->GetByteArrayRegion(env, ret, 0, ret_ref.datalen, ret_ref.data);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_ref;
+}
+static void LDKScore_JCalls_cloned(LDKScore* new_obj) {
+       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+}
+static inline LDKScore LDKScore_init (JNIEnv *env, jclass clz, jobject o) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKScore_JCalls *calls = MALLOC(sizeof(LDKScore_JCalls), "LDKScore_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->channel_penalty_msat_meth = (*env)->GetMethodID(env, c, "channel_penalty_msat", "(JJJJ)J");
+       CHECK(calls->channel_penalty_msat_meth != NULL);
+       calls->payment_path_failed_meth = (*env)->GetMethodID(env, c, "payment_path_failed", "([JJ)V");
+       CHECK(calls->payment_path_failed_meth != NULL);
+       calls->payment_path_successful_meth = (*env)->GetMethodID(env, c, "payment_path_successful", "([J)V");
+       CHECK(calls->payment_path_successful_meth != NULL);
+       calls->probe_failed_meth = (*env)->GetMethodID(env, c, "probe_failed", "([JJ)V");
+       CHECK(calls->probe_failed_meth != NULL);
+       calls->probe_successful_meth = (*env)->GetMethodID(env, c, "probe_successful", "([J)V");
+       CHECK(calls->probe_successful_meth != NULL);
+       calls->write_meth = (*env)->GetMethodID(env, c, "write", "()[B");
+       CHECK(calls->write_meth != NULL);
+
+       LDKScore ret = {
+               .this_arg = (void*) calls,
+               .channel_penalty_msat = channel_penalty_msat_LDKScore_jcall,
+               .payment_path_failed = payment_path_failed_LDKScore_jcall,
+               .payment_path_successful = payment_path_successful_LDKScore_jcall,
+               .probe_failed = probe_failed_LDKScore_jcall,
+               .probe_successful = probe_successful_LDKScore_jcall,
+               .write = write_LDKScore_jcall,
+               .free = LDKScore_JCalls_free,
+       };
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKScore_1new(JNIEnv *env, jclass clz, jobject o) {
+       LDKScore *res_ptr = MALLOC(sizeof(LDKScore), "LDKScore");
+       *res_ptr = LDKScore_init(env, clz, o);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Score_1channel_1penalty_1msat(JNIEnv *env, jclass clz, int64_t this_arg, int64_t short_channel_id, int64_t source, int64_t target, int64_t usage) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKNodeId source_conv;
+       source_conv.inner = untag_ptr(source);
+       source_conv.is_owned = ptr_is_owned(source);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_conv);
+       source_conv.is_owned = false;
+       LDKNodeId target_conv;
+       target_conv.inner = untag_ptr(target);
+       target_conv.is_owned = ptr_is_owned(target);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_conv);
+       target_conv.is_owned = false;
+       LDKChannelUsage usage_conv;
+       usage_conv.inner = untag_ptr(usage);
+       usage_conv.is_owned = ptr_is_owned(usage);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(usage_conv);
+       usage_conv = ChannelUsage_clone(&usage_conv);
+       int64_t ret_conv = (this_arg_conv->channel_penalty_msat)(this_arg_conv->this_arg, short_channel_id, &source_conv, &target_conv, usage_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->payment_path_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->payment_path_successful)(this_arg_conv->this_arg, path_constr);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->probe_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->probe_successful)(this_arg_conv->this_arg, path_constr);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_Score_1write(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
+       LDKCVec_u8Z ret_var = (this_arg_conv->write)(this_arg_conv->this_arg);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+typedef struct LDKLockableScore_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       jmethodID lock_meth;
+} LDKLockableScore_JCalls;
+static void LDKLockableScore_JCalls_free(void* this_arg) {
+       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+LDKScore lock_LDKLockableScore_jcall(const void* this_arg) {
+       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->lock_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to lock in LDKLockableScore from rust threw an exception.");
+       }
+       void* ret_ptr = untag_ptr(ret);
+       CHECK_ACCESS(ret_ptr);
+       LDKScore ret_conv = *(LDKScore*)(ret_ptr);
+       if (ret_conv.free == LDKScore_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKScore_JCalls_cloned(&ret_conv);
+       }// WARNING: we may need a move here but no clone is available for LDKScore
+       
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+static void LDKLockableScore_JCalls_cloned(LDKLockableScore* new_obj) {
+       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+}
+static inline LDKLockableScore LDKLockableScore_init (JNIEnv *env, jclass clz, jobject o) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKLockableScore_JCalls *calls = MALLOC(sizeof(LDKLockableScore_JCalls), "LDKLockableScore_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->lock_meth = (*env)->GetMethodID(env, c, "lock", "()J");
+       CHECK(calls->lock_meth != NULL);
+
+       LDKLockableScore ret = {
+               .this_arg = (void*) calls,
+               .lock = lock_LDKLockableScore_jcall,
+               .free = LDKLockableScore_JCalls_free,
+       };
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKLockableScore_1new(JNIEnv *env, jclass clz, jobject o) {
+       LDKLockableScore *res_ptr = MALLOC(sizeof(LDKLockableScore), "LDKLockableScore");
+       *res_ptr = LDKLockableScore_init(env, clz, o);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LockableScore_1lock(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKLockableScore* this_arg_conv = (LDKLockableScore*)this_arg_ptr;
+       LDKScore* ret_ret = MALLOC(sizeof(LDKScore), "LDKScore");
+       *ret_ret = (this_arg_conv->lock)(this_arg_conv->this_arg);
+       return tag_ptr(ret_ret, true);
+}
+
+typedef struct LDKWriteableScore_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       LDKLockableScore_JCalls* LockableScore;
+       jmethodID write_meth;
+} LDKWriteableScore_JCalls;
+static void LDKWriteableScore_JCalls_free(void* this_arg) {
+       LDKWriteableScore_JCalls *j_calls = (LDKWriteableScore_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+LDKCVec_u8Z write_LDKWriteableScore_jcall(const void* this_arg) {
+       LDKWriteableScore_JCalls *j_calls = (LDKWriteableScore_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       int8_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->write_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to write in LDKWriteableScore from rust threw an exception.");
+       }
+       LDKCVec_u8Z ret_ref;
+       ret_ref.datalen = (*env)->GetArrayLength(env, ret);
+       ret_ref.data = MALLOC(ret_ref.datalen, "LDKCVec_u8Z Bytes");
+       (*env)->GetByteArrayRegion(env, ret, 0, ret_ref.datalen, ret_ref.data);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_ref;
+}
+static void LDKWriteableScore_JCalls_cloned(LDKWriteableScore* new_obj) {
+       LDKWriteableScore_JCalls *j_calls = (LDKWriteableScore_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+       atomic_fetch_add_explicit(&j_calls->LockableScore->refcnt, 1, memory_order_release);
+}
+static inline LDKWriteableScore LDKWriteableScore_init (JNIEnv *env, jclass clz, jobject o, jobject LockableScore) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKWriteableScore_JCalls *calls = MALLOC(sizeof(LDKWriteableScore_JCalls), "LDKWriteableScore_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->write_meth = (*env)->GetMethodID(env, c, "write", "()[B");
+       CHECK(calls->write_meth != NULL);
+
+       LDKWriteableScore ret = {
+               .this_arg = (void*) calls,
+               .write = write_LDKWriteableScore_jcall,
+               .free = LDKWriteableScore_JCalls_free,
+               .LockableScore = LDKLockableScore_init(env, clz, LockableScore),
+       };
+       calls->LockableScore = ret.LockableScore.this_arg;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKWriteableScore_1new(JNIEnv *env, jclass clz, jobject o, jobject LockableScore) {
+       LDKWriteableScore *res_ptr = MALLOC(sizeof(LDKWriteableScore), "LDKWriteableScore");
+       *res_ptr = LDKWriteableScore_init(env, clz, o, LockableScore);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKWriteableScore_1get_1LockableScore(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKWriteableScore *inp = (LDKWriteableScore *)untag_ptr(arg);
+       return tag_ptr(&inp->LockableScore, false);
+}
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_WriteableScore_1write(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKWriteableScore* this_arg_conv = (LDKWriteableScore*)this_arg_ptr;
+       LDKCVec_u8Z ret_var = (this_arg_conv->write)(this_arg_conv->this_arg);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+static jclass LDKCOption_WriteableScoreZ_Some_class = NULL;
+static jmethodID LDKCOption_WriteableScoreZ_Some_meth = NULL;
+static jclass LDKCOption_WriteableScoreZ_None_class = NULL;
+static jmethodID LDKCOption_WriteableScoreZ_None_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKCOption_1WriteableScoreZ_init (JNIEnv *env, jclass clz) {
+       LDKCOption_WriteableScoreZ_Some_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_WriteableScoreZ$Some"));
+       CHECK(LDKCOption_WriteableScoreZ_Some_class != NULL);
+       LDKCOption_WriteableScoreZ_Some_meth = (*env)->GetMethodID(env, LDKCOption_WriteableScoreZ_Some_class, "<init>", "(J)V");
+       CHECK(LDKCOption_WriteableScoreZ_Some_meth != NULL);
+       LDKCOption_WriteableScoreZ_None_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_WriteableScoreZ$None"));
+       CHECK(LDKCOption_WriteableScoreZ_None_class != NULL);
+       LDKCOption_WriteableScoreZ_None_meth = (*env)->GetMethodID(env, LDKCOption_WriteableScoreZ_None_class, "<init>", "()V");
+       CHECK(LDKCOption_WriteableScoreZ_None_meth != NULL);
+}
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1WriteableScoreZ_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKCOption_WriteableScoreZ *obj = (LDKCOption_WriteableScoreZ*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKCOption_WriteableScoreZ_Some: {
+                       LDKWriteableScore* some_ret = MALLOC(sizeof(LDKWriteableScore), "LDKWriteableScore");
+                       *some_ret = obj->some;
+                       // WARNING: We likely need to clone here, but no clone is available, so we just do it for Java instances
+                       if ((*some_ret).free == LDKWriteableScore_JCalls_free) {
+                               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+                               LDKWriteableScore_JCalls_cloned(&(*some_ret));
+                       }
+                       return (*env)->NewObject(env, LDKCOption_WriteableScoreZ_Some_class, LDKCOption_WriteableScoreZ_Some_meth, tag_ptr(some_ret, true));
+               }
+               case LDKCOption_WriteableScoreZ_None: {
+                       return (*env)->NewObject(env, LDKCOption_WriteableScoreZ_None_class, LDKCOption_WriteableScoreZ_None_meth);
+               }
+               default: abort();
+       }
+}
 static inline void CResult_NoneErrorZ_get_ok(LDKCResult_NoneErrorZ *NONNULL_PTR owner){
 CHECK(owner->result_ok);
        return *owner->contents.result;
@@ -1581,13 +2297,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RouteHopDecodeErro
        return ret_ref;
 }
 
-static inline LDKCVec_RouteHopZ CVec_RouteHopZ_clone(const LDKCVec_RouteHopZ *orig) {
-       LDKCVec_RouteHopZ ret = { .data = MALLOC(sizeof(LDKRouteHop) * orig->datalen, "LDKCVec_RouteHopZ clone bytes"), .datalen = orig->datalen };
-       for (size_t i = 0; i < ret.datalen; i++) {
-               ret.data[i] = RouteHop_clone(&orig->data[i]);
-       }
-       return ret;
-}
 static inline LDKCVec_CVec_RouteHopZZ CVec_CVec_RouteHopZZ_clone(const LDKCVec_CVec_RouteHopZZ *orig) {
        LDKCVec_CVec_RouteHopZZ ret = { .data = MALLOC(sizeof(LDKCVec_RouteHopZ) * orig->datalen, "LDKCVec_CVec_RouteHopZZ clone bytes"), .datalen = orig->datalen };
        for (size_t i = 0; i < ret.datalen; i++) {
@@ -2443,7 +3152,7 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKEvent_1ref_1from_1ptr(JN
                        (*env)->SetByteArrayRegion(env, payment_id_arr, 0, 32, obj->payment_path_failed.payment_id.data);
                        int8_tArray payment_hash_arr = (*env)->NewByteArray(env, 32);
                        (*env)->SetByteArrayRegion(env, payment_hash_arr, 0, 32, obj->payment_path_failed.payment_hash.data);
-                       jboolean rejected_by_dest_conv = obj->payment_path_failed.rejected_by_dest;
+                       jboolean payment_failed_permanently_conv = obj->payment_path_failed.payment_failed_permanently;
                        int64_t network_update_ref = tag_ptr(&obj->payment_path_failed.network_update, false);
                        jboolean all_paths_failed_conv = obj->payment_path_failed.all_paths_failed;
                        LDKCVec_RouteHopZ path_var = obj->payment_path_failed.path;
@@ -2463,7 +3172,7 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKEvent_1ref_1from_1ptr(JN
                        int64_t retry_ref = 0;
                        CHECK_INNER_FIELD_ACCESS_OR_NULL(retry_var);
                        retry_ref = tag_ptr(retry_var.inner, false);
-                       return (*env)->NewObject(env, LDKEvent_PaymentPathFailed_class, LDKEvent_PaymentPathFailed_meth, payment_id_arr, payment_hash_arr, rejected_by_dest_conv, network_update_ref, all_paths_failed_conv, path_arr, short_channel_id_ref, retry_ref);
+                       return (*env)->NewObject(env, LDKEvent_PaymentPathFailed_class, LDKEvent_PaymentPathFailed_meth, payment_id_arr, payment_hash_arr, payment_failed_permanently_conv, network_update_ref, all_paths_failed_conv, path_arr, short_channel_id_ref, retry_ref);
                }
                case LDKEvent_ProbeSuccessful: {
                        int8_tArray payment_id_arr = (*env)->NewByteArray(env, 32);
@@ -2725,10 +3434,10 @@ static jclass LDKMessageSendEvent_SendShutdown_class = NULL;
 static jmethodID LDKMessageSendEvent_SendShutdown_meth = NULL;
 static jclass LDKMessageSendEvent_SendChannelReestablish_class = NULL;
 static jmethodID LDKMessageSendEvent_SendChannelReestablish_meth = NULL;
+static jclass LDKMessageSendEvent_SendChannelAnnouncement_class = NULL;
+static jmethodID LDKMessageSendEvent_SendChannelAnnouncement_meth = NULL;
 static jclass LDKMessageSendEvent_BroadcastChannelAnnouncement_class = NULL;
 static jmethodID LDKMessageSendEvent_BroadcastChannelAnnouncement_meth = NULL;
-static jclass LDKMessageSendEvent_BroadcastNodeAnnouncement_class = NULL;
-static jmethodID LDKMessageSendEvent_BroadcastNodeAnnouncement_meth = NULL;
 static jclass LDKMessageSendEvent_BroadcastChannelUpdate_class = NULL;
 static jmethodID LDKMessageSendEvent_BroadcastChannelUpdate_meth = NULL;
 static jclass LDKMessageSendEvent_SendChannelUpdate_class = NULL;
@@ -2799,16 +3508,16 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKMessageSendEvent_init
        CHECK(LDKMessageSendEvent_SendChannelReestablish_class != NULL);
        LDKMessageSendEvent_SendChannelReestablish_meth = (*env)->GetMethodID(env, LDKMessageSendEvent_SendChannelReestablish_class, "<init>", "([BJ)V");
        CHECK(LDKMessageSendEvent_SendChannelReestablish_meth != NULL);
+       LDKMessageSendEvent_SendChannelAnnouncement_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKMessageSendEvent$SendChannelAnnouncement"));
+       CHECK(LDKMessageSendEvent_SendChannelAnnouncement_class != NULL);
+       LDKMessageSendEvent_SendChannelAnnouncement_meth = (*env)->GetMethodID(env, LDKMessageSendEvent_SendChannelAnnouncement_class, "<init>", "([BJJ)V");
+       CHECK(LDKMessageSendEvent_SendChannelAnnouncement_meth != NULL);
        LDKMessageSendEvent_BroadcastChannelAnnouncement_class =
                (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKMessageSendEvent$BroadcastChannelAnnouncement"));
        CHECK(LDKMessageSendEvent_BroadcastChannelAnnouncement_class != NULL);
        LDKMessageSendEvent_BroadcastChannelAnnouncement_meth = (*env)->GetMethodID(env, LDKMessageSendEvent_BroadcastChannelAnnouncement_class, "<init>", "(JJ)V");
        CHECK(LDKMessageSendEvent_BroadcastChannelAnnouncement_meth != NULL);
-       LDKMessageSendEvent_BroadcastNodeAnnouncement_class =
-               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKMessageSendEvent$BroadcastNodeAnnouncement"));
-       CHECK(LDKMessageSendEvent_BroadcastNodeAnnouncement_class != NULL);
-       LDKMessageSendEvent_BroadcastNodeAnnouncement_meth = (*env)->GetMethodID(env, LDKMessageSendEvent_BroadcastNodeAnnouncement_class, "<init>", "(J)V");
-       CHECK(LDKMessageSendEvent_BroadcastNodeAnnouncement_meth != NULL);
        LDKMessageSendEvent_BroadcastChannelUpdate_class =
                (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKMessageSendEvent$BroadcastChannelUpdate"));
        CHECK(LDKMessageSendEvent_BroadcastChannelUpdate_class != NULL);
@@ -2947,23 +3656,29 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKMessageSendEvent_1ref_1f
                        msg_ref = tag_ptr(msg_var.inner, false);
                        return (*env)->NewObject(env, LDKMessageSendEvent_SendChannelReestablish_class, LDKMessageSendEvent_SendChannelReestablish_meth, node_id_arr, msg_ref);
                }
-               case LDKMessageSendEvent_BroadcastChannelAnnouncement: {
-                       LDKChannelAnnouncement msg_var = obj->broadcast_channel_announcement.msg;
+               case LDKMessageSendEvent_SendChannelAnnouncement: {
+                       int8_tArray node_id_arr = (*env)->NewByteArray(env, 33);
+                       (*env)->SetByteArrayRegion(env, node_id_arr, 0, 33, obj->send_channel_announcement.node_id.compressed_form);
+                       LDKChannelAnnouncement msg_var = obj->send_channel_announcement.msg;
                        int64_t msg_ref = 0;
                        CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_var);
                        msg_ref = tag_ptr(msg_var.inner, false);
-                       LDKChannelUpdate update_msg_var = obj->broadcast_channel_announcement.update_msg;
+                       LDKChannelUpdate update_msg_var = obj->send_channel_announcement.update_msg;
                        int64_t update_msg_ref = 0;
                        CHECK_INNER_FIELD_ACCESS_OR_NULL(update_msg_var);
                        update_msg_ref = tag_ptr(update_msg_var.inner, false);
-                       return (*env)->NewObject(env, LDKMessageSendEvent_BroadcastChannelAnnouncement_class, LDKMessageSendEvent_BroadcastChannelAnnouncement_meth, msg_ref, update_msg_ref);
+                       return (*env)->NewObject(env, LDKMessageSendEvent_SendChannelAnnouncement_class, LDKMessageSendEvent_SendChannelAnnouncement_meth, node_id_arr, msg_ref, update_msg_ref);
                }
-               case LDKMessageSendEvent_BroadcastNodeAnnouncement: {
-                       LDKNodeAnnouncement msg_var = obj->broadcast_node_announcement.msg;
+               case LDKMessageSendEvent_BroadcastChannelAnnouncement: {
+                       LDKChannelAnnouncement msg_var = obj->broadcast_channel_announcement.msg;
                        int64_t msg_ref = 0;
                        CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_var);
                        msg_ref = tag_ptr(msg_var.inner, false);
-                       return (*env)->NewObject(env, LDKMessageSendEvent_BroadcastNodeAnnouncement_class, LDKMessageSendEvent_BroadcastNodeAnnouncement_meth, msg_ref);
+                       LDKChannelUpdate update_msg_var = obj->broadcast_channel_announcement.update_msg;
+                       int64_t update_msg_ref = 0;
+                       CHECK_INNER_FIELD_ACCESS_OR_NULL(update_msg_var);
+                       update_msg_ref = tag_ptr(update_msg_var.inner, false);
+                       return (*env)->NewObject(env, LDKMessageSendEvent_BroadcastChannelAnnouncement_class, LDKMessageSendEvent_BroadcastChannelAnnouncement_meth, msg_ref, update_msg_ref);
                }
                case LDKMessageSendEvent_BroadcastChannelUpdate: {
                        LDKChannelUpdate msg_var = obj->broadcast_channel_update.msg;
@@ -3230,37 +3945,6 @@ static inline LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ CVec_C3Tuple
        }
        return ret;
 }
-static jclass LDKCOption_C2Tuple_usizeTransactionZZ_Some_class = NULL;
-static jmethodID LDKCOption_C2Tuple_usizeTransactionZZ_Some_meth = NULL;
-static jclass LDKCOption_C2Tuple_usizeTransactionZZ_None_class = NULL;
-static jmethodID LDKCOption_C2Tuple_usizeTransactionZZ_None_meth = NULL;
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKCOption_1C2Tuple_1usizeTransactionZZ_init (JNIEnv *env, jclass clz) {
-       LDKCOption_C2Tuple_usizeTransactionZZ_Some_class =
-               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_C2Tuple_usizeTransactionZZ$Some"));
-       CHECK(LDKCOption_C2Tuple_usizeTransactionZZ_Some_class != NULL);
-       LDKCOption_C2Tuple_usizeTransactionZZ_Some_meth = (*env)->GetMethodID(env, LDKCOption_C2Tuple_usizeTransactionZZ_Some_class, "<init>", "(J)V");
-       CHECK(LDKCOption_C2Tuple_usizeTransactionZZ_Some_meth != NULL);
-       LDKCOption_C2Tuple_usizeTransactionZZ_None_class =
-               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_C2Tuple_usizeTransactionZZ$None"));
-       CHECK(LDKCOption_C2Tuple_usizeTransactionZZ_None_class != NULL);
-       LDKCOption_C2Tuple_usizeTransactionZZ_None_meth = (*env)->GetMethodID(env, LDKCOption_C2Tuple_usizeTransactionZZ_None_class, "<init>", "()V");
-       CHECK(LDKCOption_C2Tuple_usizeTransactionZZ_None_meth != NULL);
-}
-JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1C2Tuple_1usizeTransactionZZ_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKCOption_C2Tuple_usizeTransactionZZ *obj = (LDKCOption_C2Tuple_usizeTransactionZZ*)untag_ptr(ptr);
-       switch(obj->tag) {
-               case LDKCOption_C2Tuple_usizeTransactionZZ_Some: {
-                       LDKC2Tuple_usizeTransactionZ* some_conv = MALLOC(sizeof(LDKC2Tuple_usizeTransactionZ), "LDKC2Tuple_usizeTransactionZ");
-                       *some_conv = obj->some;
-                       *some_conv = C2Tuple_usizeTransactionZ_clone(some_conv);
-                       return (*env)->NewObject(env, LDKCOption_C2Tuple_usizeTransactionZZ_Some_class, LDKCOption_C2Tuple_usizeTransactionZZ_Some_meth, tag_ptr(some_conv, true));
-               }
-               case LDKCOption_C2Tuple_usizeTransactionZZ_None: {
-                       return (*env)->NewObject(env, LDKCOption_C2Tuple_usizeTransactionZZ_None_class, LDKCOption_C2Tuple_usizeTransactionZZ_None_meth);
-               }
-               default: abort();
-       }
-}
 static inline struct LDKFixedPenaltyScorer CResult_FixedPenaltyScorerDecodeErrorZ_get_ok(LDKCResult_FixedPenaltyScorerDecodeErrorZ *NONNULL_PTR owner){
        LDKFixedPenaltyScorer ret = *owner->contents.result;
        ret.is_owned = false;
@@ -3832,19 +4516,36 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C3Tuple_1ChannelAnnouncemen
        return ret_ref;
 }
 
-static inline LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(const LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *orig) {
-       LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret = { .data = MALLOC(sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ) * orig->datalen, "LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ clone bytes"), .datalen = orig->datalen };
-       for (size_t i = 0; i < ret.datalen; i++) {
-               ret.data[i] = C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_clone(&orig->data[i]);
-       }
-       return ret;
+static jclass LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class = NULL;
+static jmethodID LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_meth = NULL;
+static jclass LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class = NULL;
+static jmethodID LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKCOption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_init (JNIEnv *env, jclass clz) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ$Some"));
+       CHECK(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class != NULL);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_meth = (*env)->GetMethodID(env, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class, "<init>", "(J)V");
+       CHECK(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_meth != NULL);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ$None"));
+       CHECK(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class != NULL);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_meth = (*env)->GetMethodID(env, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class, "<init>", "()V");
+       CHECK(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_meth != NULL);
 }
-static inline LDKCVec_NodeAnnouncementZ CVec_NodeAnnouncementZ_clone(const LDKCVec_NodeAnnouncementZ *orig) {
-       LDKCVec_NodeAnnouncementZ ret = { .data = MALLOC(sizeof(LDKNodeAnnouncement) * orig->datalen, "LDKCVec_NodeAnnouncementZ clone bytes"), .datalen = orig->datalen };
-       for (size_t i = 0; i < ret.datalen; i++) {
-               ret.data[i] = NodeAnnouncement_clone(&orig->data[i]);
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *obj = (LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some: {
+                       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ* some_conv = MALLOC(sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ");
+                       *some_conv = obj->some;
+                       *some_conv = C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_clone(some_conv);
+                       return (*env)->NewObject(env, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_class, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_Some_meth, tag_ptr(some_conv, true));
+               }
+               case LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None: {
+                       return (*env)->NewObject(env, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_class, LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_None_meth);
+               }
+               default: abort();
        }
-       return ret;
 }
 static inline void CResult_NoneLightningErrorZ_get_ok(LDKCResult_NoneLightningErrorZ *NONNULL_PTR owner){
 CHECK(owner->result_ok);
@@ -4402,6 +5103,55 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeyNoneZ_1get_1
        CResult_SecretKeyNoneZ_get_err(owner_conv);
 }
 
+static jclass LDKCOption_ScalarZ_Some_class = NULL;
+static jmethodID LDKCOption_ScalarZ_Some_meth = NULL;
+static jclass LDKCOption_ScalarZ_None_class = NULL;
+static jmethodID LDKCOption_ScalarZ_None_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKCOption_1ScalarZ_init (JNIEnv *env, jclass clz) {
+       LDKCOption_ScalarZ_Some_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_ScalarZ$Some"));
+       CHECK(LDKCOption_ScalarZ_Some_class != NULL);
+       LDKCOption_ScalarZ_Some_meth = (*env)->GetMethodID(env, LDKCOption_ScalarZ_Some_class, "<init>", "(J)V");
+       CHECK(LDKCOption_ScalarZ_Some_meth != NULL);
+       LDKCOption_ScalarZ_None_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKCOption_ScalarZ$None"));
+       CHECK(LDKCOption_ScalarZ_None_class != NULL);
+       LDKCOption_ScalarZ_None_meth = (*env)->GetMethodID(env, LDKCOption_ScalarZ_None_class, "<init>", "()V");
+       CHECK(LDKCOption_ScalarZ_None_meth != NULL);
+}
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1ScalarZ_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKCOption_ScalarZ *obj = (LDKCOption_ScalarZ*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKCOption_ScalarZ_Some: {
+                       LDKBigEndianScalar* some_ref = &obj->some;
+                       return (*env)->NewObject(env, LDKCOption_ScalarZ_Some_class, LDKCOption_ScalarZ_Some_meth, tag_ptr(some_ref, false));
+               }
+               case LDKCOption_ScalarZ_None: {
+                       return (*env)->NewObject(env, LDKCOption_ScalarZ_None_class, LDKCOption_ScalarZ_None_meth);
+               }
+               default: abort();
+       }
+}
+static inline struct LDKThirtyTwoBytes CResult_SharedSecretNoneZ_get_ok(LDKCResult_SharedSecretNoneZ *NONNULL_PTR owner){
+CHECK(owner->result_ok);
+       return ThirtyTwoBytes_clone(&*owner->contents.result);
+}
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_SharedSecretNoneZ* owner_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(owner);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, 32);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, CResult_SharedSecretNoneZ_get_ok(owner_conv).data);
+       return ret_arr;
+}
+
+static inline void CResult_SharedSecretNoneZ_get_err(LDKCResult_SharedSecretNoneZ *NONNULL_PTR owner){
+CHECK(!owner->result_ok);
+       return *owner->contents.err;
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_SharedSecretNoneZ* owner_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(owner);
+       CResult_SharedSecretNoneZ_get_err(owner_conv);
+}
+
 typedef struct LDKBaseSign_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -6338,6 +7088,7 @@ typedef struct LDKKeysInterface_JCalls {
        JavaVM *vm;
        jweak o;
        jmethodID get_node_secret_meth;
+       jmethodID ecdh_meth;
        jmethodID get_destination_script_meth;
        jmethodID get_shutdown_scriptpubkey_meth;
        jmethodID get_channel_signer_meth;
@@ -6389,6 +7140,37 @@ LDKCResult_SecretKeyNoneZ get_node_secret_LDKKeysInterface_jcall(const void* thi
        }
        return ret_conv;
 }
+LDKCResult_SharedSecretNoneZ ecdh_LDKKeysInterface_jcall(const void* this_arg, LDKRecipient recipient, LDKPublicKey other_key, LDKCOption_ScalarZ tweak) {
+       LDKKeysInterface_JCalls *j_calls = (LDKKeysInterface_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jclass recipient_conv = LDKRecipient_to_java(env, recipient);
+       int8_tArray other_key_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, other_key_arr, 0, 33, other_key.compressed_form);
+       LDKCOption_ScalarZ *tweak_copy = MALLOC(sizeof(LDKCOption_ScalarZ), "LDKCOption_ScalarZ");
+       *tweak_copy = tweak;
+       int64_t tweak_ref = tag_ptr(tweak_copy, true);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->ecdh_meth, recipient_conv, other_key_arr, tweak_ref);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to ecdh in LDKKeysInterface from rust threw an exception.");
+       }
+       void* ret_ptr = untag_ptr(ret);
+       CHECK_ACCESS(ret_ptr);
+       LDKCResult_SharedSecretNoneZ ret_conv = *(LDKCResult_SharedSecretNoneZ*)(ret_ptr);
+       FREE(untag_ptr(ret));
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
 LDKCVec_u8Z get_destination_script_LDKKeysInterface_jcall(const void* this_arg) {
        LDKKeysInterface_JCalls *j_calls = (LDKKeysInterface_JCalls*) this_arg;
        JNIEnv *env;
@@ -6594,6 +7376,8 @@ static inline LDKKeysInterface LDKKeysInterface_init (JNIEnv *env, jclass clz, j
        calls->o = (*env)->NewWeakGlobalRef(env, o);
        calls->get_node_secret_meth = (*env)->GetMethodID(env, c, "get_node_secret", "(Lorg/ldk/enums/Recipient;)J");
        CHECK(calls->get_node_secret_meth != NULL);
+       calls->ecdh_meth = (*env)->GetMethodID(env, c, "ecdh", "(Lorg/ldk/enums/Recipient;[BJ)J");
+       CHECK(calls->ecdh_meth != NULL);
        calls->get_destination_script_meth = (*env)->GetMethodID(env, c, "get_destination_script", "()[B");
        CHECK(calls->get_destination_script_meth != NULL);
        calls->get_shutdown_scriptpubkey_meth = (*env)->GetMethodID(env, c, "get_shutdown_scriptpubkey", "()J");
@@ -6612,6 +7396,7 @@ static inline LDKKeysInterface LDKKeysInterface_init (JNIEnv *env, jclass clz, j
        LDKKeysInterface ret = {
                .this_arg = (void*) calls,
                .get_node_secret = get_node_secret_LDKKeysInterface_jcall,
+               .ecdh = ecdh_LDKKeysInterface_jcall,
                .get_destination_script = get_destination_script_LDKKeysInterface_jcall,
                .get_shutdown_scriptpubkey = get_shutdown_scriptpubkey_LDKKeysInterface_jcall,
                .get_channel_signer = get_channel_signer_LDKKeysInterface_jcall,
@@ -6638,6 +7423,23 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_KeysInterface_1get_1node_1s
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_KeysInterface_1ecdh(JNIEnv *env, jclass clz, int64_t this_arg, jclass recipient, int8_tArray other_key, int64_t tweak) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKKeysInterface* this_arg_conv = (LDKKeysInterface*)this_arg_ptr;
+       LDKRecipient recipient_conv = LDKRecipient_from_java(env, recipient);
+       LDKPublicKey other_key_ref;
+       CHECK((*env)->GetArrayLength(env, other_key) == 33);
+       (*env)->GetByteArrayRegion(env, other_key, 0, 33, other_key_ref.compressed_form);
+       void* tweak_ptr = untag_ptr(tweak);
+       CHECK_ACCESS(tweak_ptr);
+       LDKCOption_ScalarZ tweak_conv = *(LDKCOption_ScalarZ*)(tweak_ptr);
+       // WARNING: we may need a move here but no clone is available for LDKCOption_ScalarZ
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = (this_arg_conv->ecdh)(this_arg_conv->this_arg, recipient_conv, other_key_ref, tweak_conv);
+       return tag_ptr(ret_conv, true);
+}
+
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_KeysInterface_1get_1destination_1script(JNIEnv *env, jclass clz, int64_t this_arg) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
@@ -7190,6 +7992,34 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentIdPaymentEr
        return ret_ref;
 }
 
+static inline struct LDKInFlightHtlcs CResult_InFlightHtlcsDecodeErrorZ_get_ok(LDKCResult_InFlightHtlcsDecodeErrorZ *NONNULL_PTR owner){
+       LDKInFlightHtlcs ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_InFlightHtlcsDecodeErrorZ* owner_conv = (LDKCResult_InFlightHtlcsDecodeErrorZ*)untag_ptr(owner);
+       LDKInFlightHtlcs ret_var = CResult_InFlightHtlcsDecodeErrorZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKDecodeError CResult_InFlightHtlcsDecodeErrorZ_get_err(LDKCResult_InFlightHtlcsDecodeErrorZ *NONNULL_PTR owner){
+       LDKDecodeError ret = *owner->contents.err;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_InFlightHtlcsDecodeErrorZ* owner_conv = (LDKCResult_InFlightHtlcsDecodeErrorZ*)untag_ptr(owner);
+       LDKDecodeError ret_var = CResult_InFlightHtlcsDecodeErrorZ_get_err(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 static jclass LDKParseError_Bech32Error_class = NULL;
 static jmethodID LDKParseError_Bech32Error_meth = NULL;
 static jclass LDKParseError_ParseAmountError_class = NULL;
@@ -7969,8 +8799,12 @@ static jclass LDKBalance_ClaimableAwaitingConfirmations_class = NULL;
 static jmethodID LDKBalance_ClaimableAwaitingConfirmations_meth = NULL;
 static jclass LDKBalance_ContentiousClaimable_class = NULL;
 static jmethodID LDKBalance_ContentiousClaimable_meth = NULL;
-static jclass LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class = NULL;
-static jmethodID LDKBalance_MaybeClaimableHTLCAwaitingTimeout_meth = NULL;
+static jclass LDKBalance_MaybeTimeoutClaimableHTLC_class = NULL;
+static jmethodID LDKBalance_MaybeTimeoutClaimableHTLC_meth = NULL;
+static jclass LDKBalance_MaybePreimageClaimableHTLC_class = NULL;
+static jmethodID LDKBalance_MaybePreimageClaimableHTLC_meth = NULL;
+static jclass LDKBalance_CounterpartyRevokedOutputClaimable_class = NULL;
+static jmethodID LDKBalance_CounterpartyRevokedOutputClaimable_meth = NULL;
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKBalance_init (JNIEnv *env, jclass clz) {
        LDKBalance_ClaimableOnChannelClose_class =
                (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$ClaimableOnChannelClose"));
@@ -7987,11 +8821,21 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKBalance_init (JNIEnv *
        CHECK(LDKBalance_ContentiousClaimable_class != NULL);
        LDKBalance_ContentiousClaimable_meth = (*env)->GetMethodID(env, LDKBalance_ContentiousClaimable_class, "<init>", "(JI)V");
        CHECK(LDKBalance_ContentiousClaimable_meth != NULL);
-       LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class =
-               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$MaybeClaimableHTLCAwaitingTimeout"));
-       CHECK(LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class != NULL);
-       LDKBalance_MaybeClaimableHTLCAwaitingTimeout_meth = (*env)->GetMethodID(env, LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class, "<init>", "(JI)V");
-       CHECK(LDKBalance_MaybeClaimableHTLCAwaitingTimeout_meth != NULL);
+       LDKBalance_MaybeTimeoutClaimableHTLC_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$MaybeTimeoutClaimableHTLC"));
+       CHECK(LDKBalance_MaybeTimeoutClaimableHTLC_class != NULL);
+       LDKBalance_MaybeTimeoutClaimableHTLC_meth = (*env)->GetMethodID(env, LDKBalance_MaybeTimeoutClaimableHTLC_class, "<init>", "(JI)V");
+       CHECK(LDKBalance_MaybeTimeoutClaimableHTLC_meth != NULL);
+       LDKBalance_MaybePreimageClaimableHTLC_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$MaybePreimageClaimableHTLC"));
+       CHECK(LDKBalance_MaybePreimageClaimableHTLC_class != NULL);
+       LDKBalance_MaybePreimageClaimableHTLC_meth = (*env)->GetMethodID(env, LDKBalance_MaybePreimageClaimableHTLC_class, "<init>", "(JI)V");
+       CHECK(LDKBalance_MaybePreimageClaimableHTLC_meth != NULL);
+       LDKBalance_CounterpartyRevokedOutputClaimable_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKBalance$CounterpartyRevokedOutputClaimable"));
+       CHECK(LDKBalance_CounterpartyRevokedOutputClaimable_class != NULL);
+       LDKBalance_CounterpartyRevokedOutputClaimable_meth = (*env)->GetMethodID(env, LDKBalance_CounterpartyRevokedOutputClaimable_class, "<init>", "(J)V");
+       CHECK(LDKBalance_CounterpartyRevokedOutputClaimable_meth != NULL);
 }
 JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKBalance_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
        LDKBalance *obj = (LDKBalance*)untag_ptr(ptr);
@@ -8010,10 +8854,19 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKBalance_1ref_1from_1ptr(
                        int32_t timeout_height_conv = obj->contentious_claimable.timeout_height;
                        return (*env)->NewObject(env, LDKBalance_ContentiousClaimable_class, LDKBalance_ContentiousClaimable_meth, claimable_amount_satoshis_conv, timeout_height_conv);
                }
-               case LDKBalance_MaybeClaimableHTLCAwaitingTimeout: {
-                       int64_t claimable_amount_satoshis_conv = obj->maybe_claimable_htlc_awaiting_timeout.claimable_amount_satoshis;
-                       int32_t claimable_height_conv = obj->maybe_claimable_htlc_awaiting_timeout.claimable_height;
-                       return (*env)->NewObject(env, LDKBalance_MaybeClaimableHTLCAwaitingTimeout_class, LDKBalance_MaybeClaimableHTLCAwaitingTimeout_meth, claimable_amount_satoshis_conv, claimable_height_conv);
+               case LDKBalance_MaybeTimeoutClaimableHTLC: {
+                       int64_t claimable_amount_satoshis_conv = obj->maybe_timeout_claimable_htlc.claimable_amount_satoshis;
+                       int32_t claimable_height_conv = obj->maybe_timeout_claimable_htlc.claimable_height;
+                       return (*env)->NewObject(env, LDKBalance_MaybeTimeoutClaimableHTLC_class, LDKBalance_MaybeTimeoutClaimableHTLC_meth, claimable_amount_satoshis_conv, claimable_height_conv);
+               }
+               case LDKBalance_MaybePreimageClaimableHTLC: {
+                       int64_t claimable_amount_satoshis_conv = obj->maybe_preimage_claimable_htlc.claimable_amount_satoshis;
+                       int32_t expiry_height_conv = obj->maybe_preimage_claimable_htlc.expiry_height;
+                       return (*env)->NewObject(env, LDKBalance_MaybePreimageClaimableHTLC_class, LDKBalance_MaybePreimageClaimableHTLC_meth, claimable_amount_satoshis_conv, expiry_height_conv);
+               }
+               case LDKBalance_CounterpartyRevokedOutputClaimable: {
+                       int64_t claimable_amount_satoshis_conv = obj->counterparty_revoked_output_claimable.claimable_amount_satoshis;
+                       return (*env)->NewObject(env, LDKBalance_CounterpartyRevokedOutputClaimable_class, LDKBalance_CounterpartyRevokedOutputClaimable_meth, claimable_amount_satoshis_conv);
                }
                default: abort();
        }
@@ -8180,6 +9033,86 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErro
        return ret_ref;
 }
 
+static jclass LDKSendError_Secp256k1_class = NULL;
+static jmethodID LDKSendError_Secp256k1_meth = NULL;
+static jclass LDKSendError_TooBigPacket_class = NULL;
+static jmethodID LDKSendError_TooBigPacket_meth = NULL;
+static jclass LDKSendError_TooFewBlindedHops_class = NULL;
+static jmethodID LDKSendError_TooFewBlindedHops_meth = NULL;
+static jclass LDKSendError_InvalidFirstHop_class = NULL;
+static jmethodID LDKSendError_InvalidFirstHop_meth = NULL;
+static jclass LDKSendError_BufferFull_class = NULL;
+static jmethodID LDKSendError_BufferFull_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKSendError_init (JNIEnv *env, jclass clz) {
+       LDKSendError_Secp256k1_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$Secp256k1"));
+       CHECK(LDKSendError_Secp256k1_class != NULL);
+       LDKSendError_Secp256k1_meth = (*env)->GetMethodID(env, LDKSendError_Secp256k1_class, "<init>", "(Lorg/ldk/enums/Secp256k1Error;)V");
+       CHECK(LDKSendError_Secp256k1_meth != NULL);
+       LDKSendError_TooBigPacket_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$TooBigPacket"));
+       CHECK(LDKSendError_TooBigPacket_class != NULL);
+       LDKSendError_TooBigPacket_meth = (*env)->GetMethodID(env, LDKSendError_TooBigPacket_class, "<init>", "()V");
+       CHECK(LDKSendError_TooBigPacket_meth != NULL);
+       LDKSendError_TooFewBlindedHops_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$TooFewBlindedHops"));
+       CHECK(LDKSendError_TooFewBlindedHops_class != NULL);
+       LDKSendError_TooFewBlindedHops_meth = (*env)->GetMethodID(env, LDKSendError_TooFewBlindedHops_class, "<init>", "()V");
+       CHECK(LDKSendError_TooFewBlindedHops_meth != NULL);
+       LDKSendError_InvalidFirstHop_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$InvalidFirstHop"));
+       CHECK(LDKSendError_InvalidFirstHop_class != NULL);
+       LDKSendError_InvalidFirstHop_meth = (*env)->GetMethodID(env, LDKSendError_InvalidFirstHop_class, "<init>", "()V");
+       CHECK(LDKSendError_InvalidFirstHop_meth != NULL);
+       LDKSendError_BufferFull_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKSendError$BufferFull"));
+       CHECK(LDKSendError_BufferFull_class != NULL);
+       LDKSendError_BufferFull_meth = (*env)->GetMethodID(env, LDKSendError_BufferFull_class, "<init>", "()V");
+       CHECK(LDKSendError_BufferFull_meth != NULL);
+}
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKSendError_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKSendError *obj = (LDKSendError*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKSendError_Secp256k1: {
+                       jclass secp256k1_conv = LDKSecp256k1Error_to_java(env, obj->secp256k1);
+                       return (*env)->NewObject(env, LDKSendError_Secp256k1_class, LDKSendError_Secp256k1_meth, secp256k1_conv);
+               }
+               case LDKSendError_TooBigPacket: {
+                       return (*env)->NewObject(env, LDKSendError_TooBigPacket_class, LDKSendError_TooBigPacket_meth);
+               }
+               case LDKSendError_TooFewBlindedHops: {
+                       return (*env)->NewObject(env, LDKSendError_TooFewBlindedHops_class, LDKSendError_TooFewBlindedHops_meth);
+               }
+               case LDKSendError_InvalidFirstHop: {
+                       return (*env)->NewObject(env, LDKSendError_InvalidFirstHop_class, LDKSendError_InvalidFirstHop_meth);
+               }
+               case LDKSendError_BufferFull: {
+                       return (*env)->NewObject(env, LDKSendError_BufferFull_class, LDKSendError_BufferFull_meth);
+               }
+               default: abort();
+       }
+}
+static inline void CResult_NoneSendErrorZ_get_ok(LDKCResult_NoneSendErrorZ *NONNULL_PTR owner){
+CHECK(owner->result_ok);
+       return *owner->contents.result;
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_NoneSendErrorZ* owner_conv = (LDKCResult_NoneSendErrorZ*)untag_ptr(owner);
+       CResult_NoneSendErrorZ_get_ok(owner_conv);
+}
+
+static inline struct LDKSendError CResult_NoneSendErrorZ_get_err(LDKCResult_NoneSendErrorZ *NONNULL_PTR owner){
+CHECK(!owner->result_ok);
+       return SendError_clone(&*owner->contents.err);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_NoneSendErrorZ* owner_conv = (LDKCResult_NoneSendErrorZ*)untag_ptr(owner);
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = CResult_NoneSendErrorZ_get_err(owner_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
 static jclass LDKGraphSyncError_DecodeError_class = NULL;
 static jmethodID LDKGraphSyncError_DecodeError_meth = NULL;
 static jclass LDKGraphSyncError_LightningError_class = NULL;
@@ -8796,6 +9729,34 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecod
        return ret_ref;
 }
 
+static inline struct LDKOnionMessage CResult_OnionMessageDecodeErrorZ_get_ok(LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR owner){
+       LDKOnionMessage ret = *owner->contents.result;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_OnionMessageDecodeErrorZ* owner_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(owner);
+       LDKOnionMessage ret_var = CResult_OnionMessageDecodeErrorZ_get_ok(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+static inline struct LDKDecodeError CResult_OnionMessageDecodeErrorZ_get_err(LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR owner){
+       LDKDecodeError ret = *owner->contents.err;
+       ret.is_owned = false;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t owner) {
+       LDKCResult_OnionMessageDecodeErrorZ* owner_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(owner);
+       LDKDecodeError ret_var = CResult_OnionMessageDecodeErrorZ_get_err(owner_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 static inline struct LDKPing CResult_PingDecodeErrorZ_get_ok(LDKCResult_PingDecodeErrorZ *NONNULL_PTR owner){
        LDKPing ret = *owner->contents.result;
        ret.is_owned = false;
@@ -9327,7 +10288,7 @@ void register_tx_LDKFilter_jcall(const void* this_arg, const uint8_t (* txid)[32
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
 }
-LDKCOption_C2Tuple_usizeTransactionZZ register_output_LDKFilter_jcall(const void* this_arg, LDKWatchedOutput output) {
+void register_output_LDKFilter_jcall(const void* this_arg, LDKWatchedOutput output) {
        LDKFilter_JCalls *j_calls = (LDKFilter_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -9342,19 +10303,14 @@ LDKCOption_C2Tuple_usizeTransactionZZ register_output_LDKFilter_jcall(const void
        output_ref = tag_ptr(output_var.inner, output_var.is_owned);
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->register_output_meth, output_ref);
+       (*env)->CallVoidMethod(env, obj, j_calls->register_output_meth, output_ref);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
                (*env)->FatalError(env, "A call to register_output in LDKFilter from rust threw an exception.");
        }
-       void* ret_ptr = untag_ptr(ret);
-       CHECK_ACCESS(ret_ptr);
-       LDKCOption_C2Tuple_usizeTransactionZZ ret_conv = *(LDKCOption_C2Tuple_usizeTransactionZZ*)(ret_ptr);
-       FREE(untag_ptr(ret));
        if (get_jenv_res == JNI_EDETACHED) {
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
-       return ret_conv;
 }
 static void LDKFilter_JCalls_cloned(LDKFilter* new_obj) {
        LDKFilter_JCalls *j_calls = (LDKFilter_JCalls*) new_obj->this_arg;
@@ -9369,7 +10325,7 @@ static inline LDKFilter LDKFilter_init (JNIEnv *env, jclass clz, jobject o) {
        calls->o = (*env)->NewWeakGlobalRef(env, o);
        calls->register_tx_meth = (*env)->GetMethodID(env, c, "register_tx", "([B[B)V");
        CHECK(calls->register_tx_meth != NULL);
-       calls->register_output_meth = (*env)->GetMethodID(env, c, "register_output", "(J)J");
+       calls->register_output_meth = (*env)->GetMethodID(env, c, "register_output", "(J)V");
        CHECK(calls->register_output_meth != NULL);
 
        LDKFilter ret = {
@@ -9400,7 +10356,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Filter_1register_1tx(JNIEnv *e
        (*env)->ReleaseByteArrayElements(env, script_pubkey, (int8_t*)script_pubkey_ref.data, 0);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Filter_1register_1output(JNIEnv *env, jclass clz, int64_t this_arg, int64_t output) {
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Filter_1register_1output(JNIEnv *env, jclass clz, int64_t this_arg, int64_t output) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKFilter* this_arg_conv = (LDKFilter*)this_arg_ptr;
@@ -9409,10 +10365,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Filter_1register_1output(JN
        output_conv.is_owned = ptr_is_owned(output);
        CHECK_INNER_FIELD_ACCESS_OR_NULL(output_conv);
        output_conv = WatchedOutput_clone(&output_conv);
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = (this_arg_conv->register_output)(this_arg_conv->this_arg, output_conv);
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
+       (this_arg_conv->register_output)(this_arg_conv->this_arg, output_conv);
 }
 
 static jclass LDKCOption_FilterZ_Some_class = NULL;
@@ -9585,6 +10538,96 @@ JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_MessageSendEventsProvi
        return ret_arr;
 }
 
+typedef struct LDKOnionMessageProvider_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       jmethodID next_onion_message_for_peer_meth;
+} LDKOnionMessageProvider_JCalls;
+static void LDKOnionMessageProvider_JCalls_free(void* this_arg) {
+       LDKOnionMessageProvider_JCalls *j_calls = (LDKOnionMessageProvider_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+LDKOnionMessage next_onion_message_for_peer_LDKOnionMessageProvider_jcall(const void* this_arg, LDKPublicKey peer_node_id) {
+       LDKOnionMessageProvider_JCalls *j_calls = (LDKOnionMessageProvider_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray peer_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, peer_node_id_arr, 0, 33, peer_node_id.compressed_form);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->next_onion_message_for_peer_meth, peer_node_id_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to next_onion_message_for_peer in LDKOnionMessageProvider from rust threw an exception.");
+       }
+       LDKOnionMessage ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+static void LDKOnionMessageProvider_JCalls_cloned(LDKOnionMessageProvider* new_obj) {
+       LDKOnionMessageProvider_JCalls *j_calls = (LDKOnionMessageProvider_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+}
+static inline LDKOnionMessageProvider LDKOnionMessageProvider_init (JNIEnv *env, jclass clz, jobject o) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKOnionMessageProvider_JCalls *calls = MALLOC(sizeof(LDKOnionMessageProvider_JCalls), "LDKOnionMessageProvider_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->next_onion_message_for_peer_meth = (*env)->GetMethodID(env, c, "next_onion_message_for_peer", "([B)J");
+       CHECK(calls->next_onion_message_for_peer_meth != NULL);
+
+       LDKOnionMessageProvider ret = {
+               .this_arg = (void*) calls,
+               .next_onion_message_for_peer = next_onion_message_for_peer_LDKOnionMessageProvider_jcall,
+               .free = LDKOnionMessageProvider_JCalls_free,
+       };
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKOnionMessageProvider_1new(JNIEnv *env, jclass clz, jobject o) {
+       LDKOnionMessageProvider *res_ptr = MALLOC(sizeof(LDKOnionMessageProvider), "LDKOnionMessageProvider");
+       *res_ptr = LDKOnionMessageProvider_init(env, clz, o);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessageProvider_1next_1onion_1message_1for_1peer(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray peer_node_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageProvider* this_arg_conv = (LDKOnionMessageProvider*)this_arg_ptr;
+       LDKPublicKey peer_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, peer_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, peer_node_id, 0, 33, peer_node_id_ref.compressed_form);
+       LDKOnionMessage ret_var = (this_arg_conv->next_onion_message_for_peer)(this_arg_conv->this_arg, peer_node_id_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 typedef struct LDKEventHandler_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -9750,400 +10793,6 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_EventsProvider_1process_1pendi
        (this_arg_conv->process_pending_events)(this_arg_conv->this_arg, handler_conv);
 }
 
-typedef struct LDKScore_JCalls {
-       atomic_size_t refcnt;
-       JavaVM *vm;
-       jweak o;
-       jmethodID channel_penalty_msat_meth;
-       jmethodID payment_path_failed_meth;
-       jmethodID payment_path_successful_meth;
-       jmethodID probe_failed_meth;
-       jmethodID probe_successful_meth;
-       jmethodID write_meth;
-} LDKScore_JCalls;
-static void LDKScore_JCalls_free(void* this_arg) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
-               JNIEnv *env;
-               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-               if (get_jenv_res == JNI_EDETACHED) {
-                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-               } else {
-                       DO_ASSERT(get_jenv_res == JNI_OK);
-               }
-               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
-               if (get_jenv_res == JNI_EDETACHED) {
-                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-               }
-               FREE(j_calls);
-       }
-}
-uint64_t channel_penalty_msat_LDKScore_jcall(const void* this_arg, uint64_t short_channel_id, const LDKNodeId * source, const LDKNodeId * target, LDKChannelUsage usage) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       int64_t short_channel_id_conv = short_channel_id;
-       LDKNodeId source_var = *source;
-       int64_t source_ref = 0;
-       source_var = NodeId_clone(&source_var);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_var);
-       source_ref = tag_ptr(source_var.inner, source_var.is_owned);
-       LDKNodeId target_var = *target;
-       int64_t target_ref = 0;
-       target_var = NodeId_clone(&target_var);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_var);
-       target_ref = tag_ptr(target_var.inner, target_var.is_owned);
-       LDKChannelUsage usage_var = usage;
-       int64_t usage_ref = 0;
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(usage_var);
-       usage_ref = tag_ptr(usage_var.inner, usage_var.is_owned);
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       int64_t ret = (*env)->CallLongMethod(env, obj, j_calls->channel_penalty_msat_meth, short_channel_id_conv, source_ref, target_ref, usage_ref);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to channel_penalty_msat in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-       return ret;
-}
-void payment_path_failed_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       LDKCVec_RouteHopZ path_var = path;
-       int64_tArray path_arr = NULL;
-       path_arr = (*env)->NewLongArray(env, path_var.datalen);
-       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
-       for (size_t k = 0; k < path_var.datalen; k++) {
-               LDKRouteHop path_conv_10_var = path_var.data[k];
-               int64_t path_conv_10_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
-               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
-               path_arr_ptr[k] = path_conv_10_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
-       FREE(path_var.data);
-       int64_t short_channel_id_conv = short_channel_id;
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       (*env)->CallVoidMethod(env, obj, j_calls->payment_path_failed_meth, path_arr, short_channel_id_conv);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to payment_path_failed in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-}
-void payment_path_successful_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       LDKCVec_RouteHopZ path_var = path;
-       int64_tArray path_arr = NULL;
-       path_arr = (*env)->NewLongArray(env, path_var.datalen);
-       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
-       for (size_t k = 0; k < path_var.datalen; k++) {
-               LDKRouteHop path_conv_10_var = path_var.data[k];
-               int64_t path_conv_10_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
-               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
-               path_arr_ptr[k] = path_conv_10_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
-       FREE(path_var.data);
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       (*env)->CallVoidMethod(env, obj, j_calls->payment_path_successful_meth, path_arr);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to payment_path_successful in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-}
-void probe_failed_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       LDKCVec_RouteHopZ path_var = path;
-       int64_tArray path_arr = NULL;
-       path_arr = (*env)->NewLongArray(env, path_var.datalen);
-       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
-       for (size_t k = 0; k < path_var.datalen; k++) {
-               LDKRouteHop path_conv_10_var = path_var.data[k];
-               int64_t path_conv_10_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
-               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
-               path_arr_ptr[k] = path_conv_10_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
-       FREE(path_var.data);
-       int64_t short_channel_id_conv = short_channel_id;
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       (*env)->CallVoidMethod(env, obj, j_calls->probe_failed_meth, path_arr, short_channel_id_conv);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to probe_failed in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-}
-void probe_successful_LDKScore_jcall(void* this_arg, LDKCVec_RouteHopZ path) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       LDKCVec_RouteHopZ path_var = path;
-       int64_tArray path_arr = NULL;
-       path_arr = (*env)->NewLongArray(env, path_var.datalen);
-       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
-       for (size_t k = 0; k < path_var.datalen; k++) {
-               LDKRouteHop path_conv_10_var = path_var.data[k];
-               int64_t path_conv_10_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
-               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
-               path_arr_ptr[k] = path_conv_10_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
-       FREE(path_var.data);
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       (*env)->CallVoidMethod(env, obj, j_calls->probe_successful_meth, path_arr);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to probe_successful in LDKScore from rust threw an exception.");
-       }
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-}
-LDKCVec_u8Z write_LDKScore_jcall(const void* this_arg) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       int8_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->write_meth);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to write in LDKScore from rust threw an exception.");
-       }
-       LDKCVec_u8Z ret_ref;
-       ret_ref.datalen = (*env)->GetArrayLength(env, ret);
-       ret_ref.data = MALLOC(ret_ref.datalen, "LDKCVec_u8Z Bytes");
-       (*env)->GetByteArrayRegion(env, ret, 0, ret_ref.datalen, ret_ref.data);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
-       }
-       return ret_ref;
-}
-static void LDKScore_JCalls_cloned(LDKScore* new_obj) {
-       LDKScore_JCalls *j_calls = (LDKScore_JCalls*) new_obj->this_arg;
-       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
-}
-static inline LDKScore LDKScore_init (JNIEnv *env, jclass clz, jobject o) {
-       jclass c = (*env)->GetObjectClass(env, o);
-       CHECK(c != NULL);
-       LDKScore_JCalls *calls = MALLOC(sizeof(LDKScore_JCalls), "LDKScore_JCalls");
-       atomic_init(&calls->refcnt, 1);
-       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
-       calls->o = (*env)->NewWeakGlobalRef(env, o);
-       calls->channel_penalty_msat_meth = (*env)->GetMethodID(env, c, "channel_penalty_msat", "(JJJJ)J");
-       CHECK(calls->channel_penalty_msat_meth != NULL);
-       calls->payment_path_failed_meth = (*env)->GetMethodID(env, c, "payment_path_failed", "([JJ)V");
-       CHECK(calls->payment_path_failed_meth != NULL);
-       calls->payment_path_successful_meth = (*env)->GetMethodID(env, c, "payment_path_successful", "([J)V");
-       CHECK(calls->payment_path_successful_meth != NULL);
-       calls->probe_failed_meth = (*env)->GetMethodID(env, c, "probe_failed", "([JJ)V");
-       CHECK(calls->probe_failed_meth != NULL);
-       calls->probe_successful_meth = (*env)->GetMethodID(env, c, "probe_successful", "([J)V");
-       CHECK(calls->probe_successful_meth != NULL);
-       calls->write_meth = (*env)->GetMethodID(env, c, "write", "()[B");
-       CHECK(calls->write_meth != NULL);
-
-       LDKScore ret = {
-               .this_arg = (void*) calls,
-               .channel_penalty_msat = channel_penalty_msat_LDKScore_jcall,
-               .payment_path_failed = payment_path_failed_LDKScore_jcall,
-               .payment_path_successful = payment_path_successful_LDKScore_jcall,
-               .probe_failed = probe_failed_LDKScore_jcall,
-               .probe_successful = probe_successful_LDKScore_jcall,
-               .write = write_LDKScore_jcall,
-               .free = LDKScore_JCalls_free,
-       };
-       return ret;
-}
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKScore_1new(JNIEnv *env, jclass clz, jobject o) {
-       LDKScore *res_ptr = MALLOC(sizeof(LDKScore), "LDKScore");
-       *res_ptr = LDKScore_init(env, clz, o);
-       return tag_ptr(res_ptr, true);
-}
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Score_1channel_1penalty_1msat(JNIEnv *env, jclass clz, int64_t this_arg, int64_t short_channel_id, int64_t source, int64_t target, int64_t usage) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKNodeId source_conv;
-       source_conv.inner = untag_ptr(source);
-       source_conv.is_owned = ptr_is_owned(source);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_conv);
-       source_conv.is_owned = false;
-       LDKNodeId target_conv;
-       target_conv.inner = untag_ptr(target);
-       target_conv.is_owned = ptr_is_owned(target);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_conv);
-       target_conv.is_owned = false;
-       LDKChannelUsage usage_conv;
-       usage_conv.inner = untag_ptr(usage);
-       usage_conv.is_owned = ptr_is_owned(usage);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(usage_conv);
-       usage_conv = ChannelUsage_clone(&usage_conv);
-       int64_t ret_conv = (this_arg_conv->channel_penalty_msat)(this_arg_conv->this_arg, short_channel_id, &source_conv, &target_conv, usage_conv);
-       return ret_conv;
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_RouteHopZ path_constr;
-       path_constr.datalen = (*env)->GetArrayLength(env, path);
-       if (path_constr.datalen > 0)
-               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
-       else
-               path_constr.data = NULL;
-       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
-       for (size_t k = 0; k < path_constr.datalen; k++) {
-               int64_t path_conv_10 = path_vals[k];
-               LDKRouteHop path_conv_10_conv;
-               path_conv_10_conv.inner = untag_ptr(path_conv_10);
-               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
-               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
-               path_constr.data[k] = path_conv_10_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
-       (this_arg_conv->payment_path_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_RouteHopZ path_constr;
-       path_constr.datalen = (*env)->GetArrayLength(env, path);
-       if (path_constr.datalen > 0)
-               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
-       else
-               path_constr.data = NULL;
-       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
-       for (size_t k = 0; k < path_constr.datalen; k++) {
-               int64_t path_conv_10 = path_vals[k];
-               LDKRouteHop path_conv_10_conv;
-               path_conv_10_conv.inner = untag_ptr(path_conv_10);
-               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
-               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
-               path_constr.data[k] = path_conv_10_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
-       (this_arg_conv->payment_path_successful)(this_arg_conv->this_arg, path_constr);
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_RouteHopZ path_constr;
-       path_constr.datalen = (*env)->GetArrayLength(env, path);
-       if (path_constr.datalen > 0)
-               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
-       else
-               path_constr.data = NULL;
-       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
-       for (size_t k = 0; k < path_constr.datalen; k++) {
-               int64_t path_conv_10 = path_vals[k];
-               LDKRouteHop path_conv_10_conv;
-               path_conv_10_conv.inner = untag_ptr(path_conv_10);
-               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
-               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
-               path_constr.data[k] = path_conv_10_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
-       (this_arg_conv->probe_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_RouteHopZ path_constr;
-       path_constr.datalen = (*env)->GetArrayLength(env, path);
-       if (path_constr.datalen > 0)
-               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
-       else
-               path_constr.data = NULL;
-       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
-       for (size_t k = 0; k < path_constr.datalen; k++) {
-               int64_t path_conv_10 = path_vals[k];
-               LDKRouteHop path_conv_10_conv;
-               path_conv_10_conv.inner = untag_ptr(path_conv_10);
-               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
-               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
-               path_constr.data[k] = path_conv_10_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
-       (this_arg_conv->probe_successful)(this_arg_conv->this_arg, path_constr);
-}
-
-JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_Score_1write(JNIEnv *env, jclass clz, int64_t this_arg) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKScore* this_arg_conv = (LDKScore*)this_arg_ptr;
-       LDKCVec_u8Z ret_var = (this_arg_conv->write)(this_arg_conv->this_arg);
-       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
-       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
-       CVec_u8Z_free(ret_var);
-       return ret_arr;
-}
-
 typedef struct LDKPersister_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -10229,7 +10878,7 @@ LDKCResult_NoneErrorZ persist_graph_LDKPersister_jcall(const void* this_arg, con
        }
        return ret_conv;
 }
-LDKCResult_NoneErrorZ persist_scorer_LDKPersister_jcall(const void* this_arg, const LDKMultiThreadedLockableScore * scorer) {
+LDKCResult_NoneErrorZ persist_scorer_LDKPersister_jcall(const void* this_arg, const LDKWriteableScore * scorer) {
        LDKPersister_JCalls *j_calls = (LDKPersister_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -10238,14 +10887,11 @@ LDKCResult_NoneErrorZ persist_scorer_LDKPersister_jcall(const void* this_arg, co
        } else {
                DO_ASSERT(get_jenv_res == JNI_OK);
        }
-       LDKMultiThreadedLockableScore scorer_var = *scorer;
-       int64_t scorer_ref = 0;
-       // WARNING: we may need a move here but no clone is available for LDKMultiThreadedLockableScore
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(scorer_var);
-       scorer_ref = tag_ptr(scorer_var.inner, scorer_var.is_owned);
+       // WARNING: This object doesn't live past this scope, needs clone!
+       int64_t ret_scorer = tag_ptr(scorer, false);
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->persist_scorer_meth, scorer_ref);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->persist_scorer_meth, ret_scorer);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
                (*env)->FatalError(env, "A call to persist_scorer in LDKPersister from rust threw an exception.");
@@ -10323,16 +10969,90 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Persister_1persist_1scorer(
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKPersister* this_arg_conv = (LDKPersister*)this_arg_ptr;
-       LDKMultiThreadedLockableScore scorer_conv;
-       scorer_conv.inner = untag_ptr(scorer);
-       scorer_conv.is_owned = ptr_is_owned(scorer);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(scorer_conv);
-       scorer_conv.is_owned = false;
+       void* scorer_ptr = untag_ptr(scorer);
+       if (ptr_is_owned(scorer)) { CHECK_ACCESS(scorer_ptr); }
+       LDKWriteableScore* scorer_conv = (LDKWriteableScore*)scorer_ptr;
        LDKCResult_NoneErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneErrorZ), "LDKCResult_NoneErrorZ");
-       *ret_conv = (this_arg_conv->persist_scorer)(this_arg_conv->this_arg, &scorer_conv);
+       *ret_conv = (this_arg_conv->persist_scorer)(this_arg_conv->this_arg, scorer_conv);
        return tag_ptr(ret_conv, true);
 }
 
+typedef struct LDKFutureCallback_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       jmethodID call_meth;
+} LDKFutureCallback_JCalls;
+static void LDKFutureCallback_JCalls_free(void* this_arg) {
+       LDKFutureCallback_JCalls *j_calls = (LDKFutureCallback_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+void call_LDKFutureCallback_jcall(const void* this_arg) {
+       LDKFutureCallback_JCalls *j_calls = (LDKFutureCallback_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->call_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to call in LDKFutureCallback from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+static void LDKFutureCallback_JCalls_cloned(LDKFutureCallback* new_obj) {
+       LDKFutureCallback_JCalls *j_calls = (LDKFutureCallback_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+}
+static inline LDKFutureCallback LDKFutureCallback_init (JNIEnv *env, jclass clz, jobject o) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKFutureCallback_JCalls *calls = MALLOC(sizeof(LDKFutureCallback_JCalls), "LDKFutureCallback_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->call_meth = (*env)->GetMethodID(env, c, "call", "()V");
+       CHECK(calls->call_meth != NULL);
+
+       LDKFutureCallback ret = {
+               .this_arg = (void*) calls,
+               .call = call_LDKFutureCallback_jcall,
+               .free = LDKFutureCallback_JCalls_free,
+       };
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKFutureCallback_1new(JNIEnv *env, jclass clz, jobject o) {
+       LDKFutureCallback *res_ptr = MALLOC(sizeof(LDKFutureCallback), "LDKFutureCallback");
+       *res_ptr = LDKFutureCallback_init(env, clz, o);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_FutureCallback_1call(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKFutureCallback* this_arg_conv = (LDKFutureCallback*)this_arg_ptr;
+       (this_arg_conv->call)(this_arg_conv->this_arg);
+}
+
 typedef struct LDKListen_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -10973,6 +11693,8 @@ typedef struct LDKChannelMessageHandler_JCalls {
        jmethodID handle_channel_reestablish_meth;
        jmethodID handle_channel_update_meth;
        jmethodID handle_error_meth;
+       jmethodID provided_node_features_meth;
+       jmethodID provided_init_features_meth;
 } LDKChannelMessageHandler_JCalls;
 static void LDKChannelMessageHandler_JCalls_free(void* this_arg) {
        LDKChannelMessageHandler_JCalls *j_calls = (LDKChannelMessageHandler_JCalls*) this_arg;
@@ -11540,6 +12262,58 @@ void handle_error_LDKChannelMessageHandler_jcall(const void* this_arg, LDKPublic
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
 }
+LDKNodeFeatures provided_node_features_LDKChannelMessageHandler_jcall(const void* this_arg) {
+       LDKChannelMessageHandler_JCalls *j_calls = (LDKChannelMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_node_features_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_node_features in LDKChannelMessageHandler from rust threw an exception.");
+       }
+       LDKNodeFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+LDKInitFeatures provided_init_features_LDKChannelMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id) {
+       LDKChannelMessageHandler_JCalls *j_calls = (LDKChannelMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_init_features_meth, their_node_id_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_init_features in LDKChannelMessageHandler from rust threw an exception.");
+       }
+       LDKInitFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
 static void LDKChannelMessageHandler_JCalls_cloned(LDKChannelMessageHandler* new_obj) {
        LDKChannelMessageHandler_JCalls *j_calls = (LDKChannelMessageHandler_JCalls*) new_obj->this_arg;
        atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
@@ -11592,6 +12366,10 @@ static inline LDKChannelMessageHandler LDKChannelMessageHandler_init (JNIEnv *en
        CHECK(calls->handle_channel_update_meth != NULL);
        calls->handle_error_meth = (*env)->GetMethodID(env, c, "handle_error", "([BJ)V");
        CHECK(calls->handle_error_meth != NULL);
+       calls->provided_node_features_meth = (*env)->GetMethodID(env, c, "provided_node_features", "()J");
+       CHECK(calls->provided_node_features_meth != NULL);
+       calls->provided_init_features_meth = (*env)->GetMethodID(env, c, "provided_init_features", "([B)J");
+       CHECK(calls->provided_init_features_meth != NULL);
 
        LDKChannelMessageHandler ret = {
                .this_arg = (void*) calls,
@@ -11615,6 +12393,8 @@ static inline LDKChannelMessageHandler LDKChannelMessageHandler_init (JNIEnv *en
                .handle_channel_reestablish = handle_channel_reestablish_LDKChannelMessageHandler_jcall,
                .handle_channel_update = handle_channel_update_LDKChannelMessageHandler_jcall,
                .handle_error = handle_error_LDKChannelMessageHandler_jcall,
+               .provided_node_features = provided_node_features_LDKChannelMessageHandler_jcall,
+               .provided_init_features = provided_init_features_LDKChannelMessageHandler_jcall,
                .free = LDKChannelMessageHandler_JCalls_free,
                .MessageSendEventsProvider = LDKMessageSendEventsProvider_init(env, clz, MessageSendEventsProvider),
        };
@@ -11940,6 +12720,31 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1handle_
        (this_arg_conv->handle_error)(this_arg_conv->this_arg, their_node_id_ref, &msg_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1provided_1node_1features(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKChannelMessageHandler* this_arg_conv = (LDKChannelMessageHandler*)this_arg_ptr;
+       LDKNodeFeatures ret_var = (this_arg_conv->provided_node_features)(this_arg_conv->this_arg);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1provided_1init_1features(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKChannelMessageHandler* this_arg_conv = (LDKChannelMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       LDKInitFeatures ret_var = (this_arg_conv->provided_init_features)(this_arg_conv->this_arg, their_node_id_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 typedef struct LDKRoutingMessageHandler_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -11948,13 +12753,15 @@ typedef struct LDKRoutingMessageHandler_JCalls {
        jmethodID handle_node_announcement_meth;
        jmethodID handle_channel_announcement_meth;
        jmethodID handle_channel_update_meth;
-       jmethodID get_next_channel_announcements_meth;
-       jmethodID get_next_node_announcements_meth;
+       jmethodID get_next_channel_announcement_meth;
+       jmethodID get_next_node_announcement_meth;
        jmethodID peer_connected_meth;
        jmethodID handle_reply_channel_range_meth;
        jmethodID handle_reply_short_channel_ids_end_meth;
        jmethodID handle_query_channel_range_meth;
        jmethodID handle_query_short_channel_ids_meth;
+       jmethodID provided_node_features_meth;
+       jmethodID provided_init_features_meth;
 } LDKRoutingMessageHandler_JCalls;
 static void LDKRoutingMessageHandler_JCalls_free(void* this_arg) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
@@ -12063,7 +12870,7 @@ LDKCResult_boolLightningErrorZ handle_channel_update_LDKRoutingMessageHandler_jc
        }
        return ret_conv;
 }
-LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ get_next_channel_announcements_LDKRoutingMessageHandler_jcall(const void* this_arg, uint64_t starting_point, uint8_t batch_amount) {
+LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ get_next_channel_announcement_LDKRoutingMessageHandler_jcall(const void* this_arg, uint64_t starting_point) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -12073,36 +12880,23 @@ LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ get_next_channel
                DO_ASSERT(get_jenv_res == JNI_OK);
        }
        int64_t starting_point_conv = starting_point;
-       int8_t batch_amount_conv = batch_amount;
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       int64_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->get_next_channel_announcements_meth, starting_point_conv, batch_amount_conv);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->get_next_channel_announcement_meth, starting_point_conv);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to get_next_channel_announcements in LDKRoutingMessageHandler from rust threw an exception.");
+               (*env)->FatalError(env, "A call to get_next_channel_announcement in LDKRoutingMessageHandler from rust threw an exception.");
        }
-       LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_constr;
-       ret_constr.datalen = (*env)->GetArrayLength(env, ret);
-       if (ret_constr.datalen > 0)
-               ret_constr.data = MALLOC(ret_constr.datalen * sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ Elements");
-       else
-               ret_constr.data = NULL;
-       int64_t* ret_vals = (*env)->GetLongArrayElements (env, ret, NULL);
-       for (size_t h = 0; h < ret_constr.datalen; h++) {
-               int64_t ret_conv_59 = ret_vals[h];
-               void* ret_conv_59_ptr = untag_ptr(ret_conv_59);
-               CHECK_ACCESS(ret_conv_59_ptr);
-               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ ret_conv_59_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(ret_conv_59_ptr);
-               FREE(untag_ptr(ret_conv_59));
-               ret_constr.data[h] = ret_conv_59_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, ret, ret_vals, 0);
+       void* ret_ptr = untag_ptr(ret);
+       CHECK_ACCESS(ret_ptr);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_conv = *(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)(ret_ptr);
+       FREE(untag_ptr(ret));
        if (get_jenv_res == JNI_EDETACHED) {
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
-       return ret_constr;
+       return ret_conv;
 }
-LDKCVec_NodeAnnouncementZ get_next_node_announcements_LDKRoutingMessageHandler_jcall(const void* this_arg, LDKPublicKey starting_point, uint8_t batch_amount) {
+LDKNodeAnnouncement get_next_node_announcement_LDKRoutingMessageHandler_jcall(const void* this_arg, LDKPublicKey starting_point) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -12113,34 +12907,21 @@ LDKCVec_NodeAnnouncementZ get_next_node_announcements_LDKRoutingMessageHandler_j
        }
        int8_tArray starting_point_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, starting_point_arr, 0, 33, starting_point.compressed_form);
-       int8_t batch_amount_conv = batch_amount;
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       int64_tArray ret = (*env)->CallObjectMethod(env, obj, j_calls->get_next_node_announcements_meth, starting_point_arr, batch_amount_conv);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->get_next_node_announcement_meth, starting_point_arr);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to get_next_node_announcements in LDKRoutingMessageHandler from rust threw an exception.");
-       }
-       LDKCVec_NodeAnnouncementZ ret_constr;
-       ret_constr.datalen = (*env)->GetArrayLength(env, ret);
-       if (ret_constr.datalen > 0)
-               ret_constr.data = MALLOC(ret_constr.datalen * sizeof(LDKNodeAnnouncement), "LDKCVec_NodeAnnouncementZ Elements");
-       else
-               ret_constr.data = NULL;
-       int64_t* ret_vals = (*env)->GetLongArrayElements (env, ret, NULL);
-       for (size_t s = 0; s < ret_constr.datalen; s++) {
-               int64_t ret_conv_18 = ret_vals[s];
-               LDKNodeAnnouncement ret_conv_18_conv;
-               ret_conv_18_conv.inner = untag_ptr(ret_conv_18);
-               ret_conv_18_conv.is_owned = ptr_is_owned(ret_conv_18);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv_18_conv);
-               ret_constr.data[s] = ret_conv_18_conv;
+               (*env)->FatalError(env, "A call to get_next_node_announcement in LDKRoutingMessageHandler from rust threw an exception.");
        }
-       (*env)->ReleaseLongArrayElements(env, ret, ret_vals, 0);
+       LDKNodeAnnouncement ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
        if (get_jenv_res == JNI_EDETACHED) {
                DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
        }
-       return ret_constr;
+       return ret_conv;
 }
 void peer_connected_LDKRoutingMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id, const LDKInit * init) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
@@ -12293,6 +13074,58 @@ LDKCResult_NoneLightningErrorZ handle_query_short_channel_ids_LDKRoutingMessageH
        }
        return ret_conv;
 }
+LDKNodeFeatures provided_node_features_LDKRoutingMessageHandler_jcall(const void* this_arg) {
+       LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_node_features_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_node_features in LDKRoutingMessageHandler from rust threw an exception.");
+       }
+       LDKNodeFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+LDKInitFeatures provided_init_features_LDKRoutingMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id) {
+       LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_init_features_meth, their_node_id_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_init_features in LDKRoutingMessageHandler from rust threw an exception.");
+       }
+       LDKInitFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
 static void LDKRoutingMessageHandler_JCalls_cloned(LDKRoutingMessageHandler* new_obj) {
        LDKRoutingMessageHandler_JCalls *j_calls = (LDKRoutingMessageHandler_JCalls*) new_obj->this_arg;
        atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
@@ -12311,10 +13144,10 @@ static inline LDKRoutingMessageHandler LDKRoutingMessageHandler_init (JNIEnv *en
        CHECK(calls->handle_channel_announcement_meth != NULL);
        calls->handle_channel_update_meth = (*env)->GetMethodID(env, c, "handle_channel_update", "(J)J");
        CHECK(calls->handle_channel_update_meth != NULL);
-       calls->get_next_channel_announcements_meth = (*env)->GetMethodID(env, c, "get_next_channel_announcements", "(JB)[J");
-       CHECK(calls->get_next_channel_announcements_meth != NULL);
-       calls->get_next_node_announcements_meth = (*env)->GetMethodID(env, c, "get_next_node_announcements", "([BB)[J");
-       CHECK(calls->get_next_node_announcements_meth != NULL);
+       calls->get_next_channel_announcement_meth = (*env)->GetMethodID(env, c, "get_next_channel_announcement", "(J)J");
+       CHECK(calls->get_next_channel_announcement_meth != NULL);
+       calls->get_next_node_announcement_meth = (*env)->GetMethodID(env, c, "get_next_node_announcement", "([B)J");
+       CHECK(calls->get_next_node_announcement_meth != NULL);
        calls->peer_connected_meth = (*env)->GetMethodID(env, c, "peer_connected", "([BJ)V");
        CHECK(calls->peer_connected_meth != NULL);
        calls->handle_reply_channel_range_meth = (*env)->GetMethodID(env, c, "handle_reply_channel_range", "([BJ)J");
@@ -12325,19 +13158,25 @@ static inline LDKRoutingMessageHandler LDKRoutingMessageHandler_init (JNIEnv *en
        CHECK(calls->handle_query_channel_range_meth != NULL);
        calls->handle_query_short_channel_ids_meth = (*env)->GetMethodID(env, c, "handle_query_short_channel_ids", "([BJ)J");
        CHECK(calls->handle_query_short_channel_ids_meth != NULL);
+       calls->provided_node_features_meth = (*env)->GetMethodID(env, c, "provided_node_features", "()J");
+       CHECK(calls->provided_node_features_meth != NULL);
+       calls->provided_init_features_meth = (*env)->GetMethodID(env, c, "provided_init_features", "([B)J");
+       CHECK(calls->provided_init_features_meth != NULL);
 
        LDKRoutingMessageHandler ret = {
                .this_arg = (void*) calls,
                .handle_node_announcement = handle_node_announcement_LDKRoutingMessageHandler_jcall,
                .handle_channel_announcement = handle_channel_announcement_LDKRoutingMessageHandler_jcall,
                .handle_channel_update = handle_channel_update_LDKRoutingMessageHandler_jcall,
-               .get_next_channel_announcements = get_next_channel_announcements_LDKRoutingMessageHandler_jcall,
-               .get_next_node_announcements = get_next_node_announcements_LDKRoutingMessageHandler_jcall,
+               .get_next_channel_announcement = get_next_channel_announcement_LDKRoutingMessageHandler_jcall,
+               .get_next_node_announcement = get_next_node_announcement_LDKRoutingMessageHandler_jcall,
                .peer_connected = peer_connected_LDKRoutingMessageHandler_jcall,
                .handle_reply_channel_range = handle_reply_channel_range_LDKRoutingMessageHandler_jcall,
                .handle_reply_short_channel_ids_end = handle_reply_short_channel_ids_end_LDKRoutingMessageHandler_jcall,
                .handle_query_channel_range = handle_query_channel_range_LDKRoutingMessageHandler_jcall,
                .handle_query_short_channel_ids = handle_query_short_channel_ids_LDKRoutingMessageHandler_jcall,
+               .provided_node_features = provided_node_features_LDKRoutingMessageHandler_jcall,
+               .provided_init_features = provided_init_features_LDKRoutingMessageHandler_jcall,
                .free = LDKRoutingMessageHandler_JCalls_free,
                .MessageSendEventsProvider = LDKMessageSendEventsProvider_init(env, clz, MessageSendEventsProvider),
        };
@@ -12395,45 +13234,28 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1hand
        return tag_ptr(ret_conv, true);
 }
 
-JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1channel_1announcements(JNIEnv *env, jclass clz, int64_t this_arg, int64_t starting_point, int8_t batch_amount) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1channel_1announcement(JNIEnv *env, jclass clz, int64_t this_arg, int64_t starting_point) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKRoutingMessageHandler* this_arg_conv = (LDKRoutingMessageHandler*)this_arg_ptr;
-       LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret_var = (this_arg_conv->get_next_channel_announcements)(this_arg_conv->this_arg, starting_point, batch_amount);
-       int64_tArray ret_arr = NULL;
-       ret_arr = (*env)->NewLongArray(env, ret_var.datalen);
-       int64_t *ret_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, ret_arr, NULL);
-       for (size_t h = 0; h < ret_var.datalen; h++) {
-               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ* ret_conv_59_conv = MALLOC(sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ");
-               *ret_conv_59_conv = ret_var.data[h];
-               ret_arr_ptr[h] = tag_ptr(ret_conv_59_conv, true);
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, ret_arr, ret_arr_ptr, 0);
-       FREE(ret_var.data);
-       return ret_arr;
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = (this_arg_conv->get_next_channel_announcement)(this_arg_conv->this_arg, starting_point);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
 }
 
-JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1node_1announcements(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray starting_point, int8_t batch_amount) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1node_1announcement(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray starting_point) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKRoutingMessageHandler* this_arg_conv = (LDKRoutingMessageHandler*)this_arg_ptr;
        LDKPublicKey starting_point_ref;
        CHECK((*env)->GetArrayLength(env, starting_point) == 33);
        (*env)->GetByteArrayRegion(env, starting_point, 0, 33, starting_point_ref.compressed_form);
-       LDKCVec_NodeAnnouncementZ ret_var = (this_arg_conv->get_next_node_announcements)(this_arg_conv->this_arg, starting_point_ref, batch_amount);
-       int64_tArray ret_arr = NULL;
-       ret_arr = (*env)->NewLongArray(env, ret_var.datalen);
-       int64_t *ret_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, ret_arr, NULL);
-       for (size_t s = 0; s < ret_var.datalen; s++) {
-               LDKNodeAnnouncement ret_conv_18_var = ret_var.data[s];
-               int64_t ret_conv_18_ref = 0;
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv_18_var);
-               ret_conv_18_ref = tag_ptr(ret_conv_18_var.inner, ret_conv_18_var.is_owned);
-               ret_arr_ptr[s] = ret_conv_18_ref;
-       }
-       (*env)->ReleasePrimitiveArrayCritical(env, ret_arr, ret_arr_ptr, 0);
-       FREE(ret_var.data);
-       return ret_arr;
+       LDKNodeAnnouncement ret_var = (this_arg_conv->get_next_node_announcement)(this_arg_conv->this_arg, starting_point_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1peer_1connected(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id, int64_t init) {
@@ -12519,6 +13341,298 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1hand
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1provided_1node_1features(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRoutingMessageHandler* this_arg_conv = (LDKRoutingMessageHandler*)this_arg_ptr;
+       LDKNodeFeatures ret_var = (this_arg_conv->provided_node_features)(this_arg_conv->this_arg);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1provided_1init_1features(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRoutingMessageHandler* this_arg_conv = (LDKRoutingMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       LDKInitFeatures ret_var = (this_arg_conv->provided_init_features)(this_arg_conv->this_arg, their_node_id_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+typedef struct LDKOnionMessageHandler_JCalls {
+       atomic_size_t refcnt;
+       JavaVM *vm;
+       jweak o;
+       LDKOnionMessageProvider_JCalls* OnionMessageProvider;
+       jmethodID handle_onion_message_meth;
+       jmethodID peer_connected_meth;
+       jmethodID peer_disconnected_meth;
+       jmethodID provided_node_features_meth;
+       jmethodID provided_init_features_meth;
+} LDKOnionMessageHandler_JCalls;
+static void LDKOnionMessageHandler_JCalls_free(void* this_arg) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
+               JNIEnv *env;
+               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+               } else {
+                       DO_ASSERT(get_jenv_res == JNI_OK);
+               }
+               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
+               if (get_jenv_res == JNI_EDETACHED) {
+                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               }
+               FREE(j_calls);
+       }
+}
+void handle_onion_message_LDKOnionMessageHandler_jcall(const void* this_arg, LDKPublicKey peer_node_id, const LDKOnionMessage * msg) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray peer_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, peer_node_id_arr, 0, 33, peer_node_id.compressed_form);
+       LDKOnionMessage msg_var = *msg;
+       int64_t msg_ref = 0;
+       msg_var = OnionMessage_clone(&msg_var);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_var);
+       msg_ref = tag_ptr(msg_var.inner, msg_var.is_owned);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->handle_onion_message_meth, peer_node_id_arr, msg_ref);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to handle_onion_message in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void peer_connected_LDKOnionMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id, const LDKInit * init) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       LDKInit init_var = *init;
+       int64_t init_ref = 0;
+       init_var = Init_clone(&init_var);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(init_var);
+       init_ref = tag_ptr(init_var.inner, init_var.is_owned);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->peer_connected_meth, their_node_id_arr, init_ref);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to peer_connected in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void peer_disconnected_LDKOnionMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id, bool no_connection_possible) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       jboolean no_connection_possible_conv = no_connection_possible;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->peer_disconnected_meth, their_node_id_arr, no_connection_possible_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to peer_disconnected in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+LDKNodeFeatures provided_node_features_LDKOnionMessageHandler_jcall(const void* this_arg) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_node_features_meth);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_node_features in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       LDKNodeFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+LDKInitFeatures provided_init_features_LDKOnionMessageHandler_jcall(const void* this_arg, LDKPublicKey their_node_id) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->provided_init_features_meth, their_node_id_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to provided_init_features in LDKOnionMessageHandler from rust threw an exception.");
+       }
+       LDKInitFeatures ret_conv;
+       ret_conv.inner = untag_ptr(ret);
+       ret_conv.is_owned = ptr_is_owned(ret);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_conv);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+       return ret_conv;
+}
+static void LDKOnionMessageHandler_JCalls_cloned(LDKOnionMessageHandler* new_obj) {
+       LDKOnionMessageHandler_JCalls *j_calls = (LDKOnionMessageHandler_JCalls*) new_obj->this_arg;
+       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
+       atomic_fetch_add_explicit(&j_calls->OnionMessageProvider->refcnt, 1, memory_order_release);
+}
+static inline LDKOnionMessageHandler LDKOnionMessageHandler_init (JNIEnv *env, jclass clz, jobject o, jobject OnionMessageProvider) {
+       jclass c = (*env)->GetObjectClass(env, o);
+       CHECK(c != NULL);
+       LDKOnionMessageHandler_JCalls *calls = MALLOC(sizeof(LDKOnionMessageHandler_JCalls), "LDKOnionMessageHandler_JCalls");
+       atomic_init(&calls->refcnt, 1);
+       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
+       calls->o = (*env)->NewWeakGlobalRef(env, o);
+       calls->handle_onion_message_meth = (*env)->GetMethodID(env, c, "handle_onion_message", "([BJ)V");
+       CHECK(calls->handle_onion_message_meth != NULL);
+       calls->peer_connected_meth = (*env)->GetMethodID(env, c, "peer_connected", "([BJ)V");
+       CHECK(calls->peer_connected_meth != NULL);
+       calls->peer_disconnected_meth = (*env)->GetMethodID(env, c, "peer_disconnected", "([BZ)V");
+       CHECK(calls->peer_disconnected_meth != NULL);
+       calls->provided_node_features_meth = (*env)->GetMethodID(env, c, "provided_node_features", "()J");
+       CHECK(calls->provided_node_features_meth != NULL);
+       calls->provided_init_features_meth = (*env)->GetMethodID(env, c, "provided_init_features", "([B)J");
+       CHECK(calls->provided_init_features_meth != NULL);
+
+       LDKOnionMessageHandler ret = {
+               .this_arg = (void*) calls,
+               .handle_onion_message = handle_onion_message_LDKOnionMessageHandler_jcall,
+               .peer_connected = peer_connected_LDKOnionMessageHandler_jcall,
+               .peer_disconnected = peer_disconnected_LDKOnionMessageHandler_jcall,
+               .provided_node_features = provided_node_features_LDKOnionMessageHandler_jcall,
+               .provided_init_features = provided_init_features_LDKOnionMessageHandler_jcall,
+               .free = LDKOnionMessageHandler_JCalls_free,
+               .OnionMessageProvider = LDKOnionMessageProvider_init(env, clz, OnionMessageProvider),
+       };
+       calls->OnionMessageProvider = ret.OnionMessageProvider.this_arg;
+       return ret;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKOnionMessageHandler_1new(JNIEnv *env, jclass clz, jobject o, jobject OnionMessageProvider) {
+       LDKOnionMessageHandler *res_ptr = MALLOC(sizeof(LDKOnionMessageHandler), "LDKOnionMessageHandler");
+       *res_ptr = LDKOnionMessageHandler_init(env, clz, o, OnionMessageProvider);
+       return tag_ptr(res_ptr, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKOnionMessageHandler_1get_1OnionMessageProvider(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKOnionMessageHandler *inp = (LDKOnionMessageHandler *)untag_ptr(arg);
+       return tag_ptr(&inp->OnionMessageProvider, false);
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1handle_1onion_1message(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray peer_node_id, int64_t msg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKPublicKey peer_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, peer_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, peer_node_id, 0, 33, peer_node_id_ref.compressed_form);
+       LDKOnionMessage msg_conv;
+       msg_conv.inner = untag_ptr(msg);
+       msg_conv.is_owned = ptr_is_owned(msg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_conv);
+       msg_conv.is_owned = false;
+       (this_arg_conv->handle_onion_message)(this_arg_conv->this_arg, peer_node_id_ref, &msg_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1peer_1connected(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id, int64_t init) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       LDKInit init_conv;
+       init_conv.inner = untag_ptr(init);
+       init_conv.is_owned = ptr_is_owned(init);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(init_conv);
+       init_conv.is_owned = false;
+       (this_arg_conv->peer_connected)(this_arg_conv->this_arg, their_node_id_ref, &init_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1peer_1disconnected(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id, jboolean no_connection_possible) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       (this_arg_conv->peer_disconnected)(this_arg_conv->this_arg, their_node_id_ref, no_connection_possible);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1provided_1node_1features(JNIEnv *env, jclass clz, int64_t this_arg) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKNodeFeatures ret_var = (this_arg_conv->provided_node_features)(this_arg_conv->this_arg);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1provided_1init_1features(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray their_node_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKOnionMessageHandler* this_arg_conv = (LDKOnionMessageHandler*)this_arg_ptr;
+       LDKPublicKey their_node_id_ref;
+       CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
+       (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
+       LDKInitFeatures ret_var = (this_arg_conv->provided_init_features)(this_arg_conv->this_arg, their_node_id_ref);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 typedef struct LDKCustomMessageReader_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -13014,93 +14128,40 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKEffectiveCapacity_1ref_1
                default: abort();
        }
 }
-typedef struct LDKLockableScore_JCalls {
-       atomic_size_t refcnt;
-       JavaVM *vm;
-       jweak o;
-       jmethodID lock_meth;
-} LDKLockableScore_JCalls;
-static void LDKLockableScore_JCalls_free(void* this_arg) {
-       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) this_arg;
-       if (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {
-               JNIEnv *env;
-               jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-               if (get_jenv_res == JNI_EDETACHED) {
-                       DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-               } else {
-                       DO_ASSERT(get_jenv_res == JNI_OK);
+static jclass LDKDestination_Node_class = NULL;
+static jmethodID LDKDestination_Node_meth = NULL;
+static jclass LDKDestination_BlindedRoute_class = NULL;
+static jmethodID LDKDestination_BlindedRoute_meth = NULL;
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKDestination_init (JNIEnv *env, jclass clz) {
+       LDKDestination_Node_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKDestination$Node"));
+       CHECK(LDKDestination_Node_class != NULL);
+       LDKDestination_Node_meth = (*env)->GetMethodID(env, LDKDestination_Node_class, "<init>", "([B)V");
+       CHECK(LDKDestination_Node_meth != NULL);
+       LDKDestination_BlindedRoute_class =
+               (*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/ldk/impl/bindings$LDKDestination$BlindedRoute"));
+       CHECK(LDKDestination_BlindedRoute_class != NULL);
+       LDKDestination_BlindedRoute_meth = (*env)->GetMethodID(env, LDKDestination_BlindedRoute_class, "<init>", "(J)V");
+       CHECK(LDKDestination_BlindedRoute_meth != NULL);
+}
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKDestination_1ref_1from_1ptr(JNIEnv *env, jclass clz, int64_t ptr) {
+       LDKDestination *obj = (LDKDestination*)untag_ptr(ptr);
+       switch(obj->tag) {
+               case LDKDestination_Node: {
+                       int8_tArray node_arr = (*env)->NewByteArray(env, 33);
+                       (*env)->SetByteArrayRegion(env, node_arr, 0, 33, obj->node.compressed_form);
+                       return (*env)->NewObject(env, LDKDestination_Node_class, LDKDestination_Node_meth, node_arr);
                }
-               (*env)->DeleteWeakGlobalRef(env, j_calls->o);
-               if (get_jenv_res == JNI_EDETACHED) {
-                       DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               case LDKDestination_BlindedRoute: {
+                       LDKBlindedRoute blinded_route_var = obj->blinded_route;
+                       int64_t blinded_route_ref = 0;
+                       CHECK_INNER_FIELD_ACCESS_OR_NULL(blinded_route_var);
+                       blinded_route_ref = tag_ptr(blinded_route_var.inner, false);
+                       return (*env)->NewObject(env, LDKDestination_BlindedRoute_class, LDKDestination_BlindedRoute_meth, blinded_route_ref);
                }
-               FREE(j_calls);
-       }
-}
-LDKScore lock_LDKLockableScore_jcall(const void* this_arg) {
-       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) this_arg;
-       JNIEnv *env;
-       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
-       } else {
-               DO_ASSERT(get_jenv_res == JNI_OK);
-       }
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->lock_meth);
-       if (UNLIKELY((*env)->ExceptionCheck(env))) {
-               (*env)->ExceptionDescribe(env);
-               (*env)->FatalError(env, "A call to lock in LDKLockableScore from rust threw an exception.");
-       }
-       void* ret_ptr = untag_ptr(ret);
-       CHECK_ACCESS(ret_ptr);
-       LDKScore ret_conv = *(LDKScore*)(ret_ptr);
-       if (ret_conv.free == LDKScore_JCalls_free) {
-               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
-               LDKScore_JCalls_cloned(&ret_conv);
-       }// WARNING: we may need a move here but no clone is available for LDKScore
-       
-       if (get_jenv_res == JNI_EDETACHED) {
-               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+               default: abort();
        }
-       return ret_conv;
-}
-static void LDKLockableScore_JCalls_cloned(LDKLockableScore* new_obj) {
-       LDKLockableScore_JCalls *j_calls = (LDKLockableScore_JCalls*) new_obj->this_arg;
-       atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
-}
-static inline LDKLockableScore LDKLockableScore_init (JNIEnv *env, jclass clz, jobject o) {
-       jclass c = (*env)->GetObjectClass(env, o);
-       CHECK(c != NULL);
-       LDKLockableScore_JCalls *calls = MALLOC(sizeof(LDKLockableScore_JCalls), "LDKLockableScore_JCalls");
-       atomic_init(&calls->refcnt, 1);
-       DO_ASSERT((*env)->GetJavaVM(env, &calls->vm) == 0);
-       calls->o = (*env)->NewWeakGlobalRef(env, o);
-       calls->lock_meth = (*env)->GetMethodID(env, c, "lock", "()J");
-       CHECK(calls->lock_meth != NULL);
-
-       LDKLockableScore ret = {
-               .this_arg = (void*) calls,
-               .lock = lock_LDKLockableScore_jcall,
-               .free = LDKLockableScore_JCalls_free,
-       };
-       return ret;
-}
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKLockableScore_1new(JNIEnv *env, jclass clz, jobject o) {
-       LDKLockableScore *res_ptr = MALLOC(sizeof(LDKLockableScore), "LDKLockableScore");
-       *res_ptr = LDKLockableScore_init(env, clz, o);
-       return tag_ptr(res_ptr, true);
 }
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LockableScore_1lock(JNIEnv *env, jclass clz, int64_t this_arg) {
-       void* this_arg_ptr = untag_ptr(this_arg);
-       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
-       LDKLockableScore* this_arg_conv = (LDKLockableScore*)this_arg_ptr;
-       LDKScore* ret_ret = MALLOC(sizeof(LDKScore), "LDKScore");
-       *ret_ret = (this_arg_conv->lock)(this_arg_conv->this_arg);
-       return tag_ptr(ret_ret, true);
-}
-
 static jclass LDKGossipSync_P2P_class = NULL;
 static jmethodID LDKGossipSync_P2P_meth = NULL;
 static jclass LDKGossipSync_Rapid_class = NULL;
@@ -13541,6 +14602,10 @@ typedef struct LDKRouter_JCalls {
        JavaVM *vm;
        jweak o;
        jmethodID find_route_meth;
+       jmethodID notify_payment_path_failed_meth;
+       jmethodID notify_payment_path_successful_meth;
+       jmethodID notify_payment_probe_successful_meth;
+       jmethodID notify_payment_probe_failed_meth;
 } LDKRouter_JCalls;
 static void LDKRouter_JCalls_free(void* this_arg) {
        LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
@@ -13559,7 +14624,7 @@ static void LDKRouter_JCalls_free(void* this_arg) {
                FREE(j_calls);
        }
 }
-LDKCResult_RouteLightningErrorZ find_route_LDKRouter_jcall(const void* this_arg, LDKPublicKey payer, const LDKRouteParameters * route_params, const uint8_t (* payment_hash)[32], LDKCVec_ChannelDetailsZ * first_hops, const LDKScore * scorer) {
+LDKCResult_RouteLightningErrorZ find_route_LDKRouter_jcall(const void* this_arg, LDKPublicKey payer, const LDKRouteParameters * route_params, const uint8_t (* payment_hash)[32], LDKCVec_ChannelDetailsZ * first_hops, LDKInFlightHtlcs inflight_htlcs) {
        LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
        JNIEnv *env;
        jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
@@ -13592,11 +14657,13 @@ LDKCResult_RouteLightningErrorZ find_route_LDKRouter_jcall(const void* this_arg,
                }
                (*env)->ReleasePrimitiveArrayCritical(env, first_hops_arr, first_hops_arr_ptr, 0);
        }
-       // WARNING: This object doesn't live past this scope, needs clone!
-       int64_t ret_scorer = tag_ptr(scorer, false);
+       LDKInFlightHtlcs inflight_htlcs_var = inflight_htlcs;
+       int64_t inflight_htlcs_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(inflight_htlcs_var);
+       inflight_htlcs_ref = tag_ptr(inflight_htlcs_var.inner, inflight_htlcs_var.is_owned);
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->find_route_meth, payer_arr, route_params_ref, payment_hash_arr, first_hops_arr, ret_scorer);
+       uint64_t ret = (*env)->CallLongMethod(env, obj, j_calls->find_route_meth, payer_arr, route_params_ref, payment_hash_arr, first_hops_arr, inflight_htlcs_ref);
        if (UNLIKELY((*env)->ExceptionCheck(env))) {
                (*env)->ExceptionDescribe(env);
                (*env)->FatalError(env, "A call to find_route in LDKRouter from rust threw an exception.");
@@ -13610,6 +14677,140 @@ LDKCResult_RouteLightningErrorZ find_route_LDKRouter_jcall(const void* this_arg,
        }
        return ret_conv;
 }
+void notify_payment_path_failed_LDKRouter_jcall(const void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
+       LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       int64_t short_channel_id_conv = short_channel_id;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->notify_payment_path_failed_meth, path_arr, short_channel_id_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to notify_payment_path_failed in LDKRouter from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void notify_payment_path_successful_LDKRouter_jcall(const void* this_arg, LDKCVec_RouteHopZ path) {
+       LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->notify_payment_path_successful_meth, path_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to notify_payment_path_successful in LDKRouter from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void notify_payment_probe_successful_LDKRouter_jcall(const void* this_arg, LDKCVec_RouteHopZ path) {
+       LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->notify_payment_probe_successful_meth, path_arr);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to notify_payment_probe_successful in LDKRouter from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
+void notify_payment_probe_failed_LDKRouter_jcall(const void* this_arg, LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
+       LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) this_arg;
+       JNIEnv *env;
+       jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);
+       } else {
+               DO_ASSERT(get_jenv_res == JNI_OK);
+       }
+       LDKCVec_RouteHopZ path_var = path;
+       int64_tArray path_arr = NULL;
+       path_arr = (*env)->NewLongArray(env, path_var.datalen);
+       int64_t *path_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, path_arr, NULL);
+       for (size_t k = 0; k < path_var.datalen; k++) {
+               LDKRouteHop path_conv_10_var = path_var.data[k];
+               int64_t path_conv_10_ref = 0;
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_var);
+               path_conv_10_ref = tag_ptr(path_conv_10_var.inner, path_conv_10_var.is_owned);
+               path_arr_ptr[k] = path_conv_10_ref;
+       }
+       (*env)->ReleasePrimitiveArrayCritical(env, path_arr, path_arr_ptr, 0);
+       FREE(path_var.data);
+       int64_t short_channel_id_conv = short_channel_id;
+       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
+       CHECK(obj != NULL);
+       (*env)->CallVoidMethod(env, obj, j_calls->notify_payment_probe_failed_meth, path_arr, short_channel_id_conv);
+       if (UNLIKELY((*env)->ExceptionCheck(env))) {
+               (*env)->ExceptionDescribe(env);
+               (*env)->FatalError(env, "A call to notify_payment_probe_failed in LDKRouter from rust threw an exception.");
+       }
+       if (get_jenv_res == JNI_EDETACHED) {
+               DO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);
+       }
+}
 static void LDKRouter_JCalls_cloned(LDKRouter* new_obj) {
        LDKRouter_JCalls *j_calls = (LDKRouter_JCalls*) new_obj->this_arg;
        atomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);
@@ -13623,10 +14824,22 @@ static inline LDKRouter LDKRouter_init (JNIEnv *env, jclass clz, jobject o) {
        calls->o = (*env)->NewWeakGlobalRef(env, o);
        calls->find_route_meth = (*env)->GetMethodID(env, c, "find_route", "([BJ[B[JJ)J");
        CHECK(calls->find_route_meth != NULL);
+       calls->notify_payment_path_failed_meth = (*env)->GetMethodID(env, c, "notify_payment_path_failed", "([JJ)V");
+       CHECK(calls->notify_payment_path_failed_meth != NULL);
+       calls->notify_payment_path_successful_meth = (*env)->GetMethodID(env, c, "notify_payment_path_successful", "([J)V");
+       CHECK(calls->notify_payment_path_successful_meth != NULL);
+       calls->notify_payment_probe_successful_meth = (*env)->GetMethodID(env, c, "notify_payment_probe_successful", "([J)V");
+       CHECK(calls->notify_payment_probe_successful_meth != NULL);
+       calls->notify_payment_probe_failed_meth = (*env)->GetMethodID(env, c, "notify_payment_probe_failed", "([JJ)V");
+       CHECK(calls->notify_payment_probe_failed_meth != NULL);
 
        LDKRouter ret = {
                .this_arg = (void*) calls,
                .find_route = find_route_LDKRouter_jcall,
+               .notify_payment_path_failed = notify_payment_path_failed_LDKRouter_jcall,
+               .notify_payment_path_successful = notify_payment_path_successful_LDKRouter_jcall,
+               .notify_payment_probe_successful = notify_payment_probe_successful_LDKRouter_jcall,
+               .notify_payment_probe_failed = notify_payment_probe_failed_LDKRouter_jcall,
                .free = LDKRouter_JCalls_free,
        };
        return ret;
@@ -13636,7 +14849,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKRouter_1new(JNIEnv *env,
        *res_ptr = LDKRouter_init(env, clz, o);
        return tag_ptr(res_ptr, true);
 }
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Router_1find_1route(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray payer, int64_t route_params, int8_tArray payment_hash, int64_tArray first_hops, int64_t scorer) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Router_1find_1route(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray payer, int64_t route_params, int8_tArray payment_hash, int64_tArray first_hops, int64_t inflight_htlcs) {
        void* this_arg_ptr = untag_ptr(this_arg);
        if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
        LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
@@ -13673,15 +14886,114 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Router_1find_1route(JNIEnv
                (*env)->ReleaseLongArrayElements(env, first_hops, first_hops_vals, 0);
                first_hops_ptr = &first_hops_constr;
        }
-       void* scorer_ptr = untag_ptr(scorer);
-       if (ptr_is_owned(scorer)) { CHECK_ACCESS(scorer_ptr); }
-       LDKScore* scorer_conv = (LDKScore*)scorer_ptr;
+       LDKInFlightHtlcs inflight_htlcs_conv;
+       inflight_htlcs_conv.inner = untag_ptr(inflight_htlcs);
+       inflight_htlcs_conv.is_owned = ptr_is_owned(inflight_htlcs);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(inflight_htlcs_conv);
+       // WARNING: we need a move here but no clone is available for LDKInFlightHtlcs
+       
        LDKCResult_RouteLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_RouteLightningErrorZ), "LDKCResult_RouteLightningErrorZ");
-       *ret_conv = (this_arg_conv->find_route)(this_arg_conv->this_arg, payer_ref, &route_params_conv, payment_hash_ref, first_hops_ptr, scorer_conv);
+       *ret_conv = (this_arg_conv->find_route)(this_arg_conv->this_arg, payer_ref, &route_params_conv, payment_hash_ref, first_hops_ptr, inflight_htlcs_conv);
        if (first_hops_ptr != NULL) { FREE(first_hops_constr.data); }
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1path_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->notify_payment_path_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1path_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->notify_payment_path_successful)(this_arg_conv->this_arg, path_constr);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1probe_1successful(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->notify_payment_probe_successful)(this_arg_conv->this_arg, path_constr);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1probe_1failed(JNIEnv *env, jclass clz, int64_t this_arg, int64_tArray path, int64_t short_channel_id) {
+       void* this_arg_ptr = untag_ptr(this_arg);
+       if (ptr_is_owned(this_arg)) { CHECK_ACCESS(this_arg_ptr); }
+       LDKRouter* this_arg_conv = (LDKRouter*)this_arg_ptr;
+       LDKCVec_RouteHopZ path_constr;
+       path_constr.datalen = (*env)->GetArrayLength(env, path);
+       if (path_constr.datalen > 0)
+               path_constr.data = MALLOC(path_constr.datalen * sizeof(LDKRouteHop), "LDKCVec_RouteHopZ Elements");
+       else
+               path_constr.data = NULL;
+       int64_t* path_vals = (*env)->GetLongArrayElements (env, path, NULL);
+       for (size_t k = 0; k < path_constr.datalen; k++) {
+               int64_t path_conv_10 = path_vals[k];
+               LDKRouteHop path_conv_10_conv;
+               path_conv_10_conv.inner = untag_ptr(path_conv_10);
+               path_conv_10_conv.is_owned = ptr_is_owned(path_conv_10);
+               CHECK_INNER_FIELD_ACCESS_OR_NULL(path_conv_10_conv);
+               path_conv_10_conv = RouteHop_clone(&path_conv_10_conv);
+               path_constr.data[k] = path_conv_10_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, path, path_vals, 0);
+       (this_arg_conv->notify_payment_probe_failed)(this_arg_conv->this_arg, path_constr, short_channel_id);
+}
+
 static jclass LDKRetry_Attempts_class = NULL;
 static jmethodID LDKRetry_Attempts_meth = NULL;
 static jclass LDKRetry_Timeout_class = NULL;
@@ -13726,6 +15038,15 @@ JNIEXPORT jstring JNICALL Java_org_ldk_impl_bindings__1ldk_1c_1bindings_1get_1co
        return ret_conv;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BigEndianScalar_1new(JNIEnv *env, jclass clz, int8_tArray big_endian_bytes) {
+       LDKThirtyTwoBytes big_endian_bytes_ref;
+       CHECK((*env)->GetArrayLength(env, big_endian_bytes) == 32);
+       (*env)->GetByteArrayRegion(env, big_endian_bytes, 0, 32, big_endian_bytes_ref.data);
+       LDKBigEndianScalar* ret_ref = MALLOC(sizeof(LDKBigEndianScalar), "LDKBigEndianScalar");
+       *ret_ref = BigEndianScalar_new(big_endian_bytes_ref);
+       return tag_ptr(ret_ref, true);
+}
+
 static inline uint64_t Bech32Error_clone_ptr(LDKBech32Error *NONNULL_PTR arg) {
        LDKBech32Error *ret_copy = MALLOC(sizeof(LDKBech32Error), "LDKBech32Error");
        *ret_copy = Bech32Error_clone(arg);
@@ -13806,6 +15127,132 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Str_1free(JNIEnv *env, jclass
        Str_free(dummy);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1PublicKeyZ_1free(JNIEnv *env, jclass clz, jobjectArray _res) {
+       LDKCVec_PublicKeyZ _res_constr;
+       _res_constr.datalen = (*env)->GetArrayLength(env, _res);
+       if (_res_constr.datalen > 0)
+               _res_constr.data = MALLOC(_res_constr.datalen * sizeof(LDKPublicKey), "LDKCVec_PublicKeyZ Elements");
+       else
+               _res_constr.data = NULL;
+       for (size_t i = 0; i < _res_constr.datalen; i++) {
+               int8_tArray _res_conv_8 = (*env)->GetObjectArrayElement(env, _res, i);
+               LDKPublicKey _res_conv_8_ref;
+               CHECK((*env)->GetArrayLength(env, _res_conv_8) == 33);
+               (*env)->GetByteArrayRegion(env, _res_conv_8, 0, 33, _res_conv_8_ref.compressed_form);
+               _res_constr.data[i] = _res_conv_8_ref;
+       }
+       CVec_PublicKeyZ_free(_res_constr);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKBlindedRoute o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       // WARNING: we need a move here but no clone is available for LDKBlindedRoute
+       
+       LDKCResult_BlindedRouteNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteNoneZ), "LDKCResult_BlindedRouteNoneZ");
+       *ret_conv = CResult_BlindedRouteNoneZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1err(JNIEnv *env, jclass clz) {
+       LDKCResult_BlindedRouteNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteNoneZ), "LDKCResult_BlindedRouteNoneZ");
+       *ret_conv = CResult_BlindedRouteNoneZ_err();
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_BlindedRouteNoneZ* o_conv = (LDKCResult_BlindedRouteNoneZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_BlindedRouteNoneZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_BlindedRouteNoneZ _res_conv = *(LDKCResult_BlindedRouteNoneZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_BlindedRouteNoneZ_free(_res_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKBlindedRoute o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       // WARNING: we need a move here but no clone is available for LDKBlindedRoute
+       
+       LDKCResult_BlindedRouteDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteDecodeErrorZ), "LDKCResult_BlindedRouteDecodeErrorZ");
+       *ret_conv = CResult_BlindedRouteDecodeErrorZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       LDKDecodeError e_conv;
+       e_conv.inner = untag_ptr(e);
+       e_conv.is_owned = ptr_is_owned(e);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(e_conv);
+       e_conv = DecodeError_clone(&e_conv);
+       LDKCResult_BlindedRouteDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteDecodeErrorZ), "LDKCResult_BlindedRouteDecodeErrorZ");
+       *ret_conv = CResult_BlindedRouteDecodeErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_BlindedRouteDecodeErrorZ* o_conv = (LDKCResult_BlindedRouteDecodeErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_BlindedRouteDecodeErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_BlindedRouteDecodeErrorZ _res_conv = *(LDKCResult_BlindedRouteDecodeErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_BlindedRouteDecodeErrorZ_free(_res_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKBlindedHop o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       // WARNING: we need a move here but no clone is available for LDKBlindedHop
+       
+       LDKCResult_BlindedHopDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedHopDecodeErrorZ), "LDKCResult_BlindedHopDecodeErrorZ");
+       *ret_conv = CResult_BlindedHopDecodeErrorZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       LDKDecodeError e_conv;
+       e_conv.inner = untag_ptr(e);
+       e_conv.is_owned = ptr_is_owned(e);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(e_conv);
+       e_conv = DecodeError_clone(&e_conv);
+       LDKCResult_BlindedHopDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedHopDecodeErrorZ), "LDKCResult_BlindedHopDecodeErrorZ");
+       *ret_conv = CResult_BlindedHopDecodeErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_BlindedHopDecodeErrorZ* o_conv = (LDKCResult_BlindedHopDecodeErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_BlindedHopDecodeErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_BlindedHopDecodeErrorZ _res_conv = *(LDKCResult_BlindedHopDecodeErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_BlindedHopDecodeErrorZ_free(_res_conv);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneNoneZ_1ok(JNIEnv *env, jclass clz) {
        LDKCResult_NoneNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneNoneZ), "LDKCResult_NoneNoneZ");
        *ret_conv = CResult_NoneNoneZ_ok();
@@ -14804,6 +16251,36 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ShutdownScriptInva
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1WriteableScoreZ_1some(JNIEnv *env, jclass clz, int64_t o) {
+       void* o_ptr = untag_ptr(o);
+       CHECK_ACCESS(o_ptr);
+       LDKWriteableScore o_conv = *(LDKWriteableScore*)(o_ptr);
+       if (o_conv.free == LDKWriteableScore_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKWriteableScore_JCalls_cloned(&o_conv);
+       }
+       LDKCOption_WriteableScoreZ *ret_copy = MALLOC(sizeof(LDKCOption_WriteableScoreZ), "LDKCOption_WriteableScoreZ");
+       *ret_copy = COption_WriteableScoreZ_some(o_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1WriteableScoreZ_1none(JNIEnv *env, jclass clz) {
+       LDKCOption_WriteableScoreZ *ret_copy = MALLOC(sizeof(LDKCOption_WriteableScoreZ), "LDKCOption_WriteableScoreZ");
+       *ret_copy = COption_WriteableScoreZ_none();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1WriteableScoreZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCOption_WriteableScoreZ _res_conv = *(LDKCOption_WriteableScoreZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       COption_WriteableScoreZ_free(_res_conv);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneErrorZ_1ok(JNIEnv *env, jclass clz) {
        LDKCResult_NoneErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneErrorZ), "LDKCResult_NoneErrorZ");
        *ret_conv = CResult_NoneErrorZ_ok();
@@ -15404,23 +16881,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RouteLightningErro
        return tag_ptr(ret_conv, true);
 }
 
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1PublicKeyZ_1free(JNIEnv *env, jclass clz, jobjectArray _res) {
-       LDKCVec_PublicKeyZ _res_constr;
-       _res_constr.datalen = (*env)->GetArrayLength(env, _res);
-       if (_res_constr.datalen > 0)
-               _res_constr.data = MALLOC(_res_constr.datalen * sizeof(LDKPublicKey), "LDKCVec_PublicKeyZ Elements");
-       else
-               _res_constr.data = NULL;
-       for (size_t i = 0; i < _res_constr.datalen; i++) {
-               int8_tArray _res_conv_8 = (*env)->GetObjectArrayElement(env, _res, i);
-               LDKPublicKey _res_conv_8_ref;
-               CHECK((*env)->GetArrayLength(env, _res_conv_8) == 33);
-               (*env)->GetByteArrayRegion(env, _res_conv_8, 0, 33, _res_conv_8_ref.compressed_form);
-               _res_constr.data[i] = _res_conv_8_ref;
-       }
-       CVec_PublicKeyZ_free(_res_constr);
-}
-
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentPurposeDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        void* o_ptr = untag_ptr(o);
        CHECK_ACCESS(o_ptr);
@@ -16133,53 +17593,6 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C3Tuple_1OutPointCVec_1M
        CVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ_free(_res_constr);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1some(JNIEnv *env, jclass clz, int64_t o) {
-       void* o_ptr = untag_ptr(o);
-       CHECK_ACCESS(o_ptr);
-       LDKC2Tuple_usizeTransactionZ o_conv = *(LDKC2Tuple_usizeTransactionZ*)(o_ptr);
-       o_conv = C2Tuple_usizeTransactionZ_clone((LDKC2Tuple_usizeTransactionZ*)untag_ptr(o));
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = COption_C2Tuple_usizeTransactionZZ_some(o_conv);
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
-}
-
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1none(JNIEnv *env, jclass clz) {
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = COption_C2Tuple_usizeTransactionZZ_none();
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       if (!ptr_is_owned(_res)) return;
-       void* _res_ptr = untag_ptr(_res);
-       CHECK_ACCESS(_res_ptr);
-       LDKCOption_C2Tuple_usizeTransactionZZ _res_conv = *(LDKCOption_C2Tuple_usizeTransactionZZ*)(_res_ptr);
-       FREE(untag_ptr(_res));
-       COption_C2Tuple_usizeTransactionZZ_free(_res_conv);
-}
-
-static inline uint64_t COption_C2Tuple_usizeTransactionZZ_clone_ptr(LDKCOption_C2Tuple_usizeTransactionZZ *NONNULL_PTR arg) {
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = COption_C2Tuple_usizeTransactionZZ_clone(arg);
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
-}
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCOption_C2Tuple_usizeTransactionZZ* arg_conv = (LDKCOption_C2Tuple_usizeTransactionZZ*)untag_ptr(arg);
-       int64_t ret_conv = COption_C2Tuple_usizeTransactionZZ_clone_ptr(arg_conv);
-       return ret_conv;
-}
-
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKCOption_C2Tuple_usizeTransactionZZ* orig_conv = (LDKCOption_C2Tuple_usizeTransactionZZ*)untag_ptr(orig);
-       LDKCOption_C2Tuple_usizeTransactionZZ *ret_copy = MALLOC(sizeof(LDKCOption_C2Tuple_usizeTransactionZZ), "LDKCOption_C2Tuple_usizeTransactionZZ");
-       *ret_copy = COption_C2Tuple_usizeTransactionZZ_clone(orig_conv);
-       int64_t ret_ref = tag_ptr(ret_copy, true);
-       return ret_ref;
-}
-
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1FixedPenaltyScorerDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        LDKFixedPenaltyScorer o_conv;
        o_conv.inner = untag_ptr(o);
@@ -16885,44 +18298,51 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C3Tuple_1ChannelAnnouncementCh
        C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free(_res_conv);
 }
 
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1free(JNIEnv *env, jclass clz, int64_tArray _res) {
-       LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ _res_constr;
-       _res_constr.datalen = (*env)->GetArrayLength(env, _res);
-       if (_res_constr.datalen > 0)
-               _res_constr.data = MALLOC(_res_constr.datalen * sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ Elements");
-       else
-               _res_constr.data = NULL;
-       int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
-       for (size_t h = 0; h < _res_constr.datalen; h++) {
-               int64_t _res_conv_59 = _res_vals[h];
-               void* _res_conv_59_ptr = untag_ptr(_res_conv_59);
-               CHECK_ACCESS(_res_conv_59_ptr);
-               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ _res_conv_59_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(_res_conv_59_ptr);
-               FREE(untag_ptr(_res_conv_59));
-               _res_constr.data[h] = _res_conv_59_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, _res, _res_vals, 0);
-       CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free(_res_constr);
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1some(JNIEnv *env, jclass clz, int64_t o) {
+       void* o_ptr = untag_ptr(o);
+       CHECK_ACCESS(o_ptr);
+       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ o_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(o_ptr);
+       o_conv = C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_clone((LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)untag_ptr(o));
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_some(o_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
 }
 
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1NodeAnnouncementZ_1free(JNIEnv *env, jclass clz, int64_tArray _res) {
-       LDKCVec_NodeAnnouncementZ _res_constr;
-       _res_constr.datalen = (*env)->GetArrayLength(env, _res);
-       if (_res_constr.datalen > 0)
-               _res_constr.data = MALLOC(_res_constr.datalen * sizeof(LDKNodeAnnouncement), "LDKCVec_NodeAnnouncementZ Elements");
-       else
-               _res_constr.data = NULL;
-       int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
-       for (size_t s = 0; s < _res_constr.datalen; s++) {
-               int64_t _res_conv_18 = _res_vals[s];
-               LDKNodeAnnouncement _res_conv_18_conv;
-               _res_conv_18_conv.inner = untag_ptr(_res_conv_18);
-               _res_conv_18_conv.is_owned = ptr_is_owned(_res_conv_18);
-               CHECK_INNER_FIELD_ACCESS_OR_NULL(_res_conv_18_conv);
-               _res_constr.data[s] = _res_conv_18_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, _res, _res_vals, 0);
-       CVec_NodeAnnouncementZ_free(_res_constr);
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1none(JNIEnv *env, jclass clz) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_none();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ _res_conv = *(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free(_res_conv);
+}
+
+static inline uint64_t COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone_ptr(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *NONNULL_PTR arg) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(arg);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ* arg_conv = (LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)untag_ptr(arg);
+       int64_t ret_conv = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone_ptr(arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ* orig_conv = (LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ*)untag_ptr(orig);
+       LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *ret_copy = MALLOC(sizeof(LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ), "LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ");
+       *ret_copy = COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(orig_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneLightningErrorZ_1ok(JNIEnv *env, jclass clz) {
@@ -17885,6 +19305,81 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeyNoneZ_1cl
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1ScalarZ_1some(JNIEnv *env, jclass clz, int64_t o) {
+       void* o_ptr = untag_ptr(o);
+       CHECK_ACCESS(o_ptr);
+       LDKBigEndianScalar o_conv = *(LDKBigEndianScalar*)(o_ptr);
+       // WARNING: we may need a move here but no clone is available for LDKBigEndianScalar
+       LDKCOption_ScalarZ *ret_copy = MALLOC(sizeof(LDKCOption_ScalarZ), "LDKCOption_ScalarZ");
+       *ret_copy = COption_ScalarZ_some(o_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_COption_1ScalarZ_1none(JNIEnv *env, jclass clz) {
+       LDKCOption_ScalarZ *ret_copy = MALLOC(sizeof(LDKCOption_ScalarZ), "LDKCOption_ScalarZ");
+       *ret_copy = COption_ScalarZ_none();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1ScalarZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCOption_ScalarZ _res_conv = *(LDKCOption_ScalarZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       COption_ScalarZ_free(_res_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1ok(JNIEnv *env, jclass clz, int8_tArray o) {
+       LDKThirtyTwoBytes o_ref;
+       CHECK((*env)->GetArrayLength(env, o) == 32);
+       (*env)->GetByteArrayRegion(env, o, 0, 32, o_ref.data);
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = CResult_SharedSecretNoneZ_ok(o_ref);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1err(JNIEnv *env, jclass clz) {
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = CResult_SharedSecretNoneZ_err();
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_SharedSecretNoneZ* o_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_SharedSecretNoneZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_SharedSecretNoneZ _res_conv = *(LDKCResult_SharedSecretNoneZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_SharedSecretNoneZ_free(_res_conv);
+}
+
+static inline uint64_t CResult_SharedSecretNoneZ_clone_ptr(LDKCResult_SharedSecretNoneZ *NONNULL_PTR arg) {
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = CResult_SharedSecretNoneZ_clone(arg);
+       return tag_ptr(ret_conv, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKCResult_SharedSecretNoneZ* arg_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(arg);
+       int64_t ret_conv = CResult_SharedSecretNoneZ_clone_ptr(arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_SharedSecretNoneZ* orig_conv = (LDKCResult_SharedSecretNoneZ*)untag_ptr(orig);
+       LDKCResult_SharedSecretNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SharedSecretNoneZ), "LDKCResult_SharedSecretNoneZ");
+       *ret_conv = CResult_SharedSecretNoneZ_clone(orig_conv);
+       return tag_ptr(ret_conv, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SignDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        void* o_ptr = untag_ptr(o);
        CHECK_ACCESS(o_ptr);
@@ -19593,6 +21088,44 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentIdPaymentEr
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKInFlightHtlcs o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       // WARNING: we need a move here but no clone is available for LDKInFlightHtlcs
+       
+       LDKCResult_InFlightHtlcsDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InFlightHtlcsDecodeErrorZ), "LDKCResult_InFlightHtlcsDecodeErrorZ");
+       *ret_conv = CResult_InFlightHtlcsDecodeErrorZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       LDKDecodeError e_conv;
+       e_conv.inner = untag_ptr(e);
+       e_conv.is_owned = ptr_is_owned(e);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(e_conv);
+       e_conv = DecodeError_clone(&e_conv);
+       LDKCResult_InFlightHtlcsDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InFlightHtlcsDecodeErrorZ), "LDKCResult_InFlightHtlcsDecodeErrorZ");
+       *ret_conv = CResult_InFlightHtlcsDecodeErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_InFlightHtlcsDecodeErrorZ* o_conv = (LDKCResult_InFlightHtlcsDecodeErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_InFlightHtlcsDecodeErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_InFlightHtlcsDecodeErrorZ _res_conv = *(LDKCResult_InFlightHtlcsDecodeErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_InFlightHtlcsDecodeErrorZ_free(_res_conv);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SiPrefixParseErrorZ_1ok(JNIEnv *env, jclass clz, jclass o) {
        LDKSiPrefix o_conv = LDKSiPrefix_from_java(env, o);
        LDKCResult_SiPrefixParseErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_SiPrefixParseErrorZ), "LDKCResult_SiPrefixParseErrorZ");
@@ -21053,6 +22586,37 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErro
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1ok(JNIEnv *env, jclass clz) {
+       LDKCResult_NoneSendErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneSendErrorZ), "LDKCResult_NoneSendErrorZ");
+       *ret_conv = CResult_NoneSendErrorZ_ok();
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       void* e_ptr = untag_ptr(e);
+       CHECK_ACCESS(e_ptr);
+       LDKSendError e_conv = *(LDKSendError*)(e_ptr);
+       e_conv = SendError_clone((LDKSendError*)untag_ptr(e));
+       LDKCResult_NoneSendErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneSendErrorZ), "LDKCResult_NoneSendErrorZ");
+       *ret_conv = CResult_NoneSendErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_NoneSendErrorZ* o_conv = (LDKCResult_NoneSendErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_NoneSendErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_NoneSendErrorZ _res_conv = *(LDKCResult_NoneSendErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_NoneSendErrorZ_free(_res_conv);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1u32GraphSyncErrorZ_1ok(JNIEnv *env, jclass clz, int32_t o) {
        LDKCResult_u32GraphSyncErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_u32GraphSyncErrorZ), "LDKCResult_u32GraphSyncErrorZ");
        *ret_conv = CResult_u32GraphSyncErrorZ_ok(o);
@@ -22208,6 +23772,61 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecod
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKOnionMessage o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv = OnionMessage_clone(&o_conv);
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = CResult_OnionMessageDecodeErrorZ_ok(o_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
+       LDKDecodeError e_conv;
+       e_conv.inner = untag_ptr(e);
+       e_conv.is_owned = ptr_is_owned(e);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(e_conv);
+       e_conv = DecodeError_clone(&e_conv);
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = CResult_OnionMessageDecodeErrorZ_err(e_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1is_1ok(JNIEnv *env, jclass clz, int64_t o) {
+       LDKCResult_OnionMessageDecodeErrorZ* o_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(o);
+       jboolean ret_conv = CResult_OnionMessageDecodeErrorZ_is_ok(o_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if (!ptr_is_owned(_res)) return;
+       void* _res_ptr = untag_ptr(_res);
+       CHECK_ACCESS(_res_ptr);
+       LDKCResult_OnionMessageDecodeErrorZ _res_conv = *(LDKCResult_OnionMessageDecodeErrorZ*)(_res_ptr);
+       FREE(untag_ptr(_res));
+       CResult_OnionMessageDecodeErrorZ_free(_res_conv);
+}
+
+static inline uint64_t CResult_OnionMessageDecodeErrorZ_clone_ptr(LDKCResult_OnionMessageDecodeErrorZ *NONNULL_PTR arg) {
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = CResult_OnionMessageDecodeErrorZ_clone(arg);
+       return tag_ptr(ret_conv, true);
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKCResult_OnionMessageDecodeErrorZ* arg_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(arg);
+       int64_t ret_conv = CResult_OnionMessageDecodeErrorZ_clone_ptr(arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_OnionMessageDecodeErrorZ* orig_conv = (LDKCResult_OnionMessageDecodeErrorZ*)untag_ptr(orig);
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = CResult_OnionMessageDecodeErrorZ_clone(orig_conv);
+       return tag_ptr(ret_conv, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PingDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        LDKPing o_conv;
        o_conv.inner = untag_ptr(o);
@@ -23582,7 +25201,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Event_1payment_1path_1succe
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Event_1payment_1path_1failed(JNIEnv *env, jclass clz, int8_tArray payment_id, int8_tArray payment_hash, jboolean rejected_by_dest, int64_t network_update, jboolean all_paths_failed, int64_tArray path, int64_t short_channel_id, int64_t retry) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Event_1payment_1path_1failed(JNIEnv *env, jclass clz, int8_tArray payment_id, int8_tArray payment_hash, jboolean payment_failed_permanently, int64_t network_update, jboolean all_paths_failed, int64_tArray path, int64_t short_channel_id, int64_t retry) {
        LDKThirtyTwoBytes payment_id_ref;
        CHECK((*env)->GetArrayLength(env, payment_id) == 32);
        (*env)->GetByteArrayRegion(env, payment_id, 0, 32, payment_id_ref.data);
@@ -23620,7 +25239,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Event_1payment_1path_1faile
        CHECK_INNER_FIELD_ACCESS_OR_NULL(retry_conv);
        retry_conv = RouteParameters_clone(&retry_conv);
        LDKEvent *ret_copy = MALLOC(sizeof(LDKEvent), "LDKEvent");
-       *ret_copy = Event_payment_path_failed(payment_id_ref, payment_hash_ref, rejected_by_dest, network_update_conv, all_paths_failed, path_constr, short_channel_id_conv, retry_conv);
+       *ret_copy = Event_payment_path_failed(payment_id_ref, payment_hash_ref, payment_failed_permanently, network_update_conv, all_paths_failed, path_constr, short_channel_id_conv, retry_conv);
        int64_t ret_ref = tag_ptr(ret_copy, true);
        return ret_ref;
 }
@@ -24010,7 +25629,10 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1send_1cha
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast_1channel_1announcement(JNIEnv *env, jclass clz, int64_t msg, int64_t update_msg) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1send_1channel_1announcement(JNIEnv *env, jclass clz, int8_tArray node_id, int64_t msg, int64_t update_msg) {
+       LDKPublicKey node_id_ref;
+       CHECK((*env)->GetArrayLength(env, node_id) == 33);
+       (*env)->GetByteArrayRegion(env, node_id, 0, 33, node_id_ref.compressed_form);
        LDKChannelAnnouncement msg_conv;
        msg_conv.inner = untag_ptr(msg);
        msg_conv.is_owned = ptr_is_owned(msg);
@@ -24022,19 +25644,24 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast
        CHECK_INNER_FIELD_ACCESS_OR_NULL(update_msg_conv);
        update_msg_conv = ChannelUpdate_clone(&update_msg_conv);
        LDKMessageSendEvent *ret_copy = MALLOC(sizeof(LDKMessageSendEvent), "LDKMessageSendEvent");
-       *ret_copy = MessageSendEvent_broadcast_channel_announcement(msg_conv, update_msg_conv);
+       *ret_copy = MessageSendEvent_send_channel_announcement(node_id_ref, msg_conv, update_msg_conv);
        int64_t ret_ref = tag_ptr(ret_copy, true);
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast_1node_1announcement(JNIEnv *env, jclass clz, int64_t msg) {
-       LDKNodeAnnouncement msg_conv;
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast_1channel_1announcement(JNIEnv *env, jclass clz, int64_t msg, int64_t update_msg) {
+       LDKChannelAnnouncement msg_conv;
        msg_conv.inner = untag_ptr(msg);
        msg_conv.is_owned = ptr_is_owned(msg);
        CHECK_INNER_FIELD_ACCESS_OR_NULL(msg_conv);
-       msg_conv = NodeAnnouncement_clone(&msg_conv);
+       msg_conv = ChannelAnnouncement_clone(&msg_conv);
+       LDKChannelUpdate update_msg_conv;
+       update_msg_conv.inner = untag_ptr(update_msg);
+       update_msg_conv.is_owned = ptr_is_owned(update_msg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(update_msg_conv);
+       update_msg_conv = ChannelUpdate_clone(&update_msg_conv);
        LDKMessageSendEvent *ret_copy = MALLOC(sizeof(LDKMessageSendEvent), "LDKMessageSendEvent");
-       *ret_copy = MessageSendEvent_broadcast_node_announcement(msg_conv);
+       *ret_copy = MessageSendEvent_broadcast_channel_announcement(msg_conv, update_msg_conv);
        int64_t ret_ref = tag_ptr(ret_copy, true);
        return ret_ref;
 }
@@ -24149,6 +25776,15 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageSendEventsProvider_1fre
        MessageSendEventsProvider_free(this_ptr_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageProvider_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKOnionMessageProvider this_ptr_conv = *(LDKOnionMessageProvider*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       OnionMessageProvider_free(this_ptr_conv);
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_EventsProvider_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
        if (!ptr_is_owned(this_ptr)) return;
        void* this_ptr_ptr = untag_ptr(this_ptr);
@@ -24402,6 +26038,39 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Persister_1free(JNIEnv *env, j
        Persister_free(this_ptr_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_FutureCallback_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKFutureCallback this_ptr_conv = *(LDKFutureCallback*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       FutureCallback_free(this_ptr_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Future_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKFuture this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       Future_free(this_obj_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Future_1register_1callback_1fn(JNIEnv *env, jclass clz, int64_t this_arg, int64_t callback) {
+       LDKFuture this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       void* callback_ptr = untag_ptr(callback);
+       CHECK_ACCESS(callback_ptr);
+       LDKFutureCallback callback_conv = *(LDKFutureCallback*)(callback_ptr);
+       if (callback_conv.free == LDKFutureCallback_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKFutureCallback_JCalls_cloned(&callback_conv);
+       }
+       Future_register_callback_fn(&this_arg_conv, callback_conv);
+}
+
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_Level_1clone(JNIEnv *env, jclass clz, int64_t orig) {
        LDKLevel* orig_conv = (LDKLevel*)untag_ptr(orig);
        jclass ret_conv = LDKLevel_to_java(env, Level_clone(orig_conv));
@@ -24749,8 +26418,27 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1set_1c
        ChannelHandshakeConfig_set_commit_upfront_shutdown_pubkey(&this_ptr_conv, val);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1new(JNIEnv *env, jclass clz, int32_t minimum_depth_arg, int16_t our_to_self_delay_arg, int64_t our_htlc_minimum_msat_arg, int8_t max_inbound_htlc_value_in_flight_percent_of_channel_arg, jboolean negotiate_scid_privacy_arg, jboolean announced_channel_arg, jboolean commit_upfront_shutdown_pubkey_arg) {
-       LDKChannelHandshakeConfig ret_var = ChannelHandshakeConfig_new(minimum_depth_arg, our_to_self_delay_arg, our_htlc_minimum_msat_arg, max_inbound_htlc_value_in_flight_percent_of_channel_arg, negotiate_scid_privacy_arg, announced_channel_arg, commit_upfront_shutdown_pubkey_arg);
+JNIEXPORT int32_t JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1get_1their_1channel_1reserve_1proportional_1millionths(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       LDKChannelHandshakeConfig this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       int32_t ret_conv = ChannelHandshakeConfig_get_their_channel_reserve_proportional_millionths(&this_ptr_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1set_1their_1channel_1reserve_1proportional_1millionths(JNIEnv *env, jclass clz, int64_t this_ptr, int32_t val) {
+       LDKChannelHandshakeConfig this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       ChannelHandshakeConfig_set_their_channel_reserve_proportional_millionths(&this_ptr_conv, val);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1new(JNIEnv *env, jclass clz, int32_t minimum_depth_arg, int16_t our_to_self_delay_arg, int64_t our_htlc_minimum_msat_arg, int8_t max_inbound_htlc_value_in_flight_percent_of_channel_arg, jboolean negotiate_scid_privacy_arg, jboolean announced_channel_arg, jboolean commit_upfront_shutdown_pubkey_arg, int32_t their_channel_reserve_proportional_millionths_arg) {
+       LDKChannelHandshakeConfig ret_var = ChannelHandshakeConfig_new(minimum_depth_arg, our_to_self_delay_arg, our_htlc_minimum_msat_arg, max_inbound_htlc_value_in_flight_percent_of_channel_arg, negotiate_scid_privacy_arg, announced_channel_arg, commit_upfront_shutdown_pubkey_arg, their_channel_reserve_proportional_millionths_arg);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
@@ -26326,9 +28014,23 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1contentious_1claim
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1maybe_1claimable_1htlcawaiting_1timeout(JNIEnv *env, jclass clz, int64_t claimable_amount_satoshis, int32_t claimable_height) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1maybe_1timeout_1claimable_1htlc(JNIEnv *env, jclass clz, int64_t claimable_amount_satoshis, int32_t claimable_height) {
+       LDKBalance *ret_copy = MALLOC(sizeof(LDKBalance), "LDKBalance");
+       *ret_copy = Balance_maybe_timeout_claimable_htlc(claimable_amount_satoshis, claimable_height);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1maybe_1preimage_1claimable_1htlc(JNIEnv *env, jclass clz, int64_t claimable_amount_satoshis, int32_t expiry_height) {
        LDKBalance *ret_copy = MALLOC(sizeof(LDKBalance), "LDKBalance");
-       *ret_copy = Balance_maybe_claimable_htlcawaiting_timeout(claimable_amount_satoshis, claimable_height);
+       *ret_copy = Balance_maybe_preimage_claimable_htlc(claimable_amount_satoshis, expiry_height);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Balance_1counterparty_1revoked_1output_1claimable(JNIEnv *env, jclass clz, int64_t claimable_amount_satoshis) {
+       LDKBalance *ret_copy = MALLOC(sizeof(LDKBalance), "LDKBalance");
+       *ret_copy = Balance_counterparty_revoked_output_claimable(claimable_amount_satoshis);
        int64_t ret_ref = tag_ptr(ret_copy, true);
        return ret_ref;
 }
@@ -29828,36 +31530,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1funding_1tr
        return tag_ptr(ret_conv, true);
 }
 
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1broadcast_1node_1announcement(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray rgb, int8_tArray alias, int64_tArray addresses) {
-       LDKChannelManager this_arg_conv;
-       this_arg_conv.inner = untag_ptr(this_arg);
-       this_arg_conv.is_owned = ptr_is_owned(this_arg);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
-       this_arg_conv.is_owned = false;
-       LDKThreeBytes rgb_ref;
-       CHECK((*env)->GetArrayLength(env, rgb) == 3);
-       (*env)->GetByteArrayRegion(env, rgb, 0, 3, rgb_ref.data);
-       LDKThirtyTwoBytes alias_ref;
-       CHECK((*env)->GetArrayLength(env, alias) == 32);
-       (*env)->GetByteArrayRegion(env, alias, 0, 32, alias_ref.data);
-       LDKCVec_NetAddressZ addresses_constr;
-       addresses_constr.datalen = (*env)->GetArrayLength(env, addresses);
-       if (addresses_constr.datalen > 0)
-               addresses_constr.data = MALLOC(addresses_constr.datalen * sizeof(LDKNetAddress), "LDKCVec_NetAddressZ Elements");
-       else
-               addresses_constr.data = NULL;
-       int64_t* addresses_vals = (*env)->GetLongArrayElements (env, addresses, NULL);
-       for (size_t m = 0; m < addresses_constr.datalen; m++) {
-               int64_t addresses_conv_12 = addresses_vals[m];
-               void* addresses_conv_12_ptr = untag_ptr(addresses_conv_12);
-               CHECK_ACCESS(addresses_conv_12_ptr);
-               LDKNetAddress addresses_conv_12_conv = *(LDKNetAddress*)(addresses_conv_12_ptr);
-               addresses_constr.data[m] = addresses_conv_12_conv;
-       }
-       (*env)->ReleaseLongArrayElements(env, addresses, addresses_vals, 0);
-       ChannelManager_broadcast_node_announcement(&this_arg_conv, rgb_ref, alias_ref, addresses_constr);
-}
-
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1update_1channel_1config(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray counterparty_node_id, jobjectArray channel_ids, int64_t config) {
        LDKChannelManager this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
@@ -30149,6 +31821,19 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1await_1persist
        ChannelManager_await_persistable_update(&this_arg_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1get_1persistable_1update_1future(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKChannelManager this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKFuture ret_var = ChannelManager_get_persistable_update_future(&this_arg_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1current_1best_1block(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKChannelManager this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
@@ -32709,6 +34394,67 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_UpdateAddHTLC_1clone(JNIEnv
        return ret_ref;
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessage_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKOnionMessage this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       OnionMessage_free(this_obj_conv);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_OnionMessage_1get_1blinding_1point(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       LDKOnionMessage this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       int8_tArray ret_arr = (*env)->NewByteArray(env, 33);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 33, OnionMessage_get_blinding_point(&this_ptr_conv).compressed_form);
+       return ret_arr;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessage_1set_1blinding_1point(JNIEnv *env, jclass clz, int64_t this_ptr, int8_tArray val) {
+       LDKOnionMessage this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       LDKPublicKey val_ref;
+       CHECK((*env)->GetArrayLength(env, val) == 33);
+       (*env)->GetByteArrayRegion(env, val, 0, 33, val_ref.compressed_form);
+       OnionMessage_set_blinding_point(&this_ptr_conv, val_ref);
+}
+
+static inline uint64_t OnionMessage_clone_ptr(LDKOnionMessage *NONNULL_PTR arg) {
+       LDKOnionMessage ret_var = OnionMessage_clone(arg);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessage_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKOnionMessage arg_conv;
+       arg_conv.inner = untag_ptr(arg);
+       arg_conv.is_owned = ptr_is_owned(arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(arg_conv);
+       arg_conv.is_owned = false;
+       int64_t ret_conv = OnionMessage_clone_ptr(&arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessage_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKOnionMessage orig_conv;
+       orig_conv.inner = untag_ptr(orig);
+       orig_conv.is_owned = ptr_is_owned(orig);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(orig_conv);
+       orig_conv.is_owned = false;
+       LDKOnionMessage ret_var = OnionMessage_clone(&orig_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_UpdateFulfillHTLC_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKUpdateFulfillHTLC this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -36045,6 +37791,15 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1free(JN
        RoutingMessageHandler_free(this_ptr_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKOnionMessageHandler this_ptr_conv = *(LDKOnionMessageHandler*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       OnionMessageHandler_free(this_ptr_conv);
+}
+
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_AcceptChannel_1write(JNIEnv *env, jclass clz, int64_t obj) {
        LDKAcceptChannel obj_conv;
        obj_conv.inner = untag_ptr(obj);
@@ -36459,6 +38214,29 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_UpdateAddHTLC_1read(JNIEnv
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessage_1read(JNIEnv *env, jclass clz, int8_tArray ser) {
+       LDKu8slice ser_ref;
+       ser_ref.datalen = (*env)->GetArrayLength(env, ser);
+       ser_ref.data = (*env)->GetByteArrayElements (env, ser, NULL);
+       LDKCResult_OnionMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_OnionMessageDecodeErrorZ), "LDKCResult_OnionMessageDecodeErrorZ");
+       *ret_conv = OnionMessage_read(ser_ref);
+       (*env)->ReleaseByteArrayElements(env, ser, (int8_t*)ser_ref.data, 0);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_OnionMessage_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKOnionMessage obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = OnionMessage_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_Ping_1write(JNIEnv *env, jclass clz, int64_t obj) {
        LDKPing obj_conv;
        obj_conv.inner = untag_ptr(obj);
@@ -36861,6 +38639,28 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_
        return tag_ptr(ret_ret, true);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1OnionMessageProvider(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKIgnoringMessageHandler this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKOnionMessageProvider* ret_ret = MALLOC(sizeof(LDKOnionMessageProvider), "LDKOnionMessageProvider");
+       *ret_ret = IgnoringMessageHandler_as_OnionMessageProvider(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1OnionMessageHandler(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKIgnoringMessageHandler this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKOnionMessageHandler* ret_ret = MALLOC(sizeof(LDKOnionMessageHandler), "LDKOnionMessageHandler");
+       *ret_ret = IgnoringMessageHandler_as_OnionMessageHandler(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1CustomMessageReader(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKIgnoringMessageHandler this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
@@ -36983,7 +38783,34 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageHandler_1set_1route_1ha
        MessageHandler_set_route_handler(&this_ptr_conv, val_conv);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageHandler_1new(JNIEnv *env, jclass clz, int64_t chan_handler_arg, int64_t route_handler_arg) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageHandler_1get_1onion_1message_1handler(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       LDKMessageHandler this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       // WARNING: This object doesn't live past this scope, needs clone!
+       int64_t ret_ret = tag_ptr(MessageHandler_get_onion_message_handler(&this_ptr_conv), false);
+       return ret_ret;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageHandler_1set_1onion_1message_1handler(JNIEnv *env, jclass clz, int64_t this_ptr, int64_t val) {
+       LDKMessageHandler this_ptr_conv;
+       this_ptr_conv.inner = untag_ptr(this_ptr);
+       this_ptr_conv.is_owned = ptr_is_owned(this_ptr);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_ptr_conv);
+       this_ptr_conv.is_owned = false;
+       void* val_ptr = untag_ptr(val);
+       CHECK_ACCESS(val_ptr);
+       LDKOnionMessageHandler val_conv = *(LDKOnionMessageHandler*)(val_ptr);
+       if (val_conv.free == LDKOnionMessageHandler_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKOnionMessageHandler_JCalls_cloned(&val_conv);
+       }
+       MessageHandler_set_onion_message_handler(&this_ptr_conv, val_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageHandler_1new(JNIEnv *env, jclass clz, int64_t chan_handler_arg, int64_t route_handler_arg, int64_t onion_message_handler_arg) {
        void* chan_handler_arg_ptr = untag_ptr(chan_handler_arg);
        CHECK_ACCESS(chan_handler_arg_ptr);
        LDKChannelMessageHandler chan_handler_arg_conv = *(LDKChannelMessageHandler*)(chan_handler_arg_ptr);
@@ -36998,7 +38825,14 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageHandler_1new(JNIEnv
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKRoutingMessageHandler_JCalls_cloned(&route_handler_arg_conv);
        }
-       LDKMessageHandler ret_var = MessageHandler_new(chan_handler_arg_conv, route_handler_arg_conv);
+       void* onion_message_handler_arg_ptr = untag_ptr(onion_message_handler_arg);
+       CHECK_ACCESS(onion_message_handler_arg_ptr);
+       LDKOnionMessageHandler onion_message_handler_arg_conv = *(LDKOnionMessageHandler*)(onion_message_handler_arg_ptr);
+       if (onion_message_handler_arg_conv.free == LDKOnionMessageHandler_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKOnionMessageHandler_JCalls_cloned(&onion_message_handler_arg_conv);
+       }
+       LDKMessageHandler ret_var = MessageHandler_new(chan_handler_arg_conv, route_handler_arg_conv, onion_message_handler_arg_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
@@ -37109,7 +38943,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1free(JNIEnv *env,
        PeerManager_free(this_obj_conv);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new(JNIEnv *env, jclass clz, int64_t message_handler, int8_tArray our_node_secret, int8_tArray ephemeral_random_data, int64_t logger, int64_t custom_message_handler) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new(JNIEnv *env, jclass clz, int64_t message_handler, int8_tArray our_node_secret, int64_t current_time, int8_tArray ephemeral_random_data, int64_t logger, int64_t custom_message_handler) {
        LDKMessageHandler message_handler_conv;
        message_handler_conv.inner = untag_ptr(message_handler);
        message_handler_conv.is_owned = ptr_is_owned(message_handler);
@@ -37137,7 +38971,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new(JNIEnv *en
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKCustomMessageHandler_JCalls_cloned(&custom_message_handler_conv);
        }
-       LDKPeerManager ret_var = PeerManager_new(message_handler_conv, our_node_secret_ref, ephemeral_random_data_ref, logger_conv, custom_message_handler_conv);
+       LDKPeerManager ret_var = PeerManager_new(message_handler_conv, our_node_secret_ref, current_time, ephemeral_random_data_ref, logger_conv, custom_message_handler_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
@@ -37292,6 +39126,36 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1timer_1tick_1occu
        PeerManager_timer_tick_occurred(&this_arg_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1broadcast_1node_1announcement(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray rgb, int8_tArray alias, int64_tArray addresses) {
+       LDKPeerManager this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKThreeBytes rgb_ref;
+       CHECK((*env)->GetArrayLength(env, rgb) == 3);
+       (*env)->GetByteArrayRegion(env, rgb, 0, 3, rgb_ref.data);
+       LDKThirtyTwoBytes alias_ref;
+       CHECK((*env)->GetArrayLength(env, alias) == 32);
+       (*env)->GetByteArrayRegion(env, alias, 0, 32, alias_ref.data);
+       LDKCVec_NetAddressZ addresses_constr;
+       addresses_constr.datalen = (*env)->GetArrayLength(env, addresses);
+       if (addresses_constr.datalen > 0)
+               addresses_constr.data = MALLOC(addresses_constr.datalen * sizeof(LDKNetAddress), "LDKCVec_NetAddressZ Elements");
+       else
+               addresses_constr.data = NULL;
+       int64_t* addresses_vals = (*env)->GetLongArrayElements (env, addresses, NULL);
+       for (size_t m = 0; m < addresses_constr.datalen; m++) {
+               int64_t addresses_conv_12 = addresses_vals[m];
+               void* addresses_conv_12_ptr = untag_ptr(addresses_conv_12);
+               CHECK_ACCESS(addresses_conv_12_ptr);
+               LDKNetAddress addresses_conv_12_conv = *(LDKNetAddress*)(addresses_conv_12_ptr);
+               addresses_constr.data[m] = addresses_conv_12_conv;
+       }
+       (*env)->ReleaseLongArrayElements(env, addresses, addresses_vals, 0);
+       PeerManager_broadcast_node_announcement(&this_arg_conv, rgb_ref, alias_ref, addresses_constr);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_htlc_1success_1tx_1weight(JNIEnv *env, jclass clz, jboolean opt_anchors) {
        int64_t ret_conv = htlc_success_tx_weight(opt_anchors);
        return ret_conv;
@@ -39654,6 +41518,22 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelTypeFeatures_1free(JNIE
        ChannelTypeFeatures_free(this_obj_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InitFeatures_1known_1channel_1features(JNIEnv *env, jclass clz) {
+       LDKInitFeatures ret_var = InitFeatures_known_channel_features();
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1known_1channel_1features(JNIEnv *env, jclass clz) {
+       LDKNodeFeatures ret_var = NodeFeatures_known_channel_features();
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InitFeatures_1empty(JNIEnv *env, jclass clz) {
        LDKInitFeatures ret_var = InitFeatures_empty();
        int64_t ret_ref = 0;
@@ -40763,6 +42643,82 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1requires_1sh
        return ret_conv;
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InitFeatures_1set_1onion_1messages_1optional(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKInitFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       InitFeatures_set_onion_messages_optional(&this_arg_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InitFeatures_1set_1onion_1messages_1required(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKInitFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       InitFeatures_set_onion_messages_required(&this_arg_conv);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InitFeatures_1supports_1onion_1messages(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKInitFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       jboolean ret_conv = InitFeatures_supports_onion_messages(&this_arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1onion_1messages_1optional(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKNodeFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       NodeFeatures_set_onion_messages_optional(&this_arg_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1onion_1messages_1required(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKNodeFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       NodeFeatures_set_onion_messages_required(&this_arg_conv);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1supports_1onion_1messages(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKNodeFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       jboolean ret_conv = NodeFeatures_supports_onion_messages(&this_arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InitFeatures_1requires_1onion_1messages(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKInitFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       jboolean ret_conv = InitFeatures_requires_onion_messages(&this_arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1requires_1onion_1messages(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKNodeFeatures this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       jboolean ret_conv = NodeFeatures_requires_onion_messages(&this_arg_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InitFeatures_1set_1channel_1type_1optional(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKInitFeatures this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
@@ -44834,6 +46790,15 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LockableScore_1free(JNIEnv *en
        LockableScore_free(this_ptr_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_WriteableScore_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKWriteableScore this_ptr_conv = *(LDKWriteableScore*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       WriteableScore_free(this_ptr_conv);
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKMultiThreadedLockableScore this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -44842,6 +46807,49 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1fr
        MultiThreadedLockableScore_free(this_obj_conv);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MultiThreadedScoreLock_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKMultiThreadedScoreLock this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       MultiThreadedScoreLock_free(this_obj_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MultiThreadedScoreLock_1as_1Score(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKMultiThreadedScoreLock this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKScore* ret_ret = MALLOC(sizeof(LDKScore), "LDKScore");
+       *ret_ret = MultiThreadedScoreLock_as_Score(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_MultiThreadedScoreLock_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKMultiThreadedScoreLock obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = MultiThreadedScoreLock_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1as_1LockableScore(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKMultiThreadedLockableScore this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKLockableScore* ret_ret = MALLOC(sizeof(LDKLockableScore), "LDKLockableScore");
+       *ret_ret = MultiThreadedLockableScore_as_LockableScore(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1write(JNIEnv *env, jclass clz, int64_t obj) {
        LDKMultiThreadedLockableScore obj_conv;
        obj_conv.inner = untag_ptr(obj);
@@ -44855,6 +46863,17 @@ JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableSc
        return ret_arr;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1as_1WriteableScore(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKMultiThreadedLockableScore this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKWriteableScore* ret_ret = MALLOC(sizeof(LDKWriteableScore), "LDKWriteableScore");
+       *ret_ret = MultiThreadedLockableScore_as_WriteableScore(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1new(JNIEnv *env, jclass clz, int64_t score) {
        void* score_ptr = untag_ptr(score);
        CHECK_ACCESS(score_ptr);
@@ -45443,6 +47462,272 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ProbabilisticScorer_1read(J
        return tag_ptr(ret_conv, true);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKBlindedRoute this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       BlindedRoute_free(this_obj_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BlindedHop_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKBlindedHop this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       BlindedHop_free(this_obj_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1new(JNIEnv *env, jclass clz, jobjectArray node_pks, int64_t keys_manager) {
+       LDKCVec_PublicKeyZ node_pks_constr;
+       node_pks_constr.datalen = (*env)->GetArrayLength(env, node_pks);
+       if (node_pks_constr.datalen > 0)
+               node_pks_constr.data = MALLOC(node_pks_constr.datalen * sizeof(LDKPublicKey), "LDKCVec_PublicKeyZ Elements");
+       else
+               node_pks_constr.data = NULL;
+       for (size_t i = 0; i < node_pks_constr.datalen; i++) {
+               int8_tArray node_pks_conv_8 = (*env)->GetObjectArrayElement(env, node_pks, i);
+               LDKPublicKey node_pks_conv_8_ref;
+               CHECK((*env)->GetArrayLength(env, node_pks_conv_8) == 33);
+               (*env)->GetByteArrayRegion(env, node_pks_conv_8, 0, 33, node_pks_conv_8_ref.compressed_form);
+               node_pks_constr.data[i] = node_pks_conv_8_ref;
+       }
+       void* keys_manager_ptr = untag_ptr(keys_manager);
+       if (ptr_is_owned(keys_manager)) { CHECK_ACCESS(keys_manager_ptr); }
+       LDKKeysInterface* keys_manager_conv = (LDKKeysInterface*)keys_manager_ptr;
+       LDKCResult_BlindedRouteNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteNoneZ), "LDKCResult_BlindedRouteNoneZ");
+       *ret_conv = BlindedRoute_new(node_pks_constr, keys_manager_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKBlindedRoute obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = BlindedRoute_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1read(JNIEnv *env, jclass clz, int8_tArray ser) {
+       LDKu8slice ser_ref;
+       ser_ref.datalen = (*env)->GetArrayLength(env, ser);
+       ser_ref.data = (*env)->GetByteArrayElements (env, ser, NULL);
+       LDKCResult_BlindedRouteDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedRouteDecodeErrorZ), "LDKCResult_BlindedRouteDecodeErrorZ");
+       *ret_conv = BlindedRoute_read(ser_ref);
+       (*env)->ReleaseByteArrayElements(env, ser, (int8_t*)ser_ref.data, 0);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_BlindedHop_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKBlindedHop obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = BlindedHop_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BlindedHop_1read(JNIEnv *env, jclass clz, int8_tArray ser) {
+       LDKu8slice ser_ref;
+       ser_ref.datalen = (*env)->GetArrayLength(env, ser);
+       ser_ref.data = (*env)->GetByteArrayElements (env, ser, NULL);
+       LDKCResult_BlindedHopDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_BlindedHopDecodeErrorZ), "LDKCResult_BlindedHopDecodeErrorZ");
+       *ret_conv = BlindedHop_read(ser_ref);
+       (*env)->ReleaseByteArrayElements(env, ser, (int8_t*)ser_ref.data, 0);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKOnionMessenger this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       OnionMessenger_free(this_obj_conv);
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Destination_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKDestination this_ptr_conv = *(LDKDestination*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       Destination_free(this_ptr_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Destination_1node(JNIEnv *env, jclass clz, int8_tArray a) {
+       LDKPublicKey a_ref;
+       CHECK((*env)->GetArrayLength(env, a) == 33);
+       (*env)->GetByteArrayRegion(env, a, 0, 33, a_ref.compressed_form);
+       LDKDestination *ret_copy = MALLOC(sizeof(LDKDestination), "LDKDestination");
+       *ret_copy = Destination_node(a_ref);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Destination_1blinded_1route(JNIEnv *env, jclass clz, int64_t a) {
+       LDKBlindedRoute a_conv;
+       a_conv.inner = untag_ptr(a);
+       a_conv.is_owned = ptr_is_owned(a);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(a_conv);
+       // WARNING: we need a move here but no clone is available for LDKBlindedRoute
+       
+       LDKDestination *ret_copy = MALLOC(sizeof(LDKDestination), "LDKDestination");
+       *ret_copy = Destination_blinded_route(a_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_SendError_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
+       if (!ptr_is_owned(this_ptr)) return;
+       void* this_ptr_ptr = untag_ptr(this_ptr);
+       CHECK_ACCESS(this_ptr_ptr);
+       LDKSendError this_ptr_conv = *(LDKSendError*)(this_ptr_ptr);
+       FREE(untag_ptr(this_ptr));
+       SendError_free(this_ptr_conv);
+}
+
+static inline uint64_t SendError_clone_ptr(LDKSendError *NONNULL_PTR arg) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_clone(arg);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1clone_1ptr(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKSendError* arg_conv = (LDKSendError*)untag_ptr(arg);
+       int64_t ret_conv = SendError_clone_ptr(arg_conv);
+       return ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKSendError* orig_conv = (LDKSendError*)untag_ptr(orig);
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_clone(orig_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1secp256k1(JNIEnv *env, jclass clz, jclass a) {
+       LDKSecp256k1Error a_conv = LDKSecp256k1Error_from_java(env, a);
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_secp256k1(a_conv);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1too_1big_1packet(JNIEnv *env, jclass clz) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_too_big_packet();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1too_1few_1blinded_1hops(JNIEnv *env, jclass clz) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_too_few_blinded_hops();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1invalid_1first_1hop(JNIEnv *env, jclass clz) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_invalid_first_hop();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SendError_1buffer_1full(JNIEnv *env, jclass clz) {
+       LDKSendError *ret_copy = MALLOC(sizeof(LDKSendError), "LDKSendError");
+       *ret_copy = SendError_buffer_full();
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1new(JNIEnv *env, jclass clz, int64_t keys_manager, int64_t logger) {
+       void* keys_manager_ptr = untag_ptr(keys_manager);
+       CHECK_ACCESS(keys_manager_ptr);
+       LDKKeysInterface keys_manager_conv = *(LDKKeysInterface*)(keys_manager_ptr);
+       if (keys_manager_conv.free == LDKKeysInterface_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKKeysInterface_JCalls_cloned(&keys_manager_conv);
+       }
+       void* logger_ptr = untag_ptr(logger);
+       CHECK_ACCESS(logger_ptr);
+       LDKLogger logger_conv = *(LDKLogger*)(logger_ptr);
+       if (logger_conv.free == LDKLogger_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKLogger_JCalls_cloned(&logger_conv);
+       }
+       LDKOnionMessenger ret_var = OnionMessenger_new(keys_manager_conv, logger_conv);
+       int64_t ret_ref = 0;
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
+       ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
+       return ret_ref;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1send_1onion_1message(JNIEnv *env, jclass clz, int64_t this_arg, jobjectArray intermediate_nodes, int64_t destination, int64_t reply_path) {
+       LDKOnionMessenger this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKCVec_PublicKeyZ intermediate_nodes_constr;
+       intermediate_nodes_constr.datalen = (*env)->GetArrayLength(env, intermediate_nodes);
+       if (intermediate_nodes_constr.datalen > 0)
+               intermediate_nodes_constr.data = MALLOC(intermediate_nodes_constr.datalen * sizeof(LDKPublicKey), "LDKCVec_PublicKeyZ Elements");
+       else
+               intermediate_nodes_constr.data = NULL;
+       for (size_t i = 0; i < intermediate_nodes_constr.datalen; i++) {
+               int8_tArray intermediate_nodes_conv_8 = (*env)->GetObjectArrayElement(env, intermediate_nodes, i);
+               LDKPublicKey intermediate_nodes_conv_8_ref;
+               CHECK((*env)->GetArrayLength(env, intermediate_nodes_conv_8) == 33);
+               (*env)->GetByteArrayRegion(env, intermediate_nodes_conv_8, 0, 33, intermediate_nodes_conv_8_ref.compressed_form);
+               intermediate_nodes_constr.data[i] = intermediate_nodes_conv_8_ref;
+       }
+       void* destination_ptr = untag_ptr(destination);
+       CHECK_ACCESS(destination_ptr);
+       LDKDestination destination_conv = *(LDKDestination*)(destination_ptr);
+       // WARNING: we may need a move here but no clone is available for LDKDestination
+       LDKBlindedRoute reply_path_conv;
+       reply_path_conv.inner = untag_ptr(reply_path);
+       reply_path_conv.is_owned = ptr_is_owned(reply_path);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(reply_path_conv);
+       reply_path_conv.is_owned = false;
+       LDKCResult_NoneSendErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneSendErrorZ), "LDKCResult_NoneSendErrorZ");
+       *ret_conv = OnionMessenger_send_onion_message(&this_arg_conv, intermediate_nodes_constr, destination_conv, reply_path_conv);
+       return tag_ptr(ret_conv, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1as_1OnionMessageHandler(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKOnionMessenger this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKOnionMessageHandler* ret_ret = MALLOC(sizeof(LDKOnionMessageHandler), "LDKOnionMessageHandler");
+       *ret_ret = OnionMessenger_as_OnionMessageHandler(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1as_1OnionMessageProvider(JNIEnv *env, jclass clz, int64_t this_arg) {
+       LDKOnionMessenger this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKOnionMessageProvider* ret_ret = MALLOC(sizeof(LDKOnionMessageProvider), "LDKOnionMessageProvider");
+       *ret_ret = OnionMessenger_as_OnionMessageProvider(&this_arg_conv);
+       return tag_ptr(ret_ret, true);
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_FilesystemPersister_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKFilesystemPersister this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -45579,11 +47864,17 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_BackgroundProcessor_1start(
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_cloned(&logger_conv);
        }
-       LDKMultiThreadedLockableScore scorer_conv;
-       scorer_conv.inner = untag_ptr(scorer);
-       scorer_conv.is_owned = ptr_is_owned(scorer);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(scorer_conv);
-       scorer_conv.is_owned = false;
+       void* scorer_ptr = untag_ptr(scorer);
+       CHECK_ACCESS(scorer_ptr);
+       LDKCOption_WriteableScoreZ scorer_conv = *(LDKCOption_WriteableScoreZ*)(scorer_ptr);
+       // WARNING: we may need a move here but no clone is available for LDKCOption_WriteableScoreZ
+       if (scorer_conv.tag == LDKCOption_WriteableScoreZ_Some) {
+               // Manually implement clone for Java trait instances
+               if (scorer_conv.some.free == LDKWriteableScore_JCalls_free) {
+                       // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+                       LDKWriteableScore_JCalls_cloned(&scorer_conv.some);
+               }
+       }
        LDKBackgroundProcessor ret_var = BackgroundProcessor_start(persister_conv, event_handler_conv, &chain_monitor_conv, &channel_manager_conv, gossip_sync_conv, &peer_manager_conv, logger_conv, scorer_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
@@ -45879,6 +48170,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Invoice_1clone(JNIEnv *env,
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Invoice_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKInvoice o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = Invoice_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKSignedRawInvoice this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -45932,6 +48233,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1clone(JNI
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKSignedRawInvoice o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = SignedRawInvoice_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RawInvoice_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKRawInvoice this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -46012,6 +48323,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RawInvoice_1clone(JNIEnv *e
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RawInvoice_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKRawInvoice o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = RawInvoice_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RawDataPart_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKRawDataPart this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -46092,6 +48413,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RawDataPart_1clone(JNIEnv *
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RawDataPart_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKRawDataPart o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = RawDataPart_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PositiveTimestamp_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
        LDKPositiveTimestamp this_obj_conv;
        this_obj_conv.inner = untag_ptr(this_obj);
@@ -46145,6 +48476,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PositiveTimestamp_1clone(JN
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PositiveTimestamp_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKPositiveTimestamp o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = PositiveTimestamp_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_SiPrefix_1clone(JNIEnv *env, jclass clz, int64_t orig) {
        LDKSiPrefix* orig_conv = (LDKSiPrefix*)untag_ptr(orig);
        jclass ret_conv = LDKSiPrefix_to_java(env, SiPrefix_clone(orig_conv));
@@ -46178,6 +48519,12 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_SiPrefix_1eq(JNIEnv *env,
        return ret_conv;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SiPrefix_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKSiPrefix* o_conv = (LDKSiPrefix*)untag_ptr(o);
+       int64_t ret_conv = SiPrefix_hash(o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SiPrefix_1multiplier(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKSiPrefix* this_arg_conv = (LDKSiPrefix*)untag_ptr(this_arg);
        int64_t ret_conv = SiPrefix_multiplier(this_arg_conv);
@@ -46716,6 +49063,16 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoiceSignature_1clone(JNI
        return ret_ref;
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoiceSignature_1hash(JNIEnv *env, jclass clz, int64_t o) {
+       LDKInvoiceSignature o_conv;
+       o_conv.inner = untag_ptr(o);
+       o_conv.is_owned = ptr_is_owned(o);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(o_conv);
+       o_conv.is_owned = false;
+       int64_t ret_conv = InvoiceSignature_hash(&o_conv);
+       return ret_conv;
+}
+
 JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InvoiceSignature_1eq(JNIEnv *env, jclass clz, int64_t a, int64_t b) {
        LDKInvoiceSignature a_conv;
        a_conv.inner = untag_ptr(a);
@@ -46818,14 +49175,14 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1raw_1invo
        return ret_ref;
 }
 
-JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1hash(JNIEnv *env, jclass clz, int64_t this_arg) {
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1signable_1hash(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKSignedRawInvoice this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
        this_arg_conv.is_owned = ptr_is_owned(this_arg);
        CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
        this_arg_conv.is_owned = false;
        int8_tArray ret_arr = (*env)->NewByteArray(env, 32);
-       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, *SignedRawInvoice_hash(&this_arg_conv));
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, *SignedRawInvoice_signable_hash(&this_arg_conv));
        return ret_arr;
 }
 
@@ -46863,14 +49220,14 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1check_1s
        return ret_conv;
 }
 
-JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_RawInvoice_1hash(JNIEnv *env, jclass clz, int64_t this_arg) {
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_RawInvoice_1signable_1hash(JNIEnv *env, jclass clz, int64_t this_arg) {
        LDKRawInvoice this_arg_conv;
        this_arg_conv.inner = untag_ptr(this_arg);
        this_arg_conv.is_owned = ptr_is_owned(this_arg);
        CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
        this_arg_conv.is_owned = false;
        int8_tArray ret_arr = (*env)->NewByteArray(env, 32);
-       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, RawInvoice_hash(&this_arg_conv).data);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, 32, RawInvoice_signable_hash(&this_arg_conv).data);
        return ret_arr;
 }
 
@@ -47683,7 +50040,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PaymentError_1sending(JNIEn
        return ret_ref;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1new(JNIEnv *env, jclass clz, int64_t payer, int64_t router, int64_t scorer, int64_t logger, int64_t event_handler, int64_t retry) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1new(JNIEnv *env, jclass clz, int64_t payer, int64_t router, int64_t logger, int64_t event_handler, int64_t retry) {
        void* payer_ptr = untag_ptr(payer);
        CHECK_ACCESS(payer_ptr);
        LDKPayer payer_conv = *(LDKPayer*)(payer_ptr);
@@ -47698,11 +50055,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1new(JNIEnv *e
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKRouter_JCalls_cloned(&router_conv);
        }
-       LDKMultiThreadedLockableScore scorer_conv;
-       scorer_conv.inner = untag_ptr(scorer);
-       scorer_conv.is_owned = ptr_is_owned(scorer);
-       CHECK_INNER_FIELD_ACCESS_OR_NULL(scorer_conv);
-       scorer_conv.is_owned = false;
        void* logger_ptr = untag_ptr(logger);
        CHECK_ACCESS(logger_ptr);
        LDKLogger logger_conv = *(LDKLogger*)(logger_ptr);
@@ -47721,7 +50073,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1new(JNIEnv *e
        CHECK_ACCESS(retry_ptr);
        LDKRetry retry_conv = *(LDKRetry*)(retry_ptr);
        retry_conv = Retry_clone((LDKRetry*)untag_ptr(retry));
-       LDKInvoicePayer ret_var = InvoicePayer_new(payer_conv, router_conv, &scorer_conv, logger_conv, event_handler_conv, retry_conv);
+       LDKInvoicePayer ret_var = InvoicePayer_new(payer_conv, router_conv, logger_conv, event_handler_conv, retry_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
@@ -47801,6 +50153,59 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1as_1EventHand
        return tag_ptr(ret_ret, true);
 }
 
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1free(JNIEnv *env, jclass clz, int64_t this_obj) {
+       LDKInFlightHtlcs this_obj_conv;
+       this_obj_conv.inner = untag_ptr(this_obj);
+       this_obj_conv.is_owned = ptr_is_owned(this_obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_obj_conv);
+       InFlightHtlcs_free(this_obj_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1used_1liquidity_1msat(JNIEnv *env, jclass clz, int64_t this_arg, int64_t source, int64_t target, int64_t channel_scid) {
+       LDKInFlightHtlcs this_arg_conv;
+       this_arg_conv.inner = untag_ptr(this_arg);
+       this_arg_conv.is_owned = ptr_is_owned(this_arg);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(this_arg_conv);
+       this_arg_conv.is_owned = false;
+       LDKNodeId source_conv;
+       source_conv.inner = untag_ptr(source);
+       source_conv.is_owned = ptr_is_owned(source);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(source_conv);
+       source_conv.is_owned = false;
+       LDKNodeId target_conv;
+       target_conv.inner = untag_ptr(target);
+       target_conv.is_owned = ptr_is_owned(target);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(target_conv);
+       target_conv.is_owned = false;
+       LDKCOption_u64Z *ret_copy = MALLOC(sizeof(LDKCOption_u64Z), "LDKCOption_u64Z");
+       *ret_copy = InFlightHtlcs_used_liquidity_msat(&this_arg_conv, &source_conv, &target_conv, channel_scid);
+       int64_t ret_ref = tag_ptr(ret_copy, true);
+       return ret_ref;
+}
+
+JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1write(JNIEnv *env, jclass clz, int64_t obj) {
+       LDKInFlightHtlcs obj_conv;
+       obj_conv.inner = untag_ptr(obj);
+       obj_conv.is_owned = ptr_is_owned(obj);
+       CHECK_INNER_FIELD_ACCESS_OR_NULL(obj_conv);
+       obj_conv.is_owned = false;
+       LDKCVec_u8Z ret_var = InFlightHtlcs_write(&obj_conv);
+       int8_tArray ret_arr = (*env)->NewByteArray(env, ret_var.datalen);
+       (*env)->SetByteArrayRegion(env, ret_arr, 0, ret_var.datalen, ret_var.data);
+       CVec_u8Z_free(ret_var);
+       return ret_arr;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1read(JNIEnv *env, jclass clz, int8_tArray ser) {
+       LDKu8slice ser_ref;
+       ser_ref.datalen = (*env)->GetArrayLength(env, ser);
+       ser_ref.data = (*env)->GetByteArrayElements (env, ser, NULL);
+       LDKCResult_InFlightHtlcsDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InFlightHtlcsDecodeErrorZ), "LDKCResult_InFlightHtlcsDecodeErrorZ");
+       *ret_conv = InFlightHtlcs_read(ser_ref);
+       (*env)->ReleaseByteArrayElements(env, ser, (int8_t*)ser_ref.data, 0);
+       return tag_ptr(ret_conv, true);
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_create_1phantom_1invoice(JNIEnv *env, jclass clz, int64_t amt_msat, int8_tArray payment_hash, jstring description, int32_t invoice_expiry_delta_secs, int64_tArray phantom_route_hints, int64_t keys_manager, jclass network) {
        void* amt_msat_ptr = untag_ptr(amt_msat);
        CHECK_ACCESS(amt_msat_ptr);
@@ -47995,7 +50400,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1free(JNIEnv *en
        DefaultRouter_free(this_obj_conv);
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1new(JNIEnv *env, jclass clz, int64_t network_graph, int64_t logger, int8_tArray random_seed_bytes) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1new(JNIEnv *env, jclass clz, int64_t network_graph, int64_t logger, int8_tArray random_seed_bytes, int64_t scorer) {
        LDKNetworkGraph network_graph_conv;
        network_graph_conv.inner = untag_ptr(network_graph);
        network_graph_conv.is_owned = ptr_is_owned(network_graph);
@@ -48011,7 +50416,14 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1new(JNIEnv *
        LDKThirtyTwoBytes random_seed_bytes_ref;
        CHECK((*env)->GetArrayLength(env, random_seed_bytes) == 32);
        (*env)->GetByteArrayRegion(env, random_seed_bytes, 0, 32, random_seed_bytes_ref.data);
-       LDKDefaultRouter ret_var = DefaultRouter_new(&network_graph_conv, logger_conv, random_seed_bytes_ref);
+       void* scorer_ptr = untag_ptr(scorer);
+       CHECK_ACCESS(scorer_ptr);
+       LDKLockableScore scorer_conv = *(LDKLockableScore*)(scorer_ptr);
+       if (scorer_conv.free == LDKLockableScore_JCalls_free) {
+               // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
+               LDKLockableScore_JCalls_cloned(&scorer_conv);
+       }
+       LDKDefaultRouter ret_var = DefaultRouter_new(&network_graph_conv, logger_conv, random_seed_bytes_ref, scorer_conv);
        int64_t ret_ref = 0;
        CHECK_INNER_FIELD_ACCESS_OR_NULL(ret_var);
        ret_ref = tag_ptr(ret_var.inner, ret_var.is_owned);
index 4133a2361b949d58d16fa5119bcfade66d0e4f3a..9c415656050cc30a11ea274bd3382918ee619c18 100644 (file)
@@ -135,6 +135,22 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_vec_1slice_1len
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_new_1empty_1slice_1vec
   (JNIEnv *, jclass);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BigEndianScalar_get_bytes
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_BigEndianScalar_1get_1bytes
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BigEndianScalar_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BigEndianScalar_1free
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKBech32Error_ref_from_ptr
@@ -159,6 +175,54 @@ JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_TxOut_1get_1script_1pubk
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_TxOut_1get_1value
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteNoneZ_get_ok
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1get_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteNoneZ_get_err
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1get_1err
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteDecodeErrorZ_get_ok
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1get_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteDecodeErrorZ_get_err
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1get_1err
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedHopDecodeErrorZ_get_ok
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1get_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedHopDecodeErrorZ_get_err
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1get_1err
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_NoneNoneZ_get_ok
@@ -455,6 +519,110 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1ShutdownScriptInvali
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1ShutdownScriptInvalidShutdownScriptZ_1get_1err
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKScore_new
+ * Signature: (Lorg/ldk/impl/bindings/LDKScore;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKScore_1new
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Score_channel_penalty_msat
+ * Signature: (JJJJJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Score_1channel_1penalty_1msat
+  (JNIEnv *, jclass, jlong, jlong, jlong, jlong, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Score_payment_path_failed
+ * Signature: (J[JJ)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1failed
+  (JNIEnv *, jclass, jlong, jlongArray, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Score_payment_path_successful
+ * Signature: (J[J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1successful
+  (JNIEnv *, jclass, jlong, jlongArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Score_probe_failed
+ * Signature: (J[JJ)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1failed
+  (JNIEnv *, jclass, jlong, jlongArray, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Score_probe_successful
+ * Signature: (J[J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1successful
+  (JNIEnv *, jclass, jlong, jlongArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Score_write
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_Score_1write
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKLockableScore_new
+ * Signature: (Lorg/ldk/impl/bindings/LDKLockableScore;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKLockableScore_1new
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LockableScore_lock
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LockableScore_1lock
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKWriteableScore_new
+ * Signature: (Lorg/ldk/impl/bindings/LDKWriteableScore;Lorg/ldk/impl/bindings/LDKLockableScore;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKWriteableScore_1new
+  (JNIEnv *, jclass, jobject, jobject);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKWriteableScore_get_LockableScore
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKWriteableScore_1get_1LockableScore
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    WriteableScore_write
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_WriteableScore_1write
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKCOption_WriteableScoreZ_ref_from_ptr
+ * Signature: (J)Lorg/ldk/impl/bindings/LDKCOption_WriteableScoreZ;
+ */
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1WriteableScoreZ_1ref_1from_1ptr
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_NoneErrorZ_get_ok
@@ -831,14 +999,6 @@ JNIEXPORT jlongArray JNICALL Java_org_ldk_impl_bindings_C3Tuple_1OutPointCVec_1M
 JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_C3Tuple_1OutPointCVec_1MonitorEventZPublicKeyZ_1get_1c
   (JNIEnv *, jclass, jlong);
 
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    LDKCOption_C2Tuple_usizeTransactionZZ_ref_from_ptr
- * Signature: (J)Lorg/ldk/impl/bindings/LDKCOption_C2Tuple_usizeTransactionZZ;
- */
-JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1C2Tuple_1usizeTransactionZZ_1ref_1from_1ptr
-  (JNIEnv *, jclass, jlong);
-
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_FixedPenaltyScorerDecodeErrorZ_get_ok
@@ -1079,6 +1239,14 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_C3Tuple_1ChannelAnnouncementC
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZ_1get_1c
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_ref_from_ptr
+ * Signature: (J)Lorg/ldk/impl/bindings/LDKCOption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ;
+ */
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1ref_1from_1ptr
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_NoneLightningErrorZ_get_ok
@@ -1367,6 +1535,30 @@ JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeyNoneZ_
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeyNoneZ_1get_1err
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKCOption_ScalarZ_ref_from_ptr
+ * Signature: (J)Lorg/ldk/impl/bindings/LDKCOption_ScalarZ;
+ */
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKCOption_1ScalarZ_1ref_1from_1ptr
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_SharedSecretNoneZ_get_ok
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1get_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_SharedSecretNoneZ_get_err
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1get_1err
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKBaseSign_new
@@ -1967,6 +2159,14 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKKeysInterface_1new
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_KeysInterface_1get_1node_1secret
   (JNIEnv *, jclass, jlong, jobject);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    KeysInterface_ecdh
+ * Signature: (JLorg/ldk/enums/Recipient;[BJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_KeysInterface_1ecdh
+  (JNIEnv *, jclass, jlong, jobject, jbyteArray, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    KeysInterface_get_destination_script
@@ -2183,6 +2383,22 @@ JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentIdPaymen
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentIdPaymentErrorZ_1get_1err
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_InFlightHtlcsDecodeErrorZ_get_ok
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1get_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_InFlightHtlcsDecodeErrorZ_get_err
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1get_1err
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKParseError_ref_from_ptr
@@ -2615,6 +2831,30 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErr
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErrorZ_1get_1err
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKSendError_ref_from_ptr
+ * Signature: (J)Lorg/ldk/impl/bindings/LDKSendError;
+ */
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKSendError_1ref_1from_1ptr
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_NoneSendErrorZ_get_ok
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1get_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_NoneSendErrorZ_get_err
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1get_1err
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKGraphSyncError_ref_from_ptr
@@ -2943,6 +3183,22 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeE
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1get_1err
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_OnionMessageDecodeErrorZ_get_ok
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1get_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_OnionMessageDecodeErrorZ_get_err
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1get_1err
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_PingDecodeErrorZ_get_ok
@@ -3226,9 +3482,9 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Filter_1register_1tx
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    Filter_register_output
- * Signature: (JJ)J
+ * Signature: (JJ)V
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Filter_1register_1output
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Filter_1register_1output
   (JNIEnv *, jclass, jlong, jlong);
 
 /*
@@ -3271,6 +3527,22 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKMessageSendEventsProvider_
 JNIEXPORT jlongArray JNICALL Java_org_ldk_impl_bindings_MessageSendEventsProvider_1get_1and_1clear_1pending_1msg_1events
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKOnionMessageProvider_new
+ * Signature: (Lorg/ldk/impl/bindings/LDKOnionMessageProvider;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKOnionMessageProvider_1new
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessageProvider_next_onion_message_for_peer
+ * Signature: (J[B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessageProvider_1next_1onion_1message_1for_1peer
+  (JNIEnv *, jclass, jlong, jbyteArray);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKEventHandler_new
@@ -3303,62 +3575,6 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKEventsProvider_1new
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_EventsProvider_1process_1pending_1events
   (JNIEnv *, jclass, jlong, jlong);
 
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    LDKScore_new
- * Signature: (Lorg/ldk/impl/bindings/LDKScore;)J
- */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKScore_1new
-  (JNIEnv *, jclass, jobject);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    Score_channel_penalty_msat
- * Signature: (JJJJJ)J
- */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Score_1channel_1penalty_1msat
-  (JNIEnv *, jclass, jlong, jlong, jlong, jlong, jlong);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    Score_payment_path_failed
- * Signature: (J[JJ)V
- */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1failed
-  (JNIEnv *, jclass, jlong, jlongArray, jlong);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    Score_payment_path_successful
- * Signature: (J[J)V
- */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1payment_1path_1successful
-  (JNIEnv *, jclass, jlong, jlongArray);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    Score_probe_failed
- * Signature: (J[JJ)V
- */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1failed
-  (JNIEnv *, jclass, jlong, jlongArray, jlong);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    Score_probe_successful
- * Signature: (J[J)V
- */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1probe_1successful
-  (JNIEnv *, jclass, jlong, jlongArray);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    Score_write
- * Signature: (J)[B
- */
-JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_Score_1write
-  (JNIEnv *, jclass, jlong);
-
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKPersister_new
@@ -3391,6 +3607,22 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Persister_1persist_1graph
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Persister_1persist_1scorer
   (JNIEnv *, jclass, jlong, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKFutureCallback_new
+ * Signature: (Lorg/ldk/impl/bindings/LDKFutureCallback;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKFutureCallback_1new
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    FutureCallback_call
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_FutureCallback_1call
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKListen_new
@@ -3663,6 +3895,22 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1handle_
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1handle_1error
   (JNIEnv *, jclass, jlong, jbyteArray, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    ChannelMessageHandler_provided_node_features
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1provided_1node_1features
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    ChannelMessageHandler_provided_init_features
+ * Signature: (J[B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1provided_1init_1features
+  (JNIEnv *, jclass, jlong, jbyteArray);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKRoutingMessageHandler_new
@@ -3705,19 +3953,19 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1handle
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    RoutingMessageHandler_get_next_channel_announcements
- * Signature: (JJB)[J
+ * Method:    RoutingMessageHandler_get_next_channel_announcement
+ * Signature: (JJ)J
  */
-JNIEXPORT jlongArray JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1channel_1announcements
-  (JNIEnv *, jclass, jlong, jlong, jbyte);
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1channel_1announcement
+  (JNIEnv *, jclass, jlong, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    RoutingMessageHandler_get_next_node_announcements
- * Signature: (J[BB)[J
+ * Method:    RoutingMessageHandler_get_next_node_announcement
+ * Signature: (J[B)J
  */
-JNIEXPORT jlongArray JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1node_1announcements
-  (JNIEnv *, jclass, jlong, jbyteArray, jbyte);
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1get_1next_1node_1announcement
+  (JNIEnv *, jclass, jlong, jbyteArray);
 
 /*
  * Class:     org_ldk_impl_bindings
@@ -3759,6 +4007,78 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1handle
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1handle_1query_1short_1channel_1ids
   (JNIEnv *, jclass, jlong, jbyteArray, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    RoutingMessageHandler_provided_node_features
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1provided_1node_1features
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    RoutingMessageHandler_provided_init_features
+ * Signature: (J[B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1provided_1init_1features
+  (JNIEnv *, jclass, jlong, jbyteArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKOnionMessageHandler_new
+ * Signature: (Lorg/ldk/impl/bindings/LDKOnionMessageHandler;Lorg/ldk/impl/bindings/LDKOnionMessageProvider;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKOnionMessageHandler_1new
+  (JNIEnv *, jclass, jobject, jobject);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    LDKOnionMessageHandler_get_OnionMessageProvider
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKOnionMessageHandler_1get_1OnionMessageProvider
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessageHandler_handle_onion_message
+ * Signature: (J[BJ)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1handle_1onion_1message
+  (JNIEnv *, jclass, jlong, jbyteArray, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessageHandler_peer_connected
+ * Signature: (J[BJ)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1peer_1connected
+  (JNIEnv *, jclass, jlong, jbyteArray, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessageHandler_peer_disconnected
+ * Signature: (J[BZ)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1peer_1disconnected
+  (JNIEnv *, jclass, jlong, jbyteArray, jboolean);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessageHandler_provided_node_features
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1provided_1node_1features
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessageHandler_provided_init_features
+ * Signature: (J[B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1provided_1init_1features
+  (JNIEnv *, jclass, jlong, jbyteArray);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKCustomMessageReader_new
@@ -3849,18 +4169,10 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKEffectiveCapacity_1ref_1
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    LDKLockableScore_new
- * Signature: (Lorg/ldk/impl/bindings/LDKLockableScore;)J
+ * Method:    LDKDestination_ref_from_ptr
+ * Signature: (J)Lorg/ldk/impl/bindings/LDKDestination;
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKLockableScore_1new
-  (JNIEnv *, jclass, jobject);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    LockableScore_lock
- * Signature: (J)J
- */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LockableScore_1lock
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKDestination_1ref_1from_1ptr
   (JNIEnv *, jclass, jlong);
 
 /*
@@ -3951,6 +4263,38 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_LDKRouter_1new
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Router_1find_1route
   (JNIEnv *, jclass, jlong, jbyteArray, jlong, jbyteArray, jlongArray, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Router_notify_payment_path_failed
+ * Signature: (J[JJ)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1path_1failed
+  (JNIEnv *, jclass, jlong, jlongArray, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Router_notify_payment_path_successful
+ * Signature: (J[J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1path_1successful
+  (JNIEnv *, jclass, jlong, jlongArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Router_notify_payment_probe_successful
+ * Signature: (J[J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1probe_1successful
+  (JNIEnv *, jclass, jlong, jlongArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Router_notify_payment_probe_failed
+ * Signature: (J[JJ)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Router_1notify_1payment_1probe_1failed
+  (JNIEnv *, jclass, jlong, jlongArray, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    LDKRetry_ref_from_ptr
@@ -3975,6 +4319,14 @@ JNIEXPORT jstring JNICALL Java_org_ldk_impl_bindings__1ldk_1get_1compiled_1versi
 JNIEXPORT jstring JNICALL Java_org_ldk_impl_bindings__1ldk_1c_1bindings_1get_1compiled_1version
   (JNIEnv *, jclass);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BigEndianScalar_new
+ * Signature: ([B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_BigEndianScalar_1new
+  (JNIEnv *, jclass, jbyteArray);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    Bech32Error_clone_ptr
@@ -4009,43 +4361,147 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Transaction_1free
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    TxOut_new
- * Signature: ([BJ)J
+ * Method:    TxOut_new
+ * Signature: ([BJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_TxOut_1new
+  (JNIEnv *, jclass, jbyteArray, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    TxOut_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_TxOut_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    TxOut_clone_ptr
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_TxOut_1clone_1ptr
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    TxOut_clone
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_TxOut_1clone
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Str_free
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Str_1free
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CVec_PublicKeyZ_free
+ * Signature: ([[B)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1PublicKeyZ_1free
+  (JNIEnv *, jclass, jobjectArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteNoneZ_ok
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteNoneZ_err
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1err
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteNoneZ_is_ok
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1is_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteNoneZ_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteNoneZ_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteDecodeErrorZ_ok
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteDecodeErrorZ_err
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1err
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedRouteDecodeErrorZ_is_ok
+ * Signature: (J)Z
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_TxOut_1new
-  (JNIEnv *, jclass, jbyteArray, jlong);
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1is_1ok
+  (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    TxOut_free
+ * Method:    CResult_BlindedRouteDecodeErrorZ_free
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_TxOut_1free
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedRouteDecodeErrorZ_1free
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    TxOut_clone_ptr
+ * Method:    CResult_BlindedHopDecodeErrorZ_ok
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_TxOut_1clone_1ptr
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1ok
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    TxOut_clone
+ * Method:    CResult_BlindedHopDecodeErrorZ_err
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_TxOut_1clone
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1err
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    Str_free
- * Signature: (Ljava/lang/String;)V
+ * Method:    CResult_BlindedHopDecodeErrorZ_is_ok
+ * Signature: (J)Z
  */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Str_1free
-  (JNIEnv *, jclass, jstring);
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1is_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_BlindedHopDecodeErrorZ_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1BlindedHopDecodeErrorZ_1free
+  (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
@@ -4951,6 +5407,30 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1ShutdownScriptInvali
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1ShutdownScriptInvalidShutdownScriptZ_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    COption_WriteableScoreZ_some
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1WriteableScoreZ_1some
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    COption_WriteableScoreZ_none
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1WriteableScoreZ_1none
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    COption_WriteableScoreZ_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1WriteableScoreZ_1free
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_NoneErrorZ_ok
@@ -5423,14 +5903,6 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1RouteLightningErrorZ
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1RouteLightningErrorZ_1clone
   (JNIEnv *, jclass, jlong);
 
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    CVec_PublicKeyZ_free
- * Signature: ([[B)V
- */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1PublicKeyZ_1free
-  (JNIEnv *, jclass, jobjectArray);
-
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_PaymentPurposeDecodeErrorZ_ok
@@ -5991,46 +6463,6 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C3Tuple_1OutPointCVec_1Monitor
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C3Tuple_1OutPointCVec_1MonitorEventZPublicKeyZZ_1free
   (JNIEnv *, jclass, jlongArray);
 
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    COption_C2Tuple_usizeTransactionZZ_some
- * Signature: (J)J
- */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1some
-  (JNIEnv *, jclass, jlong);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    COption_C2Tuple_usizeTransactionZZ_none
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1none
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    COption_C2Tuple_usizeTransactionZZ_free
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1free
-  (JNIEnv *, jclass, jlong);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    COption_C2Tuple_usizeTransactionZZ_clone_ptr
- * Signature: (J)J
- */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1clone_1ptr
-  (JNIEnv *, jclass, jlong);
-
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    COption_C2Tuple_usizeTransactionZZ_clone
- * Signature: (J)J
- */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1C2Tuple_1usizeTransactionZZ_1clone
-  (JNIEnv *, jclass, jlong);
-
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_FixedPenaltyScorerDecodeErrorZ_ok
@@ -6633,19 +7065,43 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C3Tuple_1ChannelAnnouncementCh
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free
- * Signature: ([J)V
+ * Method:    COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_some
+ * Signature: (J)J
  */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1free
-  (JNIEnv *, jclass, jlongArray);
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1some
+  (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CVec_NodeAnnouncementZ_free
- * Signature: ([J)V
+ * Method:    COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_none
+ * Signature: ()J
  */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1NodeAnnouncementZ_1free
-  (JNIEnv *, jclass, jlongArray);
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1none
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone_ptr
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1clone_1ptr
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    COption_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZZ_1clone
+  (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
@@ -7471,6 +7927,78 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeyNoneZ_1clon
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeyNoneZ_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    COption_ScalarZ_some
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1ScalarZ_1some
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    COption_ScalarZ_none
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_COption_1ScalarZ_1none
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    COption_ScalarZ_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_COption_1ScalarZ_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_SharedSecretNoneZ_ok
+ * Signature: ([B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1ok
+  (JNIEnv *, jclass, jbyteArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_SharedSecretNoneZ_err
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1err
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_SharedSecretNoneZ_is_ok
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1is_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_SharedSecretNoneZ_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_SharedSecretNoneZ_clone_ptr
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1clone_1ptr
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_SharedSecretNoneZ_clone
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1SharedSecretNoneZ_1clone
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_SignDecodeErrorZ_ok
@@ -8919,6 +9447,38 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentIdPaymentErro
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1PaymentIdPaymentErrorZ_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_InFlightHtlcsDecodeErrorZ_ok
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_InFlightHtlcsDecodeErrorZ_err
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1err
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_InFlightHtlcsDecodeErrorZ_is_ok
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1is_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_InFlightHtlcsDecodeErrorZ_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1InFlightHtlcsDecodeErrorZ_1free
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_SiPrefixParseErrorZ_ok
@@ -10111,6 +10671,38 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErrorZ
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErrorZ_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_NoneSendErrorZ_ok
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1ok
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_NoneSendErrorZ_err
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1err
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_NoneSendErrorZ_is_ok
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1is_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_NoneSendErrorZ_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneSendErrorZ_1free
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    CResult_u32GraphSyncErrorZ_ok
@@ -11001,90 +11593,138 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDec
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_err
+ * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_err
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1err
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_is_ok
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1is_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_clone_ptr
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1clone_1ptr
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_clone
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1clone
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_UpdateAddHTLCDecodeErrorZ_ok
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1ok
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    CResult_UpdateAddHTLCDecodeErrorZ_err
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1err
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1err
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_is_ok
+ * Method:    CResult_UpdateAddHTLCDecodeErrorZ_is_ok
  * Signature: (J)Z
  */
-JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1is_1ok
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1is_1ok
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_free
+ * Method:    CResult_UpdateAddHTLCDecodeErrorZ_free
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1free
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1free
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_clone_ptr
+ * Method:    CResult_UpdateAddHTLCDecodeErrorZ_clone_ptr
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1clone_1ptr
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1clone_1ptr
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateFulfillHTLCDecodeErrorZ_clone
+ * Method:    CResult_UpdateAddHTLCDecodeErrorZ_clone
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateFulfillHTLCDecodeErrorZ_1clone
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1clone
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateAddHTLCDecodeErrorZ_ok
+ * Method:    CResult_OnionMessageDecodeErrorZ_ok
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1ok
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1ok
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateAddHTLCDecodeErrorZ_err
+ * Method:    CResult_OnionMessageDecodeErrorZ_err
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1err
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1err
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateAddHTLCDecodeErrorZ_is_ok
+ * Method:    CResult_OnionMessageDecodeErrorZ_is_ok
  * Signature: (J)Z
  */
-JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1is_1ok
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1is_1ok
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateAddHTLCDecodeErrorZ_free
+ * Method:    CResult_OnionMessageDecodeErrorZ_free
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1free
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1free
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateAddHTLCDecodeErrorZ_clone_ptr
+ * Method:    CResult_OnionMessageDecodeErrorZ_clone_ptr
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1clone_1ptr
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1clone_1ptr
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    CResult_UpdateAddHTLCDecodeErrorZ_clone
+ * Method:    CResult_OnionMessageDecodeErrorZ_clone
  * Signature: (J)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1UpdateAddHTLCDecodeErrorZ_1clone
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1OnionMessageDecodeErrorZ_1clone
   (JNIEnv *, jclass, jlong);
 
 /*
@@ -12433,19 +13073,19 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1send_1chann
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    MessageSendEvent_broadcast_channel_announcement
- * Signature: (JJ)J
+ * Method:    MessageSendEvent_send_channel_announcement
+ * Signature: ([BJJ)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast_1channel_1announcement
-  (JNIEnv *, jclass, jlong, jlong);
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1send_1channel_1announcement
+  (JNIEnv *, jclass, jbyteArray, jlong, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    MessageSendEvent_broadcast_node_announcement
- * Signature: (J)J
+ * Method:    MessageSendEvent_broadcast_channel_announcement
+ * Signature: (JJ)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast_1node_1announcement
-  (JNIEnv *, jclass, jlong);
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1broadcast_1channel_1announcement
+  (JNIEnv *, jclass, jlong, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
@@ -12511,6 +13151,14 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1send_1gossi
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageSendEventsProvider_1free
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessageProvider_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageProvider_1free
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    EventsProvider_free
@@ -12703,6 +13351,30 @@ JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_construct_1invoice_1prei
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Persister_1free
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    FutureCallback_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_FutureCallback_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Future_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Future_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Future_register_callback_fn
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Future_1register_1callback_1fn
+  (JNIEnv *, jclass, jlong, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    Level_clone
@@ -13015,13 +13687,29 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1ge
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1set_1commit_1upfront_1shutdown_1pubkey
   (JNIEnv *, jclass, jlong, jboolean);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    ChannelHandshakeConfig_get_their_channel_reserve_proportional_millionths
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1get_1their_1channel_1reserve_1proportional_1millionths
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    ChannelHandshakeConfig_set_their_channel_reserve_proportional_millionths
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1set_1their_1channel_1reserve_1proportional_1millionths
+  (JNIEnv *, jclass, jlong, jint);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    ChannelHandshakeConfig_new
- * Signature: (ISJBZZZ)J
+ * Signature: (ISJBZZZI)J
  */
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChannelHandshakeConfig_1new
-  (JNIEnv *, jclass, jint, jshort, jlong, jbyte, jboolean, jboolean, jboolean);
+  (JNIEnv *, jclass, jint, jshort, jlong, jbyte, jboolean, jboolean, jboolean, jint);
 
 /*
  * Class:     org_ldk_impl_bindings
@@ -14161,12 +14849,28 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Balance_1contentious_1claimab
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    Balance_maybe_claimable_htlcawaiting_timeout
+ * Method:    Balance_maybe_timeout_claimable_htlc
+ * Signature: (JI)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Balance_1maybe_1timeout_1claimable_1htlc
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Balance_maybe_preimage_claimable_htlc
  * Signature: (JI)J
  */
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Balance_1maybe_1claimable_1htlcawaiting_1timeout
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Balance_1maybe_1preimage_1claimable_1htlc
   (JNIEnv *, jclass, jlong, jint);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Balance_counterparty_revoked_output_claimable
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Balance_1counterparty_1revoked_1output_1claimable
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    Balance_eq
@@ -16135,14 +16839,6 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChannelManager_1send_1probe
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChannelManager_1funding_1transaction_1generated
   (JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jbyteArray);
 
-/*
- * Class:     org_ldk_impl_bindings
- * Method:    ChannelManager_broadcast_node_announcement
- * Signature: (J[B[B[J)V
- */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1broadcast_1node_1announcement
-  (JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jlongArray);
-
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    ChannelManager_update_channel_config
@@ -16311,6 +17007,14 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_ChannelManager_1await_1per
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1await_1persistable_1update
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    ChannelManager_get_persistable_update_future
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChannelManager_1get_1persistable_1update_1future
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    ChannelManager_current_best_block
@@ -18039,6 +18743,46 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_UpdateAddHTLC_1clone_1ptr
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_UpdateAddHTLC_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessage_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessage_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessage_get_blinding_point
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_OnionMessage_1get_1blinding_1point
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessage_set_blinding_point
+ * Signature: (J[B)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessage_1set_1blinding_1point
+  (JNIEnv *, jclass, jlong, jbyteArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessage_clone_ptr
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessage_1clone_1ptr
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessage_clone
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessage_1clone
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    UpdateFulfillHTLC_free
@@ -20151,6 +20895,14 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1free
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1free
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessageHandler_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessageHandler_1free
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    AcceptChannel_write
@@ -20439,6 +21191,22 @@ JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_UpdateAddHTLC_1write
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_UpdateAddHTLC_1read
   (JNIEnv *, jclass, jbyteArray);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessage_read
+ * Signature: ([B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessage_1read
+  (JNIEnv *, jclass, jbyteArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessage_write
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_OnionMessage_1write
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    Ping_write
@@ -20727,6 +21495,22 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1M
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1RoutingMessageHandler
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    IgnoringMessageHandler_as_OnionMessageProvider
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1OnionMessageProvider
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    IgnoringMessageHandler_as_OnionMessageHandler
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_IgnoringMessageHandler_1as_1OnionMessageHandler
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    IgnoringMessageHandler_as_CustomMessageReader
@@ -20815,13 +21599,29 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MessageHandler_1get_1route_1h
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageHandler_1set_1route_1handler
   (JNIEnv *, jclass, jlong, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    MessageHandler_get_onion_message_handler
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MessageHandler_1get_1onion_1message_1handler
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    MessageHandler_set_onion_message_handler
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageHandler_1set_1onion_1message_1handler
+  (JNIEnv *, jclass, jlong, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    MessageHandler_new
- * Signature: (JJ)J
+ * Signature: (JJJ)J
  */
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MessageHandler_1new
-  (JNIEnv *, jclass, jlong, jlong);
+  (JNIEnv *, jclass, jlong, jlong, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
@@ -20906,10 +21706,10 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1free
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    PeerManager_new
- * Signature: (J[B[BJJ)J
+ * Signature: (J[BJ[BJJ)J
  */
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_PeerManager_1new
-  (JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jlong, jlong);
+  (JNIEnv *, jclass, jlong, jbyteArray, jlong, jbyteArray, jlong, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
@@ -20991,6 +21791,14 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1disconnect_1all_1
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1timer_1tick_1occurred
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    PeerManager_broadcast_node_announcement
+ * Signature: (J[B[B[J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerManager_1broadcast_1node_1announcement
+  (JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jlongArray);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    htlc_success_tx_weight
@@ -22471,6 +23279,22 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InvoiceFeatures_1free
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelTypeFeatures_1free
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InitFeatures_known_channel_features
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_InitFeatures_1known_1channel_1features
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    NodeFeatures_known_channel_features
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1known_1channel_1features
+  (JNIEnv *, jclass);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    InitFeatures_empty
@@ -23364,39 +24188,103 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InitFeatures_1supports_1sh
  * Method:    NodeFeatures_set_shutdown_any_segwit_optional
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1shutdown_1any_1segwit_1optional
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1shutdown_1any_1segwit_1optional
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    NodeFeatures_set_shutdown_any_segwit_required
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1shutdown_1any_1segwit_1required
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    NodeFeatures_supports_shutdown_anysegwit
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1supports_1shutdown_1anysegwit
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InitFeatures_requires_shutdown_anysegwit
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InitFeatures_1requires_1shutdown_1anysegwit
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    NodeFeatures_requires_shutdown_anysegwit
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1requires_1shutdown_1anysegwit
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InitFeatures_set_onion_messages_optional
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InitFeatures_1set_1onion_1messages_1optional
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InitFeatures_set_onion_messages_required
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InitFeatures_1set_1onion_1messages_1required
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InitFeatures_supports_onion_messages
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InitFeatures_1supports_1onion_1messages
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    NodeFeatures_set_onion_messages_optional
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1onion_1messages_1optional
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    NodeFeatures_set_shutdown_any_segwit_required
+ * Method:    NodeFeatures_set_onion_messages_required
  * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1shutdown_1any_1segwit_1required
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1set_1onion_1messages_1required
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    NodeFeatures_supports_shutdown_anysegwit
+ * Method:    NodeFeatures_supports_onion_messages
  * Signature: (J)Z
  */
-JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1supports_1shutdown_1anysegwit
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1supports_1onion_1messages
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    InitFeatures_requires_shutdown_anysegwit
+ * Method:    InitFeatures_requires_onion_messages
  * Signature: (J)Z
  */
-JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InitFeatures_1requires_1shutdown_1anysegwit
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_InitFeatures_1requires_1onion_1messages
   (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    NodeFeatures_requires_shutdown_anysegwit
+ * Method:    NodeFeatures_requires_onion_messages
  * Signature: (J)Z
  */
-JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1requires_1shutdown_1anysegwit
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_NodeFeatures_1requires_1onion_1messages
   (JNIEnv *, jclass, jlong);
 
 /*
@@ -25919,6 +26807,14 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Score_1free
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LockableScore_1free
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    WriteableScore_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_WriteableScore_1free
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    MultiThreadedLockableScore_free
@@ -25927,6 +26823,38 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LockableScore_1free
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1free
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    MultiThreadedScoreLock_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MultiThreadedScoreLock_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    MultiThreadedScoreLock_as_Score
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MultiThreadedScoreLock_1as_1Score
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    MultiThreadedScoreLock_write
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_MultiThreadedScoreLock_1write
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    MultiThreadedLockableScore_as_LockableScore
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1as_1LockableScore
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    MultiThreadedLockableScore_write
@@ -25935,6 +26863,14 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1fr
 JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1write
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    MultiThreadedLockableScore_as_WriteableScore
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_MultiThreadedLockableScore_1as_1WriteableScore
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    MultiThreadedLockableScore_new
@@ -26327,6 +27263,190 @@ JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_ProbabilisticScorer_1wri
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ProbabilisticScorer_1read
   (JNIEnv *, jclass, jbyteArray, jlong, jlong, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BlindedRoute_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BlindedHop_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BlindedHop_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BlindedRoute_new
+ * Signature: ([[BJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1new
+  (JNIEnv *, jclass, jobjectArray, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BlindedRoute_write
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1write
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BlindedRoute_read
+ * Signature: ([B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_BlindedRoute_1read
+  (JNIEnv *, jclass, jbyteArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BlindedHop_write
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_BlindedHop_1write
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    BlindedHop_read
+ * Signature: ([B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_BlindedHop_1read
+  (JNIEnv *, jclass, jbyteArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessenger_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Destination_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Destination_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Destination_node
+ * Signature: ([B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Destination_1node
+  (JNIEnv *, jclass, jbyteArray);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Destination_blinded_route
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Destination_1blinded_1route
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SendError_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_SendError_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SendError_clone_ptr
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SendError_1clone_1ptr
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SendError_clone
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SendError_1clone
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SendError_secp256k1
+ * Signature: (Lorg/ldk/enums/Secp256k1Error;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SendError_1secp256k1
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SendError_too_big_packet
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SendError_1too_1big_1packet
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SendError_too_few_blinded_hops
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SendError_1too_1few_1blinded_1hops
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SendError_invalid_first_hop
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SendError_1invalid_1first_1hop
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SendError_buffer_full
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SendError_1buffer_1full
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessenger_new
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1new
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessenger_send_onion_message
+ * Signature: (J[[BJJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1send_1onion_1message
+  (JNIEnv *, jclass, jlong, jobjectArray, jlong, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessenger_as_OnionMessageHandler
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1as_1OnionMessageHandler
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    OnionMessenger_as_OnionMessageProvider
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_OnionMessenger_1as_1OnionMessageProvider
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    FilesystemPersister_free
@@ -26663,6 +27783,14 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Invoice_1clone_1ptr
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Invoice_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    Invoice_hash
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Invoice_1hash
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    SignedRawInvoice_free
@@ -26695,6 +27823,14 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1clone_1ptr
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SignedRawInvoice_hash
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1hash
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    RawInvoice_free
@@ -26743,6 +27879,14 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RawInvoice_1clone_1ptr
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RawInvoice_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    RawInvoice_hash
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RawInvoice_1hash
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    RawDataPart_free
@@ -26791,6 +27935,14 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RawDataPart_1clone_1ptr
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RawDataPart_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    RawDataPart_hash
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_RawDataPart_1hash
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    PositiveTimestamp_free
@@ -26823,6 +27975,14 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_PositiveTimestamp_1clone_1ptr
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_PositiveTimestamp_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    PositiveTimestamp_hash
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_PositiveTimestamp_1hash
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    SiPrefix_clone
@@ -26871,6 +28031,14 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_SiPrefix_1pico
 JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_SiPrefix_1eq
   (JNIEnv *, jclass, jlong, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    SiPrefix_hash
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SiPrefix_1hash
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    SiPrefix_multiplier
@@ -27279,6 +28447,14 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_InvoiceSignature_1clone_1ptr
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_InvoiceSignature_1clone
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InvoiceSignature_hash
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_InvoiceSignature_1hash
+  (JNIEnv *, jclass, jlong);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    InvoiceSignature_eq
@@ -27345,10 +28521,10 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1raw_1invoic
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    SignedRawInvoice_hash
+ * Method:    SignedRawInvoice_signable_hash
  * Signature: (J)[B
  */
-JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1hash
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1signable_1hash
   (JNIEnv *, jclass, jlong);
 
 /*
@@ -27377,10 +28553,10 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_SignedRawInvoice_1check_1s
 
 /*
  * Class:     org_ldk_impl_bindings
- * Method:    RawInvoice_hash
+ * Method:    RawInvoice_signable_hash
  * Signature: (J)[B
  */
-JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_RawInvoice_1hash
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_RawInvoice_1signable_1hash
   (JNIEnv *, jclass, jlong);
 
 /*
@@ -28082,10 +29258,10 @@ JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_PaymentError_1sending
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    InvoicePayer_new
- * Signature: (JJJJJJ)J
+ * Signature: (JJJJJ)J
  */
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1new
-  (JNIEnv *, jclass, jlong, jlong, jlong, jlong, jlong, jlong);
+  (JNIEnv *, jclass, jlong, jlong, jlong, jlong, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
@@ -28127,6 +29303,38 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1remove_1cached_1
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_InvoicePayer_1as_1EventHandler
   (JNIEnv *, jclass, jlong);
 
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InFlightHtlcs_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1free
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InFlightHtlcs_used_liquidity_msat
+ * Signature: (JJJJ)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1used_1liquidity_1msat
+  (JNIEnv *, jclass, jlong, jlong, jlong, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InFlightHtlcs_write
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1write
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     org_ldk_impl_bindings
+ * Method:    InFlightHtlcs_read
+ * Signature: ([B)J
+ */
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_InFlightHtlcs_1read
+  (JNIEnv *, jclass, jbyteArray);
+
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    create_phantom_invoice
@@ -28186,10 +29394,10 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1free
 /*
  * Class:     org_ldk_impl_bindings
  * Method:    DefaultRouter_new
- * Signature: (JJ[B)J
+ * Signature: (JJ[BJ)J
  */
 JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_DefaultRouter_1new
-  (JNIEnv *, jclass, jlong, jlong, jbyteArray);
+  (JNIEnv *, jclass, jlong, jlong, jbyteArray, jlong);
 
 /*
  * Class:     org_ldk_impl_bindings
diff --git a/src/main/jni/org_ldk_impl_bindings_LDKCOption_C2Tuple_usizeTransactionZZ.h b/src/main/jni/org_ldk_impl_bindings_LDKCOption_C2Tuple_usizeTransactionZZ.h
deleted file mode 100644 (file)
index 53ef8b3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_ldk_impl_bindings_LDKCOption_C2Tuple_usizeTransactionZZ */
-
-#ifndef _Included_org_ldk_impl_bindings_LDKCOption_C2Tuple_usizeTransactionZZ
-#define _Included_org_ldk_impl_bindings_LDKCOption_C2Tuple_usizeTransactionZZ
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_ldk_impl_bindings_LDKCOption_C2Tuple_usizeTransactionZZ
- * Method:    init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_00024LDKCOption_1C2Tuple_1usizeTransactionZZ_init
-  (JNIEnv *, jclass);
-
-#ifdef __cplusplus
-}
-#endif
-#endif