*
* Non-proportional fees are fixed according to our risk using the provided fee estimator.
*
- * panics if channel_value_satoshis is >= `MAX_FUNDING_SATOSHIS`!
- *
* Users need to notify the new ChannelManager when a new block is connected or
* disconnected using its `block_connected` and `block_disconnected` methods, starting
* from after `params.latest_hash`.
*/
public static ChannelManager of(FeeEstimator fee_est, Watch chain_monitor, BroadcasterInterface tx_broadcaster, Logger logger, KeysInterface keys_manager, UserConfig config, ChainParameters params) {
- long ret = bindings.ChannelManager_new(fee_est == null ? 0 : fee_est.ptr, chain_monitor == null ? 0 : chain_monitor.ptr, tx_broadcaster == null ? 0 : tx_broadcaster.ptr, logger == null ? 0 : logger.ptr, keys_manager == null ? 0 : keys_manager.ptr, config == null ? 0 : config.ptr & ~1, params == null ? 0 : params.ptr & ~1);
+ long ret = bindings.ChannelManager_new(fee_est == null ? 0 : fee_est.ptr, chain_monitor == null ? 0 : chain_monitor.ptr, tx_broadcaster == null ? 0 : tx_broadcaster.ptr, logger == null ? 0 : logger.ptr, keys_manager == null ? 0 : keys_manager.ptr, config == null ? 0 : config.ptr, params == null ? 0 : params.ptr);
Reference.reachabilityFence(fee_est);
Reference.reachabilityFence(chain_monitor);
Reference.reachabilityFence(tx_broadcaster);
Reference.reachabilityFence(config);
Reference.reachabilityFence(params);
if (ret >= 0 && ret <= 4096) { return null; }
- ChannelManager ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new ChannelManager(null, ret); }
- ret_hu_conv.ptrs_to.add(ret_hu_conv);
- ret_hu_conv.ptrs_to.add(fee_est);
- ret_hu_conv.ptrs_to.add(chain_monitor);
- ret_hu_conv.ptrs_to.add(tx_broadcaster);
- ret_hu_conv.ptrs_to.add(logger);
- ret_hu_conv.ptrs_to.add(keys_manager);
+ org.ldk.structs.ChannelManager ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.ChannelManager(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(fee_est); };
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(chain_monitor); };
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(tx_broadcaster); };
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(logger); };
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(keys_manager); };
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(config); };
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(params); };
return ret_hu_conv;
}
/**
- * 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);
Reference.reachabilityFence(this);
if (ret >= 0 && ret <= 4096) { return null; }
- UserConfig ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new UserConfig(null, ret); }
- ret_hu_conv.ptrs_to.add(this);
+ org.ldk.structs.UserConfig ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.UserConfig(null, ret); }
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
return ret_hu_conv;
}
* Note that override_config (or a relevant inner pointer) may be NULL or all-0s to represent None
*/
public Result__u832APIErrorZ create_channel(byte[] their_network_key, long channel_value_satoshis, long push_msat, long user_channel_id, @Nullable UserConfig override_config) {
- long ret = bindings.ChannelManager_create_channel(this.ptr, InternalUtils.check_arr_len(their_network_key, 33), channel_value_satoshis, push_msat, user_channel_id, override_config == null ? 0 : override_config.ptr & ~1);
+ long ret = bindings.ChannelManager_create_channel(this.ptr, InternalUtils.check_arr_len(their_network_key, 33), channel_value_satoshis, push_msat, user_channel_id, override_config == null ? 0 : override_config.ptr);
Reference.reachabilityFence(this);
Reference.reachabilityFence(their_network_key);
Reference.reachabilityFence(channel_value_satoshis);
Reference.reachabilityFence(override_config);
if (ret >= 0 && ret <= 4096) { return null; }
Result__u832APIErrorZ ret_hu_conv = Result__u832APIErrorZ.constr_from_ptr(ret);
+ if (this != null) { this.ptrs_to.add(override_config); };
return ret_hu_conv;
}
ChannelDetails[] ret_conv_16_arr = new ChannelDetails[ret_conv_16_len];
for (int q = 0; q < ret_conv_16_len; q++) {
long ret_conv_16 = ret[q];
- ChannelDetails ret_conv_16_hu_conv = null; if (ret_conv_16 < 0 || ret_conv_16 > 4096) { ret_conv_16_hu_conv = new ChannelDetails(null, ret_conv_16); }
- ret_conv_16_hu_conv.ptrs_to.add(this);
+ org.ldk.structs.ChannelDetails ret_conv_16_hu_conv = null; if (ret_conv_16 < 0 || ret_conv_16 > 4096) { ret_conv_16_hu_conv = new org.ldk.structs.ChannelDetails(null, ret_conv_16); }
+ if (ret_conv_16_hu_conv != null) { ret_conv_16_hu_conv.ptrs_to.add(this); };
ret_conv_16_arr[q] = ret_conv_16_hu_conv;
}
return ret_conv_16_arr;
}
/**
- * Gets the list of usable channels, in random order. Useful as an argument to
- * get_route to ensure non-announced channels are used.
+ * Gets the list of usable channels, in random order. Useful as an argument to [`find_route`]
+ * to ensure non-announced channels are used.
*
* These are guaranteed to have their [`ChannelDetails::is_usable`] value set to true, see the
* documentation for [`ChannelDetails::is_usable`] for more info on exactly what the criteria
* are.
+ *
+ * [`find_route`]: crate::routing::router::find_route
*/
public ChannelDetails[] list_usable_channels() {
long[] ret = bindings.ChannelManager_list_usable_channels(this.ptr);
ChannelDetails[] ret_conv_16_arr = new ChannelDetails[ret_conv_16_len];
for (int q = 0; q < ret_conv_16_len; q++) {
long ret_conv_16 = ret[q];
- ChannelDetails ret_conv_16_hu_conv = null; if (ret_conv_16 < 0 || ret_conv_16 > 4096) { ret_conv_16_hu_conv = new ChannelDetails(null, ret_conv_16); }
- ret_conv_16_hu_conv.ptrs_to.add(this);
+ org.ldk.structs.ChannelDetails ret_conv_16_hu_conv = null; if (ret_conv_16 < 0 || ret_conv_16 > 4096) { ret_conv_16_hu_conv = new org.ldk.structs.ChannelDetails(null, ret_conv_16); }
+ if (ret_conv_16_hu_conv != null) { ret_conv_16_hu_conv.ptrs_to.add(this); };
ret_conv_16_arr[q] = ret_conv_16_hu_conv;
}
return ret_conv_16_arr;
* [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background
* [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal
*/
- public Result_NoneAPIErrorZ close_channel(byte[] channel_id) {
- long ret = bindings.ChannelManager_close_channel(this.ptr, InternalUtils.check_arr_len(channel_id, 32));
+ public Result_NoneAPIErrorZ close_channel(byte[] channel_id, byte[] counterparty_node_id) {
+ long ret = bindings.ChannelManager_close_channel(this.ptr, InternalUtils.check_arr_len(channel_id, 32), InternalUtils.check_arr_len(counterparty_node_id, 33));
Reference.reachabilityFence(this);
Reference.reachabilityFence(channel_id);
+ Reference.reachabilityFence(counterparty_node_id);
if (ret >= 0 && ret <= 4096) { return null; }
Result_NoneAPIErrorZ ret_hu_conv = Result_NoneAPIErrorZ.constr_from_ptr(ret);
return ret_hu_conv;
* [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background
* [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal
*/
- public Result_NoneAPIErrorZ close_channel_with_target_feerate(byte[] channel_id, int target_feerate_sats_per_1000_weight) {
- long ret = bindings.ChannelManager_close_channel_with_target_feerate(this.ptr, InternalUtils.check_arr_len(channel_id, 32), target_feerate_sats_per_1000_weight);
+ public Result_NoneAPIErrorZ close_channel_with_target_feerate(byte[] channel_id, byte[] counterparty_node_id, int target_feerate_sats_per_1000_weight) {
+ long ret = bindings.ChannelManager_close_channel_with_target_feerate(this.ptr, InternalUtils.check_arr_len(channel_id, 32), InternalUtils.check_arr_len(counterparty_node_id, 33), target_feerate_sats_per_1000_weight);
Reference.reachabilityFence(this);
Reference.reachabilityFence(channel_id);
+ Reference.reachabilityFence(counterparty_node_id);
Reference.reachabilityFence(target_feerate_sats_per_1000_weight);
if (ret >= 0 && ret <= 4096) { return null; }
Result_NoneAPIErrorZ ret_hu_conv = Result_NoneAPIErrorZ.constr_from_ptr(ret);
}
/**
- * Force closes a channel, immediately broadcasting the latest local commitment transaction to
- * the chain and rejecting new HTLCs on the given channel. Fails if channel_id is unknown to the manager.
+ * Force closes a channel, immediately broadcasting the latest local transaction(s) and
+ * rejecting new HTLCs on the given channel. Fails if `channel_id` is unknown to
+ * the manager, or if the `counterparty_node_id` isn't the counterparty of the corresponding
+ * channel.
*/
- public Result_NoneAPIErrorZ force_close_channel(byte[] channel_id) {
- long ret = bindings.ChannelManager_force_close_channel(this.ptr, InternalUtils.check_arr_len(channel_id, 32));
+ public Result_NoneAPIErrorZ force_close_broadcasting_latest_txn(byte[] channel_id, byte[] counterparty_node_id) {
+ long ret = bindings.ChannelManager_force_close_broadcasting_latest_txn(this.ptr, InternalUtils.check_arr_len(channel_id, 32), InternalUtils.check_arr_len(counterparty_node_id, 33));
Reference.reachabilityFence(this);
Reference.reachabilityFence(channel_id);
+ Reference.reachabilityFence(counterparty_node_id);
+ if (ret >= 0 && ret <= 4096) { return null; }
+ Result_NoneAPIErrorZ ret_hu_conv = Result_NoneAPIErrorZ.constr_from_ptr(ret);
+ return ret_hu_conv;
+ }
+
+ /**
+ * Force closes a channel, rejecting new HTLCs on the given channel but skips broadcasting
+ * the latest local transaction(s). Fails if `channel_id` is unknown to the manager, or if the
+ * `counterparty_node_id` isn't the counterparty of the corresponding channel.
+ *
+ * You can always get the latest local transaction(s) to broadcast from
+ * [`ChannelMonitor::get_latest_holder_commitment_txn`].
+ */
+ public Result_NoneAPIErrorZ force_close_without_broadcasting_txn(byte[] channel_id, byte[] counterparty_node_id) {
+ long ret = bindings.ChannelManager_force_close_without_broadcasting_txn(this.ptr, InternalUtils.check_arr_len(channel_id, 32), InternalUtils.check_arr_len(counterparty_node_id, 33));
+ Reference.reachabilityFence(this);
+ Reference.reachabilityFence(channel_id);
+ Reference.reachabilityFence(counterparty_node_id);
if (ret >= 0 && ret <= 4096) { return null; }
Result_NoneAPIErrorZ ret_hu_conv = Result_NoneAPIErrorZ.constr_from_ptr(ret);
return ret_hu_conv;
* Force close all channels, immediately broadcasting the latest local commitment transaction
* for each to the chain and rejecting new HTLCs on each.
*/
- public void force_close_all_channels() {
- bindings.ChannelManager_force_close_all_channels(this.ptr);
+ public void force_close_all_channels_broadcasting_latest_txn() {
+ bindings.ChannelManager_force_close_all_channels_broadcasting_latest_txn(this.ptr);
+ Reference.reachabilityFence(this);
+ }
+
+ /**
+ * Force close all channels rejecting new HTLCs on each but without broadcasting the latest
+ * local transaction(s).
+ */
+ public void force_close_all_channels_without_broadcasting_txn() {
+ bindings.ChannelManager_force_close_all_channels_without_broadcasting_txn(this.ptr);
Reference.reachabilityFence(this);
}
* Note that payment_secret (or a relevant inner pointer) may be NULL or all-0s to represent None
*/
public Result_PaymentIdPaymentSendFailureZ send_payment(Route route, byte[] payment_hash, @Nullable byte[] payment_secret) {
- long ret = bindings.ChannelManager_send_payment(this.ptr, route == null ? 0 : route.ptr & ~1, InternalUtils.check_arr_len(payment_hash, 32), InternalUtils.check_arr_len(payment_secret, 32));
+ long ret = bindings.ChannelManager_send_payment(this.ptr, route == null ? 0 : route.ptr, InternalUtils.check_arr_len(payment_hash, 32), InternalUtils.check_arr_len(payment_secret, 32));
Reference.reachabilityFence(this);
Reference.reachabilityFence(route);
Reference.reachabilityFence(payment_hash);
Reference.reachabilityFence(payment_secret);
if (ret >= 0 && ret <= 4096) { return null; }
Result_PaymentIdPaymentSendFailureZ ret_hu_conv = Result_PaymentIdPaymentSendFailureZ.constr_from_ptr(ret);
- this.ptrs_to.add(route);
+ if (this != null) { this.ptrs_to.add(route); };
return ret_hu_conv;
}
* [`abandon_payment`]: [`ChannelManager::abandon_payment`]
*/
public Result_NonePaymentSendFailureZ retry_payment(Route route, byte[] payment_id) {
- long ret = bindings.ChannelManager_retry_payment(this.ptr, route == null ? 0 : route.ptr & ~1, InternalUtils.check_arr_len(payment_id, 32));
+ long ret = bindings.ChannelManager_retry_payment(this.ptr, route == null ? 0 : route.ptr, InternalUtils.check_arr_len(payment_id, 32));
Reference.reachabilityFence(this);
Reference.reachabilityFence(route);
Reference.reachabilityFence(payment_id);
if (ret >= 0 && ret <= 4096) { return null; }
Result_NonePaymentSendFailureZ ret_hu_conv = Result_NonePaymentSendFailureZ.constr_from_ptr(ret);
- this.ptrs_to.add(route);
+ if (this != null) { this.ptrs_to.add(route); };
return ret_hu_conv;
}
* Note that payment_preimage (or a relevant inner pointer) may be NULL or all-0s to represent None
*/
public Result_C2Tuple_PaymentHashPaymentIdZPaymentSendFailureZ send_spontaneous_payment(Route route, @Nullable byte[] payment_preimage) {
- long ret = bindings.ChannelManager_send_spontaneous_payment(this.ptr, route == null ? 0 : route.ptr & ~1, InternalUtils.check_arr_len(payment_preimage, 32));
+ long ret = bindings.ChannelManager_send_spontaneous_payment(this.ptr, route == null ? 0 : route.ptr, InternalUtils.check_arr_len(payment_preimage, 32));
Reference.reachabilityFence(this);
Reference.reachabilityFence(route);
Reference.reachabilityFence(payment_preimage);
if (ret >= 0 && ret <= 4096) { return null; }
Result_C2Tuple_PaymentHashPaymentIdZPaymentSendFailureZ ret_hu_conv = Result_C2Tuple_PaymentHashPaymentIdZPaymentSendFailureZ.constr_from_ptr(ret);
- this.ptrs_to.add(route);
+ if (this != null) { this.ptrs_to.add(route); };
+ return ret_hu_conv;
+ }
+
+ /**
+ * Send a payment that is probing the given route for liquidity. We calculate the
+ * [`PaymentHash`] of probes based on a static secret and a random [`PaymentId`], which allows
+ * us to easily discern them from real payments.
+ */
+ public Result_C2Tuple_PaymentHashPaymentIdZPaymentSendFailureZ send_probe(RouteHop[] hops) {
+ long ret = bindings.ChannelManager_send_probe(this.ptr, hops != null ? Arrays.stream(hops).mapToLong(hops_conv_10 -> hops_conv_10 == null ? 0 : hops_conv_10.ptr).toArray() : null);
+ Reference.reachabilityFence(this);
+ Reference.reachabilityFence(hops);
+ if (ret >= 0 && ret <= 4096) { return null; }
+ Result_C2Tuple_PaymentHashPaymentIdZPaymentSendFailureZ ret_hu_conv = Result_C2Tuple_PaymentHashPaymentIdZPaymentSendFailureZ.constr_from_ptr(ret);
+ for (RouteHop hops_conv_10: hops) { if (this != null) { this.ptrs_to.add(hops_conv_10); }; };
return ret_hu_conv;
}
* Returns an [`APIError::APIMisuseError`] if the funding_transaction spent non-SegWit outputs
* or if no output was found which matches the parameters in [`Event::FundingGenerationReady`].
*
+ * Returns [`APIError::APIMisuseError`] if the funding transaction is not final for propagation
+ * across the p2p network.
+ *
* Returns [`APIError::ChannelUnavailable`] if a funding transaction has already been provided
* for the channel or if the channel has been closed as indicated by [`Event::ChannelClosed`].
*
* not currently support replacing a funding transaction on an existing channel. Instead,
* create a new channel with a conflicting funding transaction.
*
+ * Note to keep the miner incentives aligned in moving the blockchain forward, we recommend
+ * the wallet software generating the funding transaction to apply anti-fee sniping as
+ * implemented by Bitcoin Core wallet. See <https://bitcoinops.org/en/topics/fee-sniping/>
+ * for more details.
+ *
* [`Event::FundingGenerationReady`]: crate::util::events::Event::FundingGenerationReady
* [`Event::ChannelClosed`]: crate::util::events::Event::ChannelClosed
*/
- public Result_NoneAPIErrorZ funding_transaction_generated(byte[] temporary_channel_id, byte[] funding_transaction) {
- long ret = bindings.ChannelManager_funding_transaction_generated(this.ptr, InternalUtils.check_arr_len(temporary_channel_id, 32), funding_transaction);
+ public Result_NoneAPIErrorZ funding_transaction_generated(byte[] temporary_channel_id, byte[] counterparty_node_id, byte[] funding_transaction) {
+ long ret = bindings.ChannelManager_funding_transaction_generated(this.ptr, InternalUtils.check_arr_len(temporary_channel_id, 32), InternalUtils.check_arr_len(counterparty_node_id, 33), funding_transaction);
Reference.reachabilityFence(this);
Reference.reachabilityFence(temporary_channel_id);
+ Reference.reachabilityFence(counterparty_node_id);
Reference.reachabilityFence(funding_transaction);
if (ret >= 0 && ret <= 4096) { return null; }
Result_NoneAPIErrorZ ret_hu_conv = Result_NoneAPIErrorZ.constr_from_ptr(ret);
}
/**
- * 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.
+ * Atomically updates the [`ChannelConfig`] for the given channels.
*
- * `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.
+ * Once the updates are applied, each eligible channel (advertised with a known short channel
+ * ID and a change in [`forwarding_fee_proportional_millionths`], [`forwarding_fee_base_msat`],
+ * or [`cltv_expiry_delta`]) has a [`BroadcastChannelUpdate`] event message generated
+ * containing the new [`ChannelUpdate`] message which should be broadcast to the network.
*
- * `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.
+ * Returns [`ChannelUnavailable`] when a channel is not found or an incorrect
+ * `counterparty_node_id` is provided.
*
- * Panics if `addresses` is absurdly large (more than 500).
+ * Returns [`APIMisuseError`] when a [`cltv_expiry_delta`] update is to be applied with a value
+ * below [`MIN_CLTV_EXPIRY_DELTA`].
*
- * [`get_and_clear_pending_msg_events`]: MessageSendEventsProvider::get_and_clear_pending_msg_events
+ * If an error is returned, none of the updates should be considered applied.
+ *
+ * [`forwarding_fee_proportional_millionths`]: ChannelConfig::forwarding_fee_proportional_millionths
+ * [`forwarding_fee_base_msat`]: ChannelConfig::forwarding_fee_base_msat
+ * [`cltv_expiry_delta`]: ChannelConfig::cltv_expiry_delta
+ * [`BroadcastChannelUpdate`]: events::MessageSendEvent::BroadcastChannelUpdate
+ * [`ChannelUpdate`]: msgs::ChannelUpdate
+ * [`ChannelUnavailable`]: APIError::ChannelUnavailable
+ * [`APIMisuseError`]: APIError::APIMisuseError
*/
- 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);
+ public Result_NoneAPIErrorZ update_channel_config(byte[] counterparty_node_id, byte[][] channel_ids, ChannelConfig config) {
+ long ret = bindings.ChannelManager_update_channel_config(this.ptr, InternalUtils.check_arr_len(counterparty_node_id, 33), channel_ids != null ? Arrays.stream(channel_ids).map(channel_ids_conv_8 -> InternalUtils.check_arr_len(channel_ids_conv_8, 32)).toArray(byte[][]::new) : null, config == null ? 0 : config.ptr);
Reference.reachabilityFence(this);
- Reference.reachabilityFence(rgb);
- Reference.reachabilityFence(alias);
- Reference.reachabilityFence(addresses);
+ Reference.reachabilityFence(counterparty_node_id);
+ Reference.reachabilityFence(channel_ids);
+ Reference.reachabilityFence(config);
+ if (ret >= 0 && ret <= 4096) { return null; }
+ Result_NoneAPIErrorZ ret_hu_conv = Result_NoneAPIErrorZ.constr_from_ptr(ret);
+ if (this != null) { this.ptrs_to.add(config); };
+ return ret_hu_conv;
}
/**
* Broadcasting `ChannelUpdate` messages if we've been disconnected from our peer for more
* than a minute, informing the network that they should no longer attempt to route over
* the channel.
+ * Expiring a channel's previous `ChannelConfig` if necessary to only allow forwarding HTLCs
+ * with the current `ChannelConfig`.
*
* Note that this may cause reentrancy through `chain::Watch::update_channel` calls or feerate
* estimate fetches.
* Indicates that the preimage for payment_hash is unknown or the received amount is incorrect
* after a PaymentReceived event, failing the HTLC back to its origin and freeing resources
* along the path (including in our own channel on which we received it).
- * Returns false if no payment was found to fail backwards, true if the process of failing the
- * HTLC backwards has been started.
+ *
+ * Note that in some cases around unclean shutdown, it is possible the payment may have
+ * already been claimed by you via [`ChannelManager::claim_funds`] prior to you seeing (a
+ * second copy of) the [`events::Event::PaymentReceived`] event. Alternatively, the payment
+ * may have already been failed automatically by LDK if it was nearing its expiration time.
+ *
+ * While LDK will never claim a payment automatically on your behalf (i.e. without you calling
+ * [`ChannelManager::claim_funds`]), you should still monitor for
+ * [`events::Event::PaymentClaimed`] events even for payments you intend to fail, especially on
+ * startup during which time claims that were in-progress at shutdown may be replayed.
*/
- public boolean fail_htlc_backwards(byte[] payment_hash) {
- boolean ret = bindings.ChannelManager_fail_htlc_backwards(this.ptr, InternalUtils.check_arr_len(payment_hash, 32));
+ public void fail_htlc_backwards(byte[] payment_hash) {
+ bindings.ChannelManager_fail_htlc_backwards(this.ptr, InternalUtils.check_arr_len(payment_hash, 32));
Reference.reachabilityFence(this);
Reference.reachabilityFence(payment_hash);
- return ret;
}
/**
* Provides a payment preimage in response to [`Event::PaymentReceived`], generating any
* [`MessageSendEvent`]s needed to claim the payment.
*
+ * Note that calling this method does *not* guarantee that the payment has been claimed. You
+ * must* wait for an [`Event::PaymentClaimed`] event which upon a successful claim will be
+ * provided to your [`EventHandler`] when [`process_pending_events`] is next called.
+ *
* Note that if you did not set an `amount_msat` when calling [`create_inbound_payment`] or
* [`create_inbound_payment_for_hash`] you must check that the amount in the `PaymentReceived`
* event matches your expectation. If you fail to do so and call this method, you may provide
* the sender \"proof-of-payment\" when they did not fulfill the full expected payment.
*
- * Returns whether any HTLCs were claimed, and thus if any new [`MessageSendEvent`]s are now
- * pending for processing via [`get_and_clear_pending_msg_events`].
- *
* [`Event::PaymentReceived`]: crate::util::events::Event::PaymentReceived
+ * [`Event::PaymentClaimed`]: crate::util::events::Event::PaymentClaimed
+ * [`process_pending_events`]: EventsProvider::process_pending_events
* [`create_inbound_payment`]: Self::create_inbound_payment
* [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
* [`get_and_clear_pending_msg_events`]: MessageSendEventsProvider::get_and_clear_pending_msg_events
*/
- public boolean claim_funds(byte[] payment_preimage) {
- boolean ret = bindings.ChannelManager_claim_funds(this.ptr, InternalUtils.check_arr_len(payment_preimage, 32));
+ public void claim_funds(byte[] payment_preimage) {
+ bindings.ChannelManager_claim_funds(this.ptr, InternalUtils.check_arr_len(payment_preimage, 32));
Reference.reachabilityFence(this);
Reference.reachabilityFence(payment_preimage);
- return ret;
}
/**
return ret;
}
+ /**
+ * Accepts a request to open a channel after a [`Event::OpenChannelRequest`].
+ *
+ * The `temporary_channel_id` parameter indicates which inbound channel should be accepted,
+ * and the `counterparty_node_id` parameter is the id of the peer which has requested to open
+ * the channel.
+ *
+ * The `user_channel_id` parameter will be provided back in
+ * [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
+ * with which `accept_inbound_channel`/`accept_inbound_channel_from_trusted_peer_0conf` call.
+ *
+ * Note that this method will return an error and reject the channel, if it requires support
+ * for zero confirmations. Instead, `accept_inbound_channel_from_trusted_peer_0conf` must be
+ * used to accept such channels.
+ *
+ * [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
+ * [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
+ */
+ public Result_NoneAPIErrorZ accept_inbound_channel(byte[] temporary_channel_id, byte[] counterparty_node_id, long user_channel_id) {
+ long ret = bindings.ChannelManager_accept_inbound_channel(this.ptr, InternalUtils.check_arr_len(temporary_channel_id, 32), InternalUtils.check_arr_len(counterparty_node_id, 33), user_channel_id);
+ Reference.reachabilityFence(this);
+ Reference.reachabilityFence(temporary_channel_id);
+ Reference.reachabilityFence(counterparty_node_id);
+ Reference.reachabilityFence(user_channel_id);
+ if (ret >= 0 && ret <= 4096) { return null; }
+ Result_NoneAPIErrorZ ret_hu_conv = Result_NoneAPIErrorZ.constr_from_ptr(ret);
+ return ret_hu_conv;
+ }
+
+ /**
+ * Accepts a request to open a channel after a [`events::Event::OpenChannelRequest`], treating
+ * it as confirmed immediately.
+ *
+ * The `user_channel_id` parameter will be provided back in
+ * [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
+ * with which `accept_inbound_channel`/`accept_inbound_channel_from_trusted_peer_0conf` call.
+ *
+ * Unlike [`ChannelManager::accept_inbound_channel`], this method accepts the incoming channel
+ * and (if the counterparty agrees), enables forwarding of payments immediately.
+ *
+ * This fully trusts that the counterparty has honestly and correctly constructed the funding
+ * transaction and blindly assumes that it will eventually confirm.
+ *
+ * If it does not confirm before we decide to close the channel, or if the funding transaction
+ * does not pay to the correct script the correct amount, *you will lose funds*.
+ *
+ * [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
+ * [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
+ */
+ public Result_NoneAPIErrorZ accept_inbound_channel_from_trusted_peer_0conf(byte[] temporary_channel_id, byte[] counterparty_node_id, long user_channel_id) {
+ long ret = bindings.ChannelManager_accept_inbound_channel_from_trusted_peer_0conf(this.ptr, InternalUtils.check_arr_len(temporary_channel_id, 32), InternalUtils.check_arr_len(counterparty_node_id, 33), user_channel_id);
+ Reference.reachabilityFence(this);
+ Reference.reachabilityFence(temporary_channel_id);
+ Reference.reachabilityFence(counterparty_node_id);
+ Reference.reachabilityFence(user_channel_id);
+ if (ret >= 0 && ret <= 4096) { return null; }
+ Result_NoneAPIErrorZ ret_hu_conv = Result_NoneAPIErrorZ.constr_from_ptr(ret);
+ return ret_hu_conv;
+ }
+
/**
* Gets a payment secret and payment hash for use in an invoice given to a third party wishing
* to pay us.
* Legacy version of [`create_inbound_payment`]. Use this method if you wish to share
* serialized state with LDK node(s) running 0.0.103 and earlier.
*
+ * May panic if `invoice_expiry_delta_secs` is greater than one year.
+ *
* # Note
* This method is deprecated and will be removed soon.
*
* If you need exact expiry semantics, you should enforce them upon receipt of
* [`PaymentReceived`].
*
- * May panic if `invoice_expiry_delta_secs` is greater than one year.
- *
* Note that invoices generated for inbound payments should have their `min_final_cltv_expiry`
* set to at least [`MIN_FINAL_CLTV_EXPIRY`].
*
* Legacy version of [`create_inbound_payment_for_hash`]. Use this method if you wish to share
* serialized state with LDK node(s) running 0.0.103 and earlier.
*
+ * May panic if `invoice_expiry_delta_secs` is greater than one year.
+ *
* # Note
* This method is deprecated and will be removed soon.
*
return ret_hu_conv;
}
+ /**
+ * Gets a fake short channel id for use in receiving [phantom node payments]. These fake scids
+ * are used when constructing the phantom invoice's route hints.
+ *
+ * [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
+ */
+ public long get_phantom_scid() {
+ long ret = bindings.ChannelManager_get_phantom_scid(this.ptr);
+ Reference.reachabilityFence(this);
+ return ret;
+ }
+
+ /**
+ * Gets route hints for use in receiving [phantom node payments].
+ *
+ * [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
+ */
+ public PhantomRouteHints get_phantom_route_hints() {
+ long ret = bindings.ChannelManager_get_phantom_route_hints(this.ptr);
+ Reference.reachabilityFence(this);
+ if (ret >= 0 && ret <= 4096) { return null; }
+ org.ldk.structs.PhantomRouteHints ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.PhantomRouteHints(null, ret); }
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
+ return ret_hu_conv;
+ }
+
/**
* Constructs a new MessageSendEventsProvider which calls the relevant methods on this_arg.
* This copies the `inner` pointer in this_arg and thus the returned MessageSendEventsProvider must be freed before this_arg is
Reference.reachabilityFence(this);
if (ret >= 0 && ret <= 4096) { return null; }
MessageSendEventsProvider ret_hu_conv = new MessageSendEventsProvider(null, ret);
- ret_hu_conv.ptrs_to.add(this);
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
return ret_hu_conv;
}
Reference.reachabilityFence(this);
if (ret >= 0 && ret <= 4096) { return null; }
EventsProvider ret_hu_conv = new EventsProvider(null, ret);
- ret_hu_conv.ptrs_to.add(this);
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
return ret_hu_conv;
}
Reference.reachabilityFence(this);
if (ret >= 0 && ret <= 4096) { return null; }
Listen ret_hu_conv = new Listen(null, ret);
- ret_hu_conv.ptrs_to.add(this);
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
return ret_hu_conv;
}
Reference.reachabilityFence(this);
if (ret >= 0 && ret <= 4096) { return null; }
Confirm ret_hu_conv = new Confirm(null, ret);
- ret_hu_conv.ptrs_to.add(this);
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
return ret_hu_conv;
}
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.
long ret = bindings.ChannelManager_current_best_block(this.ptr);
Reference.reachabilityFence(this);
if (ret >= 0 && ret <= 4096) { return null; }
- BestBlock ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new BestBlock(null, ret); }
- ret_hu_conv.ptrs_to.add(this);
+ org.ldk.structs.BestBlock ret_hu_conv = null; if (ret < 0 || ret > 4096) { ret_hu_conv = new org.ldk.structs.BestBlock(null, ret); }
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
return ret_hu_conv;
}
Reference.reachabilityFence(this);
if (ret >= 0 && ret <= 4096) { return null; }
ChannelMessageHandler ret_hu_conv = new ChannelMessageHandler(null, ret);
- ret_hu_conv.ptrs_to.add(this);
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
return ret_hu_conv;
}
Reference.reachabilityFence(this);
if (ret >= 0 && ret <= 4096) { return null; }
Payer ret_hu_conv = new Payer(null, ret);
- ret_hu_conv.ptrs_to.add(this);
+ if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); };
return ret_hu_conv;
}