diff --git a/.msggen.json b/.msggen.json index b3eea3946a5a..8a3bc16b93d1 100644 --- a/.msggen.json +++ b/.msggen.json @@ -3137,6 +3137,7 @@ }, "Splice_signedResponse": { "Splice_Signed.outnum": 3, + "Splice_Signed.psbt": 4, "Splice_Signed.tx": 1, "Splice_Signed.txid": 2 }, @@ -3146,7 +3147,8 @@ }, "Splice_updateResponse": { "Splice_Update.commitments_secured": 2, - "Splice_Update.psbt": 1 + "Splice_Update.psbt": 1, + "Splice_Update.signatures_secured": 3 }, "StaticbackupResponse": { "StaticBackup.scb[]": 1 @@ -10928,6 +10930,10 @@ "added": "pre-v0.10.1", "deprecated": null }, + "Splice_Update.signatures_secured": { + "added": "v24.11", + "deprecated": null + }, "StaticBackup": { "added": "pre-v0.10.1", "deprecated": null diff --git a/bitcoin/psbt.c b/bitcoin/psbt.c index 5a1a2494679a..a1e19c401b19 100644 --- a/bitcoin/psbt.c +++ b/bitcoin/psbt.c @@ -311,6 +311,36 @@ bool psbt_input_have_signature(const struct wally_psbt *psbt, return ok; } +bool psbt_input_get_ecdsa_sig(const tal_t *ctx, + const struct wally_psbt *psbt, + size_t in, + const struct pubkey *pubkey, + struct bitcoin_signature **sig) +{ + u8 pk_der[PUBKEY_CMPR_LEN]; + size_t index_plus_one; + struct wally_map_item *item; + bool ok; + + assert(in < psbt->num_inputs); + + pubkey_to_der(pk_der, pubkey); + *sig = NULL; + + ok = wally_psbt_input_find_signature(&psbt->inputs[in], pk_der, + sizeof(pk_der), + &index_plus_one) == WALLY_OK; + if (ok) { + item = &psbt->inputs[in].signatures.items[index_plus_one - 1]; + *sig = tal(ctx, struct bitcoin_signature); + if (!signature_from_der(item->value, item->value_len, *sig)) { + *sig = tal_free(*sig); + return false; + } + } + return ok; +} + void psbt_input_set_wit_utxo(struct wally_psbt *psbt, size_t in, const u8 *scriptPubkey, struct amount_sat amt) { @@ -611,6 +641,17 @@ void *psbt_get_lightning(const struct wally_map *map, return item->value; } +void psbt_set_lightning(const tal_t *ctx, + struct wally_map *map, + const u8 proprietary_type, + const void *value, + size_t val_len) +{ + u8 *key = psbt_make_key(NULL, proprietary_type, NULL); + map_replace(ctx, map, key, value, val_len); + tal_free(key); +} + void psbt_output_set_unknown(const tal_t *ctx, struct wally_psbt_output *out, const u8 *key, diff --git a/bitcoin/psbt.h b/bitcoin/psbt.h index 31abd2d42ed7..1335431ff6f5 100644 --- a/bitcoin/psbt.h +++ b/bitcoin/psbt.h @@ -180,12 +180,20 @@ WARN_UNUSED_RESULT bool psbt_input_set_signature(struct wally_psbt *psbt, size_t /* Returns false on error. On success, *signature_found is set to true if the * input has a signature present for `pubkey` and false if if one was not found. - * Only ignature presence is checked, is not validated. */ + * Only signature presence is checked, it is not validated. */ WARN_UNUSED_RESULT bool psbt_input_have_signature(const struct wally_psbt *psbt, size_t in, const struct pubkey *pubkey, bool *signature_found); +/* Returns false on error. On success *sig is set to the signature otherwise + * *sig is set to NULL. */ +WARN_UNUSED_RESULT bool psbt_input_get_ecdsa_sig(const tal_t *ctx, + const struct wally_psbt *psbt, + size_t in, + const struct pubkey *pubkey, + struct bitcoin_signature **sig); + void psbt_input_set_witscript(struct wally_psbt *psbt, size_t in, const u8 *wscript); /* psbt_input_set_unknown - Set the given Key-Value in the psbt's input keymap @@ -212,6 +220,19 @@ void *psbt_get_lightning(const struct wally_map *map, const u8 proprietary_type, size_t *val_len); +/* psbt_set_lightning - Set a propreitary lightning value on the given map + * + * @map - map of unknowns to set the value + * @proprietary_type - type no. to set + * @value - the value to be set + * @val_len - length of value + */ +void psbt_set_lightning(const tal_t *ctx, + struct wally_map *map, + const u8 proprietary_type, + const void *value, + size_t val_len); + /* psbt_output_set_unknown - Set the given Key-Value in the psbt's output keymap * * @ctx - tal context for allocations diff --git a/bitcoin/test/run-psbt-from-tx.c b/bitcoin/test/run-psbt-from-tx.c index 3c71675e55ae..85e2ca677100 100644 --- a/bitcoin/test/run-psbt-from-tx.c +++ b/bitcoin/test/run-psbt-from-tx.c @@ -68,6 +68,9 @@ void sha256_double(struct sha256_double *shadouble UNNEEDED, const void *p UNNEE /* Generated stub for signature_to_der */ size_t signature_to_der(u8 der[73] UNNEEDED, const struct bitcoin_signature *sig UNNEEDED) { fprintf(stderr, "signature_to_der called!\n"); abort(); } +/* Generated stub for signature_to_der */ +bool signature_from_der(const u8 *der UNNEEDED, size_t len UNNEEDED, struct bitcoin_signature *sig UNNEEDED) +{ fprintf(stderr, "signature_from_der called!\n"); abort(); } /* Generated stub for towire_sha256_double */ void towire_sha256_double(u8 **pptr UNNEEDED, const struct sha256_double *sha256d UNNEEDED) { fprintf(stderr, "towire_sha256_double called!\n"); abort(); } diff --git a/ccan/ccan/mem/mem.c b/ccan/ccan/mem/mem.c index 13027a2a7b0f..fcd4dda9fe7f 100644 --- a/ccan/ccan/mem/mem.c +++ b/ccan/ccan/mem/mem.c @@ -123,6 +123,6 @@ void memtaint(void *data, size_t len) memcpy(p, tainter, len); #if HAVE_VALGRIND_MEMCHECK_H - VALGRIND_MAKE_MEM_UNDEFINED(data, len); + (void)VALGRIND_MAKE_MEM_UNDEFINED(data, len); #endif } diff --git a/ccan/ccan/mem/mem.h b/ccan/ccan/mem/mem.h index 20286dcbefd4..61792575702e 100644 --- a/ccan/ccan/mem/mem.h +++ b/ccan/ccan/mem/mem.h @@ -244,7 +244,7 @@ void memswap(void *a, void *b, size_t n); #include static inline void *memcheck_(const void *data, size_t len) { - VALGRIND_CHECK_MEM_IS_DEFINED(data, len); + (void)VALGRIND_CHECK_MEM_IS_DEFINED(data, len); return (void *)data; } #else diff --git a/channeld/channeld.c b/channeld/channeld.c index 976117da5e3f..503f6fb605f4 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -57,7 +57,8 @@ #define VALID_STFU_MESSAGE(msg) \ ((msg) == WIRE_SPLICE || \ - (msg) == WIRE_SPLICE_ACK) + (msg) == WIRE_SPLICE_ACK || \ + (msg) == WIRE_TX_ABORT) #define SAT_MIN(a, b) (amount_sat_less((a), (b)) ? (a) : (b)) @@ -1149,8 +1150,10 @@ static u8 *send_commit_part(const tal_t *ctx, if (feature_negotiated(peer->our_features, peer->their_features, OPT_EXPERIMENTAL_SPLICE)) { - status_debug("send_commit_part(splice: %d, remote_splice: %d)", - (int)splice_amnt, (int)remote_splice_amnt); + status_debug("send_commit_part(splice: %d, remote_splice: %d," + " index: %"PRIu64")", + (int)splice_amnt, (int)remote_splice_amnt, + remote_index); cs_tlv->splice_info = tal(cs_tlv, struct channel_id); derive_channel_id(cs_tlv->splice_info, funding); @@ -1645,6 +1648,24 @@ static bool have_i_signed_inflight(const struct peer *peer, return has_sig; } +static bool have_they_signed_inflight(const struct peer *peer, + const struct inflight *inflight) +{ + bool has_sig; + u32 index; + + index = find_channel_funding_input(inflight->psbt, + &peer->channel->funding); + + if (!psbt_input_have_signature(inflight->psbt, index, + &peer->channel->funding_pubkey[REMOTE], + &has_sig)) + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Unable parse inflight psbt"); + + return has_sig; +} + /* this checks if local has signed everything buy the funding input */ static bool missing_user_signatures(const struct peer *peer, const struct inflight *inflight) @@ -1820,8 +1841,9 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer, const struct commitsig **commitsigs; int remote_anchor_outnum; - status_debug("handle_peer_commit_sig(splice: %d, remote_splice: %d)", - (int)splice_amnt, (int)remote_splice_amnt); + status_debug("handle_peer_commit_sig(splice: %d, remote_splice: %d," + " index: %"PRIu64")", + (int)splice_amnt, (int)remote_splice_amnt, local_index); struct tlv_commitment_signed_tlvs *cs_tlv = tlv_commitment_signed_tlvs_new(tmpctx); @@ -2684,8 +2706,11 @@ static struct commitsig *interactive_send_commitments(struct peer *peer, if (do_i_sign_first(peer, psbt, our_role, inflight->force_sign_first) && send_commitments) { - status_debug("Splice %s: we commit first", - our_role == TX_INITIATOR ? "initiator" : "accepter"); + status_debug("Splice %s: we commit first;" + " next_index_local:%"PRIu64";" + " next_index_remote:%"PRIu64, + our_role == TX_INITIATOR ? "initiator" : "accepter", + next_index_local, next_index_remote); peer_write(peer->pps, send_commit_part(tmpctx, peer, @@ -2712,6 +2737,12 @@ static struct commitsig *interactive_send_commitments(struct peer *peer, if (msg_received) *msg_received = msg; + status_debug("Splice %s: we recv commit;" + " next_index_local:%"PRIu64";" + " next_index_remote:%"PRIu64, + our_role == TX_INITIATOR ? "initiator" : "accepter", + next_index_local, next_index_remote); + /* Funding counts as 0th commit so we do inflight_index + 1 */ if (fromwire_peektype(msg) == WIRE_COMMITMENT_SIGNED) { get_per_commitment_point(next_index_local - 1, @@ -2731,8 +2762,11 @@ static struct commitsig *interactive_send_commitments(struct peer *peer, if (!do_i_sign_first(peer, psbt, our_role, inflight->force_sign_first) && send_commitments) { - status_debug("Splice %s: we commit second", - our_role == TX_INITIATOR ? "initiator" : "accepter"); + status_debug("Splice %s: we commit second;" + " next_index_local:%"PRIu64";" + " next_index_remote:%"PRIu64, + our_role == TX_INITIATOR ? "initiator" : "accepter", + next_index_local, next_index_remote); peer_write(peer->pps, send_commit_part(tmpctx, peer, @@ -2870,7 +2904,8 @@ static struct amount_sat check_balances(struct peer *peer, { struct amount_sat min_initiator_fee, min_accepter_fee, max_initiator_fee, max_accepter_fee, - funding_amount_res, min_multiplied; + funding_amount_res, min_multiplied, + initiator_penalty_fee, accepter_penalty_fee; struct amount_msat funding_amount, initiator_fee, accepter_fee; struct amount_msat in[NUM_TX_ROLES], out[NUM_TX_ROLES], @@ -2949,20 +2984,20 @@ static struct amount_sat check_balances(struct peer *peer, * While we're, here, adjust the output counts by splice amount. */ if (!amount_msat_add_sat_s64(&funding_amount, funding_amount, - peer->splicing->opener_relative)) - peer_failed_warn(peer->pps, &peer->channel_id, - "Unable to add opener funding"); + peer->splicing->opener_relative)) + splice_abort(peer, "Splice initiator did not provide enough" + " funding"); if (!amount_msat_add_sat_s64(&out[TX_INITIATOR], out[TX_INITIATOR], - peer->splicing->opener_relative)) + peer->splicing->opener_relative)) peer_failed_warn(peer->pps, &peer->channel_id, "Unable to add opener funding to out amnt."); if (!amount_msat_add_sat_s64(&funding_amount, funding_amount, - peer->splicing->accepter_relative)) - peer_failed_warn(peer->pps, &peer->channel_id, - "Unable to add accepter funding"); + peer->splicing->accepter_relative)) + splice_abort(peer, "Splice accepter did not provide enough" + " funding"); if (!amount_msat_add_sat_s64(&out[TX_ACCEPTER], out[TX_ACCEPTER], - peer->splicing->accepter_relative)) + peer->splicing->accepter_relative)) peer_failed_warn(peer->pps, &peer->channel_id, "Unable to add accepter funding to out amnt."); @@ -3022,14 +3057,22 @@ static struct amount_sat check_balances(struct peer *peer, calc_weight(TX_ACCEPTER, psbt)); max_initiator_fee = amount_tx_fee(peer->feerate_max, calc_weight(TX_INITIATOR, psbt)); + initiator_penalty_fee = amount_tx_fee(peer->feerate_penalty, + calc_weight(TX_INITIATOR, psbt)); + accepter_penalty_fee = amount_tx_fee(peer->feerate_penalty, + calc_weight(TX_ACCEPTER, psbt)); /* Sometimes feerate_max is some absurdly high value, in that case we * give a fee warning based of a multiple of the min value. */ amount_sat_mul(&min_multiplied, min_accepter_fee, 5); max_accepter_fee = SAT_MIN(min_multiplied, max_accepter_fee); + if (amount_sat_greater(accepter_penalty_fee, max_accepter_fee)) + max_accepter_fee = accepter_penalty_fee; amount_sat_mul(&min_multiplied, min_initiator_fee, 5); max_initiator_fee = SAT_MIN(min_multiplied, max_initiator_fee); + if (amount_sat_greater(initiator_penalty_fee, max_initiator_fee)) + max_initiator_fee = initiator_penalty_fee; /* Check initiator fee */ if (amount_msat_less_sat(initiator_fee, min_initiator_fee)) { @@ -3142,7 +3185,7 @@ static void update_view_from_inflights(struct peer *peer) } } -/* Called to finish an ongoing splice OR on restart from chanenl_reestablish. */ +/* Called to finish an ongoing splice OR on restart from channel_reestablish. */ static void resume_splice_negotiation(struct peer *peer, bool send_commitments, bool recv_commitments, @@ -3158,7 +3201,6 @@ static void resume_splice_negotiation(struct peer *peer, enum peer_wire type; struct wally_psbt *current_psbt = inflight->psbt; struct commitsig *their_commit; - struct witness **inws; const struct witness **outws; u8 der[73]; size_t der_len; @@ -3167,13 +3209,23 @@ static void resume_splice_negotiation(struct peer *peer, u32 splice_funding_index; const u8 *msg, *sigmsg; u32 chan_output_index; - struct bitcoin_signature their_sig; struct pubkey *their_pubkey; - struct bitcoin_tx *final_tx COMPILER_WANTS_INIT("12.3.0 -O3"); + struct bitcoin_tx *final_tx; struct bitcoin_txid final_txid; u8 **wit_stack; struct tlv_txsigs_tlvs *txsig_tlvs, *their_txsigs_tlvs; const u8 *msg_received; + struct witness **inws; + struct bitcoin_signature *their_sig; + + if (peer->splicing) { + inws = peer->splicing->inws; + their_sig = peer->splicing->their_sig; + } + else { + inws = NULL; + their_sig = NULL; + } status_info("Splice negotation, will %ssend commit, %srecv commit," " %ssend signature, %srecv signature as %s", @@ -3246,9 +3298,10 @@ static void resume_splice_negotiation(struct peer *peer, tal_hex(tmpctx, msg)); /* Set the splice_sig on the splice funding tx psbt */ - if (!psbt_input_set_signature(current_psbt, splice_funding_index, - &peer->channel->funding_pubkey[LOCAL], - &splice_sig)) + if (send_signature + && !psbt_input_set_signature(current_psbt, splice_funding_index, + &peer->channel->funding_pubkey[LOCAL], + &splice_sig)) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Unable to set signature internally " "funding_index: %d " @@ -3300,10 +3353,18 @@ static void resume_splice_negotiation(struct peer *peer, status_debug("Splice is using cached tx_sig_msg"); } - if (fromwire_peektype(msg_received) == WIRE_TX_SIGNATURES) + assert(!peer->splicing || !peer->splicing->their_sig); + assert(!peer->splicing || !peer->splicing->inws); + + if (fromwire_peektype(msg_received) == WIRE_TX_SIGNATURES) { + status_debug("Splice: Using existing sig msg"); msg = msg_received; - else + } + else { + status_debug("Splice: Awaiting signature message"); msg = peer_read(tmpctx, peer->pps); + status_debug("Splice: Got peer message! (is signature?)"); + } type = fromwire_peektype(msg); @@ -3329,32 +3390,43 @@ static void resume_splice_negotiation(struct peer *peer, "Splicing bad tx_signatures %s", tal_hex(msg, msg)); + if (peer->splicing) + peer->splicing->inws = tal_steal(peer->splicing, inws); + /* BOLT-0d8b701614b09c6ee4172b04da2203e73deec7e2 #2: * - Upon receipt of `tx_signatures` for the splice transaction: * - MUST consider splice negotiation complete. * - MUST consider the connection no longer quiescent. */ - end_stfu_mode(peer); + if (send_signature) + end_stfu_mode(peer); + + their_sig = tal(tmpctx, struct bitcoin_signature); /* BOLT-a8b9f495cac28124c69cc5ee429f9ef2bacb9921 #2: * Both nodes: * - MUST sign the transaction using SIGHASH_ALL */ - their_sig.sighash_type = SIGHASH_ALL; + their_sig->sighash_type = SIGHASH_ALL; if (!signature_from_der(their_txsigs_tlvs->funding_outpoint_sig, tal_count(their_txsigs_tlvs->funding_outpoint_sig), - &their_sig)) { + their_sig)) { + tal_free(their_txsigs_tlvs); peer_failed_warn(peer->pps, &peer->channel_id, "Splicing bad tx_signatures %s", tal_hex(msg, msg)); } + if (peer->splicing) + peer->splicing->their_sig = tal_steal(peer->splicing, + their_sig); + tal_free(their_txsigs_tlvs); /* Set the commit_sig on the commitment tx psbt */ if (!psbt_input_set_signature(current_psbt, splice_funding_index, their_pubkey, - &their_sig)) { + their_sig)) { status_failed(STATUS_FAIL_INTERNAL_ERROR, "Unable to set signature internally " @@ -3364,9 +3436,25 @@ static void resume_splice_negotiation(struct peer *peer, "psbt: %s", splice_funding_index, fmt_pubkey(tmpctx, their_pubkey), - fmt_bitcoin_signature(tmpctx, &their_sig), + fmt_bitcoin_signature(tmpctx, their_sig), fmt_wally_psbt(tmpctx, current_psbt)); } + } + + if (have_i_signed_inflight(peer, inflight) + && have_they_signed_inflight(peer, inflight)) { + + if (!their_sig) { + status_debug("Splice: Extracting their_sig from psbt"); + if (!psbt_input_get_ecdsa_sig(tmpctx, current_psbt, + splice_funding_index, + &peer->channel->funding_pubkey[REMOTE], + &their_sig)) + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Should not arrive here w/o" + " their_sig"); + } + assert(their_sig); psbt_input_set_witscript(current_psbt, splice_funding_index, @@ -3402,25 +3490,25 @@ static void resume_splice_negotiation(struct peer *peer, &peer->channel_id, "Mismatch witness stack count." " Most likely you are missing" - " signatures. Your" - " TX_SIGNATURES message: %s.", - tal_hex(msg, msg)); + " signatures."); - psbt_finalize_input(current_psbt, in, inws[j++]); + psbt_finalize_input(current_psbt, in, + inws[j++]); } final_tx = bitcoin_tx_with_psbt(tmpctx, current_psbt); wit_stack = bitcoin_witness_2of2(final_tx, &splice_sig, - &their_sig, + their_sig, &peer->channel->funding_pubkey[LOCAL], their_pubkey); bitcoin_tx_input_set_witness(final_tx, splice_funding_index, wit_stack); + } + if (recv_signature) { /* We let core validate our peer's signatures are correct. */ - msg = towire_channeld_update_inflight(NULL, current_psbt, NULL, NULL); wire_sync_write(MASTER_FD, take(msg)); @@ -3436,9 +3524,13 @@ static void resume_splice_negotiation(struct peer *peer, status_debug("Splice: we signed second"); } - peer->splicing = tal_free(peer->splicing); + if (send_signature) { + if (!recv_signature) + end_stfu_mode(peer); - if (recv_signature) { + peer->splicing = tal_free(peer->splicing); + + final_tx = bitcoin_tx_with_psbt(tmpctx, current_psbt); msg = towire_channeld_splice_confirmed_signed(tmpctx, final_tx, chan_output_index); wire_sync_write(MASTER_FD, take(msg)); @@ -3678,8 +3770,6 @@ static void splice_initiator(struct peer *peer, const u8 *inmsg) struct bitcoin_tx *prev_tx; u32 sequence = 0; u8 *scriptPubkey; - char *error; - u8 *abort_msg; ictx = new_interactivetx_context(tmpctx, TX_INITIATOR, peer->pps, peer->channel_id); @@ -3768,31 +3858,18 @@ static void splice_initiator(struct peer *peer, const u8 *inmsg) psbt_add_serials(ictx->desired_psbt, ictx->our_role); - error = process_interactivetx_updates(tmpctx, - ictx, - &peer->splicing->received_tx_complete, - &abort_msg); - - if (error) - peer_failed_warn(peer->pps, &peer->channel_id, - "Interactive splicing_ack error: %s", error); - - check_tx_abort(peer, abort_msg); - - peer->splicing->tx_add_input_count = ictx->tx_add_input_count; - peer->splicing->tx_add_output_count = ictx->tx_add_output_count; - - if (peer->splicing->current_psbt != ictx->current_psbt) - tal_free(peer->splicing->current_psbt); - peer->splicing->current_psbt = tal_steal(peer->splicing, - ictx->current_psbt); + peer->splicing->tx_add_input_count = 0; + peer->splicing->tx_add_output_count = 0; peer->splicing->mode = true; /* Return the current PSBT to the channel_control to give to user. */ outmsg = towire_channeld_splice_confirmed_init(NULL, - ictx->current_psbt); + ictx->desired_psbt); wire_sync_write(MASTER_FD, take(outmsg)); + + tal_free(peer->splicing->current_psbt); + peer->splicing->current_psbt = create_psbt(peer->splicing, 0, 0, 0); } /* This occurs when the user has marked they are done making changes to the @@ -3804,6 +3881,7 @@ static void splice_initiator_user_finalized(struct peer *peer) { u8 *outmsg; struct interactivetx_context *ictx; + bool sign_first; char *error; u32 chan_output_index, splice_funding_index; struct wally_psbt_output *new_chan_output; @@ -3871,24 +3949,35 @@ static void splice_initiator_user_finalized(struct peer *peer) new_inflight = inflights_new(peer); - psbt_txid(tmpctx, ictx->current_psbt, &new_inflight->outpoint.txid, NULL); + psbt_txid(tmpctx, ictx->current_psbt, &new_inflight->outpoint.txid, + NULL); new_inflight->outpoint.n = chan_output_index; - new_inflight->psbt = tal_steal(new_inflight, ictx->current_psbt); new_inflight->amnt = amount_sat(new_chan_output->amount); new_inflight->splice_amnt = peer->splicing->opener_relative; new_inflight->last_tx = NULL; new_inflight->i_am_initiator = true; new_inflight->force_sign_first = peer->splicing->force_sign_first; - current_push_val = relative_splice_balance_fundee(peer, our_role, ictx->current_psbt, - chan_output_index, splice_funding_index); + /* Switch over to using inflight psbt. This allows us to be reentrant. + * On restart we *will* have inflight psbt but we will not have any + * normal in-memory copy of the psbt: peer->splicing/ictx->current_psbt. + * Since we have to support using the inflight psbt anyway, we default + * to it. */ + new_inflight->psbt = tal_steal(new_inflight, ictx->current_psbt); + ictx->current_psbt = NULL; + peer->splicing->current_psbt = NULL; + + current_push_val = relative_splice_balance_fundee(peer, our_role, + new_inflight->psbt, + chan_output_index, + splice_funding_index); update_hsmd_with_splice(peer, new_inflight, our_role, current_push_val); update_view_from_inflights(peer); peer->splice_state->count++; - their_commit = interactive_send_commitments(peer, ictx->current_psbt, + their_commit = interactive_send_commitments(peer, new_inflight->psbt, our_role, last_inflight_index(peer), true, true, NULL); @@ -3896,17 +3985,21 @@ static void splice_initiator_user_finalized(struct peer *peer) new_inflight->last_tx = tal_steal(new_inflight, their_commit->tx); new_inflight->last_sig = their_commit->commit_signature; - outmsg = towire_channeld_update_inflight(NULL, ictx->current_psbt, + outmsg = towire_channeld_update_inflight(NULL, new_inflight->psbt, their_commit->tx, &their_commit->commit_signature); wire_sync_write(MASTER_FD, take(outmsg)); - if (peer->splicing->current_psbt != ictx->current_psbt) - tal_free(peer->splicing->current_psbt); - peer->splicing->current_psbt = tal_steal(peer->splicing, ictx->current_psbt); + sign_first = do_i_sign_first(peer, new_inflight->psbt, our_role, + peer->splicing->force_sign_first); + + if (!sign_first) + resume_splice_negotiation(peer, false, false, false, true); + outmsg = towire_channeld_splice_confirmed_update(NULL, - ictx->current_psbt, - true); + new_inflight->psbt, + true, + !sign_first); wire_sync_write(MASTER_FD, take(outmsg)); } @@ -3952,13 +4045,10 @@ static void splice_initiator_user_update(struct peer *peer, const u8 *inmsg) ictx->tx_add_input_count = peer->splicing->tx_add_input_count; ictx->tx_add_output_count = peer->splicing->tx_add_output_count; - /* User may not have setup serial numbers on their modifeid PSBT, so we - * ensure that for them here */ - psbt_add_serials(ictx->desired_psbt, ictx->our_role); - - /* If there no are no changes, we consider the splice 'user finalized' */ + /* If there no are no changes, we consider the splice user finalized */ if (!interactivetx_has_changes(ictx, ictx->desired_psbt)) { splice_initiator_user_finalized(peer); + tal_steal(last_inflight(peer), last_inflight(peer)->psbt); return; } @@ -3982,7 +4072,7 @@ static void splice_initiator_user_update(struct peer *peer, const u8 *inmsg) /* Peer may have modified our PSBT so we return it to the user here */ outmsg = towire_channeld_splice_confirmed_update(NULL, ictx->current_psbt, - false); + false, false); wire_sync_write(MASTER_FD, take(outmsg)); } @@ -3995,10 +4085,11 @@ static void splice_initiator_user_update(struct peer *peer, const u8 *inmsg) * theirs back. */ static void splice_initiator_user_signed(struct peer *peer, const u8 *inmsg) { + struct inflight *inflight = last_inflight(peer); struct wally_psbt *signed_psbt; struct bitcoin_txid current_psbt_txid, signed_psbt_txid; - struct inflight *inflight; const u8 *msg, *outmsg; + bool sign_first; if (!peer->splicing) { msg = towire_channeld_splice_state_error(NULL, "Can't accept a" @@ -4038,7 +4129,7 @@ static void splice_initiator_user_signed(struct peer *peer, const u8 *inmsg) return; } - psbt_txid(tmpctx, peer->splicing->current_psbt, ¤t_psbt_txid, NULL); + psbt_txid(tmpctx, inflight->psbt, ¤t_psbt_txid, NULL); psbt_txid(tmpctx, signed_psbt, &signed_psbt_txid, NULL); if (!bitcoin_txid_eq(&signed_psbt_txid, ¤t_psbt_txid)) @@ -4048,9 +4139,7 @@ static void splice_initiator_user_signed(struct peer *peer, const u8 *inmsg) fmt_bitcoin_txid(tmpctx, &signed_psbt_txid), fmt_bitcoin_txid(tmpctx, ¤t_psbt_txid)); - peer->splicing->current_psbt = tal_free(peer->splicing->current_psbt); - - inflight = last_inflight(peer); + tal_free(inflight->psbt); inflight->psbt = tal_steal(inflight, signed_psbt); /* Save the user provided signatures to DB incase we have to @@ -4061,7 +4150,10 @@ static void splice_initiator_user_signed(struct peer *peer, const u8 *inmsg) wire_sync_write(MASTER_FD, take(outmsg)); - resume_splice_negotiation(peer, false, false, true, true); + sign_first = do_i_sign_first(peer, signed_psbt, TX_INITIATOR, + inflight->force_sign_first); + + resume_splice_negotiation(peer, false, false, true, sign_first); } /* This occurs once our 'stfu' transition was successful. */ @@ -4085,6 +4177,7 @@ static void handle_splice_stfu_success(struct peer *peer) static void handle_splice_init(struct peer *peer, const u8 *inmsg) { u8 *msg; + bool skip_stfu; /* Can't start a splice with another splice still active */ if (peer->splicing) { @@ -4101,23 +4194,32 @@ static void handle_splice_init(struct peer *peer, const u8 *inmsg) &peer->splicing->current_psbt, &peer->splicing->opener_relative, &peer->splicing->feerate_per_kw, - &peer->splicing->force_feerate)) + &peer->splicing->force_feerate, + &skip_stfu)) master_badmsg(WIRE_CHANNELD_SPLICE_INIT, inmsg); - if (peer->want_stfu) { + if (!skip_stfu && peer->want_stfu) { msg = towire_channeld_splice_state_error(NULL, "Can't begin a" " splice while waiting" " for STFU."); wire_sync_write(MASTER_FD, take(msg)); return; } - if (is_stfu_active(peer)) { + if (!skip_stfu && is_stfu_active(peer)) { msg = towire_channeld_splice_state_error(NULL, "Can't begin a" " splice while" " currently in STFU"); wire_sync_write(MASTER_FD, take(msg)); return; } + if (skip_stfu && !is_stfu_active(peer)) { + msg = towire_channeld_splice_state_error(NULL, "Can't begin a" + " splice with" + " skip_stfu if not" + " already in STFU"); + wire_sync_write(MASTER_FD, take(msg)); + return; + } if (peer->splicing->mode) { msg = towire_channeld_splice_state_error(NULL, "Can't begin a" " splice while already" @@ -4137,16 +4239,74 @@ static void handle_splice_init(struct peer *peer, const u8 *inmsg) return; } - status_debug("Getting handle_splice_init psbt version %d", peer->splicing->current_psbt->version); + status_debug("Getting handle_splice_init psbt version %d", + peer->splicing->current_psbt->version); - peer->on_stfu_success = handle_splice_stfu_success; + if (skip_stfu) { + handle_splice_stfu_success(peer); + } else { + peer->on_stfu_success = handle_splice_stfu_success; + + /* First things first we must STFU the channel */ + peer->stfu_initiator = LOCAL; + peer->want_stfu = true; + maybe_send_stfu(peer); + } +} + +static void handle_stfu_req_success(struct peer *peer) +{ + struct amount_msat available_funds = peer->channel->view->owed[LOCAL]; + /* DTODO: Subtract reserve requirment from available_funds? */ + wire_sync_write(MASTER_FD, + take(towire_channeld_confirmed_stfu(NULL, + available_funds))); +} + +static void handle_stfu_req(struct peer *peer, const u8 *inmsg) +{ + u8 *msg; + + if (!fromwire_channeld_stfu(inmsg)) + master_badmsg(WIRE_CHANNELD_STFU, inmsg); + + if (peer->splicing) { + msg = towire_channeld_splice_state_error(NULL, "Can't start" + " stfu when a splice" + " is active"); + wire_sync_write(MASTER_FD, take(msg)); + return; + } + if (peer->want_stfu) { + msg = towire_channeld_splice_state_error(NULL, "Can't stfu" + " splice while waiting" + " for STFU."); + wire_sync_write(MASTER_FD, take(msg)); + return; + } + if (is_stfu_active(peer)) { + msg = towire_channeld_splice_state_error(NULL, "Can't stfu" + " splice while" + " currently in STFU"); + wire_sync_write(MASTER_FD, take(msg)); + return; + } + + peer->on_stfu_success = handle_stfu_req_success; - /* First things first we must STFU the channel */ peer->stfu_initiator = LOCAL; peer->want_stfu = true; maybe_send_stfu(peer); } +static void handle_abort_req(struct peer *peer, const u8 *inmsg) +{ + if (!fromwire_channeld_abort(inmsg)) + master_badmsg(WIRE_CHANNELD_ABORT, inmsg); + + splice_abort(peer, "requested by user"); +} + static void peer_in(struct peer *peer, const u8 *msg) { enum peer_wire type = fromwire_peektype(msg); @@ -4247,6 +4407,9 @@ static void peer_in(struct peer *peer, const u8 *msg) case WIRE_SPLICE_LOCKED: handle_peer_splice_locked(peer, msg); return; + case WIRE_TX_ABORT: + check_tx_abort(peer, msg); + return; case WIRE_INIT: case WIRE_OPEN_CHANNEL: case WIRE_ACCEPT_CHANNEL: @@ -4258,7 +4421,6 @@ static void peer_in(struct peer *peer, const u8 *msg) case WIRE_TX_ADD_OUTPUT: case WIRE_TX_REMOVE_OUTPUT: case WIRE_TX_COMPLETE: - case WIRE_TX_ABORT: case WIRE_OPEN_CHANNEL2: case WIRE_ACCEPT_CHANNEL2: case WIRE_TX_SIGNATURES: @@ -4893,7 +5055,6 @@ static void peer_reconnect(struct peer *peer, if (inflight && (remote_next_funding || local_next_funding)) { if (!remote_next_funding) { status_info("Resuming splice negotation."); - assume_stfu_mode(peer); resume_splice_negotiation(peer, false, true, @@ -4905,6 +5066,7 @@ static void peer_reconnect(struct peer *peer, assert(local_next_funding || inflight->remote_tx_sigs); status_info("Resuming splice negotation"); + /* If send & receive sigs we must assume stfu */ if (local_next_funding) assume_stfu_mode(peer); resume_splice_negotiation(peer, @@ -5706,6 +5868,12 @@ static void req_in(struct peer *peer, const u8 *msg) case WIRE_CHANNELD_SPLICE_SIGNED: splice_initiator_user_signed(peer, msg); return; + case WIRE_CHANNELD_STFU: + handle_stfu_req(peer, msg); + return; + case WIRE_CHANNELD_ABORT: + handle_abort_req(peer, msg); + return; case WIRE_CHANNELD_SPLICE_CONFIRMED_INIT: case WIRE_CHANNELD_SPLICE_CONFIRMED_SIGNED: case WIRE_CHANNELD_SPLICE_SENDING_SIGS: @@ -5716,6 +5884,7 @@ static void req_in(struct peer *peer, const u8 *msg) case WIRE_CHANNELD_SPLICE_FUNDING_ERROR: case WIRE_CHANNELD_SPLICE_ABORT: check_tx_abort(peer, msg); + case WIRE_CHANNELD_CONFIRMED_STFU: break; case WIRE_CHANNELD_DEV_REENABLE_COMMIT: if (peer->developer) { diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index c521901b03e2..592a8b65a6b9 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -210,6 +210,7 @@ msgdata,channeld_splice_init,psbt,wally_psbt, msgdata,channeld_splice_init,relative_amount,s64, msgdata,channeld_splice_init,feerate_per_kw,u32, msgdata,channeld_splice_init,force_feerate,bool, +msgdata,channeld_splice_init,skip_stfu,bool, # channeld->master: hello, I started a channel splice open msgtype,channeld_splice_confirmed_init,7205 @@ -223,6 +224,7 @@ msgdata,channeld_splice_update,psbt,wally_psbt, msgtype,channeld_splice_confirmed_update,7207 msgdata,channeld_splice_confirmed_update,psbt,wally_psbt, msgdata,channeld_splice_confirmed_update,commitments_secured,bool, +msgdata,channeld_splice_confirmed_update,signatures_secured,bool, # channeld->master: Lookup a transaction msgtype,channeld_splice_lookup_tx,7208 @@ -287,6 +289,16 @@ msgdata,channeld_splice_abort,did_i_initiate,bool, msgdata,channeld_splice_abort,inflight_outpoint,?bitcoin_outpoint, msgdata,channeld_splice_abort,reason,?wirestring, +# master->channeld: Please enter stfu mode +msgtype,channeld_stfu,7224 + +# channeld->master: Entered stfu result +msgtype,channeld_confirmed_stfu,7225 +msgdata,channeld_confirmed_stfu,available_funds,amount_msat, + +# master->channeld: Please enter perform tx_abort +msgtype,channeld_abort,7226 + # Tell peer to shut down channel. msgtype,channeld_send_shutdown,1023 msgdata,channeld_send_shutdown,final_index,?u32, diff --git a/channeld/splice.c b/channeld/splice.c index ffb3d5877390..3ef245f7d9ed 100644 --- a/channeld/splice.c +++ b/channeld/splice.c @@ -31,6 +31,8 @@ struct splicing *splicing_new(const tal_t *ctx) splicing->received_tx_complete = false; splicing->sent_tx_complete = false; splicing->tx_sig_msg = NULL; + splicing->inws = NULL; + splicing->their_sig = NULL; return splicing; } diff --git a/channeld/splice.h b/channeld/splice.h index 04b62cbb9485..eca46eb5c6c5 100644 --- a/channeld/splice.h +++ b/channeld/splice.h @@ -53,6 +53,10 @@ struct splicing { bool sent_tx_complete; /* If our peer signs early, we allow that and cache it here */ const u8 *tx_sig_msg; + /* The witness stack data received by peer */ + struct witness **inws; + /* Their channel funding signature */ + struct bitcoin_signature *their_sig; }; /* Sets `splice` items to default values */ diff --git a/cln-grpc/proto/node.proto b/cln-grpc/proto/node.proto index f085f8dbd091..7be003745017 100644 --- a/cln-grpc/proto/node.proto +++ b/cln-grpc/proto/node.proto @@ -2665,6 +2665,7 @@ message Splice_signedResponse { bytes tx = 1; bytes txid = 2; optional uint32 outnum = 3; + string psbt = 4; } message Splice_updateRequest { @@ -2675,6 +2676,7 @@ message Splice_updateRequest { message Splice_updateResponse { string psbt = 1; bool commitments_secured = 2; + optional bool signatures_secured = 3; } message UnreserveinputsRequest { diff --git a/cln-grpc/src/convert.rs b/cln-grpc/src/convert.rs index 80d4cfd52a62..4c8f8939141e 100644 --- a/cln-grpc/src/convert.rs +++ b/cln-grpc/src/convert.rs @@ -2505,6 +2505,7 @@ impl From for pb::SpliceSignedResponse { fn from(c: responses::Splice_signedResponse) -> Self { Self { outnum: c.outnum, // Rule #2 for type u32? + psbt: c.psbt, // Rule #2 for type string tx: hex::decode(&c.tx).unwrap(), // Rule #2 for type hex txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid } @@ -2517,6 +2518,7 @@ impl From for pb::SpliceUpdateResponse { Self { commitments_secured: c.commitments_secured, // Rule #2 for type boolean psbt: c.psbt, // Rule #2 for type string + signatures_secured: c.signatures_secured, // Rule #2 for type boolean? } } } diff --git a/cln-rpc/src/model.rs b/cln-rpc/src/model.rs index 2ae9fe0d7a8c..b83084f7d1b0 100644 --- a/cln-rpc/src/model.rs +++ b/cln-rpc/src/model.rs @@ -8505,6 +8505,7 @@ pub mod responses { pub struct Splice_signedResponse { #[serde(skip_serializing_if = "Option::is_none")] pub outnum: Option, + pub psbt: String, pub tx: String, pub txid: String, } @@ -8522,6 +8523,8 @@ pub mod responses { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Splice_updateResponse { + #[serde(skip_serializing_if = "Option::is_none")] + pub signatures_secured: Option, pub commitments_secured: bool, pub psbt: String, } diff --git a/common/Makefile b/common/Makefile index a594f91f3354..dec98e099b26 100644 --- a/common/Makefile +++ b/common/Makefile @@ -92,6 +92,7 @@ COMMON_SRC_NOGEN := \ common/setup.c \ common/shutdown_scriptpubkey.c \ common/sphinx.c \ + common/splice_script.c \ common/status.c \ common/status_levels.c \ common/status_wire.c \ diff --git a/common/addr.c b/common/addr.c index b1eae073e30a..e7ff17c3a486 100644 --- a/common/addr.c +++ b/common/addr.c @@ -36,3 +36,79 @@ char *encode_scriptpubkey_to_addr(const tal_t *ctx, return out; } + +static const char *segwit_addr_net_decode(int *witness_version, + uint8_t *witness_program, + size_t *witness_program_len, + const char *addrz, + const struct chainparams *chainparams) +{ + if (segwit_addr_decode(witness_version, witness_program, + witness_program_len, chainparams->onchain_hrp, + addrz)) + return chainparams->onchain_hrp; + else + return NULL; +} + +bool decode_scriptpubkey_from_addr(const tal_t *ctx, + const struct chainparams *chainparams, + const char *address, + u8 **scriptpubkey) +{ + struct bitcoin_address destination; + int witness_version; + /* segwit_addr_net_decode requires a buffer of size 40, and will + * not write to the buffer if the address is too long, so a buffer + * of fixed size 40 will not overflow. */ + uint8_t witness_program[40]; + size_t witness_program_len; + const char *bech32; + u8 addr_version; + + if (ripemd160_from_base58(&addr_version, &destination.addr, + address, strlen(address))) { + if (addr_version == chainparams->p2pkh_version) { + *scriptpubkey = scriptpubkey_p2pkh(ctx, &destination); + return true; + } else if (addr_version == chainparams->p2sh_version) { + *scriptpubkey = + scriptpubkey_p2sh_hash(ctx, &destination.addr); + return true; + } else { + return false; + } + /* Insert other parsers that accept pointer+len here. */ + return false; + } + + bech32 = segwit_addr_net_decode(&witness_version, witness_program, + &witness_program_len, address, + chainparams); + if (bech32) { + bool witness_ok; + + if (witness_version == 0) { + witness_ok = (witness_program_len == 20 || + witness_program_len == 32); + } else if (witness_version == 1) { + witness_ok = (witness_program_len == 32); + } else { + witness_ok = true; + } + + if (!witness_ok) + return false; + + if (!streq(bech32, chainparams->onchain_hrp)) + return false; + + *scriptpubkey = scriptpubkey_witness_raw(ctx, witness_version, + witness_program, + witness_program_len); + return true; + } + + /* Insert other parsers that accept null-terminated string here. */ + return false; +} diff --git a/common/addr.h b/common/addr.h index 1f8f0ffba9b7..7ab70f50158a 100644 --- a/common/addr.h +++ b/common/addr.h @@ -8,4 +8,9 @@ char *encode_scriptpubkey_to_addr(const tal_t *ctx, const struct chainparams *chainparams, const u8 *scriptpubkey); +bool decode_scriptpubkey_from_addr(const tal_t *ctx, + const struct chainparams *chainparams, + const char *address, + u8 **scriptpubkey); + #endif /* LIGHTNING_COMMON_ADDR_H */ diff --git a/common/channel_id.h b/common/channel_id.h index 1e1b3c4d5cee..8ca48628ad2b 100644 --- a/common/channel_id.h +++ b/common/channel_id.h @@ -43,4 +43,7 @@ char *fmt_channel_id(const tal_t *ctx, const struct channel_id *channel_id); void towire_channel_id(u8 **pptr, const struct channel_id *channel_id); bool fromwire_channel_id(const u8 **cursor, size_t *max, struct channel_id *channel_id); + +char *fmt_channel_id(const tal_t *ctx, const struct channel_id *channel_id); + #endif /* LIGHTNING_COMMON_CHANNEL_ID_H */ diff --git a/common/json_param.c b/common/json_param.c index 216451271803..4138144231ff 100644 --- a/common/json_param.c +++ b/common/json_param.c @@ -465,6 +465,22 @@ struct command_result *param_string(struct command *cmd, const char *name, return NULL; } +/* Extract a string or a json array */ +struct command_result *param_string_or_array(struct command *cmd, const char *name, + const char * buffer, const jsmntok_t *tok, + struct str_or_arr **result) +{ + *result = tal(cmd, struct str_or_arr); + (*result)->arr = NULL; + (*result)->str = NULL; + if (tok->type == JSMN_ARRAY) { + (*result)->arr = tok; + return NULL; + } + + return param_string(cmd, name, buffer, tok, &(*result)->str); +} + struct command_result *param_invstring(struct command *cmd, const char *name, const char * buffer, const jsmntok_t *tok, const char **str) diff --git a/common/json_param.h b/common/json_param.h index 07db22f3d2cf..cb06e080a537 100644 --- a/common/json_param.h +++ b/common/json_param.h @@ -198,6 +198,17 @@ struct command_result *param_string(struct command *cmd, const char *name, const char * buffer, const jsmntok_t *tok, const char **str); +struct str_or_arr +{ + const char *str; + const jsmntok_t *arr; +}; + +/* Extract a string or a json array */ +struct command_result *param_string_or_array(struct command *cmd, const char *name, + const char * buffer, const jsmntok_t *tok, + struct str_or_arr **result); + /* Extract an invoice string from a generic string, strip the `lightning:` * prefix from it if needed. */ struct command_result *param_invstring(struct command *cmd, const char *name, diff --git a/common/jsonrpc_errors.h b/common/jsonrpc_errors.h index 96a09da2365b..a701a9559afd 100644 --- a/common/jsonrpc_errors.h +++ b/common/jsonrpc_errors.h @@ -68,6 +68,7 @@ enum jsonrpc_errcode { FUNDING_UNKNOWN_CHANNEL = 311, FUNDING_STATE_INVALID = 312, FUND_CANNOT_AFFORD_WITH_EMERGENCY = 313, + FUND_INPUT_IS_ZERO = 314, /* Splice errors */ SPLICE_BROADCAST_FAIL = 350, diff --git a/common/psbt_open.c b/common/psbt_open.c index da05fc3973d0..42fe1e1808a6 100644 --- a/common/psbt_open.c +++ b/common/psbt_open.c @@ -4,10 +4,13 @@ #include #include #include +#include #include #include #include +#define MAX_CHANNEL_IDS 4096 + bool psbt_get_serial_id(const struct wally_map *map, u64 *serial_id) { size_t value_len; @@ -197,6 +200,56 @@ void psbt_sort_by_serial_id(struct wally_psbt *psbt) sort_outputs(psbt); } +bool psbt_get_channel_ids(const tal_t *ctx, + const struct wally_psbt *psbt, + struct channel_id **channel_ids) +{ + size_t value_len; + void *res = psbt_get_lightning(&psbt->unknowns, PSBT_TYPE_CHANNELIDS, + &value_len); + if (!res) + return false; + + /* Max channel id limit */ + if (value_len > MAX_CHANNEL_IDS * 32) + return false; + + /* Must be a multiple of 32 */ + if (value_len % 32) + return false; + + *channel_ids = tal_arr(ctx, struct channel_id, value_len / 32); + for (size_t i = 0; i < value_len / 32; i++) + memcpy((*channel_ids)[i].id, res + i * 32, 32); + + return true; +} + +void psbt_set_channel_ids(struct wally_psbt *psbt, + struct channel_id *channel_ids) +{ + BUILD_ASSERT(sizeof(channel_ids[0].id) == 32); + int data_size = tal_count(channel_ids) * 32; + u8 *data = tal_arr(tmpctx, u8, data_size); + + for (size_t i = 0; i < tal_count(channel_ids); i++) + memcpy(data + i * 32, channel_ids[i].id, 32); + + psbt_set_lightning(psbt, + &psbt->unknowns, + PSBT_TYPE_CHANNELIDS, + data, + data_size); +} + +/* psbt_set_channel_ids - Stores the channel_ids in the PSBT + * + * @psbt - the psbt to put the channel_ids into + * @channel_ids - the channel ids to put in + */ +void psbt_set_channel_ids(struct wally_psbt *psbt, + struct channel_id *channel_ids); + #define ADD(type, add_to, from, index) \ do { \ struct type##_set a; \ diff --git a/common/psbt_open.h b/common/psbt_open.h index be3c4995b46f..b3c74c92ad1f 100644 --- a/common/psbt_open.h +++ b/common/psbt_open.h @@ -36,6 +36,7 @@ struct psbt_changeset { #define PSBT_TYPE_SERIAL_ID 0x01 #define PSBT_TYPE_INPUT_MARKER 0x02 #define PSBT_TYPE_OUTPUT_EXTERNAL 0x04 +#define PSBT_TYPE_CHANNELIDS 0x08 /* The channel ids (used for splice resume) */ /* psbt_get_serial_id - Returns the serial_id from an unknowns map * @@ -55,6 +56,25 @@ WARN_UNUSED_RESULT bool psbt_get_serial_id(const struct wally_map *map, */ void psbt_sort_by_serial_id(struct wally_psbt *psbt); + +/* psbt_get_channel_ids - Returns the array of channel_ids stored in the PSBT + * + * @ctx - allocation context for returned changeset + * @psbt - psbt to search + * @channel_ids - result placed into this tal array + */ +WARN_UNUSED_RESULT bool psbt_get_channel_ids(const tal_t *ctx, + const struct wally_psbt *psbt, + struct channel_id **channel_ids); + +/* psbt_set_channel_ids - Stores the channel_ids in the PSBT + * + * @psbt - the psbt to put the channel_ids into + * @channel_ids - the channel ids to put in + */ +void psbt_set_channel_ids(struct wally_psbt *psbt, + struct channel_id *channel_ids); + /* psbt_get_changeset - Returns set of diffs btw orig + new psbt * * All inputs+outputs MUST have a serial_id field present before diff --git a/common/splice_script.c b/common/splice_script.c new file mode 100644 index 000000000000..afda5545d9bf --- /dev/null +++ b/common/splice_script.c @@ -0,0 +1,2824 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SCRIPT_DUMP_TOKENS 0 +#define SCRIPT_DUMP_SEGMENTS 0 + +#define ARROW_SYMBOL "->" +#define PIPE_SYMBOL '|' +#define AT_SYMBOL '@' +#define COLON_SYMBOL ':' +#define Q_SYMBOL '?' +#define WILD_SYMBOL '*' +#define PLUS_SYMBOL '+' +#define MINUS_SYMBOL '-' +#define FEE_SYMBOL "fee" + +#define PERCENT_REGEX "^([0-9]*)[.]?([0-9]*)%$" +#define Q_REGEX "^\\?$" +#define WILD_REGEX "^\\*$" +#define CHANID_REGEX "^[0-9A-Fa-f]{64}$" +#define NODEID_REGEX "^0[23][0-9A-Fa-f]{62}$" +#define WALLET_REGEX "^wallet$" +#define FEE_REGEX "^" FEE_SYMBOL "$" +#define SATM_REGEX "^([0-9]*)[.]?([0-9]*)[Mm]$" +#define SATK_REGEX "^([0-9]*)[.]?([0-9]*)[Kk]$" + +#define CODE_SNIPPET_PADDING 80 + +/* Minimum # of matching charaters to autocomplete nodeid or chanid */ +#define NODEID_MIN_CHARS 4 +#define CHANID_MIN_CHARS 4 + +/* Token types from simplest to most complex. */ +enum token_type { + TOK_CHAR, + TOK_DELIMITER, /* Newline or semicolon. Guaranteed one at end. */ + TOK_ARROW, + TOK_STR, + TOK_PIPE, /* lease separator "|", ex 5M|3M (add 5M, lease 3M) */ + TOK_COLON, /* node query separator ":", ex nodeid:0 */ + TOK_ATSYM, /* lease rate separator "@", ex 3M@2% */ + TOK_PLUS, + TOK_MINUS, + TOK_PERCENT, /* ie "80%" */ + TOK_SATS, /* ie 8M or 0 */ + TOK_QUESTION, /* ie "?" */ + TOK_WILDCARD, /* ie "*" */ + TOK_FEE, /* ie the word "fee" */ + TOK_CHANID, + TOK_WALLET, + TOK_FEERATE, /* The fee rate */ + TOK_NODEID, + TOK_BTCADDR, + TOK_CHANQUERY, /* ie nodeid:? */ + TOK_MULTI_CHANID, /* Matches stored in ->right */ + TOK_LEASEREQ, + TOK_LEASERATE, /* ie @2% */ + TOK_SEGMENT, /* An entire line or semicolon separated segment */ +}; + +#define TOKEN_FLAG_FEERATE_NEGATIVE 0x01 + +struct token { + enum token_type type; + size_t script_index; /* For error messages */ + char c; + char *str; + u32 ppm; + struct amount_sat amount_sat; + struct node_id *node_id; + struct channel_id *chan_id; + struct token *left, *middle, *right; + u32 flags; +}; + +static struct token *new_token(const tal_t *ctx, enum token_type token_type, + size_t script_index) +{ + struct token *token = tal(ctx, struct token); + + token->type = token_type; + token->script_index = script_index; + token->c = 0; + token->str = NULL; + token->ppm = 0; + token->amount_sat = AMOUNT_SAT(0); + token->node_id = NULL; + token->chan_id = NULL; + token->left = NULL; + token->middle = NULL; + token->right = NULL; + token->flags = 0; + + return token; +} + +#if SCRIPT_DUMP_TOKENS || SCRIPT_DUMP_SEGMENTS +static const char *token_type_str(enum token_type type) +{ + switch (type) { + case TOK_CHAR: return "TOK_CHAR"; + case TOK_DELIMITER: return "TOK_DELIMITER"; + case TOK_ARROW: return "TOK_ARROW"; + case TOK_STR: return "TOK_STR"; + case TOK_PIPE: return "TOK_PIPE"; + case TOK_ATSYM: return "TOK_ATSYM"; + case TOK_PLUS: return "TOK_PLUS"; + case TOK_MINUS: return "TOK_MINUS"; + case TOK_COLON: return "TOK_COLON"; + case TOK_SATS: return "TOK_SATS"; + case TOK_PERCENT: return "TOK_PERCENT"; + case TOK_QUESTION: return "TOK_QUESTION"; + case TOK_WILDCARD: return "TOK_WILDCARD"; + case TOK_FEE: return "TOK_FEE"; + case TOK_CHANID: return "TOK_CHANID"; + case TOK_WALLET: return "TOK_WALLET"; + case TOK_FEERATE: return "TOK_FEERATE"; + case TOK_NODEID: return "TOK_NODEID"; + case TOK_BTCADDR: return "TOK_BTCADDR"; + case TOK_CHANQUERY: return "TOK_CHANQUERY"; + case TOK_MULTI_CHANID: return "TOK_MULTI_CHANID"; + case TOK_LEASEREQ: return "TOK_LEASEREQ"; + case TOK_LEASERATE: return "TOK_LEASERATE"; + case TOK_SEGMENT: return "TOK_SEGMENT"; + } + + return NULL; +} + +static void dump_token_shallow(char **str, struct token *token, char *prefix) +{ + const char *tmp; + + tal_append_fmt(str, "%s%zu:%s", prefix, token->script_index, + token_type_str(token->type)); + + if (token->c) { + tal_append_fmt(str, " char:"); + if (token->c == '\n') + tal_append_fmt(str, "'\\n'"); + else if (token->c == '\r') + tal_append_fmt(str, "'\\r'"); + else if (token->c == '\t') + tal_append_fmt(str, "'\\t'"); + else if (token->c < ' ') + tal_append_fmt(str, "0x%02x", token->c); + else + tal_append_fmt(str, "'%c'", token->c); + } + + if (token->str) + tal_append_fmt(str, " str:\"%s\"", token->str); + + if (token->node_id) + tal_append_fmt(str, " node_id:%s", + fmt_node_id(tmpctx, token->node_id)); + + if (token->chan_id) + tal_append_fmt(str, " chan_id:%s", + tal_hexstr(tmpctx, token->chan_id, sizeof(struct channel_id))); + + if (token->ppm) + tal_append_fmt(str, " ppm:%u", token->ppm); + + if (!amount_sat_is_zero(token->amount_sat) || token->type == TOK_SATS) { + tmp = fmt_amount_sat(tmpctx, token->amount_sat); + tal_append_fmt(str, " amnt:%s", tmp); + tal_free(tmp); + } + + if (token->flags) + tal_append_fmt(str, " flags:%u", token->flags); +} +#endif /* SCRIPT_DUMP_TOKENS || SCRIPT_DUMP_SEGMENTS */ + +#if SCRIPT_DUMP_TOKENS +/* Returns the indent used */ +static int dump_token(char **str, struct token *token, int indent, char *prefix) +{ + if (token->left) + indent = dump_token(str, token->left, indent, "l ") + 1; + + for (int i = 0; i < indent; i++) + tal_append_fmt(str, " "); + + dump_token_shallow(str, token, prefix); + + tal_append_fmt(str, "\n"); + + if (token->middle) + dump_token(str, token->middle, indent, "m "); + + if (token->right) + dump_token(str, token->right, indent + 1, "r "); + + return indent; +} + +static struct splice_script_error *debug_dump(const tal_t *ctx, + struct token **tokens) +{ + struct splice_script_error *error = tal(ctx, + struct splice_script_error); + + error->type = DEBUG_DUMP; + error->script_index = 0; + error->message = tal_strdup(error, ""); + + for (size_t i = 0; i < tal_count(tokens); i++) + dump_token(&error->message, tokens[i], 0, "- "); + + return error; +} +#endif /* SCRIPT_DUMP_TOKENS */ + +#if SCRIPT_DUMP_SEGMENTS +static struct splice_script_error *dump_segments(const tal_t *ctx, + struct token **tokens) +{ + struct splice_script_error *error = tal(ctx, + struct splice_script_error); + + error->type = DEBUG_DUMP; + error->script_index = 0; + error->message = tal_strdup(error, ""); + + for (size_t i = 0; i < tal_count(tokens); i++) { + if (tokens[i]->type == TOK_SEGMENT) { + dump_token_shallow(&error->message, tokens[i]->left, + ""); + dump_token_shallow(&error->message, tokens[i]->middle, + " -> "); + if (tokens[i]->right) + dump_token_shallow(&error->message, + tokens[i]->right, " -> "); + } + else { + tal_append_fmt(&error->message, "Invalid token!! "); + dump_token_shallow(&error->message, tokens[i], ""); + } + tal_append_fmt(&error->message, "\n"); + } + + return error; +} +#endif /* SCRIPT_DUMP_SEGMENTS */ + +static struct splice_script_error *new_error_offset(const tal_t *ctx, + enum splice_script_error_type type, + struct token *token, + const char *phase, + int index_offset) +{ + struct splice_script_error *error = tal(ctx, struct splice_script_error); + + error->type = type; + error->script_index = token->script_index + index_offset; + error->message = tal_strdup(error, ""); + error->phase = phase; + + return error; +} + +static struct splice_script_error *new_error(const tal_t *ctx, + enum splice_script_error_type type, + struct token *token, + const char *phase) +{ + return new_error_offset(ctx, type, token, phase, 0); +} + +static char *context_snippet(const tal_t *ctx, + const char *script, + struct splice_script_error *error) +{ + const char *start = script + error->script_index; + const char *last = start; + const char *end = script + strlen(script); + char *str; + + for (size_t i = 0; i < CODE_SNIPPET_PADDING && start-1 >= script && start[-1] >= ' '; i++) + start--; + + for (size_t i = 0; i < CODE_SNIPPET_PADDING && last < end && last[0] >= ' '; i++) + last++; + + str = tal_strndup(ctx, start, last - start); + + tal_append_fmt(&str, "\n"); + + for (const char *ptr = start; ptr < script + error->script_index; ptr++) + tal_append_fmt(&str, " "); + + tal_append_fmt(&str, "^\n"); + + if (error->message && strlen(error->message)) + tal_append_fmt(&str, "%s\n", error->message); + + if (error->phase) + tal_append_fmt(&str, "Compiler phase: %s\n", error->phase); + + return str; +} + +char *fmt_splice_script_compiler_error(const tal_t *ctx, + const char *script, + struct splice_script_error *error) +{ + switch (error->type) { + case INTERNAL_ERROR: + return tal_fmt(ctx, "Internal error\n%s", + context_snippet(ctx, script, error)); + case INVALID_TOKEN: + return tal_fmt(ctx, "Invalid token error\n%s", + context_snippet(ctx, script, error)); + case DEBUG_DUMP: + return tal_fmt(ctx, "Token Dump:\n%s", error->message); + case TOO_MANY_PIPES: + return tal_fmt(ctx, "Too many '%c' symbols near here\n%s", + PIPE_SYMBOL, + context_snippet(ctx, script, error)); + case TOO_MANY_ATS: + return tal_fmt(ctx, "Too many '%c' symbols near here\n%s", + AT_SYMBOL, + context_snippet(ctx, script, error)); + case TOO_MANY_COLONS: + return tal_fmt(ctx, "Too many '%c' symbols near here\n%s", + COLON_SYMBOL, + context_snippet(ctx, script, error)); + case TOO_MANY_PLUS: + return tal_fmt(ctx, "Too many '%c' symbols near here\n%s", + PLUS_SYMBOL, + context_snippet(ctx, script, error)); + case TOO_MANY_MINUS: + return tal_fmt(ctx, "Too many '%c' symbols near here\n%s", + MINUS_SYMBOL, + context_snippet(ctx, script, error)); + case INVALID_NODEID: + return tal_fmt(ctx, "Invalid node id\n%s", + context_snippet(ctx, script, error)); + case INVALID_CHANID: + return tal_fmt(ctx, "Invalid channel id\n%s", + context_snippet(ctx, script, error)); + case WRONG_NUM_SEGMENT_CHUNKS: + return tal_fmt(ctx, "Segments must have one or two \"" + ARROW_SYMBOL "\" symbols\n%s", + context_snippet(ctx, script, error)); + case MISSING_ARROW: + return tal_fmt(ctx, "Segments elements must be separated by \"" + ARROW_SYMBOL "\" symbols\n%s", + context_snippet(ctx, script, error)); + case NO_MATCHING_NODES: + return tal_fmt(ctx, "No matching nodes for node query\n%s", + context_snippet(ctx, script, error)); + case INVALID_INDEX: + return tal_fmt(ctx, "Valid index must be only number digits" + " and no other characters\n%s", + context_snippet(ctx, script, error)); + case CHAN_INDEX_ON_WILDCARD_NODE: + return tal_fmt(ctx, "Node wildcard matches must use an index," + " '%c', or '%c' after the '%c'\n%s", + Q_SYMBOL, WILD_SYMBOL, COLON_SYMBOL, + context_snippet(ctx, script, error)); + case CHANQUERY_TYPEERROR: + return tal_fmt(ctx, "Channel query has invalid type(s)\n%s", + context_snippet(ctx, script, error)); + case CHAN_INDEX_NOT_FOUND: + return tal_fmt(ctx, "Channel index not found for node\n%s", + context_snippet(ctx, script, error)); + case NODE_ID_MULTIMATCH: + return tal_fmt(ctx, "Node id matched multiple nodes, specify" + " more characters to be more specific\n%s", + context_snippet(ctx, script, error)); + case NODE_ID_CHAN_OVERMATCH: + return tal_fmt(ctx, "Node id matched a channel id, specify" + " more characters to be more specific\n%s", + context_snippet(ctx, script, error)); + case CHAN_ID_MULTIMATCH: + return tal_fmt(ctx, "Channel id matched multiple channels," + " specify more characters to be more specific" + "\n%s", + context_snippet(ctx, script, error)); + case CHAN_ID_NODE_OVERMATCH: + return tal_fmt(ctx, "Channel id matched a node id, specify" + " more characters to be more specific\n%s", + context_snippet(ctx, script, error)); + case NODE_ID_NO_UNUSED: + return tal_fmt(ctx, "No unused channels for node id. Other" + " channel queries already claimed all channels" + "\n%s", + context_snippet(ctx, script, error)); + case DOUBLE_MIDDLE_OP: + return tal_fmt(ctx, "Duplicate channel or address equivalent." + " Each line must contain only one\n%s", + context_snippet(ctx, script, error)); + case MISSING_MIDDLE_OP: + return tal_fmt(ctx, "Missing channel or address equivalent." + " Each line must contain one\n%s", + context_snippet(ctx, script, error)); + case MISSING_AMOUNT_OP: + return tal_fmt(ctx, "Missing amount. An amount is required here" + "\n%s", + context_snippet(ctx, script, error)); + case MISSING_AMOUNT_OR_WILD_OP: + return tal_fmt(ctx, "Missing sat amount. A sat amount or '%c'" + " is required here\n%s", WILD_SYMBOL, + context_snippet(ctx, script, error)); + case CANNOT_PARSE_SAT_AMNT: + return tal_fmt(ctx, "Failed to parse sat amount\n%s", + context_snippet(ctx, script, error)); + case ZERO_AMOUNTS: + return tal_fmt(ctx, "Each line must specify a non-zero amount," + "lease request, or pay the onchain fee. This" + " line specifies none of these\n%s", + context_snippet(ctx, script, error)); + case IN_AND_OUT_AMOUNTS: + return tal_fmt(ctx, "Can't specify funds going into and out of" + " in the same segment\n%s", + context_snippet(ctx, script, error)); + case MISSING_PERCENT: + return tal_fmt(ctx, "A percentage value is required here (ie." + " 1.5%%)\n%s", + context_snippet(ctx, script, error)); + case LEASE_AMOUNT_ZERO: + return tal_fmt(ctx, "Lease specified without a non-zero amount." + " Must specify a non-zero amount.\n%s", + context_snippet(ctx, script, error)); + case CHANNEL_ID_UNRECOGNIZED: + return tal_fmt(ctx, "Channel id not one of our channels.\n%s", + context_snippet(ctx, script, error)); + case DUPLICATE_CHANID: + return tal_fmt(ctx, "Channel referenced on multiple lines. Each" + " channel id must appear only once.\n%s", + context_snippet(ctx, script, error)); + case INVALID_MIDDLE_OP: + return tal_fmt(ctx, "Unrecognized channel query. Must be" + " channel id query, bitcoin address, or" + " \"wallet\"\n%s", + context_snippet(ctx, script, error)); + case INSUFFICENT_FUNDS: + return tal_fmt(ctx, "Script as written has insufficent funds to" + " be completed\n%s", + context_snippet(ctx, script, error)); + case PERCENT_IS_ZERO: + return tal_fmt(ctx, "Percentage channel input will result in" + " zero\n%s", + context_snippet(ctx, script, error)); + case WILDCARD_IS_ZERO: + return tal_fmt(ctx, "Wildcard channel input will result in zero" + "\n%s", + context_snippet(ctx, script, error)); + case INVALID_PERCENT: + return tal_fmt(ctx, "Percentage value invalid. Percentages must" + " be in range 0%% to 100%%.\n%s", + context_snippet(ctx, script, error)); + case LEFT_PERCENT_OVER_100: + return tal_fmt(ctx, "Left operand percentage total out of" + " range. Left percentages must add up to 100%%" + " or less\n%s", + context_snippet(ctx, script, error)); + case LEFT_FEE_NOT_NEGATIVE: + return tal_fmt(ctx, "Fees on the left operand must be negative" + " as they subtract from the amount\n%s", + context_snippet(ctx, script, error)); + case RIGHT_FEE_NOT_POSITIVE: + return tal_fmt(ctx, "Fees on the right operand must be positive" + " as they pull out extra to cover the fee\n%s", + context_snippet(ctx, script, error)); + case MISSING_FEESTR: + return tal_fmt(ctx, "Must have \"%s\" token here\n%s", + FEE_SYMBOL, + context_snippet(ctx, script, error)); + case DUPLICATE_FEESTR: + return tal_fmt(ctx, "Duplicate \"%s\" token here. Only one" + " channel or location may pay the fee\n%s", + FEE_SYMBOL, + context_snippet(ctx, script, error)); + case TOO_MUCH_DECIMAL: + return tal_fmt(ctx, "Too many digits after the decimal. This" + " type does not support this many\n%s", + context_snippet(ctx, script, error)); + case INVALID_FEERATE: + return tal_fmt(ctx, "Valid feerate must be only number digits" + " and no other characters\n%s", + context_snippet(ctx, script, error)); + } + + return NULL; +} + +static bool is_whitespace(char c) +{ + return isspace(c); +} + +static struct splice_script_error *clean_whitespace(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, tal_count(input)); + size_t n = 0; + + for (size_t i = 0; i < tal_count(input); i++) + if (input[i]->type != TOK_CHAR || !is_whitespace(input[i]->c)) + tokens[n++] = tal_steal(tokens, input[i]); + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +/* Returns point in str that starts match of suffix. */ +static char *find_suffix(char *str, char *suffix) +{ + char *ptr; + + if (strlen(str) < strlen(suffix)) + return false; + + ptr = str + strlen(str) - strlen(suffix); + + if (streq(ptr, suffix)) + return ptr; + + return NULL; +} + +static struct splice_script_error *find_arrows_and_strs(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, tal_count(input)); + struct token *token = NULL; + size_t n = 0; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_DELIMITER: + if (token) + tokens[n++] = token; + token = NULL; + tokens[n++] = tal_steal(tokens, input[i]); + break; + case TOK_CHAR: + if (!token) { + token = new_token(tokens, TOK_STR, + input[i]->script_index); + token->str = tal_strdup(token, ""); + } + tal_append_fmt(&token->str, "%c", input[i]->c); + + if (find_suffix(token->str, ARROW_SYMBOL)) { + + /* Terminmate the string at the arrow */ + *find_suffix(token->str, ARROW_SYMBOL) = 0; + + if (*token->str) + tokens[n++] = token; + else + tal_free(token); + token = NULL; + + tokens[n++] = new_token(tokens, + TOK_ARROW, + input[i]->script_index); + } + break; + case TOK_ARROW: + case TOK_STR: + case TOK_PIPE: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_COLON: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASERATE: + case TOK_LEASEREQ: + case TOK_SEGMENT: + return new_error(ctx, INVALID_TOKEN, input[i], + "arrows"); + } + } + + /* Script should always end in a delimiter which NULLS token */ + assert(!token); + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static struct splice_script_error *process_top_separators(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, + tal_count(input) * 3); + char *split_point; + size_t script_index; + size_t n = 0; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + return new_error(ctx, INVALID_TOKEN, input[i], + "top_separators"); + case TOK_DELIMITER: + case TOK_ARROW: + tokens[n++] = tal_steal(tokens, input[i]); + break; + case TOK_STR: + if ((split_point = strchr(input[i]->str, + PIPE_SYMBOL))) { + if (split_point != strrchr(input[i]->str, + PIPE_SYMBOL)) + return new_error_offset(ctx, + TOO_MANY_PIPES, + input[i], + "top_separators", + split_point - input[i]->str); + + *split_point = 0; + tokens[n++] = tal_steal(tokens, input[i]); + + script_index = input[i]->script_index; + script_index += (split_point - input[i]->str); + + tokens[n++] = new_token(tokens, TOK_PIPE, + script_index); + + script_index++; + + tokens[n] = new_token(tokens, TOK_STR, + script_index); + tokens[n++]->str = split_point + 1; + + } else if ((split_point = strchr(input[i]->str, + COLON_SYMBOL))) { + if (split_point != strrchr(input[i]->str, + COLON_SYMBOL)) + return new_error_offset(ctx, + TOO_MANY_COLONS, + input[i], + "top_separators", + split_point - input[i]->str); + + *split_point = 0; + tokens[n++] = tal_steal(tokens, input[i]); + + script_index = input[i]->script_index; + script_index += (split_point - input[i]->str); + + tokens[n++] = new_token(tokens, TOK_COLON, + script_index); + + script_index++; + + tokens[n] = new_token(tokens, TOK_STR, + script_index); + tokens[n++]->str = split_point + 1; + } else { + tokens[n++] = tal_steal(tokens, input[i]); + } + break; + case TOK_PIPE: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_COLON: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASERATE: + case TOK_LEASEREQ: + case TOK_SEGMENT: + return new_error(ctx, INVALID_TOKEN, input[i], + "top_separators"); + } + } + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static struct splice_script_error *process_2nd_separators(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, + tal_count(input) * 3); + char *split_point; + size_t script_index; + size_t n = 0; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + return new_error(ctx, INVALID_TOKEN, input[i], + "2nd_separators"); + case TOK_DELIMITER: + case TOK_ARROW: + case TOK_PIPE: + case TOK_COLON: + tokens[n++] = tal_steal(tokens, input[i]); + break; + case TOK_STR: + if ((split_point = strchr(input[i]->str, + PLUS_SYMBOL))) { + if (split_point != strrchr(input[i]->str, + PLUS_SYMBOL)) + return new_error_offset(ctx, + TOO_MANY_PLUS, + input[i], + "2nd_separators", + split_point - input[i]->str); + + *split_point = 0; + tokens[n++] = tal_steal(tokens, input[i]); + + script_index = input[i]->script_index; + script_index += (split_point - input[i]->str); + + tokens[n++] = new_token(tokens, TOK_PLUS, + script_index); + + script_index++; + + tokens[n] = new_token(tokens, TOK_STR, + script_index); + tokens[n++]->str = split_point + 1; + } else if ((split_point = strchr(input[i]->str, + MINUS_SYMBOL))) { + if (split_point != strrchr(input[i]->str, + MINUS_SYMBOL)) + return new_error_offset(ctx, + TOO_MANY_MINUS, + input[i], + "2nd_separators", + split_point - input[i]->str); + + *split_point = 0; + tokens[n++] = tal_steal(tokens, input[i]); + + script_index = input[i]->script_index; + script_index += (split_point - input[i]->str); + + tokens[n++] = new_token(tokens, TOK_MINUS, + script_index); + + script_index++; + + tokens[n] = new_token(tokens, TOK_STR, + script_index); + tokens[n++]->str = split_point + 1; + } else { + tokens[n++] = tal_steal(tokens, input[i]); + } + break; + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASERATE: + case TOK_LEASEREQ: + case TOK_SEGMENT: + return new_error(ctx, INVALID_TOKEN, input[i], + "2nd_separators"); + } + } + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static struct splice_script_error *process_3rd_separators(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, + tal_count(input) * 3); + char *split_point; + size_t script_index; + size_t n = 0; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + return new_error(ctx, INVALID_TOKEN, input[i], + "3rd_separators"); + case TOK_DELIMITER: + case TOK_ARROW: + case TOK_PIPE: + case TOK_COLON: + case TOK_PLUS: + case TOK_MINUS: + tokens[n++] = tal_steal(tokens, input[i]); + break; + case TOK_STR: + if ((split_point = strchr(input[i]->str, + AT_SYMBOL))) { + if (split_point != strrchr(input[i]->str, + AT_SYMBOL)) + return new_error_offset(ctx, + TOO_MANY_ATS, + input[i], + "3rd_separators", + split_point - input[i]->str); + + *split_point = 0; + tokens[n++] = tal_steal(tokens, input[i]); + + script_index = input[i]->script_index; + script_index += (split_point - input[i]->str); + + tokens[n++] = new_token(tokens, TOK_ATSYM, + script_index); + + script_index++; + + tokens[n] = new_token(tokens, TOK_STR, + script_index); + tokens[n++]->str = split_point + 1; + } else { + tokens[n++] = tal_steal(tokens, input[i]); + } + break; + case TOK_ATSYM: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASERATE: + case TOK_LEASEREQ: + case TOK_SEGMENT: + return new_error(ctx, INVALID_TOKEN, input[i], + "3rd_separators"); + } + } + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static const char *segwit_addr_net_decode(int *witness_version, + uint8_t *witness_program, + size_t *witness_program_len, + const char *addrz, + const struct chainparams *chainparams) +{ + if (segwit_addr_decode(witness_version, witness_program, + witness_program_len, chainparams->onchain_hrp, + addrz)) + return chainparams->onchain_hrp; + else + return NULL; +} + +static bool is_bitcoin_address(const char *address) +{ + struct ripemd160 addr; + int witness_version; + /* segwit_addr_net_decode requires a buffer of size 40, and will + * not write to the buffer if the address is too long, so a buffer + * of fixed size 40 will not overflow. */ + uint8_t witness_program[40]; + size_t witness_program_len; + + const char *bech32; + + u8 addr_version; + + if (ripemd160_from_base58(&addr_version, &addr, + address, strlen(address))) { + if (addr_version == chainparams->p2pkh_version) { + return true; + } else if (addr_version == chainparams->p2sh_version) { + return true; + } + return false; + } + + bech32 = segwit_addr_net_decode(&witness_version, witness_program, + &witness_program_len, address, + chainparams); + if (bech32) { + bool witness_ok; + + /* Only V0 has restricted lengths of witness programs */ + if (witness_version == 0) { + witness_ok = (witness_program_len == 20 || + witness_program_len == 32); + } else if (witness_version == 1) { + witness_ok = (witness_program_len == 32); + } else { + witness_ok = true; + } + + if (!witness_ok) + return false; + + return true; + } + + return false; +} + +/* Checks token->str for a short node id and auto completes it. */ +static bool autocomplete_node_id(struct token *token, + struct splice_script_chan **channels, + bool *multiple_nodes, + bool *chan_id_overmatch) +{ + struct node_id *match; + struct node_id candidate; + size_t len = strlen(token->str) / 2; + + *multiple_nodes = false; + *chan_id_overmatch = false; + + if (strlen(token->str) < NODEID_MIN_CHARS) + return false; + if (len > PUBKEY_CMPR_LEN) + return false; + if (!hex_decode(token->str, len * 2, + candidate.k, len)) + return false; + + match = NULL; + for (size_t i = 0; i < tal_count(channels); i++) { + if (len <= sizeof(channels[i]->node_id.k) + && memeq(candidate.k, len, channels[i]->node_id.k, len)) { + /* must not match multiple node ids */ + if (match && !node_id_eq(match, &channels[i]->node_id)) { + *multiple_nodes = true; + return true; + } + match = &channels[i]->node_id; + } + /* nodeid query must *not* match any channel ids */ + if (len <= sizeof(channels[i]->chan_id.id) + && memeq(candidate.k, len, channels[i]->chan_id.id, len)) + *chan_id_overmatch = true; + } + + if (!match) + return false; + + assert(!token->node_id); + token->node_id = tal_dup(token, struct node_id, match); + + return true; +} + +static bool autocomplete_chan_id(struct token *token, + struct splice_script_chan **channels, + bool *multiple_chans, + bool *node_id_overmatch) +{ + struct channel_id *match; + struct channel_id candidate; + size_t len = strlen(token->str) / 2; + + *multiple_chans = false; + *node_id_overmatch = false; + + if (strlen(token->str) < NODEID_MIN_CHARS) + return false; + if (len > PUBKEY_CMPR_LEN) + return false; + if (!hex_decode(token->str, len * 2, + candidate.id, len)) + return false; + + match = NULL; + for (size_t i = 0; i < tal_count(channels); i++) { + if (len <= sizeof(channels[i]->chan_id.id) + && memeq(candidate.id, len, channels[i]->chan_id.id, len)) { + /* must not match multiple channel ids */ + if (match && !channel_id_eq(match, &channels[i]->chan_id)) { + *multiple_chans = true; + return true; + } + match = &channels[i]->chan_id; + } + /* nodeid query must *not* match any node ids */ + if (len <= sizeof(channels[i]->node_id.k) + && memeq(candidate.id, len, channels[i]->node_id.k, len)) + *node_id_overmatch = true; + } + + if (!match) + return false; + + assert(!token->chan_id); + token->chan_id = tal_dup(token, struct channel_id, match); + + return true; +} + +static struct splice_script_error *type_data(const tal_t *ctx, + struct splice_script_chan **channels, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, tal_count(input)); + char *whole, *decimal; + char *sat_candidate; + struct amount_sat amount_sat; + bool multiple = false; + bool overmatch = false; + size_t n = 0; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + return new_error(ctx, INVALID_TOKEN, input[i], + "type_data"); + case TOK_DELIMITER: + case TOK_ARROW: + case TOK_PIPE: + case TOK_COLON: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + tokens[n++] = tal_steal(tokens, input[i]); + break; + case TOK_STR: + if (tal_strreg(ctx, input[i]->str, PERCENT_REGEX, + &whole, &decimal)) { + if (atoll(whole) < 0 || atoll(decimal) < 0) + return new_error(ctx, INVALID_PERCENT, + input[i], + "type_data"); + while (strlen(decimal) < 4) + tal_append_fmt(&decimal, "0"); + if (decimal[4]) + return new_error(ctx, TOO_MUCH_DECIMAL, + input[i], + "type_data"); + + input[i]->ppm = (u32)(10000 * atoll(whole) + + atoll(decimal)); + input[i]->type = TOK_PERCENT; + if (input[i]->ppm > 1000000) + return new_error(ctx, INVALID_PERCENT, + input[i], + "type_data"); + } else if (tal_strreg(ctx, input[i]->str, Q_REGEX)) { + input[i]->type = TOK_QUESTION; + } else if (tal_strreg(ctx, input[i]->str, WILD_REGEX)) { + input[i]->type = TOK_WILDCARD; + } else if (tal_strreg(ctx, input[i]->str, + NODEID_REGEX)) { + input[i]->type = TOK_NODEID; + input[i]->node_id = tal(input[i], + struct node_id); + if (!node_id_from_hexstr(input[i]->str, + strlen(input[i]->str), + input[i]->node_id)) + return new_error(ctx, INVALID_NODEID, + input[i], + "type_data"); + /* Rare corner case where channel begins with + * prefix of 02 or 03 */ + if (autocomplete_chan_id(input[i], channels, + &multiple, + &overmatch)) { + if (multiple) + return new_error(ctx, + CHAN_ID_MULTIMATCH, + input[i], + "type_data"); + if (overmatch) + return new_error(ctx, + CHAN_ID_NODE_OVERMATCH, + input[i], + "type_data"); + input[i]->type = TOK_CHANID; + input[i]->node_id = tal_free(input[i]->node_id); + } + } else if (is_bitcoin_address(input[i]->str)) { + input[i]->type = TOK_BTCADDR; + } else if (tal_strreg(ctx, input[i]->str, + CHANID_REGEX)) { + input[i]->type = TOK_CHANID; + input[i]->chan_id = tal(input[i], + struct channel_id); + if (!hex_decode(input[i]->str, + strlen(input[i]->str), + input[i]->chan_id, + 32)) + return new_error(ctx, INVALID_CHANID, + input[i], + "type_data"); + } else if (tal_strreg(ctx, input[i]->str, + WALLET_REGEX)) { + input[i]->type = TOK_WALLET; + } else if (tal_strreg(ctx, input[i]->str, FEE_REGEX)) { + input[i]->type = TOK_FEE; + } else if (autocomplete_node_id(input[i], channels, + &multiple, + &overmatch)) { + if (multiple) + return new_error(ctx, + NODE_ID_MULTIMATCH, + input[i], + "type_data"); + + if (overmatch) + return new_error(ctx, + NODE_ID_CHAN_OVERMATCH, + input[i], + "type_data"); + input[i]->type = TOK_NODEID; + } else if (autocomplete_chan_id(input[i], channels, + &multiple, + &overmatch)) { + if (multiple) + return new_error(ctx, + CHAN_ID_MULTIMATCH, + input[i], + "type_data"); + + if (overmatch) + return new_error(ctx, + CHAN_ID_NODE_OVERMATCH, + input[i], + "type_data"); + input[i]->type = TOK_CHANID; + } else { + + /* Parse shorthand sat formats */ + sat_candidate = input[i]->str; + + if (tal_strreg(ctx, sat_candidate, SATM_REGEX, + &whole, &decimal)) { + while (strlen(decimal) < 6) + tal_append_fmt(&decimal, "0"); + if (decimal[6]) + return new_error(ctx, + TOO_MUCH_DECIMAL, + input[i], + "type_data"); + + sat_candidate = tal_fmt(input[i], + "%"PRIu64, + (u64)(1000000 * atoll(whole) + + atoll(decimal))); + } else if (tal_strreg(ctx, sat_candidate, SATK_REGEX, + &whole, &decimal)) { + while (strlen(decimal) < 3) + tal_append_fmt(&decimal, "0"); + if (decimal[3]) + return new_error(ctx, + TOO_MUCH_DECIMAL, + input[i], + "type_data"); + + sat_candidate = tal_fmt(input[i], + "%"PRIu64, + (u64)(1000 * atoll(whole) + + atoll(decimal))); + } + + if (parse_amount_sat(&amount_sat, sat_candidate, + strlen(sat_candidate))) { + input[i]->type = TOK_SATS; + input[i]->amount_sat = amount_sat; + } else if(!sat_candidate || !strlen(sat_candidate)) { + input[i]->type = TOK_SATS; + input[i]->amount_sat = AMOUNT_SAT(0); + } else { + return new_error(ctx, + CANNOT_PARSE_SAT_AMNT, + input[i], + "type_data"); + } + + if (sat_candidate != input[i]->str) + tal_free(sat_candidate); + } + + tokens[n++] = tal_steal(tokens, input[i]); + break; + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASERATE: + case TOK_LEASEREQ: + case TOK_SEGMENT: + return new_error(ctx, INVALID_TOKEN, input[i], + "type_data"); + } + } + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static struct splice_script_error *compress_top_operands(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, tal_count(input)); + size_t n = 0; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + return new_error(ctx, INVALID_TOKEN, input[i], + "operands"); + case TOK_DELIMITER: + case TOK_ARROW: + case TOK_PIPE: + case TOK_STR: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_PLUS: + case TOK_MINUS: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_NODEID: + case TOK_BTCADDR: + tokens[n++] = tal_steal(tokens, input[i]); + break; + case TOK_ATSYM: + if (!n || i + 1 >= tal_count(input)) + return new_error(ctx, INVALID_TOKEN, input[i], + "operands"); + input[i]->type = tokens[n-1]->type == TOK_FEE + ? TOK_FEERATE + : TOK_LEASERATE; + input[i]->right = tal_steal(input[i], input[i+1]); + tokens[n-1]->right = tal_steal(tokens[n-1], input[i]); + i++; + break; + case TOK_COLON: + if (!n || i + 1 >= tal_count(input)) + return new_error(ctx, INVALID_TOKEN, input[i], + "operands"); + input[i]->type = TOK_CHANQUERY; + input[i]->left = tal_steal(input[i], tokens[n-1]); + input[i]->right = tal_steal(input[i], input[i+1]); + tokens[n-1] = tal_steal(tokens, input[i]); + i++; + break; + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_FEERATE: + case TOK_LEASERATE: + case TOK_LEASEREQ: + case TOK_SEGMENT: + return new_error(ctx, INVALID_TOKEN, input[i], + "operands"); + } + } + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static struct splice_script_error *compress_2nd_operands(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, tal_count(input)); + size_t n = 0; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + case TOK_ATSYM: + case TOK_COLON: + return new_error(ctx, INVALID_TOKEN, input[i], + "2nd_operands"); + case TOK_DELIMITER: + case TOK_ARROW: + case TOK_STR: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASERATE: + tokens[n++] = tal_steal(tokens, input[i]); + break; + case TOK_MINUS: + case TOK_PLUS: + if (i + 1 >= tal_count(input) + || input[i+1]->type != TOK_FEE) + return new_error(ctx, MISSING_FEESTR, input[i], + "2nd_operands"); + + /* This token is consumed. If negative, add flag to next + * token */ + if (input[i]->type == TOK_MINUS) + input[i+1]->flags |= TOKEN_FLAG_FEERATE_NEGATIVE; + break; + case TOK_FEE: + if (!n) + return new_error(ctx, INVALID_TOKEN, input[i], + "2nd_operands"); + + /* We put FEE on the middle spot of the amount */ + tokens[n-1]->middle = tal_steal(tokens[n-1], input[i]); + break; + case TOK_PIPE: + if (!n || i + 1 >= tal_count(input)) + return new_error(ctx, INVALID_TOKEN, input[i], + "2nd_operands"); + input[i]->type = TOK_LEASEREQ; + input[i]->right = tal_steal(input[i], input[i+1]); + + /* We put LEASEREQ on the right spot of the amount */ + tokens[n-1]->right = tal_steal(tokens[n-1], input[i]); + i++; + break; + case TOK_LEASEREQ: + case TOK_SEGMENT: + return new_error(ctx, INVALID_TOKEN, input[i], + "2nd_operands"); + } + } + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static bool matches_chan_id(struct token *token, struct channel_id chan_id) +{ + if (token->chan_id && channel_id_eq(token->chan_id, &chan_id)) + return true; + + if (token->left && matches_chan_id(token->left, chan_id)) + return true; + + if (token->middle && matches_chan_id(token->middle, chan_id)) + return true; + + if (token->right && matches_chan_id(token->right, chan_id)) + return true; + + return false; +} + +/* Searches through both tokensA and tokensB. */ +static struct node_id *first_node_with_unused_chan(const tal_t *ctx, + struct splice_script_chan **channels, + struct token **tokensA, + size_t a_size, + struct token **tokensB, + size_t b_size) +{ + for (size_t i = 0; i < tal_count(channels); i++) { + bool used = false; + for (size_t j = 0; j < a_size; j++) + if (matches_chan_id(tokensA[j], channels[i]->chan_id)) + used = true; + for (size_t k = 0; k < b_size; k++) + if (matches_chan_id(tokensB[k], channels[i]->chan_id)) + used = true; + if (!used) + return tal_dup(ctx, struct node_id, + &channels[i]->node_id); + } + + return NULL; +} + +static struct channel_id *chan_for_node_index(const tal_t *ctx, + struct splice_script_chan **channels, + struct node_id node_id, + size_t channel_index) +{ + for (size_t i = 0; i < tal_count(channels); i++) + if (node_id_eq(&node_id, &channels[i]->node_id)) + if (channel_index-- == 0) + return tal_dup(ctx, struct channel_id, + &channels[i]->chan_id); + return NULL; +} + +static struct channel_id **unused_chans(const tal_t *ctx, + struct splice_script_chan **channels, + struct token **tokensA, + size_t a_size, + struct token **tokensB, + size_t b_size) +{ + struct channel_id **result = tal_arr(ctx, struct channel_id*, 0); + + for (size_t i = 0; i < tal_count(channels); i++) { + bool used = false; + for (size_t j = 0; j < a_size; j++) + if (matches_chan_id(tokensA[j], channels[i]->chan_id)) + used = true; + for (size_t k = 0; k < b_size; k++) + if (matches_chan_id(tokensB[k], channels[i]->chan_id)) + used = true; + if (!used) + tal_arr_expand(&result, tal_dup(result, + struct channel_id, + &channels[i]->chan_id)); + } + + if (!tal_count(result)) + result = tal_free(result); + + return result; +} + +static struct channel_id **unused_chans_for_node(const tal_t *ctx, + struct splice_script_chan **channels, + struct token **tokensA, + size_t a_size, + struct token **tokensB, + size_t b_size, + struct node_id node_id) +{ + struct channel_id **result = tal_arr(ctx, struct channel_id*, 0); + + for (size_t i = 0; i < tal_count(channels); i++) { + bool used = false; + if (!node_id_eq(&node_id, &channels[i]->node_id)) + continue; + for (size_t j = 0; j < a_size; j++) + if (matches_chan_id(tokensA[j], channels[i]->chan_id)) + used = true; + for (size_t k = 0; k < b_size; k++) + if (matches_chan_id(tokensB[k], channels[i]->chan_id)) + used = true; + if (!used) + tal_arr_expand(&result, tal_dup(result, + struct channel_id, + &channels[i]->chan_id)); + } + + if (!tal_count(result)) + result = tal_free(result); + + return result; +} + +static bool parse_channel_index(struct token *token, size_t *channel_index) +{ + long long result; + char *endptr; + if (!token->str || !strlen(token->str)) + return false; + + errno = 0; + result = strtoll(token->str, &endptr, 10); + if (errno || *endptr) + return false; + + *channel_index = result; + return true; +} + +static bool parse_feerate(struct token *token, u32 *feerate) +{ + long long result; + char *endptr; + if (!token->str) + return false; + + /* zero length feerate is valid and implies 0 */ + if (0 == strlen(token->str)) { + *feerate = 0; + return true; + } + + /* If no feerate was found, str wont contain feerate */ + if (0 == strcmp(token->str, FEE_SYMBOL)) { + *feerate = 0; + return true; + } + + errno = 0; + result = strtoll(token->str, &endptr, 10); + if (errno || *endptr) + return false; + + *feerate = result; + return true; +} + +static struct splice_script_error *resolve_channel_ids(const tal_t *ctx, + struct splice_script_chan **channels, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, tal_count(input)); + struct node_id *node_id; + struct channel_id *chan_id; + struct channel_id **chan_ids; + struct token *token_itr; + size_t channel_index; + size_t n = 0; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_COLON: + case TOK_PIPE: + case TOK_STR: + case TOK_FEE: + return new_error(ctx, INVALID_TOKEN, input[i], + "resolve_channel_ids"); + case TOK_LEASERATE: + case TOK_ARROW: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_LEASEREQ: + case TOK_DELIMITER: + tokens[n++] = tal_steal(tokens, input[i]); + break; + case TOK_CHANQUERY: + if (!input[i]->left || !input[i]->right) + return new_error(ctx, INVALID_TOKEN, input[i], + "resolve_channel_ids"); + + /* If user specifies *:? it is same as ?:? */ + if (input[i]->left->type == TOK_WILDCARD + && input[i]->right->type == TOK_QUESTION) + input[i]->left->type = TOK_QUESTION; + + /* If user specifies *:# it is same as ?:# */ + if (input[i]->left->type == TOK_WILDCARD + && input[i]->right->type == TOK_SATS) + input[i]->left->type = TOK_QUESTION; + + if (input[i]->left->type == TOK_QUESTION) { + node_id = first_node_with_unused_chan(ctx, + channels, + input, + tal_count(input), + tokens, + n); + if (!node_id) + return new_error(ctx, NO_MATCHING_NODES, + input[i], + "resolve_channel_ids"); + input[i]->left->type = TOK_NODEID; + input[i]->left->node_id = tal_steal(input[i]->left, + node_id); + } + + if (input[i]->left->type == TOK_NODEID + && input[i]->right->type == TOK_SATS) { + if (!parse_channel_index(input[i]->right, + &channel_index)) + return new_error(ctx, INVALID_INDEX, + input[i], + "resolve_channel_ids"); + chan_id = chan_for_node_index(ctx, channels, + *input[i]->left->node_id, + channel_index); + if (!chan_id) + return new_error(ctx, + CHAN_INDEX_NOT_FOUND, + input[i], + "resolve_channel_ids"); + input[i]->type = TOK_CHANID; + input[i]->chan_id = tal_steal(input[i], + chan_id); + input[i]->left = tal_free(input[i]->left); + input[i]->right = tal_free(input[i]->right); + tokens[n++] = tal_steal(tokens, input[i]); + + } else if (input[i]->left->type == TOK_NODEID) { + chan_ids = unused_chans_for_node(ctx, channels, + input, + tal_count(input), + tokens, n, + *input[i]->left->node_id); + if (!tal_count(chan_ids)) + return new_error(ctx, NODE_ID_NO_UNUSED, + input[i], + "resolve_channel_ids"); + if (input[i]->right->type == TOK_QUESTION) { + input[i]->type = TOK_CHANID; + input[i]->chan_id = tal_steal(input[i], + chan_ids[0]); + tokens[n++] = tal_steal(tokens, + input[i]); + } else if (input[i]->right->type == TOK_WILDCARD) { + input[i]->type = TOK_MULTI_CHANID; + token_itr = input[i]; + input[i]->right = tal_free(input[i]->right); + for (size_t j = 0; j < tal_count(chan_ids); j++) { + token_itr->right = new_token(token_itr, + TOK_CHANID, + token_itr->script_index); + token_itr->right->chan_id = tal_dup(token_itr->right, + struct channel_id, + chan_ids[j]); + token_itr = token_itr->right; + } + tokens[n++] = tal_steal(tokens, input[i]); + } else { + return new_error(ctx, + CHAN_INDEX_ON_WILDCARD_NODE, + input[i], + "resolve_channel_ids"); + } + tal_free(chan_ids); + + } else if (input[i]->left->type == TOK_WILDCARD) { + if (input[i]->right->type != TOK_WILDCARD) + return new_error(ctx, + CHAN_INDEX_ON_WILDCARD_NODE, + input[i], + "resolve_channel_ids"); + chan_ids = unused_chans(ctx, channels, + input, + tal_count(input), + tokens, n); + input[i]->type = TOK_MULTI_CHANID; + input[i]->right = tal_free(input[i]->right); + token_itr = input[i]; + for (size_t j = 0; j < tal_count(chan_ids); j++) { + token_itr->right = new_token(token_itr, + TOK_CHANID, + token_itr->script_index); + token_itr->right->chan_id = tal_dup(token_itr->right, + struct channel_id, + chan_ids[j]); + token_itr = token_itr->right; + } + tokens[n++] = tal_steal(tokens, input[i]); + tal_free(chan_ids); + } else { + return new_error(ctx, + CHANQUERY_TYPEERROR, + input[i], + "resolve_channel_ids"); + } + break; + case TOK_SEGMENT: + case TOK_MULTI_CHANID: + return new_error(ctx, INVALID_TOKEN, input[i], + "resolve_channel_ids"); + } + } + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static bool is_valid_middle(struct token *token) +{ + switch(token->type) { + case TOK_CHANID: + if (!token->chan_id) + return false; + return true; + case TOK_MULTI_CHANID: + case TOK_BTCADDR: + case TOK_WALLET: + return true; + case TOK_FEERATE: + case TOK_CHAR: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_COLON: + case TOK_LEASERATE: + case TOK_ARROW: + case TOK_PIPE: + case TOK_STR: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_NODEID: + case TOK_CHANQUERY: + case TOK_LEASEREQ: + case TOK_DELIMITER: + case TOK_SEGMENT: + return false; + } + + return false; +} + +static struct splice_script_error *make_segments(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, tal_count(input)); + size_t n = 0; + size_t next_consumable = 0; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_FEE: + case TOK_COLON: + case TOK_LEASERATE: + case TOK_STR: + case TOK_CHANQUERY: + return new_error(ctx, INVALID_TOKEN, input[i], + "segments"); + case TOK_ARROW: + case TOK_PIPE: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_MULTI_CHANID: + case TOK_LEASEREQ: + break; + case TOK_DELIMITER: + if (i == 0 || input[i-1]->type == TOK_SEGMENT + || input[i-1]->type == TOK_DELIMITER) { + next_consumable = i+1; + break; + } + if (i - next_consumable == 3) { + if (input[next_consumable+1]->type != TOK_ARROW) + return new_error(ctx, MISSING_ARROW, + input[next_consumable+1], + "segments"); + input[i]->type = TOK_SEGMENT; + input[i]->left = tal_steal(input[i], + input[next_consumable]); + input[i]->middle = tal_steal(input[i], + input[next_consumable+2]); + tokens[n++] = tal_steal(tokens, input[i]); + next_consumable = i+1; + } + else if (i - next_consumable == 5) { + if (input[next_consumable+1]->type != TOK_ARROW) + return new_error(ctx, MISSING_ARROW, + input[next_consumable+1], + "segments"); + if (input[next_consumable+3]->type != TOK_ARROW) + return new_error(ctx, MISSING_ARROW, + input[next_consumable+3], + "segments"); + input[i]->type = TOK_SEGMENT; + input[i]->left = tal_steal(input[i], + input[next_consumable]); + input[i]->middle = tal_steal(input[i], + input[next_consumable+2]); + input[i]->right = tal_steal(input[i], + input[next_consumable+4]); + tokens[n++] = tal_steal(tokens, input[i]); + next_consumable = i+1; + } + else { + return new_error(ctx, WRONG_NUM_SEGMENT_CHUNKS, + input[i], "segments"); + } + + /* Move middle OP to middle and validate */ + if (!tokens[n-1]->right) { + if (is_valid_middle(tokens[n-1]->left)) { + if (is_valid_middle(tokens[n-1]->middle)) + return new_error(ctx, + DOUBLE_MIDDLE_OP, + tokens[n-1]->middle, + "make_segments"); + tokens[n-1]->right = tokens[n-1]->middle; + tokens[n-1]->middle = tokens[n-1]->left; + tokens[n-1]->left = new_token(tokens[n-1], + TOK_SATS, + tokens[n-1]->script_index); + tokens[n-1]->left->amount_sat = AMOUNT_SAT(0); + + } else if (is_valid_middle(tokens[n-1]->middle)) { + tokens[n-1]->right = new_token(tokens[n-1], + TOK_SATS, + tokens[n-1]->script_index); + tokens[n-1]->right->amount_sat = AMOUNT_SAT(0); + } else { + return new_error(ctx, MISSING_MIDDLE_OP, + tokens[n-1]->middle, + "make_segments"); + } + } + if (tokens[n-1]->left->type == TOK_STR + && !strlen(tokens[n-1]->left->str)) { + tokens[n-1]->left->type = TOK_SATS; + tokens[n-1]->left->amount_sat = AMOUNT_SAT(0); + } + if (tokens[n-1]->right->type == TOK_STR + && !strlen(tokens[n-1]->right->str)) { + tokens[n-1]->right->type = TOK_SATS; + tokens[n-1]->right->amount_sat = AMOUNT_SAT(0); + } + break; + case TOK_SEGMENT: + return new_error(ctx, INVALID_TOKEN, input[i], + "segments"); + } + } + + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static void steal_sub_tokens(const tal_t *ctx, struct token *token) +{ + tal_steal(token, token->left); + tal_steal(token, token->middle); + tal_steal(token, token->right); +} + +static struct splice_script_error *expand_multichans(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, 0); + struct token *token_itr; + struct token *token; + size_t chan_count; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_COLON: + case TOK_LEASERATE: + case TOK_ARROW: + case TOK_PIPE: + case TOK_STR: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASEREQ: + case TOK_DELIMITER: + return new_error(ctx, INVALID_TOKEN, input[i], + "expand_multichans"); + case TOK_SEGMENT: + if (input[i]->middle->type == TOK_MULTI_CHANID) { + token_itr = input[i]->middle->right; + /* First we count how many chan_ids */ + chan_count = 0; + while (token_itr) { + chan_count++; + token_itr = token_itr->right; + } + /* Now we loop through each chan_id */ + token_itr = input[i]->middle->right; + while (token_itr) { + /* Duplicate the SEGMENT token */ + token = tal_dup(tokens, struct token, + input[i]); + token->left = tal_dup(token, + struct token, + token->left); + token->right = tal_dup(token, + struct token, + token->right); + /* token_itr is already a CHANID */ + token->middle = tal_steal(token, + token_itr); + + steal_sub_tokens(token->left, + token->left); + steal_sub_tokens(token->middle, + token->middle); + steal_sub_tokens(token->right, + token->right); + + /* Divide percentage between chans */ + if (input[i]->left->type == TOK_PERCENT) { + token->left->ppm = input[i]->left->ppm / chan_count; + } + + /* Add modified copy to token array */ + tal_arr_expand(&tokens, token); + + token_itr = token_itr->right; + + /* Any remainder points to go the last + * destination in script */ + if (!token_itr) + token->left->ppm += input[i]->left->ppm % chan_count; + } + } else { + tal_arr_expand(&tokens, + tal_steal(tokens, input[i])); + } + break; + } + } + + tal_free(input); + *tokens_inout = tokens; + return NULL; +} + +static bool is_valid_amount(struct token *token) +{ + switch(token->type) { + case TOK_SATS: + case TOK_WILDCARD: + case TOK_PERCENT: + return true; + case TOK_FEE: + case TOK_CHAR: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_COLON: + case TOK_LEASERATE: + case TOK_ARROW: + case TOK_PIPE: + case TOK_STR: + case TOK_QUESTION: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASEREQ: + case TOK_DELIMITER: + case TOK_SEGMENT: + return false; + } + + return false; +} + +static bool is_valid_nonzero_amount(struct token *token) +{ + if (token->type == TOK_SATS && amount_sat_is_zero(token->amount_sat)) + return false; + + return is_valid_amount(token); +} + +static bool valid_channel_id(struct channel_id *chan_id, + struct splice_script_chan **channels) +{ + for (size_t i = 0; i < tal_count(channels); i++) + if (channel_id_eq(chan_id, &channels[i]->chan_id)) + return true; + + return false; +} + +static struct splice_script_error *validate_and_clean(const tal_t *ctx, + struct splice_script_chan **channels, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens = tal_arr(ctx, struct token *, tal_count(input)); + size_t n = 0; + struct channel_id *chan_ids = tal_arr(ctx, struct channel_id, 0); + struct token *lease, *leaserate, *fee, *feerate; + bool pay_fee_found = false; + + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_COLON: + case TOK_LEASERATE: + case TOK_ARROW: + case TOK_PIPE: + case TOK_STR: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASEREQ: + case TOK_DELIMITER: + return new_error(ctx, INVALID_TOKEN, input[i], + "validate_and_clean"); + case TOK_SEGMENT: + if (!is_valid_amount(input[i]->left)) + return new_error(ctx, MISSING_AMOUNT_OR_WILD_OP, + input[i]->left, + "validate_and_clean"); + if (!is_valid_amount(input[i]->right)) + return new_error(ctx, MISSING_AMOUNT_OR_WILD_OP, + input[i]->right, + "validate_and_clean"); + + /* Process lease & lease rate. + * ex: "0|10M@1% -> chan_id" (lease 10M at 1% fee) */ + lease = input[i]->left->right; + leaserate = NULL; + if (lease) { + if (lease->type != TOK_LEASEREQ) + return new_error(ctx, INTERNAL_ERROR, + lease, + "validate_and_clean"); + if (lease->right->type != TOK_SATS) + return new_error(ctx, LEASE_AMOUNT_ZERO, + lease, + "validate_and_clean"); + lease->amount_sat = lease->right->amount_sat; + if (amount_sat_is_zero(lease->amount_sat)) + return new_error(ctx, LEASE_AMOUNT_ZERO, + lease->right, + "validate_and_clean"); + leaserate = lease->right->right; + } + if (leaserate) { + if (leaserate->type != TOK_LEASERATE) + return new_error(ctx, INTERNAL_ERROR, + leaserate, + "validate_and_clean"); + if (leaserate->right->type != TOK_PERCENT) + return new_error(ctx, MISSING_PERCENT, + leaserate, + "validate_and_clean"); + lease->ppm = leaserate->right->ppm; + } + + /* Process left fee & fee rate. + * ex: "10M-fee@4k -> chan_id" (splice in 10M less fee) */ + fee = input[i]->left->middle; + feerate = NULL; + if (fee) { + if (fee->type != TOK_FEE) + return new_error(ctx, INTERNAL_ERROR, + fee, + "validate_and_clean"); + if (!(fee->flags & TOKEN_FLAG_FEERATE_NEGATIVE)) + return new_error(ctx, + LEFT_FEE_NOT_NEGATIVE, + fee, + "validate_and_clean"); + if (pay_fee_found) + return new_error(ctx, DUPLICATE_FEESTR, + fee, + "validate_and_clean"); + pay_fee_found = true; + feerate = fee->right; + } + if (feerate) { + if (feerate->type != TOK_FEERATE) + return new_error(ctx, INTERNAL_ERROR, + feerate, + "validate_and_clean"); + if (feerate->right->type != TOK_SATS) + return new_error(ctx, MISSING_AMOUNT_OP, + feerate, + "validate_and_clean"); + fee->amount_sat = feerate->right->amount_sat; + fee->str = feerate->right->str; + } + + /* Process right fee & fee rate. + * ex: "chan_id -> 10M+fee@4k" (splice out 10M + fee) */ + fee = input[i]->right->middle; + feerate = NULL; + if (fee) { + if (fee->type != TOK_FEE) + return new_error(ctx, INTERNAL_ERROR, + fee, + "validate_and_clean"); + if ((fee->flags & TOKEN_FLAG_FEERATE_NEGATIVE)) + return new_error(ctx, + RIGHT_FEE_NOT_POSITIVE, + fee, + "validate_and_clean"); + if (pay_fee_found) + return new_error(ctx, DUPLICATE_FEESTR, + fee, + "validate_and_clean"); + pay_fee_found = true; + feerate = fee->right; + } + if (feerate) { + if (feerate->type != TOK_FEERATE) + return new_error(ctx, INTERNAL_ERROR, + feerate, + "validate_and_clean"); + if (feerate->right->type != TOK_SATS) + return new_error(ctx, MISSING_AMOUNT_OP, + feerate, + "validate_and_clean"); + fee->amount_sat = feerate->right->amount_sat; + fee->str = feerate->right->str; + } + + if (!is_valid_nonzero_amount(input[i]->left) + && !is_valid_nonzero_amount(input[i]->right) + && !lease + && !fee) + return new_error(ctx, ZERO_AMOUNTS, + input[i]->left, + "validate_and_clean"); + /* Can't specify funds going into and out of into the + * same segment. User should simply subtract one amount + * from the other. */ + if (is_valid_nonzero_amount(input[i]->left) + && is_valid_nonzero_amount(input[i]->right)) + return new_error(ctx, IN_AND_OUT_AMOUNTS, + input[i]->left, + "validate_and_clean"); + /* Check the channel id is one of our channels */ + if (input[i]->middle->type == TOK_CHANID + && !valid_channel_id(input[i]->middle->chan_id, + channels)) + return new_error(ctx, CHANNEL_ID_UNRECOGNIZED, + input[i]->middle, + "validate_and_clean"); + /* Check for duplicate channel ids */ + for (size_t j = 0; j < tal_count(chan_ids); j++) + if (input[i]->middle->type == TOK_CHANID + && channel_id_eq(&chan_ids[j], + input[i]->middle->chan_id)) + return new_error(ctx, DUPLICATE_CHANID, + input[i]->middle, + "validate_and_clean"); + + /* Now add our channel id to the array */ + if (input[i]->middle->type == TOK_CHANID) + tal_arr_expand(&chan_ids, + *input[i]->middle->chan_id); + if (!is_valid_middle(input[i]->middle)) + return new_error(ctx, INVALID_MIDDLE_OP, + input[i]->middle, + "validate_and_clean"); + tokens[n++] = tal_steal(tokens, input[i]); + break; + } + } + + tal_free(chan_ids); + tal_free(input); + tal_resize(&tokens, n); + *tokens_inout = tokens; + return NULL; +} + +static struct splice_script_error *calculate_amounts(const tal_t *ctx, + struct token ***tokens_inout) +{ + struct token **input = *tokens_inout; + struct token **tokens; + size_t n, left_wild_index, left_wilds, right_wilds; + u32 left_used_ppm; + bool right_used_ppm; + struct amount_sat left_total, right_total; + struct token *left_wildcard_token, *left_percent_token, *wallet_token; + + left_wilds = 0; + right_wilds = 0; + left_used_ppm = 0; + right_used_ppm = false; + left_total = AMOUNT_SAT(0); + right_total = AMOUNT_SAT(0); + left_wildcard_token = NULL; + left_percent_token = NULL; + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_COLON: + case TOK_LEASERATE: + case TOK_ARROW: + case TOK_PIPE: + case TOK_STR: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASEREQ: + case TOK_DELIMITER: + return new_error(ctx, INVALID_TOKEN, input[i], + "calculate_amounts"); + case TOK_SEGMENT: + if (input[i]->left->type == TOK_WILDCARD) { + left_wildcard_token = input[i]->left; + left_wilds++; + } + if (input[i]->right->type == TOK_WILDCARD) + right_wilds++; + if (input[i]->left->type == TOK_SATS) + if (!amount_sat_add(&left_total, left_total, + input[i]->left->amount_sat)) + return new_error(ctx, INTERNAL_ERROR, + input[i]->left, + "calculate_amounts"); + if (input[i]->right->type == TOK_SATS) + if (!amount_sat_add(&right_total, right_total, + input[i]->right->amount_sat)) + return new_error(ctx, INTERNAL_ERROR, + input[i]->right, + "calculate_amounts"); + if (input[i]->left->type == TOK_PERCENT) { + left_percent_token = input[i]->left; + left_used_ppm += input[i]->left->ppm; + if (left_used_ppm > 1000000) + return new_error(ctx, + LEFT_PERCENT_OVER_100, + input[i]->left, + "calculate_amounts"); + } + if (input[i]->right->type == TOK_PERCENT) + right_used_ppm = true; + break; + } + } + + /* Do we know precisely how much we're getting? */ + if (!right_wilds && !right_used_ppm) { + /* Then we can give sat amount errors */ + if (amount_sat_greater(left_total, right_total)) + return new_error(ctx, INSUFFICENT_FUNDS, + left_wildcard_token ?: input[0], + "calculate_amounts"); + if (left_used_ppm && amount_sat_eq(left_total, right_total)) + return new_error(ctx, PERCENT_IS_ZERO, + left_percent_token ?: input[0], + "calculate_amounts"); + if (left_wilds && amount_sat_eq(left_total, right_total)) + return new_error(ctx, WILDCARD_IS_ZERO, + left_wildcard_token ?: input[0], + "calculate_amounts"); + } + + tokens = tal_arr(ctx, struct token *, tal_count(input)); + n = 0; + + left_wild_index = 0; + for (size_t i = 0; i < tal_count(input); i++) { + switch(input[i]->type) { + case TOK_CHAR: + case TOK_ATSYM: + case TOK_PLUS: + case TOK_MINUS: + case TOK_COLON: + case TOK_LEASERATE: + case TOK_ARROW: + case TOK_PIPE: + case TOK_STR: + case TOK_SATS: + case TOK_PERCENT: + case TOK_QUESTION: + case TOK_WILDCARD: + case TOK_FEE: + case TOK_CHANID: + case TOK_WALLET: + case TOK_FEERATE: + case TOK_NODEID: + case TOK_BTCADDR: + case TOK_CHANQUERY: + case TOK_MULTI_CHANID: + case TOK_LEASEREQ: + case TOK_DELIMITER: + return new_error(ctx, INVALID_TOKEN, input[i], + "calculate_amounts"); + case TOK_SEGMENT: + if (input[i]->left->type == TOK_WILDCARD) { + input[i]->left->ppm = (1000000 - left_used_ppm) / left_wilds; + + /* Place remainder points into the last wildcard + * spot */ + if (++left_wild_index == left_wilds) + input[i]->left->ppm += (1000000 - left_used_ppm) % left_wilds; + + } + if (input[i]->right->type == TOK_WILDCARD) + input[i]->right->ppm = 1000000; + tokens[n++] = tal_steal(tokens, input[i]); + break; + } + } + + tal_free(input); + tal_resize(&tokens, n); + + /* Are there potential unclaimed funds? Typically we will have right + * side funds but in some channel lease situations and / or user + * provided funds (via user provided PSBT) we may have 0 funds coming + * in aka 'on the right side'. */ + if (!amount_sat_is_zero(right_total) || right_wilds || right_used_ppm) { + /* Are they not already claimed by a % or wildcard? */ + if (!left_wilds && left_used_ppm < 1000000) { + wallet_token = new_token(tokens, TOK_SEGMENT, 0); + wallet_token->left = new_token(wallet_token, + TOK_WILDCARD, 0); + wallet_token->middle = new_token(wallet_token, + TOK_WALLET, 0); + wallet_token->right = new_token(wallet_token, + TOK_SATS, 0); + wallet_token->left->ppm = 1000000 - left_used_ppm; + tal_arr_expand(&tokens, wallet_token); + } + } + + *tokens_inout = tokens; + return NULL; +} + +static bool is_delimiter(char c) +{ + return c == '\n' || c == ';'; +} + +struct splice_script_error *parse_splice_script(const tal_t *ctx, + const char *script, + struct splice_script_chan **channels, + struct splice_script_result ***result) +{ + struct splice_script_error *error; + struct token **tokens = tal_arr(ctx, struct token *, + strlen(script) + 1); + + for (size_t i = 0; i < strlen(script); i++) { + tokens[i] = new_token(tokens, is_delimiter(script[i]) + ? TOK_DELIMITER + : TOK_CHAR, i); + tokens[i]->c = script[i]; + } + + /* We add a delimiter on the end to make life simple. */ + tokens[strlen(script)] = new_token(tokens, TOK_DELIMITER, + strlen(script)); + + if ((error = clean_whitespace(ctx, &tokens))) + return error; + + if ((error = find_arrows_and_strs(ctx, &tokens))) + return error; + + if ((error = process_top_separators(ctx, &tokens))) + return error; + + if ((error = process_2nd_separators(ctx, &tokens))) + return error; + + if ((error = process_3rd_separators(ctx, &tokens))) + return error; + + if ((error = type_data(ctx, channels, &tokens))) + return error; + + if ((error = compress_top_operands(ctx, &tokens))) + return error; + + if ((error = compress_2nd_operands(ctx, &tokens))) + return error; + + if ((error = resolve_channel_ids(ctx, channels, &tokens))) + return error; + + if ((error = make_segments(ctx, &tokens))) + return error; + + if ((error = expand_multichans(ctx, &tokens))) + return error; + + if ((error = validate_and_clean(ctx, channels, &tokens))) + return error; + + if ((error = calculate_amounts(ctx, &tokens))) + return error; + +#if SCRIPT_DUMP_TOKENS + return debug_dump(ctx, tokens); +#endif +#if SCRIPT_DUMP_SEGMENTS + return dump_segments(ctx, tokens); +#endif + + *result = tal_arr(ctx, struct splice_script_result*, tal_count(tokens)); + + for (size_t i = 0; i < tal_count(tokens); i++) { + (*result)[i] = talz(*result, struct splice_script_result); + struct splice_script_result *itr = (*result)[i]; + struct token *lease = tokens[i]->left->right; + struct token *fee = tokens[i]->left->middle + ? tokens[i]->left->middle + : tokens[i]->right->middle; + + if (lease) { + itr->lease_sat = lease->amount_sat; + itr->lease_max_ppm = lease->ppm; + } + + itr->in_sat = tokens[i]->left->amount_sat; + itr->in_ppm = tokens[i]->left->ppm; + + if (tokens[i]->middle->type == TOK_CHANID) + itr->channel_id = tal_dup(itr, struct channel_id, + tokens[i]->middle->chan_id); + else if (tokens[i]->middle->type == TOK_BTCADDR) + itr->bitcoin_address = tal_strdup(itr, + tokens[i]->middle->str); + else if (tokens[i]->middle->type == TOK_WALLET) + itr->onchain_wallet = true; + else + return new_error(ctx, INTERNAL_ERROR, tokens[i], + "splice_script_result"); + + itr->out_sat = tokens[i]->right->amount_sat; + itr->out_ppm = tokens[i]->right->ppm; + + if (tokens[i]->right->type == TOK_WILDCARD) + itr->out_ppm = UINT32_MAX; + + if (fee) { + itr->pays_fee = true; + if (!parse_feerate(fee, &itr->feerate_per_kw)) + return new_error(ctx, INVALID_FEERATE, + fee->right ? fee->right->right + ?: fee->right : fee, + "splice_script_result"); + } + } + + return NULL; +} + +void splice_to_json(const tal_t *ctx, + struct splice_script_result **splice, + struct json_stream *js) +{ + json_object_start(js, NULL); + json_array_start(js, "splice"); + for (size_t i = 0; i < tal_count(splice); i++) { + json_object_start(js, NULL); + + if (!amount_sat_is_zero(splice[i]->lease_sat)) { + json_object_start(js, "lease_request"); + json_add_amount_sat_msat(js, "amount_msat", + splice[i]->lease_sat); + json_add_u32(js, "max_ppm", splice[i]->lease_max_ppm); + json_object_end(js); + } + + if (!amount_sat_is_zero(splice[i]->in_sat) || splice[i]->in_ppm) { + json_object_start(js, "into_destination"); + if (!amount_sat_is_zero(splice[i]->in_sat)) + json_add_amount_sat_msat(js, "amount_msat", + splice[i]->in_sat); + if (splice[i]->in_ppm) + json_add_u32(js, "ppm", splice[i]->in_ppm); + json_object_end(js); + } + + json_object_start(js, "destination"); + if (splice[i]->channel_id) + json_add_channel_id(js, "channel_id", + splice[i]->channel_id); + if (splice[i]->bitcoin_address) + json_add_string(js, "bitcoin_address", + splice[i]->bitcoin_address); + if (splice[i]->onchain_wallet) + json_add_bool(js, "onchain_wallet", true); + json_object_end(js); + + if (!amount_sat_is_zero(splice[i]->out_sat) + || splice[i]->out_ppm) { + json_object_start(js, "outof_destination"); + if (!amount_sat_is_zero(splice[i]->out_sat)) + json_add_amount_sat_msat(js, "amount_msat", + splice[i]->out_sat); + if (splice[i]->out_ppm) + json_add_u32(js, "ppm", splice[i]->out_ppm); + json_object_end(js); + } + + if (splice[i]->pays_fee || splice[i]->feerate_per_kw) { + json_object_start(js, "fee"); + if (splice[i]->pays_fee) + json_add_bool(js, "pays_fee", + splice[i]->pays_fee); + if (splice[i]->feerate_per_kw) + json_add_u32(js, "feerate_per_kw", + splice[i]->feerate_per_kw); + json_object_end(js); + } + + json_object_end(js); + } + json_array_end(js); + json_object_end(js); +} + +static bool json_to_msat_to_sat(const char *buffer, const jsmntok_t *tok, + struct amount_sat *sat) +{ + struct amount_msat msat; + + if (!json_to_msat(buffer, tok, &msat)) + return false; + return amount_msat_to_sat(sat, msat); +} + +bool json_to_splice(const tal_t *ctx, const char *buffer, const jsmntok_t *tok, + struct splice_script_result ***result) +{ + const jsmntok_t *splice; + const jsmntok_t *itr; + size_t i; + + splice = json_get_member(buffer, tok, "splice"); + if (!splice || splice->type != JSMN_ARRAY) + return false; + + *result = tal_arr(ctx, struct splice_script_result*, 0); + json_for_each_arr(i, itr, splice) { + const jsmntok_t *lease, *in, *dest, *out, *fee, *obj; + struct splice_script_result *ele = talz(*result, struct splice_script_result); + + if ((lease = json_get_member(buffer, itr, "lease_request"))) { + if ((obj = json_get_member(buffer, lease, + "amount_msat"))) { + if (!json_to_msat_to_sat(buffer, obj, + &ele->lease_sat)) + return false; + } + if ((obj = json_get_member(buffer, lease, "max_ppm"))) { + if (!json_to_u32(buffer, obj, + &ele->lease_max_ppm)) + return false; + } + } + + if ((in = json_get_member(buffer, itr, "into_destination"))) { + if ((obj = json_get_member(buffer, in, + "amount_msat"))) { + if (!json_to_msat_to_sat(buffer, obj, + &ele->in_sat)) + return false; + } + if ((obj = json_get_member(buffer, in, "ppm"))) { + if (!json_to_u32(buffer, obj, &ele->in_ppm)) + return false; + } + } + + if ((dest = json_get_member(buffer, itr, "destination"))) { + if ((obj = json_get_member(buffer, dest, + "channel_id"))) { + ele->channel_id = tal(ele, struct channel_id); + if (!json_to_channel_id(buffer, obj, + ele->channel_id)) + return false; + } + if ((obj = json_get_member(buffer, dest, + "bitcoin_address"))) { + ele->bitcoin_address = json_strdup(ele, buffer, + obj); + if (!ele->bitcoin_address) + return false; + } + if ((obj = json_get_member(buffer, dest, + "onchain_wallet"))) { + if (!json_to_bool(buffer, obj, + &ele->onchain_wallet)) + return false; + } + } + + if ((out = json_get_member(buffer, itr, "outof_destination"))) { + if ((obj = json_get_member(buffer, out, + "amount_msat"))) { + if (!json_to_msat_to_sat(buffer, obj, + &ele->out_sat)) + return false; + } + if ((obj = json_get_member(buffer, out, "ppm"))) { + if (!json_to_u32(buffer, obj, &ele->out_ppm)) + return false; + } + } + + if ((fee = json_get_member(buffer, itr, "fee"))) { + if ((obj = json_get_member(buffer, fee, "pays_fee"))) { + if (!json_to_bool(buffer, obj, &ele->pays_fee)) + return false; + } + if ((obj = json_get_member(buffer, fee, + "feerate_per_kw"))) { + if (!json_to_u32(buffer, obj, + &ele->feerate_per_kw)) + return false; + } + } + + tal_arr_expand(result, ele); + } + + return true; +} + +static char *ppm_to_str(const tal_t *ctx, u32 ppm) +{ + if (ppm == UINT_MAX) + return tal_fmt(ctx, "max"); + + if (ppm % 10000) + return tal_fmt(ctx, "%u.%04u%%", ppm / 10000, ppm % 10000); + + return tal_fmt(ctx, "%u%%", ppm / 10000); +} + +char *splice_to_string(const tal_t *ctx, + struct splice_script_result *result) +{ + const char *into_prefix, *fee_str; + char *str = tal_strdup(ctx, ""); + + into_prefix = ""; + fee_str = ""; + if (!amount_sat_is_zero(result->lease_sat)) { + into_prefix = "and "; + tal_append_fmt(&str, "lease %s ", + fmt_amount_sat(ctx, + result->lease_sat)); + if (result->lease_max_ppm) + tal_append_fmt(&str, "(max fee %s) ", + ppm_to_str(ctx, result->lease_max_ppm)); + } + + if (result->pays_fee) + fee_str = " less fee"; + if (result->feerate_per_kw) + fee_str = tal_fmt(tmpctx, " less fee (%u/kw)", + result->feerate_per_kw); + + if (!amount_sat_is_zero(result->in_sat)) + tal_append_fmt(&str, "%sput %s%s into ", into_prefix, + fmt_amount_sat(ctx, result->in_sat), + fee_str); + if (result->in_ppm) + tal_append_fmt(&str, "%sput %s%s of rest into ", into_prefix, + ppm_to_str(ctx, result->in_ppm), + fee_str); + + if (result->channel_id) + tal_append_fmt(&str, "%s", + tal_hexstr(tmpctx, result->channel_id, sizeof(struct channel_id))); + if (result->bitcoin_address) + tal_append_fmt(&str, "%s", result->bitcoin_address); + if (result->onchain_wallet) + tal_append_fmt(&str, "wallet"); + + fee_str = ""; + if (result->pays_fee) + fee_str = " plus fee"; + if (result->feerate_per_kw) + fee_str = tal_fmt(tmpctx, " plus fee (%u/kw, %.02f" + " sat/vB) ", + result->feerate_per_kw, + 4 * result->feerate_per_kw / 1000.0f); + + if (!amount_sat_is_zero(result->out_sat)) + tal_append_fmt(&str, " withdraw %s%s", + fmt_amount_sat(ctx, result->out_sat), + fee_str); + if (result->out_ppm) + tal_append_fmt(&str, " withdraw %s%s", + ppm_to_str(ctx, result->out_ppm), + fee_str); + + if (amount_sat_is_zero(result->in_sat) && !result->in_ppm + && amount_sat_is_zero(result->out_sat) + && !result->out_ppm + && result->pays_fee) { + + tal_append_fmt(&str, " withdraw fee"); + if (result->feerate_per_kw) + tal_append_fmt(&str, " (%u/kw, %.02f sat/vB)", + result->feerate_per_kw, + 4 * result->feerate_per_kw / 1000.0f); + } + + return str; +} + +char *splicearr_to_string(const tal_t *ctx, + struct splice_script_result **result) +{ + char *str = tal_strdup(ctx, ""); + + for (size_t i = 0; i < tal_count(result); i++) + tal_append_fmt(&str, "%s\n", splice_to_string(str, result[i])); + + return str; +} diff --git a/common/splice_script.h b/common/splice_script.h new file mode 100644 index 000000000000..17b3de28916d --- /dev/null +++ b/common/splice_script.h @@ -0,0 +1,114 @@ +#ifndef LIGHTNING_COMMON_SPLICE_SCRIPT_H +#define LIGHTNING_COMMON_SPLICE_SCRIPT_H + +#include "config.h" +#include +#include +#include +#include + +enum splice_script_error_type { + INTERNAL_ERROR, + INVALID_TOKEN, + DEBUG_DUMP, + TOO_MANY_PIPES, + TOO_MANY_ATS, + TOO_MANY_COLONS, + TOO_MANY_PLUS, + TOO_MANY_MINUS, + INVALID_NODEID, + INVALID_CHANID, + WRONG_NUM_SEGMENT_CHUNKS, + MISSING_ARROW, + NO_MATCHING_NODES, + INVALID_INDEX, + CHAN_INDEX_ON_WILDCARD_NODE, + CHAN_INDEX_NOT_FOUND, + CHANQUERY_TYPEERROR, + NODE_ID_MULTIMATCH, + NODE_ID_CHAN_OVERMATCH, + CHAN_ID_MULTIMATCH, + CHAN_ID_NODE_OVERMATCH, + NODE_ID_NO_UNUSED, + DOUBLE_MIDDLE_OP, + MISSING_MIDDLE_OP, + MISSING_AMOUNT_OP, + MISSING_AMOUNT_OR_WILD_OP, + CANNOT_PARSE_SAT_AMNT, + ZERO_AMOUNTS, + IN_AND_OUT_AMOUNTS, + MISSING_PERCENT, + LEASE_AMOUNT_ZERO, + CHANNEL_ID_UNRECOGNIZED, + DUPLICATE_CHANID, + INVALID_MIDDLE_OP, + INSUFFICENT_FUNDS, + PERCENT_IS_ZERO, + WILDCARD_IS_ZERO, + INVALID_PERCENT, + LEFT_PERCENT_OVER_100, + LEFT_FEE_NOT_NEGATIVE, + RIGHT_FEE_NOT_POSITIVE, + MISSING_FEESTR, + DUPLICATE_FEESTR, + TOO_MUCH_DECIMAL, + INVALID_FEERATE, +}; + +struct splice_script_error { + enum splice_script_error_type type; + size_t script_index; /* where in `script` was error found */ + char *message; + const char *phase; +}; + +/* Outputs a multiline helpful compiler error for the user. */ +char *fmt_splice_script_compiler_error(const tal_t *ctx, + const char *script, + struct splice_script_error *error); + +struct splice_script_chan { + struct node_id node_id; + struct channel_id chan_id; +}; + +struct splice_script_result { + /* Lease request info */ + struct amount_sat lease_sat; + u32 lease_max_ppm; + + /* Funds going in to destination (just one) */ + struct amount_sat in_sat; + u32 in_ppm; + + /* Destination (just one) */ + struct channel_id *channel_id; + char *bitcoin_address; + bool onchain_wallet; + + /* Funds coming out of destination (just one) */ + struct amount_sat out_sat; + u32 out_ppm; /* UINT32_MAX means "max available from channel" */ + + /* If true, this 'destination' pays the fee. Only one destination may + * do so. If feerate_per_kw is non-zero, it will be used for feerate. */ + bool pays_fee; + u32 feerate_per_kw; +}; + +struct splice_script_error *parse_splice_script(const tal_t *ctx, + const char *script, + struct splice_script_chan **channels, + struct splice_script_result ***result); + +void splice_to_json(const tal_t *ctx, + struct splice_script_result **splice, + struct json_stream *js); + +bool json_to_splice(const tal_t *ctx, const char *buffer, const jsmntok_t *tok, + struct splice_script_result ***result); + +char *splice_to_string(const tal_t *ctx, struct splice_script_result *splice); +char *splicearr_to_string(const tal_t *ctx, struct splice_script_result **splice); + +#endif /* LIGHTNING_COMMON_SPLICE_SCRIPT_H */ diff --git a/common/test/Makefile b/common/test/Makefile index 3313a10577c6..d251eaa76f13 100644 --- a/common/test/Makefile +++ b/common/test/Makefile @@ -104,6 +104,17 @@ common/test/run-version: \ wire/towire.o +common/test/run-splice_script: \ + common/amount.o \ + common/node_id.o \ + common/bech32.o \ + common/splice_script.o \ + common/wireaddr.o \ + common/base32.o \ + wire/fromwire.o \ + wire/towire.o + + common/test/run-trace: \ common/amount.o \ common/memleak.o \ diff --git a/common/test/run-splice_script.c b/common/test/run-splice_script.c new file mode 100644 index 000000000000..43bd579a3389 --- /dev/null +++ b/common/test/run-splice_script.c @@ -0,0 +1,384 @@ +#include "config.h" +#include "../version.c" +#include "../json_command.c" +#include "../json_filter.c" +#include "../json_parse.c" +#include "../json_stream.c" +#include "../json_parse_simple.c" +#include +#include +#include +#include +#include +#include +/* Include the C files directly. */ +#include +#include + +/* AUTOGENERATED MOCKS START */ +/* Generated stub for command_check_only */ +bool command_check_only(const struct command *cmd UNNEEDED) +{ fprintf(stderr, "command_check_only called!\n"); abort(); } +/* Generated stub for command_dev_apis */ +bool command_dev_apis(const struct command *cmd UNNEEDED) +{ fprintf(stderr, "command_dev_apis called!\n"); abort(); } +/* Generated stub for command_fail */ +struct command_result *command_fail(struct command *cmd UNNEEDED, enum jsonrpc_errcode code UNNEEDED, + const char *fmt UNNEEDED, ...) + +{ fprintf(stderr, "command_fail called!\n"); abort(); } +/* Generated stub for command_filter_ptr */ +struct json_filter **command_filter_ptr(struct command *cmd UNNEEDED) +{ fprintf(stderr, "command_filter_ptr called!\n"); abort(); } +/* Generated stub for command_log */ +void command_log(struct command *cmd UNNEEDED, enum log_level level UNNEEDED, + const char *fmt UNNEEDED, ...) + +{ fprintf(stderr, "command_log called!\n"); abort(); } +const char *mvt_tag_str(enum mvt_tag tag UNNEEDED) +{ fprintf(stderr, "mvt_tag_str called!\n"); abort(); } +/* AUTOGENERATED MOCKS END */ + +static void set_node_id(struct splice_script_chan *chan, const char *hexstr) +{ + int result = hex_decode(hexstr, strlen(hexstr), &chan->node_id, + sizeof(chan->node_id)); + assert(result); +} + +static void set_chan_id(struct splice_script_chan *chan, const char *hexstr) +{ + int result = hex_decode(hexstr, strlen(hexstr), &chan->chan_id, + sizeof(chan->chan_id)); + assert(result); +} + + +int main(int argc, char *argv[]) +{ + size_t i, len; + const char *str; + struct splice_script_error *error; + struct splice_script_result **result, **final; + jsmntok_t *toks; + struct splice_script_chan **channels; + const char *script; + struct splice_script_result *expect; + + common_setup(argv[0]); + + i = 0; + channels = tal_arr(tmpctx, struct splice_script_chan*, 0); + /* A */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0399069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120100"); + set_chan_id(channels[i], "f5699c3d5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2700"); + i++; + /* B */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0393069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120101"); + set_chan_id(channels[i], "f5699c3d5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2701"); + i++; + /* C */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0393069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120101"); + set_chan_id(channels[i], "f5699c3d5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2702"); + i++; + /* D */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0393069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120101"); + set_chan_id(channels[i], "f5699c3d5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2703"); + i++; + /* E */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0393069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120101"); + set_chan_id(channels[i], "f5699c3d5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2704"); + i++; + /* F */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0393069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120101"); + set_chan_id(channels[i], "f5699c3d5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2705"); + i++; + /* G */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0394069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120101"); + set_chan_id(channels[i], "f5699c3d5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2706"); + i++; + /* H */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0394069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120101"); + set_chan_id(channels[i], "f4699c3d5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2700"); + i++; + /* I */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0394069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120102"); + set_chan_id(channels[i], "ffffffff5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2700"); + i++; + /* J */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0394069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120103"); + set_chan_id(channels[i], "eeeeeeee5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2700"); + i++; + /* K */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0394069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120103"); + set_chan_id(channels[i], "eeeeeeee5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2701"); + i++; + /* L */ + tal_arr_expand(&channels, tal(channels, struct splice_script_chan)); + set_node_id(channels[i], "0394069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120104"); + set_chan_id(channels[i], "eeeeeeee5302e4486c83ef9d0f2d12a969ab41ccc9301bd042c50760a87b2702"); + i++; + + script = "" + "0->0399:0->3M;\n" /* A */ + "3.000001M->bcrt1pp5ygqjg0q3mmv8ng8ceu59kl5a3etlf2vvryvnnyumvdyr8a77tqx507vk;\n" + "wallet->1M;\n" + "0->f4699c->3M;\n" /* H */ + "0->0393069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120101:0->*;\n" /* B */ + "0->0393069f1693fd89a453f0caf03ee36b6f6c8abaa7ef778d3e2bcc7c2b44120101:?->12M;\n" /* C */ + "0->03930:*->*\n" /* D, E, F */ + "|4.91M@2%->*:?;\n" /* G */ + "25.010%|100K->*:?;\n" /* I */ + "*:?->+fee@40000;\n" /* J */ + "10.0003%->*:*;\n"; /* K, L */ + + expect = tal_arr(tmpctx, struct splice_script_result, 15); + i = 0; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = &channels[0]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(3000000); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(3000001); + expect[i].in_ppm = 0; + expect[i].channel_id = 0; + expect[i].bitcoin_address = "bcrt1pp5ygqjg0q3mmv8ng8ceu59kl5a3etlf2vvryvnnyumvdyr8a77tqx507vk"; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = 0; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 1; + expect[i].out_sat = AMOUNT_SAT(1000000); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = &channels[7]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(3000000); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = &channels[1]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = UINT32_MAX; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = &channels[2]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(12000000); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = &channels[3]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = UINT32_MAX; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = &channels[4]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = UINT32_MAX; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = &channels[5]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = UINT32_MAX; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(4910000); + expect[i].lease_max_ppm = 20000; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = &channels[6]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(100000); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 250100; + expect[i].channel_id = &channels[8]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 0; + expect[i].channel_id = &channels[9]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = 0; + expect[i].pays_fee = 1; + expect[i].feerate_per_kw = 40000; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 50001; + expect[i].channel_id = &channels[10]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 50002; + expect[i].channel_id = &channels[11]->chan_id; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 0; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + expect[i].lease_sat = AMOUNT_SAT(0); + expect[i].lease_max_ppm = 0; + expect[i].in_sat = AMOUNT_SAT(0); + expect[i].in_ppm = 649897; + expect[i].channel_id = 0; + expect[i].bitcoin_address = 0; + expect[i].onchain_wallet = 1; + expect[i].out_sat = AMOUNT_SAT(0); + expect[i].out_ppm = 0; + expect[i].pays_fee = 0; + expect[i].feerate_per_kw = 0; + i++; + + assert(i == tal_count(expect)); + + chainparams = chainparams_for_network("regtest"); + + error = parse_splice_script(tmpctx, script, channels, &result); + + if (error) { + printf("%s\n", fmt_splice_script_compiler_error(tmpctx, script, + error)); + common_shutdown(); + abort(); + } + + struct json_stream *js = new_json_stream(tmpctx, NULL, NULL); + + splice_to_json(tmpctx, result, js); + + str = json_out_contents(js->jout, &len); + + printf("%.*s\n", (int)len, str); + + assert(str); + + toks = json_parse_simple(tmpctx, str, len); + + assert(toks); + + assert(json_to_splice(tmpctx, str, toks, &final)); + + assert(tal_count(final) == tal_count(expect)); + + for (i = 0; i < tal_count(expect); i++) { + assert(amount_sat_eq(final[i]->lease_sat, expect[i].lease_sat)); + assert(final[i]->lease_max_ppm == expect[i].lease_max_ppm); + assert(amount_sat_eq(final[i]->in_sat, expect[i].in_sat)); + assert(final[i]->in_ppm == expect[i].in_ppm); + if (final[i]->channel_id != expect[i].channel_id) + assert(channel_id_eq(final[i]->channel_id, expect[i].channel_id)); + if (final[i]->bitcoin_address != expect[i].bitcoin_address) + assert(!strcmp(final[i]->bitcoin_address, expect[i].bitcoin_address)); + assert(final[i]->onchain_wallet == expect[i].onchain_wallet); + assert(amount_sat_eq(final[i]->out_sat, expect[i].out_sat)); + assert(final[i]->out_ppm == expect[i].out_ppm); + if (expect[i].pays_fee) + assert(final[i]->pays_fee); + else + assert(!final[i]->pays_fee); + assert(final[i]->feerate_per_kw == expect[i].feerate_per_kw); + } + + printf("DRY RUN:\n%s", splicearr_to_string(tmpctx, final)); + + common_shutdown(); + + return 0; +} diff --git a/contrib/msggen/msggen/schema.json b/contrib/msggen/msggen/schema.json index 062b84f39d89..ea49016f888d 100644 --- a/contrib/msggen/msggen/schema.json +++ b/contrib/msggen/msggen/schema.json @@ -11265,6 +11265,438 @@ } ] }, + "lightning-dev-splice.json": { + "$schema": "../rpc-schema-draft.json", + "type": "object", + "additionalProperties": false, + "added": "v24.11", + "rpc": "dev-splice", + "title": "Command to initiate a channel to a peer", + "warning": "experimental-splicing only", + "description": [ + "`splice` is the command to move funds into or out of a channel. Multiple actions can be combined together resulting in a single onchain transaction. Funds may be moved out of a channel and into another in a single batch enabling cross-channel movement." + ], + "request": { + "required": [ + "script_or_json" + ], + "properties": { + "script_or_json": { + "type": "string", + "description": [ + "The splice script to execute or json equivilent" + ] + }, + "dryrun": { + "type": "boolean", + "description": [ + "Don't execute any actions and output a transcript of what would have been done" + ] + }, + "force_feerate": { + "type": "boolean", + "description": [ + "By default splices will fail if the fee provided looks too high. This is to protect against accidentally setting your fee higher than intended. Set `force_feerate` to true to skip this saftey check" + ] + }, + "debug_log": { + "type": "boolean", + "description": [ + "Adds a verbose log of each splice calculation step to the result" + ] + }, + "dev-wetrun": { + "type": "boolean", + "description": [ + "Executes the splice up until the point signatures would be sent and then aborts" + ] + } + } + }, + "response": { + "required": [], + "properties": { + "dryrun": { + "type": "array", + "items": { + "type": "string", + "description": [ + "One action line of the splice script result" + ] + }, + "description": [ + "The transcript of what the script would have done" + ] + }, + "psbt": { + "type": "string", + "description": [ + "The final psbt" + ] + }, + "tx": { + "type": "string", + "description": [ + "The final transaction in hex" + ] + }, + "txid": { + "type": "string", + "description": [ + "The txid of the final transaction" + ] + }, + "log": { + "type": "array", + "description": [ + "A verbose log of each step of splice calcuations" + ], + "items": { + "type": "string", + "description": [ + "A line of detail about splice calcuations" + ] + } + } + } + }, + "usage": [ + "The primary method is to make a `script` containing one or more splice actions", + "that will be merged into a single transaction. If possible the entire operation", + "will be completed and broadcast to the mempool.", + "", + "However if you specified your own inputs using `psbt`, then the command will", + "return a psbt that you must sign and then pass to `splice_signed`.", + "", + "It is required to pass `script_or_json`.", + "", + "It is recommended you first do a `dryrun` to confirm your script does what you", + "expect it to do.", + "", + "*script* The splice script to execute", + "", + "*dryrun* Don't execute any actions and output a transcript of what would have", + "been done", + "", + "*psbt* An initial psbt to begin the splice with", + "", + "*user\\_provided\\_sats* The amount of sats being contributed by the initial psbt", + "", + "*force\\_feerate* By default splices will fail if the fee provided looks too high.", + "This is to protect against accidentally setting your fee higher than intended.", + "Set to true to skip this saftey check", + "", + "*json* A json payload of instructions can be passed instead of script", + "", + "*debug\\_log* Adds a verbose log of each splice calculation step to the result", + "", + "*dev-wetrun* Executes the splice up until the point signatures would be sent and then aborts", + "", + "The primary purpose of splice script is to execute all types of splices using", + "a single command. You can perform all these actions manually using the lower", + "level api (see `splice_init`) however this splice command interface is much simpler to use", + "and it provides some security against signing maliciously inserted inputs.", + "", + "SCRIPT", + "-----", + "", + "A splice script is a series of 'segments' that are separated by newlines or ", + "semicolons. Each segment represents one splice action which is typically adding", + "to or removing from a channel. The funds are designated as going into the", + "channel or coming out of the channel by which side of an arrow \"->\" the channel", + "identifier is placed on. The amount of funds is placed on the other side of the", + "arrow.", + "", + "Take this example:", + "```shell", + "8338aef0 -> 10000sat", + "```", + "", + "This is how we take 10,000 sats out of channel 8338aef0.", + "", + "To put 10,000 sats into the channel, we make the arrow point into the channel", + "like so:", + "```shell", + "10000sat -> 8338aef0", + "```", + "", + "In the last two examples we specified the first 8 digits of the channel", + "identifier. You can specify as few as 4 digits of the beginning of the channel", + "identifier and it will be autocompleted to the matching channel. If the code", + "matches more than one channel or node id, the script will fail with an error.", + "", + "In order to put funds into a channel however, we need get the funds from", + "somewhere. The simplest place to get them is the built in onchain wallet. The", + "\"wallet\" operator can be placed just like channel identifiers. We can take funds", + "out of the wallet like so:", + "```shell", + "wallet -> 10000sat", + "```", + "", + "We can put funds back into the wallet like so:", + "```shell", + "10000sat -> wallet", + "```", + "", + "Now that we know how to take funds out of a wallet, let's combine them into an", + "individual script:", + "```shell", + "wallet -> 10000sat", + "10000sat -> 8338aef0", + "```", + "", + "The first line withdraws 10,000 sats from the wallet and puts them in the", + "script's \"general script funds.\" The second line takes 10,000 sats from the", + "\"general script funds\" and places them into channel 8338aef0. This example is", + "called a \"splice in.\"", + "", + "In order for this script to work, we need one more thing. Onchain fees must be", + "funded from somewhere. The simplest way to pay the fee from the \"general script", + "funds.\" If we change the amount going into the channel to a percentage, the fee", + "will automatically be taken from the \"general script funds\" like so:", + "```shell", + "wallet -> 10000sat", + "100% -> 8338aef0", + "```", + "", + "When specifying a percentage instead of an amount, it means take that percentage", + "out of the \"general script fund.\"", + "", + "This will take 10,000 sats from the onchain wallet and put that amount less any", + "onchain fees into channel 8338aef0. The feerate used will be the node's", + "standard opening feerate. In order to use your own feerate you must us the fee", + "operator.", + "", + "The fee operator is attached to an amount. If you want to take out extra to", + "cover the fee, use \"+fee\" and if you want to reduce the amount being sent", + "somewhere use the \"-fee\" suffix. Take this example:", + "```shell", + "wallet -> 10000sat+fee", + "10000sat -> 8338aef0", + "```", + "", + "In this example we add precisely 10,000 sats to channel 8338aef0 and withdraw", + "enough from the wallet to cover the 10,000 sats and the onchain fee.", + "", + "To control the amount of fee, you can specify a fee-rate with the use of the at", + "\"@\" symbol after fee. After the at symbol, specify a number of sats to pay per", + "kiloweight (aka. perkw) like so:", + "```shell", + "wallet -> 10000sat+fee@300", + "10000sat -> 8338aef0", + "```", + "", + "This example pays a fee rate of 300 sats per thousand weight units. To view this", + "amount in other units (ie. sats/vbyte) execute a `dryrun` of the script.", + "", + "Instead of withdrawing extra from the wallet, we can reduce the amount going to", + "channel 8338aef0 using the \"-fee\" operator like so:", + "```shell", + "wallet -> 10000sat", + "10000sat-fee -> 8338aef0", + "```", + "", + "This example withdraws 10,000 sats from the onchain wallet, pays the onchain", + "fee from that amount, and puts the rest into channel 8338aef0.", + "", + "You can also specify the feerate here like so:", + "```shell", + "wallet -> 10000sat", + "10000sat-fee@300 -> 8338aef0", + "```", + "", + "Now let's build a script that takes funds out of a channel and puts them into", + "the onchain wallet:", + "```shell", + "8338aef0 -> 10000sat", + "100% -> wallet", + "```", + "", + "By default however, scripts that leave sats in the \"general script fund,\" will", + "be automatically sent to the wallet. So the second line is not needed, we can", + "simplify the script to:", + "```shell", + "8338aef0 -> 10000sat", + "```", + "", + "We can can also move sats to a specific bitcoin address like so:", + "```shell", + "8338aef0 -> 10000sat+fee", + "100% -> 1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu", + "```", + "", + "This example pays 10,000 sats to the address 1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu", + "out of your channel balance in 8338aef0.", + "", + "Percentages on the right side take out that amount of available funds from a", + "channel. For example:", + "```shell", + "8338aef0 -> 100%", + "```", + "", + "This takes all available funds out of channel 8338aef0 and puts them into the", + "onchain wallet. Note that available funds is restricted by pending HTLCs and", + "the 1% reserve requirement. To get all the funds you need to close the channel.", + "More useful would be something like this:", + "```shell", + "8338aef0 -> 50%", + "100% -> 07bfddea", + "```", + "", + "This example takes half the available funds from channel 8338aef0 and puts them", + "into channel 07bfddea.", + "", + "We can also split this amount like so:", + "```shell", + "8338aef0 -> 50%", + "50% -> 07bfddea", + "50% -> 09ad6278", + "```", + "", + "This example takes half the funds in 8338aef0 and splits them between channels", + "07bfddea and 09ad6278.", + "", + "If we want to send funds to more channels calculating percentages can get", + "unwieldy so we can use the asterisk operator \"\\*\" which divides the \"general", + "script funds\" amongst all destinations using it, like so:", + "```shell", + "8338aef0 -> 50%", + "* -> 07bfddea", + "* -> 09ad6278", + "* -> efc2a7ff", + "```", + "", + "This example takes half the available funds in 8338aef0 and splits them evenly", + "among three achannels.", + "", + "Sats can be specified with multiple suffixes including sat, msat, btc, M, or K.", + "The M suffix is shorthand for a million satoshis and the K suffix is shorthand", + "for a thousand satoshis. These can be combined with a decimal point like so:", + "```shell", + "07bfddea -> 1.23M", + "09ad6278 -> 900K", + "efc2a7ff -> 0.01btc", + "```", + "", + "This example takes 1,230,000 sats from 07bfddea, 900,000 sats from 09ad6278, and", + "1,000,000 sats from efc2a7ff and puts them in the onchain wallet.", + "", + "Another way to specify channel ids is a channel query. These take the form of a", + "node id, a colon, and a number or symbol (ie. \"034645dc:0\") which results in", + "your first channel with the peer whose node id starts with 034645dc. Change the", + "number after the colon to get a different index like so:", + "```shell", + "034645dc:0 -> 10K", + "034645dc:1 -> 10K", + "034645dc:2 -> 10K", + "```", + "", + "This example takes 10,000 sats out of the first three channels with peer", + "034645dc and puts the total minus fees into the onchain wallet.", + "", + "In addition to index numbers, the symbol after the colon can be a question mark", + "\"?\" or an asterisk \"\\*\" which mean match the first unused channel or all the", + "remaining channels respectively like so:", + "```shell", + "* -> 034645dc:?", + "* -> 03e3d03e:0", + "03e3d03e:* -> 100%", + "```", + "", + "This example takes 100% of available funds from all of 03e3d03e's channels", + "except the first one and splits them between 03e3d03e's first channel and", + "034645dc's first channel.", + "", + "The node id prefix can also be replaced with the asterisk \"\\*\" which means match", + "all nodes. This can be combined with the asterisk \"\\*\" that matches all unused", + "channels like so:", + "```shell", + "wallet -> 10000sat", + "100% -> *:*", + "```", + "", + "This example takes 10,000 sats from the onchain wallet and divides them between", + "all channels.", + "", + "It is possible to request a peer to add funds to a channel with a lease request.", + "This is done using the pipe \"|\" symbol and optionally specifying the maximum fee", + "you authorize using the at \"@\" symbol. After the pipe you specify the amount of", + "sats you would like to lease, followed by the at symbol and a percentage value", + "like so:", + "```shell", + "wallet -> 10M+fee", + "100%|10M@1% -> 8338aef0", + "```", + "", + "This example splices 10,000,000 sats into channel and requests your peer also", + "add 10,000,000 sats to the channel. If they fee they demand is over 1% or the lease", + "amount is too small the operation will be aborted. Whatever lease fee they do", + "charge will come out of the 10,000,000 sats going into the channel balance. The", + "onchain fee will be paid by taking extra funds out of the onchain wallet.", + "", + "Lease requests do not need to combined with splicing in funds but you must pay", + "the onchain fee from somewhere. One simple location to take the fees from is", + "your existing channel balance. Doing so requires using two arrows since funds", + "are going into and out of the channel at the same time, like so:", + "```shell", + "|10M@1% -> 8338aef0 -> 0+fee", + "```", + "", + "This example makes a lease request from your peer on 8338aef0 for 10,000,000", + "sats and pays the onchain fee using the channel balance. This is a particularly", + "elegant way to pay the onchain fee without adding any inputs or outputs beyond", + "the channel funding itself.", + "", + "When passing via the command line using semicolons can be simpler instead of", + "newlines. Here are some command line examples:", + "", + "Splice out 10 million satoshis to the onchain wallet", + "```shell", + "lightning-cli splice \"8338aef0 -> 10M\"", + "```", + "", + "Splice in 10 thousand satoshis from the onchain wallet", + "```shell", + "lightning-cli splice \"wallet -> 10K; 100% -> 8338aef0\"", + "```", + "", + "Send 900 thousand satoshis from a channel to an onchain address", + "```shell", + "lightning-cli splice \"8338aef0 -> 0.9M+fee; 0.9M -> 1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu\"", + "```", + "", + "Move 1 bitcoin between two channels", + "```shell", + "lightning-cli splice \"8338aef0 -> 1btc; 100% -> 07bfddea\"", + "```", + "", + "Splice in 100 thousand sats to the first channel with peer id 034645dc", + "```shell", + "lightning-cli splice \"wallet -> 0.1M; 100% -> 034645dc:?\"", + "```", + "", + "Splice in 100 thousand sats split across *all* channels with peer id 034645dc", + "```shell", + "lightning-cli splice \"wallet -> 100000; 100% -> 034645dc:*\"", + "```", + "", + "Take the maximum out of one chanel and split the value across peer 034645dc's", + "channel plus one more channel", + "```shell", + "lightning-cli splice \"8338aef0 -> 100%; * -> 034645dc:*; * -> 07bfddea\"", + "```" + ], + "author": [ + "Dusty <<@dusty_daemon>> is mainly responsible." + ], + "see_also": [ + "lightning-splice_signed(7)", + "lightning-splice_update(7)" + ], + "resources": [ + "Main web site: " + ] + }, "lightning-disableinvoicerequest.json": { "$schema": "../rpc-schema-draft.json", "type": "object", @@ -32578,7 +33010,7 @@ "psbt": { "type": "string", "description": [ - "The final version of the psbt to complete the splice with." + "The psbt of the resulting transaction after splice negotiation(s)" ] }, "sign_first": { @@ -32592,7 +33024,8 @@ "response": { "required": [ "tx", - "txid" + "txid", + "psbt" ], "additionalProperties": false, "properties": { @@ -32608,6 +33041,12 @@ "The txid is of the final transaction." ] }, + "psbt": { + "type": "string", + "description": [ + "The psbt of the resulting transaction after splice negotiation(s)" + ] + }, "outnum": { "added": "v24.08", "type": "u32", @@ -32751,7 +33190,8 @@ "response": { "required": [ "psbt", - "commitments_secured" + "commitments_secured", + "signatures_secured" ], "additionalProperties": false, "properties": { @@ -32766,6 +33206,13 @@ "description": [ "Whether or not the commitments were secured." ] + }, + "signatures_secured": { + "added": "v24.11", + "type": "boolean", + "description": [ + "whether or not the peer sent us their signatures for this splice" + ] } } }, @@ -32846,7 +33293,8 @@ }, "response": { "psbt": "cHNidP8BAgQCAAAAAQMEkgAAAAEEAQIBBQECAQYBAwH7BAIAAAAAAQCJAgAAAAH5+Z9NssTFQhFzAFkPSrEKg0AcgN7uwR9geC5Lqd+SfgAAAAAA/f///wJAQg8AAAAAACIAIJPe3QwmW8qGhXbT7i5Z7ruyDrwpblj37cqT1e6uwImWgWzcCwAAAAAiUSBbtDt/2hcV0N0BQWgloYUiotfssWR1uIeA6Pr8HHPviY0AAAABASuBbNwLAAAAACJRIFu0O3/aFxXQ3QFBaCWhhSKi1+yxZHW4h4Do+vwcc++JAQ4g9iEmrLThqBE+s85A7YDjSknUmwNcudNkF7HBMzInESwBDwQBAAAAARAE/f///wz8CWxpZ2h0bmluZwEImfI55kWjFBwAAQCJAgAAAAH5+Z9NssTFQhFzAFkPSrEKg0AcgN7uwR9geC5Lqd+SfgAAAAAA/f///wJAQg8AAAAAACIAIJPe3QwmW8qGhXbT7i5Z7ruyDrwpblj37cqT1e6uwImWgWzcCwAAAAAiUSBbtDt/2hcV0N0BQWgloYUiotfssWR1uIeA6Pr8HHPviY0AAAABAStAQg8AAAAAACIAIJPe3QwmW8qGhXbT7i5Z7ruyDrwpblj37cqT1e6uwImWAQ4g9iEmrLThqBE+s85A7YDjSknUmwNcudNkF7HBMzInESwBDwQAAAAAARAEAAAAAAz8CWxpZ2h0bmluZwEIo0w+EfrhL4QAAQMIzrnaCwAAAAABBCJRII+O1EYnVX28zEKuAYqcVHSpkShXksTKiRwfWcVmXTRgDPwJbGlnaHRuaW5nAQiPzwRTPwtPWgABAwjgyBAAAAAAAAEEIgAgk97dDCZbyoaFdtPuLlnuu7IOvCluWPftypPV7q7AiZYM/AlsaWdodG5pbmcBCK3lpE4Vja7KAA==", - "commitments_secured": true + "commitments_secured": true, + "signatures_secured": true } }, { @@ -32860,7 +33308,8 @@ }, "response": { "psbt": "cHNidP8BAgQCAAAAAQMElAAAAAEEAQEBBQECAQYBAwH7BAIAAAAAAQCyAgAAAAL2ISastOGoET6zzkDtgONKSdSbA1y502QXscEzMicRLAEAAAAA/f////YhJqy04agRPrPOQO2A40pJ1JsDXLnTZBexwTMyJxEsAAAAAAAAAAAAAs652gsAAAAAIlEgj47URidVfbzMQq4BipxUdKmRKFeSxMqJHB9ZxWZdNGDgyBAAAAAAACIAIJPe3QwmW8qGhXbT7i5Z7ruyDrwpblj37cqT1e6uwImWkgAAAAEBK+DIEAAAAAAAIgAgk97dDCZbyoaFdtPuLlnuu7IOvCluWPftypPV7q7AiZYBDiCVuxWBeu80WsQES0HKNSpjl7RUGPMhcKRnsXRp4BRF+AEPBAEAAAABEAQAAAAADPwJbGlnaHRuaW5nAQheLXaEp+y8AgABAwi4Lg8AAAAAAAEEIgAgk97dDCZbyoaFdtPuLlnuu7IOvCluWPftypPV7q7AiZYM/AlsaWdodG5pbmcBCBkNULro+QrwAAEDCKCGAQAAAAAAAQQiUSDE0oJBX5qB0Y4IthmhnRFrhlbLG/ST5fVAu/e3oFhM2gz8CWxpZ2h0bmluZwEIuBcidnXj4BAA", - "commitments_secured": true + "commitments_secured": true, + "signatures_secured": true } } ] diff --git a/contrib/pyln-client/pyln/client/lightning.py b/contrib/pyln-client/pyln/client/lightning.py index 4669d9b35acf..510118289353 100644 --- a/contrib/pyln-client/pyln/client/lightning.py +++ b/contrib/pyln-client/pyln/client/lightning.py @@ -1135,6 +1135,17 @@ def openchannel_abort(self, channel_id): } return self.call("openchannel_abort", payload) + def splice(self, script_or_json, dryrun=None, force_feerate=None, debug_log=None, wetrun=None): + """ Execute a splice """ + payload = { + "script_or_json": script_or_json, + "dryrun": dryrun, + "force_feerate": force_feerate, + "debug_log": debug_log, + "dev-wetrun": wetrun, + } + return self.call("dev-splice", payload) + def splice_init(self, chan_id, amount, initialpsbt=None, feerate_per_kw=None): """ Initiate a splice """ payload = { diff --git a/contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py b/contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py index 964a750a2d0d..9248feabb3ba 100644 --- a/contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py +++ b/contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py @@ -15,7 +15,7 @@ from pyln.grpc import primitives_pb2 as primitives__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nnode.proto\x12\x03\x63ln\x1a\x10primitives.proto\"\x10\n\x0eGetinfoRequest\"\xc1\x04\n\x0fGetinfoResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\x05\x61lias\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\r\n\x05\x63olor\x18\x03 \x01(\x0c\x12\x11\n\tnum_peers\x18\x04 \x01(\r\x12\x1c\n\x14num_pending_channels\x18\x05 \x01(\r\x12\x1b\n\x13num_active_channels\x18\x06 \x01(\r\x12\x1d\n\x15num_inactive_channels\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\rlightning_dir\x18\t \x01(\t\x12\x33\n\x0cour_features\x18\n \x01(\x0b\x32\x18.cln.GetinfoOur_featuresH\x01\x88\x01\x01\x12\x13\n\x0b\x62lockheight\x18\x0b \x01(\r\x12\x0f\n\x07network\x18\x0c \x01(\t\x12(\n\x13\x66\x65\x65s_collected_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x07\x61\x64\x64ress\x18\x0e \x03(\x0b\x32\x13.cln.GetinfoAddress\x12$\n\x07\x62inding\x18\x0f \x03(\x0b\x32\x13.cln.GetinfoBinding\x12\"\n\x15warning_bitcoind_sync\x18\x10 \x01(\tH\x02\x88\x01\x01\x12$\n\x17warning_lightningd_sync\x18\x11 \x01(\tH\x03\x88\x01\x01\x42\x08\n\x06_aliasB\x0f\n\r_our_featuresB\x18\n\x16_warning_bitcoind_syncB\x1a\n\x18_warning_lightningd_sync\"S\n\x13GetinfoOur_features\x12\x0c\n\x04init\x18\x01 \x01(\x0c\x12\x0c\n\x04node\x18\x02 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\x0c\x12\x0f\n\x07invoice\x18\x04 \x01(\x0c\"\xc4\x01\n\x0eGetinfoAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoAddress.GetinfoAddressType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\"G\n\x12GetinfoAddressType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_address\"\xac\x02\n\x0eGetinfoBinding\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoBinding.GetinfoBindingType\x12\x14\n\x07\x61\x64\x64ress\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06socket\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07subtype\x18\x05 \x01(\tH\x03\x88\x01\x01\"_\n\x12GetinfoBindingType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x12\r\n\tWEBSOCKET\x10\x05\x42\n\n\x08_addressB\x07\n\x05_portB\t\n\x07_socketB\n\n\x08_subtype\"\xb5\x01\n\x10ListpeersRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x38\n\x05level\x18\x02 \x01(\x0e\x32$.cln.ListpeersRequest.ListpeersLevelH\x01\x88\x01\x01\"E\n\x0eListpeersLevel\x12\x06\n\x02IO\x10\x00\x12\t\n\x05\x44\x45\x42UG\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\x0b\n\x07UNUSUAL\x10\x03\x12\t\n\x05TRACE\x10\x04\x42\x05\n\x03_idB\x08\n\x06_level\"7\n\x11ListpeersResponse\x12\"\n\x05peers\x18\x01 \x03(\x0b\x32\x13.cln.ListpeersPeers\"\xdf\x01\n\x0eListpeersPeers\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x11\n\tconnected\x18\x02 \x01(\x08\x12#\n\x03log\x18\x03 \x03(\x0b\x32\x16.cln.ListpeersPeersLog\x12\x0f\n\x07netaddr\x18\x05 \x03(\t\x12\x15\n\x08\x66\x65\x61tures\x18\x06 \x01(\x0cH\x00\x88\x01\x01\x12\x18\n\x0bremote_addr\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x19\n\x0cnum_channels\x18\x08 \x01(\rH\x02\x88\x01\x01\x42\x0b\n\t_featuresB\x0e\n\x0c_remote_addrB\x0f\n\r_num_channels\"\x88\x03\n\x11ListpeersPeersLog\x12?\n\titem_type\x18\x01 \x01(\x0e\x32,.cln.ListpeersPeersLog.ListpeersPeersLogType\x12\x18\n\x0bnum_skipped\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04time\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06source\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x10\n\x03log\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x07node_id\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x11\n\x04\x64\x61ta\x18\x07 \x01(\x0cH\x05\x88\x01\x01\"t\n\x15ListpeersPeersLogType\x12\x0b\n\x07SKIPPED\x10\x00\x12\n\n\x06\x42ROKEN\x10\x01\x12\x0b\n\x07UNUSUAL\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\t\n\x05\x44\x45\x42UG\x10\x04\x12\t\n\x05IO_IN\x10\x05\x12\n\n\x06IO_OUT\x10\x06\x12\t\n\x05TRACE\x10\x07\x42\x0e\n\x0c_num_skippedB\x07\n\x05_timeB\t\n\x07_sourceB\x06\n\x04_logB\n\n\x08_node_idB\x07\n\x05_data\"0\n\x10ListfundsRequest\x12\x12\n\x05spent\x18\x01 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_spent\"e\n\x11ListfundsResponse\x12&\n\x07outputs\x18\x01 \x03(\x0b\x32\x15.cln.ListfundsOutputs\x12(\n\x08\x63hannels\x18\x02 \x03(\x0b\x32\x16.cln.ListfundsChannels\"\xb9\x03\n\x10ListfundsOutputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06output\x18\x02 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0cscriptpubkey\x18\x04 \x01(\x0c\x12\x14\n\x07\x61\x64\x64ress\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0credeemscript\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12<\n\x06status\x18\x07 \x01(\x0e\x32,.cln.ListfundsOutputs.ListfundsOutputsStatus\x12\x18\n\x0b\x62lockheight\x18\x08 \x01(\rH\x02\x88\x01\x01\x12\x10\n\x08reserved\x18\t \x01(\x08\x12\x1e\n\x11reserved_to_block\x18\n \x01(\rH\x03\x88\x01\x01\"Q\n\x16ListfundsOutputsStatus\x12\x0f\n\x0bUNCONFIRMED\x10\x00\x12\r\n\tCONFIRMED\x10\x01\x12\t\n\x05SPENT\x10\x02\x12\x0c\n\x08IMMATURE\x10\x03\x42\n\n\x08_addressB\x0f\n\r_redeemscriptB\x0e\n\x0c_blockheightB\x14\n\x12_reserved_to_block\"\xab\x02\n\x11ListfundsChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12$\n\x0four_amount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0c\x66unding_txid\x18\x04 \x01(\x0c\x12\x16\n\x0e\x66unding_output\x18\x05 \x01(\r\x12\x11\n\tconnected\x18\x06 \x01(\x08\x12 \n\x05state\x18\x07 \x01(\x0e\x32\x11.cln.ChannelState\x12\x1d\n\x10short_channel_id\x18\x08 \x01(\tH\x00\x88\x01\x01\x12\x17\n\nchannel_id\x18\t \x01(\x0cH\x01\x88\x01\x01\x42\x13\n\x11_short_channel_idB\r\n\x0b_channel_id\"\xbb\x03\n\x0eSendpayRequest\x12 \n\x05route\x18\x01 \x03(\x0b\x32\x11.cln.SendpayRoute\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x1b\n\x0epayment_secret\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x12\x13\n\x06partid\x18\x07 \x01(\x04H\x03\x88\x01\x01\x12\x14\n\x07groupid\x18\t \x01(\x04H\x04\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\x0b \x01(\x0cH\x06\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\x0c \x01(\x0cH\x07\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\r \x01(\tH\x08\x88\x01\x01\x42\x08\n\x06_labelB\t\n\x07_bolt11B\x11\n\x0f_payment_secretB\t\n\x07_partidB\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x10\n\x0e_localinvreqidB\x13\n\x11_payment_metadataB\x0e\n\x0c_description\"\xad\x05\n\x0fSendpayResponse\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x32\n\x06status\x18\x04 \x01(\x0e\x32\".cln.SendpayResponse.SendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x14\n\x07message\x18\x0e \x01(\tH\x08\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0f \x01(\x04H\t\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\n\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x0b\x88\x01\x01\"*\n\rSendpayStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\n\n\x08_messageB\x0f\n\r_completed_atB\x10\n\x0e_created_indexB\x10\n\x0e_updated_index\"\\\n\x0cSendpayRoute\x12\n\n\x02id\x18\x02 \x01(\x0c\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r\x12\x0f\n\x07\x63hannel\x18\x04 \x01(\t\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\"\x93\x01\n\x13ListchannelsRequest\x12\x1d\n\x10short_channel_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06source\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x42\x13\n\x11_short_channel_idB\t\n\x07_sourceB\x0e\n\x0c_destination\"C\n\x14ListchannelsResponse\x12+\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x19.cln.ListchannelsChannels\"\xb3\x03\n\x14ListchannelsChannels\x12\x0e\n\x06source\x18\x01 \x01(\x0c\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\x0c\x12\x18\n\x10short_channel_id\x18\x03 \x01(\t\x12\x0e\n\x06public\x18\x04 \x01(\x08\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x15\n\rmessage_flags\x18\x06 \x01(\r\x12\x15\n\rchannel_flags\x18\x07 \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x08 \x01(\x08\x12\x13\n\x0blast_update\x18\t \x01(\r\x12\x1d\n\x15\x62\x61se_fee_millisatoshi\x18\n \x01(\r\x12\x19\n\x11\x66\x65\x65_per_millionth\x18\x0b \x01(\r\x12\r\n\x05\x64\x65lay\x18\x0c \x01(\r\x12&\n\x11htlc_minimum_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x11htlc_maximum_msat\x18\x0e \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x10\n\x08\x66\x65\x61tures\x18\x0f \x01(\x0c\x12\x11\n\tdirection\x18\x10 \x01(\rB\x14\n\x12_htlc_maximum_msat\"#\n\x10\x41\x64\x64gossipRequest\x12\x0f\n\x07message\x18\x01 \x01(\x0c\"\x13\n\x11\x41\x64\x64gossipResponse\"\xac\x01\n\x14\x41\x64\x64psbtoutputRequest\x12\x1c\n\x07satoshi\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x15\n\x08locktime\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x18\n\x0binitialpsbt\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\x0b\n\t_locktimeB\x0e\n\x0c_initialpsbtB\x0e\n\x0c_destination\"U\n\x15\x41\x64\x64psbtoutputResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x1e\n\x16\x65stimated_added_weight\x18\x02 \x01(\r\x12\x0e\n\x06outnum\x18\x03 \x01(\r\"O\n\x14\x41utocleanonceRequest\x12*\n\tsubsystem\x18\x01 \x01(\x0e\x32\x17.cln.AutocleanSubsystem\x12\x0b\n\x03\x61ge\x18\x02 \x01(\x04\"G\n\x15\x41utocleanonceResponse\x12.\n\tautoclean\x18\x01 \x01(\x0b\x32\x1b.cln.AutocleanonceAutoclean\"\xb1\x04\n\x16\x41utocleanonceAutoclean\x12L\n\x11succeededforwards\x18\x01 \x01(\x0b\x32,.cln.AutocleanonceAutocleanSucceededforwardsH\x00\x88\x01\x01\x12\x46\n\x0e\x66\x61iledforwards\x18\x02 \x01(\x0b\x32).cln.AutocleanonceAutocleanFailedforwardsH\x01\x88\x01\x01\x12\x44\n\rsucceededpays\x18\x03 \x01(\x0b\x32(.cln.AutocleanonceAutocleanSucceededpaysH\x02\x88\x01\x01\x12>\n\nfailedpays\x18\x04 \x01(\x0b\x32%.cln.AutocleanonceAutocleanFailedpaysH\x03\x88\x01\x01\x12\x42\n\x0cpaidinvoices\x18\x05 \x01(\x0b\x32\'.cln.AutocleanonceAutocleanPaidinvoicesH\x04\x88\x01\x01\x12H\n\x0f\x65xpiredinvoices\x18\x06 \x01(\x0b\x32*.cln.AutocleanonceAutocleanExpiredinvoicesH\x05\x88\x01\x01\x42\x14\n\x12_succeededforwardsB\x11\n\x0f_failedforwardsB\x10\n\x0e_succeededpaysB\r\n\x0b_failedpaysB\x0f\n\r_paidinvoicesB\x12\n\x10_expiredinvoices\"M\n\'AutocleanonceAutocleanSucceededforwards\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"J\n$AutocleanonceAutocleanFailedforwards\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"I\n#AutocleanonceAutocleanSucceededpays\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"F\n AutocleanonceAutocleanFailedpays\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"H\n\"AutocleanonceAutocleanPaidinvoices\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"K\n%AutocleanonceAutocleanExpiredinvoices\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"W\n\x16\x41utocleanstatusRequest\x12/\n\tsubsystem\x18\x01 \x01(\x0e\x32\x17.cln.AutocleanSubsystemH\x00\x88\x01\x01\x42\x0c\n\n_subsystem\"K\n\x17\x41utocleanstatusResponse\x12\x30\n\tautoclean\x18\x01 \x01(\x0b\x32\x1d.cln.AutocleanstatusAutoclean\"\xbf\x04\n\x18\x41utocleanstatusAutoclean\x12N\n\x11succeededforwards\x18\x01 \x01(\x0b\x32..cln.AutocleanstatusAutocleanSucceededforwardsH\x00\x88\x01\x01\x12H\n\x0e\x66\x61iledforwards\x18\x02 \x01(\x0b\x32+.cln.AutocleanstatusAutocleanFailedforwardsH\x01\x88\x01\x01\x12\x46\n\rsucceededpays\x18\x03 \x01(\x0b\x32*.cln.AutocleanstatusAutocleanSucceededpaysH\x02\x88\x01\x01\x12@\n\nfailedpays\x18\x04 \x01(\x0b\x32\'.cln.AutocleanstatusAutocleanFailedpaysH\x03\x88\x01\x01\x12\x44\n\x0cpaidinvoices\x18\x05 \x01(\x0b\x32).cln.AutocleanstatusAutocleanPaidinvoicesH\x04\x88\x01\x01\x12J\n\x0f\x65xpiredinvoices\x18\x06 \x01(\x0b\x32,.cln.AutocleanstatusAutocleanExpiredinvoicesH\x05\x88\x01\x01\x42\x14\n\x12_succeededforwardsB\x11\n\x0f_failedforwardsB\x10\n\x0e_succeededpaysB\r\n\x0b_failedpaysB\x0f\n\r_paidinvoicesB\x12\n\x10_expiredinvoices\"g\n)AutocleanstatusAutocleanSucceededforwards\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"d\n&AutocleanstatusAutocleanFailedforwards\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"c\n%AutocleanstatusAutocleanSucceededpays\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"`\n\"AutocleanstatusAutocleanFailedpays\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"b\n$AutocleanstatusAutocleanPaidinvoices\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"e\n\'AutocleanstatusAutocleanExpiredinvoices\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"U\n\x13\x43heckmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\r\n\x05zbase\x18\x02 \x01(\t\x12\x13\n\x06pubkey\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x42\t\n\x07_pubkey\"8\n\x14\x43heckmessageResponse\x12\x10\n\x08verified\x18\x01 \x01(\x08\x12\x0e\n\x06pubkey\x18\x02 \x01(\x0c\"\xcb\x02\n\x0c\x43loseRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1e\n\x11unilateraltimeout\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\tH\x01\x88\x01\x01\x12!\n\x14\x66\x65\x65_negotiation_step\x18\x04 \x01(\tH\x02\x88\x01\x01\x12)\n\rwrong_funding\x18\x05 \x01(\x0b\x32\r.cln.OutpointH\x03\x88\x01\x01\x12\x1f\n\x12\x66orce_lease_closed\x18\x06 \x01(\x08H\x04\x88\x01\x01\x12\x1e\n\x08\x66\x65\x65range\x18\x07 \x03(\x0b\x32\x0c.cln.FeerateB\x14\n\x12_unilateraltimeoutB\x0e\n\x0c_destinationB\x17\n\x15_fee_negotiation_stepB\x10\n\x0e_wrong_fundingB\x15\n\x13_force_lease_closed\"\xab\x01\n\rCloseResponse\x12/\n\titem_type\x18\x01 \x01(\x0e\x32\x1c.cln.CloseResponse.CloseType\x12\x0f\n\x02tx\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x11\n\x04txid\x18\x03 \x01(\x0cH\x01\x88\x01\x01\"5\n\tCloseType\x12\n\n\x06MUTUAL\x10\x00\x12\x0e\n\nUNILATERAL\x10\x01\x12\x0c\n\x08UNOPENED\x10\x02\x42\x05\n\x03_txB\x07\n\x05_txid\"T\n\x0e\x43onnectRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\x04host\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_hostB\x07\n\x05_port\"\xb4\x01\n\x0f\x43onnectResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0c\x12\x38\n\tdirection\x18\x03 \x01(\x0e\x32%.cln.ConnectResponse.ConnectDirection\x12$\n\x07\x61\x64\x64ress\x18\x04 \x01(\x0b\x32\x13.cln.ConnectAddress\"#\n\x10\x43onnectDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\"\xfb\x01\n\x0e\x43onnectAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.ConnectAddress.ConnectAddressType\x12\x13\n\x06socket\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x11\n\x04port\x18\x04 \x01(\rH\x02\x88\x01\x01\"P\n\x12\x43onnectAddressType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\t\n\x07_socketB\n\n\x08_addressB\x07\n\x05_port\"J\n\x14\x43reateinvoiceRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x10\n\x08preimage\x18\x03 \x01(\x0c\"\xfe\x05\n\x15\x43reateinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x04 \x01(\x0c\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12>\n\x06status\x18\x06 \x01(\x0e\x32..cln.CreateinvoiceResponse.CreateinvoiceStatus\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x16\n\tpay_index\x18\t \x01(\x04H\x03\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x06\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0f \x01(\tH\x08\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\t\x88\x01\x01\x12;\n\rpaid_outpoint\x18\x11 \x01(\x0b\x32\x1f.cln.CreateinvoicePaid_outpointH\n\x88\x01\x01\"8\n\x13\x43reateinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimageB\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_noteB\x10\n\x0e_created_indexB\x10\n\x0e_paid_outpoint\":\n\x1a\x43reateinvoicePaid_outpoint\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\"\xb4\x02\n\x10\x44\x61tastoreRequest\x12\x10\n\x03hex\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x36\n\x04mode\x18\x03 \x01(\x0e\x32#.cln.DatastoreRequest.DatastoreModeH\x01\x88\x01\x01\x12\x17\n\ngeneration\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x13\n\x06string\x18\x06 \x01(\tH\x03\x88\x01\x01\"p\n\rDatastoreMode\x12\x0f\n\x0bMUST_CREATE\x10\x00\x12\x10\n\x0cMUST_REPLACE\x10\x01\x12\x15\n\x11\x43REATE_OR_REPLACE\x10\x02\x12\x0f\n\x0bMUST_APPEND\x10\x03\x12\x14\n\x10\x43REATE_OR_APPEND\x10\x04\x42\x06\n\x04_hexB\x07\n\x05_modeB\r\n\x0b_generationB\t\n\x07_string\"\x82\x01\n\x11\x44\x61tastoreResponse\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x0b\n\x03key\x18\x05 \x03(\tB\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"$\n\x15\x44\x61tastoreusageRequest\x12\x0b\n\x03key\x18\x01 \x03(\t\"S\n\x16\x44\x61tastoreusageResponse\x12\x39\n\x0e\x64\x61tastoreusage\x18\x01 \x01(\x0b\x32!.cln.DatastoreusageDatastoreusage\"@\n\x1c\x44\x61tastoreusageDatastoreusage\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x13\n\x0btotal_bytes\x18\x02 \x01(\x04\"\x9d\x01\n\x12\x43reateonionRequest\x12\"\n\x04hops\x18\x01 \x03(\x0b\x32\x14.cln.CreateonionHops\x12\x11\n\tassocdata\x18\x02 \x01(\x0c\x12\x18\n\x0bsession_key\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x17\n\nonion_size\x18\x04 \x01(\rH\x01\x88\x01\x01\x42\x0e\n\x0c_session_keyB\r\n\x0b_onion_size\"<\n\x13\x43reateonionResponse\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12\x16\n\x0eshared_secrets\x18\x02 \x03(\x0c\"2\n\x0f\x43reateonionHops\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"J\n\x13\x44\x65ldatastoreRequest\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x0b\n\x03key\x18\x03 \x03(\tB\r\n\x0b_generation\"\x85\x01\n\x14\x44\x65ldatastoreResponse\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x0b\n\x03key\x18\x05 \x03(\tB\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"\xb6\x01\n\x11\x44\x65linvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t\x12\x37\n\x06status\x18\x02 \x01(\x0e\x32\'.cln.DelinvoiceRequest.DelinvoiceStatus\x12\x15\n\x08\x64\x65sconly\x18\x03 \x01(\x08H\x00\x88\x01\x01\"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\x0b\n\t_desconly\"\xe6\x05\n\x12\x44\x65linvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x38\n\x06status\x18\x07 \x01(\x0e\x32(.cln.DelinvoiceResponse.DelinvoiceStatus\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0b \x01(\tH\x05\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x0c \x01(\x04H\x06\x88\x01\x01\x12\x1a\n\rupdated_index\x18\r \x01(\x04H\x07\x88\x01\x01\x12\x16\n\tpay_index\x18\x0e \x01(\x04H\x08\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\t\x88\x01\x01\x12\x14\n\x07paid_at\x18\x10 \x01(\x04H\n\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x11 \x01(\x0cH\x0b\x88\x01\x01\"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_noteB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimage\"\x9f\x01\n\x17\x44\x65vforgetchannelRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x17\n\nchannel_id\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x12\n\x05\x66orce\x18\x04 \x01(\x08H\x02\x88\x01\x01\x42\x13\n\x11_short_channel_idB\r\n\x0b_channel_idB\x08\n\x06_force\"Y\n\x18\x44\x65vforgetchannelResponse\x12\x0e\n\x06\x66orced\x18\x01 \x01(\x08\x12\x17\n\x0f\x66unding_unspent\x18\x02 \x01(\x08\x12\x14\n\x0c\x66unding_txid\x18\x03 \x01(\x0c\"\x19\n\x17\x45mergencyrecoverRequest\")\n\x18\x45mergencyrecoverResponse\x12\r\n\x05stubs\x18\x01 \x03(\x0c\"#\n\x0eRecoverRequest\x12\x11\n\thsmsecret\x18\x01 \x01(\t\"\x88\x01\n\x0fRecoverResponse\x12\x37\n\x06result\x18\x01 \x01(\x0e\x32\".cln.RecoverResponse.RecoverResultH\x00\x88\x01\x01\"1\n\rRecoverResult\x12 \n\x1cRECOVERY_RESTART_IN_PROGRESS\x10\x00\x42\t\n\x07_result\"$\n\x15RecoverchannelRequest\x12\x0b\n\x03scb\x18\x01 \x03(\x0c\"\'\n\x16RecoverchannelResponse\x12\r\n\x05stubs\x18\x01 \x03(\t\"\x99\x02\n\x0eInvoiceRequest\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\r\n\x05label\x18\x03 \x01(\t\x12\x11\n\tfallbacks\x18\x04 \x03(\t\x12\x15\n\x08preimage\x18\x05 \x01(\x0cH\x00\x88\x01\x01\x12\x11\n\x04\x63ltv\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06\x65xpiry\x18\x07 \x01(\x04H\x02\x88\x01\x01\x12\x1d\n\x15\x65xposeprivatechannels\x18\x08 \x03(\t\x12\x19\n\x0c\x64\x65schashonly\x18\t \x01(\x08H\x03\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x10.cln.AmountOrAnyB\x0b\n\t_preimageB\x07\n\x05_cltvB\t\n\x07_expiryB\x0f\n\r_deschashonly\"\x95\x03\n\x0fInvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x16\n\x0epayment_secret\x18\x03 \x01(\x0c\x12\x12\n\nexpires_at\x18\x04 \x01(\x04\x12\x1d\n\x10warning_capacity\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x1c\n\x0fwarning_offline\x18\x06 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x10warning_deadends\x18\x07 \x01(\tH\x02\x88\x01\x01\x12#\n\x16warning_private_unused\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x18\n\x0bwarning_mpp\x18\t \x01(\tH\x04\x88\x01\x01\x12\x1a\n\rcreated_index\x18\n \x01(\x04H\x05\x88\x01\x01\x42\x13\n\x11_warning_capacityB\x12\n\x10_warning_offlineB\x13\n\x11_warning_deadendsB\x19\n\x17_warning_private_unusedB\x0e\n\x0c_warning_mppB\x10\n\x0e_created_index\"\xe1\x01\n\x15InvoicerequestRequest\x12\x1b\n\x06\x61mount\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x13\n\x06issuer\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x12\n\x05label\x18\x04 \x01(\tH\x01\x88\x01\x01\x12\x1c\n\x0f\x61\x62solute_expiry\x18\x05 \x01(\x04H\x02\x88\x01\x01\x12\x17\n\nsingle_use\x18\x06 \x01(\x08H\x03\x88\x01\x01\x42\t\n\x07_issuerB\x08\n\x06_labelB\x12\n\x10_absolute_expiryB\r\n\x0b_single_use\"\x8b\x01\n\x16InvoicerequestResponse\x12\x11\n\tinvreq_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"1\n\x1c\x44isableinvoicerequestRequest\x12\x11\n\tinvreq_id\x18\x01 \x01(\t\"\x92\x01\n\x1d\x44isableinvoicerequestResponse\x12\x11\n\tinvreq_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"l\n\x1aListinvoicerequestsRequest\x12\x16\n\tinvreq_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x61\x63tive_only\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\x0c\n\n_invreq_idB\x0e\n\x0c_active_only\"_\n\x1bListinvoicerequestsResponse\x12@\n\x0finvoicerequests\x18\x01 \x03(\x0b\x32\'.cln.ListinvoicerequestsInvoicerequests\"\x97\x01\n\"ListinvoicerequestsInvoicerequests\x12\x11\n\tinvreq_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"#\n\x14ListdatastoreRequest\x12\x0b\n\x03key\x18\x02 \x03(\t\"G\n\x15ListdatastoreResponse\x12.\n\tdatastore\x18\x01 \x03(\x0b\x32\x1b.cln.ListdatastoreDatastore\"\x87\x01\n\x16ListdatastoreDatastore\x12\x0b\n\x03key\x18\x01 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"\xde\x02\n\x13ListinvoicesRequest\x12\x12\n\x05label\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tinvstring\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08offer_id\x18\x04 \x01(\tH\x03\x88\x01\x01\x12>\n\x05index\x18\x05 \x01(\x0e\x32*.cln.ListinvoicesRequest.ListinvoicesIndexH\x04\x88\x01\x01\x12\x12\n\x05start\x18\x06 \x01(\x04H\x05\x88\x01\x01\x12\x12\n\x05limit\x18\x07 \x01(\rH\x06\x88\x01\x01\"-\n\x11ListinvoicesIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\x08\n\x06_labelB\x0c\n\n_invstringB\x0f\n\r_payment_hashB\x0b\n\t_offer_idB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListinvoicesResponse\x12+\n\x08invoices\x18\x01 \x03(\x0b\x32\x19.cln.ListinvoicesInvoices\"\xd4\x06\n\x14ListinvoicesInvoices\x12\r\n\x05label\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListinvoicesInvoices.ListinvoicesInvoicesStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x16\n\tpay_index\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x14\n\x07paid_at\x18\r \x01(\x04H\x07\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0e \x01(\x0cH\x08\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0f \x01(\tH\t\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\n\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x0b\x88\x01\x01\x12\x42\n\rpaid_outpoint\x18\x12 \x01(\x0b\x32&.cln.ListinvoicesInvoicesPaid_outpointH\x0c\x88\x01\x01\"?\n\x1aListinvoicesInvoicesStatus\x12\n\n\x06UNPAID\x10\x00\x12\x08\n\x04PAID\x10\x01\x12\x0b\n\x07\x45XPIRED\x10\x02\x42\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x11\n\x0f_local_offer_idB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimageB\x14\n\x12_invreq_payer_noteB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x10\n\x0e_paid_outpoint\"A\n!ListinvoicesInvoicesPaid_outpoint\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\"\xb4\x03\n\x10SendonionRequest\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12*\n\tfirst_hop\x18\x02 \x01(\x0b\x32\x17.cln.SendonionFirst_hop\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\x05label\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x16\n\x0eshared_secrets\x18\x05 \x03(\x0c\x12\x13\n\x06partid\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\t \x01(\x0cH\x03\x88\x01\x01\x12\x14\n\x07groupid\x18\x0b \x01(\x04H\x04\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\r \x01(\x0cH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0e \x01(\tH\x07\x88\x01\x01\x42\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\x0e\n\x0c_destinationB\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x10\n\x0e_localinvreqidB\x0e\n\x0c_description\"\xe7\x04\n\x11SendonionResponse\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x36\n\x06status\x18\x03 \x01(\x0e\x32&.cln.SendonionResponse.SendonionStatus\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x12\n\ncreated_at\x18\x06 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\n \x01(\tH\x04\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0b \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x07message\x18\x0c \x01(\tH\x06\x88\x01\x01\x12\x13\n\x06partid\x18\r \x01(\x04H\x07\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x0e \x01(\x04H\x08\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0f \x01(\x04H\t\x88\x01\x01\",\n\x0fSendonionStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\n\n\x08_messageB\t\n\x07_partidB\x10\n\x0e_created_indexB\x10\n\x0e_updated_index\"Q\n\x12SendonionFirst_hop\x12\n\n\x02id\x18\x01 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r\"\xa0\x03\n\x13ListsendpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12@\n\x06status\x18\x03 \x01(\x0e\x32+.cln.ListsendpaysRequest.ListsendpaysStatusH\x02\x88\x01\x01\x12>\n\x05index\x18\x04 \x01(\x0e\x32*.cln.ListsendpaysRequest.ListsendpaysIndexH\x03\x88\x01\x01\x12\x12\n\x05start\x18\x05 \x01(\x04H\x04\x88\x01\x01\x12\x12\n\x05limit\x18\x06 \x01(\rH\x05\x88\x01\x01\";\n\x12ListsendpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\"-\n\x11ListsendpaysIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_statusB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListsendpaysResponse\x12+\n\x08payments\x18\x01 \x03(\x0b\x32\x19.cln.ListsendpaysPayments\"\xfc\x05\n\x14ListsendpaysPayments\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0f\n\x07groupid\x18\x02 \x01(\x04\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListsendpaysPayments.ListsendpaysPaymentsStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\n \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0b \x01(\tH\x04\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x05\x88\x01\x01\x12\x17\n\nerroronion\x18\r \x01(\x0cH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0e \x01(\tH\x07\x88\x01\x01\x12\x13\n\x06partid\x18\x0f \x01(\x04H\x08\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\t\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\n\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x12 \x01(\x04H\x0b\x88\x01\x01\"C\n\x1aListsendpaysPaymentsStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\r\n\x0b_erroronionB\x0e\n\x0c_descriptionB\t\n\x07_partidB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0f\n\r_completed_at\"\x19\n\x17ListtransactionsRequest\"S\n\x18ListtransactionsResponse\x12\x37\n\x0ctransactions\x18\x01 \x03(\x0b\x32!.cln.ListtransactionsTransactions\"\xf8\x01\n\x1cListtransactionsTransactions\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\r\n\x05rawtx\x18\x02 \x01(\x0c\x12\x13\n\x0b\x62lockheight\x18\x03 \x01(\r\x12\x0f\n\x07txindex\x18\x04 \x01(\r\x12\x10\n\x08locktime\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x37\n\x06inputs\x18\t \x03(\x0b\x32\'.cln.ListtransactionsTransactionsInputs\x12\x39\n\x07outputs\x18\n \x03(\x0b\x32(.cln.ListtransactionsTransactionsOutputs\"S\n\"ListtransactionsTransactionsInputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\r\n\x05index\x18\x02 \x01(\r\x12\x10\n\x08sequence\x18\x03 \x01(\r\"l\n#ListtransactionsTransactionsOutputs\x12\r\n\x05index\x18\x01 \x01(\r\x12\x14\n\x0cscriptPubKey\x18\x03 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\"M\n\x11MakesecretRequest\x12\x10\n\x03hex\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06string\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x06\n\x04_hexB\t\n\x07_string\"$\n\x12MakesecretResponse\x12\x0e\n\x06secret\x18\x01 \x01(\x0c\"\x93\x04\n\nPayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x01\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x03\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x17\n\nriskfactor\x18\x08 \x01(\x01H\x05\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\n \x03(\t\x12 \n\x06maxfee\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0c \x01(\tH\x07\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\r \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\x0e \x01(\x0cH\t\x88\x01\x01\x12&\n\x0cpartial_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\n\x88\x01\x01\x42\x08\n\x06_labelB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\r\n\x0b_riskfactorB\t\n\x07_maxfeeB\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\x10\n\x0e_localinvreqidB\x0f\n\r_partial_msat\"\xfb\x02\n\x0bPayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12*\n\x06status\x18\t \x01(\x0e\x32\x1a.cln.PayResponse.PayStatus\"2\n\tPayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion\"*\n\x10ListnodesRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"7\n\x11ListnodesResponse\x12\"\n\x05nodes\x18\x01 \x03(\x0b\x32\x13.cln.ListnodesNodes\"\xba\x02\n\x0eListnodesNodes\x12\x0e\n\x06nodeid\x18\x01 \x01(\x0c\x12\x1b\n\x0elast_timestamp\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x12\n\x05\x61lias\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05\x63olor\x18\x04 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x05 \x01(\x0cH\x03\x88\x01\x01\x12/\n\taddresses\x18\x06 \x03(\x0b\x32\x1c.cln.ListnodesNodesAddresses\x12\x42\n\x10option_will_fund\x18\x07 \x01(\x0b\x32#.cln.ListnodesNodesOption_will_fundH\x04\x88\x01\x01\x42\x11\n\x0f_last_timestampB\x08\n\x06_aliasB\x08\n\x06_colorB\x0b\n\t_featuresB\x13\n\x11_option_will_fund\"\xf4\x01\n\x1eListnodesNodesOption_will_fund\x12(\n\x13lease_fee_base_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x17\n\x0flease_fee_basis\x18\x02 \x01(\r\x12\x16\n\x0e\x66unding_weight\x18\x03 \x01(\r\x12.\n\x19\x63hannel_fee_max_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x30\n(channel_fee_max_proportional_thousandths\x18\x05 \x01(\r\x12\x15\n\rcompact_lease\x18\x06 \x01(\x0c\"\xe8\x01\n\x17ListnodesNodesAddresses\x12K\n\titem_type\x18\x01 \x01(\x0e\x32\x38.cln.ListnodesNodesAddresses.ListnodesNodesAddressesType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\"P\n\x1bListnodesNodesAddressesType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_address\"g\n\x15WaitanyinvoiceRequest\x12\x1a\n\rlastpay_index\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07timeout\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x10\n\x0e_lastpay_indexB\n\n\x08_timeout\"\xd4\x05\n\x16WaitanyinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12@\n\x06status\x18\x04 \x01(\x0e\x32\x30.cln.WaitanyinvoiceResponse.WaitanyinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x04\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x07\x88\x01\x01\x12\x1a\n\rcreated_index\x18\r \x01(\x04H\x08\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0e \x01(\x04H\t\x88\x01\x01\x12<\n\rpaid_outpoint\x18\x0f \x01(\x0b\x32 .cln.WaitanyinvoicePaid_outpointH\n\x88\x01\x01\"-\n\x14WaitanyinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimageB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x10\n\x0e_paid_outpoint\";\n\x1bWaitanyinvoicePaid_outpoint\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\"#\n\x12WaitinvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t\"\xc5\x05\n\x13WaitinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitinvoiceResponse.WaitinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x04\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x07\x88\x01\x01\x12\x1a\n\rcreated_index\x18\r \x01(\x04H\x08\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0e \x01(\x04H\t\x88\x01\x01\x12\x39\n\rpaid_outpoint\x18\x0f \x01(\x0b\x32\x1d.cln.WaitinvoicePaid_outpointH\n\x88\x01\x01\"*\n\x11WaitinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimageB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x10\n\x0e_paid_outpoint\"8\n\x18WaitinvoicePaid_outpoint\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\"\x8e\x01\n\x12WaitsendpayRequest\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x13\n\x06partid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07timeout\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x14\n\x07groupid\x18\x04 \x01(\x04H\x02\x88\x01\x01\x42\t\n\x07_partidB\n\n\x08_timeoutB\n\n\x08_groupid\"\x8e\x05\n\x13WaitsendpayResponse\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitsendpayResponse.WaitsendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0e \x01(\x01H\x08\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x0f \x01(\x04H\t\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x10 \x01(\x04H\n\x88\x01\x01\"!\n\x11WaitsendpayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\x0f\n\r_completed_atB\x10\n\x0e_created_indexB\x10\n\x0e_updated_index\"\x97\x01\n\x0eNewaddrRequest\x12@\n\x0b\x61\x64\x64resstype\x18\x01 \x01(\x0e\x32&.cln.NewaddrRequest.NewaddrAddresstypeH\x00\x88\x01\x01\"3\n\x12NewaddrAddresstype\x12\n\n\x06\x42\x45\x43H32\x10\x00\x12\x07\n\x03\x41LL\x10\x02\x12\x08\n\x04P2TR\x10\x03\x42\x0e\n\x0c_addresstype\"M\n\x0fNewaddrResponse\x12\x13\n\x06\x62\x65\x63h32\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04p2tr\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_bech32B\x07\n\x05_p2tr\"\xb9\x01\n\x0fWithdrawRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\t\x12!\n\x07satoshi\x18\x02 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12\"\n\x07\x66\x65\x65rate\x18\x05 \x01(\x0b\x32\x0c.cln.FeerateH\x01\x88\x01\x01\x42\n\n\x08_minconfB\n\n\x08_feerate\":\n\x10WithdrawResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x0c\n\x04psbt\x18\x03 \x01(\t\"\xaf\x03\n\x0eKeysendRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\x0c\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x01\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x03\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12+\n\nroutehints\x18\x08 \x01(\x0b\x32\x12.cln.RoutehintListH\x05\x88\x01\x01\x12&\n\textratlvs\x18\t \x01(\x0b\x32\x0e.cln.TlvStreamH\x06\x88\x01\x01\x12 \n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x0b.cln.Amount\x12 \n\x06maxfee\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x07\x88\x01\x01\x42\x08\n\x06_labelB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\r\n\x0b_routehintsB\x0c\n\n_extratlvsB\t\n\x07_maxfee\"\xf2\x02\n\x0fKeysendResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x32\n\x06status\x18\t \x01(\x0e\x32\".cln.KeysendResponse.KeysendStatus\"\x1d\n\rKeysendStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion\"\xa4\x03\n\x0f\x46undpsbtRequest\x12!\n\x07satoshi\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x14\n\x07minconf\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\x08 \x01(\x08H\x04\x88\x01\x01\x12\x17\n\nnonwrapped\x18\t \x01(\x08H\x05\x88\x01\x01\x12#\n\x16opening_anchor_channel\x18\n \x01(\x08H\x06\x88\x01\x01\x42\n\n\x08_minconfB\n\n\x08_reserveB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\x13\n\x11_excess_as_changeB\r\n\x0b_nonwrappedB\x19\n\x17_opening_anchor_channel\"\xd9\x01\n\x10\x46undpsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.FundpsbtReservationsB\x10\n\x0e_change_outnum\"u\n\x14\x46undpsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\"A\n\x0fSendpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x14\n\x07reserve\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\n\n\x08_reserve\",\n\x10SendpsbtResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"1\n\x0fSignpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x10\n\x08signonly\x18\x02 \x03(\r\"\'\n\x10SignpsbtResponse\x12\x13\n\x0bsigned_psbt\x18\x01 \x01(\t\"\xa0\x03\n\x0fUtxopsbtRequest\x12!\n\x07satoshi\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x00\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x02\x88\x01\x01\x12\x17\n\nreservedok\x18\x08 \x01(\x08H\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\t \x01(\x08H\x04\x88\x01\x01\x12#\n\x16opening_anchor_channel\x18\n \x01(\x08H\x05\x88\x01\x01\x42\n\n\x08_reserveB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\r\n\x0b_reservedokB\x13\n\x11_excess_as_changeB\x19\n\x17_opening_anchor_channel\"\xd9\x01\n\x10UtxopsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.UtxopsbtReservationsB\x10\n\x0e_change_outnum\"u\n\x14UtxopsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\" \n\x10TxdiscardRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\"6\n\x11TxdiscardResponse\x12\x13\n\x0bunsigned_tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"\xa4\x01\n\x10TxprepareRequest\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12 \n\x07outputs\x18\x05 \x03(\x0b\x32\x0f.cln.OutputDescB\n\n\x08_feerateB\n\n\x08_minconf\"D\n\x11TxprepareResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x13\n\x0bunsigned_tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"\x1d\n\rTxsendRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\"8\n\x0eTxsendResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\n\n\x02tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"1\n\x17ListpeerchannelsRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"K\n\x18ListpeerchannelsResponse\x12/\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1d.cln.ListpeerchannelsChannels\"\xd7\x1b\n\x18ListpeerchannelsChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x16\n\x0epeer_connected\x18\x02 \x01(\x08\x12J\n\x05state\x18\x03 \x01(\x0e\x32;.cln.ListpeerchannelsChannels.ListpeerchannelsChannelsState\x12\x19\n\x0cscratch_txid\x18\x04 \x01(\x0cH\x00\x88\x01\x01\x12:\n\x07\x66\x65\x65rate\x18\x06 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsFeerateH\x01\x88\x01\x01\x12\x12\n\x05owner\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x1d\n\x10short_channel_id\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x17\n\nchannel_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x19\n\x0c\x66unding_txid\x18\n \x01(\x0cH\x05\x88\x01\x01\x12\x1b\n\x0e\x66unding_outnum\x18\x0b \x01(\rH\x06\x88\x01\x01\x12\x1c\n\x0finitial_feerate\x18\x0c \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0clast_feerate\x18\r \x01(\tH\x08\x88\x01\x01\x12\x19\n\x0cnext_feerate\x18\x0e \x01(\tH\t\x88\x01\x01\x12\x1a\n\rnext_fee_step\x18\x0f \x01(\rH\n\x88\x01\x01\x12\x37\n\x08inflight\x18\x10 \x03(\x0b\x32%.cln.ListpeerchannelsChannelsInflight\x12\x15\n\x08\x63lose_to\x18\x11 \x01(\x0cH\x0b\x88\x01\x01\x12\x14\n\x07private\x18\x12 \x01(\x08H\x0c\x88\x01\x01\x12 \n\x06opener\x18\x13 \x01(\x0e\x32\x10.cln.ChannelSide\x12%\n\x06\x63loser\x18\x14 \x01(\x0e\x32\x10.cln.ChannelSideH\r\x88\x01\x01\x12:\n\x07\x66unding\x18\x16 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsFundingH\x0e\x88\x01\x01\x12$\n\nto_us_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x0f\x88\x01\x01\x12(\n\x0emin_to_us_msat\x18\x18 \x01(\x0b\x32\x0b.cln.AmountH\x10\x88\x01\x01\x12(\n\x0emax_to_us_msat\x18\x19 \x01(\x0b\x32\x0b.cln.AmountH\x11\x88\x01\x01\x12$\n\ntotal_msat\x18\x1a \x01(\x0b\x32\x0b.cln.AmountH\x12\x88\x01\x01\x12\'\n\rfee_base_msat\x18\x1b \x01(\x0b\x32\x0b.cln.AmountH\x13\x88\x01\x01\x12(\n\x1b\x66\x65\x65_proportional_millionths\x18\x1c \x01(\rH\x14\x88\x01\x01\x12)\n\x0f\x64ust_limit_msat\x18\x1d \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12\x30\n\x16max_total_htlc_in_msat\x18\x1e \x01(\x0b\x32\x0b.cln.AmountH\x16\x88\x01\x01\x12,\n\x12their_reserve_msat\x18\x1f \x01(\x0b\x32\x0b.cln.AmountH\x17\x88\x01\x01\x12*\n\x10our_reserve_msat\x18 \x01(\x0b\x32\x0b.cln.AmountH\x18\x88\x01\x01\x12(\n\x0espendable_msat\x18! \x01(\x0b\x32\x0b.cln.AmountH\x19\x88\x01\x01\x12)\n\x0freceivable_msat\x18\" \x01(\x0b\x32\x0b.cln.AmountH\x1a\x88\x01\x01\x12.\n\x14minimum_htlc_in_msat\x18# \x01(\x0b\x32\x0b.cln.AmountH\x1b\x88\x01\x01\x12/\n\x15minimum_htlc_out_msat\x18$ \x01(\x0b\x32\x0b.cln.AmountH\x1c\x88\x01\x01\x12/\n\x15maximum_htlc_out_msat\x18% \x01(\x0b\x32\x0b.cln.AmountH\x1d\x88\x01\x01\x12 \n\x13their_to_self_delay\x18& \x01(\rH\x1e\x88\x01\x01\x12\x1e\n\x11our_to_self_delay\x18\' \x01(\rH\x1f\x88\x01\x01\x12\x1f\n\x12max_accepted_htlcs\x18( \x01(\rH \x88\x01\x01\x12\x36\n\x05\x61lias\x18) \x01(\x0b\x32\".cln.ListpeerchannelsChannelsAliasH!\x88\x01\x01\x12\x0e\n\x06status\x18+ \x03(\t\x12 \n\x13in_payments_offered\x18, \x01(\x04H\"\x88\x01\x01\x12)\n\x0fin_offered_msat\x18- \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12\"\n\x15in_payments_fulfilled\x18. \x01(\x04H$\x88\x01\x01\x12+\n\x11in_fulfilled_msat\x18/ \x01(\x0b\x32\x0b.cln.AmountH%\x88\x01\x01\x12!\n\x14out_payments_offered\x18\x30 \x01(\x04H&\x88\x01\x01\x12*\n\x10out_offered_msat\x18\x31 \x01(\x0b\x32\x0b.cln.AmountH\'\x88\x01\x01\x12#\n\x16out_payments_fulfilled\x18\x32 \x01(\x04H(\x88\x01\x01\x12,\n\x12out_fulfilled_msat\x18\x33 \x01(\x0b\x32\x0b.cln.AmountH)\x88\x01\x01\x12\x31\n\x05htlcs\x18\x34 \x03(\x0b\x32\".cln.ListpeerchannelsChannelsHtlcs\x12\x1a\n\rclose_to_addr\x18\x35 \x01(\tH*\x88\x01\x01\x12\x1e\n\x11ignore_fee_limits\x18\x36 \x01(\x08H+\x88\x01\x01\x12:\n\x07updates\x18\x37 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsUpdatesH,\x88\x01\x01\x12#\n\x16last_stable_connection\x18\x38 \x01(\x04H-\x88\x01\x01\x12\x17\n\nlost_state\x18\x39 \x01(\x08H.\x88\x01\x01\x12\x1a\n\rreestablished\x18: \x01(\x08H/\x88\x01\x01\x12*\n\x10last_tx_fee_msat\x18; \x01(\x0b\x32\x0b.cln.AmountH0\x88\x01\x01\x12\x16\n\tdirection\x18< \x01(\rH1\x88\x01\x01\"\x80\x03\n\x1dListpeerchannelsChannelsState\x12\x0c\n\x08OPENINGD\x10\x00\x12\x1c\n\x18\x43HANNELD_AWAITING_LOCKIN\x10\x01\x12\x13\n\x0f\x43HANNELD_NORMAL\x10\x02\x12\x1a\n\x16\x43HANNELD_SHUTTING_DOWN\x10\x03\x12\x18\n\x14\x43LOSINGD_SIGEXCHANGE\x10\x04\x12\x15\n\x11\x43LOSINGD_COMPLETE\x10\x05\x12\x17\n\x13\x41WAITING_UNILATERAL\x10\x06\x12\x16\n\x12\x46UNDING_SPEND_SEEN\x10\x07\x12\x0b\n\x07ONCHAIN\x10\x08\x12\x17\n\x13\x44UALOPEND_OPEN_INIT\x10\t\x12\x1d\n\x19\x44UALOPEND_AWAITING_LOCKIN\x10\n\x12\x1c\n\x18\x43HANNELD_AWAITING_SPLICE\x10\x0b\x12\x1c\n\x18\x44UALOPEND_OPEN_COMMITTED\x10\x0c\x12\x1f\n\x1b\x44UALOPEND_OPEN_COMMIT_READY\x10\rB\x0f\n\r_scratch_txidB\n\n\x08_feerateB\x08\n\x06_ownerB\x13\n\x11_short_channel_idB\r\n\x0b_channel_idB\x0f\n\r_funding_txidB\x11\n\x0f_funding_outnumB\x12\n\x10_initial_feerateB\x0f\n\r_last_feerateB\x0f\n\r_next_feerateB\x10\n\x0e_next_fee_stepB\x0b\n\t_close_toB\n\n\x08_privateB\t\n\x07_closerB\n\n\x08_fundingB\r\n\x0b_to_us_msatB\x11\n\x0f_min_to_us_msatB\x11\n\x0f_max_to_us_msatB\r\n\x0b_total_msatB\x10\n\x0e_fee_base_msatB\x1e\n\x1c_fee_proportional_millionthsB\x12\n\x10_dust_limit_msatB\x19\n\x17_max_total_htlc_in_msatB\x15\n\x13_their_reserve_msatB\x13\n\x11_our_reserve_msatB\x11\n\x0f_spendable_msatB\x12\n\x10_receivable_msatB\x17\n\x15_minimum_htlc_in_msatB\x18\n\x16_minimum_htlc_out_msatB\x18\n\x16_maximum_htlc_out_msatB\x16\n\x14_their_to_self_delayB\x14\n\x12_our_to_self_delayB\x15\n\x13_max_accepted_htlcsB\x08\n\x06_aliasB\x16\n\x14_in_payments_offeredB\x12\n\x10_in_offered_msatB\x18\n\x16_in_payments_fulfilledB\x14\n\x12_in_fulfilled_msatB\x17\n\x15_out_payments_offeredB\x13\n\x11_out_offered_msatB\x19\n\x17_out_payments_fulfilledB\x15\n\x13_out_fulfilled_msatB\x10\n\x0e_close_to_addrB\x14\n\x12_ignore_fee_limitsB\n\n\x08_updatesB\x19\n\x17_last_stable_connectionB\r\n\x0b_lost_stateB\x10\n\x0e_reestablishedB\x13\n\x11_last_tx_fee_msatB\x0c\n\n_direction\"\xa7\x01\n\x1fListpeerchannelsChannelsUpdates\x12\x38\n\x05local\x18\x01 \x01(\x0b\x32).cln.ListpeerchannelsChannelsUpdatesLocal\x12?\n\x06remote\x18\x02 \x01(\x0b\x32*.cln.ListpeerchannelsChannelsUpdatesRemoteH\x00\x88\x01\x01\x42\t\n\x07_remote\"\xda\x01\n$ListpeerchannelsChannelsUpdatesLocal\x12&\n\x11htlc_minimum_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11htlc_maximum_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x19\n\x11\x63ltv_expiry_delta\x18\x03 \x01(\r\x12\"\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\r\"\xdb\x01\n%ListpeerchannelsChannelsUpdatesRemote\x12&\n\x11htlc_minimum_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11htlc_maximum_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x19\n\x11\x63ltv_expiry_delta\x18\x03 \x01(\r\x12\"\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\r\"?\n\x1fListpeerchannelsChannelsFeerate\x12\r\n\x05perkw\x18\x01 \x01(\r\x12\r\n\x05perkb\x18\x02 \x01(\r\"\x8b\x02\n ListpeerchannelsChannelsInflight\x12\x14\n\x0c\x66unding_txid\x18\x01 \x01(\x0c\x12\x16\n\x0e\x66unding_outnum\x18\x02 \x01(\r\x12\x0f\n\x07\x66\x65\x65rate\x18\x03 \x01(\t\x12\'\n\x12total_funding_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10our_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x19\n\x0cscratch_txid\x18\x06 \x01(\x0cH\x00\x88\x01\x01\x12\x1a\n\rsplice_amount\x18\x07 \x01(\x12H\x01\x88\x01\x01\x42\x0f\n\r_scratch_txidB\x10\n\x0e_splice_amount\"\x9d\x02\n\x1fListpeerchannelsChannelsFunding\x12%\n\x0bpushed_msat\x18\x01 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12%\n\x10local_funds_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11remote_funds_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\rfee_paid_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\'\n\rfee_rcvd_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x42\x0e\n\x0c_pushed_msatB\x10\n\x0e_fee_paid_msatB\x10\n\x0e_fee_rcvd_msat\"]\n\x1dListpeerchannelsChannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"\xf9\x02\n\x1dListpeerchannelsChannelsHtlcs\x12\\\n\tdirection\x18\x01 \x01(\x0e\x32I.cln.ListpeerchannelsChannelsHtlcs.ListpeerchannelsChannelsHtlcsDirection\x12\n\n\x02id\x18\x02 \x01(\x04\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06\x65xpiry\x18\x04 \x01(\r\x12\x14\n\x0cpayment_hash\x18\x05 \x01(\x0c\x12\x1a\n\rlocal_trimmed\x18\x06 \x01(\x08H\x00\x88\x01\x01\x12\x13\n\x06status\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x05state\x18\x08 \x01(\x0e\x32\x0e.cln.HtlcState\"9\n&ListpeerchannelsChannelsHtlcsDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\x42\x10\n\x0e_local_trimmedB\t\n\x07_status\"3\n\x19ListclosedchannelsRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"[\n\x1aListclosedchannelsResponse\x12=\n\x0e\x63losedchannels\x18\x01 \x03(\x0b\x32%.cln.ListclosedchannelsClosedchannels\"\xf2\t\n ListclosedchannelsClosedchannels\x12\x14\n\x07peer_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\nchannel_id\x18\x02 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x03 \x01(\tH\x01\x88\x01\x01\x12>\n\x05\x61lias\x18\x04 \x01(\x0b\x32*.cln.ListclosedchannelsClosedchannelsAliasH\x02\x88\x01\x01\x12 \n\x06opener\x18\x05 \x01(\x0e\x32\x10.cln.ChannelSide\x12%\n\x06\x63loser\x18\x06 \x01(\x0e\x32\x10.cln.ChannelSideH\x03\x88\x01\x01\x12\x0f\n\x07private\x18\x07 \x01(\x08\x12\x1f\n\x17total_local_commitments\x18\t \x01(\x04\x12 \n\x18total_remote_commitments\x18\n \x01(\x04\x12\x18\n\x10total_htlcs_sent\x18\x0b \x01(\x04\x12\x14\n\x0c\x66unding_txid\x18\x0c \x01(\x0c\x12\x16\n\x0e\x66unding_outnum\x18\r \x01(\r\x12\x0e\n\x06leased\x18\x0e \x01(\x08\x12/\n\x15\x66unding_fee_paid_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12/\n\x15\x66unding_fee_rcvd_msat\x18\x10 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12-\n\x13\x66unding_pushed_msat\x18\x11 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1f\n\ntotal_msat\x18\x12 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x66inal_to_us_msat\x18\x13 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0emin_to_us_msat\x18\x14 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0emax_to_us_msat\x18\x15 \x01(\x0b\x32\x0b.cln.Amount\x12!\n\x14last_commitment_txid\x18\x16 \x01(\x0cH\x07\x88\x01\x01\x12\x32\n\x18last_commitment_fee_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x66\n\x0b\x63lose_cause\x18\x18 \x01(\x0e\x32Q.cln.ListclosedchannelsClosedchannels.ListclosedchannelsClosedchannelsClose_cause\x12#\n\x16last_stable_connection\x18\x19 \x01(\x04H\t\x88\x01\x01\"v\n+ListclosedchannelsClosedchannelsClose_cause\x12\x0b\n\x07UNKNOWN\x10\x00\x12\t\n\x05LOCAL\x10\x01\x12\x08\n\x04USER\x10\x02\x12\n\n\x06REMOTE\x10\x03\x12\x0c\n\x08PROTOCOL\x10\x04\x12\x0b\n\x07ONCHAIN\x10\x05\x42\n\n\x08_peer_idB\x13\n\x11_short_channel_idB\x08\n\x06_aliasB\t\n\x07_closerB\x18\n\x16_funding_fee_paid_msatB\x18\n\x16_funding_fee_rcvd_msatB\x16\n\x14_funding_pushed_msatB\x17\n\x15_last_commitment_txidB\x1b\n\x19_last_commitment_fee_msatB\x19\n\x17_last_stable_connection\"e\n%ListclosedchannelsClosedchannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"L\n\x10\x44\x65\x63odepayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xc7\x04\n\x11\x44\x65\x63odepayResponse\x12\x10\n\x08\x63urrency\x18\x01 \x01(\t\x12\x12\n\ncreated_at\x18\x02 \x01(\x04\x12\x0e\n\x06\x65xpiry\x18\x03 \x01(\x04\x12\r\n\x05payee\x18\x04 \x01(\x0c\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x11\n\tsignature\x18\x07 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x10\x64\x65scription_hash\x18\t \x01(\x0cH\x02\x88\x01\x01\x12\x1d\n\x15min_final_cltv_expiry\x18\n \x01(\r\x12\x1b\n\x0epayment_secret\x18\x0b \x01(\x0cH\x03\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x0c \x01(\x0cH\x04\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\r \x01(\x0cH\x05\x88\x01\x01\x12*\n\tfallbacks\x18\x0e \x03(\x0b\x32\x17.cln.DecodepayFallbacks\x12\"\n\x05\x65xtra\x18\x10 \x03(\x0b\x32\x13.cln.DecodepayExtra\x12-\n\x06routes\x18\x11 \x01(\x0b\x32\x18.cln.DecodeRoutehintListH\x06\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x13\n\x11_description_hashB\x11\n\x0f_payment_secretB\x0b\n\t_featuresB\x13\n\x11_payment_metadataB\t\n\x07_routes\"\xd0\x01\n\x12\x44\x65\x63odepayFallbacks\x12\x41\n\titem_type\x18\x01 \x01(\x0e\x32..cln.DecodepayFallbacks.DecodepayFallbacksType\x12\x11\n\x04\x61\x64\x64r\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x0b\n\x03hex\x18\x03 \x01(\x0c\"N\n\x16\x44\x65\x63odepayFallbacksType\x12\t\n\x05P2PKH\x10\x00\x12\x08\n\x04P2SH\x10\x01\x12\n\n\x06P2WPKH\x10\x02\x12\t\n\x05P2WSH\x10\x03\x12\x08\n\x04P2TR\x10\x04\x42\x07\n\x05_addr\"+\n\x0e\x44\x65\x63odepayExtra\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\"\x1f\n\rDecodeRequest\x12\x0e\n\x06string\x18\x01 \x01(\t\"\xec%\n\x0e\x44\x65\x63odeResponse\x12\x31\n\titem_type\x18\x01 \x01(\x0e\x32\x1e.cln.DecodeResponse.DecodeType\x12\r\n\x05valid\x18\x02 \x01(\x08\x12\x15\n\x08offer_id\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0coffer_chains\x18\x04 \x03(\x0c\x12\x1b\n\x0eoffer_metadata\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x1b\n\x0eoffer_currency\x18\x06 \x01(\tH\x02\x88\x01\x01\x12+\n\x1ewarning_unknown_offer_currency\x18\x07 \x01(\tH\x03\x88\x01\x01\x12 \n\x13\x63urrency_minor_unit\x18\x08 \x01(\rH\x04\x88\x01\x01\x12\x19\n\x0coffer_amount\x18\t \x01(\x04H\x05\x88\x01\x01\x12+\n\x11offer_amount_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1e\n\x11offer_description\x18\x0b \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0coffer_issuer\x18\x0c \x01(\tH\x08\x88\x01\x01\x12\x1b\n\x0eoffer_features\x18\r \x01(\x0cH\t\x88\x01\x01\x12\"\n\x15offer_absolute_expiry\x18\x0e \x01(\x04H\n\x88\x01\x01\x12\x1f\n\x12offer_quantity_max\x18\x0f \x01(\x04H\x0b\x88\x01\x01\x12+\n\x0boffer_paths\x18\x10 \x03(\x0b\x32\x16.cln.DecodeOffer_paths\x12\x1a\n\roffer_node_id\x18\x11 \x01(\x0cH\x0c\x88\x01\x01\x12*\n\x1dwarning_missing_offer_node_id\x18\x14 \x01(\tH\r\x88\x01\x01\x12.\n!warning_invalid_offer_description\x18\x15 \x01(\tH\x0e\x88\x01\x01\x12.\n!warning_missing_offer_description\x18\x16 \x01(\tH\x0f\x88\x01\x01\x12+\n\x1ewarning_invalid_offer_currency\x18\x17 \x01(\tH\x10\x88\x01\x01\x12)\n\x1cwarning_invalid_offer_issuer\x18\x18 \x01(\tH\x11\x88\x01\x01\x12\x1c\n\x0finvreq_metadata\x18\x19 \x01(\x0cH\x12\x88\x01\x01\x12\x1c\n\x0finvreq_payer_id\x18\x1a \x01(\x0cH\x13\x88\x01\x01\x12\x19\n\x0cinvreq_chain\x18\x1b \x01(\x0cH\x14\x88\x01\x01\x12,\n\x12invreq_amount_msat\x18\x1c \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12\x1c\n\x0finvreq_features\x18\x1d \x01(\x0cH\x16\x88\x01\x01\x12\x1c\n\x0finvreq_quantity\x18\x1e \x01(\x04H\x17\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x1f \x01(\tH\x18\x88\x01\x01\x12&\n\x19invreq_recurrence_counter\x18 \x01(\rH\x19\x88\x01\x01\x12$\n\x17invreq_recurrence_start\x18! \x01(\rH\x1a\x88\x01\x01\x12,\n\x1fwarning_missing_invreq_metadata\x18# \x01(\tH\x1b\x88\x01\x01\x12,\n\x1fwarning_missing_invreq_payer_id\x18$ \x01(\tH\x1c\x88\x01\x01\x12.\n!warning_invalid_invreq_payer_note\x18% \x01(\tH\x1d\x88\x01\x01\x12\x36\n)warning_missing_invoice_request_signature\x18& \x01(\tH\x1e\x88\x01\x01\x12\x36\n)warning_invalid_invoice_request_signature\x18\' \x01(\tH\x1f\x88\x01\x01\x12\x1f\n\x12invoice_created_at\x18) \x01(\x04H \x88\x01\x01\x12$\n\x17invoice_relative_expiry\x18* \x01(\rH!\x88\x01\x01\x12!\n\x14invoice_payment_hash\x18+ \x01(\x0cH\"\x88\x01\x01\x12-\n\x13invoice_amount_msat\x18, \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12\x37\n\x11invoice_fallbacks\x18- \x03(\x0b\x32\x1c.cln.DecodeInvoice_fallbacks\x12\x1d\n\x10invoice_features\x18. \x01(\x0cH$\x88\x01\x01\x12\x1c\n\x0finvoice_node_id\x18/ \x01(\x0cH%\x88\x01\x01\x12(\n\x1binvoice_recurrence_basetime\x18\x30 \x01(\x04H&\x88\x01\x01\x12*\n\x1dwarning_missing_invoice_paths\x18\x32 \x01(\tH\'\x88\x01\x01\x12/\n\"warning_missing_invoice_blindedpay\x18\x33 \x01(\tH(\x88\x01\x01\x12/\n\"warning_missing_invoice_created_at\x18\x34 \x01(\tH)\x88\x01\x01\x12\x31\n$warning_missing_invoice_payment_hash\x18\x35 \x01(\tH*\x88\x01\x01\x12+\n\x1ewarning_missing_invoice_amount\x18\x36 \x01(\tH+\x88\x01\x01\x12\x38\n+warning_missing_invoice_recurrence_basetime\x18\x37 \x01(\tH,\x88\x01\x01\x12,\n\x1fwarning_missing_invoice_node_id\x18\x38 \x01(\tH-\x88\x01\x01\x12.\n!warning_missing_invoice_signature\x18\x39 \x01(\tH.\x88\x01\x01\x12.\n!warning_invalid_invoice_signature\x18: \x01(\tH/\x88\x01\x01\x12\'\n\tfallbacks\x18; \x03(\x0b\x32\x14.cln.DecodeFallbacks\x12\x17\n\ncreated_at\x18< \x01(\x04H0\x88\x01\x01\x12\x13\n\x06\x65xpiry\x18= \x01(\x04H1\x88\x01\x01\x12\x12\n\x05payee\x18> \x01(\x0cH2\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18? \x01(\x0cH3\x88\x01\x01\x12\x1d\n\x10\x64\x65scription_hash\x18@ \x01(\x0cH4\x88\x01\x01\x12\"\n\x15min_final_cltv_expiry\x18\x41 \x01(\rH5\x88\x01\x01\x12\x1b\n\x0epayment_secret\x18\x42 \x01(\x0cH6\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\x43 \x01(\x0cH7\x88\x01\x01\x12\x1f\n\x05\x65xtra\x18\x45 \x03(\x0b\x32\x10.cln.DecodeExtra\x12\x16\n\tunique_id\x18\x46 \x01(\tH8\x88\x01\x01\x12\x14\n\x07version\x18G \x01(\tH9\x88\x01\x01\x12\x13\n\x06string\x18H \x01(\tH:\x88\x01\x01\x12-\n\x0crestrictions\x18I \x03(\x0b\x32\x17.cln.DecodeRestrictions\x12&\n\x19warning_rune_invalid_utf8\x18J \x01(\tH;\x88\x01\x01\x12\x10\n\x03hex\x18K \x01(\x0cH<\x88\x01\x01\x12\x16\n\tdecrypted\x18L \x01(\x0cH=\x88\x01\x01\x12\x16\n\tsignature\x18M \x01(\tH>\x88\x01\x01\x12\x15\n\x08\x63urrency\x18N \x01(\tH?\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18O \x01(\x0b\x32\x0b.cln.AmountH@\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18P \x01(\tHA\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18Q \x01(\x0cHB\x88\x01\x01\x12-\n\x06routes\x18R \x01(\x0b\x32\x18.cln.DecodeRoutehintListHC\x88\x01\x01\x12\x1c\n\x0foffer_issuer_id\x18S \x01(\x0cHD\x88\x01\x01\x12,\n\x1fwarning_missing_offer_issuer_id\x18T \x01(\tHE\x88\x01\x01\x12-\n\x0cinvreq_paths\x18U \x03(\x0b\x32\x17.cln.DecodeInvreq_paths\x12\'\n\x1awarning_empty_blinded_path\x18V \x01(\tHF\x88\x01\x01\"\x83\x01\n\nDecodeType\x12\x10\n\x0c\x42OLT12_OFFER\x10\x00\x12\x12\n\x0e\x42OLT12_INVOICE\x10\x01\x12\x1a\n\x16\x42OLT12_INVOICE_REQUEST\x10\x02\x12\x12\n\x0e\x42OLT11_INVOICE\x10\x03\x12\x08\n\x04RUNE\x10\x04\x12\x15\n\x11\x45MERGENCY_RECOVER\x10\x05\x42\x0b\n\t_offer_idB\x11\n\x0f_offer_metadataB\x11\n\x0f_offer_currencyB!\n\x1f_warning_unknown_offer_currencyB\x16\n\x14_currency_minor_unitB\x0f\n\r_offer_amountB\x14\n\x12_offer_amount_msatB\x14\n\x12_offer_descriptionB\x0f\n\r_offer_issuerB\x11\n\x0f_offer_featuresB\x18\n\x16_offer_absolute_expiryB\x15\n\x13_offer_quantity_maxB\x10\n\x0e_offer_node_idB \n\x1e_warning_missing_offer_node_idB$\n\"_warning_invalid_offer_descriptionB$\n\"_warning_missing_offer_descriptionB!\n\x1f_warning_invalid_offer_currencyB\x1f\n\x1d_warning_invalid_offer_issuerB\x12\n\x10_invreq_metadataB\x12\n\x10_invreq_payer_idB\x0f\n\r_invreq_chainB\x15\n\x13_invreq_amount_msatB\x12\n\x10_invreq_featuresB\x12\n\x10_invreq_quantityB\x14\n\x12_invreq_payer_noteB\x1c\n\x1a_invreq_recurrence_counterB\x1a\n\x18_invreq_recurrence_startB\"\n _warning_missing_invreq_metadataB\"\n _warning_missing_invreq_payer_idB$\n\"_warning_invalid_invreq_payer_noteB,\n*_warning_missing_invoice_request_signatureB,\n*_warning_invalid_invoice_request_signatureB\x15\n\x13_invoice_created_atB\x1a\n\x18_invoice_relative_expiryB\x17\n\x15_invoice_payment_hashB\x16\n\x14_invoice_amount_msatB\x13\n\x11_invoice_featuresB\x12\n\x10_invoice_node_idB\x1e\n\x1c_invoice_recurrence_basetimeB \n\x1e_warning_missing_invoice_pathsB%\n#_warning_missing_invoice_blindedpayB%\n#_warning_missing_invoice_created_atB\'\n%_warning_missing_invoice_payment_hashB!\n\x1f_warning_missing_invoice_amountB.\n,_warning_missing_invoice_recurrence_basetimeB\"\n _warning_missing_invoice_node_idB$\n\"_warning_missing_invoice_signatureB$\n\"_warning_invalid_invoice_signatureB\r\n\x0b_created_atB\t\n\x07_expiryB\x08\n\x06_payeeB\x0f\n\r_payment_hashB\x13\n\x11_description_hashB\x18\n\x16_min_final_cltv_expiryB\x11\n\x0f_payment_secretB\x13\n\x11_payment_metadataB\x0c\n\n_unique_idB\n\n\x08_versionB\t\n\x07_stringB\x1c\n\x1a_warning_rune_invalid_utf8B\x06\n\x04_hexB\x0c\n\n_decryptedB\x0c\n\n_signatureB\x0b\n\t_currencyB\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x0b\n\t_featuresB\t\n\x07_routesB\x12\n\x10_offer_issuer_idB\"\n _warning_missing_offer_issuer_idB\x1d\n\x1b_warning_empty_blinded_path\"\xed\x01\n\x11\x44\x65\x63odeOffer_paths\x12\x1a\n\rfirst_node_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x15\n\x08\x62linding\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x1b\n\x0e\x66irst_scid_dir\x18\x04 \x01(\rH\x02\x88\x01\x01\x12\x17\n\nfirst_scid\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x1b\n\x0e\x66irst_path_key\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x42\x10\n\x0e_first_node_idB\x0b\n\t_blindingB\x11\n\x0f_first_scid_dirB\r\n\x0b_first_scidB\x11\n\x0f_first_path_key\"\x8a\x01\n\x1f\x44\x65\x63odeOffer_recurrencePaywindow\x12\x16\n\x0eseconds_before\x18\x01 \x01(\r\x12\x15\n\rseconds_after\x18\x02 \x01(\r\x12 \n\x13proportional_amount\x18\x03 \x01(\x08H\x00\x88\x01\x01\x42\x16\n\x14_proportional_amount\"\x99\x02\n\x12\x44\x65\x63odeInvreq_paths\x12\x1b\n\x0e\x66irst_scid_dir\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x15\n\x08\x62linding\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x1a\n\rfirst_node_id\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x17\n\nfirst_scid\x18\x04 \x01(\tH\x03\x88\x01\x01\x12)\n\x04path\x18\x05 \x03(\x0b\x32\x1b.cln.DecodeInvreq_pathsPath\x12\x1b\n\x0e\x66irst_path_key\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x42\x11\n\x0f_first_scid_dirB\x0b\n\t_blindingB\x10\n\x0e_first_node_idB\r\n\x0b_first_scidB\x11\n\x0f_first_path_key\"S\n\x16\x44\x65\x63odeInvreq_pathsPath\x12\x17\n\x0f\x62linded_node_id\x18\x01 \x01(\x0c\x12 \n\x18\x65ncrypted_recipient_data\x18\x02 \x01(\x0c\"T\n\x17\x44\x65\x63odeInvoice_pathsPath\x12\x17\n\x0f\x62linded_node_id\x18\x01 \x01(\x0c\x12 \n\x18\x65ncrypted_recipient_data\x18\x02 \x01(\x0c\"Y\n\x17\x44\x65\x63odeInvoice_fallbacks\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x0b\n\x03hex\x18\x02 \x01(\x0c\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_address\"\xaa\x02\n\x0f\x44\x65\x63odeFallbacks\x12\x36\n)warning_invoice_fallbacks_version_invalid\x18\x01 \x01(\tH\x00\x88\x01\x01\x12;\n\titem_type\x18\x02 \x01(\x0e\x32(.cln.DecodeFallbacks.DecodeFallbacksType\x12\x11\n\x04\x61\x64\x64r\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x0b\n\x03hex\x18\x04 \x01(\x0c\"K\n\x13\x44\x65\x63odeFallbacksType\x12\t\n\x05P2PKH\x10\x00\x12\x08\n\x04P2SH\x10\x01\x12\n\n\x06P2WPKH\x10\x02\x12\t\n\x05P2WSH\x10\x03\x12\x08\n\x04P2TR\x10\x04\x42,\n*_warning_invoice_fallbacks_version_invalidB\x07\n\x05_addr\"(\n\x0b\x44\x65\x63odeExtra\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\";\n\x12\x44\x65\x63odeRestrictions\x12\x14\n\x0c\x61lternatives\x18\x01 \x03(\t\x12\x0f\n\x07summary\x18\x02 \x01(\t\"\xc2\x01\n\rDelpayRequest\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12/\n\x06status\x18\x02 \x01(\x0e\x32\x1f.cln.DelpayRequest.DelpayStatus\x12\x13\n\x06partid\x18\x03 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07groupid\x18\x04 \x01(\x04H\x01\x88\x01\x01\"(\n\x0c\x44\x65lpayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x42\t\n\x07_partidB\n\n\x08_groupid\"7\n\x0e\x44\x65lpayResponse\x12%\n\x08payments\x18\x01 \x03(\x0b\x32\x13.cln.DelpayPayments\"\xcb\x05\n\x0e\x44\x65lpayPayments\x12\x1a\n\rcreated_index\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\n\n\x02id\x18\x02 \x01(\x04\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x38\n\x06status\x18\x04 \x01(\x0e\x32(.cln.DelpayPayments.DelpayPaymentsStatus\x12%\n\x10\x61mount_sent_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x13\n\x06partid\x18\x06 \x01(\x04H\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x07 \x01(\x0cH\x02\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x12\n\ncreated_at\x18\t \x01(\x04\x12\x1a\n\rupdated_index\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\x0c \x01(\x04H\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x12\n\x05label\x18\x0e \x01(\tH\x08\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0f \x01(\tH\t\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x10 \x01(\tH\n\x88\x01\x01\x12\x17\n\nerroronion\x18\x11 \x01(\x0cH\x0b\x88\x01\x01\"=\n\x14\x44\x65lpayPaymentsStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x10\n\x0e_created_indexB\t\n\x07_partidB\x0e\n\x0c_destinationB\x0e\n\x0c_amount_msatB\x10\n\x0e_updated_indexB\x0f\n\r_completed_atB\n\n\x08_groupidB\x13\n\x11_payment_preimageB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\r\n\x0b_erroronion\"\xb3\x01\n\x11\x44\x65lforwardRequest\x12\x12\n\nin_channel\x18\x01 \x01(\t\x12\x12\n\nin_htlc_id\x18\x02 \x01(\x04\x12\x37\n\x06status\x18\x03 \x01(\x0e\x32\'.cln.DelforwardRequest.DelforwardStatus\"=\n\x10\x44\x65lforwardStatus\x12\x0b\n\x07SETTLED\x10\x00\x12\x10\n\x0cLOCAL_FAILED\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\"\x14\n\x12\x44\x65lforwardResponse\"\'\n\x13\x44isableofferRequest\x12\x10\n\x08offer_id\x18\x01 \x01(\x0c\"\x88\x01\n\x14\x44isableofferResponse\x12\x10\n\x08offer_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"=\n\x11\x44isconnectRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\x05\x66orce\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_force\"\x14\n\x12\x44isconnectResponse\"k\n\x0f\x46\x65\x65ratesRequest\x12\x31\n\x05style\x18\x01 \x01(\x0e\x32\".cln.FeeratesRequest.FeeratesStyle\"%\n\rFeeratesStyle\x12\t\n\x05PERKB\x10\x00\x12\t\n\x05PERKW\x10\x01\"\x9c\x02\n\x10\x46\x65\x65ratesResponse\x12%\n\x18warning_missing_feerates\x18\x01 \x01(\tH\x00\x88\x01\x01\x12&\n\x05perkb\x18\x02 \x01(\x0b\x32\x12.cln.FeeratesPerkbH\x01\x88\x01\x01\x12&\n\x05perkw\x18\x03 \x01(\x0b\x32\x12.cln.FeeratesPerkwH\x02\x88\x01\x01\x12\x46\n\x15onchain_fee_estimates\x18\x04 \x01(\x0b\x32\".cln.FeeratesOnchain_fee_estimatesH\x03\x88\x01\x01\x42\x1b\n\x19_warning_missing_feeratesB\x08\n\x06_perkbB\x08\n\x06_perkwB\x18\n\x16_onchain_fee_estimates\"\xd3\x03\n\rFeeratesPerkb\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x14\n\x07opening\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x03\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x05\x88\x01\x01\x12.\n\testimates\x18\t \x03(\x0b\x32\x1b.cln.FeeratesPerkbEstimates\x12\x12\n\x05\x66loor\x18\n \x01(\rH\x06\x88\x01\x01\x12$\n\x17unilateral_anchor_close\x18\x0b \x01(\rH\x07\x88\x01\x01\x42\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penaltyB\x08\n\x06_floorB\x1a\n\x18_unilateral_anchor_close\"W\n\x16\x46\x65\x65ratesPerkbEstimates\x12\x12\n\nblockcount\x18\x01 \x01(\r\x12\x0f\n\x07\x66\x65\x65rate\x18\x02 \x01(\r\x12\x18\n\x10smoothed_feerate\x18\x03 \x01(\r\"\xd3\x03\n\rFeeratesPerkw\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x14\n\x07opening\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x03\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x05\x88\x01\x01\x12.\n\testimates\x18\t \x03(\x0b\x32\x1b.cln.FeeratesPerkwEstimates\x12\x12\n\x05\x66loor\x18\n \x01(\rH\x06\x88\x01\x01\x12$\n\x17unilateral_anchor_close\x18\x0b \x01(\rH\x07\x88\x01\x01\x42\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penaltyB\x08\n\x06_floorB\x1a\n\x18_unilateral_anchor_close\"W\n\x16\x46\x65\x65ratesPerkwEstimates\x12\x12\n\nblockcount\x18\x01 \x01(\r\x12\x0f\n\x07\x66\x65\x65rate\x18\x02 \x01(\r\x12\x18\n\x10smoothed_feerate\x18\x03 \x01(\r\"\x9b\x02\n\x1d\x46\x65\x65ratesOnchain_fee_estimates\x12 \n\x18opening_channel_satoshis\x18\x01 \x01(\x04\x12\x1d\n\x15mutual_close_satoshis\x18\x02 \x01(\x04\x12!\n\x19unilateral_close_satoshis\x18\x03 \x01(\x04\x12\x1d\n\x15htlc_timeout_satoshis\x18\x04 \x01(\x04\x12\x1d\n\x15htlc_success_satoshis\x18\x05 \x01(\x04\x12\x30\n#unilateral_close_nonanchor_satoshis\x18\x06 \x01(\x04H\x00\x88\x01\x01\x42&\n$_unilateral_close_nonanchor_satoshis\"\xe9\x02\n\x13\x46\x65tchinvoiceRequest\x12\r\n\x05offer\x18\x01 \x01(\t\x12%\n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x15\n\x08quantity\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x1f\n\x12recurrence_counter\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x1d\n\x10recurrence_start\x18\x05 \x01(\x01H\x03\x88\x01\x01\x12\x1d\n\x10recurrence_label\x18\x06 \x01(\tH\x04\x88\x01\x01\x12\x14\n\x07timeout\x18\x07 \x01(\x01H\x05\x88\x01\x01\x12\x17\n\npayer_note\x18\x08 \x01(\tH\x06\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\x0b\n\t_quantityB\x15\n\x13_recurrence_counterB\x13\n\x11_recurrence_startB\x13\n\x11_recurrence_labelB\n\n\x08_timeoutB\r\n\x0b_payer_note\"\x9a\x01\n\x14\x46\x65tchinvoiceResponse\x12\x0f\n\x07invoice\x18\x01 \x01(\t\x12)\n\x07\x63hanges\x18\x02 \x01(\x0b\x32\x18.cln.FetchinvoiceChanges\x12\x36\n\x0bnext_period\x18\x03 \x01(\x0b\x32\x1c.cln.FetchinvoiceNext_periodH\x00\x88\x01\x01\x42\x0e\n\x0c_next_period\"\x82\x02\n\x13\x46\x65tchinvoiceChanges\x12!\n\x14\x64\x65scription_appended\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1b\n\x0evendor_removed\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06vendor\x18\x04 \x01(\tH\x03\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x42\x17\n\x15_description_appendedB\x0e\n\x0c_descriptionB\x11\n\x0f_vendor_removedB\t\n\x07_vendorB\x0e\n\x0c_amount_msat\"~\n\x17\x46\x65tchinvoiceNext_period\x12\x0f\n\x07\x63ounter\x18\x01 \x01(\x04\x12\x11\n\tstarttime\x18\x02 \x01(\x04\x12\x0f\n\x07\x65ndtime\x18\x03 \x01(\x04\x12\x17\n\x0fpaywindow_start\x18\x04 \x01(\x04\x12\x15\n\rpaywindow_end\x18\x05 \x01(\x04\"\'\n\x19\x46undchannel_cancelRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\"/\n\x1a\x46undchannel_cancelResponse\x12\x11\n\tcancelled\x18\x01 \x01(\t\"7\n\x1b\x46undchannel_completeRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\"O\n\x1c\x46undchannel_completeResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x1b\n\x13\x63ommitments_secured\x18\x02 \x01(\x08\"\xfb\x03\n\x12\x46undchannelRequest\x12 \n\x06\x61mount\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x15\n\x08\x61nnounce\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12#\n\tpush_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x06 \x01(\tH\x03\x88\x01\x01\x12%\n\x0brequest_amt\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x08 \x01(\tH\x05\x88\x01\x01\x12\n\n\x02id\x18\t \x01(\x0c\x12\x14\n\x07minconf\x18\n \x01(\rH\x06\x88\x01\x01\x12\x1c\n\x05utxos\x18\x0b \x03(\x0b\x32\r.cln.Outpoint\x12\x15\n\x08mindepth\x18\x0c \x01(\rH\x07\x88\x01\x01\x12!\n\x07reserve\x18\r \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x14\n\x0c\x63hannel_type\x18\x0e \x03(\rB\n\n\x08_feerateB\x0b\n\t_announceB\x0c\n\n_push_msatB\x0b\n\t_close_toB\x0e\n\x0c_request_amtB\x10\n\x0e_compact_leaseB\n\n\x08_minconfB\x0b\n\t_mindepthB\n\n\x08_reserve\"\xe5\x01\n\x13\x46undchannelResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x0e\n\x06outnum\x18\x03 \x01(\r\x12\x12\n\nchannel_id\x18\x04 \x01(\x0c\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\x0cH\x00\x88\x01\x01\x12\x15\n\x08mindepth\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x37\n\x0c\x63hannel_type\x18\x07 \x01(\x0b\x32\x1c.cln.FundchannelChannel_typeH\x02\x88\x01\x01\x42\x0b\n\t_close_toB\x0b\n\t_mindepthB\x0f\n\r_channel_type\"L\n\x17\x46undchannelChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"\xd7\x02\n\x18\x46undchannel_startRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x1b\n\x06\x61mount\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\"\n\x07\x66\x65\x65rate\x18\x03 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x15\n\x08\x61nnounce\x18\x04 \x01(\x08H\x01\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\tH\x02\x88\x01\x01\x12#\n\tpush_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x15\n\x08mindepth\x18\x07 \x01(\rH\x04\x88\x01\x01\x12!\n\x07reserve\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x0c\x63hannel_type\x18\t \x03(\rB\n\n\x08_feerateB\x0b\n\t_announceB\x0b\n\t_close_toB\x0c\n\n_push_msatB\x0b\n\t_mindepthB\n\n\x08_reserve\"\xf9\x01\n\x19\x46undchannel_startResponse\x12\x17\n\x0f\x66unding_address\x18\x01 \x01(\t\x12\x14\n\x0cscriptpubkey\x18\x02 \x01(\x0c\x12=\n\x0c\x63hannel_type\x18\x03 \x01(\x0b\x32\".cln.Fundchannel_startChannel_typeH\x00\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x04 \x01(\x0cH\x01\x88\x01\x01\x12\x15\n\rwarning_usage\x18\x05 \x01(\t\x12\x15\n\x08mindepth\x18\x06 \x01(\rH\x02\x88\x01\x01\x42\x0f\n\r_channel_typeB\x0b\n\t_close_toB\x0b\n\t_mindepth\"R\n\x1d\x46undchannel_startChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"\x9d\x01\n\rGetlogRequest\x12\x32\n\x05level\x18\x01 \x01(\x0e\x32\x1e.cln.GetlogRequest.GetlogLevelH\x00\x88\x01\x01\"N\n\x0bGetlogLevel\x12\n\n\x06\x42ROKEN\x10\x00\x12\x0b\n\x07UNUSUAL\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\t\n\x05\x44\x45\x42UG\x10\x03\x12\x06\n\x02IO\x10\x04\x12\t\n\x05TRACE\x10\x05\x42\x08\n\x06_level\"h\n\x0eGetlogResponse\x12\x12\n\ncreated_at\x18\x01 \x01(\t\x12\x12\n\nbytes_used\x18\x02 \x01(\r\x12\x11\n\tbytes_max\x18\x03 \x01(\r\x12\x1b\n\x03log\x18\x04 \x03(\x0b\x32\x0e.cln.GetlogLog\"\xe8\x02\n\tGetlogLog\x12/\n\titem_type\x18\x01 \x01(\x0e\x32\x1c.cln.GetlogLog.GetlogLogType\x12\x18\n\x0bnum_skipped\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04time\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06source\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x10\n\x03log\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x07node_id\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x11\n\x04\x64\x61ta\x18\x07 \x01(\x0cH\x05\x88\x01\x01\"l\n\rGetlogLogType\x12\x0b\n\x07SKIPPED\x10\x00\x12\n\n\x06\x42ROKEN\x10\x01\x12\x0b\n\x07UNUSUAL\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\t\n\x05\x44\x45\x42UG\x10\x04\x12\t\n\x05IO_IN\x10\x05\x12\n\n\x06IO_OUT\x10\x06\x12\t\n\x05TRACE\x10\x07\x42\x0e\n\x0c_num_skippedB\x07\n\x05_timeB\t\n\x07_sourceB\x06\n\x04_logB\n\n\x08_node_idB\x07\n\x05_data\"\xd9\x08\n\x13\x46underupdateRequest\x12@\n\x06policy\x18\x01 \x01(\x0e\x32+.cln.FunderupdateRequest.FunderupdatePolicyH\x00\x88\x01\x01\x12$\n\npolicy_mod\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0bleases_only\x18\x03 \x01(\x08H\x02\x88\x01\x01\x12\x30\n\x16min_their_funding_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x30\n\x16max_their_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12.\n\x14per_channel_min_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12.\n\x14per_channel_max_msat\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12+\n\x11reserve_tank_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x07\x88\x01\x01\x12\x19\n\x0c\x66uzz_percent\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1d\n\x10\x66und_probability\x18\n \x01(\rH\t\x88\x01\x01\x12-\n\x13lease_fee_base_msat\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\n\x88\x01\x01\x12\x1c\n\x0flease_fee_basis\x18\x0c \x01(\rH\x0b\x88\x01\x01\x12\x1b\n\x0e\x66unding_weight\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x33\n\x19\x63hannel_fee_max_base_msat\x18\x0e \x01(\x0b\x32\x0b.cln.AmountH\r\x88\x01\x01\x12\x35\n(channel_fee_max_proportional_thousandths\x18\x0f \x01(\rH\x0e\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x10 \x01(\x0cH\x0f\x88\x01\x01\"9\n\x12\x46underupdatePolicy\x12\t\n\x05MATCH\x10\x00\x12\r\n\tAVAILABLE\x10\x01\x12\t\n\x05\x46IXED\x10\x02\x42\t\n\x07_policyB\r\n\x0b_policy_modB\x0e\n\x0c_leases_onlyB\x19\n\x17_min_their_funding_msatB\x19\n\x17_max_their_funding_msatB\x17\n\x15_per_channel_min_msatB\x17\n\x15_per_channel_max_msatB\x14\n\x12_reserve_tank_msatB\x0f\n\r_fuzz_percentB\x13\n\x11_fund_probabilityB\x16\n\x14_lease_fee_base_msatB\x12\n\x10_lease_fee_basisB\x11\n\x0f_funding_weightB\x1c\n\x1a_channel_fee_max_base_msatB+\n)_channel_fee_max_proportional_thousandthsB\x10\n\x0e_compact_lease\"\xdf\x06\n\x14\x46underupdateResponse\x12\x0f\n\x07summary\x18\x01 \x01(\t\x12<\n\x06policy\x18\x02 \x01(\x0e\x32,.cln.FunderupdateResponse.FunderupdatePolicy\x12\x12\n\npolicy_mod\x18\x03 \x01(\r\x12\x13\n\x0bleases_only\x18\x04 \x01(\x08\x12+\n\x16min_their_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x16max_their_funding_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12)\n\x14per_channel_min_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12)\n\x14per_channel_max_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11reserve_tank_msat\x18\t \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0c\x66uzz_percent\x18\n \x01(\r\x12\x18\n\x10\x66und_probability\x18\x0b \x01(\r\x12-\n\x13lease_fee_base_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x1c\n\x0flease_fee_basis\x18\r \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0e\x66unding_weight\x18\x0e \x01(\rH\x02\x88\x01\x01\x12\x33\n\x19\x63hannel_fee_max_base_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x35\n(channel_fee_max_proportional_thousandths\x18\x10 \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x11 \x01(\x0cH\x05\x88\x01\x01\"9\n\x12\x46underupdatePolicy\x12\t\n\x05MATCH\x10\x00\x12\r\n\tAVAILABLE\x10\x01\x12\t\n\x05\x46IXED\x10\x02\x42\x16\n\x14_lease_fee_base_msatB\x12\n\x10_lease_fee_basisB\x11\n\x0f_funding_weightB\x1c\n\x1a_channel_fee_max_base_msatB+\n)_channel_fee_max_proportional_thousandthsB\x10\n\x0e_compact_lease\"\xec\x01\n\x0fGetrouteRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\nriskfactor\x18\x03 \x01(\x04\x12\x11\n\x04\x63ltv\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x13\n\x06\x66romid\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x66uzzpercent\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\x07 \x03(\t\x12\x14\n\x07maxhops\x18\x08 \x01(\rH\x03\x88\x01\x01\x12 \n\x0b\x61mount_msat\x18\t \x01(\x0b\x32\x0b.cln.AmountB\x07\n\x05_cltvB\t\n\x07_fromidB\x0e\n\x0c_fuzzpercentB\n\n\x08_maxhops\"5\n\x10GetrouteResponse\x12!\n\x05route\x18\x01 \x03(\x0b\x32\x12.cln.GetrouteRoute\"\xc5\x01\n\rGetrouteRoute\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\t\x12\x11\n\tdirection\x18\x03 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x05 \x01(\r\x12\x34\n\x05style\x18\x06 \x01(\x0e\x32%.cln.GetrouteRoute.GetrouteRouteStyle\"\x1d\n\x12GetrouteRouteStyle\x12\x07\n\x03TLV\x10\x00\"\xb7\x03\n\x13ListforwardsRequest\x12@\n\x06status\x18\x01 \x01(\x0e\x32+.cln.ListforwardsRequest.ListforwardsStatusH\x00\x88\x01\x01\x12\x17\n\nin_channel\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bout_channel\x18\x03 \x01(\tH\x02\x88\x01\x01\x12>\n\x05index\x18\x04 \x01(\x0e\x32*.cln.ListforwardsRequest.ListforwardsIndexH\x03\x88\x01\x01\x12\x12\n\x05start\x18\x05 \x01(\x04H\x04\x88\x01\x01\x12\x12\n\x05limit\x18\x06 \x01(\rH\x05\x88\x01\x01\"L\n\x12ListforwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"-\n\x11ListforwardsIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\t\n\x07_statusB\r\n\x0b_in_channelB\x0e\n\x0c_out_channelB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListforwardsResponse\x12+\n\x08\x66orwards\x18\x01 \x03(\x0b\x32\x19.cln.ListforwardsForwards\"\xb4\x06\n\x14ListforwardsForwards\x12\x12\n\nin_channel\x18\x01 \x01(\t\x12\x1c\n\x07in_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x44\n\x06status\x18\x03 \x01(\x0e\x32\x34.cln.ListforwardsForwards.ListforwardsForwardsStatus\x12\x15\n\rreceived_time\x18\x04 \x01(\x01\x12\x18\n\x0bout_channel\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\"\n\x08\x66\x65\x65_msat\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\"\n\x08out_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12G\n\x05style\x18\t \x01(\x0e\x32\x33.cln.ListforwardsForwards.ListforwardsForwardsStyleH\x03\x88\x01\x01\x12\x17\n\nin_htlc_id\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x18\n\x0bout_htlc_id\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x0c \x01(\x04H\x06\x88\x01\x01\x12\x1a\n\rupdated_index\x18\r \x01(\x04H\x07\x88\x01\x01\x12\x1a\n\rresolved_time\x18\x0e \x01(\x01H\x08\x88\x01\x01\x12\x15\n\x08\x66\x61ilcode\x18\x0f \x01(\rH\t\x88\x01\x01\x12\x17\n\nfailreason\x18\x10 \x01(\tH\n\x88\x01\x01\"T\n\x1aListforwardsForwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"0\n\x19ListforwardsForwardsStyle\x12\n\n\x06LEGACY\x10\x00\x12\x07\n\x03TLV\x10\x01\x42\x0e\n\x0c_out_channelB\x0b\n\t_fee_msatB\x0b\n\t_out_msatB\x08\n\x06_styleB\r\n\x0b_in_htlc_idB\x0e\n\x0c_out_htlc_idB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x10\n\x0e_resolved_timeB\x0b\n\t_failcodeB\r\n\x0b_failreason\"a\n\x11ListoffersRequest\x12\x15\n\x08offer_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x18\n\x0b\x61\x63tive_only\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\x0b\n\t_offer_idB\x0e\n\x0c_active_only\";\n\x12ListoffersResponse\x12%\n\x06offers\x18\x01 \x03(\x0b\x32\x15.cln.ListoffersOffers\"\x84\x01\n\x10ListoffersOffers\x12\x10\n\x08offer_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"\xdb\x01\n\x0fListpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x38\n\x06status\x18\x03 \x01(\x0e\x32#.cln.ListpaysRequest.ListpaysStatusH\x02\x88\x01\x01\"7\n\x0eListpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_status\"3\n\x10ListpaysResponse\x12\x1f\n\x04pays\x18\x01 \x03(\x0b\x32\x11.cln.ListpaysPays\"\xff\x04\n\x0cListpaysPays\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x34\n\x06status\x18\x02 \x01(\x0e\x32$.cln.ListpaysPays.ListpaysPaysStatus\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\ncreated_at\x18\x04 \x01(\x04\x12\x12\n\x05label\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x07 \x01(\tH\x03\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12*\n\x10\x61mount_sent_msat\x18\t \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x17\n\nerroronion\x18\n \x01(\x0cH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0b \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0c \x01(\x04H\x08\x88\x01\x01\x12\x15\n\x08preimage\x18\r \x01(\x0cH\t\x88\x01\x01\x12\x1c\n\x0fnumber_of_parts\x18\x0e \x01(\x04H\n\x88\x01\x01\";\n\x12ListpaysPaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x13\n\x11_amount_sent_msatB\r\n\x0b_erroronionB\x0e\n\x0c_descriptionB\x0f\n\r_completed_atB\x0b\n\t_preimageB\x12\n\x10_number_of_parts\"*\n\x10ListhtlcsRequest\x12\x0f\n\x02id\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x05\n\x03_id\"7\n\x11ListhtlcsResponse\x12\"\n\x05htlcs\x18\x01 \x03(\x0b\x32\x13.cln.ListhtlcsHtlcs\"\x89\x02\n\x0eListhtlcsHtlcs\x12\x18\n\x10short_channel_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\x04\x12\x0e\n\x06\x65xpiry\x18\x03 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12>\n\tdirection\x18\x05 \x01(\x0e\x32+.cln.ListhtlcsHtlcs.ListhtlcsHtlcsDirection\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x1d\n\x05state\x18\x07 \x01(\x0e\x32\x0e.cln.HtlcState\"*\n\x17ListhtlcsHtlcsDirection\x12\x07\n\x03OUT\x10\x00\x12\x06\n\x02IN\x10\x01\"\xb2\x02\n\x17MultifundchannelRequest\x12\x37\n\x0c\x64\x65stinations\x18\x01 \x03(\x0b\x32!.cln.MultifundchannelDestinations\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\x12H\x01\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12\x18\n\x0bminchannels\x18\x05 \x01(\x12H\x02\x88\x01\x01\x12-\n\x12\x63ommitment_feerate\x18\x06 \x01(\x0b\x32\x0c.cln.FeerateH\x03\x88\x01\x01\x42\n\n\x08_feerateB\n\n\x08_minconfB\x0e\n\x0c_minchannelsB\x15\n\x13_commitment_feerate\"\x98\x01\n\x18MultifundchannelResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x35\n\x0b\x63hannel_ids\x18\x03 \x03(\x0b\x32 .cln.MultifundchannelChannel_ids\x12+\n\x06\x66\x61iled\x18\x04 \x03(\x0b\x32\x1b.cln.MultifundchannelFailed\"\xff\x02\n\x1cMultifundchannelDestinations\x12\n\n\x02id\x18\x01 \x01(\t\x12 \n\x06\x61mount\x18\x02 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x15\n\x08\x61nnounce\x18\x03 \x01(\x08H\x00\x88\x01\x01\x12#\n\tpush_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\tH\x02\x88\x01\x01\x12%\n\x0brequest_amt\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x07 \x01(\tH\x04\x88\x01\x01\x12\x15\n\x08mindepth\x18\x08 \x01(\rH\x05\x88\x01\x01\x12!\n\x07reserve\x18\t \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x42\x0b\n\t_announceB\x0c\n\n_push_msatB\x0b\n\t_close_toB\x0e\n\x0c_request_amtB\x10\n\x0e_compact_leaseB\x0b\n\t_mindepthB\n\n\x08_reserve\"\xcb\x01\n\x1bMultifundchannelChannel_ids\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\x12\x12\n\nchannel_id\x18\x03 \x01(\x0c\x12G\n\x0c\x63hannel_type\x18\x04 \x01(\x0b\x32,.cln.MultifundchannelChannel_idsChannel_typeH\x00\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x42\x0f\n\r_channel_typeB\x0b\n\t_close_to\"\\\n\'MultifundchannelChannel_idsChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"\x93\x02\n\x16MultifundchannelFailed\x12\n\n\x02id\x18\x01 \x01(\x0c\x12H\n\x06method\x18\x02 \x01(\x0e\x32\x38.cln.MultifundchannelFailed.MultifundchannelFailedMethod\x12/\n\x05\x65rror\x18\x03 \x01(\x0b\x32 .cln.MultifundchannelFailedError\"r\n\x1cMultifundchannelFailedMethod\x12\x0b\n\x07\x43ONNECT\x10\x00\x12\x14\n\x10OPENCHANNEL_INIT\x10\x01\x12\x15\n\x11\x46UNDCHANNEL_START\x10\x02\x12\x18\n\x14\x46UNDCHANNEL_COMPLETE\x10\x03\"<\n\x1bMultifundchannelFailedError\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x12\x12\x0f\n\x07message\x18\x02 \x01(\t\"\xa8\x01\n\x14MultiwithdrawRequest\x12 \n\x07outputs\x18\x01 \x03(\x0b\x32\x0f.cln.OutputDesc\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.OutpointB\n\n\x08_feerateB\n\n\x08_minconf\"1\n\x15MultiwithdrawResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"\xa0\x04\n\x0cOfferRequest\x12\x0e\n\x06\x61mount\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06issuer\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05label\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x19\n\x0cquantity_max\x18\x05 \x01(\x04H\x03\x88\x01\x01\x12\x1c\n\x0f\x61\x62solute_expiry\x18\x06 \x01(\x04H\x04\x88\x01\x01\x12\x17\n\nrecurrence\x18\x07 \x01(\tH\x05\x88\x01\x01\x12\x1c\n\x0frecurrence_base\x18\x08 \x01(\tH\x06\x88\x01\x01\x12!\n\x14recurrence_paywindow\x18\t \x01(\tH\x07\x88\x01\x01\x12\x1d\n\x10recurrence_limit\x18\n \x01(\rH\x08\x88\x01\x01\x12\x17\n\nsingle_use\x18\x0b \x01(\x08H\t\x88\x01\x01\x12(\n\x1brecurrence_start_any_period\x18\x0c \x01(\x08H\n\x88\x01\x01\x42\x0e\n\x0c_descriptionB\t\n\x07_issuerB\x08\n\x06_labelB\x0f\n\r_quantity_maxB\x12\n\x10_absolute_expiryB\r\n\x0b_recurrenceB\x12\n\x10_recurrence_baseB\x17\n\x15_recurrence_paywindowB\x13\n\x11_recurrence_limitB\r\n\x0b_single_useB\x1e\n\x1c_recurrence_start_any_period\"\x92\x01\n\rOfferResponse\x12\x10\n\x08offer_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x0f\n\x07\x63reated\x18\x06 \x01(\x08\x12\x12\n\x05label\x18\x07 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\".\n\x18Openchannel_abortRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\"Y\n\x19Openchannel_abortResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x18\n\x10\x63hannel_canceled\x18\x02 \x01(\x08\x12\x0e\n\x06reason\x18\x03 \x01(\t\"\x9f\x01\n\x17Openchannel_bumpRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x13\n\x0binitialpsbt\x18\x02 \x01(\t\x12*\n\x0f\x66unding_feerate\x18\x03 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x1b\n\x06\x61mount\x18\x04 \x01(\x0b\x32\x0b.cln.AmountB\x12\n\x10_funding_feerate\"\x86\x02\n\x18Openchannel_bumpResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12<\n\x0c\x63hannel_type\x18\x02 \x01(\x0b\x32!.cln.Openchannel_bumpChannel_typeH\x00\x88\x01\x01\x12\x0c\n\x04psbt\x18\x03 \x01(\t\x12\x1b\n\x13\x63ommitments_secured\x18\x04 \x01(\x08\x12\x16\n\x0e\x66unding_serial\x18\x05 \x01(\x04\x12&\n\x19requires_confirmed_inputs\x18\x06 \x01(\x08H\x01\x88\x01\x01\x42\x0f\n\r_channel_typeB\x1c\n\x1a_requires_confirmed_inputs\"Q\n\x1cOpenchannel_bumpChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"\xa0\x03\n\x17Openchannel_initRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x13\n\x0binitialpsbt\x18\x02 \x01(\t\x12-\n\x12\x63ommitment_feerate\x18\x03 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12*\n\x0f\x66unding_feerate\x18\x04 \x01(\x0b\x32\x0c.cln.FeerateH\x01\x88\x01\x01\x12\x15\n\x08\x61nnounce\x18\x05 \x01(\x08H\x02\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x06 \x01(\tH\x03\x88\x01\x01\x12%\n\x0brequest_amt\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x08 \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x0c\x63hannel_type\x18\t \x03(\r\x12\x1b\n\x06\x61mount\x18\n \x01(\x0b\x32\x0b.cln.AmountB\x15\n\x13_commitment_feerateB\x12\n\x10_funding_feerateB\x0b\n\t_announceB\x0b\n\t_close_toB\x0e\n\x0c_request_amtB\x10\n\x0e_compact_lease\"\x86\x02\n\x18Openchannel_initResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\x12<\n\x0c\x63hannel_type\x18\x03 \x01(\x0b\x32!.cln.Openchannel_initChannel_typeH\x00\x88\x01\x01\x12\x1b\n\x13\x63ommitments_secured\x18\x04 \x01(\x08\x12\x16\n\x0e\x66unding_serial\x18\x05 \x01(\x04\x12&\n\x19requires_confirmed_inputs\x18\x06 \x01(\x08H\x01\x88\x01\x01\x42\x0f\n\r_channel_typeB\x1c\n\x1a_requires_confirmed_inputs\"Q\n\x1cOpenchannel_initChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"D\n\x19Openchannel_signedRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x13\n\x0bsigned_psbt\x18\x02 \x01(\t\"J\n\x1aOpenchannel_signedResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\n\n\x02tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"=\n\x19Openchannel_updateRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\"\xae\x02\n\x1aOpenchannel_updateResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12>\n\x0c\x63hannel_type\x18\x02 \x01(\x0b\x32#.cln.Openchannel_updateChannel_typeH\x00\x88\x01\x01\x12\x0c\n\x04psbt\x18\x03 \x01(\t\x12\x1b\n\x13\x63ommitments_secured\x18\x04 \x01(\x08\x12\x16\n\x0e\x66unding_outnum\x18\x05 \x01(\r\x12\x15\n\x08\x63lose_to\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12&\n\x19requires_confirmed_inputs\x18\x07 \x01(\x08H\x02\x88\x01\x01\x42\x0f\n\r_channel_typeB\x0b\n\t_close_toB\x1c\n\x1a_requires_confirmed_inputs\"S\n\x1eOpenchannel_updateChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"Y\n\x0bPingRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x03len\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x16\n\tpongbytes\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x06\n\x04_lenB\x0c\n\n_pongbytes\"\x1e\n\x0cPingResponse\x12\x0e\n\x06totlen\x18\x01 \x01(\r\"\x91\x01\n\rPluginRequest\x12)\n\nsubcommand\x18\x01 \x01(\x0e\x32\x15.cln.PluginSubcommand\x12\x13\n\x06plugin\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tdirectory\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x0f\n\x07options\x18\x04 \x03(\tB\t\n\x07_pluginB\x0c\n\n_directory\"}\n\x0ePluginResponse\x12&\n\x07\x63ommand\x18\x01 \x01(\x0e\x32\x15.cln.PluginSubcommand\x12#\n\x07plugins\x18\x02 \x03(\x0b\x32\x12.cln.PluginPlugins\x12\x13\n\x06result\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_result\">\n\rPluginPlugins\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x0f\n\x07\x64ynamic\x18\x03 \x01(\x08\"<\n\x14RenepaystatusRequest\x12\x16\n\tinvstring\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_invstring\"G\n\x15RenepaystatusResponse\x12.\n\tpaystatus\x18\x01 \x03(\x0b\x32\x1b.cln.RenepaystatusPaystatus\"\xe2\x03\n\x16RenepaystatusPaystatus\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x1d\n\x10payment_preimage\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\x0f\n\x07groupid\x18\x05 \x01(\r\x12\x12\n\x05parts\x18\x06 \x01(\rH\x01\x88\x01\x01\x12 \n\x0b\x61mount_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12*\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12H\n\x06status\x18\t \x01(\x0e\x32\x38.cln.RenepaystatusPaystatus.RenepaystatusPaystatusStatus\x12\x18\n\x0b\x64\x65stination\x18\n \x01(\x0cH\x03\x88\x01\x01\x12\r\n\x05notes\x18\x0b \x03(\t\"E\n\x1cRenepaystatusPaystatusStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\x13\n\x11_payment_preimageB\x08\n\x06_partsB\x13\n\x11_amount_sent_msatB\x0e\n\x0c_destination\"\xda\x02\n\x0eRenepayRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\x12%\n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12 \n\x06maxfee\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x04 \x01(\rH\x02\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x06 \x01(\tH\x04\x88\x01\x01\x12\x12\n\x05label\x18\x07 \x01(\tH\x05\x88\x01\x01\x12\x1b\n\x0e\x64\x65v_use_shadow\x18\x08 \x01(\x08H\x06\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\t \x03(\tB\x0e\n\x0c_amount_msatB\t\n\x07_maxfeeB\x0b\n\t_maxdelayB\x0c\n\n_retry_forB\x0e\n\x0c_descriptionB\x08\n\x06_labelB\x11\n\x0f_dev_use_shadow\"\xa5\x03\n\x0fRenepayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\ncreated_at\x18\x03 \x01(\x01\x12\r\n\x05parts\x18\x04 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12\x32\n\x06status\x18\x07 \x01(\x0e\x32\".cln.RenepayResponse.RenepayStatus\x12\x18\n\x0b\x64\x65stination\x18\x08 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\t \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\n \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07groupid\x18\x0b \x01(\x04H\x03\x88\x01\x01\"6\n\rRenepayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\x0e\n\x0c_destinationB\t\n\x07_bolt11B\t\n\x07_bolt12B\n\n\x08_groupid\"l\n\x14ReserveinputsRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\texclusive\x18\x02 \x01(\x08H\x00\x88\x01\x01\x12\x14\n\x07reserve\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x0c\n\n_exclusiveB\n\n\x08_reserve\"M\n\x15ReserveinputsResponse\x12\x34\n\x0creservations\x18\x01 \x03(\x0b\x32\x1e.cln.ReserveinputsReservations\"z\n\x19ReserveinputsReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\"4\n\x14SendcustommsgRequest\x12\x0f\n\x07node_id\x18\x01 \x01(\x0c\x12\x0b\n\x03msg\x18\x02 \x01(\x0c\"\'\n\x15SendcustommsgResponse\x12\x0e\n\x06status\x18\x01 \x01(\t\"\xb0\x01\n\x12SendinvoiceRequest\x12\x0e\n\x06invreq\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12%\n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x14\n\x07timeout\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08quantity\x18\x05 \x01(\x04H\x02\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\n\n\x08_timeoutB\x0b\n\t_quantity\"\xcf\x04\n\x13SendinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.SendinvoiceResponse.SendinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x08 \x01(\x04H\x02\x88\x01\x01\x12\x1a\n\rupdated_index\x18\t \x01(\x04H\x03\x88\x01\x01\x12\x16\n\tpay_index\x18\n \x01(\x04H\x04\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0c \x01(\x04H\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01\"6\n\x11SendinvoiceStatus\x12\n\n\x06UNPAID\x10\x00\x12\x08\n\x04PAID\x10\x01\x12\x0b\n\x07\x45XPIRED\x10\x02\x42\x0e\n\x0c_amount_msatB\t\n\x07_bolt12B\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimage\"\xaa\x02\n\x11SetchannelRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12!\n\x07\x66\x65\x65\x62\x61se\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x66\x65\x65ppm\x18\x03 \x01(\rH\x01\x88\x01\x01\x12!\n\x07htlcmin\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12!\n\x07htlcmax\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x19\n\x0c\x65nforcedelay\x18\x06 \x01(\rH\x04\x88\x01\x01\x12\x1c\n\x0fignorefeelimits\x18\x07 \x01(\x08H\x05\x88\x01\x01\x42\n\n\x08_feebaseB\t\n\x07_feeppmB\n\n\x08_htlcminB\n\n\x08_htlcmaxB\x0f\n\r_enforcedelayB\x12\n\x10_ignorefeelimits\"?\n\x12SetchannelResponse\x12)\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x17.cln.SetchannelChannels\"\xca\x03\n\x12SetchannelChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x12\n\nchannel_id\x18\x02 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\"\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\r\x12*\n\x15minimum_htlc_out_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x17warning_htlcmin_too_low\x18\x07 \x01(\tH\x01\x88\x01\x01\x12*\n\x15maximum_htlc_out_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x18warning_htlcmax_too_high\x18\t \x01(\tH\x02\x88\x01\x01\x12\x1e\n\x11ignore_fee_limits\x18\n \x01(\x08H\x03\x88\x01\x01\x42\x13\n\x11_short_channel_idB\x1a\n\x18_warning_htlcmin_too_lowB\x1b\n\x19_warning_htlcmax_too_highB\x14\n\x12_ignore_fee_limits\"<\n\x10SetconfigRequest\x12\x0e\n\x06\x63onfig\x18\x01 \x01(\t\x12\x10\n\x03val\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x06\n\x04_val\"9\n\x11SetconfigResponse\x12$\n\x06\x63onfig\x18\x01 \x01(\x0b\x32\x14.cln.SetconfigConfig\"\xa5\x02\n\x0fSetconfigConfig\x12\x0e\n\x06\x63onfig\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x13\n\x06plugin\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x0f\n\x07\x64ynamic\x18\x04 \x01(\x08\x12\x10\n\x03set\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12\x16\n\tvalue_str\x18\x06 \x01(\tH\x02\x88\x01\x01\x12$\n\nvalue_msat\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x16\n\tvalue_int\x18\x08 \x01(\x12H\x04\x88\x01\x01\x12\x17\n\nvalue_bool\x18\t \x01(\x08H\x05\x88\x01\x01\x42\t\n\x07_pluginB\x06\n\x04_setB\x0c\n\n_value_strB\r\n\x0b_value_msatB\x0c\n\n_value_intB\r\n\x0b_value_bool\"6\n\x15SetpsbtversionRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\r\"&\n\x16SetpsbtversionResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\"\'\n\x12SigninvoiceRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\"%\n\x13SigninvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\"%\n\x12SignmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t\"F\n\x13SignmessageResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\x12\r\n\x05recid\x18\x02 \x01(\x0c\x12\r\n\x05zbase\x18\x03 \x01(\t\"\xc9\x01\n\x12Splice_initRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x17\n\x0frelative_amount\x18\x02 \x01(\x12\x12\x18\n\x0binitialpsbt\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x1b\n\x0e\x66\x65\x65rate_per_kw\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x1a\n\rforce_feerate\x18\x05 \x01(\x08H\x02\x88\x01\x01\x42\x0e\n\x0c_initialpsbtB\x11\n\x0f_feerate_per_kwB\x10\n\x0e_force_feerate\"#\n\x13Splice_initResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\"`\n\x14Splice_signedRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\x12\x17\n\nsign_first\x18\x03 \x01(\x08H\x00\x88\x01\x01\x42\r\n\x0b_sign_first\"Q\n\x15Splice_signedResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x13\n\x06outnum\x18\x03 \x01(\rH\x00\x88\x01\x01\x42\t\n\x07_outnum\"8\n\x14Splice_updateRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\"B\n\x15Splice_updateResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x1b\n\x13\x63ommitments_secured\x18\x02 \x01(\x08\"H\n\x16UnreserveinputsRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x14\n\x07reserve\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\n\n\x08_reserve\"Q\n\x17UnreserveinputsResponse\x12\x36\n\x0creservations\x18\x01 \x03(\x0b\x32 .cln.UnreserveinputsReservations\"\x97\x01\n\x1bUnreserveinputsReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x1e\n\x11reserved_to_block\x18\x05 \x01(\rH\x00\x88\x01\x01\x42\x14\n\x12_reserved_to_block\"n\n\x14UpgradewalletRequest\x12\"\n\x07\x66\x65\x65rate\x18\x01 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x17\n\nreservedok\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\n\n\x08_feerateB\r\n\x0b_reservedok\"\x95\x01\n\x15UpgradewalletResponse\x12\x1a\n\rupgraded_outs\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x11\n\x04psbt\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x0f\n\x02tx\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x11\n\x04txid\x18\x04 \x01(\x0cH\x03\x88\x01\x01\x42\x10\n\x0e_upgraded_outsB\x07\n\x05_psbtB\x05\n\x03_txB\x07\n\x05_txid\"O\n\x16WaitblockheightRequest\x12\x13\n\x0b\x62lockheight\x18\x01 \x01(\r\x12\x14\n\x07timeout\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\n\n\x08_timeout\".\n\x17WaitblockheightResponse\x12\x13\n\x0b\x62lockheight\x18\x01 \x01(\r\"\xf9\x01\n\x0bWaitRequest\x12\x31\n\tsubsystem\x18\x01 \x01(\x0e\x32\x1e.cln.WaitRequest.WaitSubsystem\x12\x31\n\tindexname\x18\x02 \x01(\x0e\x32\x1e.cln.WaitRequest.WaitIndexname\x12\x11\n\tnextvalue\x18\x03 \x01(\x04\"9\n\rWaitSubsystem\x12\x0c\n\x08INVOICES\x10\x00\x12\x0c\n\x08\x46ORWARDS\x10\x01\x12\x0c\n\x08SENDPAYS\x10\x02\"6\n\rWaitIndexname\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x12\x0b\n\x07\x44\x45LETED\x10\x02\"\x97\x02\n\x0cWaitResponse\x12\x32\n\tsubsystem\x18\x01 \x01(\x0e\x32\x1f.cln.WaitResponse.WaitSubsystem\x12\x14\n\x07\x63reated\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07updated\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07\x64\x65leted\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12&\n\x07\x64\x65tails\x18\x05 \x01(\x0b\x32\x10.cln.WaitDetailsH\x03\x88\x01\x01\"9\n\rWaitSubsystem\x12\x0c\n\x08INVOICES\x10\x00\x12\x0c\n\x08\x46ORWARDS\x10\x01\x12\x0c\n\x08SENDPAYS\x10\x02\x42\n\n\x08_createdB\n\n\x08_updatedB\n\n\x08_deletedB\n\n\x08_details\"\xfc\x04\n\x0bWaitDetails\x12\x37\n\x06status\x18\x01 \x01(\x0e\x32\".cln.WaitDetails.WaitDetailsStatusH\x00\x88\x01\x01\x12\x12\n\x05label\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x04 \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x05 \x01(\tH\x04\x88\x01\x01\x12\x13\n\x06partid\x18\x06 \x01(\x04H\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\x07 \x01(\x04H\x06\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x08 \x01(\x0cH\x07\x88\x01\x01\x12\x17\n\nin_channel\x18\t \x01(\tH\x08\x88\x01\x01\x12\x17\n\nin_htlc_id\x18\n \x01(\x04H\t\x88\x01\x01\x12!\n\x07in_msat\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\n\x88\x01\x01\x12\x18\n\x0bout_channel\x18\x0c \x01(\tH\x0b\x88\x01\x01\"\x89\x01\n\x11WaitDetailsStatus\x12\n\n\x06UNPAID\x10\x00\x12\x08\n\x04PAID\x10\x01\x12\x0b\n\x07\x45XPIRED\x10\x02\x12\x0b\n\x07PENDING\x10\x03\x12\n\n\x06\x46\x41ILED\x10\x04\x12\x0c\n\x08\x43OMPLETE\x10\x05\x12\x0b\n\x07OFFERED\x10\x06\x12\x0b\n\x07SETTLED\x10\x07\x12\x10\n\x0cLOCAL_FAILED\x10\x08\x42\t\n\x07_statusB\x08\n\x06_labelB\x0e\n\x0c_descriptionB\t\n\x07_bolt11B\t\n\x07_bolt12B\t\n\x07_partidB\n\n\x08_groupidB\x0f\n\r_payment_hashB\r\n\x0b_in_channelB\r\n\x0b_in_htlc_idB\n\n\x08_in_msatB\x0e\n\x0c_out_channel\"4\n\x12ListconfigsRequest\x12\x13\n\x06\x63onfig\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_config\"\xdf\x1b\n\x13ListconfigsResponse\x12-\n\x07\x63onfigs\x18\x01 \x01(\x0b\x32\x17.cln.ListconfigsConfigsH\x00\x88\x01\x01\x12(\n\x07plugins\x18\x03 \x03(\x0b\x32\x17.cln.ListconfigsPlugins\x12;\n\x11important_plugins\x18\x04 \x03(\x0b\x32 .cln.ListconfigsImportantplugins\x12\x11\n\x04\x63onf\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x1a\n\rlightning_dir\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07network\x18\x07 \x01(\tH\x03\x88\x01\x01\x12\"\n\x15\x61llow_deprecated_apis\x18\x08 \x01(\x08H\x04\x88\x01\x01\x12\x15\n\x08rpc_file\x18\t \x01(\tH\x05\x88\x01\x01\x12\x16\n\x0e\x64isable_plugin\x18\n \x03(\t\x12\x1b\n\x0e\x62ookkeeper_dir\x18\x0b \x01(\tH\x06\x88\x01\x01\x12\x1a\n\rbookkeeper_db\x18\x0c \x01(\tH\x07\x88\x01\x01\x12\x1d\n\x10\x61lways_use_proxy\x18\r \x01(\x08H\x08\x88\x01\x01\x12\x13\n\x06\x64\x61\x65mon\x18\x0e \x01(\x08H\t\x88\x01\x01\x12\x13\n\x06wallet\x18\x0f \x01(\tH\n\x88\x01\x01\x12\x1b\n\x0elarge_channels\x18\x10 \x01(\x08H\x0b\x88\x01\x01\x12#\n\x16\x65xperimental_dual_fund\x18\x11 \x01(\x08H\x0c\x88\x01\x01\x12\"\n\x15\x65xperimental_splicing\x18\x12 \x01(\x08H\r\x88\x01\x01\x12(\n\x1b\x65xperimental_onion_messages\x18\x13 \x01(\x08H\x0e\x88\x01\x01\x12 \n\x13\x65xperimental_offers\x18\x14 \x01(\x08H\x0f\x88\x01\x01\x12\x30\n#experimental_shutdown_wrong_funding\x18\x15 \x01(\x08H\x10\x88\x01\x01\x12&\n\x19\x65xperimental_peer_storage\x18\x16 \x01(\x08H\x11\x88\x01\x01\x12!\n\x14\x65xperimental_quiesce\x18\x17 \x01(\x08H\x12\x88\x01\x01\x12*\n\x1d\x65xperimental_upgrade_protocol\x18\x18 \x01(\x08H\x13\x88\x01\x01\x12&\n\x19invoices_onchain_fallback\x18\x19 \x01(\x08H\x14\x88\x01\x01\x12\x1d\n\x10\x64\x61tabase_upgrade\x18\x1a \x01(\x08H\x15\x88\x01\x01\x12\x10\n\x03rgb\x18\x1b \x01(\x0cH\x16\x88\x01\x01\x12\x12\n\x05\x61lias\x18\x1c \x01(\tH\x17\x88\x01\x01\x12\x15\n\x08pid_file\x18\x1d \x01(\tH\x18\x88\x01\x01\x12\x1e\n\x11ignore_fee_limits\x18\x1e \x01(\x08H\x19\x88\x01\x01\x12\x1d\n\x10watchtime_blocks\x18\x1f \x01(\rH\x1a\x88\x01\x01\x12 \n\x13max_locktime_blocks\x18 \x01(\rH\x1b\x88\x01\x01\x12\x1d\n\x10\x66unding_confirms\x18! \x01(\rH\x1c\x88\x01\x01\x12\x17\n\ncltv_delta\x18\" \x01(\rH\x1d\x88\x01\x01\x12\x17\n\ncltv_final\x18# \x01(\rH\x1e\x88\x01\x01\x12\x18\n\x0b\x63ommit_time\x18$ \x01(\rH\x1f\x88\x01\x01\x12\x15\n\x08\x66\x65\x65_base\x18% \x01(\rH \x88\x01\x01\x12\x13\n\x06rescan\x18& \x01(\x12H!\x88\x01\x01\x12\x1c\n\x0f\x66\x65\x65_per_satoshi\x18\' \x01(\rH\"\x88\x01\x01\x12!\n\x14max_concurrent_htlcs\x18( \x01(\rH#\x88\x01\x01\x12+\n\x11htlc_minimum_msat\x18) \x01(\x0b\x32\x0b.cln.AmountH$\x88\x01\x01\x12+\n\x11htlc_maximum_msat\x18* \x01(\x0b\x32\x0b.cln.AmountH%\x88\x01\x01\x12\x35\n\x1bmax_dust_htlc_exposure_msat\x18+ \x01(\x0b\x32\x0b.cln.AmountH&\x88\x01\x01\x12\x1d\n\x10min_capacity_sat\x18, \x01(\x04H\'\x88\x01\x01\x12\x11\n\x04\x61\x64\x64r\x18- \x01(\tH(\x88\x01\x01\x12\x1a\n\rannounce_addr\x18. \x01(\tH)\x88\x01\x01\x12\x16\n\tbind_addr\x18/ \x01(\tH*\x88\x01\x01\x12\x14\n\x07offline\x18\x30 \x01(\x08H+\x88\x01\x01\x12\x17\n\nautolisten\x18\x31 \x01(\x08H,\x88\x01\x01\x12\x12\n\x05proxy\x18\x32 \x01(\tH-\x88\x01\x01\x12\x18\n\x0b\x64isable_dns\x18\x33 \x01(\x08H.\x88\x01\x01\x12%\n\x18\x61nnounce_addr_discovered\x18\x34 \x01(\tH/\x88\x01\x01\x12*\n\x1d\x61nnounce_addr_discovered_port\x18\x35 \x01(\x12H0\x88\x01\x01\x12\x1a\n\rencrypted_hsm\x18\x36 \x01(\x08H1\x88\x01\x01\x12\x1a\n\rrpc_file_mode\x18\x37 \x01(\tH2\x88\x01\x01\x12\x16\n\tlog_level\x18\x38 \x01(\tH3\x88\x01\x01\x12\x17\n\nlog_prefix\x18\x39 \x01(\tH4\x88\x01\x01\x12\x15\n\x08log_file\x18: \x01(\tH5\x88\x01\x01\x12\x1b\n\x0elog_timestamps\x18; \x01(\x08H6\x88\x01\x01\x12\x1b\n\x0e\x66orce_feerates\x18< \x01(\tH7\x88\x01\x01\x12\x16\n\tsubdaemon\x18= \x01(\tH8\x88\x01\x01\x12#\n\x16\x66\x65tchinvoice_noconnect\x18> \x01(\x08H9\x88\x01\x01\x12\"\n\x15\x61\x63\x63\x65pt_htlc_tlv_types\x18? \x01(\tH:\x88\x01\x01\x12!\n\x14tor_service_password\x18@ \x01(\tH;\x88\x01\x01\x12!\n\x14\x64\x65v_allowdustreserve\x18\x41 \x01(\x08H<\x88\x01\x01\x12\x1e\n\x11\x61nnounce_addr_dns\x18\x42 \x01(\x08H=\x88\x01\x01\x12%\n\x18require_confirmed_inputs\x18\x43 \x01(\x08H>\x88\x01\x01\x12\x16\n\tdeveloper\x18\x44 \x01(\x08H?\x88\x01\x01\x12\x17\n\ncommit_fee\x18\x45 \x01(\x04H@\x88\x01\x01\x12,\n\x12min_emergency_msat\x18\x46 \x01(\x0b\x32\x0b.cln.AmountHA\x88\x01\x01\x12\"\n\x15\x63ommit_feerate_offset\x18G \x01(\rHB\x88\x01\x01\x42\n\n\x08_configsB\x07\n\x05_confB\x10\n\x0e_lightning_dirB\n\n\x08_networkB\x18\n\x16_allow_deprecated_apisB\x0b\n\t_rpc_fileB\x11\n\x0f_bookkeeper_dirB\x10\n\x0e_bookkeeper_dbB\x13\n\x11_always_use_proxyB\t\n\x07_daemonB\t\n\x07_walletB\x11\n\x0f_large_channelsB\x19\n\x17_experimental_dual_fundB\x18\n\x16_experimental_splicingB\x1e\n\x1c_experimental_onion_messagesB\x16\n\x14_experimental_offersB&\n$_experimental_shutdown_wrong_fundingB\x1c\n\x1a_experimental_peer_storageB\x17\n\x15_experimental_quiesceB \n\x1e_experimental_upgrade_protocolB\x1c\n\x1a_invoices_onchain_fallbackB\x13\n\x11_database_upgradeB\x06\n\x04_rgbB\x08\n\x06_aliasB\x0b\n\t_pid_fileB\x14\n\x12_ignore_fee_limitsB\x13\n\x11_watchtime_blocksB\x16\n\x14_max_locktime_blocksB\x13\n\x11_funding_confirmsB\r\n\x0b_cltv_deltaB\r\n\x0b_cltv_finalB\x0e\n\x0c_commit_timeB\x0b\n\t_fee_baseB\t\n\x07_rescanB\x12\n\x10_fee_per_satoshiB\x17\n\x15_max_concurrent_htlcsB\x14\n\x12_htlc_minimum_msatB\x14\n\x12_htlc_maximum_msatB\x1e\n\x1c_max_dust_htlc_exposure_msatB\x13\n\x11_min_capacity_satB\x07\n\x05_addrB\x10\n\x0e_announce_addrB\x0c\n\n_bind_addrB\n\n\x08_offlineB\r\n\x0b_autolistenB\x08\n\x06_proxyB\x0e\n\x0c_disable_dnsB\x1b\n\x19_announce_addr_discoveredB \n\x1e_announce_addr_discovered_portB\x10\n\x0e_encrypted_hsmB\x10\n\x0e_rpc_file_modeB\x0c\n\n_log_levelB\r\n\x0b_log_prefixB\x0b\n\t_log_fileB\x11\n\x0f_log_timestampsB\x11\n\x0f_force_feeratesB\x0c\n\n_subdaemonB\x19\n\x17_fetchinvoice_noconnectB\x18\n\x16_accept_htlc_tlv_typesB\x17\n\x15_tor_service_passwordB\x17\n\x15_dev_allowdustreserveB\x14\n\x12_announce_addr_dnsB\x1b\n\x19_require_confirmed_inputsB\x0c\n\n_developerB\r\n\x0b_commit_feeB\x15\n\x13_min_emergency_msatB\x18\n\x16_commit_feerate_offset\"\xdf.\n\x12ListconfigsConfigs\x12.\n\x04\x63onf\x18\x01 \x01(\x0b\x32\x1b.cln.ListconfigsConfigsConfH\x00\x88\x01\x01\x12\x38\n\tdeveloper\x18\x02 \x01(\x0b\x32 .cln.ListconfigsConfigsDeveloperH\x01\x88\x01\x01\x12?\n\rclear_plugins\x18\x03 \x01(\x0b\x32#.cln.ListconfigsConfigsClearpluginsH\x02\x88\x01\x01\x12;\n\x0b\x64isable_mpp\x18\x04 \x01(\x0b\x32!.cln.ListconfigsConfigsDisablemppH\x03\x88\x01\x01\x12\x34\n\x07mainnet\x18\x05 \x01(\x0b\x32\x1e.cln.ListconfigsConfigsMainnetH\x04\x88\x01\x01\x12\x34\n\x07regtest\x18\x06 \x01(\x0b\x32\x1e.cln.ListconfigsConfigsRegtestH\x05\x88\x01\x01\x12\x32\n\x06signet\x18\x07 \x01(\x0b\x32\x1d.cln.ListconfigsConfigsSignetH\x06\x88\x01\x01\x12\x34\n\x07testnet\x18\x08 \x01(\x0b\x32\x1e.cln.ListconfigsConfigsTestnetH\x07\x88\x01\x01\x12\x45\n\x10important_plugin\x18\t \x01(\x0b\x32&.cln.ListconfigsConfigsImportantpluginH\x08\x88\x01\x01\x12\x32\n\x06plugin\x18\n \x01(\x0b\x32\x1d.cln.ListconfigsConfigsPluginH\t\x88\x01\x01\x12\x39\n\nplugin_dir\x18\x0b \x01(\x0b\x32 .cln.ListconfigsConfigsPlugindirH\n\x88\x01\x01\x12?\n\rlightning_dir\x18\x0c \x01(\x0b\x32#.cln.ListconfigsConfigsLightningdirH\x0b\x88\x01\x01\x12\x34\n\x07network\x18\r \x01(\x0b\x32\x1e.cln.ListconfigsConfigsNetworkH\x0c\x88\x01\x01\x12N\n\x15\x61llow_deprecated_apis\x18\x0e \x01(\x0b\x32*.cln.ListconfigsConfigsAllowdeprecatedapisH\r\x88\x01\x01\x12\x35\n\x08rpc_file\x18\x0f \x01(\x0b\x32\x1e.cln.ListconfigsConfigsRpcfileH\x0e\x88\x01\x01\x12\x41\n\x0e\x64isable_plugin\x18\x10 \x01(\x0b\x32$.cln.ListconfigsConfigsDisablepluginH\x0f\x88\x01\x01\x12\x44\n\x10\x61lways_use_proxy\x18\x11 \x01(\x0b\x32%.cln.ListconfigsConfigsAlwaysuseproxyH\x10\x88\x01\x01\x12\x32\n\x06\x64\x61\x65mon\x18\x12 \x01(\x0b\x32\x1d.cln.ListconfigsConfigsDaemonH\x11\x88\x01\x01\x12\x32\n\x06wallet\x18\x13 \x01(\x0b\x32\x1d.cln.ListconfigsConfigsWalletH\x12\x88\x01\x01\x12\x41\n\x0elarge_channels\x18\x14 \x01(\x0b\x32$.cln.ListconfigsConfigsLargechannelsH\x13\x88\x01\x01\x12P\n\x16\x65xperimental_dual_fund\x18\x15 \x01(\x0b\x32+.cln.ListconfigsConfigsExperimentaldualfundH\x14\x88\x01\x01\x12O\n\x15\x65xperimental_splicing\x18\x16 \x01(\x0b\x32+.cln.ListconfigsConfigsExperimentalsplicingH\x15\x88\x01\x01\x12Z\n\x1b\x65xperimental_onion_messages\x18\x17 \x01(\x0b\x32\x30.cln.ListconfigsConfigsExperimentalonionmessagesH\x16\x88\x01\x01\x12K\n\x13\x65xperimental_offers\x18\x18 \x01(\x0b\x32).cln.ListconfigsConfigsExperimentaloffersH\x17\x88\x01\x01\x12i\n#experimental_shutdown_wrong_funding\x18\x19 \x01(\x0b\x32\x37.cln.ListconfigsConfigsExperimentalshutdownwrongfundingH\x18\x88\x01\x01\x12V\n\x19\x65xperimental_peer_storage\x18\x1a \x01(\x0b\x32..cln.ListconfigsConfigsExperimentalpeerstorageH\x19\x88\x01\x01\x12M\n\x14\x65xperimental_anchors\x18\x1b \x01(\x0b\x32*.cln.ListconfigsConfigsExperimentalanchorsH\x1a\x88\x01\x01\x12\x45\n\x10\x64\x61tabase_upgrade\x18\x1c \x01(\x0b\x32&.cln.ListconfigsConfigsDatabaseupgradeH\x1b\x88\x01\x01\x12,\n\x03rgb\x18\x1d \x01(\x0b\x32\x1a.cln.ListconfigsConfigsRgbH\x1c\x88\x01\x01\x12\x30\n\x05\x61lias\x18\x1e \x01(\x0b\x32\x1c.cln.ListconfigsConfigsAliasH\x1d\x88\x01\x01\x12\x35\n\x08pid_file\x18\x1f \x01(\x0b\x32\x1e.cln.ListconfigsConfigsPidfileH\x1e\x88\x01\x01\x12\x46\n\x11ignore_fee_limits\x18 \x01(\x0b\x32&.cln.ListconfigsConfigsIgnorefeelimitsH\x1f\x88\x01\x01\x12\x45\n\x10watchtime_blocks\x18! \x01(\x0b\x32&.cln.ListconfigsConfigsWatchtimeblocksH \x88\x01\x01\x12J\n\x13max_locktime_blocks\x18\" \x01(\x0b\x32(.cln.ListconfigsConfigsMaxlocktimeblocksH!\x88\x01\x01\x12\x45\n\x10\x66unding_confirms\x18# \x01(\x0b\x32&.cln.ListconfigsConfigsFundingconfirmsH\"\x88\x01\x01\x12\x39\n\ncltv_delta\x18$ \x01(\x0b\x32 .cln.ListconfigsConfigsCltvdeltaH#\x88\x01\x01\x12\x39\n\ncltv_final\x18% \x01(\x0b\x32 .cln.ListconfigsConfigsCltvfinalH$\x88\x01\x01\x12;\n\x0b\x63ommit_time\x18& \x01(\x0b\x32!.cln.ListconfigsConfigsCommittimeH%\x88\x01\x01\x12\x35\n\x08\x66\x65\x65_base\x18\' \x01(\x0b\x32\x1e.cln.ListconfigsConfigsFeebaseH&\x88\x01\x01\x12\x32\n\x06rescan\x18( \x01(\x0b\x32\x1d.cln.ListconfigsConfigsRescanH\'\x88\x01\x01\x12\x42\n\x0f\x66\x65\x65_per_satoshi\x18) \x01(\x0b\x32$.cln.ListconfigsConfigsFeepersatoshiH(\x88\x01\x01\x12L\n\x14max_concurrent_htlcs\x18* \x01(\x0b\x32).cln.ListconfigsConfigsMaxconcurrenthtlcsH)\x88\x01\x01\x12\x46\n\x11htlc_minimum_msat\x18+ \x01(\x0b\x32&.cln.ListconfigsConfigsHtlcminimummsatH*\x88\x01\x01\x12\x46\n\x11htlc_maximum_msat\x18, \x01(\x0b\x32&.cln.ListconfigsConfigsHtlcmaximummsatH+\x88\x01\x01\x12X\n\x1bmax_dust_htlc_exposure_msat\x18- \x01(\x0b\x32..cln.ListconfigsConfigsMaxdusthtlcexposuremsatH,\x88\x01\x01\x12\x44\n\x10min_capacity_sat\x18. \x01(\x0b\x32%.cln.ListconfigsConfigsMincapacitysatH-\x88\x01\x01\x12.\n\x04\x61\x64\x64r\x18/ \x01(\x0b\x32\x1b.cln.ListconfigsConfigsAddrH.\x88\x01\x01\x12?\n\rannounce_addr\x18\x30 \x01(\x0b\x32#.cln.ListconfigsConfigsAnnounceaddrH/\x88\x01\x01\x12\x37\n\tbind_addr\x18\x31 \x01(\x0b\x32\x1f.cln.ListconfigsConfigsBindaddrH0\x88\x01\x01\x12\x34\n\x07offline\x18\x32 \x01(\x0b\x32\x1e.cln.ListconfigsConfigsOfflineH1\x88\x01\x01\x12:\n\nautolisten\x18\x33 \x01(\x0b\x32!.cln.ListconfigsConfigsAutolistenH2\x88\x01\x01\x12\x30\n\x05proxy\x18\x34 \x01(\x0b\x32\x1c.cln.ListconfigsConfigsProxyH3\x88\x01\x01\x12;\n\x0b\x64isable_dns\x18\x35 \x01(\x0b\x32!.cln.ListconfigsConfigsDisablednsH4\x88\x01\x01\x12T\n\x18\x61nnounce_addr_discovered\x18\x36 \x01(\x0b\x32-.cln.ListconfigsConfigsAnnounceaddrdiscoveredH5\x88\x01\x01\x12]\n\x1d\x61nnounce_addr_discovered_port\x18\x37 \x01(\x0b\x32\x31.cln.ListconfigsConfigsAnnounceaddrdiscoveredportH6\x88\x01\x01\x12?\n\rencrypted_hsm\x18\x38 \x01(\x0b\x32#.cln.ListconfigsConfigsEncryptedhsmH7\x88\x01\x01\x12>\n\rrpc_file_mode\x18\x39 \x01(\x0b\x32\".cln.ListconfigsConfigsRpcfilemodeH8\x88\x01\x01\x12\x37\n\tlog_level\x18: \x01(\x0b\x32\x1f.cln.ListconfigsConfigsLoglevelH9\x88\x01\x01\x12\x39\n\nlog_prefix\x18; \x01(\x0b\x32 .cln.ListconfigsConfigsLogprefixH:\x88\x01\x01\x12\x35\n\x08log_file\x18< \x01(\x0b\x32\x1e.cln.ListconfigsConfigsLogfileH;\x88\x01\x01\x12\x41\n\x0elog_timestamps\x18= \x01(\x0b\x32$.cln.ListconfigsConfigsLogtimestampsH<\x88\x01\x01\x12\x41\n\x0e\x66orce_feerates\x18> \x01(\x0b\x32$.cln.ListconfigsConfigsForcefeeratesH=\x88\x01\x01\x12\x38\n\tsubdaemon\x18? \x01(\x0b\x32 .cln.ListconfigsConfigsSubdaemonH>\x88\x01\x01\x12Q\n\x16\x66\x65tchinvoice_noconnect\x18@ \x01(\x0b\x32,.cln.ListconfigsConfigsFetchinvoicenoconnectH?\x88\x01\x01\x12M\n\x15\x61\x63\x63\x65pt_htlc_tlv_types\x18\x41 \x01(\x0b\x32).cln.ListconfigsConfigsAccepthtlctlvtypesH@\x88\x01\x01\x12L\n\x14tor_service_password\x18\x42 \x01(\x0b\x32).cln.ListconfigsConfigsTorservicepasswordHA\x88\x01\x01\x12\x46\n\x11\x61nnounce_addr_dns\x18\x43 \x01(\x0b\x32&.cln.ListconfigsConfigsAnnounceaddrdnsHB\x88\x01\x01\x12T\n\x18require_confirmed_inputs\x18\x44 \x01(\x0b\x32-.cln.ListconfigsConfigsRequireconfirmedinputsHC\x88\x01\x01\x12\x39\n\ncommit_fee\x18\x45 \x01(\x0b\x32 .cln.ListconfigsConfigsCommitfeeHD\x88\x01\x01\x12N\n\x15\x63ommit_feerate_offset\x18\x46 \x01(\x0b\x32*.cln.ListconfigsConfigsCommitfeerateoffsetHE\x88\x01\x01\x42\x07\n\x05_confB\x0c\n\n_developerB\x10\n\x0e_clear_pluginsB\x0e\n\x0c_disable_mppB\n\n\x08_mainnetB\n\n\x08_regtestB\t\n\x07_signetB\n\n\x08_testnetB\x13\n\x11_important_pluginB\t\n\x07_pluginB\r\n\x0b_plugin_dirB\x10\n\x0e_lightning_dirB\n\n\x08_networkB\x18\n\x16_allow_deprecated_apisB\x0b\n\t_rpc_fileB\x11\n\x0f_disable_pluginB\x13\n\x11_always_use_proxyB\t\n\x07_daemonB\t\n\x07_walletB\x11\n\x0f_large_channelsB\x19\n\x17_experimental_dual_fundB\x18\n\x16_experimental_splicingB\x1e\n\x1c_experimental_onion_messagesB\x16\n\x14_experimental_offersB&\n$_experimental_shutdown_wrong_fundingB\x1c\n\x1a_experimental_peer_storageB\x17\n\x15_experimental_anchorsB\x13\n\x11_database_upgradeB\x06\n\x04_rgbB\x08\n\x06_aliasB\x0b\n\t_pid_fileB\x14\n\x12_ignore_fee_limitsB\x13\n\x11_watchtime_blocksB\x16\n\x14_max_locktime_blocksB\x13\n\x11_funding_confirmsB\r\n\x0b_cltv_deltaB\r\n\x0b_cltv_finalB\x0e\n\x0c_commit_timeB\x0b\n\t_fee_baseB\t\n\x07_rescanB\x12\n\x10_fee_per_satoshiB\x17\n\x15_max_concurrent_htlcsB\x14\n\x12_htlc_minimum_msatB\x14\n\x12_htlc_maximum_msatB\x1e\n\x1c_max_dust_htlc_exposure_msatB\x13\n\x11_min_capacity_satB\x07\n\x05_addrB\x10\n\x0e_announce_addrB\x0c\n\n_bind_addrB\n\n\x08_offlineB\r\n\x0b_autolistenB\x08\n\x06_proxyB\x0e\n\x0c_disable_dnsB\x1b\n\x19_announce_addr_discoveredB \n\x1e_announce_addr_discovered_portB\x10\n\x0e_encrypted_hsmB\x10\n\x0e_rpc_file_modeB\x0c\n\n_log_levelB\r\n\x0b_log_prefixB\x0b\n\t_log_fileB\x11\n\x0f_log_timestampsB\x11\n\x0f_force_feeratesB\x0c\n\n_subdaemonB\x19\n\x17_fetchinvoice_noconnectB\x18\n\x16_accept_htlc_tlv_typesB\x17\n\x15_tor_service_passwordB\x14\n\x12_announce_addr_dnsB\x1b\n\x19_require_confirmed_inputsB\r\n\x0b_commit_feeB\x18\n\x16_commit_feerate_offset\"\xa2\x01\n\x16ListconfigsConfigsConf\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12H\n\x06source\x18\x02 \x01(\x0e\x32\x38.cln.ListconfigsConfigsConf.ListconfigsConfigsConfSource\"+\n\x1cListconfigsConfigsConfSource\x12\x0b\n\x07\x43MDLINE\x10\x00\":\n\x1bListconfigsConfigsDeveloper\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"=\n\x1eListconfigsConfigsClearplugins\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"[\n\x1cListconfigsConfigsDisablempp\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x13\n\x06plugin\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_plugin\"8\n\x19ListconfigsConfigsMainnet\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"8\n\x19ListconfigsConfigsRegtest\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"7\n\x18ListconfigsConfigsSignet\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"8\n\x19ListconfigsConfigsTestnet\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"H\n!ListconfigsConfigsImportantplugin\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"?\n\x18ListconfigsConfigsPlugin\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"B\n\x1bListconfigsConfigsPlugindir\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"C\n\x1eListconfigsConfigsLightningdir\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x19ListconfigsConfigsNetwork\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"K\n%ListconfigsConfigsAllowdeprecatedapis\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x19ListconfigsConfigsRpcfile\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"F\n\x1fListconfigsConfigsDisableplugin\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"F\n ListconfigsConfigsAlwaysuseproxy\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"7\n\x18ListconfigsConfigsDaemon\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"=\n\x18ListconfigsConfigsWallet\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x1fListconfigsConfigsLargechannels\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"E\n&ListconfigsConfigsExperimentaldualfund\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"E\n&ListconfigsConfigsExperimentalsplicing\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"J\n+ListconfigsConfigsExperimentalonionmessages\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"C\n$ListconfigsConfigsExperimentaloffers\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"Q\n2ListconfigsConfigsExperimentalshutdownwrongfunding\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"H\n)ListconfigsConfigsExperimentalpeerstorage\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"D\n%ListconfigsConfigsExperimentalanchors\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"G\n!ListconfigsConfigsDatabaseupgrade\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\":\n\x15ListconfigsConfigsRgb\x12\x11\n\tvalue_str\x18\x01 \x01(\x0c\x12\x0e\n\x06source\x18\x02 \x01(\t\"<\n\x17ListconfigsConfigsAlias\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x19ListconfigsConfigsPidfile\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"G\n!ListconfigsConfigsIgnorefeelimits\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"F\n!ListconfigsConfigsWatchtimeblocks\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"H\n#ListconfigsConfigsMaxlocktimeblocks\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"F\n!ListconfigsConfigsFundingconfirms\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x1bListconfigsConfigsCltvdelta\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x1bListconfigsConfigsCltvfinal\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"A\n\x1cListconfigsConfigsCommittime\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x19ListconfigsConfigsFeebase\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"=\n\x18ListconfigsConfigsRescan\x12\x11\n\tvalue_int\x18\x01 \x01(\x12\x12\x0e\n\x06source\x18\x02 \x01(\t\"D\n\x1fListconfigsConfigsFeepersatoshi\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"I\n$ListconfigsConfigsMaxconcurrenthtlcs\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"T\n!ListconfigsConfigsHtlcminimummsat\x12\x1f\n\nvalue_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06source\x18\x02 \x01(\t\"T\n!ListconfigsConfigsHtlcmaximummsat\x12\x1f\n\nvalue_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06source\x18\x02 \x01(\t\"\\\n)ListconfigsConfigsMaxdusthtlcexposuremsat\x12\x1f\n\nvalue_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06source\x18\x02 \x01(\t\"g\n ListconfigsConfigsMincapacitysat\x12\x11\n\tvalue_int\x18\x01 \x01(\x04\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x14\n\x07\x64ynamic\x18\x03 \x01(\x08H\x00\x88\x01\x01\x42\n\n\x08_dynamic\"=\n\x16ListconfigsConfigsAddr\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"E\n\x1eListconfigsConfigsAnnounceaddr\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"A\n\x1aListconfigsConfigsBindaddr\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"8\n\x19ListconfigsConfigsOffline\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"B\n\x1cListconfigsConfigsAutolisten\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"<\n\x17ListconfigsConfigsProxy\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\";\n\x1cListconfigsConfigsDisabledns\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"\x82\x02\n(ListconfigsConfigsAnnounceaddrdiscovered\x12r\n\tvalue_str\x18\x01 \x01(\x0e\x32_.cln.ListconfigsConfigsAnnounceaddrdiscovered.ListconfigsConfigsAnnounceaddrdiscoveredValue_str\x12\x0e\n\x06source\x18\x02 \x01(\t\"R\n1ListconfigsConfigsAnnounceaddrdiscoveredValue_str\x12\x08\n\x04TRUE\x10\x00\x12\t\n\x05\x46\x41LSE\x10\x01\x12\x08\n\x04\x41UTO\x10\x02\"Q\n,ListconfigsConfigsAnnounceaddrdiscoveredport\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"=\n\x1eListconfigsConfigsEncryptedhsm\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"B\n\x1dListconfigsConfigsRpcfilemode\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"?\n\x1aListconfigsConfigsLoglevel\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x1bListconfigsConfigsLogprefix\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x19ListconfigsConfigsLogfile\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"E\n\x1fListconfigsConfigsLogtimestamps\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"D\n\x1fListconfigsConfigsForcefeerates\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"B\n\x1bListconfigsConfigsSubdaemon\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"f\n\'ListconfigsConfigsFetchinvoicenoconnect\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x13\n\x06plugin\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_plugin\"I\n$ListconfigsConfigsAccepthtlctlvtypes\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"I\n$ListconfigsConfigsTorservicepassword\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"G\n!ListconfigsConfigsAnnounceaddrdns\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"N\n(ListconfigsConfigsRequireconfirmedinputs\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x1bListconfigsConfigsCommitfee\x12\x11\n\tvalue_int\x18\x01 \x01(\x04\x12\x0e\n\x06source\x18\x02 \x01(\t\"J\n%ListconfigsConfigsCommitfeerateoffset\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"r\n\x12ListconfigsPlugins\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x34\n\x07options\x18\x03 \x01(\x0b\x32\x1e.cln.ListconfigsPluginsOptionsH\x00\x88\x01\x01\x42\n\n\x08_options\"\x1b\n\x19ListconfigsPluginsOptions\"\x84\x01\n\x1bListconfigsImportantplugins\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12=\n\x07options\x18\x03 \x01(\x0b\x32\'.cln.ListconfigsImportantpluginsOptionsH\x00\x88\x01\x01\x42\n\n\x08_options\"$\n\"ListconfigsImportantpluginsOptions\"\r\n\x0bStopRequest\"q\n\x0cStopResponse\x12\x31\n\x06result\x18\x01 \x01(\x0e\x32\x1c.cln.StopResponse.StopResultH\x00\x88\x01\x01\"#\n\nStopResult\x12\x15\n\x11SHUTDOWN_COMPLETE\x10\x00\x42\t\n\x07_result\"/\n\x0bHelpRequest\x12\x14\n\x07\x63ommand\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_command\"\x95\x01\n\x0cHelpResponse\x12\x1b\n\x04help\x18\x01 \x03(\x0b\x32\r.cln.HelpHelp\x12:\n\x0b\x66ormat_hint\x18\x02 \x01(\x0e\x32 .cln.HelpResponse.HelpFormathintH\x00\x88\x01\x01\"\x1c\n\x0eHelpFormathint\x12\n\n\x06SIMPLE\x10\x00\x42\x0e\n\x0c_format_hint\"\x1b\n\x08HelpHelp\x12\x0f\n\x07\x63ommand\x18\x01 \x01(\t\"g\n\x18PreapprovekeysendRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\x0c\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\"\x1b\n\x19PreapprovekeysendResponse\"*\n\x18PreapproveinvoiceRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\"\x1b\n\x19PreapproveinvoiceResponse\"\x15\n\x13StaticbackupRequest\"#\n\x14StaticbackupResponse\x12\x0b\n\x03scb\x18\x01 \x03(\x0c\"d\n\x16\x42kprchannelsapyRequest\x12\x17\n\nstart_time\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x15\n\x08\x65nd_time\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\r\n\x0b_start_timeB\x0b\n\t_end_time\"Q\n\x17\x42kprchannelsapyResponse\x12\x36\n\x0c\x63hannels_apy\x18\x01 \x03(\x0b\x32 .cln.BkprchannelsapyChannels_apy\"\xfa\x06\n\x1b\x42kprchannelsapyChannels_apy\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12$\n\x0frouted_out_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0erouted_in_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12(\n\x13lease_fee_paid_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12*\n\x15lease_fee_earned_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x0fpushed_out_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0epushed_in_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x16our_start_balance_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12/\n\x1a\x63hannel_start_balance_msat\x18\t \x01(\x0b\x32\x0b.cln.Amount\x12\"\n\rfees_out_msat\x18\n \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x0c\x66\x65\x65s_in_msat\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x17\n\x0futilization_out\x18\x0c \x01(\t\x12$\n\x17utilization_out_initial\x18\r \x01(\tH\x01\x88\x01\x01\x12\x16\n\x0eutilization_in\x18\x0e \x01(\t\x12#\n\x16utilization_in_initial\x18\x0f \x01(\tH\x02\x88\x01\x01\x12\x0f\n\x07\x61py_out\x18\x10 \x01(\t\x12\x1c\n\x0f\x61py_out_initial\x18\x11 \x01(\tH\x03\x88\x01\x01\x12\x0e\n\x06\x61py_in\x18\x12 \x01(\t\x12\x1b\n\x0e\x61py_in_initial\x18\x13 \x01(\tH\x04\x88\x01\x01\x12\x11\n\tapy_total\x18\x14 \x01(\t\x12\x1e\n\x11\x61py_total_initial\x18\x15 \x01(\tH\x05\x88\x01\x01\x12\x16\n\tapy_lease\x18\x16 \x01(\tH\x06\x88\x01\x01\x42\x0f\n\r_fees_in_msatB\x1a\n\x18_utilization_out_initialB\x19\n\x17_utilization_in_initialB\x12\n\x10_apy_out_initialB\x11\n\x0f_apy_in_initialB\x14\n\x12_apy_total_initialB\x0c\n\n_apy_lease\"\xd2\x01\n\x18\x42kprdumpincomecsvRequest\x12\x12\n\ncsv_format\x18\x01 \x01(\t\x12\x15\n\x08\x63sv_file\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x1d\n\x10\x63onsolidate_fees\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12\x17\n\nstart_time\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x15\n\x08\x65nd_time\x18\x05 \x01(\x04H\x03\x88\x01\x01\x42\x0b\n\t_csv_fileB\x13\n\x11_consolidate_feesB\r\n\x0b_start_timeB\x0b\n\t_end_time\"\xd6\x01\n\x19\x42kprdumpincomecsvResponse\x12\x10\n\x08\x63sv_file\x18\x01 \x01(\t\x12N\n\ncsv_format\x18\x02 \x01(\x0e\x32:.cln.BkprdumpincomecsvResponse.BkprdumpincomecsvCsv_format\"W\n\x1b\x42kprdumpincomecsvCsv_format\x12\x0f\n\x0b\x43OINTRACKER\x10\x00\x12\n\n\x06KOINLY\x10\x01\x12\x0b\n\x07HARMONY\x10\x02\x12\x0e\n\nQUICKBOOKS\x10\x03\"%\n\x12\x42kprinspectRequest\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\"7\n\x13\x42kprinspectResponse\x12 \n\x03txs\x18\x01 \x03(\x0b\x32\x13.cln.BkprinspectTxs\"\x9a\x01\n\x0e\x42kprinspectTxs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x18\n\x0b\x62lockheight\x18\x02 \x01(\rH\x00\x88\x01\x01\x12#\n\x0e\x66\x65\x65s_paid_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x07outputs\x18\x04 \x03(\x0b\x32\x1a.cln.BkprinspectTxsOutputsB\x0e\n\x0c_blockheight\"\xbc\x03\n\x15\x42kprinspectTxsOutputs\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12\x0e\n\x06outnum\x18\x02 \x01(\r\x12&\n\x11output_value_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x10\n\x08\x63urrency\x18\x04 \x01(\t\x12%\n\x0b\x63redit_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12$\n\ndebit_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12 \n\x13originating_account\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x17\n\noutput_tag\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tspend_tag\x18\t \x01(\tH\x04\x88\x01\x01\x12\x1a\n\rspending_txid\x18\n \x01(\x0cH\x05\x88\x01\x01\x12\x17\n\npayment_id\x18\x0b \x01(\x0cH\x06\x88\x01\x01\x42\x0e\n\x0c_credit_msatB\r\n\x0b_debit_msatB\x16\n\x14_originating_accountB\r\n\x0b_output_tagB\x0c\n\n_spend_tagB\x10\n\x0e_spending_txidB\r\n\x0b_payment_id\"h\n\x1c\x42kprlistaccounteventsRequest\x12\x14\n\x07\x61\x63\x63ount\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\npayment_id\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\n\n\x08_accountB\r\n\x0b_payment_id\"Q\n\x1d\x42kprlistaccounteventsResponse\x12\x30\n\x06\x65vents\x18\x01 \x03(\x0b\x32 .cln.BkprlistaccounteventsEvents\"\xa1\x05\n\x1b\x42kprlistaccounteventsEvents\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12S\n\titem_type\x18\x02 \x01(\x0e\x32@.cln.BkprlistaccounteventsEvents.BkprlistaccounteventsEventsType\x12\x0b\n\x03tag\x18\x03 \x01(\t\x12 \n\x0b\x63redit_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1f\n\ndebit_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x10\n\x08\x63urrency\x18\x06 \x01(\t\x12\x11\n\ttimestamp\x18\x07 \x01(\r\x12\x15\n\x08outpoint\x18\x08 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x62lockheight\x18\t \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06origin\x18\n \x01(\tH\x02\x88\x01\x01\x12\x17\n\npayment_id\x18\x0b \x01(\x0cH\x03\x88\x01\x01\x12\x11\n\x04txid\x18\x0c \x01(\x0cH\x04\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\r \x01(\tH\x05\x88\x01\x01\x12#\n\tfees_msat\x18\x0e \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x19\n\x0cis_rebalance\x18\x0f \x01(\x08H\x07\x88\x01\x01\x12\x14\n\x07part_id\x18\x10 \x01(\rH\x08\x88\x01\x01\"J\n\x1f\x42kprlistaccounteventsEventsType\x12\x0f\n\x0bONCHAIN_FEE\x10\x00\x12\t\n\x05\x43HAIN\x10\x01\x12\x0b\n\x07\x43HANNEL\x10\x02\x42\x0b\n\t_outpointB\x0e\n\x0c_blockheightB\t\n\x07_originB\r\n\x0b_payment_idB\x07\n\x05_txidB\x0e\n\x0c_descriptionB\x0c\n\n_fees_msatB\x0f\n\r_is_rebalanceB\n\n\x08_part_id\"\x19\n\x17\x42kprlistbalancesRequest\"K\n\x18\x42kprlistbalancesResponse\x12/\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x1d.cln.BkprlistbalancesAccounts\"\xc6\x02\n\x18\x42kprlistbalancesAccounts\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12\x37\n\x08\x62\x61lances\x18\x02 \x03(\x0b\x32%.cln.BkprlistbalancesAccountsBalances\x12\x14\n\x07peer_id\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x16\n\twe_opened\x18\x04 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x61\x63\x63ount_closed\x18\x05 \x01(\x08H\x02\x88\x01\x01\x12\x1d\n\x10\x61\x63\x63ount_resolved\x18\x06 \x01(\x08H\x03\x88\x01\x01\x12\x1e\n\x11resolved_at_block\x18\x07 \x01(\rH\x04\x88\x01\x01\x42\n\n\x08_peer_idB\x0c\n\n_we_openedB\x11\n\x0f_account_closedB\x13\n\x11_account_resolvedB\x14\n\x12_resolved_at_block\"X\n BkprlistbalancesAccountsBalances\x12!\n\x0c\x62\x61lance_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x11\n\tcoin_type\x18\x02 \x01(\t\"\x97\x01\n\x15\x42kprlistincomeRequest\x12\x1d\n\x10\x63onsolidate_fees\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12\x17\n\nstart_time\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08\x65nd_time\x18\x03 \x01(\rH\x02\x88\x01\x01\x42\x13\n\x11_consolidate_feesB\r\n\x0b_start_timeB\x0b\n\t_end_time\"Q\n\x16\x42kprlistincomeResponse\x12\x37\n\rincome_events\x18\x01 \x03(\x0b\x32 .cln.BkprlistincomeIncome_events\"\xb5\x02\n\x1b\x42kprlistincomeIncome_events\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12\x0b\n\x03tag\x18\x02 \x01(\t\x12 \n\x0b\x63redit_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x1f\n\ndebit_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x10\n\x08\x63urrency\x18\x05 \x01(\t\x12\x11\n\ttimestamp\x18\x06 \x01(\r\x12\x18\n\x0b\x64\x65scription\x18\x07 \x01(\tH\x00\x88\x01\x01\x12\x15\n\x08outpoint\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x11\n\x04txid\x18\t \x01(\x0cH\x02\x88\x01\x01\x12\x17\n\npayment_id\x18\n \x01(\x0cH\x03\x88\x01\x01\x42\x0e\n\x0c_descriptionB\x0b\n\t_outpointB\x07\n\x05_txidB\r\n\x0b_payment_id\"N\n\x14\x42lacklistruneRequest\x12\x12\n\x05start\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03\x65nd\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x08\n\x06_startB\x06\n\x04_end\"G\n\x15\x42lacklistruneResponse\x12.\n\tblacklist\x18\x01 \x03(\x0b\x32\x1b.cln.BlacklistruneBlacklist\"4\n\x16\x42lacklistruneBlacklist\x12\r\n\x05start\x18\x01 \x01(\x04\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x04\"p\n\x10\x43heckruneRequest\x12\x0c\n\x04rune\x18\x01 \x01(\t\x12\x13\n\x06nodeid\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06method\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x0e\n\x06params\x18\x04 \x03(\tB\t\n\x07_nodeidB\t\n\x07_method\"\"\n\x11\x43heckruneResponse\x12\r\n\x05valid\x18\x01 \x01(\x08\"E\n\x11\x43reateruneRequest\x12\x11\n\x04rune\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0crestrictions\x18\x02 \x03(\tB\x07\n\x05_rune\"{\n\x12\x43reateruneResponse\x12\x0c\n\x04rune\x18\x01 \x01(\t\x12\x11\n\tunique_id\x18\x02 \x01(\t\x12&\n\x19warning_unrestricted_rune\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x1c\n\x1a_warning_unrestricted_rune\".\n\x10ShowrunesRequest\x12\x11\n\x04rune\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x07\n\x05_rune\"7\n\x11ShowrunesResponse\x12\"\n\x05runes\x18\x01 \x03(\x0b\x32\x13.cln.ShowrunesRunes\"\x9d\x02\n\x0eShowrunesRunes\x12\x0c\n\x04rune\x18\x01 \x01(\t\x12\x11\n\tunique_id\x18\x02 \x01(\t\x12\x35\n\x0crestrictions\x18\x03 \x03(\x0b\x32\x1f.cln.ShowrunesRunesRestrictions\x12\x1f\n\x17restrictions_as_english\x18\x04 \x01(\t\x12\x13\n\x06stored\x18\x05 \x01(\x08H\x00\x88\x01\x01\x12\x18\n\x0b\x62lacklisted\x18\x06 \x01(\x08H\x01\x88\x01\x01\x12\x16\n\tlast_used\x18\x07 \x01(\x01H\x02\x88\x01\x01\x12\x15\n\x08our_rune\x18\x08 \x01(\x08H\x03\x88\x01\x01\x42\t\n\x07_storedB\x0e\n\x0c_blacklistedB\x0c\n\n_last_usedB\x0b\n\t_our_rune\"p\n\x1aShowrunesRunesRestrictions\x12\x41\n\x0c\x61lternatives\x18\x01 \x03(\x0b\x32+.cln.ShowrunesRunesRestrictionsAlternatives\x12\x0f\n\x07\x65nglish\x18\x02 \x01(\t\"n\n&ShowrunesRunesRestrictionsAlternatives\x12\x11\n\tfieldname\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x12\x11\n\tcondition\x18\x03 \x01(\t\x12\x0f\n\x07\x65nglish\x18\x04 \x01(\t\"\x19\n\x17StreamBlockAddedRequest\"6\n\x16\x42lockAddedNotification\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\x0e\n\x06height\x18\x02 \x01(\r\" \n\x1eStreamChannelOpenFailedRequest\"3\n\x1d\x43hannelOpenFailedNotification\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\"\x1c\n\x1aStreamChannelOpenedRequest\"w\n\x19\x43hannelOpenedNotification\x12\n\n\x02id\x18\x01 \x01(\x0c\x12!\n\x0c\x66unding_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0c\x66unding_txid\x18\x03 \x01(\x0c\x12\x15\n\rchannel_ready\x18\x04 \x01(\x08\"\x16\n\x14StreamConnectRequest\"\xbe\x01\n\x17PeerConnectNotification\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x44\n\tdirection\x18\x02 \x01(\x0e\x32\x31.cln.PeerConnectNotification.PeerConnectDirection\x12(\n\x07\x61\x64\x64ress\x18\x03 \x01(\x0b\x32\x17.cln.PeerConnectAddress\"\'\n\x14PeerConnectDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\"\x8b\x02\n\x12PeerConnectAddress\x12\x41\n\titem_type\x18\x01 \x01(\x0e\x32..cln.PeerConnectAddress.PeerConnectAddressType\x12\x13\n\x06socket\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x11\n\x04port\x18\x04 \x01(\rH\x02\x88\x01\x01\"T\n\x16PeerConnectAddressType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\t\n\x07_socketB\n\n\x08_addressB\x07\n\x05_port\"\x18\n\x16StreamCustomMsgRequest\"9\n\x15\x43ustomMsgNotification\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x32\xcb?\n\x04Node\x12\x36\n\x07Getinfo\x12\x13.cln.GetinfoRequest\x1a\x14.cln.GetinfoResponse\"\x00\x12<\n\tListPeers\x12\x15.cln.ListpeersRequest\x1a\x16.cln.ListpeersResponse\"\x00\x12<\n\tListFunds\x12\x15.cln.ListfundsRequest\x1a\x16.cln.ListfundsResponse\"\x00\x12\x36\n\x07SendPay\x12\x13.cln.SendpayRequest\x1a\x14.cln.SendpayResponse\"\x00\x12\x45\n\x0cListChannels\x12\x18.cln.ListchannelsRequest\x1a\x19.cln.ListchannelsResponse\"\x00\x12<\n\tAddGossip\x12\x15.cln.AddgossipRequest\x1a\x16.cln.AddgossipResponse\"\x00\x12H\n\rAddPsbtOutput\x12\x19.cln.AddpsbtoutputRequest\x1a\x1a.cln.AddpsbtoutputResponse\"\x00\x12H\n\rAutoCleanOnce\x12\x19.cln.AutocleanonceRequest\x1a\x1a.cln.AutocleanonceResponse\"\x00\x12N\n\x0f\x41utoCleanStatus\x12\x1b.cln.AutocleanstatusRequest\x1a\x1c.cln.AutocleanstatusResponse\"\x00\x12\x45\n\x0c\x43heckMessage\x12\x18.cln.CheckmessageRequest\x1a\x19.cln.CheckmessageResponse\"\x00\x12\x30\n\x05\x43lose\x12\x11.cln.CloseRequest\x1a\x12.cln.CloseResponse\"\x00\x12:\n\x0b\x43onnectPeer\x12\x13.cln.ConnectRequest\x1a\x14.cln.ConnectResponse\"\x00\x12H\n\rCreateInvoice\x12\x19.cln.CreateinvoiceRequest\x1a\x1a.cln.CreateinvoiceResponse\"\x00\x12<\n\tDatastore\x12\x15.cln.DatastoreRequest\x1a\x16.cln.DatastoreResponse\"\x00\x12K\n\x0e\x44\x61tastoreUsage\x12\x1a.cln.DatastoreusageRequest\x1a\x1b.cln.DatastoreusageResponse\"\x00\x12\x42\n\x0b\x43reateOnion\x12\x17.cln.CreateonionRequest\x1a\x18.cln.CreateonionResponse\"\x00\x12\x45\n\x0c\x44\x65lDatastore\x12\x18.cln.DeldatastoreRequest\x1a\x19.cln.DeldatastoreResponse\"\x00\x12?\n\nDelInvoice\x12\x16.cln.DelinvoiceRequest\x1a\x17.cln.DelinvoiceResponse\"\x00\x12Q\n\x10\x44\x65vForgetChannel\x12\x1c.cln.DevforgetchannelRequest\x1a\x1d.cln.DevforgetchannelResponse\"\x00\x12Q\n\x10\x45mergencyRecover\x12\x1c.cln.EmergencyrecoverRequest\x1a\x1d.cln.EmergencyrecoverResponse\"\x00\x12\x36\n\x07Recover\x12\x13.cln.RecoverRequest\x1a\x14.cln.RecoverResponse\"\x00\x12K\n\x0eRecoverChannel\x12\x1a.cln.RecoverchannelRequest\x1a\x1b.cln.RecoverchannelResponse\"\x00\x12\x36\n\x07Invoice\x12\x13.cln.InvoiceRequest\x1a\x14.cln.InvoiceResponse\"\x00\x12Q\n\x14\x43reateInvoiceRequest\x12\x1a.cln.InvoicerequestRequest\x1a\x1b.cln.InvoicerequestResponse\"\x00\x12`\n\x15\x44isableInvoiceRequest\x12!.cln.DisableinvoicerequestRequest\x1a\".cln.DisableinvoicerequestResponse\"\x00\x12Z\n\x13ListInvoiceRequests\x12\x1f.cln.ListinvoicerequestsRequest\x1a .cln.ListinvoicerequestsResponse\"\x00\x12H\n\rListDatastore\x12\x19.cln.ListdatastoreRequest\x1a\x1a.cln.ListdatastoreResponse\"\x00\x12\x45\n\x0cListInvoices\x12\x18.cln.ListinvoicesRequest\x1a\x19.cln.ListinvoicesResponse\"\x00\x12<\n\tSendOnion\x12\x15.cln.SendonionRequest\x1a\x16.cln.SendonionResponse\"\x00\x12\x45\n\x0cListSendPays\x12\x18.cln.ListsendpaysRequest\x1a\x19.cln.ListsendpaysResponse\"\x00\x12Q\n\x10ListTransactions\x12\x1c.cln.ListtransactionsRequest\x1a\x1d.cln.ListtransactionsResponse\"\x00\x12?\n\nMakeSecret\x12\x16.cln.MakesecretRequest\x1a\x17.cln.MakesecretResponse\"\x00\x12*\n\x03Pay\x12\x0f.cln.PayRequest\x1a\x10.cln.PayResponse\"\x00\x12<\n\tListNodes\x12\x15.cln.ListnodesRequest\x1a\x16.cln.ListnodesResponse\"\x00\x12K\n\x0eWaitAnyInvoice\x12\x1a.cln.WaitanyinvoiceRequest\x1a\x1b.cln.WaitanyinvoiceResponse\"\x00\x12\x42\n\x0bWaitInvoice\x12\x17.cln.WaitinvoiceRequest\x1a\x18.cln.WaitinvoiceResponse\"\x00\x12\x42\n\x0bWaitSendPay\x12\x17.cln.WaitsendpayRequest\x1a\x18.cln.WaitsendpayResponse\"\x00\x12\x36\n\x07NewAddr\x12\x13.cln.NewaddrRequest\x1a\x14.cln.NewaddrResponse\"\x00\x12\x39\n\x08Withdraw\x12\x14.cln.WithdrawRequest\x1a\x15.cln.WithdrawResponse\"\x00\x12\x36\n\x07KeySend\x12\x13.cln.KeysendRequest\x1a\x14.cln.KeysendResponse\"\x00\x12\x39\n\x08\x46undPsbt\x12\x14.cln.FundpsbtRequest\x1a\x15.cln.FundpsbtResponse\"\x00\x12\x39\n\x08SendPsbt\x12\x14.cln.SendpsbtRequest\x1a\x15.cln.SendpsbtResponse\"\x00\x12\x39\n\x08SignPsbt\x12\x14.cln.SignpsbtRequest\x1a\x15.cln.SignpsbtResponse\"\x00\x12\x39\n\x08UtxoPsbt\x12\x14.cln.UtxopsbtRequest\x1a\x15.cln.UtxopsbtResponse\"\x00\x12<\n\tTxDiscard\x12\x15.cln.TxdiscardRequest\x1a\x16.cln.TxdiscardResponse\"\x00\x12<\n\tTxPrepare\x12\x15.cln.TxprepareRequest\x1a\x16.cln.TxprepareResponse\"\x00\x12\x33\n\x06TxSend\x12\x12.cln.TxsendRequest\x1a\x13.cln.TxsendResponse\"\x00\x12Q\n\x10ListPeerChannels\x12\x1c.cln.ListpeerchannelsRequest\x1a\x1d.cln.ListpeerchannelsResponse\"\x00\x12W\n\x12ListClosedChannels\x12\x1e.cln.ListclosedchannelsRequest\x1a\x1f.cln.ListclosedchannelsResponse\"\x00\x12<\n\tDecodePay\x12\x15.cln.DecodepayRequest\x1a\x16.cln.DecodepayResponse\"\x00\x12\x33\n\x06\x44\x65\x63ode\x12\x12.cln.DecodeRequest\x1a\x13.cln.DecodeResponse\"\x00\x12\x33\n\x06\x44\x65lPay\x12\x12.cln.DelpayRequest\x1a\x13.cln.DelpayResponse\"\x00\x12?\n\nDelForward\x12\x16.cln.DelforwardRequest\x1a\x17.cln.DelforwardResponse\"\x00\x12\x45\n\x0c\x44isableOffer\x12\x18.cln.DisableofferRequest\x1a\x19.cln.DisableofferResponse\"\x00\x12?\n\nDisconnect\x12\x16.cln.DisconnectRequest\x1a\x17.cln.DisconnectResponse\"\x00\x12\x39\n\x08\x46\x65\x65rates\x12\x14.cln.FeeratesRequest\x1a\x15.cln.FeeratesResponse\"\x00\x12\x45\n\x0c\x46\x65tchInvoice\x12\x18.cln.FetchinvoiceRequest\x1a\x19.cln.FetchinvoiceResponse\"\x00\x12W\n\x12\x46undChannel_Cancel\x12\x1e.cln.Fundchannel_cancelRequest\x1a\x1f.cln.Fundchannel_cancelResponse\"\x00\x12]\n\x14\x46undChannel_Complete\x12 .cln.Fundchannel_completeRequest\x1a!.cln.Fundchannel_completeResponse\"\x00\x12\x42\n\x0b\x46undChannel\x12\x17.cln.FundchannelRequest\x1a\x18.cln.FundchannelResponse\"\x00\x12T\n\x11\x46undChannel_Start\x12\x1d.cln.Fundchannel_startRequest\x1a\x1e.cln.Fundchannel_startResponse\"\x00\x12\x33\n\x06GetLog\x12\x12.cln.GetlogRequest\x1a\x13.cln.GetlogResponse\"\x00\x12\x45\n\x0c\x46underUpdate\x12\x18.cln.FunderupdateRequest\x1a\x19.cln.FunderupdateResponse\"\x00\x12\x39\n\x08GetRoute\x12\x14.cln.GetrouteRequest\x1a\x15.cln.GetrouteResponse\"\x00\x12\x45\n\x0cListForwards\x12\x18.cln.ListforwardsRequest\x1a\x19.cln.ListforwardsResponse\"\x00\x12?\n\nListOffers\x12\x16.cln.ListoffersRequest\x1a\x17.cln.ListoffersResponse\"\x00\x12\x39\n\x08ListPays\x12\x14.cln.ListpaysRequest\x1a\x15.cln.ListpaysResponse\"\x00\x12<\n\tListHtlcs\x12\x15.cln.ListhtlcsRequest\x1a\x16.cln.ListhtlcsResponse\"\x00\x12Q\n\x10MultiFundChannel\x12\x1c.cln.MultifundchannelRequest\x1a\x1d.cln.MultifundchannelResponse\"\x00\x12H\n\rMultiWithdraw\x12\x19.cln.MultiwithdrawRequest\x1a\x1a.cln.MultiwithdrawResponse\"\x00\x12\x30\n\x05Offer\x12\x11.cln.OfferRequest\x1a\x12.cln.OfferResponse\"\x00\x12T\n\x11OpenChannel_Abort\x12\x1d.cln.Openchannel_abortRequest\x1a\x1e.cln.Openchannel_abortResponse\"\x00\x12Q\n\x10OpenChannel_Bump\x12\x1c.cln.Openchannel_bumpRequest\x1a\x1d.cln.Openchannel_bumpResponse\"\x00\x12Q\n\x10OpenChannel_Init\x12\x1c.cln.Openchannel_initRequest\x1a\x1d.cln.Openchannel_initResponse\"\x00\x12W\n\x12OpenChannel_Signed\x12\x1e.cln.Openchannel_signedRequest\x1a\x1f.cln.Openchannel_signedResponse\"\x00\x12W\n\x12OpenChannel_Update\x12\x1e.cln.Openchannel_updateRequest\x1a\x1f.cln.Openchannel_updateResponse\"\x00\x12-\n\x04Ping\x12\x10.cln.PingRequest\x1a\x11.cln.PingResponse\"\x00\x12\x33\n\x06Plugin\x12\x12.cln.PluginRequest\x1a\x13.cln.PluginResponse\"\x00\x12H\n\rRenePayStatus\x12\x19.cln.RenepaystatusRequest\x1a\x1a.cln.RenepaystatusResponse\"\x00\x12\x36\n\x07RenePay\x12\x13.cln.RenepayRequest\x1a\x14.cln.RenepayResponse\"\x00\x12H\n\rReserveInputs\x12\x19.cln.ReserveinputsRequest\x1a\x1a.cln.ReserveinputsResponse\"\x00\x12H\n\rSendCustomMsg\x12\x19.cln.SendcustommsgRequest\x1a\x1a.cln.SendcustommsgResponse\"\x00\x12\x42\n\x0bSendInvoice\x12\x17.cln.SendinvoiceRequest\x1a\x18.cln.SendinvoiceResponse\"\x00\x12?\n\nSetChannel\x12\x16.cln.SetchannelRequest\x1a\x17.cln.SetchannelResponse\"\x00\x12<\n\tSetConfig\x12\x15.cln.SetconfigRequest\x1a\x16.cln.SetconfigResponse\"\x00\x12K\n\x0eSetPsbtVersion\x12\x1a.cln.SetpsbtversionRequest\x1a\x1b.cln.SetpsbtversionResponse\"\x00\x12\x42\n\x0bSignInvoice\x12\x17.cln.SigninvoiceRequest\x1a\x18.cln.SigninvoiceResponse\"\x00\x12\x42\n\x0bSignMessage\x12\x17.cln.SignmessageRequest\x1a\x18.cln.SignmessageResponse\"\x00\x12\x42\n\x0bSplice_Init\x12\x17.cln.Splice_initRequest\x1a\x18.cln.Splice_initResponse\"\x00\x12H\n\rSplice_Signed\x12\x19.cln.Splice_signedRequest\x1a\x1a.cln.Splice_signedResponse\"\x00\x12H\n\rSplice_Update\x12\x19.cln.Splice_updateRequest\x1a\x1a.cln.Splice_updateResponse\"\x00\x12N\n\x0fUnreserveInputs\x12\x1b.cln.UnreserveinputsRequest\x1a\x1c.cln.UnreserveinputsResponse\"\x00\x12H\n\rUpgradeWallet\x12\x19.cln.UpgradewalletRequest\x1a\x1a.cln.UpgradewalletResponse\"\x00\x12N\n\x0fWaitBlockHeight\x12\x1b.cln.WaitblockheightRequest\x1a\x1c.cln.WaitblockheightResponse\"\x00\x12-\n\x04Wait\x12\x10.cln.WaitRequest\x1a\x11.cln.WaitResponse\"\x00\x12\x42\n\x0bListConfigs\x12\x17.cln.ListconfigsRequest\x1a\x18.cln.ListconfigsResponse\"\x00\x12-\n\x04Stop\x12\x10.cln.StopRequest\x1a\x11.cln.StopResponse\"\x00\x12-\n\x04Help\x12\x10.cln.HelpRequest\x1a\x11.cln.HelpResponse\"\x00\x12T\n\x11PreApproveKeysend\x12\x1d.cln.PreapprovekeysendRequest\x1a\x1e.cln.PreapprovekeysendResponse\"\x00\x12T\n\x11PreApproveInvoice\x12\x1d.cln.PreapproveinvoiceRequest\x1a\x1e.cln.PreapproveinvoiceResponse\"\x00\x12\x45\n\x0cStaticBackup\x12\x18.cln.StaticbackupRequest\x1a\x19.cln.StaticbackupResponse\"\x00\x12N\n\x0f\x42kprChannelsApy\x12\x1b.cln.BkprchannelsapyRequest\x1a\x1c.cln.BkprchannelsapyResponse\"\x00\x12T\n\x11\x42kprDumpIncomeCsv\x12\x1d.cln.BkprdumpincomecsvRequest\x1a\x1e.cln.BkprdumpincomecsvResponse\"\x00\x12\x42\n\x0b\x42kprInspect\x12\x17.cln.BkprinspectRequest\x1a\x18.cln.BkprinspectResponse\"\x00\x12`\n\x15\x42kprListAccountEvents\x12!.cln.BkprlistaccounteventsRequest\x1a\".cln.BkprlistaccounteventsResponse\"\x00\x12Q\n\x10\x42kprListBalances\x12\x1c.cln.BkprlistbalancesRequest\x1a\x1d.cln.BkprlistbalancesResponse\"\x00\x12K\n\x0e\x42kprListIncome\x12\x1a.cln.BkprlistincomeRequest\x1a\x1b.cln.BkprlistincomeResponse\"\x00\x12H\n\rBlacklistRune\x12\x19.cln.BlacklistruneRequest\x1a\x1a.cln.BlacklistruneResponse\"\x00\x12<\n\tCheckRune\x12\x15.cln.CheckruneRequest\x1a\x16.cln.CheckruneResponse\"\x00\x12?\n\nCreateRune\x12\x16.cln.CreateruneRequest\x1a\x17.cln.CreateruneResponse\"\x00\x12<\n\tShowRunes\x12\x15.cln.ShowrunesRequest\x1a\x16.cln.ShowrunesResponse\"\x00\x12T\n\x13SubscribeBlockAdded\x12\x1c.cln.StreamBlockAddedRequest\x1a\x1b.cln.BlockAddedNotification\"\x00\x30\x01\x12i\n\x1aSubscribeChannelOpenFailed\x12#.cln.StreamChannelOpenFailedRequest\x1a\".cln.ChannelOpenFailedNotification\"\x00\x30\x01\x12]\n\x16SubscribeChannelOpened\x12\x1f.cln.StreamChannelOpenedRequest\x1a\x1e.cln.ChannelOpenedNotification\"\x00\x30\x01\x12O\n\x10SubscribeConnect\x12\x19.cln.StreamConnectRequest\x1a\x1c.cln.PeerConnectNotification\"\x00\x30\x01\x12Q\n\x12SubscribeCustomMsg\x12\x1b.cln.StreamCustomMsgRequest\x1a\x1a.cln.CustomMsgNotification\"\x00\x30\x01\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nnode.proto\x12\x03\x63ln\x1a\x10primitives.proto\"\x10\n\x0eGetinfoRequest\"\xc1\x04\n\x0fGetinfoResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\x05\x61lias\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\r\n\x05\x63olor\x18\x03 \x01(\x0c\x12\x11\n\tnum_peers\x18\x04 \x01(\r\x12\x1c\n\x14num_pending_channels\x18\x05 \x01(\r\x12\x1b\n\x13num_active_channels\x18\x06 \x01(\r\x12\x1d\n\x15num_inactive_channels\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\rlightning_dir\x18\t \x01(\t\x12\x33\n\x0cour_features\x18\n \x01(\x0b\x32\x18.cln.GetinfoOur_featuresH\x01\x88\x01\x01\x12\x13\n\x0b\x62lockheight\x18\x0b \x01(\r\x12\x0f\n\x07network\x18\x0c \x01(\t\x12(\n\x13\x66\x65\x65s_collected_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x07\x61\x64\x64ress\x18\x0e \x03(\x0b\x32\x13.cln.GetinfoAddress\x12$\n\x07\x62inding\x18\x0f \x03(\x0b\x32\x13.cln.GetinfoBinding\x12\"\n\x15warning_bitcoind_sync\x18\x10 \x01(\tH\x02\x88\x01\x01\x12$\n\x17warning_lightningd_sync\x18\x11 \x01(\tH\x03\x88\x01\x01\x42\x08\n\x06_aliasB\x0f\n\r_our_featuresB\x18\n\x16_warning_bitcoind_syncB\x1a\n\x18_warning_lightningd_sync\"S\n\x13GetinfoOur_features\x12\x0c\n\x04init\x18\x01 \x01(\x0c\x12\x0c\n\x04node\x18\x02 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\x0c\x12\x0f\n\x07invoice\x18\x04 \x01(\x0c\"\xc4\x01\n\x0eGetinfoAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoAddress.GetinfoAddressType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\"G\n\x12GetinfoAddressType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_address\"\xac\x02\n\x0eGetinfoBinding\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoBinding.GetinfoBindingType\x12\x14\n\x07\x61\x64\x64ress\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06socket\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07subtype\x18\x05 \x01(\tH\x03\x88\x01\x01\"_\n\x12GetinfoBindingType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x12\r\n\tWEBSOCKET\x10\x05\x42\n\n\x08_addressB\x07\n\x05_portB\t\n\x07_socketB\n\n\x08_subtype\"\xb5\x01\n\x10ListpeersRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x38\n\x05level\x18\x02 \x01(\x0e\x32$.cln.ListpeersRequest.ListpeersLevelH\x01\x88\x01\x01\"E\n\x0eListpeersLevel\x12\x06\n\x02IO\x10\x00\x12\t\n\x05\x44\x45\x42UG\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\x0b\n\x07UNUSUAL\x10\x03\x12\t\n\x05TRACE\x10\x04\x42\x05\n\x03_idB\x08\n\x06_level\"7\n\x11ListpeersResponse\x12\"\n\x05peers\x18\x01 \x03(\x0b\x32\x13.cln.ListpeersPeers\"\xdf\x01\n\x0eListpeersPeers\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x11\n\tconnected\x18\x02 \x01(\x08\x12#\n\x03log\x18\x03 \x03(\x0b\x32\x16.cln.ListpeersPeersLog\x12\x0f\n\x07netaddr\x18\x05 \x03(\t\x12\x15\n\x08\x66\x65\x61tures\x18\x06 \x01(\x0cH\x00\x88\x01\x01\x12\x18\n\x0bremote_addr\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x19\n\x0cnum_channels\x18\x08 \x01(\rH\x02\x88\x01\x01\x42\x0b\n\t_featuresB\x0e\n\x0c_remote_addrB\x0f\n\r_num_channels\"\x88\x03\n\x11ListpeersPeersLog\x12?\n\titem_type\x18\x01 \x01(\x0e\x32,.cln.ListpeersPeersLog.ListpeersPeersLogType\x12\x18\n\x0bnum_skipped\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04time\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06source\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x10\n\x03log\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x07node_id\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x11\n\x04\x64\x61ta\x18\x07 \x01(\x0cH\x05\x88\x01\x01\"t\n\x15ListpeersPeersLogType\x12\x0b\n\x07SKIPPED\x10\x00\x12\n\n\x06\x42ROKEN\x10\x01\x12\x0b\n\x07UNUSUAL\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\t\n\x05\x44\x45\x42UG\x10\x04\x12\t\n\x05IO_IN\x10\x05\x12\n\n\x06IO_OUT\x10\x06\x12\t\n\x05TRACE\x10\x07\x42\x0e\n\x0c_num_skippedB\x07\n\x05_timeB\t\n\x07_sourceB\x06\n\x04_logB\n\n\x08_node_idB\x07\n\x05_data\"0\n\x10ListfundsRequest\x12\x12\n\x05spent\x18\x01 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_spent\"e\n\x11ListfundsResponse\x12&\n\x07outputs\x18\x01 \x03(\x0b\x32\x15.cln.ListfundsOutputs\x12(\n\x08\x63hannels\x18\x02 \x03(\x0b\x32\x16.cln.ListfundsChannels\"\xb9\x03\n\x10ListfundsOutputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06output\x18\x02 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0cscriptpubkey\x18\x04 \x01(\x0c\x12\x14\n\x07\x61\x64\x64ress\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0credeemscript\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12<\n\x06status\x18\x07 \x01(\x0e\x32,.cln.ListfundsOutputs.ListfundsOutputsStatus\x12\x18\n\x0b\x62lockheight\x18\x08 \x01(\rH\x02\x88\x01\x01\x12\x10\n\x08reserved\x18\t \x01(\x08\x12\x1e\n\x11reserved_to_block\x18\n \x01(\rH\x03\x88\x01\x01\"Q\n\x16ListfundsOutputsStatus\x12\x0f\n\x0bUNCONFIRMED\x10\x00\x12\r\n\tCONFIRMED\x10\x01\x12\t\n\x05SPENT\x10\x02\x12\x0c\n\x08IMMATURE\x10\x03\x42\n\n\x08_addressB\x0f\n\r_redeemscriptB\x0e\n\x0c_blockheightB\x14\n\x12_reserved_to_block\"\xab\x02\n\x11ListfundsChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12$\n\x0four_amount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0c\x66unding_txid\x18\x04 \x01(\x0c\x12\x16\n\x0e\x66unding_output\x18\x05 \x01(\r\x12\x11\n\tconnected\x18\x06 \x01(\x08\x12 \n\x05state\x18\x07 \x01(\x0e\x32\x11.cln.ChannelState\x12\x1d\n\x10short_channel_id\x18\x08 \x01(\tH\x00\x88\x01\x01\x12\x17\n\nchannel_id\x18\t \x01(\x0cH\x01\x88\x01\x01\x42\x13\n\x11_short_channel_idB\r\n\x0b_channel_id\"\xbb\x03\n\x0eSendpayRequest\x12 \n\x05route\x18\x01 \x03(\x0b\x32\x11.cln.SendpayRoute\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x1b\n\x0epayment_secret\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x12\x13\n\x06partid\x18\x07 \x01(\x04H\x03\x88\x01\x01\x12\x14\n\x07groupid\x18\t \x01(\x04H\x04\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\x0b \x01(\x0cH\x06\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\x0c \x01(\x0cH\x07\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\r \x01(\tH\x08\x88\x01\x01\x42\x08\n\x06_labelB\t\n\x07_bolt11B\x11\n\x0f_payment_secretB\t\n\x07_partidB\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x10\n\x0e_localinvreqidB\x13\n\x11_payment_metadataB\x0e\n\x0c_description\"\xad\x05\n\x0fSendpayResponse\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x32\n\x06status\x18\x04 \x01(\x0e\x32\".cln.SendpayResponse.SendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x14\n\x07message\x18\x0e \x01(\tH\x08\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0f \x01(\x04H\t\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\n\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x0b\x88\x01\x01\"*\n\rSendpayStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\n\n\x08_messageB\x0f\n\r_completed_atB\x10\n\x0e_created_indexB\x10\n\x0e_updated_index\"\\\n\x0cSendpayRoute\x12\n\n\x02id\x18\x02 \x01(\x0c\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r\x12\x0f\n\x07\x63hannel\x18\x04 \x01(\t\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\"\x93\x01\n\x13ListchannelsRequest\x12\x1d\n\x10short_channel_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06source\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x42\x13\n\x11_short_channel_idB\t\n\x07_sourceB\x0e\n\x0c_destination\"C\n\x14ListchannelsResponse\x12+\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x19.cln.ListchannelsChannels\"\xb3\x03\n\x14ListchannelsChannels\x12\x0e\n\x06source\x18\x01 \x01(\x0c\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\x0c\x12\x18\n\x10short_channel_id\x18\x03 \x01(\t\x12\x0e\n\x06public\x18\x04 \x01(\x08\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x15\n\rmessage_flags\x18\x06 \x01(\r\x12\x15\n\rchannel_flags\x18\x07 \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x08 \x01(\x08\x12\x13\n\x0blast_update\x18\t \x01(\r\x12\x1d\n\x15\x62\x61se_fee_millisatoshi\x18\n \x01(\r\x12\x19\n\x11\x66\x65\x65_per_millionth\x18\x0b \x01(\r\x12\r\n\x05\x64\x65lay\x18\x0c \x01(\r\x12&\n\x11htlc_minimum_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x11htlc_maximum_msat\x18\x0e \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x10\n\x08\x66\x65\x61tures\x18\x0f \x01(\x0c\x12\x11\n\tdirection\x18\x10 \x01(\rB\x14\n\x12_htlc_maximum_msat\"#\n\x10\x41\x64\x64gossipRequest\x12\x0f\n\x07message\x18\x01 \x01(\x0c\"\x13\n\x11\x41\x64\x64gossipResponse\"\xac\x01\n\x14\x41\x64\x64psbtoutputRequest\x12\x1c\n\x07satoshi\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x15\n\x08locktime\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x18\n\x0binitialpsbt\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\x0b\n\t_locktimeB\x0e\n\x0c_initialpsbtB\x0e\n\x0c_destination\"U\n\x15\x41\x64\x64psbtoutputResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x1e\n\x16\x65stimated_added_weight\x18\x02 \x01(\r\x12\x0e\n\x06outnum\x18\x03 \x01(\r\"O\n\x14\x41utocleanonceRequest\x12*\n\tsubsystem\x18\x01 \x01(\x0e\x32\x17.cln.AutocleanSubsystem\x12\x0b\n\x03\x61ge\x18\x02 \x01(\x04\"G\n\x15\x41utocleanonceResponse\x12.\n\tautoclean\x18\x01 \x01(\x0b\x32\x1b.cln.AutocleanonceAutoclean\"\xb1\x04\n\x16\x41utocleanonceAutoclean\x12L\n\x11succeededforwards\x18\x01 \x01(\x0b\x32,.cln.AutocleanonceAutocleanSucceededforwardsH\x00\x88\x01\x01\x12\x46\n\x0e\x66\x61iledforwards\x18\x02 \x01(\x0b\x32).cln.AutocleanonceAutocleanFailedforwardsH\x01\x88\x01\x01\x12\x44\n\rsucceededpays\x18\x03 \x01(\x0b\x32(.cln.AutocleanonceAutocleanSucceededpaysH\x02\x88\x01\x01\x12>\n\nfailedpays\x18\x04 \x01(\x0b\x32%.cln.AutocleanonceAutocleanFailedpaysH\x03\x88\x01\x01\x12\x42\n\x0cpaidinvoices\x18\x05 \x01(\x0b\x32\'.cln.AutocleanonceAutocleanPaidinvoicesH\x04\x88\x01\x01\x12H\n\x0f\x65xpiredinvoices\x18\x06 \x01(\x0b\x32*.cln.AutocleanonceAutocleanExpiredinvoicesH\x05\x88\x01\x01\x42\x14\n\x12_succeededforwardsB\x11\n\x0f_failedforwardsB\x10\n\x0e_succeededpaysB\r\n\x0b_failedpaysB\x0f\n\r_paidinvoicesB\x12\n\x10_expiredinvoices\"M\n\'AutocleanonceAutocleanSucceededforwards\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"J\n$AutocleanonceAutocleanFailedforwards\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"I\n#AutocleanonceAutocleanSucceededpays\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"F\n AutocleanonceAutocleanFailedpays\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"H\n\"AutocleanonceAutocleanPaidinvoices\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"K\n%AutocleanonceAutocleanExpiredinvoices\x12\x0f\n\x07\x63leaned\x18\x01 \x01(\x04\x12\x11\n\tuncleaned\x18\x02 \x01(\x04\"W\n\x16\x41utocleanstatusRequest\x12/\n\tsubsystem\x18\x01 \x01(\x0e\x32\x17.cln.AutocleanSubsystemH\x00\x88\x01\x01\x42\x0c\n\n_subsystem\"K\n\x17\x41utocleanstatusResponse\x12\x30\n\tautoclean\x18\x01 \x01(\x0b\x32\x1d.cln.AutocleanstatusAutoclean\"\xbf\x04\n\x18\x41utocleanstatusAutoclean\x12N\n\x11succeededforwards\x18\x01 \x01(\x0b\x32..cln.AutocleanstatusAutocleanSucceededforwardsH\x00\x88\x01\x01\x12H\n\x0e\x66\x61iledforwards\x18\x02 \x01(\x0b\x32+.cln.AutocleanstatusAutocleanFailedforwardsH\x01\x88\x01\x01\x12\x46\n\rsucceededpays\x18\x03 \x01(\x0b\x32*.cln.AutocleanstatusAutocleanSucceededpaysH\x02\x88\x01\x01\x12@\n\nfailedpays\x18\x04 \x01(\x0b\x32\'.cln.AutocleanstatusAutocleanFailedpaysH\x03\x88\x01\x01\x12\x44\n\x0cpaidinvoices\x18\x05 \x01(\x0b\x32).cln.AutocleanstatusAutocleanPaidinvoicesH\x04\x88\x01\x01\x12J\n\x0f\x65xpiredinvoices\x18\x06 \x01(\x0b\x32,.cln.AutocleanstatusAutocleanExpiredinvoicesH\x05\x88\x01\x01\x42\x14\n\x12_succeededforwardsB\x11\n\x0f_failedforwardsB\x10\n\x0e_succeededpaysB\r\n\x0b_failedpaysB\x0f\n\r_paidinvoicesB\x12\n\x10_expiredinvoices\"g\n)AutocleanstatusAutocleanSucceededforwards\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"d\n&AutocleanstatusAutocleanFailedforwards\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"c\n%AutocleanstatusAutocleanSucceededpays\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"`\n\"AutocleanstatusAutocleanFailedpays\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"b\n$AutocleanstatusAutocleanPaidinvoices\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"e\n\'AutocleanstatusAutocleanExpiredinvoices\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x63leaned\x18\x02 \x01(\x04\x12\x10\n\x03\x61ge\x18\x03 \x01(\x04H\x00\x88\x01\x01\x42\x06\n\x04_age\"U\n\x13\x43heckmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\r\n\x05zbase\x18\x02 \x01(\t\x12\x13\n\x06pubkey\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x42\t\n\x07_pubkey\"8\n\x14\x43heckmessageResponse\x12\x10\n\x08verified\x18\x01 \x01(\x08\x12\x0e\n\x06pubkey\x18\x02 \x01(\x0c\"\xcb\x02\n\x0c\x43loseRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1e\n\x11unilateraltimeout\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\tH\x01\x88\x01\x01\x12!\n\x14\x66\x65\x65_negotiation_step\x18\x04 \x01(\tH\x02\x88\x01\x01\x12)\n\rwrong_funding\x18\x05 \x01(\x0b\x32\r.cln.OutpointH\x03\x88\x01\x01\x12\x1f\n\x12\x66orce_lease_closed\x18\x06 \x01(\x08H\x04\x88\x01\x01\x12\x1e\n\x08\x66\x65\x65range\x18\x07 \x03(\x0b\x32\x0c.cln.FeerateB\x14\n\x12_unilateraltimeoutB\x0e\n\x0c_destinationB\x17\n\x15_fee_negotiation_stepB\x10\n\x0e_wrong_fundingB\x15\n\x13_force_lease_closed\"\xab\x01\n\rCloseResponse\x12/\n\titem_type\x18\x01 \x01(\x0e\x32\x1c.cln.CloseResponse.CloseType\x12\x0f\n\x02tx\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x11\n\x04txid\x18\x03 \x01(\x0cH\x01\x88\x01\x01\"5\n\tCloseType\x12\n\n\x06MUTUAL\x10\x00\x12\x0e\n\nUNILATERAL\x10\x01\x12\x0c\n\x08UNOPENED\x10\x02\x42\x05\n\x03_txB\x07\n\x05_txid\"T\n\x0e\x43onnectRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\x04host\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_hostB\x07\n\x05_port\"\xb4\x01\n\x0f\x43onnectResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0c\x12\x38\n\tdirection\x18\x03 \x01(\x0e\x32%.cln.ConnectResponse.ConnectDirection\x12$\n\x07\x61\x64\x64ress\x18\x04 \x01(\x0b\x32\x13.cln.ConnectAddress\"#\n\x10\x43onnectDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\"\xfb\x01\n\x0e\x43onnectAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.ConnectAddress.ConnectAddressType\x12\x13\n\x06socket\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x11\n\x04port\x18\x04 \x01(\rH\x02\x88\x01\x01\"P\n\x12\x43onnectAddressType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\t\n\x07_socketB\n\n\x08_addressB\x07\n\x05_port\"J\n\x14\x43reateinvoiceRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x10\n\x08preimage\x18\x03 \x01(\x0c\"\xfe\x05\n\x15\x43reateinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x04 \x01(\x0c\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12>\n\x06status\x18\x06 \x01(\x0e\x32..cln.CreateinvoiceResponse.CreateinvoiceStatus\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x16\n\tpay_index\x18\t \x01(\x04H\x03\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x06\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0f \x01(\tH\x08\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\t\x88\x01\x01\x12;\n\rpaid_outpoint\x18\x11 \x01(\x0b\x32\x1f.cln.CreateinvoicePaid_outpointH\n\x88\x01\x01\"8\n\x13\x43reateinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimageB\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_noteB\x10\n\x0e_created_indexB\x10\n\x0e_paid_outpoint\":\n\x1a\x43reateinvoicePaid_outpoint\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\"\xb4\x02\n\x10\x44\x61tastoreRequest\x12\x10\n\x03hex\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x36\n\x04mode\x18\x03 \x01(\x0e\x32#.cln.DatastoreRequest.DatastoreModeH\x01\x88\x01\x01\x12\x17\n\ngeneration\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x13\n\x06string\x18\x06 \x01(\tH\x03\x88\x01\x01\"p\n\rDatastoreMode\x12\x0f\n\x0bMUST_CREATE\x10\x00\x12\x10\n\x0cMUST_REPLACE\x10\x01\x12\x15\n\x11\x43REATE_OR_REPLACE\x10\x02\x12\x0f\n\x0bMUST_APPEND\x10\x03\x12\x14\n\x10\x43REATE_OR_APPEND\x10\x04\x42\x06\n\x04_hexB\x07\n\x05_modeB\r\n\x0b_generationB\t\n\x07_string\"\x82\x01\n\x11\x44\x61tastoreResponse\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x0b\n\x03key\x18\x05 \x03(\tB\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"$\n\x15\x44\x61tastoreusageRequest\x12\x0b\n\x03key\x18\x01 \x03(\t\"S\n\x16\x44\x61tastoreusageResponse\x12\x39\n\x0e\x64\x61tastoreusage\x18\x01 \x01(\x0b\x32!.cln.DatastoreusageDatastoreusage\"@\n\x1c\x44\x61tastoreusageDatastoreusage\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x13\n\x0btotal_bytes\x18\x02 \x01(\x04\"\x9d\x01\n\x12\x43reateonionRequest\x12\"\n\x04hops\x18\x01 \x03(\x0b\x32\x14.cln.CreateonionHops\x12\x11\n\tassocdata\x18\x02 \x01(\x0c\x12\x18\n\x0bsession_key\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x17\n\nonion_size\x18\x04 \x01(\rH\x01\x88\x01\x01\x42\x0e\n\x0c_session_keyB\r\n\x0b_onion_size\"<\n\x13\x43reateonionResponse\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12\x16\n\x0eshared_secrets\x18\x02 \x03(\x0c\"2\n\x0f\x43reateonionHops\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"J\n\x13\x44\x65ldatastoreRequest\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x0b\n\x03key\x18\x03 \x03(\tB\r\n\x0b_generation\"\x85\x01\n\x14\x44\x65ldatastoreResponse\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x0b\n\x03key\x18\x05 \x03(\tB\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"\xb6\x01\n\x11\x44\x65linvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t\x12\x37\n\x06status\x18\x02 \x01(\x0e\x32\'.cln.DelinvoiceRequest.DelinvoiceStatus\x12\x15\n\x08\x64\x65sconly\x18\x03 \x01(\x08H\x00\x88\x01\x01\"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\x0b\n\t_desconly\"\xe6\x05\n\x12\x44\x65linvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x38\n\x06status\x18\x07 \x01(\x0e\x32(.cln.DelinvoiceResponse.DelinvoiceStatus\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0b \x01(\tH\x05\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x0c \x01(\x04H\x06\x88\x01\x01\x12\x1a\n\rupdated_index\x18\r \x01(\x04H\x07\x88\x01\x01\x12\x16\n\tpay_index\x18\x0e \x01(\x04H\x08\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\t\x88\x01\x01\x12\x14\n\x07paid_at\x18\x10 \x01(\x04H\n\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x11 \x01(\x0cH\x0b\x88\x01\x01\"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_noteB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimage\"\x9f\x01\n\x17\x44\x65vforgetchannelRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x17\n\nchannel_id\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x12\n\x05\x66orce\x18\x04 \x01(\x08H\x02\x88\x01\x01\x42\x13\n\x11_short_channel_idB\r\n\x0b_channel_idB\x08\n\x06_force\"Y\n\x18\x44\x65vforgetchannelResponse\x12\x0e\n\x06\x66orced\x18\x01 \x01(\x08\x12\x17\n\x0f\x66unding_unspent\x18\x02 \x01(\x08\x12\x14\n\x0c\x66unding_txid\x18\x03 \x01(\x0c\"\x19\n\x17\x45mergencyrecoverRequest\")\n\x18\x45mergencyrecoverResponse\x12\r\n\x05stubs\x18\x01 \x03(\x0c\"#\n\x0eRecoverRequest\x12\x11\n\thsmsecret\x18\x01 \x01(\t\"\x88\x01\n\x0fRecoverResponse\x12\x37\n\x06result\x18\x01 \x01(\x0e\x32\".cln.RecoverResponse.RecoverResultH\x00\x88\x01\x01\"1\n\rRecoverResult\x12 \n\x1cRECOVERY_RESTART_IN_PROGRESS\x10\x00\x42\t\n\x07_result\"$\n\x15RecoverchannelRequest\x12\x0b\n\x03scb\x18\x01 \x03(\x0c\"\'\n\x16RecoverchannelResponse\x12\r\n\x05stubs\x18\x01 \x03(\t\"\x99\x02\n\x0eInvoiceRequest\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\r\n\x05label\x18\x03 \x01(\t\x12\x11\n\tfallbacks\x18\x04 \x03(\t\x12\x15\n\x08preimage\x18\x05 \x01(\x0cH\x00\x88\x01\x01\x12\x11\n\x04\x63ltv\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06\x65xpiry\x18\x07 \x01(\x04H\x02\x88\x01\x01\x12\x1d\n\x15\x65xposeprivatechannels\x18\x08 \x03(\t\x12\x19\n\x0c\x64\x65schashonly\x18\t \x01(\x08H\x03\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x10.cln.AmountOrAnyB\x0b\n\t_preimageB\x07\n\x05_cltvB\t\n\x07_expiryB\x0f\n\r_deschashonly\"\x95\x03\n\x0fInvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x16\n\x0epayment_secret\x18\x03 \x01(\x0c\x12\x12\n\nexpires_at\x18\x04 \x01(\x04\x12\x1d\n\x10warning_capacity\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x1c\n\x0fwarning_offline\x18\x06 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x10warning_deadends\x18\x07 \x01(\tH\x02\x88\x01\x01\x12#\n\x16warning_private_unused\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x18\n\x0bwarning_mpp\x18\t \x01(\tH\x04\x88\x01\x01\x12\x1a\n\rcreated_index\x18\n \x01(\x04H\x05\x88\x01\x01\x42\x13\n\x11_warning_capacityB\x12\n\x10_warning_offlineB\x13\n\x11_warning_deadendsB\x19\n\x17_warning_private_unusedB\x0e\n\x0c_warning_mppB\x10\n\x0e_created_index\"\xe1\x01\n\x15InvoicerequestRequest\x12\x1b\n\x06\x61mount\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x13\n\x06issuer\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x12\n\x05label\x18\x04 \x01(\tH\x01\x88\x01\x01\x12\x1c\n\x0f\x61\x62solute_expiry\x18\x05 \x01(\x04H\x02\x88\x01\x01\x12\x17\n\nsingle_use\x18\x06 \x01(\x08H\x03\x88\x01\x01\x42\t\n\x07_issuerB\x08\n\x06_labelB\x12\n\x10_absolute_expiryB\r\n\x0b_single_use\"\x8b\x01\n\x16InvoicerequestResponse\x12\x11\n\tinvreq_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"1\n\x1c\x44isableinvoicerequestRequest\x12\x11\n\tinvreq_id\x18\x01 \x01(\t\"\x92\x01\n\x1d\x44isableinvoicerequestResponse\x12\x11\n\tinvreq_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"l\n\x1aListinvoicerequestsRequest\x12\x16\n\tinvreq_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x61\x63tive_only\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\x0c\n\n_invreq_idB\x0e\n\x0c_active_only\"_\n\x1bListinvoicerequestsResponse\x12@\n\x0finvoicerequests\x18\x01 \x03(\x0b\x32\'.cln.ListinvoicerequestsInvoicerequests\"\x97\x01\n\"ListinvoicerequestsInvoicerequests\x12\x11\n\tinvreq_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"#\n\x14ListdatastoreRequest\x12\x0b\n\x03key\x18\x02 \x03(\t\"G\n\x15ListdatastoreResponse\x12.\n\tdatastore\x18\x01 \x03(\x0b\x32\x1b.cln.ListdatastoreDatastore\"\x87\x01\n\x16ListdatastoreDatastore\x12\x0b\n\x03key\x18\x01 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"\xde\x02\n\x13ListinvoicesRequest\x12\x12\n\x05label\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tinvstring\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08offer_id\x18\x04 \x01(\tH\x03\x88\x01\x01\x12>\n\x05index\x18\x05 \x01(\x0e\x32*.cln.ListinvoicesRequest.ListinvoicesIndexH\x04\x88\x01\x01\x12\x12\n\x05start\x18\x06 \x01(\x04H\x05\x88\x01\x01\x12\x12\n\x05limit\x18\x07 \x01(\rH\x06\x88\x01\x01\"-\n\x11ListinvoicesIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\x08\n\x06_labelB\x0c\n\n_invstringB\x0f\n\r_payment_hashB\x0b\n\t_offer_idB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListinvoicesResponse\x12+\n\x08invoices\x18\x01 \x03(\x0b\x32\x19.cln.ListinvoicesInvoices\"\xd4\x06\n\x14ListinvoicesInvoices\x12\r\n\x05label\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListinvoicesInvoices.ListinvoicesInvoicesStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x16\n\tpay_index\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x14\n\x07paid_at\x18\r \x01(\x04H\x07\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0e \x01(\x0cH\x08\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0f \x01(\tH\t\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\n\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x0b\x88\x01\x01\x12\x42\n\rpaid_outpoint\x18\x12 \x01(\x0b\x32&.cln.ListinvoicesInvoicesPaid_outpointH\x0c\x88\x01\x01\"?\n\x1aListinvoicesInvoicesStatus\x12\n\n\x06UNPAID\x10\x00\x12\x08\n\x04PAID\x10\x01\x12\x0b\n\x07\x45XPIRED\x10\x02\x42\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x11\n\x0f_local_offer_idB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimageB\x14\n\x12_invreq_payer_noteB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x10\n\x0e_paid_outpoint\"A\n!ListinvoicesInvoicesPaid_outpoint\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\"\xb4\x03\n\x10SendonionRequest\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12*\n\tfirst_hop\x18\x02 \x01(\x0b\x32\x17.cln.SendonionFirst_hop\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\x05label\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x16\n\x0eshared_secrets\x18\x05 \x03(\x0c\x12\x13\n\x06partid\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\t \x01(\x0cH\x03\x88\x01\x01\x12\x14\n\x07groupid\x18\x0b \x01(\x04H\x04\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\r \x01(\x0cH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0e \x01(\tH\x07\x88\x01\x01\x42\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\x0e\n\x0c_destinationB\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x10\n\x0e_localinvreqidB\x0e\n\x0c_description\"\xe7\x04\n\x11SendonionResponse\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x36\n\x06status\x18\x03 \x01(\x0e\x32&.cln.SendonionResponse.SendonionStatus\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x12\n\ncreated_at\x18\x06 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\n \x01(\tH\x04\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0b \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x07message\x18\x0c \x01(\tH\x06\x88\x01\x01\x12\x13\n\x06partid\x18\r \x01(\x04H\x07\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x0e \x01(\x04H\x08\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0f \x01(\x04H\t\x88\x01\x01\",\n\x0fSendonionStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\n\n\x08_messageB\t\n\x07_partidB\x10\n\x0e_created_indexB\x10\n\x0e_updated_index\"Q\n\x12SendonionFirst_hop\x12\n\n\x02id\x18\x01 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r\"\xa0\x03\n\x13ListsendpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12@\n\x06status\x18\x03 \x01(\x0e\x32+.cln.ListsendpaysRequest.ListsendpaysStatusH\x02\x88\x01\x01\x12>\n\x05index\x18\x04 \x01(\x0e\x32*.cln.ListsendpaysRequest.ListsendpaysIndexH\x03\x88\x01\x01\x12\x12\n\x05start\x18\x05 \x01(\x04H\x04\x88\x01\x01\x12\x12\n\x05limit\x18\x06 \x01(\rH\x05\x88\x01\x01\";\n\x12ListsendpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\"-\n\x11ListsendpaysIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_statusB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListsendpaysResponse\x12+\n\x08payments\x18\x01 \x03(\x0b\x32\x19.cln.ListsendpaysPayments\"\xfc\x05\n\x14ListsendpaysPayments\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0f\n\x07groupid\x18\x02 \x01(\x04\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListsendpaysPayments.ListsendpaysPaymentsStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\n \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0b \x01(\tH\x04\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x05\x88\x01\x01\x12\x17\n\nerroronion\x18\r \x01(\x0cH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0e \x01(\tH\x07\x88\x01\x01\x12\x13\n\x06partid\x18\x0f \x01(\x04H\x08\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\t\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\n\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x12 \x01(\x04H\x0b\x88\x01\x01\"C\n\x1aListsendpaysPaymentsStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\r\n\x0b_erroronionB\x0e\n\x0c_descriptionB\t\n\x07_partidB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0f\n\r_completed_at\"\x19\n\x17ListtransactionsRequest\"S\n\x18ListtransactionsResponse\x12\x37\n\x0ctransactions\x18\x01 \x03(\x0b\x32!.cln.ListtransactionsTransactions\"\xf8\x01\n\x1cListtransactionsTransactions\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\r\n\x05rawtx\x18\x02 \x01(\x0c\x12\x13\n\x0b\x62lockheight\x18\x03 \x01(\r\x12\x0f\n\x07txindex\x18\x04 \x01(\r\x12\x10\n\x08locktime\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x37\n\x06inputs\x18\t \x03(\x0b\x32\'.cln.ListtransactionsTransactionsInputs\x12\x39\n\x07outputs\x18\n \x03(\x0b\x32(.cln.ListtransactionsTransactionsOutputs\"S\n\"ListtransactionsTransactionsInputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\r\n\x05index\x18\x02 \x01(\r\x12\x10\n\x08sequence\x18\x03 \x01(\r\"l\n#ListtransactionsTransactionsOutputs\x12\r\n\x05index\x18\x01 \x01(\r\x12\x14\n\x0cscriptPubKey\x18\x03 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\"M\n\x11MakesecretRequest\x12\x10\n\x03hex\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06string\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x06\n\x04_hexB\t\n\x07_string\"$\n\x12MakesecretResponse\x12\x0e\n\x06secret\x18\x01 \x01(\x0c\"\x93\x04\n\nPayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x01\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x03\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x17\n\nriskfactor\x18\x08 \x01(\x01H\x05\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\n \x03(\t\x12 \n\x06maxfee\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0c \x01(\tH\x07\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\r \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\x0e \x01(\x0cH\t\x88\x01\x01\x12&\n\x0cpartial_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\n\x88\x01\x01\x42\x08\n\x06_labelB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\r\n\x0b_riskfactorB\t\n\x07_maxfeeB\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\x10\n\x0e_localinvreqidB\x0f\n\r_partial_msat\"\xfb\x02\n\x0bPayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12*\n\x06status\x18\t \x01(\x0e\x32\x1a.cln.PayResponse.PayStatus\"2\n\tPayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion\"*\n\x10ListnodesRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"7\n\x11ListnodesResponse\x12\"\n\x05nodes\x18\x01 \x03(\x0b\x32\x13.cln.ListnodesNodes\"\xba\x02\n\x0eListnodesNodes\x12\x0e\n\x06nodeid\x18\x01 \x01(\x0c\x12\x1b\n\x0elast_timestamp\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x12\n\x05\x61lias\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05\x63olor\x18\x04 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x05 \x01(\x0cH\x03\x88\x01\x01\x12/\n\taddresses\x18\x06 \x03(\x0b\x32\x1c.cln.ListnodesNodesAddresses\x12\x42\n\x10option_will_fund\x18\x07 \x01(\x0b\x32#.cln.ListnodesNodesOption_will_fundH\x04\x88\x01\x01\x42\x11\n\x0f_last_timestampB\x08\n\x06_aliasB\x08\n\x06_colorB\x0b\n\t_featuresB\x13\n\x11_option_will_fund\"\xf4\x01\n\x1eListnodesNodesOption_will_fund\x12(\n\x13lease_fee_base_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x17\n\x0flease_fee_basis\x18\x02 \x01(\r\x12\x16\n\x0e\x66unding_weight\x18\x03 \x01(\r\x12.\n\x19\x63hannel_fee_max_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x30\n(channel_fee_max_proportional_thousandths\x18\x05 \x01(\r\x12\x15\n\rcompact_lease\x18\x06 \x01(\x0c\"\xe8\x01\n\x17ListnodesNodesAddresses\x12K\n\titem_type\x18\x01 \x01(\x0e\x32\x38.cln.ListnodesNodesAddresses.ListnodesNodesAddressesType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\"P\n\x1bListnodesNodesAddressesType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_address\"g\n\x15WaitanyinvoiceRequest\x12\x1a\n\rlastpay_index\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07timeout\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x10\n\x0e_lastpay_indexB\n\n\x08_timeout\"\xd4\x05\n\x16WaitanyinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12@\n\x06status\x18\x04 \x01(\x0e\x32\x30.cln.WaitanyinvoiceResponse.WaitanyinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x04\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x07\x88\x01\x01\x12\x1a\n\rcreated_index\x18\r \x01(\x04H\x08\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0e \x01(\x04H\t\x88\x01\x01\x12<\n\rpaid_outpoint\x18\x0f \x01(\x0b\x32 .cln.WaitanyinvoicePaid_outpointH\n\x88\x01\x01\"-\n\x14WaitanyinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimageB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x10\n\x0e_paid_outpoint\";\n\x1bWaitanyinvoicePaid_outpoint\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\"#\n\x12WaitinvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t\"\xc5\x05\n\x13WaitinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitinvoiceResponse.WaitinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x04\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x07\x88\x01\x01\x12\x1a\n\rcreated_index\x18\r \x01(\x04H\x08\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0e \x01(\x04H\t\x88\x01\x01\x12\x39\n\rpaid_outpoint\x18\x0f \x01(\x0b\x32\x1d.cln.WaitinvoicePaid_outpointH\n\x88\x01\x01\"*\n\x11WaitinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimageB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x10\n\x0e_paid_outpoint\"8\n\x18WaitinvoicePaid_outpoint\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\"\x8e\x01\n\x12WaitsendpayRequest\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x13\n\x06partid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07timeout\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x14\n\x07groupid\x18\x04 \x01(\x04H\x02\x88\x01\x01\x42\t\n\x07_partidB\n\n\x08_timeoutB\n\n\x08_groupid\"\x8e\x05\n\x13WaitsendpayResponse\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitsendpayResponse.WaitsendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0e \x01(\x01H\x08\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x0f \x01(\x04H\t\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x10 \x01(\x04H\n\x88\x01\x01\"!\n\x11WaitsendpayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\x0f\n\r_completed_atB\x10\n\x0e_created_indexB\x10\n\x0e_updated_index\"\x97\x01\n\x0eNewaddrRequest\x12@\n\x0b\x61\x64\x64resstype\x18\x01 \x01(\x0e\x32&.cln.NewaddrRequest.NewaddrAddresstypeH\x00\x88\x01\x01\"3\n\x12NewaddrAddresstype\x12\n\n\x06\x42\x45\x43H32\x10\x00\x12\x07\n\x03\x41LL\x10\x02\x12\x08\n\x04P2TR\x10\x03\x42\x0e\n\x0c_addresstype\"M\n\x0fNewaddrResponse\x12\x13\n\x06\x62\x65\x63h32\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04p2tr\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_bech32B\x07\n\x05_p2tr\"\xb9\x01\n\x0fWithdrawRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\t\x12!\n\x07satoshi\x18\x02 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12\"\n\x07\x66\x65\x65rate\x18\x05 \x01(\x0b\x32\x0c.cln.FeerateH\x01\x88\x01\x01\x42\n\n\x08_minconfB\n\n\x08_feerate\":\n\x10WithdrawResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x0c\n\x04psbt\x18\x03 \x01(\t\"\xaf\x03\n\x0eKeysendRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\x0c\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x01\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x03\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12+\n\nroutehints\x18\x08 \x01(\x0b\x32\x12.cln.RoutehintListH\x05\x88\x01\x01\x12&\n\textratlvs\x18\t \x01(\x0b\x32\x0e.cln.TlvStreamH\x06\x88\x01\x01\x12 \n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x0b.cln.Amount\x12 \n\x06maxfee\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x07\x88\x01\x01\x42\x08\n\x06_labelB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\r\n\x0b_routehintsB\x0c\n\n_extratlvsB\t\n\x07_maxfee\"\xf2\x02\n\x0fKeysendResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x32\n\x06status\x18\t \x01(\x0e\x32\".cln.KeysendResponse.KeysendStatus\"\x1d\n\rKeysendStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion\"\xa4\x03\n\x0f\x46undpsbtRequest\x12!\n\x07satoshi\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x14\n\x07minconf\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\x08 \x01(\x08H\x04\x88\x01\x01\x12\x17\n\nnonwrapped\x18\t \x01(\x08H\x05\x88\x01\x01\x12#\n\x16opening_anchor_channel\x18\n \x01(\x08H\x06\x88\x01\x01\x42\n\n\x08_minconfB\n\n\x08_reserveB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\x13\n\x11_excess_as_changeB\r\n\x0b_nonwrappedB\x19\n\x17_opening_anchor_channel\"\xd9\x01\n\x10\x46undpsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.FundpsbtReservationsB\x10\n\x0e_change_outnum\"u\n\x14\x46undpsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\"A\n\x0fSendpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x14\n\x07reserve\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\n\n\x08_reserve\",\n\x10SendpsbtResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"1\n\x0fSignpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x10\n\x08signonly\x18\x02 \x03(\r\"\'\n\x10SignpsbtResponse\x12\x13\n\x0bsigned_psbt\x18\x01 \x01(\t\"\xa0\x03\n\x0fUtxopsbtRequest\x12!\n\x07satoshi\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x00\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x02\x88\x01\x01\x12\x17\n\nreservedok\x18\x08 \x01(\x08H\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\t \x01(\x08H\x04\x88\x01\x01\x12#\n\x16opening_anchor_channel\x18\n \x01(\x08H\x05\x88\x01\x01\x42\n\n\x08_reserveB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\r\n\x0b_reservedokB\x13\n\x11_excess_as_changeB\x19\n\x17_opening_anchor_channel\"\xd9\x01\n\x10UtxopsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.UtxopsbtReservationsB\x10\n\x0e_change_outnum\"u\n\x14UtxopsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\" \n\x10TxdiscardRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\"6\n\x11TxdiscardResponse\x12\x13\n\x0bunsigned_tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"\xa4\x01\n\x10TxprepareRequest\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12 \n\x07outputs\x18\x05 \x03(\x0b\x32\x0f.cln.OutputDescB\n\n\x08_feerateB\n\n\x08_minconf\"D\n\x11TxprepareResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x13\n\x0bunsigned_tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"\x1d\n\rTxsendRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\"8\n\x0eTxsendResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\n\n\x02tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"1\n\x17ListpeerchannelsRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"K\n\x18ListpeerchannelsResponse\x12/\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1d.cln.ListpeerchannelsChannels\"\xd7\x1b\n\x18ListpeerchannelsChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x16\n\x0epeer_connected\x18\x02 \x01(\x08\x12J\n\x05state\x18\x03 \x01(\x0e\x32;.cln.ListpeerchannelsChannels.ListpeerchannelsChannelsState\x12\x19\n\x0cscratch_txid\x18\x04 \x01(\x0cH\x00\x88\x01\x01\x12:\n\x07\x66\x65\x65rate\x18\x06 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsFeerateH\x01\x88\x01\x01\x12\x12\n\x05owner\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x1d\n\x10short_channel_id\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x17\n\nchannel_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x19\n\x0c\x66unding_txid\x18\n \x01(\x0cH\x05\x88\x01\x01\x12\x1b\n\x0e\x66unding_outnum\x18\x0b \x01(\rH\x06\x88\x01\x01\x12\x1c\n\x0finitial_feerate\x18\x0c \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0clast_feerate\x18\r \x01(\tH\x08\x88\x01\x01\x12\x19\n\x0cnext_feerate\x18\x0e \x01(\tH\t\x88\x01\x01\x12\x1a\n\rnext_fee_step\x18\x0f \x01(\rH\n\x88\x01\x01\x12\x37\n\x08inflight\x18\x10 \x03(\x0b\x32%.cln.ListpeerchannelsChannelsInflight\x12\x15\n\x08\x63lose_to\x18\x11 \x01(\x0cH\x0b\x88\x01\x01\x12\x14\n\x07private\x18\x12 \x01(\x08H\x0c\x88\x01\x01\x12 \n\x06opener\x18\x13 \x01(\x0e\x32\x10.cln.ChannelSide\x12%\n\x06\x63loser\x18\x14 \x01(\x0e\x32\x10.cln.ChannelSideH\r\x88\x01\x01\x12:\n\x07\x66unding\x18\x16 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsFundingH\x0e\x88\x01\x01\x12$\n\nto_us_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x0f\x88\x01\x01\x12(\n\x0emin_to_us_msat\x18\x18 \x01(\x0b\x32\x0b.cln.AmountH\x10\x88\x01\x01\x12(\n\x0emax_to_us_msat\x18\x19 \x01(\x0b\x32\x0b.cln.AmountH\x11\x88\x01\x01\x12$\n\ntotal_msat\x18\x1a \x01(\x0b\x32\x0b.cln.AmountH\x12\x88\x01\x01\x12\'\n\rfee_base_msat\x18\x1b \x01(\x0b\x32\x0b.cln.AmountH\x13\x88\x01\x01\x12(\n\x1b\x66\x65\x65_proportional_millionths\x18\x1c \x01(\rH\x14\x88\x01\x01\x12)\n\x0f\x64ust_limit_msat\x18\x1d \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12\x30\n\x16max_total_htlc_in_msat\x18\x1e \x01(\x0b\x32\x0b.cln.AmountH\x16\x88\x01\x01\x12,\n\x12their_reserve_msat\x18\x1f \x01(\x0b\x32\x0b.cln.AmountH\x17\x88\x01\x01\x12*\n\x10our_reserve_msat\x18 \x01(\x0b\x32\x0b.cln.AmountH\x18\x88\x01\x01\x12(\n\x0espendable_msat\x18! \x01(\x0b\x32\x0b.cln.AmountH\x19\x88\x01\x01\x12)\n\x0freceivable_msat\x18\" \x01(\x0b\x32\x0b.cln.AmountH\x1a\x88\x01\x01\x12.\n\x14minimum_htlc_in_msat\x18# \x01(\x0b\x32\x0b.cln.AmountH\x1b\x88\x01\x01\x12/\n\x15minimum_htlc_out_msat\x18$ \x01(\x0b\x32\x0b.cln.AmountH\x1c\x88\x01\x01\x12/\n\x15maximum_htlc_out_msat\x18% \x01(\x0b\x32\x0b.cln.AmountH\x1d\x88\x01\x01\x12 \n\x13their_to_self_delay\x18& \x01(\rH\x1e\x88\x01\x01\x12\x1e\n\x11our_to_self_delay\x18\' \x01(\rH\x1f\x88\x01\x01\x12\x1f\n\x12max_accepted_htlcs\x18( \x01(\rH \x88\x01\x01\x12\x36\n\x05\x61lias\x18) \x01(\x0b\x32\".cln.ListpeerchannelsChannelsAliasH!\x88\x01\x01\x12\x0e\n\x06status\x18+ \x03(\t\x12 \n\x13in_payments_offered\x18, \x01(\x04H\"\x88\x01\x01\x12)\n\x0fin_offered_msat\x18- \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12\"\n\x15in_payments_fulfilled\x18. \x01(\x04H$\x88\x01\x01\x12+\n\x11in_fulfilled_msat\x18/ \x01(\x0b\x32\x0b.cln.AmountH%\x88\x01\x01\x12!\n\x14out_payments_offered\x18\x30 \x01(\x04H&\x88\x01\x01\x12*\n\x10out_offered_msat\x18\x31 \x01(\x0b\x32\x0b.cln.AmountH\'\x88\x01\x01\x12#\n\x16out_payments_fulfilled\x18\x32 \x01(\x04H(\x88\x01\x01\x12,\n\x12out_fulfilled_msat\x18\x33 \x01(\x0b\x32\x0b.cln.AmountH)\x88\x01\x01\x12\x31\n\x05htlcs\x18\x34 \x03(\x0b\x32\".cln.ListpeerchannelsChannelsHtlcs\x12\x1a\n\rclose_to_addr\x18\x35 \x01(\tH*\x88\x01\x01\x12\x1e\n\x11ignore_fee_limits\x18\x36 \x01(\x08H+\x88\x01\x01\x12:\n\x07updates\x18\x37 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsUpdatesH,\x88\x01\x01\x12#\n\x16last_stable_connection\x18\x38 \x01(\x04H-\x88\x01\x01\x12\x17\n\nlost_state\x18\x39 \x01(\x08H.\x88\x01\x01\x12\x1a\n\rreestablished\x18: \x01(\x08H/\x88\x01\x01\x12*\n\x10last_tx_fee_msat\x18; \x01(\x0b\x32\x0b.cln.AmountH0\x88\x01\x01\x12\x16\n\tdirection\x18< \x01(\rH1\x88\x01\x01\"\x80\x03\n\x1dListpeerchannelsChannelsState\x12\x0c\n\x08OPENINGD\x10\x00\x12\x1c\n\x18\x43HANNELD_AWAITING_LOCKIN\x10\x01\x12\x13\n\x0f\x43HANNELD_NORMAL\x10\x02\x12\x1a\n\x16\x43HANNELD_SHUTTING_DOWN\x10\x03\x12\x18\n\x14\x43LOSINGD_SIGEXCHANGE\x10\x04\x12\x15\n\x11\x43LOSINGD_COMPLETE\x10\x05\x12\x17\n\x13\x41WAITING_UNILATERAL\x10\x06\x12\x16\n\x12\x46UNDING_SPEND_SEEN\x10\x07\x12\x0b\n\x07ONCHAIN\x10\x08\x12\x17\n\x13\x44UALOPEND_OPEN_INIT\x10\t\x12\x1d\n\x19\x44UALOPEND_AWAITING_LOCKIN\x10\n\x12\x1c\n\x18\x43HANNELD_AWAITING_SPLICE\x10\x0b\x12\x1c\n\x18\x44UALOPEND_OPEN_COMMITTED\x10\x0c\x12\x1f\n\x1b\x44UALOPEND_OPEN_COMMIT_READY\x10\rB\x0f\n\r_scratch_txidB\n\n\x08_feerateB\x08\n\x06_ownerB\x13\n\x11_short_channel_idB\r\n\x0b_channel_idB\x0f\n\r_funding_txidB\x11\n\x0f_funding_outnumB\x12\n\x10_initial_feerateB\x0f\n\r_last_feerateB\x0f\n\r_next_feerateB\x10\n\x0e_next_fee_stepB\x0b\n\t_close_toB\n\n\x08_privateB\t\n\x07_closerB\n\n\x08_fundingB\r\n\x0b_to_us_msatB\x11\n\x0f_min_to_us_msatB\x11\n\x0f_max_to_us_msatB\r\n\x0b_total_msatB\x10\n\x0e_fee_base_msatB\x1e\n\x1c_fee_proportional_millionthsB\x12\n\x10_dust_limit_msatB\x19\n\x17_max_total_htlc_in_msatB\x15\n\x13_their_reserve_msatB\x13\n\x11_our_reserve_msatB\x11\n\x0f_spendable_msatB\x12\n\x10_receivable_msatB\x17\n\x15_minimum_htlc_in_msatB\x18\n\x16_minimum_htlc_out_msatB\x18\n\x16_maximum_htlc_out_msatB\x16\n\x14_their_to_self_delayB\x14\n\x12_our_to_self_delayB\x15\n\x13_max_accepted_htlcsB\x08\n\x06_aliasB\x16\n\x14_in_payments_offeredB\x12\n\x10_in_offered_msatB\x18\n\x16_in_payments_fulfilledB\x14\n\x12_in_fulfilled_msatB\x17\n\x15_out_payments_offeredB\x13\n\x11_out_offered_msatB\x19\n\x17_out_payments_fulfilledB\x15\n\x13_out_fulfilled_msatB\x10\n\x0e_close_to_addrB\x14\n\x12_ignore_fee_limitsB\n\n\x08_updatesB\x19\n\x17_last_stable_connectionB\r\n\x0b_lost_stateB\x10\n\x0e_reestablishedB\x13\n\x11_last_tx_fee_msatB\x0c\n\n_direction\"\xa7\x01\n\x1fListpeerchannelsChannelsUpdates\x12\x38\n\x05local\x18\x01 \x01(\x0b\x32).cln.ListpeerchannelsChannelsUpdatesLocal\x12?\n\x06remote\x18\x02 \x01(\x0b\x32*.cln.ListpeerchannelsChannelsUpdatesRemoteH\x00\x88\x01\x01\x42\t\n\x07_remote\"\xda\x01\n$ListpeerchannelsChannelsUpdatesLocal\x12&\n\x11htlc_minimum_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11htlc_maximum_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x19\n\x11\x63ltv_expiry_delta\x18\x03 \x01(\r\x12\"\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\r\"\xdb\x01\n%ListpeerchannelsChannelsUpdatesRemote\x12&\n\x11htlc_minimum_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11htlc_maximum_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x19\n\x11\x63ltv_expiry_delta\x18\x03 \x01(\r\x12\"\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\r\"?\n\x1fListpeerchannelsChannelsFeerate\x12\r\n\x05perkw\x18\x01 \x01(\r\x12\r\n\x05perkb\x18\x02 \x01(\r\"\x8b\x02\n ListpeerchannelsChannelsInflight\x12\x14\n\x0c\x66unding_txid\x18\x01 \x01(\x0c\x12\x16\n\x0e\x66unding_outnum\x18\x02 \x01(\r\x12\x0f\n\x07\x66\x65\x65rate\x18\x03 \x01(\t\x12\'\n\x12total_funding_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10our_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x19\n\x0cscratch_txid\x18\x06 \x01(\x0cH\x00\x88\x01\x01\x12\x1a\n\rsplice_amount\x18\x07 \x01(\x12H\x01\x88\x01\x01\x42\x0f\n\r_scratch_txidB\x10\n\x0e_splice_amount\"\x9d\x02\n\x1fListpeerchannelsChannelsFunding\x12%\n\x0bpushed_msat\x18\x01 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12%\n\x10local_funds_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11remote_funds_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\rfee_paid_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\'\n\rfee_rcvd_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x42\x0e\n\x0c_pushed_msatB\x10\n\x0e_fee_paid_msatB\x10\n\x0e_fee_rcvd_msat\"]\n\x1dListpeerchannelsChannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"\xf9\x02\n\x1dListpeerchannelsChannelsHtlcs\x12\\\n\tdirection\x18\x01 \x01(\x0e\x32I.cln.ListpeerchannelsChannelsHtlcs.ListpeerchannelsChannelsHtlcsDirection\x12\n\n\x02id\x18\x02 \x01(\x04\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06\x65xpiry\x18\x04 \x01(\r\x12\x14\n\x0cpayment_hash\x18\x05 \x01(\x0c\x12\x1a\n\rlocal_trimmed\x18\x06 \x01(\x08H\x00\x88\x01\x01\x12\x13\n\x06status\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x05state\x18\x08 \x01(\x0e\x32\x0e.cln.HtlcState\"9\n&ListpeerchannelsChannelsHtlcsDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\x42\x10\n\x0e_local_trimmedB\t\n\x07_status\"3\n\x19ListclosedchannelsRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"[\n\x1aListclosedchannelsResponse\x12=\n\x0e\x63losedchannels\x18\x01 \x03(\x0b\x32%.cln.ListclosedchannelsClosedchannels\"\xf2\t\n ListclosedchannelsClosedchannels\x12\x14\n\x07peer_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\nchannel_id\x18\x02 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x03 \x01(\tH\x01\x88\x01\x01\x12>\n\x05\x61lias\x18\x04 \x01(\x0b\x32*.cln.ListclosedchannelsClosedchannelsAliasH\x02\x88\x01\x01\x12 \n\x06opener\x18\x05 \x01(\x0e\x32\x10.cln.ChannelSide\x12%\n\x06\x63loser\x18\x06 \x01(\x0e\x32\x10.cln.ChannelSideH\x03\x88\x01\x01\x12\x0f\n\x07private\x18\x07 \x01(\x08\x12\x1f\n\x17total_local_commitments\x18\t \x01(\x04\x12 \n\x18total_remote_commitments\x18\n \x01(\x04\x12\x18\n\x10total_htlcs_sent\x18\x0b \x01(\x04\x12\x14\n\x0c\x66unding_txid\x18\x0c \x01(\x0c\x12\x16\n\x0e\x66unding_outnum\x18\r \x01(\r\x12\x0e\n\x06leased\x18\x0e \x01(\x08\x12/\n\x15\x66unding_fee_paid_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12/\n\x15\x66unding_fee_rcvd_msat\x18\x10 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12-\n\x13\x66unding_pushed_msat\x18\x11 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1f\n\ntotal_msat\x18\x12 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x66inal_to_us_msat\x18\x13 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0emin_to_us_msat\x18\x14 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0emax_to_us_msat\x18\x15 \x01(\x0b\x32\x0b.cln.Amount\x12!\n\x14last_commitment_txid\x18\x16 \x01(\x0cH\x07\x88\x01\x01\x12\x32\n\x18last_commitment_fee_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x66\n\x0b\x63lose_cause\x18\x18 \x01(\x0e\x32Q.cln.ListclosedchannelsClosedchannels.ListclosedchannelsClosedchannelsClose_cause\x12#\n\x16last_stable_connection\x18\x19 \x01(\x04H\t\x88\x01\x01\"v\n+ListclosedchannelsClosedchannelsClose_cause\x12\x0b\n\x07UNKNOWN\x10\x00\x12\t\n\x05LOCAL\x10\x01\x12\x08\n\x04USER\x10\x02\x12\n\n\x06REMOTE\x10\x03\x12\x0c\n\x08PROTOCOL\x10\x04\x12\x0b\n\x07ONCHAIN\x10\x05\x42\n\n\x08_peer_idB\x13\n\x11_short_channel_idB\x08\n\x06_aliasB\t\n\x07_closerB\x18\n\x16_funding_fee_paid_msatB\x18\n\x16_funding_fee_rcvd_msatB\x16\n\x14_funding_pushed_msatB\x17\n\x15_last_commitment_txidB\x1b\n\x19_last_commitment_fee_msatB\x19\n\x17_last_stable_connection\"e\n%ListclosedchannelsClosedchannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"L\n\x10\x44\x65\x63odepayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xc7\x04\n\x11\x44\x65\x63odepayResponse\x12\x10\n\x08\x63urrency\x18\x01 \x01(\t\x12\x12\n\ncreated_at\x18\x02 \x01(\x04\x12\x0e\n\x06\x65xpiry\x18\x03 \x01(\x04\x12\r\n\x05payee\x18\x04 \x01(\x0c\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x11\n\tsignature\x18\x07 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x10\x64\x65scription_hash\x18\t \x01(\x0cH\x02\x88\x01\x01\x12\x1d\n\x15min_final_cltv_expiry\x18\n \x01(\r\x12\x1b\n\x0epayment_secret\x18\x0b \x01(\x0cH\x03\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x0c \x01(\x0cH\x04\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\r \x01(\x0cH\x05\x88\x01\x01\x12*\n\tfallbacks\x18\x0e \x03(\x0b\x32\x17.cln.DecodepayFallbacks\x12\"\n\x05\x65xtra\x18\x10 \x03(\x0b\x32\x13.cln.DecodepayExtra\x12-\n\x06routes\x18\x11 \x01(\x0b\x32\x18.cln.DecodeRoutehintListH\x06\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x13\n\x11_description_hashB\x11\n\x0f_payment_secretB\x0b\n\t_featuresB\x13\n\x11_payment_metadataB\t\n\x07_routes\"\xd0\x01\n\x12\x44\x65\x63odepayFallbacks\x12\x41\n\titem_type\x18\x01 \x01(\x0e\x32..cln.DecodepayFallbacks.DecodepayFallbacksType\x12\x11\n\x04\x61\x64\x64r\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x0b\n\x03hex\x18\x03 \x01(\x0c\"N\n\x16\x44\x65\x63odepayFallbacksType\x12\t\n\x05P2PKH\x10\x00\x12\x08\n\x04P2SH\x10\x01\x12\n\n\x06P2WPKH\x10\x02\x12\t\n\x05P2WSH\x10\x03\x12\x08\n\x04P2TR\x10\x04\x42\x07\n\x05_addr\"+\n\x0e\x44\x65\x63odepayExtra\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\"\x1f\n\rDecodeRequest\x12\x0e\n\x06string\x18\x01 \x01(\t\"\xec%\n\x0e\x44\x65\x63odeResponse\x12\x31\n\titem_type\x18\x01 \x01(\x0e\x32\x1e.cln.DecodeResponse.DecodeType\x12\r\n\x05valid\x18\x02 \x01(\x08\x12\x15\n\x08offer_id\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0coffer_chains\x18\x04 \x03(\x0c\x12\x1b\n\x0eoffer_metadata\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x1b\n\x0eoffer_currency\x18\x06 \x01(\tH\x02\x88\x01\x01\x12+\n\x1ewarning_unknown_offer_currency\x18\x07 \x01(\tH\x03\x88\x01\x01\x12 \n\x13\x63urrency_minor_unit\x18\x08 \x01(\rH\x04\x88\x01\x01\x12\x19\n\x0coffer_amount\x18\t \x01(\x04H\x05\x88\x01\x01\x12+\n\x11offer_amount_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1e\n\x11offer_description\x18\x0b \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0coffer_issuer\x18\x0c \x01(\tH\x08\x88\x01\x01\x12\x1b\n\x0eoffer_features\x18\r \x01(\x0cH\t\x88\x01\x01\x12\"\n\x15offer_absolute_expiry\x18\x0e \x01(\x04H\n\x88\x01\x01\x12\x1f\n\x12offer_quantity_max\x18\x0f \x01(\x04H\x0b\x88\x01\x01\x12+\n\x0boffer_paths\x18\x10 \x03(\x0b\x32\x16.cln.DecodeOffer_paths\x12\x1a\n\roffer_node_id\x18\x11 \x01(\x0cH\x0c\x88\x01\x01\x12*\n\x1dwarning_missing_offer_node_id\x18\x14 \x01(\tH\r\x88\x01\x01\x12.\n!warning_invalid_offer_description\x18\x15 \x01(\tH\x0e\x88\x01\x01\x12.\n!warning_missing_offer_description\x18\x16 \x01(\tH\x0f\x88\x01\x01\x12+\n\x1ewarning_invalid_offer_currency\x18\x17 \x01(\tH\x10\x88\x01\x01\x12)\n\x1cwarning_invalid_offer_issuer\x18\x18 \x01(\tH\x11\x88\x01\x01\x12\x1c\n\x0finvreq_metadata\x18\x19 \x01(\x0cH\x12\x88\x01\x01\x12\x1c\n\x0finvreq_payer_id\x18\x1a \x01(\x0cH\x13\x88\x01\x01\x12\x19\n\x0cinvreq_chain\x18\x1b \x01(\x0cH\x14\x88\x01\x01\x12,\n\x12invreq_amount_msat\x18\x1c \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12\x1c\n\x0finvreq_features\x18\x1d \x01(\x0cH\x16\x88\x01\x01\x12\x1c\n\x0finvreq_quantity\x18\x1e \x01(\x04H\x17\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x1f \x01(\tH\x18\x88\x01\x01\x12&\n\x19invreq_recurrence_counter\x18 \x01(\rH\x19\x88\x01\x01\x12$\n\x17invreq_recurrence_start\x18! \x01(\rH\x1a\x88\x01\x01\x12,\n\x1fwarning_missing_invreq_metadata\x18# \x01(\tH\x1b\x88\x01\x01\x12,\n\x1fwarning_missing_invreq_payer_id\x18$ \x01(\tH\x1c\x88\x01\x01\x12.\n!warning_invalid_invreq_payer_note\x18% \x01(\tH\x1d\x88\x01\x01\x12\x36\n)warning_missing_invoice_request_signature\x18& \x01(\tH\x1e\x88\x01\x01\x12\x36\n)warning_invalid_invoice_request_signature\x18\' \x01(\tH\x1f\x88\x01\x01\x12\x1f\n\x12invoice_created_at\x18) \x01(\x04H \x88\x01\x01\x12$\n\x17invoice_relative_expiry\x18* \x01(\rH!\x88\x01\x01\x12!\n\x14invoice_payment_hash\x18+ \x01(\x0cH\"\x88\x01\x01\x12-\n\x13invoice_amount_msat\x18, \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12\x37\n\x11invoice_fallbacks\x18- \x03(\x0b\x32\x1c.cln.DecodeInvoice_fallbacks\x12\x1d\n\x10invoice_features\x18. \x01(\x0cH$\x88\x01\x01\x12\x1c\n\x0finvoice_node_id\x18/ \x01(\x0cH%\x88\x01\x01\x12(\n\x1binvoice_recurrence_basetime\x18\x30 \x01(\x04H&\x88\x01\x01\x12*\n\x1dwarning_missing_invoice_paths\x18\x32 \x01(\tH\'\x88\x01\x01\x12/\n\"warning_missing_invoice_blindedpay\x18\x33 \x01(\tH(\x88\x01\x01\x12/\n\"warning_missing_invoice_created_at\x18\x34 \x01(\tH)\x88\x01\x01\x12\x31\n$warning_missing_invoice_payment_hash\x18\x35 \x01(\tH*\x88\x01\x01\x12+\n\x1ewarning_missing_invoice_amount\x18\x36 \x01(\tH+\x88\x01\x01\x12\x38\n+warning_missing_invoice_recurrence_basetime\x18\x37 \x01(\tH,\x88\x01\x01\x12,\n\x1fwarning_missing_invoice_node_id\x18\x38 \x01(\tH-\x88\x01\x01\x12.\n!warning_missing_invoice_signature\x18\x39 \x01(\tH.\x88\x01\x01\x12.\n!warning_invalid_invoice_signature\x18: \x01(\tH/\x88\x01\x01\x12\'\n\tfallbacks\x18; \x03(\x0b\x32\x14.cln.DecodeFallbacks\x12\x17\n\ncreated_at\x18< \x01(\x04H0\x88\x01\x01\x12\x13\n\x06\x65xpiry\x18= \x01(\x04H1\x88\x01\x01\x12\x12\n\x05payee\x18> \x01(\x0cH2\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18? \x01(\x0cH3\x88\x01\x01\x12\x1d\n\x10\x64\x65scription_hash\x18@ \x01(\x0cH4\x88\x01\x01\x12\"\n\x15min_final_cltv_expiry\x18\x41 \x01(\rH5\x88\x01\x01\x12\x1b\n\x0epayment_secret\x18\x42 \x01(\x0cH6\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\x43 \x01(\x0cH7\x88\x01\x01\x12\x1f\n\x05\x65xtra\x18\x45 \x03(\x0b\x32\x10.cln.DecodeExtra\x12\x16\n\tunique_id\x18\x46 \x01(\tH8\x88\x01\x01\x12\x14\n\x07version\x18G \x01(\tH9\x88\x01\x01\x12\x13\n\x06string\x18H \x01(\tH:\x88\x01\x01\x12-\n\x0crestrictions\x18I \x03(\x0b\x32\x17.cln.DecodeRestrictions\x12&\n\x19warning_rune_invalid_utf8\x18J \x01(\tH;\x88\x01\x01\x12\x10\n\x03hex\x18K \x01(\x0cH<\x88\x01\x01\x12\x16\n\tdecrypted\x18L \x01(\x0cH=\x88\x01\x01\x12\x16\n\tsignature\x18M \x01(\tH>\x88\x01\x01\x12\x15\n\x08\x63urrency\x18N \x01(\tH?\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18O \x01(\x0b\x32\x0b.cln.AmountH@\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18P \x01(\tHA\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18Q \x01(\x0cHB\x88\x01\x01\x12-\n\x06routes\x18R \x01(\x0b\x32\x18.cln.DecodeRoutehintListHC\x88\x01\x01\x12\x1c\n\x0foffer_issuer_id\x18S \x01(\x0cHD\x88\x01\x01\x12,\n\x1fwarning_missing_offer_issuer_id\x18T \x01(\tHE\x88\x01\x01\x12-\n\x0cinvreq_paths\x18U \x03(\x0b\x32\x17.cln.DecodeInvreq_paths\x12\'\n\x1awarning_empty_blinded_path\x18V \x01(\tHF\x88\x01\x01\"\x83\x01\n\nDecodeType\x12\x10\n\x0c\x42OLT12_OFFER\x10\x00\x12\x12\n\x0e\x42OLT12_INVOICE\x10\x01\x12\x1a\n\x16\x42OLT12_INVOICE_REQUEST\x10\x02\x12\x12\n\x0e\x42OLT11_INVOICE\x10\x03\x12\x08\n\x04RUNE\x10\x04\x12\x15\n\x11\x45MERGENCY_RECOVER\x10\x05\x42\x0b\n\t_offer_idB\x11\n\x0f_offer_metadataB\x11\n\x0f_offer_currencyB!\n\x1f_warning_unknown_offer_currencyB\x16\n\x14_currency_minor_unitB\x0f\n\r_offer_amountB\x14\n\x12_offer_amount_msatB\x14\n\x12_offer_descriptionB\x0f\n\r_offer_issuerB\x11\n\x0f_offer_featuresB\x18\n\x16_offer_absolute_expiryB\x15\n\x13_offer_quantity_maxB\x10\n\x0e_offer_node_idB \n\x1e_warning_missing_offer_node_idB$\n\"_warning_invalid_offer_descriptionB$\n\"_warning_missing_offer_descriptionB!\n\x1f_warning_invalid_offer_currencyB\x1f\n\x1d_warning_invalid_offer_issuerB\x12\n\x10_invreq_metadataB\x12\n\x10_invreq_payer_idB\x0f\n\r_invreq_chainB\x15\n\x13_invreq_amount_msatB\x12\n\x10_invreq_featuresB\x12\n\x10_invreq_quantityB\x14\n\x12_invreq_payer_noteB\x1c\n\x1a_invreq_recurrence_counterB\x1a\n\x18_invreq_recurrence_startB\"\n _warning_missing_invreq_metadataB\"\n _warning_missing_invreq_payer_idB$\n\"_warning_invalid_invreq_payer_noteB,\n*_warning_missing_invoice_request_signatureB,\n*_warning_invalid_invoice_request_signatureB\x15\n\x13_invoice_created_atB\x1a\n\x18_invoice_relative_expiryB\x17\n\x15_invoice_payment_hashB\x16\n\x14_invoice_amount_msatB\x13\n\x11_invoice_featuresB\x12\n\x10_invoice_node_idB\x1e\n\x1c_invoice_recurrence_basetimeB \n\x1e_warning_missing_invoice_pathsB%\n#_warning_missing_invoice_blindedpayB%\n#_warning_missing_invoice_created_atB\'\n%_warning_missing_invoice_payment_hashB!\n\x1f_warning_missing_invoice_amountB.\n,_warning_missing_invoice_recurrence_basetimeB\"\n _warning_missing_invoice_node_idB$\n\"_warning_missing_invoice_signatureB$\n\"_warning_invalid_invoice_signatureB\r\n\x0b_created_atB\t\n\x07_expiryB\x08\n\x06_payeeB\x0f\n\r_payment_hashB\x13\n\x11_description_hashB\x18\n\x16_min_final_cltv_expiryB\x11\n\x0f_payment_secretB\x13\n\x11_payment_metadataB\x0c\n\n_unique_idB\n\n\x08_versionB\t\n\x07_stringB\x1c\n\x1a_warning_rune_invalid_utf8B\x06\n\x04_hexB\x0c\n\n_decryptedB\x0c\n\n_signatureB\x0b\n\t_currencyB\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x0b\n\t_featuresB\t\n\x07_routesB\x12\n\x10_offer_issuer_idB\"\n _warning_missing_offer_issuer_idB\x1d\n\x1b_warning_empty_blinded_path\"\xed\x01\n\x11\x44\x65\x63odeOffer_paths\x12\x1a\n\rfirst_node_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x15\n\x08\x62linding\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x1b\n\x0e\x66irst_scid_dir\x18\x04 \x01(\rH\x02\x88\x01\x01\x12\x17\n\nfirst_scid\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x1b\n\x0e\x66irst_path_key\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x42\x10\n\x0e_first_node_idB\x0b\n\t_blindingB\x11\n\x0f_first_scid_dirB\r\n\x0b_first_scidB\x11\n\x0f_first_path_key\"\x8a\x01\n\x1f\x44\x65\x63odeOffer_recurrencePaywindow\x12\x16\n\x0eseconds_before\x18\x01 \x01(\r\x12\x15\n\rseconds_after\x18\x02 \x01(\r\x12 \n\x13proportional_amount\x18\x03 \x01(\x08H\x00\x88\x01\x01\x42\x16\n\x14_proportional_amount\"\x99\x02\n\x12\x44\x65\x63odeInvreq_paths\x12\x1b\n\x0e\x66irst_scid_dir\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x15\n\x08\x62linding\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x1a\n\rfirst_node_id\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x17\n\nfirst_scid\x18\x04 \x01(\tH\x03\x88\x01\x01\x12)\n\x04path\x18\x05 \x03(\x0b\x32\x1b.cln.DecodeInvreq_pathsPath\x12\x1b\n\x0e\x66irst_path_key\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x42\x11\n\x0f_first_scid_dirB\x0b\n\t_blindingB\x10\n\x0e_first_node_idB\r\n\x0b_first_scidB\x11\n\x0f_first_path_key\"S\n\x16\x44\x65\x63odeInvreq_pathsPath\x12\x17\n\x0f\x62linded_node_id\x18\x01 \x01(\x0c\x12 \n\x18\x65ncrypted_recipient_data\x18\x02 \x01(\x0c\"T\n\x17\x44\x65\x63odeInvoice_pathsPath\x12\x17\n\x0f\x62linded_node_id\x18\x01 \x01(\x0c\x12 \n\x18\x65ncrypted_recipient_data\x18\x02 \x01(\x0c\"Y\n\x17\x44\x65\x63odeInvoice_fallbacks\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x0b\n\x03hex\x18\x02 \x01(\x0c\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_address\"\xaa\x02\n\x0f\x44\x65\x63odeFallbacks\x12\x36\n)warning_invoice_fallbacks_version_invalid\x18\x01 \x01(\tH\x00\x88\x01\x01\x12;\n\titem_type\x18\x02 \x01(\x0e\x32(.cln.DecodeFallbacks.DecodeFallbacksType\x12\x11\n\x04\x61\x64\x64r\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x0b\n\x03hex\x18\x04 \x01(\x0c\"K\n\x13\x44\x65\x63odeFallbacksType\x12\t\n\x05P2PKH\x10\x00\x12\x08\n\x04P2SH\x10\x01\x12\n\n\x06P2WPKH\x10\x02\x12\t\n\x05P2WSH\x10\x03\x12\x08\n\x04P2TR\x10\x04\x42,\n*_warning_invoice_fallbacks_version_invalidB\x07\n\x05_addr\"(\n\x0b\x44\x65\x63odeExtra\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\";\n\x12\x44\x65\x63odeRestrictions\x12\x14\n\x0c\x61lternatives\x18\x01 \x03(\t\x12\x0f\n\x07summary\x18\x02 \x01(\t\"\xc2\x01\n\rDelpayRequest\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12/\n\x06status\x18\x02 \x01(\x0e\x32\x1f.cln.DelpayRequest.DelpayStatus\x12\x13\n\x06partid\x18\x03 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07groupid\x18\x04 \x01(\x04H\x01\x88\x01\x01\"(\n\x0c\x44\x65lpayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x42\t\n\x07_partidB\n\n\x08_groupid\"7\n\x0e\x44\x65lpayResponse\x12%\n\x08payments\x18\x01 \x03(\x0b\x32\x13.cln.DelpayPayments\"\xcb\x05\n\x0e\x44\x65lpayPayments\x12\x1a\n\rcreated_index\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\n\n\x02id\x18\x02 \x01(\x04\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x38\n\x06status\x18\x04 \x01(\x0e\x32(.cln.DelpayPayments.DelpayPaymentsStatus\x12%\n\x10\x61mount_sent_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x13\n\x06partid\x18\x06 \x01(\x04H\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x07 \x01(\x0cH\x02\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x12\n\ncreated_at\x18\t \x01(\x04\x12\x1a\n\rupdated_index\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\x0c \x01(\x04H\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x12\n\x05label\x18\x0e \x01(\tH\x08\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0f \x01(\tH\t\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x10 \x01(\tH\n\x88\x01\x01\x12\x17\n\nerroronion\x18\x11 \x01(\x0cH\x0b\x88\x01\x01\"=\n\x14\x44\x65lpayPaymentsStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x10\n\x0e_created_indexB\t\n\x07_partidB\x0e\n\x0c_destinationB\x0e\n\x0c_amount_msatB\x10\n\x0e_updated_indexB\x0f\n\r_completed_atB\n\n\x08_groupidB\x13\n\x11_payment_preimageB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\r\n\x0b_erroronion\"\xb3\x01\n\x11\x44\x65lforwardRequest\x12\x12\n\nin_channel\x18\x01 \x01(\t\x12\x12\n\nin_htlc_id\x18\x02 \x01(\x04\x12\x37\n\x06status\x18\x03 \x01(\x0e\x32\'.cln.DelforwardRequest.DelforwardStatus\"=\n\x10\x44\x65lforwardStatus\x12\x0b\n\x07SETTLED\x10\x00\x12\x10\n\x0cLOCAL_FAILED\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\"\x14\n\x12\x44\x65lforwardResponse\"\'\n\x13\x44isableofferRequest\x12\x10\n\x08offer_id\x18\x01 \x01(\x0c\"\x88\x01\n\x14\x44isableofferResponse\x12\x10\n\x08offer_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"=\n\x11\x44isconnectRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\x05\x66orce\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_force\"\x14\n\x12\x44isconnectResponse\"k\n\x0f\x46\x65\x65ratesRequest\x12\x31\n\x05style\x18\x01 \x01(\x0e\x32\".cln.FeeratesRequest.FeeratesStyle\"%\n\rFeeratesStyle\x12\t\n\x05PERKB\x10\x00\x12\t\n\x05PERKW\x10\x01\"\x9c\x02\n\x10\x46\x65\x65ratesResponse\x12%\n\x18warning_missing_feerates\x18\x01 \x01(\tH\x00\x88\x01\x01\x12&\n\x05perkb\x18\x02 \x01(\x0b\x32\x12.cln.FeeratesPerkbH\x01\x88\x01\x01\x12&\n\x05perkw\x18\x03 \x01(\x0b\x32\x12.cln.FeeratesPerkwH\x02\x88\x01\x01\x12\x46\n\x15onchain_fee_estimates\x18\x04 \x01(\x0b\x32\".cln.FeeratesOnchain_fee_estimatesH\x03\x88\x01\x01\x42\x1b\n\x19_warning_missing_feeratesB\x08\n\x06_perkbB\x08\n\x06_perkwB\x18\n\x16_onchain_fee_estimates\"\xd3\x03\n\rFeeratesPerkb\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x14\n\x07opening\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x03\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x05\x88\x01\x01\x12.\n\testimates\x18\t \x03(\x0b\x32\x1b.cln.FeeratesPerkbEstimates\x12\x12\n\x05\x66loor\x18\n \x01(\rH\x06\x88\x01\x01\x12$\n\x17unilateral_anchor_close\x18\x0b \x01(\rH\x07\x88\x01\x01\x42\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penaltyB\x08\n\x06_floorB\x1a\n\x18_unilateral_anchor_close\"W\n\x16\x46\x65\x65ratesPerkbEstimates\x12\x12\n\nblockcount\x18\x01 \x01(\r\x12\x0f\n\x07\x66\x65\x65rate\x18\x02 \x01(\r\x12\x18\n\x10smoothed_feerate\x18\x03 \x01(\r\"\xd3\x03\n\rFeeratesPerkw\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x14\n\x07opening\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x03\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x05\x88\x01\x01\x12.\n\testimates\x18\t \x03(\x0b\x32\x1b.cln.FeeratesPerkwEstimates\x12\x12\n\x05\x66loor\x18\n \x01(\rH\x06\x88\x01\x01\x12$\n\x17unilateral_anchor_close\x18\x0b \x01(\rH\x07\x88\x01\x01\x42\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penaltyB\x08\n\x06_floorB\x1a\n\x18_unilateral_anchor_close\"W\n\x16\x46\x65\x65ratesPerkwEstimates\x12\x12\n\nblockcount\x18\x01 \x01(\r\x12\x0f\n\x07\x66\x65\x65rate\x18\x02 \x01(\r\x12\x18\n\x10smoothed_feerate\x18\x03 \x01(\r\"\x9b\x02\n\x1d\x46\x65\x65ratesOnchain_fee_estimates\x12 \n\x18opening_channel_satoshis\x18\x01 \x01(\x04\x12\x1d\n\x15mutual_close_satoshis\x18\x02 \x01(\x04\x12!\n\x19unilateral_close_satoshis\x18\x03 \x01(\x04\x12\x1d\n\x15htlc_timeout_satoshis\x18\x04 \x01(\x04\x12\x1d\n\x15htlc_success_satoshis\x18\x05 \x01(\x04\x12\x30\n#unilateral_close_nonanchor_satoshis\x18\x06 \x01(\x04H\x00\x88\x01\x01\x42&\n$_unilateral_close_nonanchor_satoshis\"\xe9\x02\n\x13\x46\x65tchinvoiceRequest\x12\r\n\x05offer\x18\x01 \x01(\t\x12%\n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x15\n\x08quantity\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x1f\n\x12recurrence_counter\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x1d\n\x10recurrence_start\x18\x05 \x01(\x01H\x03\x88\x01\x01\x12\x1d\n\x10recurrence_label\x18\x06 \x01(\tH\x04\x88\x01\x01\x12\x14\n\x07timeout\x18\x07 \x01(\x01H\x05\x88\x01\x01\x12\x17\n\npayer_note\x18\x08 \x01(\tH\x06\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\x0b\n\t_quantityB\x15\n\x13_recurrence_counterB\x13\n\x11_recurrence_startB\x13\n\x11_recurrence_labelB\n\n\x08_timeoutB\r\n\x0b_payer_note\"\x9a\x01\n\x14\x46\x65tchinvoiceResponse\x12\x0f\n\x07invoice\x18\x01 \x01(\t\x12)\n\x07\x63hanges\x18\x02 \x01(\x0b\x32\x18.cln.FetchinvoiceChanges\x12\x36\n\x0bnext_period\x18\x03 \x01(\x0b\x32\x1c.cln.FetchinvoiceNext_periodH\x00\x88\x01\x01\x42\x0e\n\x0c_next_period\"\x82\x02\n\x13\x46\x65tchinvoiceChanges\x12!\n\x14\x64\x65scription_appended\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1b\n\x0evendor_removed\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06vendor\x18\x04 \x01(\tH\x03\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x42\x17\n\x15_description_appendedB\x0e\n\x0c_descriptionB\x11\n\x0f_vendor_removedB\t\n\x07_vendorB\x0e\n\x0c_amount_msat\"~\n\x17\x46\x65tchinvoiceNext_period\x12\x0f\n\x07\x63ounter\x18\x01 \x01(\x04\x12\x11\n\tstarttime\x18\x02 \x01(\x04\x12\x0f\n\x07\x65ndtime\x18\x03 \x01(\x04\x12\x17\n\x0fpaywindow_start\x18\x04 \x01(\x04\x12\x15\n\rpaywindow_end\x18\x05 \x01(\x04\"\'\n\x19\x46undchannel_cancelRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\"/\n\x1a\x46undchannel_cancelResponse\x12\x11\n\tcancelled\x18\x01 \x01(\t\"7\n\x1b\x46undchannel_completeRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\"O\n\x1c\x46undchannel_completeResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x1b\n\x13\x63ommitments_secured\x18\x02 \x01(\x08\"\xfb\x03\n\x12\x46undchannelRequest\x12 \n\x06\x61mount\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x15\n\x08\x61nnounce\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12#\n\tpush_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x06 \x01(\tH\x03\x88\x01\x01\x12%\n\x0brequest_amt\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x08 \x01(\tH\x05\x88\x01\x01\x12\n\n\x02id\x18\t \x01(\x0c\x12\x14\n\x07minconf\x18\n \x01(\rH\x06\x88\x01\x01\x12\x1c\n\x05utxos\x18\x0b \x03(\x0b\x32\r.cln.Outpoint\x12\x15\n\x08mindepth\x18\x0c \x01(\rH\x07\x88\x01\x01\x12!\n\x07reserve\x18\r \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x14\n\x0c\x63hannel_type\x18\x0e \x03(\rB\n\n\x08_feerateB\x0b\n\t_announceB\x0c\n\n_push_msatB\x0b\n\t_close_toB\x0e\n\x0c_request_amtB\x10\n\x0e_compact_leaseB\n\n\x08_minconfB\x0b\n\t_mindepthB\n\n\x08_reserve\"\xe5\x01\n\x13\x46undchannelResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x0e\n\x06outnum\x18\x03 \x01(\r\x12\x12\n\nchannel_id\x18\x04 \x01(\x0c\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\x0cH\x00\x88\x01\x01\x12\x15\n\x08mindepth\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x37\n\x0c\x63hannel_type\x18\x07 \x01(\x0b\x32\x1c.cln.FundchannelChannel_typeH\x02\x88\x01\x01\x42\x0b\n\t_close_toB\x0b\n\t_mindepthB\x0f\n\r_channel_type\"L\n\x17\x46undchannelChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"\xd7\x02\n\x18\x46undchannel_startRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x1b\n\x06\x61mount\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\"\n\x07\x66\x65\x65rate\x18\x03 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x15\n\x08\x61nnounce\x18\x04 \x01(\x08H\x01\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\tH\x02\x88\x01\x01\x12#\n\tpush_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x15\n\x08mindepth\x18\x07 \x01(\rH\x04\x88\x01\x01\x12!\n\x07reserve\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x0c\x63hannel_type\x18\t \x03(\rB\n\n\x08_feerateB\x0b\n\t_announceB\x0b\n\t_close_toB\x0c\n\n_push_msatB\x0b\n\t_mindepthB\n\n\x08_reserve\"\xf9\x01\n\x19\x46undchannel_startResponse\x12\x17\n\x0f\x66unding_address\x18\x01 \x01(\t\x12\x14\n\x0cscriptpubkey\x18\x02 \x01(\x0c\x12=\n\x0c\x63hannel_type\x18\x03 \x01(\x0b\x32\".cln.Fundchannel_startChannel_typeH\x00\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x04 \x01(\x0cH\x01\x88\x01\x01\x12\x15\n\rwarning_usage\x18\x05 \x01(\t\x12\x15\n\x08mindepth\x18\x06 \x01(\rH\x02\x88\x01\x01\x42\x0f\n\r_channel_typeB\x0b\n\t_close_toB\x0b\n\t_mindepth\"R\n\x1d\x46undchannel_startChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"\x9d\x01\n\rGetlogRequest\x12\x32\n\x05level\x18\x01 \x01(\x0e\x32\x1e.cln.GetlogRequest.GetlogLevelH\x00\x88\x01\x01\"N\n\x0bGetlogLevel\x12\n\n\x06\x42ROKEN\x10\x00\x12\x0b\n\x07UNUSUAL\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\t\n\x05\x44\x45\x42UG\x10\x03\x12\x06\n\x02IO\x10\x04\x12\t\n\x05TRACE\x10\x05\x42\x08\n\x06_level\"h\n\x0eGetlogResponse\x12\x12\n\ncreated_at\x18\x01 \x01(\t\x12\x12\n\nbytes_used\x18\x02 \x01(\r\x12\x11\n\tbytes_max\x18\x03 \x01(\r\x12\x1b\n\x03log\x18\x04 \x03(\x0b\x32\x0e.cln.GetlogLog\"\xe8\x02\n\tGetlogLog\x12/\n\titem_type\x18\x01 \x01(\x0e\x32\x1c.cln.GetlogLog.GetlogLogType\x12\x18\n\x0bnum_skipped\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04time\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06source\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x10\n\x03log\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x07node_id\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x11\n\x04\x64\x61ta\x18\x07 \x01(\x0cH\x05\x88\x01\x01\"l\n\rGetlogLogType\x12\x0b\n\x07SKIPPED\x10\x00\x12\n\n\x06\x42ROKEN\x10\x01\x12\x0b\n\x07UNUSUAL\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\t\n\x05\x44\x45\x42UG\x10\x04\x12\t\n\x05IO_IN\x10\x05\x12\n\n\x06IO_OUT\x10\x06\x12\t\n\x05TRACE\x10\x07\x42\x0e\n\x0c_num_skippedB\x07\n\x05_timeB\t\n\x07_sourceB\x06\n\x04_logB\n\n\x08_node_idB\x07\n\x05_data\"\xd9\x08\n\x13\x46underupdateRequest\x12@\n\x06policy\x18\x01 \x01(\x0e\x32+.cln.FunderupdateRequest.FunderupdatePolicyH\x00\x88\x01\x01\x12$\n\npolicy_mod\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0bleases_only\x18\x03 \x01(\x08H\x02\x88\x01\x01\x12\x30\n\x16min_their_funding_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x30\n\x16max_their_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12.\n\x14per_channel_min_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12.\n\x14per_channel_max_msat\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12+\n\x11reserve_tank_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x07\x88\x01\x01\x12\x19\n\x0c\x66uzz_percent\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1d\n\x10\x66und_probability\x18\n \x01(\rH\t\x88\x01\x01\x12-\n\x13lease_fee_base_msat\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\n\x88\x01\x01\x12\x1c\n\x0flease_fee_basis\x18\x0c \x01(\rH\x0b\x88\x01\x01\x12\x1b\n\x0e\x66unding_weight\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x33\n\x19\x63hannel_fee_max_base_msat\x18\x0e \x01(\x0b\x32\x0b.cln.AmountH\r\x88\x01\x01\x12\x35\n(channel_fee_max_proportional_thousandths\x18\x0f \x01(\rH\x0e\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x10 \x01(\x0cH\x0f\x88\x01\x01\"9\n\x12\x46underupdatePolicy\x12\t\n\x05MATCH\x10\x00\x12\r\n\tAVAILABLE\x10\x01\x12\t\n\x05\x46IXED\x10\x02\x42\t\n\x07_policyB\r\n\x0b_policy_modB\x0e\n\x0c_leases_onlyB\x19\n\x17_min_their_funding_msatB\x19\n\x17_max_their_funding_msatB\x17\n\x15_per_channel_min_msatB\x17\n\x15_per_channel_max_msatB\x14\n\x12_reserve_tank_msatB\x0f\n\r_fuzz_percentB\x13\n\x11_fund_probabilityB\x16\n\x14_lease_fee_base_msatB\x12\n\x10_lease_fee_basisB\x11\n\x0f_funding_weightB\x1c\n\x1a_channel_fee_max_base_msatB+\n)_channel_fee_max_proportional_thousandthsB\x10\n\x0e_compact_lease\"\xdf\x06\n\x14\x46underupdateResponse\x12\x0f\n\x07summary\x18\x01 \x01(\t\x12<\n\x06policy\x18\x02 \x01(\x0e\x32,.cln.FunderupdateResponse.FunderupdatePolicy\x12\x12\n\npolicy_mod\x18\x03 \x01(\r\x12\x13\n\x0bleases_only\x18\x04 \x01(\x08\x12+\n\x16min_their_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x16max_their_funding_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12)\n\x14per_channel_min_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12)\n\x14per_channel_max_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11reserve_tank_msat\x18\t \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0c\x66uzz_percent\x18\n \x01(\r\x12\x18\n\x10\x66und_probability\x18\x0b \x01(\r\x12-\n\x13lease_fee_base_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x1c\n\x0flease_fee_basis\x18\r \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0e\x66unding_weight\x18\x0e \x01(\rH\x02\x88\x01\x01\x12\x33\n\x19\x63hannel_fee_max_base_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x35\n(channel_fee_max_proportional_thousandths\x18\x10 \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x11 \x01(\x0cH\x05\x88\x01\x01\"9\n\x12\x46underupdatePolicy\x12\t\n\x05MATCH\x10\x00\x12\r\n\tAVAILABLE\x10\x01\x12\t\n\x05\x46IXED\x10\x02\x42\x16\n\x14_lease_fee_base_msatB\x12\n\x10_lease_fee_basisB\x11\n\x0f_funding_weightB\x1c\n\x1a_channel_fee_max_base_msatB+\n)_channel_fee_max_proportional_thousandthsB\x10\n\x0e_compact_lease\"\xec\x01\n\x0fGetrouteRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\nriskfactor\x18\x03 \x01(\x04\x12\x11\n\x04\x63ltv\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x13\n\x06\x66romid\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x66uzzpercent\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\x07 \x03(\t\x12\x14\n\x07maxhops\x18\x08 \x01(\rH\x03\x88\x01\x01\x12 \n\x0b\x61mount_msat\x18\t \x01(\x0b\x32\x0b.cln.AmountB\x07\n\x05_cltvB\t\n\x07_fromidB\x0e\n\x0c_fuzzpercentB\n\n\x08_maxhops\"5\n\x10GetrouteResponse\x12!\n\x05route\x18\x01 \x03(\x0b\x32\x12.cln.GetrouteRoute\"\xc5\x01\n\rGetrouteRoute\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\t\x12\x11\n\tdirection\x18\x03 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x05 \x01(\r\x12\x34\n\x05style\x18\x06 \x01(\x0e\x32%.cln.GetrouteRoute.GetrouteRouteStyle\"\x1d\n\x12GetrouteRouteStyle\x12\x07\n\x03TLV\x10\x00\"\xb7\x03\n\x13ListforwardsRequest\x12@\n\x06status\x18\x01 \x01(\x0e\x32+.cln.ListforwardsRequest.ListforwardsStatusH\x00\x88\x01\x01\x12\x17\n\nin_channel\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bout_channel\x18\x03 \x01(\tH\x02\x88\x01\x01\x12>\n\x05index\x18\x04 \x01(\x0e\x32*.cln.ListforwardsRequest.ListforwardsIndexH\x03\x88\x01\x01\x12\x12\n\x05start\x18\x05 \x01(\x04H\x04\x88\x01\x01\x12\x12\n\x05limit\x18\x06 \x01(\rH\x05\x88\x01\x01\"L\n\x12ListforwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"-\n\x11ListforwardsIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\t\n\x07_statusB\r\n\x0b_in_channelB\x0e\n\x0c_out_channelB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListforwardsResponse\x12+\n\x08\x66orwards\x18\x01 \x03(\x0b\x32\x19.cln.ListforwardsForwards\"\xb4\x06\n\x14ListforwardsForwards\x12\x12\n\nin_channel\x18\x01 \x01(\t\x12\x1c\n\x07in_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x44\n\x06status\x18\x03 \x01(\x0e\x32\x34.cln.ListforwardsForwards.ListforwardsForwardsStatus\x12\x15\n\rreceived_time\x18\x04 \x01(\x01\x12\x18\n\x0bout_channel\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\"\n\x08\x66\x65\x65_msat\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\"\n\x08out_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12G\n\x05style\x18\t \x01(\x0e\x32\x33.cln.ListforwardsForwards.ListforwardsForwardsStyleH\x03\x88\x01\x01\x12\x17\n\nin_htlc_id\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x18\n\x0bout_htlc_id\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x0c \x01(\x04H\x06\x88\x01\x01\x12\x1a\n\rupdated_index\x18\r \x01(\x04H\x07\x88\x01\x01\x12\x1a\n\rresolved_time\x18\x0e \x01(\x01H\x08\x88\x01\x01\x12\x15\n\x08\x66\x61ilcode\x18\x0f \x01(\rH\t\x88\x01\x01\x12\x17\n\nfailreason\x18\x10 \x01(\tH\n\x88\x01\x01\"T\n\x1aListforwardsForwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"0\n\x19ListforwardsForwardsStyle\x12\n\n\x06LEGACY\x10\x00\x12\x07\n\x03TLV\x10\x01\x42\x0e\n\x0c_out_channelB\x0b\n\t_fee_msatB\x0b\n\t_out_msatB\x08\n\x06_styleB\r\n\x0b_in_htlc_idB\x0e\n\x0c_out_htlc_idB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x10\n\x0e_resolved_timeB\x0b\n\t_failcodeB\r\n\x0b_failreason\"a\n\x11ListoffersRequest\x12\x15\n\x08offer_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x18\n\x0b\x61\x63tive_only\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\x0b\n\t_offer_idB\x0e\n\x0c_active_only\";\n\x12ListoffersResponse\x12%\n\x06offers\x18\x01 \x03(\x0b\x32\x15.cln.ListoffersOffers\"\x84\x01\n\x10ListoffersOffers\x12\x10\n\x08offer_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x12\n\x05label\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\"\xdb\x01\n\x0fListpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x38\n\x06status\x18\x03 \x01(\x0e\x32#.cln.ListpaysRequest.ListpaysStatusH\x02\x88\x01\x01\"7\n\x0eListpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_status\"3\n\x10ListpaysResponse\x12\x1f\n\x04pays\x18\x01 \x03(\x0b\x32\x11.cln.ListpaysPays\"\xff\x04\n\x0cListpaysPays\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x34\n\x06status\x18\x02 \x01(\x0e\x32$.cln.ListpaysPays.ListpaysPaysStatus\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\ncreated_at\x18\x04 \x01(\x04\x12\x12\n\x05label\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x07 \x01(\tH\x03\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12*\n\x10\x61mount_sent_msat\x18\t \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x17\n\nerroronion\x18\n \x01(\x0cH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0b \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0c \x01(\x04H\x08\x88\x01\x01\x12\x15\n\x08preimage\x18\r \x01(\x0cH\t\x88\x01\x01\x12\x1c\n\x0fnumber_of_parts\x18\x0e \x01(\x04H\n\x88\x01\x01\";\n\x12ListpaysPaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x13\n\x11_amount_sent_msatB\r\n\x0b_erroronionB\x0e\n\x0c_descriptionB\x0f\n\r_completed_atB\x0b\n\t_preimageB\x12\n\x10_number_of_parts\"*\n\x10ListhtlcsRequest\x12\x0f\n\x02id\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x05\n\x03_id\"7\n\x11ListhtlcsResponse\x12\"\n\x05htlcs\x18\x01 \x03(\x0b\x32\x13.cln.ListhtlcsHtlcs\"\x89\x02\n\x0eListhtlcsHtlcs\x12\x18\n\x10short_channel_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\x04\x12\x0e\n\x06\x65xpiry\x18\x03 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12>\n\tdirection\x18\x05 \x01(\x0e\x32+.cln.ListhtlcsHtlcs.ListhtlcsHtlcsDirection\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x1d\n\x05state\x18\x07 \x01(\x0e\x32\x0e.cln.HtlcState\"*\n\x17ListhtlcsHtlcsDirection\x12\x07\n\x03OUT\x10\x00\x12\x06\n\x02IN\x10\x01\"\xb2\x02\n\x17MultifundchannelRequest\x12\x37\n\x0c\x64\x65stinations\x18\x01 \x03(\x0b\x32!.cln.MultifundchannelDestinations\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\x12H\x01\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12\x18\n\x0bminchannels\x18\x05 \x01(\x12H\x02\x88\x01\x01\x12-\n\x12\x63ommitment_feerate\x18\x06 \x01(\x0b\x32\x0c.cln.FeerateH\x03\x88\x01\x01\x42\n\n\x08_feerateB\n\n\x08_minconfB\x0e\n\x0c_minchannelsB\x15\n\x13_commitment_feerate\"\x98\x01\n\x18MultifundchannelResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x35\n\x0b\x63hannel_ids\x18\x03 \x03(\x0b\x32 .cln.MultifundchannelChannel_ids\x12+\n\x06\x66\x61iled\x18\x04 \x03(\x0b\x32\x1b.cln.MultifundchannelFailed\"\xff\x02\n\x1cMultifundchannelDestinations\x12\n\n\x02id\x18\x01 \x01(\t\x12 \n\x06\x61mount\x18\x02 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x15\n\x08\x61nnounce\x18\x03 \x01(\x08H\x00\x88\x01\x01\x12#\n\tpush_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\tH\x02\x88\x01\x01\x12%\n\x0brequest_amt\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x07 \x01(\tH\x04\x88\x01\x01\x12\x15\n\x08mindepth\x18\x08 \x01(\rH\x05\x88\x01\x01\x12!\n\x07reserve\x18\t \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x42\x0b\n\t_announceB\x0c\n\n_push_msatB\x0b\n\t_close_toB\x0e\n\x0c_request_amtB\x10\n\x0e_compact_leaseB\x0b\n\t_mindepthB\n\n\x08_reserve\"\xcb\x01\n\x1bMultifundchannelChannel_ids\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r\x12\x12\n\nchannel_id\x18\x03 \x01(\x0c\x12G\n\x0c\x63hannel_type\x18\x04 \x01(\x0b\x32,.cln.MultifundchannelChannel_idsChannel_typeH\x00\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x42\x0f\n\r_channel_typeB\x0b\n\t_close_to\"\\\n\'MultifundchannelChannel_idsChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"\x93\x02\n\x16MultifundchannelFailed\x12\n\n\x02id\x18\x01 \x01(\x0c\x12H\n\x06method\x18\x02 \x01(\x0e\x32\x38.cln.MultifundchannelFailed.MultifundchannelFailedMethod\x12/\n\x05\x65rror\x18\x03 \x01(\x0b\x32 .cln.MultifundchannelFailedError\"r\n\x1cMultifundchannelFailedMethod\x12\x0b\n\x07\x43ONNECT\x10\x00\x12\x14\n\x10OPENCHANNEL_INIT\x10\x01\x12\x15\n\x11\x46UNDCHANNEL_START\x10\x02\x12\x18\n\x14\x46UNDCHANNEL_COMPLETE\x10\x03\"<\n\x1bMultifundchannelFailedError\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x12\x12\x0f\n\x07message\x18\x02 \x01(\t\"\xa8\x01\n\x14MultiwithdrawRequest\x12 \n\x07outputs\x18\x01 \x03(\x0b\x32\x0f.cln.OutputDesc\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.OutpointB\n\n\x08_feerateB\n\n\x08_minconf\"1\n\x15MultiwithdrawResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"\xa0\x04\n\x0cOfferRequest\x12\x0e\n\x06\x61mount\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06issuer\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05label\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x19\n\x0cquantity_max\x18\x05 \x01(\x04H\x03\x88\x01\x01\x12\x1c\n\x0f\x61\x62solute_expiry\x18\x06 \x01(\x04H\x04\x88\x01\x01\x12\x17\n\nrecurrence\x18\x07 \x01(\tH\x05\x88\x01\x01\x12\x1c\n\x0frecurrence_base\x18\x08 \x01(\tH\x06\x88\x01\x01\x12!\n\x14recurrence_paywindow\x18\t \x01(\tH\x07\x88\x01\x01\x12\x1d\n\x10recurrence_limit\x18\n \x01(\rH\x08\x88\x01\x01\x12\x17\n\nsingle_use\x18\x0b \x01(\x08H\t\x88\x01\x01\x12(\n\x1brecurrence_start_any_period\x18\x0c \x01(\x08H\n\x88\x01\x01\x42\x0e\n\x0c_descriptionB\t\n\x07_issuerB\x08\n\x06_labelB\x0f\n\r_quantity_maxB\x12\n\x10_absolute_expiryB\r\n\x0b_recurrenceB\x12\n\x10_recurrence_baseB\x17\n\x15_recurrence_paywindowB\x13\n\x11_recurrence_limitB\r\n\x0b_single_useB\x1e\n\x1c_recurrence_start_any_period\"\x92\x01\n\rOfferResponse\x12\x10\n\x08offer_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x12\n\nsingle_use\x18\x03 \x01(\x08\x12\x0e\n\x06\x62olt12\x18\x04 \x01(\t\x12\x0c\n\x04used\x18\x05 \x01(\x08\x12\x0f\n\x07\x63reated\x18\x06 \x01(\x08\x12\x12\n\x05label\x18\x07 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_label\".\n\x18Openchannel_abortRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\"Y\n\x19Openchannel_abortResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x18\n\x10\x63hannel_canceled\x18\x02 \x01(\x08\x12\x0e\n\x06reason\x18\x03 \x01(\t\"\x9f\x01\n\x17Openchannel_bumpRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x13\n\x0binitialpsbt\x18\x02 \x01(\t\x12*\n\x0f\x66unding_feerate\x18\x03 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x1b\n\x06\x61mount\x18\x04 \x01(\x0b\x32\x0b.cln.AmountB\x12\n\x10_funding_feerate\"\x86\x02\n\x18Openchannel_bumpResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12<\n\x0c\x63hannel_type\x18\x02 \x01(\x0b\x32!.cln.Openchannel_bumpChannel_typeH\x00\x88\x01\x01\x12\x0c\n\x04psbt\x18\x03 \x01(\t\x12\x1b\n\x13\x63ommitments_secured\x18\x04 \x01(\x08\x12\x16\n\x0e\x66unding_serial\x18\x05 \x01(\x04\x12&\n\x19requires_confirmed_inputs\x18\x06 \x01(\x08H\x01\x88\x01\x01\x42\x0f\n\r_channel_typeB\x1c\n\x1a_requires_confirmed_inputs\"Q\n\x1cOpenchannel_bumpChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"\xa0\x03\n\x17Openchannel_initRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x13\n\x0binitialpsbt\x18\x02 \x01(\t\x12-\n\x12\x63ommitment_feerate\x18\x03 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12*\n\x0f\x66unding_feerate\x18\x04 \x01(\x0b\x32\x0c.cln.FeerateH\x01\x88\x01\x01\x12\x15\n\x08\x61nnounce\x18\x05 \x01(\x08H\x02\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x06 \x01(\tH\x03\x88\x01\x01\x12%\n\x0brequest_amt\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x08 \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x0c\x63hannel_type\x18\t \x03(\r\x12\x1b\n\x06\x61mount\x18\n \x01(\x0b\x32\x0b.cln.AmountB\x15\n\x13_commitment_feerateB\x12\n\x10_funding_feerateB\x0b\n\t_announceB\x0b\n\t_close_toB\x0e\n\x0c_request_amtB\x10\n\x0e_compact_lease\"\x86\x02\n\x18Openchannel_initResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\x12<\n\x0c\x63hannel_type\x18\x03 \x01(\x0b\x32!.cln.Openchannel_initChannel_typeH\x00\x88\x01\x01\x12\x1b\n\x13\x63ommitments_secured\x18\x04 \x01(\x08\x12\x16\n\x0e\x66unding_serial\x18\x05 \x01(\x04\x12&\n\x19requires_confirmed_inputs\x18\x06 \x01(\x08H\x01\x88\x01\x01\x42\x0f\n\r_channel_typeB\x1c\n\x1a_requires_confirmed_inputs\"Q\n\x1cOpenchannel_initChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"D\n\x19Openchannel_signedRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x13\n\x0bsigned_psbt\x18\x02 \x01(\t\"J\n\x1aOpenchannel_signedResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\n\n\x02tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"=\n\x19Openchannel_updateRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\"\xae\x02\n\x1aOpenchannel_updateResponse\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12>\n\x0c\x63hannel_type\x18\x02 \x01(\x0b\x32#.cln.Openchannel_updateChannel_typeH\x00\x88\x01\x01\x12\x0c\n\x04psbt\x18\x03 \x01(\t\x12\x1b\n\x13\x63ommitments_secured\x18\x04 \x01(\x08\x12\x16\n\x0e\x66unding_outnum\x18\x05 \x01(\r\x12\x15\n\x08\x63lose_to\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12&\n\x19requires_confirmed_inputs\x18\x07 \x01(\x08H\x02\x88\x01\x01\x42\x0f\n\r_channel_typeB\x0b\n\t_close_toB\x1c\n\x1a_requires_confirmed_inputs\"S\n\x1eOpenchannel_updateChannel_type\x12\x0c\n\x04\x62its\x18\x01 \x03(\r\x12#\n\x05names\x18\x02 \x03(\x0e\x32\x14.cln.ChannelTypeName\"Y\n\x0bPingRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x03len\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x16\n\tpongbytes\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x06\n\x04_lenB\x0c\n\n_pongbytes\"\x1e\n\x0cPingResponse\x12\x0e\n\x06totlen\x18\x01 \x01(\r\"\x91\x01\n\rPluginRequest\x12)\n\nsubcommand\x18\x01 \x01(\x0e\x32\x15.cln.PluginSubcommand\x12\x13\n\x06plugin\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tdirectory\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x0f\n\x07options\x18\x04 \x03(\tB\t\n\x07_pluginB\x0c\n\n_directory\"}\n\x0ePluginResponse\x12&\n\x07\x63ommand\x18\x01 \x01(\x0e\x32\x15.cln.PluginSubcommand\x12#\n\x07plugins\x18\x02 \x03(\x0b\x32\x12.cln.PluginPlugins\x12\x13\n\x06result\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_result\">\n\rPluginPlugins\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x61\x63tive\x18\x02 \x01(\x08\x12\x0f\n\x07\x64ynamic\x18\x03 \x01(\x08\"<\n\x14RenepaystatusRequest\x12\x16\n\tinvstring\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_invstring\"G\n\x15RenepaystatusResponse\x12.\n\tpaystatus\x18\x01 \x03(\x0b\x32\x1b.cln.RenepaystatusPaystatus\"\xe2\x03\n\x16RenepaystatusPaystatus\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x1d\n\x10payment_preimage\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\x0f\n\x07groupid\x18\x05 \x01(\r\x12\x12\n\x05parts\x18\x06 \x01(\rH\x01\x88\x01\x01\x12 \n\x0b\x61mount_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12*\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12H\n\x06status\x18\t \x01(\x0e\x32\x38.cln.RenepaystatusPaystatus.RenepaystatusPaystatusStatus\x12\x18\n\x0b\x64\x65stination\x18\n \x01(\x0cH\x03\x88\x01\x01\x12\r\n\x05notes\x18\x0b \x03(\t\"E\n\x1cRenepaystatusPaystatusStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\x13\n\x11_payment_preimageB\x08\n\x06_partsB\x13\n\x11_amount_sent_msatB\x0e\n\x0c_destination\"\xda\x02\n\x0eRenepayRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\x12%\n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12 \n\x06maxfee\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x04 \x01(\rH\x02\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x06 \x01(\tH\x04\x88\x01\x01\x12\x12\n\x05label\x18\x07 \x01(\tH\x05\x88\x01\x01\x12\x1b\n\x0e\x64\x65v_use_shadow\x18\x08 \x01(\x08H\x06\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\t \x03(\tB\x0e\n\x0c_amount_msatB\t\n\x07_maxfeeB\x0b\n\t_maxdelayB\x0c\n\n_retry_forB\x0e\n\x0c_descriptionB\x08\n\x06_labelB\x11\n\x0f_dev_use_shadow\"\xa5\x03\n\x0fRenepayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\ncreated_at\x18\x03 \x01(\x01\x12\r\n\x05parts\x18\x04 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12\x32\n\x06status\x18\x07 \x01(\x0e\x32\".cln.RenepayResponse.RenepayStatus\x12\x18\n\x0b\x64\x65stination\x18\x08 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\t \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\n \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07groupid\x18\x0b \x01(\x04H\x03\x88\x01\x01\"6\n\rRenepayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\x0e\n\x0c_destinationB\t\n\x07_bolt11B\t\n\x07_bolt12B\n\n\x08_groupid\"l\n\x14ReserveinputsRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\texclusive\x18\x02 \x01(\x08H\x00\x88\x01\x01\x12\x14\n\x07reserve\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x0c\n\n_exclusiveB\n\n\x08_reserve\"M\n\x15ReserveinputsResponse\x12\x34\n\x0creservations\x18\x01 \x03(\x0b\x32\x1e.cln.ReserveinputsReservations\"z\n\x19ReserveinputsReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\"4\n\x14SendcustommsgRequest\x12\x0f\n\x07node_id\x18\x01 \x01(\x0c\x12\x0b\n\x03msg\x18\x02 \x01(\x0c\"\'\n\x15SendcustommsgResponse\x12\x0e\n\x06status\x18\x01 \x01(\t\"\xb0\x01\n\x12SendinvoiceRequest\x12\x0e\n\x06invreq\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12%\n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x14\n\x07timeout\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08quantity\x18\x05 \x01(\x04H\x02\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\n\n\x08_timeoutB\x0b\n\t_quantity\"\xcf\x04\n\x13SendinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.SendinvoiceResponse.SendinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x08 \x01(\x04H\x02\x88\x01\x01\x12\x1a\n\rupdated_index\x18\t \x01(\x04H\x03\x88\x01\x01\x12\x16\n\tpay_index\x18\n \x01(\x04H\x04\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0c \x01(\x04H\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01\"6\n\x11SendinvoiceStatus\x12\n\n\x06UNPAID\x10\x00\x12\x08\n\x04PAID\x10\x01\x12\x0b\n\x07\x45XPIRED\x10\x02\x42\x0e\n\x0c_amount_msatB\t\n\x07_bolt12B\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimage\"\xaa\x02\n\x11SetchannelRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12!\n\x07\x66\x65\x65\x62\x61se\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x66\x65\x65ppm\x18\x03 \x01(\rH\x01\x88\x01\x01\x12!\n\x07htlcmin\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12!\n\x07htlcmax\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x19\n\x0c\x65nforcedelay\x18\x06 \x01(\rH\x04\x88\x01\x01\x12\x1c\n\x0fignorefeelimits\x18\x07 \x01(\x08H\x05\x88\x01\x01\x42\n\n\x08_feebaseB\t\n\x07_feeppmB\n\n\x08_htlcminB\n\n\x08_htlcmaxB\x0f\n\r_enforcedelayB\x12\n\x10_ignorefeelimits\"?\n\x12SetchannelResponse\x12)\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x17.cln.SetchannelChannels\"\xca\x03\n\x12SetchannelChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x12\n\nchannel_id\x18\x02 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\"\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\r\x12*\n\x15minimum_htlc_out_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x17warning_htlcmin_too_low\x18\x07 \x01(\tH\x01\x88\x01\x01\x12*\n\x15maximum_htlc_out_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x18warning_htlcmax_too_high\x18\t \x01(\tH\x02\x88\x01\x01\x12\x1e\n\x11ignore_fee_limits\x18\n \x01(\x08H\x03\x88\x01\x01\x42\x13\n\x11_short_channel_idB\x1a\n\x18_warning_htlcmin_too_lowB\x1b\n\x19_warning_htlcmax_too_highB\x14\n\x12_ignore_fee_limits\"<\n\x10SetconfigRequest\x12\x0e\n\x06\x63onfig\x18\x01 \x01(\t\x12\x10\n\x03val\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x06\n\x04_val\"9\n\x11SetconfigResponse\x12$\n\x06\x63onfig\x18\x01 \x01(\x0b\x32\x14.cln.SetconfigConfig\"\xa5\x02\n\x0fSetconfigConfig\x12\x0e\n\x06\x63onfig\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x13\n\x06plugin\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x0f\n\x07\x64ynamic\x18\x04 \x01(\x08\x12\x10\n\x03set\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12\x16\n\tvalue_str\x18\x06 \x01(\tH\x02\x88\x01\x01\x12$\n\nvalue_msat\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x16\n\tvalue_int\x18\x08 \x01(\x12H\x04\x88\x01\x01\x12\x17\n\nvalue_bool\x18\t \x01(\x08H\x05\x88\x01\x01\x42\t\n\x07_pluginB\x06\n\x04_setB\x0c\n\n_value_strB\r\n\x0b_value_msatB\x0c\n\n_value_intB\r\n\x0b_value_bool\"6\n\x15SetpsbtversionRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\r\"&\n\x16SetpsbtversionResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\"\'\n\x12SigninvoiceRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\"%\n\x13SigninvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\"%\n\x12SignmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t\"F\n\x13SignmessageResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\x12\r\n\x05recid\x18\x02 \x01(\x0c\x12\r\n\x05zbase\x18\x03 \x01(\t\"\xc9\x01\n\x12Splice_initRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x17\n\x0frelative_amount\x18\x02 \x01(\x12\x12\x18\n\x0binitialpsbt\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x1b\n\x0e\x66\x65\x65rate_per_kw\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x1a\n\rforce_feerate\x18\x05 \x01(\x08H\x02\x88\x01\x01\x42\x0e\n\x0c_initialpsbtB\x11\n\x0f_feerate_per_kwB\x10\n\x0e_force_feerate\"#\n\x13Splice_initResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\"`\n\x14Splice_signedRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\x12\x17\n\nsign_first\x18\x03 \x01(\x08H\x00\x88\x01\x01\x42\r\n\x0b_sign_first\"_\n\x15Splice_signedResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x13\n\x06outnum\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x0c\n\x04psbt\x18\x04 \x01(\tB\t\n\x07_outnum\"8\n\x14Splice_updateRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x0c\n\x04psbt\x18\x02 \x01(\t\"z\n\x15Splice_updateResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x1b\n\x13\x63ommitments_secured\x18\x02 \x01(\x08\x12\x1f\n\x12signatures_secured\x18\x03 \x01(\x08H\x00\x88\x01\x01\x42\x15\n\x13_signatures_secured\"H\n\x16UnreserveinputsRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x14\n\x07reserve\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\n\n\x08_reserve\"Q\n\x17UnreserveinputsResponse\x12\x36\n\x0creservations\x18\x01 \x03(\x0b\x32 .cln.UnreserveinputsReservations\"\x97\x01\n\x1bUnreserveinputsReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x1e\n\x11reserved_to_block\x18\x05 \x01(\rH\x00\x88\x01\x01\x42\x14\n\x12_reserved_to_block\"n\n\x14UpgradewalletRequest\x12\"\n\x07\x66\x65\x65rate\x18\x01 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x17\n\nreservedok\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\n\n\x08_feerateB\r\n\x0b_reservedok\"\x95\x01\n\x15UpgradewalletResponse\x12\x1a\n\rupgraded_outs\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x11\n\x04psbt\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x0f\n\x02tx\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x11\n\x04txid\x18\x04 \x01(\x0cH\x03\x88\x01\x01\x42\x10\n\x0e_upgraded_outsB\x07\n\x05_psbtB\x05\n\x03_txB\x07\n\x05_txid\"O\n\x16WaitblockheightRequest\x12\x13\n\x0b\x62lockheight\x18\x01 \x01(\r\x12\x14\n\x07timeout\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\n\n\x08_timeout\".\n\x17WaitblockheightResponse\x12\x13\n\x0b\x62lockheight\x18\x01 \x01(\r\"\xf9\x01\n\x0bWaitRequest\x12\x31\n\tsubsystem\x18\x01 \x01(\x0e\x32\x1e.cln.WaitRequest.WaitSubsystem\x12\x31\n\tindexname\x18\x02 \x01(\x0e\x32\x1e.cln.WaitRequest.WaitIndexname\x12\x11\n\tnextvalue\x18\x03 \x01(\x04\"9\n\rWaitSubsystem\x12\x0c\n\x08INVOICES\x10\x00\x12\x0c\n\x08\x46ORWARDS\x10\x01\x12\x0c\n\x08SENDPAYS\x10\x02\"6\n\rWaitIndexname\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x12\x0b\n\x07\x44\x45LETED\x10\x02\"\x97\x02\n\x0cWaitResponse\x12\x32\n\tsubsystem\x18\x01 \x01(\x0e\x32\x1f.cln.WaitResponse.WaitSubsystem\x12\x14\n\x07\x63reated\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07updated\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07\x64\x65leted\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12&\n\x07\x64\x65tails\x18\x05 \x01(\x0b\x32\x10.cln.WaitDetailsH\x03\x88\x01\x01\"9\n\rWaitSubsystem\x12\x0c\n\x08INVOICES\x10\x00\x12\x0c\n\x08\x46ORWARDS\x10\x01\x12\x0c\n\x08SENDPAYS\x10\x02\x42\n\n\x08_createdB\n\n\x08_updatedB\n\n\x08_deletedB\n\n\x08_details\"\xfc\x04\n\x0bWaitDetails\x12\x37\n\x06status\x18\x01 \x01(\x0e\x32\".cln.WaitDetails.WaitDetailsStatusH\x00\x88\x01\x01\x12\x12\n\x05label\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x04 \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x05 \x01(\tH\x04\x88\x01\x01\x12\x13\n\x06partid\x18\x06 \x01(\x04H\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\x07 \x01(\x04H\x06\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x08 \x01(\x0cH\x07\x88\x01\x01\x12\x17\n\nin_channel\x18\t \x01(\tH\x08\x88\x01\x01\x12\x17\n\nin_htlc_id\x18\n \x01(\x04H\t\x88\x01\x01\x12!\n\x07in_msat\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\n\x88\x01\x01\x12\x18\n\x0bout_channel\x18\x0c \x01(\tH\x0b\x88\x01\x01\"\x89\x01\n\x11WaitDetailsStatus\x12\n\n\x06UNPAID\x10\x00\x12\x08\n\x04PAID\x10\x01\x12\x0b\n\x07\x45XPIRED\x10\x02\x12\x0b\n\x07PENDING\x10\x03\x12\n\n\x06\x46\x41ILED\x10\x04\x12\x0c\n\x08\x43OMPLETE\x10\x05\x12\x0b\n\x07OFFERED\x10\x06\x12\x0b\n\x07SETTLED\x10\x07\x12\x10\n\x0cLOCAL_FAILED\x10\x08\x42\t\n\x07_statusB\x08\n\x06_labelB\x0e\n\x0c_descriptionB\t\n\x07_bolt11B\t\n\x07_bolt12B\t\n\x07_partidB\n\n\x08_groupidB\x0f\n\r_payment_hashB\r\n\x0b_in_channelB\r\n\x0b_in_htlc_idB\n\n\x08_in_msatB\x0e\n\x0c_out_channel\"4\n\x12ListconfigsRequest\x12\x13\n\x06\x63onfig\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_config\"\xdf\x1b\n\x13ListconfigsResponse\x12-\n\x07\x63onfigs\x18\x01 \x01(\x0b\x32\x17.cln.ListconfigsConfigsH\x00\x88\x01\x01\x12(\n\x07plugins\x18\x03 \x03(\x0b\x32\x17.cln.ListconfigsPlugins\x12;\n\x11important_plugins\x18\x04 \x03(\x0b\x32 .cln.ListconfigsImportantplugins\x12\x11\n\x04\x63onf\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x1a\n\rlightning_dir\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07network\x18\x07 \x01(\tH\x03\x88\x01\x01\x12\"\n\x15\x61llow_deprecated_apis\x18\x08 \x01(\x08H\x04\x88\x01\x01\x12\x15\n\x08rpc_file\x18\t \x01(\tH\x05\x88\x01\x01\x12\x16\n\x0e\x64isable_plugin\x18\n \x03(\t\x12\x1b\n\x0e\x62ookkeeper_dir\x18\x0b \x01(\tH\x06\x88\x01\x01\x12\x1a\n\rbookkeeper_db\x18\x0c \x01(\tH\x07\x88\x01\x01\x12\x1d\n\x10\x61lways_use_proxy\x18\r \x01(\x08H\x08\x88\x01\x01\x12\x13\n\x06\x64\x61\x65mon\x18\x0e \x01(\x08H\t\x88\x01\x01\x12\x13\n\x06wallet\x18\x0f \x01(\tH\n\x88\x01\x01\x12\x1b\n\x0elarge_channels\x18\x10 \x01(\x08H\x0b\x88\x01\x01\x12#\n\x16\x65xperimental_dual_fund\x18\x11 \x01(\x08H\x0c\x88\x01\x01\x12\"\n\x15\x65xperimental_splicing\x18\x12 \x01(\x08H\r\x88\x01\x01\x12(\n\x1b\x65xperimental_onion_messages\x18\x13 \x01(\x08H\x0e\x88\x01\x01\x12 \n\x13\x65xperimental_offers\x18\x14 \x01(\x08H\x0f\x88\x01\x01\x12\x30\n#experimental_shutdown_wrong_funding\x18\x15 \x01(\x08H\x10\x88\x01\x01\x12&\n\x19\x65xperimental_peer_storage\x18\x16 \x01(\x08H\x11\x88\x01\x01\x12!\n\x14\x65xperimental_quiesce\x18\x17 \x01(\x08H\x12\x88\x01\x01\x12*\n\x1d\x65xperimental_upgrade_protocol\x18\x18 \x01(\x08H\x13\x88\x01\x01\x12&\n\x19invoices_onchain_fallback\x18\x19 \x01(\x08H\x14\x88\x01\x01\x12\x1d\n\x10\x64\x61tabase_upgrade\x18\x1a \x01(\x08H\x15\x88\x01\x01\x12\x10\n\x03rgb\x18\x1b \x01(\x0cH\x16\x88\x01\x01\x12\x12\n\x05\x61lias\x18\x1c \x01(\tH\x17\x88\x01\x01\x12\x15\n\x08pid_file\x18\x1d \x01(\tH\x18\x88\x01\x01\x12\x1e\n\x11ignore_fee_limits\x18\x1e \x01(\x08H\x19\x88\x01\x01\x12\x1d\n\x10watchtime_blocks\x18\x1f \x01(\rH\x1a\x88\x01\x01\x12 \n\x13max_locktime_blocks\x18 \x01(\rH\x1b\x88\x01\x01\x12\x1d\n\x10\x66unding_confirms\x18! \x01(\rH\x1c\x88\x01\x01\x12\x17\n\ncltv_delta\x18\" \x01(\rH\x1d\x88\x01\x01\x12\x17\n\ncltv_final\x18# \x01(\rH\x1e\x88\x01\x01\x12\x18\n\x0b\x63ommit_time\x18$ \x01(\rH\x1f\x88\x01\x01\x12\x15\n\x08\x66\x65\x65_base\x18% \x01(\rH \x88\x01\x01\x12\x13\n\x06rescan\x18& \x01(\x12H!\x88\x01\x01\x12\x1c\n\x0f\x66\x65\x65_per_satoshi\x18\' \x01(\rH\"\x88\x01\x01\x12!\n\x14max_concurrent_htlcs\x18( \x01(\rH#\x88\x01\x01\x12+\n\x11htlc_minimum_msat\x18) \x01(\x0b\x32\x0b.cln.AmountH$\x88\x01\x01\x12+\n\x11htlc_maximum_msat\x18* \x01(\x0b\x32\x0b.cln.AmountH%\x88\x01\x01\x12\x35\n\x1bmax_dust_htlc_exposure_msat\x18+ \x01(\x0b\x32\x0b.cln.AmountH&\x88\x01\x01\x12\x1d\n\x10min_capacity_sat\x18, \x01(\x04H\'\x88\x01\x01\x12\x11\n\x04\x61\x64\x64r\x18- \x01(\tH(\x88\x01\x01\x12\x1a\n\rannounce_addr\x18. \x01(\tH)\x88\x01\x01\x12\x16\n\tbind_addr\x18/ \x01(\tH*\x88\x01\x01\x12\x14\n\x07offline\x18\x30 \x01(\x08H+\x88\x01\x01\x12\x17\n\nautolisten\x18\x31 \x01(\x08H,\x88\x01\x01\x12\x12\n\x05proxy\x18\x32 \x01(\tH-\x88\x01\x01\x12\x18\n\x0b\x64isable_dns\x18\x33 \x01(\x08H.\x88\x01\x01\x12%\n\x18\x61nnounce_addr_discovered\x18\x34 \x01(\tH/\x88\x01\x01\x12*\n\x1d\x61nnounce_addr_discovered_port\x18\x35 \x01(\x12H0\x88\x01\x01\x12\x1a\n\rencrypted_hsm\x18\x36 \x01(\x08H1\x88\x01\x01\x12\x1a\n\rrpc_file_mode\x18\x37 \x01(\tH2\x88\x01\x01\x12\x16\n\tlog_level\x18\x38 \x01(\tH3\x88\x01\x01\x12\x17\n\nlog_prefix\x18\x39 \x01(\tH4\x88\x01\x01\x12\x15\n\x08log_file\x18: \x01(\tH5\x88\x01\x01\x12\x1b\n\x0elog_timestamps\x18; \x01(\x08H6\x88\x01\x01\x12\x1b\n\x0e\x66orce_feerates\x18< \x01(\tH7\x88\x01\x01\x12\x16\n\tsubdaemon\x18= \x01(\tH8\x88\x01\x01\x12#\n\x16\x66\x65tchinvoice_noconnect\x18> \x01(\x08H9\x88\x01\x01\x12\"\n\x15\x61\x63\x63\x65pt_htlc_tlv_types\x18? \x01(\tH:\x88\x01\x01\x12!\n\x14tor_service_password\x18@ \x01(\tH;\x88\x01\x01\x12!\n\x14\x64\x65v_allowdustreserve\x18\x41 \x01(\x08H<\x88\x01\x01\x12\x1e\n\x11\x61nnounce_addr_dns\x18\x42 \x01(\x08H=\x88\x01\x01\x12%\n\x18require_confirmed_inputs\x18\x43 \x01(\x08H>\x88\x01\x01\x12\x16\n\tdeveloper\x18\x44 \x01(\x08H?\x88\x01\x01\x12\x17\n\ncommit_fee\x18\x45 \x01(\x04H@\x88\x01\x01\x12,\n\x12min_emergency_msat\x18\x46 \x01(\x0b\x32\x0b.cln.AmountHA\x88\x01\x01\x12\"\n\x15\x63ommit_feerate_offset\x18G \x01(\rHB\x88\x01\x01\x42\n\n\x08_configsB\x07\n\x05_confB\x10\n\x0e_lightning_dirB\n\n\x08_networkB\x18\n\x16_allow_deprecated_apisB\x0b\n\t_rpc_fileB\x11\n\x0f_bookkeeper_dirB\x10\n\x0e_bookkeeper_dbB\x13\n\x11_always_use_proxyB\t\n\x07_daemonB\t\n\x07_walletB\x11\n\x0f_large_channelsB\x19\n\x17_experimental_dual_fundB\x18\n\x16_experimental_splicingB\x1e\n\x1c_experimental_onion_messagesB\x16\n\x14_experimental_offersB&\n$_experimental_shutdown_wrong_fundingB\x1c\n\x1a_experimental_peer_storageB\x17\n\x15_experimental_quiesceB \n\x1e_experimental_upgrade_protocolB\x1c\n\x1a_invoices_onchain_fallbackB\x13\n\x11_database_upgradeB\x06\n\x04_rgbB\x08\n\x06_aliasB\x0b\n\t_pid_fileB\x14\n\x12_ignore_fee_limitsB\x13\n\x11_watchtime_blocksB\x16\n\x14_max_locktime_blocksB\x13\n\x11_funding_confirmsB\r\n\x0b_cltv_deltaB\r\n\x0b_cltv_finalB\x0e\n\x0c_commit_timeB\x0b\n\t_fee_baseB\t\n\x07_rescanB\x12\n\x10_fee_per_satoshiB\x17\n\x15_max_concurrent_htlcsB\x14\n\x12_htlc_minimum_msatB\x14\n\x12_htlc_maximum_msatB\x1e\n\x1c_max_dust_htlc_exposure_msatB\x13\n\x11_min_capacity_satB\x07\n\x05_addrB\x10\n\x0e_announce_addrB\x0c\n\n_bind_addrB\n\n\x08_offlineB\r\n\x0b_autolistenB\x08\n\x06_proxyB\x0e\n\x0c_disable_dnsB\x1b\n\x19_announce_addr_discoveredB \n\x1e_announce_addr_discovered_portB\x10\n\x0e_encrypted_hsmB\x10\n\x0e_rpc_file_modeB\x0c\n\n_log_levelB\r\n\x0b_log_prefixB\x0b\n\t_log_fileB\x11\n\x0f_log_timestampsB\x11\n\x0f_force_feeratesB\x0c\n\n_subdaemonB\x19\n\x17_fetchinvoice_noconnectB\x18\n\x16_accept_htlc_tlv_typesB\x17\n\x15_tor_service_passwordB\x17\n\x15_dev_allowdustreserveB\x14\n\x12_announce_addr_dnsB\x1b\n\x19_require_confirmed_inputsB\x0c\n\n_developerB\r\n\x0b_commit_feeB\x15\n\x13_min_emergency_msatB\x18\n\x16_commit_feerate_offset\"\xdf.\n\x12ListconfigsConfigs\x12.\n\x04\x63onf\x18\x01 \x01(\x0b\x32\x1b.cln.ListconfigsConfigsConfH\x00\x88\x01\x01\x12\x38\n\tdeveloper\x18\x02 \x01(\x0b\x32 .cln.ListconfigsConfigsDeveloperH\x01\x88\x01\x01\x12?\n\rclear_plugins\x18\x03 \x01(\x0b\x32#.cln.ListconfigsConfigsClearpluginsH\x02\x88\x01\x01\x12;\n\x0b\x64isable_mpp\x18\x04 \x01(\x0b\x32!.cln.ListconfigsConfigsDisablemppH\x03\x88\x01\x01\x12\x34\n\x07mainnet\x18\x05 \x01(\x0b\x32\x1e.cln.ListconfigsConfigsMainnetH\x04\x88\x01\x01\x12\x34\n\x07regtest\x18\x06 \x01(\x0b\x32\x1e.cln.ListconfigsConfigsRegtestH\x05\x88\x01\x01\x12\x32\n\x06signet\x18\x07 \x01(\x0b\x32\x1d.cln.ListconfigsConfigsSignetH\x06\x88\x01\x01\x12\x34\n\x07testnet\x18\x08 \x01(\x0b\x32\x1e.cln.ListconfigsConfigsTestnetH\x07\x88\x01\x01\x12\x45\n\x10important_plugin\x18\t \x01(\x0b\x32&.cln.ListconfigsConfigsImportantpluginH\x08\x88\x01\x01\x12\x32\n\x06plugin\x18\n \x01(\x0b\x32\x1d.cln.ListconfigsConfigsPluginH\t\x88\x01\x01\x12\x39\n\nplugin_dir\x18\x0b \x01(\x0b\x32 .cln.ListconfigsConfigsPlugindirH\n\x88\x01\x01\x12?\n\rlightning_dir\x18\x0c \x01(\x0b\x32#.cln.ListconfigsConfigsLightningdirH\x0b\x88\x01\x01\x12\x34\n\x07network\x18\r \x01(\x0b\x32\x1e.cln.ListconfigsConfigsNetworkH\x0c\x88\x01\x01\x12N\n\x15\x61llow_deprecated_apis\x18\x0e \x01(\x0b\x32*.cln.ListconfigsConfigsAllowdeprecatedapisH\r\x88\x01\x01\x12\x35\n\x08rpc_file\x18\x0f \x01(\x0b\x32\x1e.cln.ListconfigsConfigsRpcfileH\x0e\x88\x01\x01\x12\x41\n\x0e\x64isable_plugin\x18\x10 \x01(\x0b\x32$.cln.ListconfigsConfigsDisablepluginH\x0f\x88\x01\x01\x12\x44\n\x10\x61lways_use_proxy\x18\x11 \x01(\x0b\x32%.cln.ListconfigsConfigsAlwaysuseproxyH\x10\x88\x01\x01\x12\x32\n\x06\x64\x61\x65mon\x18\x12 \x01(\x0b\x32\x1d.cln.ListconfigsConfigsDaemonH\x11\x88\x01\x01\x12\x32\n\x06wallet\x18\x13 \x01(\x0b\x32\x1d.cln.ListconfigsConfigsWalletH\x12\x88\x01\x01\x12\x41\n\x0elarge_channels\x18\x14 \x01(\x0b\x32$.cln.ListconfigsConfigsLargechannelsH\x13\x88\x01\x01\x12P\n\x16\x65xperimental_dual_fund\x18\x15 \x01(\x0b\x32+.cln.ListconfigsConfigsExperimentaldualfundH\x14\x88\x01\x01\x12O\n\x15\x65xperimental_splicing\x18\x16 \x01(\x0b\x32+.cln.ListconfigsConfigsExperimentalsplicingH\x15\x88\x01\x01\x12Z\n\x1b\x65xperimental_onion_messages\x18\x17 \x01(\x0b\x32\x30.cln.ListconfigsConfigsExperimentalonionmessagesH\x16\x88\x01\x01\x12K\n\x13\x65xperimental_offers\x18\x18 \x01(\x0b\x32).cln.ListconfigsConfigsExperimentaloffersH\x17\x88\x01\x01\x12i\n#experimental_shutdown_wrong_funding\x18\x19 \x01(\x0b\x32\x37.cln.ListconfigsConfigsExperimentalshutdownwrongfundingH\x18\x88\x01\x01\x12V\n\x19\x65xperimental_peer_storage\x18\x1a \x01(\x0b\x32..cln.ListconfigsConfigsExperimentalpeerstorageH\x19\x88\x01\x01\x12M\n\x14\x65xperimental_anchors\x18\x1b \x01(\x0b\x32*.cln.ListconfigsConfigsExperimentalanchorsH\x1a\x88\x01\x01\x12\x45\n\x10\x64\x61tabase_upgrade\x18\x1c \x01(\x0b\x32&.cln.ListconfigsConfigsDatabaseupgradeH\x1b\x88\x01\x01\x12,\n\x03rgb\x18\x1d \x01(\x0b\x32\x1a.cln.ListconfigsConfigsRgbH\x1c\x88\x01\x01\x12\x30\n\x05\x61lias\x18\x1e \x01(\x0b\x32\x1c.cln.ListconfigsConfigsAliasH\x1d\x88\x01\x01\x12\x35\n\x08pid_file\x18\x1f \x01(\x0b\x32\x1e.cln.ListconfigsConfigsPidfileH\x1e\x88\x01\x01\x12\x46\n\x11ignore_fee_limits\x18 \x01(\x0b\x32&.cln.ListconfigsConfigsIgnorefeelimitsH\x1f\x88\x01\x01\x12\x45\n\x10watchtime_blocks\x18! \x01(\x0b\x32&.cln.ListconfigsConfigsWatchtimeblocksH \x88\x01\x01\x12J\n\x13max_locktime_blocks\x18\" \x01(\x0b\x32(.cln.ListconfigsConfigsMaxlocktimeblocksH!\x88\x01\x01\x12\x45\n\x10\x66unding_confirms\x18# \x01(\x0b\x32&.cln.ListconfigsConfigsFundingconfirmsH\"\x88\x01\x01\x12\x39\n\ncltv_delta\x18$ \x01(\x0b\x32 .cln.ListconfigsConfigsCltvdeltaH#\x88\x01\x01\x12\x39\n\ncltv_final\x18% \x01(\x0b\x32 .cln.ListconfigsConfigsCltvfinalH$\x88\x01\x01\x12;\n\x0b\x63ommit_time\x18& \x01(\x0b\x32!.cln.ListconfigsConfigsCommittimeH%\x88\x01\x01\x12\x35\n\x08\x66\x65\x65_base\x18\' \x01(\x0b\x32\x1e.cln.ListconfigsConfigsFeebaseH&\x88\x01\x01\x12\x32\n\x06rescan\x18( \x01(\x0b\x32\x1d.cln.ListconfigsConfigsRescanH\'\x88\x01\x01\x12\x42\n\x0f\x66\x65\x65_per_satoshi\x18) \x01(\x0b\x32$.cln.ListconfigsConfigsFeepersatoshiH(\x88\x01\x01\x12L\n\x14max_concurrent_htlcs\x18* \x01(\x0b\x32).cln.ListconfigsConfigsMaxconcurrenthtlcsH)\x88\x01\x01\x12\x46\n\x11htlc_minimum_msat\x18+ \x01(\x0b\x32&.cln.ListconfigsConfigsHtlcminimummsatH*\x88\x01\x01\x12\x46\n\x11htlc_maximum_msat\x18, \x01(\x0b\x32&.cln.ListconfigsConfigsHtlcmaximummsatH+\x88\x01\x01\x12X\n\x1bmax_dust_htlc_exposure_msat\x18- \x01(\x0b\x32..cln.ListconfigsConfigsMaxdusthtlcexposuremsatH,\x88\x01\x01\x12\x44\n\x10min_capacity_sat\x18. \x01(\x0b\x32%.cln.ListconfigsConfigsMincapacitysatH-\x88\x01\x01\x12.\n\x04\x61\x64\x64r\x18/ \x01(\x0b\x32\x1b.cln.ListconfigsConfigsAddrH.\x88\x01\x01\x12?\n\rannounce_addr\x18\x30 \x01(\x0b\x32#.cln.ListconfigsConfigsAnnounceaddrH/\x88\x01\x01\x12\x37\n\tbind_addr\x18\x31 \x01(\x0b\x32\x1f.cln.ListconfigsConfigsBindaddrH0\x88\x01\x01\x12\x34\n\x07offline\x18\x32 \x01(\x0b\x32\x1e.cln.ListconfigsConfigsOfflineH1\x88\x01\x01\x12:\n\nautolisten\x18\x33 \x01(\x0b\x32!.cln.ListconfigsConfigsAutolistenH2\x88\x01\x01\x12\x30\n\x05proxy\x18\x34 \x01(\x0b\x32\x1c.cln.ListconfigsConfigsProxyH3\x88\x01\x01\x12;\n\x0b\x64isable_dns\x18\x35 \x01(\x0b\x32!.cln.ListconfigsConfigsDisablednsH4\x88\x01\x01\x12T\n\x18\x61nnounce_addr_discovered\x18\x36 \x01(\x0b\x32-.cln.ListconfigsConfigsAnnounceaddrdiscoveredH5\x88\x01\x01\x12]\n\x1d\x61nnounce_addr_discovered_port\x18\x37 \x01(\x0b\x32\x31.cln.ListconfigsConfigsAnnounceaddrdiscoveredportH6\x88\x01\x01\x12?\n\rencrypted_hsm\x18\x38 \x01(\x0b\x32#.cln.ListconfigsConfigsEncryptedhsmH7\x88\x01\x01\x12>\n\rrpc_file_mode\x18\x39 \x01(\x0b\x32\".cln.ListconfigsConfigsRpcfilemodeH8\x88\x01\x01\x12\x37\n\tlog_level\x18: \x01(\x0b\x32\x1f.cln.ListconfigsConfigsLoglevelH9\x88\x01\x01\x12\x39\n\nlog_prefix\x18; \x01(\x0b\x32 .cln.ListconfigsConfigsLogprefixH:\x88\x01\x01\x12\x35\n\x08log_file\x18< \x01(\x0b\x32\x1e.cln.ListconfigsConfigsLogfileH;\x88\x01\x01\x12\x41\n\x0elog_timestamps\x18= \x01(\x0b\x32$.cln.ListconfigsConfigsLogtimestampsH<\x88\x01\x01\x12\x41\n\x0e\x66orce_feerates\x18> \x01(\x0b\x32$.cln.ListconfigsConfigsForcefeeratesH=\x88\x01\x01\x12\x38\n\tsubdaemon\x18? \x01(\x0b\x32 .cln.ListconfigsConfigsSubdaemonH>\x88\x01\x01\x12Q\n\x16\x66\x65tchinvoice_noconnect\x18@ \x01(\x0b\x32,.cln.ListconfigsConfigsFetchinvoicenoconnectH?\x88\x01\x01\x12M\n\x15\x61\x63\x63\x65pt_htlc_tlv_types\x18\x41 \x01(\x0b\x32).cln.ListconfigsConfigsAccepthtlctlvtypesH@\x88\x01\x01\x12L\n\x14tor_service_password\x18\x42 \x01(\x0b\x32).cln.ListconfigsConfigsTorservicepasswordHA\x88\x01\x01\x12\x46\n\x11\x61nnounce_addr_dns\x18\x43 \x01(\x0b\x32&.cln.ListconfigsConfigsAnnounceaddrdnsHB\x88\x01\x01\x12T\n\x18require_confirmed_inputs\x18\x44 \x01(\x0b\x32-.cln.ListconfigsConfigsRequireconfirmedinputsHC\x88\x01\x01\x12\x39\n\ncommit_fee\x18\x45 \x01(\x0b\x32 .cln.ListconfigsConfigsCommitfeeHD\x88\x01\x01\x12N\n\x15\x63ommit_feerate_offset\x18\x46 \x01(\x0b\x32*.cln.ListconfigsConfigsCommitfeerateoffsetHE\x88\x01\x01\x42\x07\n\x05_confB\x0c\n\n_developerB\x10\n\x0e_clear_pluginsB\x0e\n\x0c_disable_mppB\n\n\x08_mainnetB\n\n\x08_regtestB\t\n\x07_signetB\n\n\x08_testnetB\x13\n\x11_important_pluginB\t\n\x07_pluginB\r\n\x0b_plugin_dirB\x10\n\x0e_lightning_dirB\n\n\x08_networkB\x18\n\x16_allow_deprecated_apisB\x0b\n\t_rpc_fileB\x11\n\x0f_disable_pluginB\x13\n\x11_always_use_proxyB\t\n\x07_daemonB\t\n\x07_walletB\x11\n\x0f_large_channelsB\x19\n\x17_experimental_dual_fundB\x18\n\x16_experimental_splicingB\x1e\n\x1c_experimental_onion_messagesB\x16\n\x14_experimental_offersB&\n$_experimental_shutdown_wrong_fundingB\x1c\n\x1a_experimental_peer_storageB\x17\n\x15_experimental_anchorsB\x13\n\x11_database_upgradeB\x06\n\x04_rgbB\x08\n\x06_aliasB\x0b\n\t_pid_fileB\x14\n\x12_ignore_fee_limitsB\x13\n\x11_watchtime_blocksB\x16\n\x14_max_locktime_blocksB\x13\n\x11_funding_confirmsB\r\n\x0b_cltv_deltaB\r\n\x0b_cltv_finalB\x0e\n\x0c_commit_timeB\x0b\n\t_fee_baseB\t\n\x07_rescanB\x12\n\x10_fee_per_satoshiB\x17\n\x15_max_concurrent_htlcsB\x14\n\x12_htlc_minimum_msatB\x14\n\x12_htlc_maximum_msatB\x1e\n\x1c_max_dust_htlc_exposure_msatB\x13\n\x11_min_capacity_satB\x07\n\x05_addrB\x10\n\x0e_announce_addrB\x0c\n\n_bind_addrB\n\n\x08_offlineB\r\n\x0b_autolistenB\x08\n\x06_proxyB\x0e\n\x0c_disable_dnsB\x1b\n\x19_announce_addr_discoveredB \n\x1e_announce_addr_discovered_portB\x10\n\x0e_encrypted_hsmB\x10\n\x0e_rpc_file_modeB\x0c\n\n_log_levelB\r\n\x0b_log_prefixB\x0b\n\t_log_fileB\x11\n\x0f_log_timestampsB\x11\n\x0f_force_feeratesB\x0c\n\n_subdaemonB\x19\n\x17_fetchinvoice_noconnectB\x18\n\x16_accept_htlc_tlv_typesB\x17\n\x15_tor_service_passwordB\x14\n\x12_announce_addr_dnsB\x1b\n\x19_require_confirmed_inputsB\r\n\x0b_commit_feeB\x18\n\x16_commit_feerate_offset\"\xa2\x01\n\x16ListconfigsConfigsConf\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12H\n\x06source\x18\x02 \x01(\x0e\x32\x38.cln.ListconfigsConfigsConf.ListconfigsConfigsConfSource\"+\n\x1cListconfigsConfigsConfSource\x12\x0b\n\x07\x43MDLINE\x10\x00\":\n\x1bListconfigsConfigsDeveloper\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"=\n\x1eListconfigsConfigsClearplugins\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"[\n\x1cListconfigsConfigsDisablempp\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x13\n\x06plugin\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_plugin\"8\n\x19ListconfigsConfigsMainnet\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"8\n\x19ListconfigsConfigsRegtest\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"7\n\x18ListconfigsConfigsSignet\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"8\n\x19ListconfigsConfigsTestnet\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"H\n!ListconfigsConfigsImportantplugin\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"?\n\x18ListconfigsConfigsPlugin\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"B\n\x1bListconfigsConfigsPlugindir\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"C\n\x1eListconfigsConfigsLightningdir\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x19ListconfigsConfigsNetwork\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"K\n%ListconfigsConfigsAllowdeprecatedapis\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x19ListconfigsConfigsRpcfile\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"F\n\x1fListconfigsConfigsDisableplugin\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"F\n ListconfigsConfigsAlwaysuseproxy\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"7\n\x18ListconfigsConfigsDaemon\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"=\n\x18ListconfigsConfigsWallet\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x1fListconfigsConfigsLargechannels\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"E\n&ListconfigsConfigsExperimentaldualfund\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"E\n&ListconfigsConfigsExperimentalsplicing\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"J\n+ListconfigsConfigsExperimentalonionmessages\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"C\n$ListconfigsConfigsExperimentaloffers\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"Q\n2ListconfigsConfigsExperimentalshutdownwrongfunding\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"H\n)ListconfigsConfigsExperimentalpeerstorage\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"D\n%ListconfigsConfigsExperimentalanchors\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"G\n!ListconfigsConfigsDatabaseupgrade\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\":\n\x15ListconfigsConfigsRgb\x12\x11\n\tvalue_str\x18\x01 \x01(\x0c\x12\x0e\n\x06source\x18\x02 \x01(\t\"<\n\x17ListconfigsConfigsAlias\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x19ListconfigsConfigsPidfile\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"G\n!ListconfigsConfigsIgnorefeelimits\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"F\n!ListconfigsConfigsWatchtimeblocks\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"H\n#ListconfigsConfigsMaxlocktimeblocks\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"F\n!ListconfigsConfigsFundingconfirms\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x1bListconfigsConfigsCltvdelta\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x1bListconfigsConfigsCltvfinal\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"A\n\x1cListconfigsConfigsCommittime\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\">\n\x19ListconfigsConfigsFeebase\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"=\n\x18ListconfigsConfigsRescan\x12\x11\n\tvalue_int\x18\x01 \x01(\x12\x12\x0e\n\x06source\x18\x02 \x01(\t\"D\n\x1fListconfigsConfigsFeepersatoshi\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"I\n$ListconfigsConfigsMaxconcurrenthtlcs\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"T\n!ListconfigsConfigsHtlcminimummsat\x12\x1f\n\nvalue_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06source\x18\x02 \x01(\t\"T\n!ListconfigsConfigsHtlcmaximummsat\x12\x1f\n\nvalue_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06source\x18\x02 \x01(\t\"\\\n)ListconfigsConfigsMaxdusthtlcexposuremsat\x12\x1f\n\nvalue_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06source\x18\x02 \x01(\t\"g\n ListconfigsConfigsMincapacitysat\x12\x11\n\tvalue_int\x18\x01 \x01(\x04\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x14\n\x07\x64ynamic\x18\x03 \x01(\x08H\x00\x88\x01\x01\x42\n\n\x08_dynamic\"=\n\x16ListconfigsConfigsAddr\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"E\n\x1eListconfigsConfigsAnnounceaddr\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"A\n\x1aListconfigsConfigsBindaddr\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"8\n\x19ListconfigsConfigsOffline\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"B\n\x1cListconfigsConfigsAutolisten\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"<\n\x17ListconfigsConfigsProxy\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\";\n\x1cListconfigsConfigsDisabledns\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"\x82\x02\n(ListconfigsConfigsAnnounceaddrdiscovered\x12r\n\tvalue_str\x18\x01 \x01(\x0e\x32_.cln.ListconfigsConfigsAnnounceaddrdiscovered.ListconfigsConfigsAnnounceaddrdiscoveredValue_str\x12\x0e\n\x06source\x18\x02 \x01(\t\"R\n1ListconfigsConfigsAnnounceaddrdiscoveredValue_str\x12\x08\n\x04TRUE\x10\x00\x12\t\n\x05\x46\x41LSE\x10\x01\x12\x08\n\x04\x41UTO\x10\x02\"Q\n,ListconfigsConfigsAnnounceaddrdiscoveredport\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"=\n\x1eListconfigsConfigsEncryptedhsm\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"B\n\x1dListconfigsConfigsRpcfilemode\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"?\n\x1aListconfigsConfigsLoglevel\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x1bListconfigsConfigsLogprefix\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x19ListconfigsConfigsLogfile\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"E\n\x1fListconfigsConfigsLogtimestamps\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"D\n\x1fListconfigsConfigsForcefeerates\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"B\n\x1bListconfigsConfigsSubdaemon\x12\x12\n\nvalues_str\x18\x01 \x03(\t\x12\x0f\n\x07sources\x18\x02 \x03(\t\"f\n\'ListconfigsConfigsFetchinvoicenoconnect\x12\x0b\n\x03set\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x13\n\x06plugin\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_plugin\"I\n$ListconfigsConfigsAccepthtlctlvtypes\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"I\n$ListconfigsConfigsTorservicepassword\x12\x11\n\tvalue_str\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"G\n!ListconfigsConfigsAnnounceaddrdns\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"N\n(ListconfigsConfigsRequireconfirmedinputs\x12\x12\n\nvalue_bool\x18\x01 \x01(\x08\x12\x0e\n\x06source\x18\x02 \x01(\t\"@\n\x1bListconfigsConfigsCommitfee\x12\x11\n\tvalue_int\x18\x01 \x01(\x04\x12\x0e\n\x06source\x18\x02 \x01(\t\"J\n%ListconfigsConfigsCommitfeerateoffset\x12\x11\n\tvalue_int\x18\x01 \x01(\r\x12\x0e\n\x06source\x18\x02 \x01(\t\"r\n\x12ListconfigsPlugins\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x34\n\x07options\x18\x03 \x01(\x0b\x32\x1e.cln.ListconfigsPluginsOptionsH\x00\x88\x01\x01\x42\n\n\x08_options\"\x1b\n\x19ListconfigsPluginsOptions\"\x84\x01\n\x1bListconfigsImportantplugins\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12=\n\x07options\x18\x03 \x01(\x0b\x32\'.cln.ListconfigsImportantpluginsOptionsH\x00\x88\x01\x01\x42\n\n\x08_options\"$\n\"ListconfigsImportantpluginsOptions\"\r\n\x0bStopRequest\"q\n\x0cStopResponse\x12\x31\n\x06result\x18\x01 \x01(\x0e\x32\x1c.cln.StopResponse.StopResultH\x00\x88\x01\x01\"#\n\nStopResult\x12\x15\n\x11SHUTDOWN_COMPLETE\x10\x00\x42\t\n\x07_result\"/\n\x0bHelpRequest\x12\x14\n\x07\x63ommand\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_command\"\x95\x01\n\x0cHelpResponse\x12\x1b\n\x04help\x18\x01 \x03(\x0b\x32\r.cln.HelpHelp\x12:\n\x0b\x66ormat_hint\x18\x02 \x01(\x0e\x32 .cln.HelpResponse.HelpFormathintH\x00\x88\x01\x01\"\x1c\n\x0eHelpFormathint\x12\n\n\x06SIMPLE\x10\x00\x42\x0e\n\x0c_format_hint\"\x1b\n\x08HelpHelp\x12\x0f\n\x07\x63ommand\x18\x01 \x01(\t\"g\n\x18PreapprovekeysendRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\x0c\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\"\x1b\n\x19PreapprovekeysendResponse\"*\n\x18PreapproveinvoiceRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\"\x1b\n\x19PreapproveinvoiceResponse\"\x15\n\x13StaticbackupRequest\"#\n\x14StaticbackupResponse\x12\x0b\n\x03scb\x18\x01 \x03(\x0c\"d\n\x16\x42kprchannelsapyRequest\x12\x17\n\nstart_time\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x15\n\x08\x65nd_time\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\r\n\x0b_start_timeB\x0b\n\t_end_time\"Q\n\x17\x42kprchannelsapyResponse\x12\x36\n\x0c\x63hannels_apy\x18\x01 \x03(\x0b\x32 .cln.BkprchannelsapyChannels_apy\"\xfa\x06\n\x1b\x42kprchannelsapyChannels_apy\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12$\n\x0frouted_out_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0erouted_in_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12(\n\x13lease_fee_paid_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12*\n\x15lease_fee_earned_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x0fpushed_out_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0epushed_in_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x16our_start_balance_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12/\n\x1a\x63hannel_start_balance_msat\x18\t \x01(\x0b\x32\x0b.cln.Amount\x12\"\n\rfees_out_msat\x18\n \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x0c\x66\x65\x65s_in_msat\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x17\n\x0futilization_out\x18\x0c \x01(\t\x12$\n\x17utilization_out_initial\x18\r \x01(\tH\x01\x88\x01\x01\x12\x16\n\x0eutilization_in\x18\x0e \x01(\t\x12#\n\x16utilization_in_initial\x18\x0f \x01(\tH\x02\x88\x01\x01\x12\x0f\n\x07\x61py_out\x18\x10 \x01(\t\x12\x1c\n\x0f\x61py_out_initial\x18\x11 \x01(\tH\x03\x88\x01\x01\x12\x0e\n\x06\x61py_in\x18\x12 \x01(\t\x12\x1b\n\x0e\x61py_in_initial\x18\x13 \x01(\tH\x04\x88\x01\x01\x12\x11\n\tapy_total\x18\x14 \x01(\t\x12\x1e\n\x11\x61py_total_initial\x18\x15 \x01(\tH\x05\x88\x01\x01\x12\x16\n\tapy_lease\x18\x16 \x01(\tH\x06\x88\x01\x01\x42\x0f\n\r_fees_in_msatB\x1a\n\x18_utilization_out_initialB\x19\n\x17_utilization_in_initialB\x12\n\x10_apy_out_initialB\x11\n\x0f_apy_in_initialB\x14\n\x12_apy_total_initialB\x0c\n\n_apy_lease\"\xd2\x01\n\x18\x42kprdumpincomecsvRequest\x12\x12\n\ncsv_format\x18\x01 \x01(\t\x12\x15\n\x08\x63sv_file\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x1d\n\x10\x63onsolidate_fees\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12\x17\n\nstart_time\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x15\n\x08\x65nd_time\x18\x05 \x01(\x04H\x03\x88\x01\x01\x42\x0b\n\t_csv_fileB\x13\n\x11_consolidate_feesB\r\n\x0b_start_timeB\x0b\n\t_end_time\"\xd6\x01\n\x19\x42kprdumpincomecsvResponse\x12\x10\n\x08\x63sv_file\x18\x01 \x01(\t\x12N\n\ncsv_format\x18\x02 \x01(\x0e\x32:.cln.BkprdumpincomecsvResponse.BkprdumpincomecsvCsv_format\"W\n\x1b\x42kprdumpincomecsvCsv_format\x12\x0f\n\x0b\x43OINTRACKER\x10\x00\x12\n\n\x06KOINLY\x10\x01\x12\x0b\n\x07HARMONY\x10\x02\x12\x0e\n\nQUICKBOOKS\x10\x03\"%\n\x12\x42kprinspectRequest\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\"7\n\x13\x42kprinspectResponse\x12 \n\x03txs\x18\x01 \x03(\x0b\x32\x13.cln.BkprinspectTxs\"\x9a\x01\n\x0e\x42kprinspectTxs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x18\n\x0b\x62lockheight\x18\x02 \x01(\rH\x00\x88\x01\x01\x12#\n\x0e\x66\x65\x65s_paid_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x07outputs\x18\x04 \x03(\x0b\x32\x1a.cln.BkprinspectTxsOutputsB\x0e\n\x0c_blockheight\"\xbc\x03\n\x15\x42kprinspectTxsOutputs\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12\x0e\n\x06outnum\x18\x02 \x01(\r\x12&\n\x11output_value_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x10\n\x08\x63urrency\x18\x04 \x01(\t\x12%\n\x0b\x63redit_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12$\n\ndebit_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12 \n\x13originating_account\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x17\n\noutput_tag\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tspend_tag\x18\t \x01(\tH\x04\x88\x01\x01\x12\x1a\n\rspending_txid\x18\n \x01(\x0cH\x05\x88\x01\x01\x12\x17\n\npayment_id\x18\x0b \x01(\x0cH\x06\x88\x01\x01\x42\x0e\n\x0c_credit_msatB\r\n\x0b_debit_msatB\x16\n\x14_originating_accountB\r\n\x0b_output_tagB\x0c\n\n_spend_tagB\x10\n\x0e_spending_txidB\r\n\x0b_payment_id\"h\n\x1c\x42kprlistaccounteventsRequest\x12\x14\n\x07\x61\x63\x63ount\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\npayment_id\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\n\n\x08_accountB\r\n\x0b_payment_id\"Q\n\x1d\x42kprlistaccounteventsResponse\x12\x30\n\x06\x65vents\x18\x01 \x03(\x0b\x32 .cln.BkprlistaccounteventsEvents\"\xa1\x05\n\x1b\x42kprlistaccounteventsEvents\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12S\n\titem_type\x18\x02 \x01(\x0e\x32@.cln.BkprlistaccounteventsEvents.BkprlistaccounteventsEventsType\x12\x0b\n\x03tag\x18\x03 \x01(\t\x12 \n\x0b\x63redit_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1f\n\ndebit_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x10\n\x08\x63urrency\x18\x06 \x01(\t\x12\x11\n\ttimestamp\x18\x07 \x01(\r\x12\x15\n\x08outpoint\x18\x08 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x62lockheight\x18\t \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06origin\x18\n \x01(\tH\x02\x88\x01\x01\x12\x17\n\npayment_id\x18\x0b \x01(\x0cH\x03\x88\x01\x01\x12\x11\n\x04txid\x18\x0c \x01(\x0cH\x04\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\r \x01(\tH\x05\x88\x01\x01\x12#\n\tfees_msat\x18\x0e \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x19\n\x0cis_rebalance\x18\x0f \x01(\x08H\x07\x88\x01\x01\x12\x14\n\x07part_id\x18\x10 \x01(\rH\x08\x88\x01\x01\"J\n\x1f\x42kprlistaccounteventsEventsType\x12\x0f\n\x0bONCHAIN_FEE\x10\x00\x12\t\n\x05\x43HAIN\x10\x01\x12\x0b\n\x07\x43HANNEL\x10\x02\x42\x0b\n\t_outpointB\x0e\n\x0c_blockheightB\t\n\x07_originB\r\n\x0b_payment_idB\x07\n\x05_txidB\x0e\n\x0c_descriptionB\x0c\n\n_fees_msatB\x0f\n\r_is_rebalanceB\n\n\x08_part_id\"\x19\n\x17\x42kprlistbalancesRequest\"K\n\x18\x42kprlistbalancesResponse\x12/\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x1d.cln.BkprlistbalancesAccounts\"\xc6\x02\n\x18\x42kprlistbalancesAccounts\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12\x37\n\x08\x62\x61lances\x18\x02 \x03(\x0b\x32%.cln.BkprlistbalancesAccountsBalances\x12\x14\n\x07peer_id\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x16\n\twe_opened\x18\x04 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x61\x63\x63ount_closed\x18\x05 \x01(\x08H\x02\x88\x01\x01\x12\x1d\n\x10\x61\x63\x63ount_resolved\x18\x06 \x01(\x08H\x03\x88\x01\x01\x12\x1e\n\x11resolved_at_block\x18\x07 \x01(\rH\x04\x88\x01\x01\x42\n\n\x08_peer_idB\x0c\n\n_we_openedB\x11\n\x0f_account_closedB\x13\n\x11_account_resolvedB\x14\n\x12_resolved_at_block\"X\n BkprlistbalancesAccountsBalances\x12!\n\x0c\x62\x61lance_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x11\n\tcoin_type\x18\x02 \x01(\t\"\x97\x01\n\x15\x42kprlistincomeRequest\x12\x1d\n\x10\x63onsolidate_fees\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12\x17\n\nstart_time\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08\x65nd_time\x18\x03 \x01(\rH\x02\x88\x01\x01\x42\x13\n\x11_consolidate_feesB\r\n\x0b_start_timeB\x0b\n\t_end_time\"Q\n\x16\x42kprlistincomeResponse\x12\x37\n\rincome_events\x18\x01 \x03(\x0b\x32 .cln.BkprlistincomeIncome_events\"\xb5\x02\n\x1b\x42kprlistincomeIncome_events\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12\x0b\n\x03tag\x18\x02 \x01(\t\x12 \n\x0b\x63redit_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x1f\n\ndebit_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x10\n\x08\x63urrency\x18\x05 \x01(\t\x12\x11\n\ttimestamp\x18\x06 \x01(\r\x12\x18\n\x0b\x64\x65scription\x18\x07 \x01(\tH\x00\x88\x01\x01\x12\x15\n\x08outpoint\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x11\n\x04txid\x18\t \x01(\x0cH\x02\x88\x01\x01\x12\x17\n\npayment_id\x18\n \x01(\x0cH\x03\x88\x01\x01\x42\x0e\n\x0c_descriptionB\x0b\n\t_outpointB\x07\n\x05_txidB\r\n\x0b_payment_id\"N\n\x14\x42lacklistruneRequest\x12\x12\n\x05start\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03\x65nd\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x08\n\x06_startB\x06\n\x04_end\"G\n\x15\x42lacklistruneResponse\x12.\n\tblacklist\x18\x01 \x03(\x0b\x32\x1b.cln.BlacklistruneBlacklist\"4\n\x16\x42lacklistruneBlacklist\x12\r\n\x05start\x18\x01 \x01(\x04\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x04\"p\n\x10\x43heckruneRequest\x12\x0c\n\x04rune\x18\x01 \x01(\t\x12\x13\n\x06nodeid\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06method\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x0e\n\x06params\x18\x04 \x03(\tB\t\n\x07_nodeidB\t\n\x07_method\"\"\n\x11\x43heckruneResponse\x12\r\n\x05valid\x18\x01 \x01(\x08\"E\n\x11\x43reateruneRequest\x12\x11\n\x04rune\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0crestrictions\x18\x02 \x03(\tB\x07\n\x05_rune\"{\n\x12\x43reateruneResponse\x12\x0c\n\x04rune\x18\x01 \x01(\t\x12\x11\n\tunique_id\x18\x02 \x01(\t\x12&\n\x19warning_unrestricted_rune\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x1c\n\x1a_warning_unrestricted_rune\".\n\x10ShowrunesRequest\x12\x11\n\x04rune\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x07\n\x05_rune\"7\n\x11ShowrunesResponse\x12\"\n\x05runes\x18\x01 \x03(\x0b\x32\x13.cln.ShowrunesRunes\"\x9d\x02\n\x0eShowrunesRunes\x12\x0c\n\x04rune\x18\x01 \x01(\t\x12\x11\n\tunique_id\x18\x02 \x01(\t\x12\x35\n\x0crestrictions\x18\x03 \x03(\x0b\x32\x1f.cln.ShowrunesRunesRestrictions\x12\x1f\n\x17restrictions_as_english\x18\x04 \x01(\t\x12\x13\n\x06stored\x18\x05 \x01(\x08H\x00\x88\x01\x01\x12\x18\n\x0b\x62lacklisted\x18\x06 \x01(\x08H\x01\x88\x01\x01\x12\x16\n\tlast_used\x18\x07 \x01(\x01H\x02\x88\x01\x01\x12\x15\n\x08our_rune\x18\x08 \x01(\x08H\x03\x88\x01\x01\x42\t\n\x07_storedB\x0e\n\x0c_blacklistedB\x0c\n\n_last_usedB\x0b\n\t_our_rune\"p\n\x1aShowrunesRunesRestrictions\x12\x41\n\x0c\x61lternatives\x18\x01 \x03(\x0b\x32+.cln.ShowrunesRunesRestrictionsAlternatives\x12\x0f\n\x07\x65nglish\x18\x02 \x01(\t\"n\n&ShowrunesRunesRestrictionsAlternatives\x12\x11\n\tfieldname\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x12\x11\n\tcondition\x18\x03 \x01(\t\x12\x0f\n\x07\x65nglish\x18\x04 \x01(\t\"\x19\n\x17StreamBlockAddedRequest\"6\n\x16\x42lockAddedNotification\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\x0e\n\x06height\x18\x02 \x01(\r\" \n\x1eStreamChannelOpenFailedRequest\"3\n\x1d\x43hannelOpenFailedNotification\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\"\x1c\n\x1aStreamChannelOpenedRequest\"w\n\x19\x43hannelOpenedNotification\x12\n\n\x02id\x18\x01 \x01(\x0c\x12!\n\x0c\x66unding_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0c\x66unding_txid\x18\x03 \x01(\x0c\x12\x15\n\rchannel_ready\x18\x04 \x01(\x08\"\x16\n\x14StreamConnectRequest\"\xbe\x01\n\x17PeerConnectNotification\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x44\n\tdirection\x18\x02 \x01(\x0e\x32\x31.cln.PeerConnectNotification.PeerConnectDirection\x12(\n\x07\x61\x64\x64ress\x18\x03 \x01(\x0b\x32\x17.cln.PeerConnectAddress\"\'\n\x14PeerConnectDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\"\x8b\x02\n\x12PeerConnectAddress\x12\x41\n\titem_type\x18\x01 \x01(\x0e\x32..cln.PeerConnectAddress.PeerConnectAddressType\x12\x13\n\x06socket\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x11\n\x04port\x18\x04 \x01(\rH\x02\x88\x01\x01\"T\n\x16PeerConnectAddressType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\t\n\x07_socketB\n\n\x08_addressB\x07\n\x05_port\"\x18\n\x16StreamCustomMsgRequest\"9\n\x15\x43ustomMsgNotification\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x32\xcb?\n\x04Node\x12\x36\n\x07Getinfo\x12\x13.cln.GetinfoRequest\x1a\x14.cln.GetinfoResponse\"\x00\x12<\n\tListPeers\x12\x15.cln.ListpeersRequest\x1a\x16.cln.ListpeersResponse\"\x00\x12<\n\tListFunds\x12\x15.cln.ListfundsRequest\x1a\x16.cln.ListfundsResponse\"\x00\x12\x36\n\x07SendPay\x12\x13.cln.SendpayRequest\x1a\x14.cln.SendpayResponse\"\x00\x12\x45\n\x0cListChannels\x12\x18.cln.ListchannelsRequest\x1a\x19.cln.ListchannelsResponse\"\x00\x12<\n\tAddGossip\x12\x15.cln.AddgossipRequest\x1a\x16.cln.AddgossipResponse\"\x00\x12H\n\rAddPsbtOutput\x12\x19.cln.AddpsbtoutputRequest\x1a\x1a.cln.AddpsbtoutputResponse\"\x00\x12H\n\rAutoCleanOnce\x12\x19.cln.AutocleanonceRequest\x1a\x1a.cln.AutocleanonceResponse\"\x00\x12N\n\x0f\x41utoCleanStatus\x12\x1b.cln.AutocleanstatusRequest\x1a\x1c.cln.AutocleanstatusResponse\"\x00\x12\x45\n\x0c\x43heckMessage\x12\x18.cln.CheckmessageRequest\x1a\x19.cln.CheckmessageResponse\"\x00\x12\x30\n\x05\x43lose\x12\x11.cln.CloseRequest\x1a\x12.cln.CloseResponse\"\x00\x12:\n\x0b\x43onnectPeer\x12\x13.cln.ConnectRequest\x1a\x14.cln.ConnectResponse\"\x00\x12H\n\rCreateInvoice\x12\x19.cln.CreateinvoiceRequest\x1a\x1a.cln.CreateinvoiceResponse\"\x00\x12<\n\tDatastore\x12\x15.cln.DatastoreRequest\x1a\x16.cln.DatastoreResponse\"\x00\x12K\n\x0e\x44\x61tastoreUsage\x12\x1a.cln.DatastoreusageRequest\x1a\x1b.cln.DatastoreusageResponse\"\x00\x12\x42\n\x0b\x43reateOnion\x12\x17.cln.CreateonionRequest\x1a\x18.cln.CreateonionResponse\"\x00\x12\x45\n\x0c\x44\x65lDatastore\x12\x18.cln.DeldatastoreRequest\x1a\x19.cln.DeldatastoreResponse\"\x00\x12?\n\nDelInvoice\x12\x16.cln.DelinvoiceRequest\x1a\x17.cln.DelinvoiceResponse\"\x00\x12Q\n\x10\x44\x65vForgetChannel\x12\x1c.cln.DevforgetchannelRequest\x1a\x1d.cln.DevforgetchannelResponse\"\x00\x12Q\n\x10\x45mergencyRecover\x12\x1c.cln.EmergencyrecoverRequest\x1a\x1d.cln.EmergencyrecoverResponse\"\x00\x12\x36\n\x07Recover\x12\x13.cln.RecoverRequest\x1a\x14.cln.RecoverResponse\"\x00\x12K\n\x0eRecoverChannel\x12\x1a.cln.RecoverchannelRequest\x1a\x1b.cln.RecoverchannelResponse\"\x00\x12\x36\n\x07Invoice\x12\x13.cln.InvoiceRequest\x1a\x14.cln.InvoiceResponse\"\x00\x12Q\n\x14\x43reateInvoiceRequest\x12\x1a.cln.InvoicerequestRequest\x1a\x1b.cln.InvoicerequestResponse\"\x00\x12`\n\x15\x44isableInvoiceRequest\x12!.cln.DisableinvoicerequestRequest\x1a\".cln.DisableinvoicerequestResponse\"\x00\x12Z\n\x13ListInvoiceRequests\x12\x1f.cln.ListinvoicerequestsRequest\x1a .cln.ListinvoicerequestsResponse\"\x00\x12H\n\rListDatastore\x12\x19.cln.ListdatastoreRequest\x1a\x1a.cln.ListdatastoreResponse\"\x00\x12\x45\n\x0cListInvoices\x12\x18.cln.ListinvoicesRequest\x1a\x19.cln.ListinvoicesResponse\"\x00\x12<\n\tSendOnion\x12\x15.cln.SendonionRequest\x1a\x16.cln.SendonionResponse\"\x00\x12\x45\n\x0cListSendPays\x12\x18.cln.ListsendpaysRequest\x1a\x19.cln.ListsendpaysResponse\"\x00\x12Q\n\x10ListTransactions\x12\x1c.cln.ListtransactionsRequest\x1a\x1d.cln.ListtransactionsResponse\"\x00\x12?\n\nMakeSecret\x12\x16.cln.MakesecretRequest\x1a\x17.cln.MakesecretResponse\"\x00\x12*\n\x03Pay\x12\x0f.cln.PayRequest\x1a\x10.cln.PayResponse\"\x00\x12<\n\tListNodes\x12\x15.cln.ListnodesRequest\x1a\x16.cln.ListnodesResponse\"\x00\x12K\n\x0eWaitAnyInvoice\x12\x1a.cln.WaitanyinvoiceRequest\x1a\x1b.cln.WaitanyinvoiceResponse\"\x00\x12\x42\n\x0bWaitInvoice\x12\x17.cln.WaitinvoiceRequest\x1a\x18.cln.WaitinvoiceResponse\"\x00\x12\x42\n\x0bWaitSendPay\x12\x17.cln.WaitsendpayRequest\x1a\x18.cln.WaitsendpayResponse\"\x00\x12\x36\n\x07NewAddr\x12\x13.cln.NewaddrRequest\x1a\x14.cln.NewaddrResponse\"\x00\x12\x39\n\x08Withdraw\x12\x14.cln.WithdrawRequest\x1a\x15.cln.WithdrawResponse\"\x00\x12\x36\n\x07KeySend\x12\x13.cln.KeysendRequest\x1a\x14.cln.KeysendResponse\"\x00\x12\x39\n\x08\x46undPsbt\x12\x14.cln.FundpsbtRequest\x1a\x15.cln.FundpsbtResponse\"\x00\x12\x39\n\x08SendPsbt\x12\x14.cln.SendpsbtRequest\x1a\x15.cln.SendpsbtResponse\"\x00\x12\x39\n\x08SignPsbt\x12\x14.cln.SignpsbtRequest\x1a\x15.cln.SignpsbtResponse\"\x00\x12\x39\n\x08UtxoPsbt\x12\x14.cln.UtxopsbtRequest\x1a\x15.cln.UtxopsbtResponse\"\x00\x12<\n\tTxDiscard\x12\x15.cln.TxdiscardRequest\x1a\x16.cln.TxdiscardResponse\"\x00\x12<\n\tTxPrepare\x12\x15.cln.TxprepareRequest\x1a\x16.cln.TxprepareResponse\"\x00\x12\x33\n\x06TxSend\x12\x12.cln.TxsendRequest\x1a\x13.cln.TxsendResponse\"\x00\x12Q\n\x10ListPeerChannels\x12\x1c.cln.ListpeerchannelsRequest\x1a\x1d.cln.ListpeerchannelsResponse\"\x00\x12W\n\x12ListClosedChannels\x12\x1e.cln.ListclosedchannelsRequest\x1a\x1f.cln.ListclosedchannelsResponse\"\x00\x12<\n\tDecodePay\x12\x15.cln.DecodepayRequest\x1a\x16.cln.DecodepayResponse\"\x00\x12\x33\n\x06\x44\x65\x63ode\x12\x12.cln.DecodeRequest\x1a\x13.cln.DecodeResponse\"\x00\x12\x33\n\x06\x44\x65lPay\x12\x12.cln.DelpayRequest\x1a\x13.cln.DelpayResponse\"\x00\x12?\n\nDelForward\x12\x16.cln.DelforwardRequest\x1a\x17.cln.DelforwardResponse\"\x00\x12\x45\n\x0c\x44isableOffer\x12\x18.cln.DisableofferRequest\x1a\x19.cln.DisableofferResponse\"\x00\x12?\n\nDisconnect\x12\x16.cln.DisconnectRequest\x1a\x17.cln.DisconnectResponse\"\x00\x12\x39\n\x08\x46\x65\x65rates\x12\x14.cln.FeeratesRequest\x1a\x15.cln.FeeratesResponse\"\x00\x12\x45\n\x0c\x46\x65tchInvoice\x12\x18.cln.FetchinvoiceRequest\x1a\x19.cln.FetchinvoiceResponse\"\x00\x12W\n\x12\x46undChannel_Cancel\x12\x1e.cln.Fundchannel_cancelRequest\x1a\x1f.cln.Fundchannel_cancelResponse\"\x00\x12]\n\x14\x46undChannel_Complete\x12 .cln.Fundchannel_completeRequest\x1a!.cln.Fundchannel_completeResponse\"\x00\x12\x42\n\x0b\x46undChannel\x12\x17.cln.FundchannelRequest\x1a\x18.cln.FundchannelResponse\"\x00\x12T\n\x11\x46undChannel_Start\x12\x1d.cln.Fundchannel_startRequest\x1a\x1e.cln.Fundchannel_startResponse\"\x00\x12\x33\n\x06GetLog\x12\x12.cln.GetlogRequest\x1a\x13.cln.GetlogResponse\"\x00\x12\x45\n\x0c\x46underUpdate\x12\x18.cln.FunderupdateRequest\x1a\x19.cln.FunderupdateResponse\"\x00\x12\x39\n\x08GetRoute\x12\x14.cln.GetrouteRequest\x1a\x15.cln.GetrouteResponse\"\x00\x12\x45\n\x0cListForwards\x12\x18.cln.ListforwardsRequest\x1a\x19.cln.ListforwardsResponse\"\x00\x12?\n\nListOffers\x12\x16.cln.ListoffersRequest\x1a\x17.cln.ListoffersResponse\"\x00\x12\x39\n\x08ListPays\x12\x14.cln.ListpaysRequest\x1a\x15.cln.ListpaysResponse\"\x00\x12<\n\tListHtlcs\x12\x15.cln.ListhtlcsRequest\x1a\x16.cln.ListhtlcsResponse\"\x00\x12Q\n\x10MultiFundChannel\x12\x1c.cln.MultifundchannelRequest\x1a\x1d.cln.MultifundchannelResponse\"\x00\x12H\n\rMultiWithdraw\x12\x19.cln.MultiwithdrawRequest\x1a\x1a.cln.MultiwithdrawResponse\"\x00\x12\x30\n\x05Offer\x12\x11.cln.OfferRequest\x1a\x12.cln.OfferResponse\"\x00\x12T\n\x11OpenChannel_Abort\x12\x1d.cln.Openchannel_abortRequest\x1a\x1e.cln.Openchannel_abortResponse\"\x00\x12Q\n\x10OpenChannel_Bump\x12\x1c.cln.Openchannel_bumpRequest\x1a\x1d.cln.Openchannel_bumpResponse\"\x00\x12Q\n\x10OpenChannel_Init\x12\x1c.cln.Openchannel_initRequest\x1a\x1d.cln.Openchannel_initResponse\"\x00\x12W\n\x12OpenChannel_Signed\x12\x1e.cln.Openchannel_signedRequest\x1a\x1f.cln.Openchannel_signedResponse\"\x00\x12W\n\x12OpenChannel_Update\x12\x1e.cln.Openchannel_updateRequest\x1a\x1f.cln.Openchannel_updateResponse\"\x00\x12-\n\x04Ping\x12\x10.cln.PingRequest\x1a\x11.cln.PingResponse\"\x00\x12\x33\n\x06Plugin\x12\x12.cln.PluginRequest\x1a\x13.cln.PluginResponse\"\x00\x12H\n\rRenePayStatus\x12\x19.cln.RenepaystatusRequest\x1a\x1a.cln.RenepaystatusResponse\"\x00\x12\x36\n\x07RenePay\x12\x13.cln.RenepayRequest\x1a\x14.cln.RenepayResponse\"\x00\x12H\n\rReserveInputs\x12\x19.cln.ReserveinputsRequest\x1a\x1a.cln.ReserveinputsResponse\"\x00\x12H\n\rSendCustomMsg\x12\x19.cln.SendcustommsgRequest\x1a\x1a.cln.SendcustommsgResponse\"\x00\x12\x42\n\x0bSendInvoice\x12\x17.cln.SendinvoiceRequest\x1a\x18.cln.SendinvoiceResponse\"\x00\x12?\n\nSetChannel\x12\x16.cln.SetchannelRequest\x1a\x17.cln.SetchannelResponse\"\x00\x12<\n\tSetConfig\x12\x15.cln.SetconfigRequest\x1a\x16.cln.SetconfigResponse\"\x00\x12K\n\x0eSetPsbtVersion\x12\x1a.cln.SetpsbtversionRequest\x1a\x1b.cln.SetpsbtversionResponse\"\x00\x12\x42\n\x0bSignInvoice\x12\x17.cln.SigninvoiceRequest\x1a\x18.cln.SigninvoiceResponse\"\x00\x12\x42\n\x0bSignMessage\x12\x17.cln.SignmessageRequest\x1a\x18.cln.SignmessageResponse\"\x00\x12\x42\n\x0bSplice_Init\x12\x17.cln.Splice_initRequest\x1a\x18.cln.Splice_initResponse\"\x00\x12H\n\rSplice_Signed\x12\x19.cln.Splice_signedRequest\x1a\x1a.cln.Splice_signedResponse\"\x00\x12H\n\rSplice_Update\x12\x19.cln.Splice_updateRequest\x1a\x1a.cln.Splice_updateResponse\"\x00\x12N\n\x0fUnreserveInputs\x12\x1b.cln.UnreserveinputsRequest\x1a\x1c.cln.UnreserveinputsResponse\"\x00\x12H\n\rUpgradeWallet\x12\x19.cln.UpgradewalletRequest\x1a\x1a.cln.UpgradewalletResponse\"\x00\x12N\n\x0fWaitBlockHeight\x12\x1b.cln.WaitblockheightRequest\x1a\x1c.cln.WaitblockheightResponse\"\x00\x12-\n\x04Wait\x12\x10.cln.WaitRequest\x1a\x11.cln.WaitResponse\"\x00\x12\x42\n\x0bListConfigs\x12\x17.cln.ListconfigsRequest\x1a\x18.cln.ListconfigsResponse\"\x00\x12-\n\x04Stop\x12\x10.cln.StopRequest\x1a\x11.cln.StopResponse\"\x00\x12-\n\x04Help\x12\x10.cln.HelpRequest\x1a\x11.cln.HelpResponse\"\x00\x12T\n\x11PreApproveKeysend\x12\x1d.cln.PreapprovekeysendRequest\x1a\x1e.cln.PreapprovekeysendResponse\"\x00\x12T\n\x11PreApproveInvoice\x12\x1d.cln.PreapproveinvoiceRequest\x1a\x1e.cln.PreapproveinvoiceResponse\"\x00\x12\x45\n\x0cStaticBackup\x12\x18.cln.StaticbackupRequest\x1a\x19.cln.StaticbackupResponse\"\x00\x12N\n\x0f\x42kprChannelsApy\x12\x1b.cln.BkprchannelsapyRequest\x1a\x1c.cln.BkprchannelsapyResponse\"\x00\x12T\n\x11\x42kprDumpIncomeCsv\x12\x1d.cln.BkprdumpincomecsvRequest\x1a\x1e.cln.BkprdumpincomecsvResponse\"\x00\x12\x42\n\x0b\x42kprInspect\x12\x17.cln.BkprinspectRequest\x1a\x18.cln.BkprinspectResponse\"\x00\x12`\n\x15\x42kprListAccountEvents\x12!.cln.BkprlistaccounteventsRequest\x1a\".cln.BkprlistaccounteventsResponse\"\x00\x12Q\n\x10\x42kprListBalances\x12\x1c.cln.BkprlistbalancesRequest\x1a\x1d.cln.BkprlistbalancesResponse\"\x00\x12K\n\x0e\x42kprListIncome\x12\x1a.cln.BkprlistincomeRequest\x1a\x1b.cln.BkprlistincomeResponse\"\x00\x12H\n\rBlacklistRune\x12\x19.cln.BlacklistruneRequest\x1a\x1a.cln.BlacklistruneResponse\"\x00\x12<\n\tCheckRune\x12\x15.cln.CheckruneRequest\x1a\x16.cln.CheckruneResponse\"\x00\x12?\n\nCreateRune\x12\x16.cln.CreateruneRequest\x1a\x17.cln.CreateruneResponse\"\x00\x12<\n\tShowRunes\x12\x15.cln.ShowrunesRequest\x1a\x16.cln.ShowrunesResponse\"\x00\x12T\n\x13SubscribeBlockAdded\x12\x1c.cln.StreamBlockAddedRequest\x1a\x1b.cln.BlockAddedNotification\"\x00\x30\x01\x12i\n\x1aSubscribeChannelOpenFailed\x12#.cln.StreamChannelOpenFailedRequest\x1a\".cln.ChannelOpenFailedNotification\"\x00\x30\x01\x12]\n\x16SubscribeChannelOpened\x12\x1f.cln.StreamChannelOpenedRequest\x1a\x1e.cln.ChannelOpenedNotification\"\x00\x30\x01\x12O\n\x10SubscribeConnect\x12\x19.cln.StreamConnectRequest\x1a\x1c.cln.PeerConnectNotification\"\x00\x30\x01\x12Q\n\x12SubscribeCustomMsg\x12\x1b.cln.StreamCustomMsgRequest\x1a\x1a.cln.CustomMsgNotification\"\x00\x30\x01\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -675,315 +675,315 @@ _globals['_SPLICE_SIGNEDREQUEST']._serialized_start=61618 _globals['_SPLICE_SIGNEDREQUEST']._serialized_end=61714 _globals['_SPLICE_SIGNEDRESPONSE']._serialized_start=61716 - _globals['_SPLICE_SIGNEDRESPONSE']._serialized_end=61797 - _globals['_SPLICE_UPDATEREQUEST']._serialized_start=61799 - _globals['_SPLICE_UPDATEREQUEST']._serialized_end=61855 - _globals['_SPLICE_UPDATERESPONSE']._serialized_start=61857 - _globals['_SPLICE_UPDATERESPONSE']._serialized_end=61923 - _globals['_UNRESERVEINPUTSREQUEST']._serialized_start=61925 - _globals['_UNRESERVEINPUTSREQUEST']._serialized_end=61997 - _globals['_UNRESERVEINPUTSRESPONSE']._serialized_start=61999 - _globals['_UNRESERVEINPUTSRESPONSE']._serialized_end=62080 - _globals['_UNRESERVEINPUTSRESERVATIONS']._serialized_start=62083 - _globals['_UNRESERVEINPUTSRESERVATIONS']._serialized_end=62234 - _globals['_UPGRADEWALLETREQUEST']._serialized_start=62236 - _globals['_UPGRADEWALLETREQUEST']._serialized_end=62346 - _globals['_UPGRADEWALLETRESPONSE']._serialized_start=62349 - _globals['_UPGRADEWALLETRESPONSE']._serialized_end=62498 - _globals['_WAITBLOCKHEIGHTREQUEST']._serialized_start=62500 - _globals['_WAITBLOCKHEIGHTREQUEST']._serialized_end=62579 - _globals['_WAITBLOCKHEIGHTRESPONSE']._serialized_start=62581 - _globals['_WAITBLOCKHEIGHTRESPONSE']._serialized_end=62627 - _globals['_WAITREQUEST']._serialized_start=62630 - _globals['_WAITREQUEST']._serialized_end=62879 - _globals['_WAITREQUEST_WAITSUBSYSTEM']._serialized_start=62766 - _globals['_WAITREQUEST_WAITSUBSYSTEM']._serialized_end=62823 - _globals['_WAITREQUEST_WAITINDEXNAME']._serialized_start=62825 - _globals['_WAITREQUEST_WAITINDEXNAME']._serialized_end=62879 - _globals['_WAITRESPONSE']._serialized_start=62882 - _globals['_WAITRESPONSE']._serialized_end=63161 - _globals['_WAITRESPONSE_WAITSUBSYSTEM']._serialized_start=62766 - _globals['_WAITRESPONSE_WAITSUBSYSTEM']._serialized_end=62823 - _globals['_WAITDETAILS']._serialized_start=63164 - _globals['_WAITDETAILS']._serialized_end=63800 - _globals['_WAITDETAILS_WAITDETAILSSTATUS']._serialized_start=63506 - _globals['_WAITDETAILS_WAITDETAILSSTATUS']._serialized_end=63643 - _globals['_LISTCONFIGSREQUEST']._serialized_start=63802 - _globals['_LISTCONFIGSREQUEST']._serialized_end=63854 - _globals['_LISTCONFIGSRESPONSE']._serialized_start=63857 - _globals['_LISTCONFIGSRESPONSE']._serialized_end=67408 - _globals['_LISTCONFIGSCONFIGS']._serialized_start=67411 - _globals['_LISTCONFIGSCONFIGS']._serialized_end=73394 - _globals['_LISTCONFIGSCONFIGSCONF']._serialized_start=73397 - _globals['_LISTCONFIGSCONFIGSCONF']._serialized_end=73559 - _globals['_LISTCONFIGSCONFIGSCONF_LISTCONFIGSCONFIGSCONFSOURCE']._serialized_start=73516 - _globals['_LISTCONFIGSCONFIGSCONF_LISTCONFIGSCONFIGSCONFSOURCE']._serialized_end=73559 - _globals['_LISTCONFIGSCONFIGSDEVELOPER']._serialized_start=73561 - _globals['_LISTCONFIGSCONFIGSDEVELOPER']._serialized_end=73619 - _globals['_LISTCONFIGSCONFIGSCLEARPLUGINS']._serialized_start=73621 - _globals['_LISTCONFIGSCONFIGSCLEARPLUGINS']._serialized_end=73682 - _globals['_LISTCONFIGSCONFIGSDISABLEMPP']._serialized_start=73684 - _globals['_LISTCONFIGSCONFIGSDISABLEMPP']._serialized_end=73775 - _globals['_LISTCONFIGSCONFIGSMAINNET']._serialized_start=73777 - _globals['_LISTCONFIGSCONFIGSMAINNET']._serialized_end=73833 - _globals['_LISTCONFIGSCONFIGSREGTEST']._serialized_start=73835 - _globals['_LISTCONFIGSCONFIGSREGTEST']._serialized_end=73891 - _globals['_LISTCONFIGSCONFIGSSIGNET']._serialized_start=73893 - _globals['_LISTCONFIGSCONFIGSSIGNET']._serialized_end=73948 - _globals['_LISTCONFIGSCONFIGSTESTNET']._serialized_start=73950 - _globals['_LISTCONFIGSCONFIGSTESTNET']._serialized_end=74006 - _globals['_LISTCONFIGSCONFIGSIMPORTANTPLUGIN']._serialized_start=74008 - _globals['_LISTCONFIGSCONFIGSIMPORTANTPLUGIN']._serialized_end=74080 - _globals['_LISTCONFIGSCONFIGSPLUGIN']._serialized_start=74082 - _globals['_LISTCONFIGSCONFIGSPLUGIN']._serialized_end=74145 - _globals['_LISTCONFIGSCONFIGSPLUGINDIR']._serialized_start=74147 - _globals['_LISTCONFIGSCONFIGSPLUGINDIR']._serialized_end=74213 - _globals['_LISTCONFIGSCONFIGSLIGHTNINGDIR']._serialized_start=74215 - _globals['_LISTCONFIGSCONFIGSLIGHTNINGDIR']._serialized_end=74282 - _globals['_LISTCONFIGSCONFIGSNETWORK']._serialized_start=74284 - _globals['_LISTCONFIGSCONFIGSNETWORK']._serialized_end=74346 - _globals['_LISTCONFIGSCONFIGSALLOWDEPRECATEDAPIS']._serialized_start=74348 - _globals['_LISTCONFIGSCONFIGSALLOWDEPRECATEDAPIS']._serialized_end=74423 - _globals['_LISTCONFIGSCONFIGSRPCFILE']._serialized_start=74425 - _globals['_LISTCONFIGSCONFIGSRPCFILE']._serialized_end=74487 - _globals['_LISTCONFIGSCONFIGSDISABLEPLUGIN']._serialized_start=74489 - _globals['_LISTCONFIGSCONFIGSDISABLEPLUGIN']._serialized_end=74559 - _globals['_LISTCONFIGSCONFIGSALWAYSUSEPROXY']._serialized_start=74561 - _globals['_LISTCONFIGSCONFIGSALWAYSUSEPROXY']._serialized_end=74631 - _globals['_LISTCONFIGSCONFIGSDAEMON']._serialized_start=74633 - _globals['_LISTCONFIGSCONFIGSDAEMON']._serialized_end=74688 - _globals['_LISTCONFIGSCONFIGSWALLET']._serialized_start=74690 - _globals['_LISTCONFIGSCONFIGSWALLET']._serialized_end=74751 - _globals['_LISTCONFIGSCONFIGSLARGECHANNELS']._serialized_start=74753 - _globals['_LISTCONFIGSCONFIGSLARGECHANNELS']._serialized_end=74815 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALDUALFUND']._serialized_start=74817 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALDUALFUND']._serialized_end=74886 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALSPLICING']._serialized_start=74888 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALSPLICING']._serialized_end=74957 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALONIONMESSAGES']._serialized_start=74959 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALONIONMESSAGES']._serialized_end=75033 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALOFFERS']._serialized_start=75035 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALOFFERS']._serialized_end=75102 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALSHUTDOWNWRONGFUNDING']._serialized_start=75104 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALSHUTDOWNWRONGFUNDING']._serialized_end=75185 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALPEERSTORAGE']._serialized_start=75187 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALPEERSTORAGE']._serialized_end=75259 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALANCHORS']._serialized_start=75261 - _globals['_LISTCONFIGSCONFIGSEXPERIMENTALANCHORS']._serialized_end=75329 - _globals['_LISTCONFIGSCONFIGSDATABASEUPGRADE']._serialized_start=75331 - _globals['_LISTCONFIGSCONFIGSDATABASEUPGRADE']._serialized_end=75402 - _globals['_LISTCONFIGSCONFIGSRGB']._serialized_start=75404 - _globals['_LISTCONFIGSCONFIGSRGB']._serialized_end=75462 - _globals['_LISTCONFIGSCONFIGSALIAS']._serialized_start=75464 - _globals['_LISTCONFIGSCONFIGSALIAS']._serialized_end=75524 - _globals['_LISTCONFIGSCONFIGSPIDFILE']._serialized_start=75526 - _globals['_LISTCONFIGSCONFIGSPIDFILE']._serialized_end=75588 - _globals['_LISTCONFIGSCONFIGSIGNOREFEELIMITS']._serialized_start=75590 - _globals['_LISTCONFIGSCONFIGSIGNOREFEELIMITS']._serialized_end=75661 - _globals['_LISTCONFIGSCONFIGSWATCHTIMEBLOCKS']._serialized_start=75663 - _globals['_LISTCONFIGSCONFIGSWATCHTIMEBLOCKS']._serialized_end=75733 - _globals['_LISTCONFIGSCONFIGSMAXLOCKTIMEBLOCKS']._serialized_start=75735 - _globals['_LISTCONFIGSCONFIGSMAXLOCKTIMEBLOCKS']._serialized_end=75807 - _globals['_LISTCONFIGSCONFIGSFUNDINGCONFIRMS']._serialized_start=75809 - _globals['_LISTCONFIGSCONFIGSFUNDINGCONFIRMS']._serialized_end=75879 - _globals['_LISTCONFIGSCONFIGSCLTVDELTA']._serialized_start=75881 - _globals['_LISTCONFIGSCONFIGSCLTVDELTA']._serialized_end=75945 - _globals['_LISTCONFIGSCONFIGSCLTVFINAL']._serialized_start=75947 - _globals['_LISTCONFIGSCONFIGSCLTVFINAL']._serialized_end=76011 - _globals['_LISTCONFIGSCONFIGSCOMMITTIME']._serialized_start=76013 - _globals['_LISTCONFIGSCONFIGSCOMMITTIME']._serialized_end=76078 - _globals['_LISTCONFIGSCONFIGSFEEBASE']._serialized_start=76080 - _globals['_LISTCONFIGSCONFIGSFEEBASE']._serialized_end=76142 - _globals['_LISTCONFIGSCONFIGSRESCAN']._serialized_start=76144 - _globals['_LISTCONFIGSCONFIGSRESCAN']._serialized_end=76205 - _globals['_LISTCONFIGSCONFIGSFEEPERSATOSHI']._serialized_start=76207 - _globals['_LISTCONFIGSCONFIGSFEEPERSATOSHI']._serialized_end=76275 - _globals['_LISTCONFIGSCONFIGSMAXCONCURRENTHTLCS']._serialized_start=76277 - _globals['_LISTCONFIGSCONFIGSMAXCONCURRENTHTLCS']._serialized_end=76350 - _globals['_LISTCONFIGSCONFIGSHTLCMINIMUMMSAT']._serialized_start=76352 - _globals['_LISTCONFIGSCONFIGSHTLCMINIMUMMSAT']._serialized_end=76436 - _globals['_LISTCONFIGSCONFIGSHTLCMAXIMUMMSAT']._serialized_start=76438 - _globals['_LISTCONFIGSCONFIGSHTLCMAXIMUMMSAT']._serialized_end=76522 - _globals['_LISTCONFIGSCONFIGSMAXDUSTHTLCEXPOSUREMSAT']._serialized_start=76524 - _globals['_LISTCONFIGSCONFIGSMAXDUSTHTLCEXPOSUREMSAT']._serialized_end=76616 - _globals['_LISTCONFIGSCONFIGSMINCAPACITYSAT']._serialized_start=76618 - _globals['_LISTCONFIGSCONFIGSMINCAPACITYSAT']._serialized_end=76721 - _globals['_LISTCONFIGSCONFIGSADDR']._serialized_start=76723 - _globals['_LISTCONFIGSCONFIGSADDR']._serialized_end=76784 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDR']._serialized_start=76786 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDR']._serialized_end=76855 - _globals['_LISTCONFIGSCONFIGSBINDADDR']._serialized_start=76857 - _globals['_LISTCONFIGSCONFIGSBINDADDR']._serialized_end=76922 - _globals['_LISTCONFIGSCONFIGSOFFLINE']._serialized_start=76924 - _globals['_LISTCONFIGSCONFIGSOFFLINE']._serialized_end=76980 - _globals['_LISTCONFIGSCONFIGSAUTOLISTEN']._serialized_start=76982 - _globals['_LISTCONFIGSCONFIGSAUTOLISTEN']._serialized_end=77048 - _globals['_LISTCONFIGSCONFIGSPROXY']._serialized_start=77050 - _globals['_LISTCONFIGSCONFIGSPROXY']._serialized_end=77110 - _globals['_LISTCONFIGSCONFIGSDISABLEDNS']._serialized_start=77112 - _globals['_LISTCONFIGSCONFIGSDISABLEDNS']._serialized_end=77171 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVERED']._serialized_start=77174 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVERED']._serialized_end=77432 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVERED_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVEREDVALUE_STR']._serialized_start=77350 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVERED_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVEREDVALUE_STR']._serialized_end=77432 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVEREDPORT']._serialized_start=77434 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVEREDPORT']._serialized_end=77515 - _globals['_LISTCONFIGSCONFIGSENCRYPTEDHSM']._serialized_start=77517 - _globals['_LISTCONFIGSCONFIGSENCRYPTEDHSM']._serialized_end=77578 - _globals['_LISTCONFIGSCONFIGSRPCFILEMODE']._serialized_start=77580 - _globals['_LISTCONFIGSCONFIGSRPCFILEMODE']._serialized_end=77646 - _globals['_LISTCONFIGSCONFIGSLOGLEVEL']._serialized_start=77648 - _globals['_LISTCONFIGSCONFIGSLOGLEVEL']._serialized_end=77711 - _globals['_LISTCONFIGSCONFIGSLOGPREFIX']._serialized_start=77713 - _globals['_LISTCONFIGSCONFIGSLOGPREFIX']._serialized_end=77777 - _globals['_LISTCONFIGSCONFIGSLOGFILE']._serialized_start=77779 - _globals['_LISTCONFIGSCONFIGSLOGFILE']._serialized_end=77843 - _globals['_LISTCONFIGSCONFIGSLOGTIMESTAMPS']._serialized_start=77845 - _globals['_LISTCONFIGSCONFIGSLOGTIMESTAMPS']._serialized_end=77914 - _globals['_LISTCONFIGSCONFIGSFORCEFEERATES']._serialized_start=77916 - _globals['_LISTCONFIGSCONFIGSFORCEFEERATES']._serialized_end=77984 - _globals['_LISTCONFIGSCONFIGSSUBDAEMON']._serialized_start=77986 - _globals['_LISTCONFIGSCONFIGSSUBDAEMON']._serialized_end=78052 - _globals['_LISTCONFIGSCONFIGSFETCHINVOICENOCONNECT']._serialized_start=78054 - _globals['_LISTCONFIGSCONFIGSFETCHINVOICENOCONNECT']._serialized_end=78156 - _globals['_LISTCONFIGSCONFIGSACCEPTHTLCTLVTYPES']._serialized_start=78158 - _globals['_LISTCONFIGSCONFIGSACCEPTHTLCTLVTYPES']._serialized_end=78231 - _globals['_LISTCONFIGSCONFIGSTORSERVICEPASSWORD']._serialized_start=78233 - _globals['_LISTCONFIGSCONFIGSTORSERVICEPASSWORD']._serialized_end=78306 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDNS']._serialized_start=78308 - _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDNS']._serialized_end=78379 - _globals['_LISTCONFIGSCONFIGSREQUIRECONFIRMEDINPUTS']._serialized_start=78381 - _globals['_LISTCONFIGSCONFIGSREQUIRECONFIRMEDINPUTS']._serialized_end=78459 - _globals['_LISTCONFIGSCONFIGSCOMMITFEE']._serialized_start=78461 - _globals['_LISTCONFIGSCONFIGSCOMMITFEE']._serialized_end=78525 - _globals['_LISTCONFIGSCONFIGSCOMMITFEERATEOFFSET']._serialized_start=78527 - _globals['_LISTCONFIGSCONFIGSCOMMITFEERATEOFFSET']._serialized_end=78601 - _globals['_LISTCONFIGSPLUGINS']._serialized_start=78603 - _globals['_LISTCONFIGSPLUGINS']._serialized_end=78717 - _globals['_LISTCONFIGSPLUGINSOPTIONS']._serialized_start=78719 - _globals['_LISTCONFIGSPLUGINSOPTIONS']._serialized_end=78746 - _globals['_LISTCONFIGSIMPORTANTPLUGINS']._serialized_start=78749 - _globals['_LISTCONFIGSIMPORTANTPLUGINS']._serialized_end=78881 - _globals['_LISTCONFIGSIMPORTANTPLUGINSOPTIONS']._serialized_start=78883 - _globals['_LISTCONFIGSIMPORTANTPLUGINSOPTIONS']._serialized_end=78919 - _globals['_STOPREQUEST']._serialized_start=78921 - _globals['_STOPREQUEST']._serialized_end=78934 - _globals['_STOPRESPONSE']._serialized_start=78936 - _globals['_STOPRESPONSE']._serialized_end=79049 - _globals['_STOPRESPONSE_STOPRESULT']._serialized_start=79003 - _globals['_STOPRESPONSE_STOPRESULT']._serialized_end=79038 - _globals['_HELPREQUEST']._serialized_start=79051 - _globals['_HELPREQUEST']._serialized_end=79098 - _globals['_HELPRESPONSE']._serialized_start=79101 - _globals['_HELPRESPONSE']._serialized_end=79250 - _globals['_HELPRESPONSE_HELPFORMATHINT']._serialized_start=79206 - _globals['_HELPRESPONSE_HELPFORMATHINT']._serialized_end=79234 - _globals['_HELPHELP']._serialized_start=79252 - _globals['_HELPHELP']._serialized_end=79279 - _globals['_PREAPPROVEKEYSENDREQUEST']._serialized_start=79281 - _globals['_PREAPPROVEKEYSENDREQUEST']._serialized_end=79384 - _globals['_PREAPPROVEKEYSENDRESPONSE']._serialized_start=79386 - _globals['_PREAPPROVEKEYSENDRESPONSE']._serialized_end=79413 - _globals['_PREAPPROVEINVOICEREQUEST']._serialized_start=79415 - _globals['_PREAPPROVEINVOICEREQUEST']._serialized_end=79457 - _globals['_PREAPPROVEINVOICERESPONSE']._serialized_start=79459 - _globals['_PREAPPROVEINVOICERESPONSE']._serialized_end=79486 - _globals['_STATICBACKUPREQUEST']._serialized_start=79488 - _globals['_STATICBACKUPREQUEST']._serialized_end=79509 - _globals['_STATICBACKUPRESPONSE']._serialized_start=79511 - _globals['_STATICBACKUPRESPONSE']._serialized_end=79546 - _globals['_BKPRCHANNELSAPYREQUEST']._serialized_start=79548 - _globals['_BKPRCHANNELSAPYREQUEST']._serialized_end=79648 - _globals['_BKPRCHANNELSAPYRESPONSE']._serialized_start=79650 - _globals['_BKPRCHANNELSAPYRESPONSE']._serialized_end=79731 - _globals['_BKPRCHANNELSAPYCHANNELS_APY']._serialized_start=79734 - _globals['_BKPRCHANNELSAPYCHANNELS_APY']._serialized_end=80624 - _globals['_BKPRDUMPINCOMECSVREQUEST']._serialized_start=80627 - _globals['_BKPRDUMPINCOMECSVREQUEST']._serialized_end=80837 - _globals['_BKPRDUMPINCOMECSVRESPONSE']._serialized_start=80840 - _globals['_BKPRDUMPINCOMECSVRESPONSE']._serialized_end=81054 - _globals['_BKPRDUMPINCOMECSVRESPONSE_BKPRDUMPINCOMECSVCSV_FORMAT']._serialized_start=80967 - _globals['_BKPRDUMPINCOMECSVRESPONSE_BKPRDUMPINCOMECSVCSV_FORMAT']._serialized_end=81054 - _globals['_BKPRINSPECTREQUEST']._serialized_start=81056 - _globals['_BKPRINSPECTREQUEST']._serialized_end=81093 - _globals['_BKPRINSPECTRESPONSE']._serialized_start=81095 - _globals['_BKPRINSPECTRESPONSE']._serialized_end=81150 - _globals['_BKPRINSPECTTXS']._serialized_start=81153 - _globals['_BKPRINSPECTTXS']._serialized_end=81307 - _globals['_BKPRINSPECTTXSOUTPUTS']._serialized_start=81310 - _globals['_BKPRINSPECTTXSOUTPUTS']._serialized_end=81754 - _globals['_BKPRLISTACCOUNTEVENTSREQUEST']._serialized_start=81756 - _globals['_BKPRLISTACCOUNTEVENTSREQUEST']._serialized_end=81860 - _globals['_BKPRLISTACCOUNTEVENTSRESPONSE']._serialized_start=81862 - _globals['_BKPRLISTACCOUNTEVENTSRESPONSE']._serialized_end=81943 - _globals['_BKPRLISTACCOUNTEVENTSEVENTS']._serialized_start=81946 - _globals['_BKPRLISTACCOUNTEVENTSEVENTS']._serialized_end=82619 - _globals['_BKPRLISTACCOUNTEVENTSEVENTS_BKPRLISTACCOUNTEVENTSEVENTSTYPE']._serialized_start=82422 - _globals['_BKPRLISTACCOUNTEVENTSEVENTS_BKPRLISTACCOUNTEVENTSEVENTSTYPE']._serialized_end=82496 - _globals['_BKPRLISTBALANCESREQUEST']._serialized_start=82621 - _globals['_BKPRLISTBALANCESREQUEST']._serialized_end=82646 - _globals['_BKPRLISTBALANCESRESPONSE']._serialized_start=82648 - _globals['_BKPRLISTBALANCESRESPONSE']._serialized_end=82723 - _globals['_BKPRLISTBALANCESACCOUNTS']._serialized_start=82726 - _globals['_BKPRLISTBALANCESACCOUNTS']._serialized_end=83052 - _globals['_BKPRLISTBALANCESACCOUNTSBALANCES']._serialized_start=83054 - _globals['_BKPRLISTBALANCESACCOUNTSBALANCES']._serialized_end=83142 - _globals['_BKPRLISTINCOMEREQUEST']._serialized_start=83145 - _globals['_BKPRLISTINCOMEREQUEST']._serialized_end=83296 - _globals['_BKPRLISTINCOMERESPONSE']._serialized_start=83298 - _globals['_BKPRLISTINCOMERESPONSE']._serialized_end=83379 - _globals['_BKPRLISTINCOMEINCOME_EVENTS']._serialized_start=83382 - _globals['_BKPRLISTINCOMEINCOME_EVENTS']._serialized_end=83691 - _globals['_BLACKLISTRUNEREQUEST']._serialized_start=83693 - _globals['_BLACKLISTRUNEREQUEST']._serialized_end=83771 - _globals['_BLACKLISTRUNERESPONSE']._serialized_start=83773 - _globals['_BLACKLISTRUNERESPONSE']._serialized_end=83844 - _globals['_BLACKLISTRUNEBLACKLIST']._serialized_start=83846 - _globals['_BLACKLISTRUNEBLACKLIST']._serialized_end=83898 - _globals['_CHECKRUNEREQUEST']._serialized_start=83900 - _globals['_CHECKRUNEREQUEST']._serialized_end=84012 - _globals['_CHECKRUNERESPONSE']._serialized_start=84014 - _globals['_CHECKRUNERESPONSE']._serialized_end=84048 - _globals['_CREATERUNEREQUEST']._serialized_start=84050 - _globals['_CREATERUNEREQUEST']._serialized_end=84119 - _globals['_CREATERUNERESPONSE']._serialized_start=84121 - _globals['_CREATERUNERESPONSE']._serialized_end=84244 - _globals['_SHOWRUNESREQUEST']._serialized_start=84246 - _globals['_SHOWRUNESREQUEST']._serialized_end=84292 - _globals['_SHOWRUNESRESPONSE']._serialized_start=84294 - _globals['_SHOWRUNESRESPONSE']._serialized_end=84349 - _globals['_SHOWRUNESRUNES']._serialized_start=84352 - _globals['_SHOWRUNESRUNES']._serialized_end=84637 - _globals['_SHOWRUNESRUNESRESTRICTIONS']._serialized_start=84639 - _globals['_SHOWRUNESRUNESRESTRICTIONS']._serialized_end=84751 - _globals['_SHOWRUNESRUNESRESTRICTIONSALTERNATIVES']._serialized_start=84753 - _globals['_SHOWRUNESRUNESRESTRICTIONSALTERNATIVES']._serialized_end=84863 - _globals['_STREAMBLOCKADDEDREQUEST']._serialized_start=84865 - _globals['_STREAMBLOCKADDEDREQUEST']._serialized_end=84890 - _globals['_BLOCKADDEDNOTIFICATION']._serialized_start=84892 - _globals['_BLOCKADDEDNOTIFICATION']._serialized_end=84946 - _globals['_STREAMCHANNELOPENFAILEDREQUEST']._serialized_start=84948 - _globals['_STREAMCHANNELOPENFAILEDREQUEST']._serialized_end=84980 - _globals['_CHANNELOPENFAILEDNOTIFICATION']._serialized_start=84982 - _globals['_CHANNELOPENFAILEDNOTIFICATION']._serialized_end=85033 - _globals['_STREAMCHANNELOPENEDREQUEST']._serialized_start=85035 - _globals['_STREAMCHANNELOPENEDREQUEST']._serialized_end=85063 - _globals['_CHANNELOPENEDNOTIFICATION']._serialized_start=85065 - _globals['_CHANNELOPENEDNOTIFICATION']._serialized_end=85184 - _globals['_STREAMCONNECTREQUEST']._serialized_start=85186 - _globals['_STREAMCONNECTREQUEST']._serialized_end=85208 - _globals['_PEERCONNECTNOTIFICATION']._serialized_start=85211 - _globals['_PEERCONNECTNOTIFICATION']._serialized_end=85401 - _globals['_PEERCONNECTNOTIFICATION_PEERCONNECTDIRECTION']._serialized_start=85362 - _globals['_PEERCONNECTNOTIFICATION_PEERCONNECTDIRECTION']._serialized_end=85401 - _globals['_PEERCONNECTADDRESS']._serialized_start=85404 - _globals['_PEERCONNECTADDRESS']._serialized_end=85671 - _globals['_PEERCONNECTADDRESS_PEERCONNECTADDRESSTYPE']._serialized_start=85555 - _globals['_PEERCONNECTADDRESS_PEERCONNECTADDRESSTYPE']._serialized_end=85639 - _globals['_STREAMCUSTOMMSGREQUEST']._serialized_start=85673 - _globals['_STREAMCUSTOMMSGREQUEST']._serialized_end=85697 - _globals['_CUSTOMMSGNOTIFICATION']._serialized_start=85699 - _globals['_CUSTOMMSGNOTIFICATION']._serialized_end=85756 - _globals['_NODE']._serialized_start=85759 - _globals['_NODE']._serialized_end=93898 + _globals['_SPLICE_SIGNEDRESPONSE']._serialized_end=61811 + _globals['_SPLICE_UPDATEREQUEST']._serialized_start=61813 + _globals['_SPLICE_UPDATEREQUEST']._serialized_end=61869 + _globals['_SPLICE_UPDATERESPONSE']._serialized_start=61871 + _globals['_SPLICE_UPDATERESPONSE']._serialized_end=61993 + _globals['_UNRESERVEINPUTSREQUEST']._serialized_start=61995 + _globals['_UNRESERVEINPUTSREQUEST']._serialized_end=62067 + _globals['_UNRESERVEINPUTSRESPONSE']._serialized_start=62069 + _globals['_UNRESERVEINPUTSRESPONSE']._serialized_end=62150 + _globals['_UNRESERVEINPUTSRESERVATIONS']._serialized_start=62153 + _globals['_UNRESERVEINPUTSRESERVATIONS']._serialized_end=62304 + _globals['_UPGRADEWALLETREQUEST']._serialized_start=62306 + _globals['_UPGRADEWALLETREQUEST']._serialized_end=62416 + _globals['_UPGRADEWALLETRESPONSE']._serialized_start=62419 + _globals['_UPGRADEWALLETRESPONSE']._serialized_end=62568 + _globals['_WAITBLOCKHEIGHTREQUEST']._serialized_start=62570 + _globals['_WAITBLOCKHEIGHTREQUEST']._serialized_end=62649 + _globals['_WAITBLOCKHEIGHTRESPONSE']._serialized_start=62651 + _globals['_WAITBLOCKHEIGHTRESPONSE']._serialized_end=62697 + _globals['_WAITREQUEST']._serialized_start=62700 + _globals['_WAITREQUEST']._serialized_end=62949 + _globals['_WAITREQUEST_WAITSUBSYSTEM']._serialized_start=62836 + _globals['_WAITREQUEST_WAITSUBSYSTEM']._serialized_end=62893 + _globals['_WAITREQUEST_WAITINDEXNAME']._serialized_start=62895 + _globals['_WAITREQUEST_WAITINDEXNAME']._serialized_end=62949 + _globals['_WAITRESPONSE']._serialized_start=62952 + _globals['_WAITRESPONSE']._serialized_end=63231 + _globals['_WAITRESPONSE_WAITSUBSYSTEM']._serialized_start=62836 + _globals['_WAITRESPONSE_WAITSUBSYSTEM']._serialized_end=62893 + _globals['_WAITDETAILS']._serialized_start=63234 + _globals['_WAITDETAILS']._serialized_end=63870 + _globals['_WAITDETAILS_WAITDETAILSSTATUS']._serialized_start=63576 + _globals['_WAITDETAILS_WAITDETAILSSTATUS']._serialized_end=63713 + _globals['_LISTCONFIGSREQUEST']._serialized_start=63872 + _globals['_LISTCONFIGSREQUEST']._serialized_end=63924 + _globals['_LISTCONFIGSRESPONSE']._serialized_start=63927 + _globals['_LISTCONFIGSRESPONSE']._serialized_end=67478 + _globals['_LISTCONFIGSCONFIGS']._serialized_start=67481 + _globals['_LISTCONFIGSCONFIGS']._serialized_end=73464 + _globals['_LISTCONFIGSCONFIGSCONF']._serialized_start=73467 + _globals['_LISTCONFIGSCONFIGSCONF']._serialized_end=73629 + _globals['_LISTCONFIGSCONFIGSCONF_LISTCONFIGSCONFIGSCONFSOURCE']._serialized_start=73586 + _globals['_LISTCONFIGSCONFIGSCONF_LISTCONFIGSCONFIGSCONFSOURCE']._serialized_end=73629 + _globals['_LISTCONFIGSCONFIGSDEVELOPER']._serialized_start=73631 + _globals['_LISTCONFIGSCONFIGSDEVELOPER']._serialized_end=73689 + _globals['_LISTCONFIGSCONFIGSCLEARPLUGINS']._serialized_start=73691 + _globals['_LISTCONFIGSCONFIGSCLEARPLUGINS']._serialized_end=73752 + _globals['_LISTCONFIGSCONFIGSDISABLEMPP']._serialized_start=73754 + _globals['_LISTCONFIGSCONFIGSDISABLEMPP']._serialized_end=73845 + _globals['_LISTCONFIGSCONFIGSMAINNET']._serialized_start=73847 + _globals['_LISTCONFIGSCONFIGSMAINNET']._serialized_end=73903 + _globals['_LISTCONFIGSCONFIGSREGTEST']._serialized_start=73905 + _globals['_LISTCONFIGSCONFIGSREGTEST']._serialized_end=73961 + _globals['_LISTCONFIGSCONFIGSSIGNET']._serialized_start=73963 + _globals['_LISTCONFIGSCONFIGSSIGNET']._serialized_end=74018 + _globals['_LISTCONFIGSCONFIGSTESTNET']._serialized_start=74020 + _globals['_LISTCONFIGSCONFIGSTESTNET']._serialized_end=74076 + _globals['_LISTCONFIGSCONFIGSIMPORTANTPLUGIN']._serialized_start=74078 + _globals['_LISTCONFIGSCONFIGSIMPORTANTPLUGIN']._serialized_end=74150 + _globals['_LISTCONFIGSCONFIGSPLUGIN']._serialized_start=74152 + _globals['_LISTCONFIGSCONFIGSPLUGIN']._serialized_end=74215 + _globals['_LISTCONFIGSCONFIGSPLUGINDIR']._serialized_start=74217 + _globals['_LISTCONFIGSCONFIGSPLUGINDIR']._serialized_end=74283 + _globals['_LISTCONFIGSCONFIGSLIGHTNINGDIR']._serialized_start=74285 + _globals['_LISTCONFIGSCONFIGSLIGHTNINGDIR']._serialized_end=74352 + _globals['_LISTCONFIGSCONFIGSNETWORK']._serialized_start=74354 + _globals['_LISTCONFIGSCONFIGSNETWORK']._serialized_end=74416 + _globals['_LISTCONFIGSCONFIGSALLOWDEPRECATEDAPIS']._serialized_start=74418 + _globals['_LISTCONFIGSCONFIGSALLOWDEPRECATEDAPIS']._serialized_end=74493 + _globals['_LISTCONFIGSCONFIGSRPCFILE']._serialized_start=74495 + _globals['_LISTCONFIGSCONFIGSRPCFILE']._serialized_end=74557 + _globals['_LISTCONFIGSCONFIGSDISABLEPLUGIN']._serialized_start=74559 + _globals['_LISTCONFIGSCONFIGSDISABLEPLUGIN']._serialized_end=74629 + _globals['_LISTCONFIGSCONFIGSALWAYSUSEPROXY']._serialized_start=74631 + _globals['_LISTCONFIGSCONFIGSALWAYSUSEPROXY']._serialized_end=74701 + _globals['_LISTCONFIGSCONFIGSDAEMON']._serialized_start=74703 + _globals['_LISTCONFIGSCONFIGSDAEMON']._serialized_end=74758 + _globals['_LISTCONFIGSCONFIGSWALLET']._serialized_start=74760 + _globals['_LISTCONFIGSCONFIGSWALLET']._serialized_end=74821 + _globals['_LISTCONFIGSCONFIGSLARGECHANNELS']._serialized_start=74823 + _globals['_LISTCONFIGSCONFIGSLARGECHANNELS']._serialized_end=74885 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALDUALFUND']._serialized_start=74887 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALDUALFUND']._serialized_end=74956 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALSPLICING']._serialized_start=74958 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALSPLICING']._serialized_end=75027 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALONIONMESSAGES']._serialized_start=75029 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALONIONMESSAGES']._serialized_end=75103 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALOFFERS']._serialized_start=75105 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALOFFERS']._serialized_end=75172 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALSHUTDOWNWRONGFUNDING']._serialized_start=75174 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALSHUTDOWNWRONGFUNDING']._serialized_end=75255 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALPEERSTORAGE']._serialized_start=75257 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALPEERSTORAGE']._serialized_end=75329 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALANCHORS']._serialized_start=75331 + _globals['_LISTCONFIGSCONFIGSEXPERIMENTALANCHORS']._serialized_end=75399 + _globals['_LISTCONFIGSCONFIGSDATABASEUPGRADE']._serialized_start=75401 + _globals['_LISTCONFIGSCONFIGSDATABASEUPGRADE']._serialized_end=75472 + _globals['_LISTCONFIGSCONFIGSRGB']._serialized_start=75474 + _globals['_LISTCONFIGSCONFIGSRGB']._serialized_end=75532 + _globals['_LISTCONFIGSCONFIGSALIAS']._serialized_start=75534 + _globals['_LISTCONFIGSCONFIGSALIAS']._serialized_end=75594 + _globals['_LISTCONFIGSCONFIGSPIDFILE']._serialized_start=75596 + _globals['_LISTCONFIGSCONFIGSPIDFILE']._serialized_end=75658 + _globals['_LISTCONFIGSCONFIGSIGNOREFEELIMITS']._serialized_start=75660 + _globals['_LISTCONFIGSCONFIGSIGNOREFEELIMITS']._serialized_end=75731 + _globals['_LISTCONFIGSCONFIGSWATCHTIMEBLOCKS']._serialized_start=75733 + _globals['_LISTCONFIGSCONFIGSWATCHTIMEBLOCKS']._serialized_end=75803 + _globals['_LISTCONFIGSCONFIGSMAXLOCKTIMEBLOCKS']._serialized_start=75805 + _globals['_LISTCONFIGSCONFIGSMAXLOCKTIMEBLOCKS']._serialized_end=75877 + _globals['_LISTCONFIGSCONFIGSFUNDINGCONFIRMS']._serialized_start=75879 + _globals['_LISTCONFIGSCONFIGSFUNDINGCONFIRMS']._serialized_end=75949 + _globals['_LISTCONFIGSCONFIGSCLTVDELTA']._serialized_start=75951 + _globals['_LISTCONFIGSCONFIGSCLTVDELTA']._serialized_end=76015 + _globals['_LISTCONFIGSCONFIGSCLTVFINAL']._serialized_start=76017 + _globals['_LISTCONFIGSCONFIGSCLTVFINAL']._serialized_end=76081 + _globals['_LISTCONFIGSCONFIGSCOMMITTIME']._serialized_start=76083 + _globals['_LISTCONFIGSCONFIGSCOMMITTIME']._serialized_end=76148 + _globals['_LISTCONFIGSCONFIGSFEEBASE']._serialized_start=76150 + _globals['_LISTCONFIGSCONFIGSFEEBASE']._serialized_end=76212 + _globals['_LISTCONFIGSCONFIGSRESCAN']._serialized_start=76214 + _globals['_LISTCONFIGSCONFIGSRESCAN']._serialized_end=76275 + _globals['_LISTCONFIGSCONFIGSFEEPERSATOSHI']._serialized_start=76277 + _globals['_LISTCONFIGSCONFIGSFEEPERSATOSHI']._serialized_end=76345 + _globals['_LISTCONFIGSCONFIGSMAXCONCURRENTHTLCS']._serialized_start=76347 + _globals['_LISTCONFIGSCONFIGSMAXCONCURRENTHTLCS']._serialized_end=76420 + _globals['_LISTCONFIGSCONFIGSHTLCMINIMUMMSAT']._serialized_start=76422 + _globals['_LISTCONFIGSCONFIGSHTLCMINIMUMMSAT']._serialized_end=76506 + _globals['_LISTCONFIGSCONFIGSHTLCMAXIMUMMSAT']._serialized_start=76508 + _globals['_LISTCONFIGSCONFIGSHTLCMAXIMUMMSAT']._serialized_end=76592 + _globals['_LISTCONFIGSCONFIGSMAXDUSTHTLCEXPOSUREMSAT']._serialized_start=76594 + _globals['_LISTCONFIGSCONFIGSMAXDUSTHTLCEXPOSUREMSAT']._serialized_end=76686 + _globals['_LISTCONFIGSCONFIGSMINCAPACITYSAT']._serialized_start=76688 + _globals['_LISTCONFIGSCONFIGSMINCAPACITYSAT']._serialized_end=76791 + _globals['_LISTCONFIGSCONFIGSADDR']._serialized_start=76793 + _globals['_LISTCONFIGSCONFIGSADDR']._serialized_end=76854 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDR']._serialized_start=76856 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDR']._serialized_end=76925 + _globals['_LISTCONFIGSCONFIGSBINDADDR']._serialized_start=76927 + _globals['_LISTCONFIGSCONFIGSBINDADDR']._serialized_end=76992 + _globals['_LISTCONFIGSCONFIGSOFFLINE']._serialized_start=76994 + _globals['_LISTCONFIGSCONFIGSOFFLINE']._serialized_end=77050 + _globals['_LISTCONFIGSCONFIGSAUTOLISTEN']._serialized_start=77052 + _globals['_LISTCONFIGSCONFIGSAUTOLISTEN']._serialized_end=77118 + _globals['_LISTCONFIGSCONFIGSPROXY']._serialized_start=77120 + _globals['_LISTCONFIGSCONFIGSPROXY']._serialized_end=77180 + _globals['_LISTCONFIGSCONFIGSDISABLEDNS']._serialized_start=77182 + _globals['_LISTCONFIGSCONFIGSDISABLEDNS']._serialized_end=77241 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVERED']._serialized_start=77244 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVERED']._serialized_end=77502 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVERED_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVEREDVALUE_STR']._serialized_start=77420 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVERED_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVEREDVALUE_STR']._serialized_end=77502 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVEREDPORT']._serialized_start=77504 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDISCOVEREDPORT']._serialized_end=77585 + _globals['_LISTCONFIGSCONFIGSENCRYPTEDHSM']._serialized_start=77587 + _globals['_LISTCONFIGSCONFIGSENCRYPTEDHSM']._serialized_end=77648 + _globals['_LISTCONFIGSCONFIGSRPCFILEMODE']._serialized_start=77650 + _globals['_LISTCONFIGSCONFIGSRPCFILEMODE']._serialized_end=77716 + _globals['_LISTCONFIGSCONFIGSLOGLEVEL']._serialized_start=77718 + _globals['_LISTCONFIGSCONFIGSLOGLEVEL']._serialized_end=77781 + _globals['_LISTCONFIGSCONFIGSLOGPREFIX']._serialized_start=77783 + _globals['_LISTCONFIGSCONFIGSLOGPREFIX']._serialized_end=77847 + _globals['_LISTCONFIGSCONFIGSLOGFILE']._serialized_start=77849 + _globals['_LISTCONFIGSCONFIGSLOGFILE']._serialized_end=77913 + _globals['_LISTCONFIGSCONFIGSLOGTIMESTAMPS']._serialized_start=77915 + _globals['_LISTCONFIGSCONFIGSLOGTIMESTAMPS']._serialized_end=77984 + _globals['_LISTCONFIGSCONFIGSFORCEFEERATES']._serialized_start=77986 + _globals['_LISTCONFIGSCONFIGSFORCEFEERATES']._serialized_end=78054 + _globals['_LISTCONFIGSCONFIGSSUBDAEMON']._serialized_start=78056 + _globals['_LISTCONFIGSCONFIGSSUBDAEMON']._serialized_end=78122 + _globals['_LISTCONFIGSCONFIGSFETCHINVOICENOCONNECT']._serialized_start=78124 + _globals['_LISTCONFIGSCONFIGSFETCHINVOICENOCONNECT']._serialized_end=78226 + _globals['_LISTCONFIGSCONFIGSACCEPTHTLCTLVTYPES']._serialized_start=78228 + _globals['_LISTCONFIGSCONFIGSACCEPTHTLCTLVTYPES']._serialized_end=78301 + _globals['_LISTCONFIGSCONFIGSTORSERVICEPASSWORD']._serialized_start=78303 + _globals['_LISTCONFIGSCONFIGSTORSERVICEPASSWORD']._serialized_end=78376 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDNS']._serialized_start=78378 + _globals['_LISTCONFIGSCONFIGSANNOUNCEADDRDNS']._serialized_end=78449 + _globals['_LISTCONFIGSCONFIGSREQUIRECONFIRMEDINPUTS']._serialized_start=78451 + _globals['_LISTCONFIGSCONFIGSREQUIRECONFIRMEDINPUTS']._serialized_end=78529 + _globals['_LISTCONFIGSCONFIGSCOMMITFEE']._serialized_start=78531 + _globals['_LISTCONFIGSCONFIGSCOMMITFEE']._serialized_end=78595 + _globals['_LISTCONFIGSCONFIGSCOMMITFEERATEOFFSET']._serialized_start=78597 + _globals['_LISTCONFIGSCONFIGSCOMMITFEERATEOFFSET']._serialized_end=78671 + _globals['_LISTCONFIGSPLUGINS']._serialized_start=78673 + _globals['_LISTCONFIGSPLUGINS']._serialized_end=78787 + _globals['_LISTCONFIGSPLUGINSOPTIONS']._serialized_start=78789 + _globals['_LISTCONFIGSPLUGINSOPTIONS']._serialized_end=78816 + _globals['_LISTCONFIGSIMPORTANTPLUGINS']._serialized_start=78819 + _globals['_LISTCONFIGSIMPORTANTPLUGINS']._serialized_end=78951 + _globals['_LISTCONFIGSIMPORTANTPLUGINSOPTIONS']._serialized_start=78953 + _globals['_LISTCONFIGSIMPORTANTPLUGINSOPTIONS']._serialized_end=78989 + _globals['_STOPREQUEST']._serialized_start=78991 + _globals['_STOPREQUEST']._serialized_end=79004 + _globals['_STOPRESPONSE']._serialized_start=79006 + _globals['_STOPRESPONSE']._serialized_end=79119 + _globals['_STOPRESPONSE_STOPRESULT']._serialized_start=79073 + _globals['_STOPRESPONSE_STOPRESULT']._serialized_end=79108 + _globals['_HELPREQUEST']._serialized_start=79121 + _globals['_HELPREQUEST']._serialized_end=79168 + _globals['_HELPRESPONSE']._serialized_start=79171 + _globals['_HELPRESPONSE']._serialized_end=79320 + _globals['_HELPRESPONSE_HELPFORMATHINT']._serialized_start=79276 + _globals['_HELPRESPONSE_HELPFORMATHINT']._serialized_end=79304 + _globals['_HELPHELP']._serialized_start=79322 + _globals['_HELPHELP']._serialized_end=79349 + _globals['_PREAPPROVEKEYSENDREQUEST']._serialized_start=79351 + _globals['_PREAPPROVEKEYSENDREQUEST']._serialized_end=79454 + _globals['_PREAPPROVEKEYSENDRESPONSE']._serialized_start=79456 + _globals['_PREAPPROVEKEYSENDRESPONSE']._serialized_end=79483 + _globals['_PREAPPROVEINVOICEREQUEST']._serialized_start=79485 + _globals['_PREAPPROVEINVOICEREQUEST']._serialized_end=79527 + _globals['_PREAPPROVEINVOICERESPONSE']._serialized_start=79529 + _globals['_PREAPPROVEINVOICERESPONSE']._serialized_end=79556 + _globals['_STATICBACKUPREQUEST']._serialized_start=79558 + _globals['_STATICBACKUPREQUEST']._serialized_end=79579 + _globals['_STATICBACKUPRESPONSE']._serialized_start=79581 + _globals['_STATICBACKUPRESPONSE']._serialized_end=79616 + _globals['_BKPRCHANNELSAPYREQUEST']._serialized_start=79618 + _globals['_BKPRCHANNELSAPYREQUEST']._serialized_end=79718 + _globals['_BKPRCHANNELSAPYRESPONSE']._serialized_start=79720 + _globals['_BKPRCHANNELSAPYRESPONSE']._serialized_end=79801 + _globals['_BKPRCHANNELSAPYCHANNELS_APY']._serialized_start=79804 + _globals['_BKPRCHANNELSAPYCHANNELS_APY']._serialized_end=80694 + _globals['_BKPRDUMPINCOMECSVREQUEST']._serialized_start=80697 + _globals['_BKPRDUMPINCOMECSVREQUEST']._serialized_end=80907 + _globals['_BKPRDUMPINCOMECSVRESPONSE']._serialized_start=80910 + _globals['_BKPRDUMPINCOMECSVRESPONSE']._serialized_end=81124 + _globals['_BKPRDUMPINCOMECSVRESPONSE_BKPRDUMPINCOMECSVCSV_FORMAT']._serialized_start=81037 + _globals['_BKPRDUMPINCOMECSVRESPONSE_BKPRDUMPINCOMECSVCSV_FORMAT']._serialized_end=81124 + _globals['_BKPRINSPECTREQUEST']._serialized_start=81126 + _globals['_BKPRINSPECTREQUEST']._serialized_end=81163 + _globals['_BKPRINSPECTRESPONSE']._serialized_start=81165 + _globals['_BKPRINSPECTRESPONSE']._serialized_end=81220 + _globals['_BKPRINSPECTTXS']._serialized_start=81223 + _globals['_BKPRINSPECTTXS']._serialized_end=81377 + _globals['_BKPRINSPECTTXSOUTPUTS']._serialized_start=81380 + _globals['_BKPRINSPECTTXSOUTPUTS']._serialized_end=81824 + _globals['_BKPRLISTACCOUNTEVENTSREQUEST']._serialized_start=81826 + _globals['_BKPRLISTACCOUNTEVENTSREQUEST']._serialized_end=81930 + _globals['_BKPRLISTACCOUNTEVENTSRESPONSE']._serialized_start=81932 + _globals['_BKPRLISTACCOUNTEVENTSRESPONSE']._serialized_end=82013 + _globals['_BKPRLISTACCOUNTEVENTSEVENTS']._serialized_start=82016 + _globals['_BKPRLISTACCOUNTEVENTSEVENTS']._serialized_end=82689 + _globals['_BKPRLISTACCOUNTEVENTSEVENTS_BKPRLISTACCOUNTEVENTSEVENTSTYPE']._serialized_start=82492 + _globals['_BKPRLISTACCOUNTEVENTSEVENTS_BKPRLISTACCOUNTEVENTSEVENTSTYPE']._serialized_end=82566 + _globals['_BKPRLISTBALANCESREQUEST']._serialized_start=82691 + _globals['_BKPRLISTBALANCESREQUEST']._serialized_end=82716 + _globals['_BKPRLISTBALANCESRESPONSE']._serialized_start=82718 + _globals['_BKPRLISTBALANCESRESPONSE']._serialized_end=82793 + _globals['_BKPRLISTBALANCESACCOUNTS']._serialized_start=82796 + _globals['_BKPRLISTBALANCESACCOUNTS']._serialized_end=83122 + _globals['_BKPRLISTBALANCESACCOUNTSBALANCES']._serialized_start=83124 + _globals['_BKPRLISTBALANCESACCOUNTSBALANCES']._serialized_end=83212 + _globals['_BKPRLISTINCOMEREQUEST']._serialized_start=83215 + _globals['_BKPRLISTINCOMEREQUEST']._serialized_end=83366 + _globals['_BKPRLISTINCOMERESPONSE']._serialized_start=83368 + _globals['_BKPRLISTINCOMERESPONSE']._serialized_end=83449 + _globals['_BKPRLISTINCOMEINCOME_EVENTS']._serialized_start=83452 + _globals['_BKPRLISTINCOMEINCOME_EVENTS']._serialized_end=83761 + _globals['_BLACKLISTRUNEREQUEST']._serialized_start=83763 + _globals['_BLACKLISTRUNEREQUEST']._serialized_end=83841 + _globals['_BLACKLISTRUNERESPONSE']._serialized_start=83843 + _globals['_BLACKLISTRUNERESPONSE']._serialized_end=83914 + _globals['_BLACKLISTRUNEBLACKLIST']._serialized_start=83916 + _globals['_BLACKLISTRUNEBLACKLIST']._serialized_end=83968 + _globals['_CHECKRUNEREQUEST']._serialized_start=83970 + _globals['_CHECKRUNEREQUEST']._serialized_end=84082 + _globals['_CHECKRUNERESPONSE']._serialized_start=84084 + _globals['_CHECKRUNERESPONSE']._serialized_end=84118 + _globals['_CREATERUNEREQUEST']._serialized_start=84120 + _globals['_CREATERUNEREQUEST']._serialized_end=84189 + _globals['_CREATERUNERESPONSE']._serialized_start=84191 + _globals['_CREATERUNERESPONSE']._serialized_end=84314 + _globals['_SHOWRUNESREQUEST']._serialized_start=84316 + _globals['_SHOWRUNESREQUEST']._serialized_end=84362 + _globals['_SHOWRUNESRESPONSE']._serialized_start=84364 + _globals['_SHOWRUNESRESPONSE']._serialized_end=84419 + _globals['_SHOWRUNESRUNES']._serialized_start=84422 + _globals['_SHOWRUNESRUNES']._serialized_end=84707 + _globals['_SHOWRUNESRUNESRESTRICTIONS']._serialized_start=84709 + _globals['_SHOWRUNESRUNESRESTRICTIONS']._serialized_end=84821 + _globals['_SHOWRUNESRUNESRESTRICTIONSALTERNATIVES']._serialized_start=84823 + _globals['_SHOWRUNESRUNESRESTRICTIONSALTERNATIVES']._serialized_end=84933 + _globals['_STREAMBLOCKADDEDREQUEST']._serialized_start=84935 + _globals['_STREAMBLOCKADDEDREQUEST']._serialized_end=84960 + _globals['_BLOCKADDEDNOTIFICATION']._serialized_start=84962 + _globals['_BLOCKADDEDNOTIFICATION']._serialized_end=85016 + _globals['_STREAMCHANNELOPENFAILEDREQUEST']._serialized_start=85018 + _globals['_STREAMCHANNELOPENFAILEDREQUEST']._serialized_end=85050 + _globals['_CHANNELOPENFAILEDNOTIFICATION']._serialized_start=85052 + _globals['_CHANNELOPENFAILEDNOTIFICATION']._serialized_end=85103 + _globals['_STREAMCHANNELOPENEDREQUEST']._serialized_start=85105 + _globals['_STREAMCHANNELOPENEDREQUEST']._serialized_end=85133 + _globals['_CHANNELOPENEDNOTIFICATION']._serialized_start=85135 + _globals['_CHANNELOPENEDNOTIFICATION']._serialized_end=85254 + _globals['_STREAMCONNECTREQUEST']._serialized_start=85256 + _globals['_STREAMCONNECTREQUEST']._serialized_end=85278 + _globals['_PEERCONNECTNOTIFICATION']._serialized_start=85281 + _globals['_PEERCONNECTNOTIFICATION']._serialized_end=85471 + _globals['_PEERCONNECTNOTIFICATION_PEERCONNECTDIRECTION']._serialized_start=85432 + _globals['_PEERCONNECTNOTIFICATION_PEERCONNECTDIRECTION']._serialized_end=85471 + _globals['_PEERCONNECTADDRESS']._serialized_start=85474 + _globals['_PEERCONNECTADDRESS']._serialized_end=85741 + _globals['_PEERCONNECTADDRESS_PEERCONNECTADDRESSTYPE']._serialized_start=85625 + _globals['_PEERCONNECTADDRESS_PEERCONNECTADDRESSTYPE']._serialized_end=85709 + _globals['_STREAMCUSTOMMSGREQUEST']._serialized_start=85743 + _globals['_STREAMCUSTOMMSGREQUEST']._serialized_end=85767 + _globals['_CUSTOMMSGNOTIFICATION']._serialized_start=85769 + _globals['_CUSTOMMSGNOTIFICATION']._serialized_end=85826 + _globals['_NODE']._serialized_start=85829 + _globals['_NODE']._serialized_end=93968 # @@protoc_insertion_point(module_scope) diff --git a/contrib/pyln-testing/pyln/testing/grpc2py.py b/contrib/pyln-testing/pyln/testing/grpc2py.py index b4dc11ab6d7e..561fe768bed9 100644 --- a/contrib/pyln-testing/pyln/testing/grpc2py.py +++ b/contrib/pyln-testing/pyln/testing/grpc2py.py @@ -1970,6 +1970,7 @@ def splice_init2py(m): def splice_signed2py(m): return remove_default({ "outnum": m.outnum, # PrimitiveField in generate_composite + "psbt": m.psbt, # PrimitiveField in generate_composite "tx": hexlify(m.tx), # PrimitiveField in generate_composite "txid": hexlify(m.txid), # PrimitiveField in generate_composite }) @@ -1979,6 +1980,7 @@ def splice_update2py(m): return remove_default({ "commitments_secured": m.commitments_secured, # PrimitiveField in generate_composite "psbt": m.psbt, # PrimitiveField in generate_composite + "signatures_secured": m.signatures_secured, # PrimitiveField in generate_composite }) diff --git a/doc/Makefile b/doc/Makefile index f8b59cc63391..3e86816c2585 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -50,6 +50,7 @@ GENERATE_MARKDOWN := doc/lightning-addgossip.7 \ doc/lightning-delpay.7 \ doc/lightning-deprecations.7 \ doc/lightning-dev-forget-channel.7 \ + doc/lightning-dev-splice.7 \ doc/lightning-disableinvoicerequest.7 \ doc/lightning-disableoffer.7 \ doc/lightning-disconnect.7 \ diff --git a/doc/index.rst b/doc/index.rst index d1c662e54f8b..357e65453f97 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -59,6 +59,7 @@ Core Lightning Documentation lightning-delpay lightning-deprecations lightning-dev-forget-channel + lightning-dev-splice lightning-disableinvoicerequest lightning-disableoffer lightning-disconnect diff --git a/doc/schemas/lightning-dev-splice.json b/doc/schemas/lightning-dev-splice.json new file mode 100644 index 000000000000..1c58fdedda55 --- /dev/null +++ b/doc/schemas/lightning-dev-splice.json @@ -0,0 +1,432 @@ +{ + "$schema": "../rpc-schema-draft.json", + "type": "object", + "additionalProperties": false, + "added": "v24.11", + "rpc": "dev-splice", + "title": "Command to initiate a channel to a peer", + "warning": "experimental-splicing only", + "description": [ + "`splice` is the command to move funds into or out of a channel. Multiple actions can be combined together resulting in a single onchain transaction. Funds may be moved out of a channel and into another in a single batch enabling cross-channel movement." + ], + "request": { + "required": [ + "script_or_json" + ], + "properties": { + "script_or_json": { + "type": "string", + "description": [ + "The splice script to execute or json equivilent" + ] + }, + "dryrun": { + "type": "boolean", + "description": [ + "Don't execute any actions and output a transcript of what would have been done" + ] + }, + "force_feerate": { + "type": "boolean", + "description": [ + "By default splices will fail if the fee provided looks too high. This is to protect against accidentally setting your fee higher than intended. Set `force_feerate` to true to skip this saftey check" + ] + }, + "debug_log": { + "type": "boolean", + "description": [ + "Adds a verbose log of each splice calculation step to the result" + ] + }, + "dev-wetrun": { + "type": "boolean", + "description": [ + "Executes the splice up until the point signatures would be sent and then aborts" + ] + } + } + }, + "response": { + "required": [], + "properties": { + "dryrun": { + "type": "array", + "items": { + "type": "string", + "description": [ + "One action line of the splice script result" + ] + }, + "description": [ + "The transcript of what the script would have done" + ] + }, + "psbt": { + "type": "string", + "description": [ + "The final psbt" + ] + }, + "tx": { + "type": "string", + "description": [ + "The final transaction in hex" + ] + }, + "txid": { + "type": "string", + "description": [ + "The txid of the final transaction" + ] + }, + "log": { + "type": "array", + "description": [ + "A verbose log of each step of splice calcuations" + ], + "items": { + "type": "string", + "description": [ + "A line of detail about splice calcuations" + ] + } + } + } + }, + "usage": [ + "The primary method is to make a `script` containing one or more splice actions", + "that will be merged into a single transaction. If possible the entire operation", + "will be completed and broadcast to the mempool.", + "", + "However if you specified your own inputs using `psbt`, then the command will", + "return a psbt that you must sign and then pass to `splice_signed`.", + "", + "It is required to pass `script_or_json`.", + "", + "It is recommended you first do a `dryrun` to confirm your script does what you", + "expect it to do.", + "", + "*script* The splice script to execute", + "", + "*dryrun* Don't execute any actions and output a transcript of what would have", + "been done", + "", + "*psbt* An initial psbt to begin the splice with", + "", + "*user\\_provided\\_sats* The amount of sats being contributed by the initial psbt", + "", + "*force\\_feerate* By default splices will fail if the fee provided looks too high.", + "This is to protect against accidentally setting your fee higher than intended.", + "Set to true to skip this saftey check", + "", + "*json* A json payload of instructions can be passed instead of script", + "", + "*debug\\_log* Adds a verbose log of each splice calculation step to the result", + "", + "*dev-wetrun* Executes the splice up until the point signatures would be sent and then aborts", + "", + "The primary purpose of splice script is to execute all types of splices using", + "a single command. You can perform all these actions manually using the lower", + "level api (see `splice_init`) however this splice command interface is much simpler to use", + "and it provides some security against signing maliciously inserted inputs.", + "", + "SCRIPT", + "-----", + "", + "A splice script is a series of 'segments' that are separated by newlines or ", + "semicolons. Each segment represents one splice action which is typically adding", + "to or removing from a channel. The funds are designated as going into the", + "channel or coming out of the channel by which side of an arrow \"->\" the channel", + "identifier is placed on. The amount of funds is placed on the other side of the", + "arrow.", + "", + "Take this example:", + "```shell", + "8338aef0 -> 10000sat", + "```", + "", + "This is how we take 10,000 sats out of channel 8338aef0.", + "", + "To put 10,000 sats into the channel, we make the arrow point into the channel", + "like so:", + "```shell", + "10000sat -> 8338aef0", + "```", + "", + "In the last two examples we specified the first 8 digits of the channel", + "identifier. You can specify as few as 4 digits of the beginning of the channel", + "identifier and it will be autocompleted to the matching channel. If the code", + "matches more than one channel or node id, the script will fail with an error.", + "", + "In order to put funds into a channel however, we need get the funds from", + "somewhere. The simplest place to get them is the built in onchain wallet. The", + "\"wallet\" operator can be placed just like channel identifiers. We can take funds", + "out of the wallet like so:", + "```shell", + "wallet -> 10000sat", + "```", + "", + "We can put funds back into the wallet like so:", + "```shell", + "10000sat -> wallet", + "```", + "", + "Now that we know how to take funds out of a wallet, let's combine them into an", + "individual script:", + "```shell", + "wallet -> 10000sat", + "10000sat -> 8338aef0", + "```", + "", + "The first line withdraws 10,000 sats from the wallet and puts them in the", + "script's \"general script funds.\" The second line takes 10,000 sats from the", + "\"general script funds\" and places them into channel 8338aef0. This example is", + "called a \"splice in.\"", + "", + "In order for this script to work, we need one more thing. Onchain fees must be", + "funded from somewhere. The simplest way to pay the fee from the \"general script", + "funds.\" If we change the amount going into the channel to a percentage, the fee", + "will automatically be taken from the \"general script funds\" like so:", + "```shell", + "wallet -> 10000sat", + "100% -> 8338aef0", + "```", + "", + "When specifying a percentage instead of an amount, it means take that percentage", + "out of the \"general script fund.\"", + "", + "This will take 10,000 sats from the onchain wallet and put that amount less any", + "onchain fees into channel 8338aef0. The feerate used will be the node's", + "standard opening feerate. In order to use your own feerate you must us the fee", + "operator.", + "", + "The fee operator is attached to an amount. If you want to take out extra to", + "cover the fee, use \"+fee\" and if you want to reduce the amount being sent", + "somewhere use the \"-fee\" suffix. Take this example:", + "```shell", + "wallet -> 10000sat+fee", + "10000sat -> 8338aef0", + "```", + "", + "In this example we add precisely 10,000 sats to channel 8338aef0 and withdraw", + "enough from the wallet to cover the 10,000 sats and the onchain fee.", + "", + "To control the amount of fee, you can specify a fee-rate with the use of the at", + "\"@\" symbol after fee. After the at symbol, specify a number of sats to pay per", + "kiloweight (aka. perkw) like so:", + "```shell", + "wallet -> 10000sat+fee@300", + "10000sat -> 8338aef0", + "```", + "", + "This example pays a fee rate of 300 sats per thousand weight units. To view this", + "amount in other units (ie. sats/vbyte) execute a `dryrun` of the script.", + "", + "Instead of withdrawing extra from the wallet, we can reduce the amount going to", + "channel 8338aef0 using the \"-fee\" operator like so:", + "```shell", + "wallet -> 10000sat", + "10000sat-fee -> 8338aef0", + "```", + "", + "This example withdraws 10,000 sats from the onchain wallet, pays the onchain", + "fee from that amount, and puts the rest into channel 8338aef0.", + "", + "You can also specify the feerate here like so:", + "```shell", + "wallet -> 10000sat", + "10000sat-fee@300 -> 8338aef0", + "```", + "", + "Now let's build a script that takes funds out of a channel and puts them into", + "the onchain wallet:", + "```shell", + "8338aef0 -> 10000sat", + "100% -> wallet", + "```", + "", + "By default however, scripts that leave sats in the \"general script fund,\" will", + "be automatically sent to the wallet. So the second line is not needed, we can", + "simplify the script to:", + "```shell", + "8338aef0 -> 10000sat", + "```", + "", + "We can can also move sats to a specific bitcoin address like so:", + "```shell", + "8338aef0 -> 10000sat+fee", + "100% -> 1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu", + "```", + "", + "This example pays 10,000 sats to the address 1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu", + "out of your channel balance in 8338aef0.", + "", + "Percentages on the right side take out that amount of available funds from a", + "channel. For example:", + "```shell", + "8338aef0 -> 100%", + "```", + "", + "This takes all available funds out of channel 8338aef0 and puts them into the", + "onchain wallet. Note that available funds is restricted by pending HTLCs and", + "the 1% reserve requirement. To get all the funds you need to close the channel.", + "More useful would be something like this:", + "```shell", + "8338aef0 -> 50%", + "100% -> 07bfddea", + "```", + "", + "This example takes half the available funds from channel 8338aef0 and puts them", + "into channel 07bfddea.", + "", + "We can also split this amount like so:", + "```shell", + "8338aef0 -> 50%", + "50% -> 07bfddea", + "50% -> 09ad6278", + "```", + "", + "This example takes half the funds in 8338aef0 and splits them between channels", + "07bfddea and 09ad6278.", + "", + "If we want to send funds to more channels calculating percentages can get", + "unwieldy so we can use the asterisk operator \"\\*\" which divides the \"general", + "script funds\" amongst all destinations using it, like so:", + "```shell", + "8338aef0 -> 50%", + "* -> 07bfddea", + "* -> 09ad6278", + "* -> efc2a7ff", + "```", + "", + "This example takes half the available funds in 8338aef0 and splits them evenly", + "among three achannels.", + "", + "Sats can be specified with multiple suffixes including sat, msat, btc, M, or K.", + "The M suffix is shorthand for a million satoshis and the K suffix is shorthand", + "for a thousand satoshis. These can be combined with a decimal point like so:", + "```shell", + "07bfddea -> 1.23M", + "09ad6278 -> 900K", + "efc2a7ff -> 0.01btc", + "```", + "", + "This example takes 1,230,000 sats from 07bfddea, 900,000 sats from 09ad6278, and", + "1,000,000 sats from efc2a7ff and puts them in the onchain wallet.", + "", + "Another way to specify channel ids is a channel query. These take the form of a", + "node id, a colon, and a number or symbol (ie. \"034645dc:0\") which results in", + "your first channel with the peer whose node id starts with 034645dc. Change the", + "number after the colon to get a different index like so:", + "```shell", + "034645dc:0 -> 10K", + "034645dc:1 -> 10K", + "034645dc:2 -> 10K", + "```", + "", + "This example takes 10,000 sats out of the first three channels with peer", + "034645dc and puts the total minus fees into the onchain wallet.", + "", + "In addition to index numbers, the symbol after the colon can be a question mark", + "\"?\" or an asterisk \"\\*\" which mean match the first unused channel or all the", + "remaining channels respectively like so:", + "```shell", + "* -> 034645dc:?", + "* -> 03e3d03e:0", + "03e3d03e:* -> 100%", + "```", + "", + "This example takes 100% of available funds from all of 03e3d03e's channels", + "except the first one and splits them between 03e3d03e's first channel and", + "034645dc's first channel.", + "", + "The node id prefix can also be replaced with the asterisk \"\\*\" which means match", + "all nodes. This can be combined with the asterisk \"\\*\" that matches all unused", + "channels like so:", + "```shell", + "wallet -> 10000sat", + "100% -> *:*", + "```", + "", + "This example takes 10,000 sats from the onchain wallet and divides them between", + "all channels.", + "", + "It is possible to request a peer to add funds to a channel with a lease request.", + "This is done using the pipe \"|\" symbol and optionally specifying the maximum fee", + "you authorize using the at \"@\" symbol. After the pipe you specify the amount of", + "sats you would like to lease, followed by the at symbol and a percentage value", + "like so:", + "```shell", + "wallet -> 10M+fee", + "100%|10M@1% -> 8338aef0", + "```", + "", + "This example splices 10,000,000 sats into channel and requests your peer also", + "add 10,000,000 sats to the channel. If they fee they demand is over 1% or the lease", + "amount is too small the operation will be aborted. Whatever lease fee they do", + "charge will come out of the 10,000,000 sats going into the channel balance. The", + "onchain fee will be paid by taking extra funds out of the onchain wallet.", + "", + "Lease requests do not need to combined with splicing in funds but you must pay", + "the onchain fee from somewhere. One simple location to take the fees from is", + "your existing channel balance. Doing so requires using two arrows since funds", + "are going into and out of the channel at the same time, like so:", + "```shell", + "|10M@1% -> 8338aef0 -> 0+fee", + "```", + "", + "This example makes a lease request from your peer on 8338aef0 for 10,000,000", + "sats and pays the onchain fee using the channel balance. This is a particularly", + "elegant way to pay the onchain fee without adding any inputs or outputs beyond", + "the channel funding itself.", + "", + "When passing via the command line using semicolons can be simpler instead of", + "newlines. Here are some command line examples:", + "", + "Splice out 10 million satoshis to the onchain wallet", + "```shell", + "lightning-cli splice \"8338aef0 -> 10M\"", + "```", + "", + "Splice in 10 thousand satoshis from the onchain wallet", + "```shell", + "lightning-cli splice \"wallet -> 10K; 100% -> 8338aef0\"", + "```", + "", + "Send 900 thousand satoshis from a channel to an onchain address", + "```shell", + "lightning-cli splice \"8338aef0 -> 0.9M+fee; 0.9M -> 1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu\"", + "```", + "", + "Move 1 bitcoin between two channels", + "```shell", + "lightning-cli splice \"8338aef0 -> 1btc; 100% -> 07bfddea\"", + "```", + "", + "Splice in 100 thousand sats to the first channel with peer id 034645dc", + "```shell", + "lightning-cli splice \"wallet -> 0.1M; 100% -> 034645dc:?\"", + "```", + "", + "Splice in 100 thousand sats split across *all* channels with peer id 034645dc", + "```shell", + "lightning-cli splice \"wallet -> 100000; 100% -> 034645dc:*\"", + "```", + "", + "Take the maximum out of one chanel and split the value across peer 034645dc's", + "channel plus one more channel", + "```shell", + "lightning-cli splice \"8338aef0 -> 100%; * -> 034645dc:*; * -> 07bfddea\"", + "```" + ], + "author": [ + "Dusty <<@dusty_daemon>> is mainly responsible." + ], + "see_also": [ + "lightning-splice_signed(7)", + "lightning-splice_update(7)" + ], + "resources": [ + "Main web site: " + ] +} diff --git a/doc/schemas/lightning-splice_signed.json b/doc/schemas/lightning-splice_signed.json index c88cb0ca8b81..9981f221a127 100644 --- a/doc/schemas/lightning-splice_signed.json +++ b/doc/schemas/lightning-splice_signed.json @@ -26,7 +26,7 @@ "psbt": { "type": "string", "description": [ - "The final version of the psbt to complete the splice with." + "The psbt of the resulting transaction after splice negotiation(s)" ] }, "sign_first": { @@ -40,7 +40,8 @@ "response": { "required": [ "tx", - "txid" + "txid", + "psbt" ], "additionalProperties": false, "properties": { @@ -56,6 +57,12 @@ "The txid is of the final transaction." ] }, + "psbt": { + "type": "string", + "description": [ + "The psbt of the resulting transaction after splice negotiation(s)" + ] + }, "outnum": { "added": "v24.08", "type": "u32", diff --git a/doc/schemas/lightning-splice_update.json b/doc/schemas/lightning-splice_update.json index 8ab5f2bd3f8d..6a91b7307539 100644 --- a/doc/schemas/lightning-splice_update.json +++ b/doc/schemas/lightning-splice_update.json @@ -40,7 +40,8 @@ "response": { "required": [ "psbt", - "commitments_secured" + "commitments_secured", + "signatures_secured" ], "additionalProperties": false, "properties": { @@ -55,6 +56,13 @@ "description": [ "Whether or not the commitments were secured." ] + }, + "signatures_secured": { + "added": "v24.11", + "type": "boolean", + "description": [ + "whether or not the peer sent us their signatures for this splice" + ] } } }, @@ -135,7 +143,8 @@ }, "response": { "psbt": "cHNidP8BAgQCAAAAAQMEkgAAAAEEAQIBBQECAQYBAwH7BAIAAAAAAQCJAgAAAAH5+Z9NssTFQhFzAFkPSrEKg0AcgN7uwR9geC5Lqd+SfgAAAAAA/f///wJAQg8AAAAAACIAIJPe3QwmW8qGhXbT7i5Z7ruyDrwpblj37cqT1e6uwImWgWzcCwAAAAAiUSBbtDt/2hcV0N0BQWgloYUiotfssWR1uIeA6Pr8HHPviY0AAAABASuBbNwLAAAAACJRIFu0O3/aFxXQ3QFBaCWhhSKi1+yxZHW4h4Do+vwcc++JAQ4g9iEmrLThqBE+s85A7YDjSknUmwNcudNkF7HBMzInESwBDwQBAAAAARAE/f///wz8CWxpZ2h0bmluZwEImfI55kWjFBwAAQCJAgAAAAH5+Z9NssTFQhFzAFkPSrEKg0AcgN7uwR9geC5Lqd+SfgAAAAAA/f///wJAQg8AAAAAACIAIJPe3QwmW8qGhXbT7i5Z7ruyDrwpblj37cqT1e6uwImWgWzcCwAAAAAiUSBbtDt/2hcV0N0BQWgloYUiotfssWR1uIeA6Pr8HHPviY0AAAABAStAQg8AAAAAACIAIJPe3QwmW8qGhXbT7i5Z7ruyDrwpblj37cqT1e6uwImWAQ4g9iEmrLThqBE+s85A7YDjSknUmwNcudNkF7HBMzInESwBDwQAAAAAARAEAAAAAAz8CWxpZ2h0bmluZwEIo0w+EfrhL4QAAQMIzrnaCwAAAAABBCJRII+O1EYnVX28zEKuAYqcVHSpkShXksTKiRwfWcVmXTRgDPwJbGlnaHRuaW5nAQiPzwRTPwtPWgABAwjgyBAAAAAAAAEEIgAgk97dDCZbyoaFdtPuLlnuu7IOvCluWPftypPV7q7AiZYM/AlsaWdodG5pbmcBCK3lpE4Vja7KAA==", - "commitments_secured": true + "commitments_secured": true, + "signatures_secured": true } }, { @@ -149,7 +158,8 @@ }, "response": { "psbt": "cHNidP8BAgQCAAAAAQMElAAAAAEEAQEBBQECAQYBAwH7BAIAAAAAAQCyAgAAAAL2ISastOGoET6zzkDtgONKSdSbA1y502QXscEzMicRLAEAAAAA/f////YhJqy04agRPrPOQO2A40pJ1JsDXLnTZBexwTMyJxEsAAAAAAAAAAAAAs652gsAAAAAIlEgj47URidVfbzMQq4BipxUdKmRKFeSxMqJHB9ZxWZdNGDgyBAAAAAAACIAIJPe3QwmW8qGhXbT7i5Z7ruyDrwpblj37cqT1e6uwImWkgAAAAEBK+DIEAAAAAAAIgAgk97dDCZbyoaFdtPuLlnuu7IOvCluWPftypPV7q7AiZYBDiCVuxWBeu80WsQES0HKNSpjl7RUGPMhcKRnsXRp4BRF+AEPBAEAAAABEAQAAAAADPwJbGlnaHRuaW5nAQheLXaEp+y8AgABAwi4Lg8AAAAAAAEEIgAgk97dDCZbyoaFdtPuLlnuu7IOvCluWPftypPV7q7AiZYM/AlsaWdodG5pbmcBCBkNULro+QrwAAEDCKCGAQAAAAAAAQQiUSDE0oJBX5qB0Y4IthmhnRFrhlbLG/ST5fVAu/e3oFhM2gz8CWxpZ2h0bmluZwEIuBcidnXj4BAA", - "commitments_secured": true + "commitments_secured": true, + "signatures_secured": true } } ] diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 7c0b7211671d..8e23a6138abc 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,12 @@ #include #include +struct stfu_result +{ + struct channel_id channel_id; + struct amount_msat available_funds; +}; + struct splice_command { /* Inside struct lightningd splice_commands. */ struct list_node list; @@ -37,6 +44,11 @@ struct splice_command { struct command *cmd; /* Channel being spliced. */ struct channel *channel; + /* For multi-channel commands: remaining channels awaiting response. + * Allocated on ld -- free when finished. */ + struct channel_id **channel_ids; + /* For multi-channel stfu command: the pending result */ + struct stfu_result **results; }; void channel_update_feerates(struct lightningd *ld, const struct channel *channel) @@ -410,12 +422,13 @@ static void handle_splice_confirmed_update(struct lightningd *ld, { struct splice_command *cc; struct wally_psbt *psbt; - bool commitments_secured; + bool commitments_secured, signatures_secured; if (!fromwire_channeld_splice_confirmed_update(tmpctx, - msg, - &psbt, - &commitments_secured)) { + msg, + &psbt, + &commitments_secured, + &signatures_secured)) { channel_internal_error(channel, "bad splice_confirmed_update %s", tal_hex(channel, msg)); @@ -433,6 +446,7 @@ static void handle_splice_confirmed_update(struct lightningd *ld, struct json_stream *response = json_stream_success(cc->cmd); json_add_string(response, "psbt", fmt_wally_psbt(tmpctx, psbt)); json_add_bool(response, "commitments_secured", commitments_secured); + json_add_bool(response, "signatures_secured", signatures_secured); was_pending(command_success(cc->cmd, response)); } @@ -475,6 +489,7 @@ struct send_splice_info const struct bitcoin_tx *final_tx; u32 output_index; const char *err_msg; + const struct wally_psbt *psbt; }; static void handle_tx_broadcast(struct send_splice_info *info) @@ -502,6 +517,7 @@ static void handle_tx_broadcast(struct send_splice_info *info) json_add_hex(response, "tx", tx_bytes, tal_bytelen(tx_bytes)); json_add_txid(response, "txid", &txid); json_add_u32(response, "outnum", info->output_index); + json_add_psbt(response, "psbt", info->psbt); was_pending(command_success(info->cc->cmd, response)); } @@ -567,7 +583,8 @@ static void send_splice_tx_done(struct bitcoind *bitcoind UNUSED, static void send_splice_tx(struct channel *channel, const struct bitcoin_tx *tx, struct splice_command *cc, - u32 output_index) + u32 output_index, + struct wally_psbt *psbt) { struct lightningd *ld = channel->peer->ld; u8* tx_bytes = linearize_tx(tmpctx, tx); @@ -584,6 +601,7 @@ static void send_splice_tx(struct channel *channel, info->final_tx = tal_steal(info, tx); info->output_index = output_index; info->err_msg = NULL; + info->psbt = psbt; bitcoind_sendrawtx(ld->topology->bitcoind, ld->topology->bitcoind, @@ -633,7 +651,7 @@ static void handle_splice_confirmed_signed(struct lightningd *ld, cc = splice_command_for_chan(ld, channel); - send_splice_tx(channel, tx, cc, output_index); + send_splice_tx(channel, tx, cc, output_index, inflight->funding_psbt); } static enum watch_result splice_depth_cb(struct lightningd *ld, @@ -1420,6 +1438,75 @@ static void handle_local_anchors(struct channel *channel, const u8 *msg) } } +/* Channeld sends us this in response to a user's `stfu` request */ +static void handle_confirmed_stfu(struct lightningd *ld, + struct channel *channel, + const u8 *msg) +{ + struct splice_command *cc; + struct amount_msat available_funds; + struct stfu_result *stfu_result; + + if (!fromwire_channeld_confirmed_stfu(msg, + &available_funds)) { + channel_internal_error(channel, + "bad confirmed_stfu %s", + tal_hex(channel, msg)); + return; + } + + cc = splice_command_for_chan(ld, channel); + if (!cc) { + channel_internal_error(channel, "confirmed_stfu" + " received without an active command %s", + tal_hex(channel, msg)); + return; + } + + log_info(channel->log, "lightningd got confirmed stfu from channeld," + " channel_id count: %zu", tal_count(cc->channel_ids)); + + for (size_t i = 0; i < tal_count(cc->channel_ids); i++) { + if (channel_id_eq(cc->channel_ids[i], &channel->cid)) { + stfu_result = tal(cc->results, struct stfu_result); + stfu_result->channel_id = channel->cid; + stfu_result->available_funds = available_funds; + + tal_arr_expand(&cc->results, stfu_result); + tal_arr_remove(&cc->channel_ids, i); + + log_info(channel->log, "lightningd found channel_id in command and removed it"); + break; + } + } + + log_info(channel->log, "Finished processing confirmed stfu," + " channel_id count: %zu", tal_count(cc->channel_ids)); + + /* Once we run out of pending stfu requests we return to user */ + if (tal_count(cc->channel_ids)) + return; + + struct json_stream *response = json_stream_success(cc->cmd); + + json_array_start(response, "channels"); + for (size_t i = 0; i < tal_count(cc->results); i++) { + json_object_start(response, NULL); + json_add_channel_id(response, "channel_id", + &cc->results[i]->channel_id); + json_add_amount_msat(response, "available_msat", + cc->results[i]->available_funds); + json_object_end(response); + } + json_array_end(response); + + /* channel_ids and results are free'd when the last stfu is finished */ + tal_free(cc->channel_ids); + tal_free(cc->results); + + was_pending(command_success(cc->cmd, response)); +} + static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) { enum channeld_wire t = fromwire_peektype(msg); @@ -1497,6 +1584,9 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) case WIRE_CHANNELD_GOT_SPLICE_LOCKED: handle_peer_splice_locked(sd->channel, msg); break; + case WIRE_CHANNELD_CONFIRMED_STFU: + handle_confirmed_stfu(sd->ld, sd->channel, msg); + break; case WIRE_CHANNELD_UPGRADED: handle_channel_upgrade(sd->channel, msg); break; @@ -1526,7 +1616,9 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) case WIRE_CHANNELD_SPLICE_UPDATE: case WIRE_CHANNELD_SPLICE_LOOKUP_TX_RESULT: case WIRE_CHANNELD_SPLICE_SIGNED: + case WIRE_CHANNELD_STFU: case WIRE_CHANNELD_DEV_QUIESCE_REPLY: + case WIRE_CHANNELD_ABORT: break; } @@ -2035,20 +2127,10 @@ struct command_result *cancel_channel_before_broadcast(struct command *cmd, return command_still_pending(cmd); } -static struct command_result *param_channel_for_splice(struct command *cmd, - const char *name, - const char *buffer, - const jsmntok_t *tok, - struct channel **channel) +static struct command_result *channel_for_splice(struct command *cmd, + struct channel_id *cid, + struct channel **channel) { - struct command_result *result; - struct channel_id *cid; - - result = param_channel_id(cmd, name, buffer, tok, &cid); - - if (result != NULL) - return result; - *channel = channel_by_cid(cmd->ld, cid); if (!*channel) return command_fail(cmd, SPLICE_UNKNOWN_CHANNEL, @@ -2082,6 +2164,23 @@ static struct command_result *param_channel_for_splice(struct command *cmd, return NULL; } +static struct command_result *param_channel_for_splice(struct command *cmd, + const char *name, + const char *buffer, + const jsmntok_t *tok, + struct channel **channel) +{ + struct command_result *result; + struct channel_id *cid; + + result = param_channel_id(cmd, name, buffer, tok, &cid); + + if (result != NULL) + return result; + + return channel_for_splice(cmd, cid, channel); +} + static void destroy_splice_command(struct splice_command *cc) { list_del(&cc->list); @@ -2097,7 +2196,7 @@ static struct command_result *json_splice_init(struct command *cmd, struct wally_psbt *initialpsbt; s64 *relative_amount; u32 *feerate_per_kw; - bool *force_feerate; + bool *force_feerate, *skip_stfu; u8 *msg; if (!param_check(cmd, buffer, params, @@ -2106,6 +2205,7 @@ static struct command_result *json_splice_init(struct command *cmd, p_opt("initialpsbt", param_psbt, &initialpsbt), p_opt("feerate_per_kw", param_feerate, &feerate_per_kw), p_opt_def("force_feerate", param_bool, &force_feerate, false), + p_opt_def("skip_stfu", param_bool, &skip_stfu, false), NULL)) return command_param_failed(); @@ -2140,9 +2240,12 @@ static struct command_result *json_splice_init(struct command *cmd, cc->cmd = cmd; cc->channel = channel; + cc->channel_ids = NULL; + cc->results = NULL; msg = towire_channeld_splice_init(NULL, initialpsbt, *relative_amount, - *feerate_per_kw, *force_feerate); + *feerate_per_kw, *force_feerate, + *skip_stfu); subd_send_msg(channel->owner, take(msg)); return command_still_pending(cmd); @@ -2183,59 +2286,218 @@ static struct command_result *json_splice_update(struct command *cmd, cc->cmd = cmd; cc->channel = channel; + cc->channel_ids = NULL; + cc->results = NULL; subd_send_msg(channel->owner, take(towire_channeld_splice_update(NULL, psbt))); return command_still_pending(cmd); } +static struct command_result *single_splice_signed(struct command *cmd, + struct channel *channel, + struct wally_psbt *psbt, + bool sign_first, + bool *success) +{ + struct splice_command *cc; + u8 *msg; + + if (splice_command_for_chan(cmd->ld, channel)) + return command_fail(cmd, + SPLICE_BUSY_ERROR, + "Currently waiting on previous splice" + " command to finish."); + + cc = tal(cmd, struct splice_command); + + list_add_tail(&cmd->ld->splice_commands, &cc->list); + tal_add_destructor(cc, destroy_splice_command); + + cc->cmd = cmd; + cc->channel = channel; + cc->channel_ids = NULL; + cc->results = NULL; + + msg = towire_channeld_splice_signed(tmpctx, psbt, sign_first); + subd_send_msg(channel->owner, take(msg)); + if (success) + *success = true; + return command_still_pending(cmd); +} + static struct command_result *json_splice_signed(struct command *cmd, const char *buffer, const jsmntok_t *obj UNNEEDED, const jsmntok_t *params) { - u8 *msg; - struct channel *channel; - struct splice_command *cc; + struct channel *channel, **channels; struct wally_psbt *psbt; + struct channel_id *channel_ids; + struct command_result *result; bool *sign_first; + bool success; if (!param_check(cmd, buffer, params, - p_req("channel_id", param_channel_for_splice, &channel), p_req("psbt", param_psbt, &psbt), + p_opt("channel_id", param_channel_for_splice, &channel), p_opt_def("sign_first", param_bool, &sign_first, false), NULL)) return command_param_failed(); - if (splice_command_for_chan(cmd->ld, channel)) - return command_fail(cmd, - SPLICE_BUSY_ERROR, - "Currently waiting on previous splice" - " command to finish."); if (!validate_psbt(psbt)) - return command_fail(cmd, - SPLICE_INPUT_ERROR, + return command_fail(cmd, SPLICE_INPUT_ERROR, "PSBT failed to validate."); + /* If a single channel is specified, we do that and finish. */ + if (channel) { + if (command_check_only(cmd)) + return command_check_done(cmd); + return single_splice_signed(cmd, channel, psbt, *sign_first, + NULL); + } + + if (!psbt_get_channel_ids(tmpctx, psbt, &channel_ids)) + return command_fail(cmd, SPLICE_INPUT_ERROR, + "Unable to find channel_ids in psbt."); + + /* We load into channels in a seperate pass to do checks before + * beginning in earnest. */ + channels = tal_arr(tmpctx, struct channel*, tal_count(channel_ids)); + for (size_t i = 0; i < tal_count(channels); i++) { + result = channel_for_splice(cmd, &channel_ids[i], &channels[i]); + if (result) + return result; + } + if (command_check_only(cmd)) return command_check_done(cmd); - log_debug(cmd->ld->log, "splice_signed input PSBT version %d", - psbt->version); + /* Now execute the splice event for each channel */ + /* TODO: We need to intelligently choose the order of channel to splice, + * store the signatures received on each run, and pass them to the next + */ + for (size_t i = 0; i < tal_count(channels); i++) { + success = false; + result = single_splice_signed(cmd, channels[i], psbt, + *sign_first, &success); + /* If one channel fails, we stop there and return the error */ + if (!success) + return result; + } - cc = tal(cmd, struct splice_command); + /* If we did multiple channels, just return the last one */ + return result; +} - list_add_tail(&cmd->ld->splice_commands, &cc->list); - tal_add_destructor(cc, destroy_splice_command); +static struct command_result *json_stfu_channels(struct command *cmd, + const char *buffer, + const jsmntok_t *obj UNNEEDED, + const jsmntok_t *params) +{ + struct channel *channel, **channels; + struct channel_id **channel_ids; + const jsmntok_t *channel_ids_tok, *channel_id_tok; + struct command_result *result; + struct splice_command *cc; + struct stfu_result **stfu_result; + size_t i; - cc->cmd = cmd; - cc->channel = channel; + if (!param_check(cmd, buffer, params, + p_opt("channel_ids", param_array, &channel_ids_tok), + NULL)) + return command_param_failed(); + + channels = tal_arr(cmd, struct channel*, 0); + json_for_each_arr(i, channel_id_tok, channel_ids_tok) { + result = param_channel_for_splice(cmd, NULL, buffer, channel_id_tok, + &channel); + if (result) + return result; + if (splice_command_for_chan(cmd->ld, channel)) + return command_fail(cmd, + SPLICE_BUSY_ERROR, + "Currently waiting on previous" + " splice command to finish."); + + tal_arr_expand(&channels, channel); + } + + if (!tal_count(channels)) + return command_fail_badparam(cmd, "channel_ids", buffer, + channel_ids_tok, + "Must specify a channel"); + + if (command_check_only(cmd)) + return command_check_done(cmd); + + /* Next we split into multiple `stfu` commands. The final command to + * return will handle free'ing `stfu_result` and `channel_ids` */ + stfu_result = tal_arr(NULL, struct stfu_result*, 0); + channel_ids = tal_arr(NULL, struct channel_id*, tal_count(channels)); + + for (i = 0; i < tal_count(channels); i++) { + channel = channels[i]; + + channel_ids[i] = tal(channel_ids, struct channel_id); + *channel_ids[i] = channel->cid; + + cc = tal(cmd, struct splice_command); + + list_add_tail(&cmd->ld->splice_commands, &cc->list); + tal_add_destructor(cc, destroy_splice_command); + + cc->cmd = cmd; + cc->channel = channel; + cc->channel_ids = channel_ids; + cc->results = stfu_result; + + subd_send_msg(channel->owner, take(towire_channeld_stfu(NULL))); + } - msg = towire_channeld_splice_signed(tmpctx, psbt, *sign_first); - subd_send_msg(channel->owner, take(msg)); return command_still_pending(cmd); } +static struct command_result *json_abort_channels(struct command *cmd, + const char *buffer, + const jsmntok_t *obj UNNEEDED, + const jsmntok_t *params) +{ + struct channel **channels; + struct channel *channel; + const jsmntok_t *channel_ids_tok, *channel_id_tok; + struct command_result *result; + size_t i; + + if (!param_check(cmd, buffer, params, + p_opt("channel_ids", param_array, &channel_ids_tok), + NULL)) + return command_param_failed(); + + channels = tal_arr(cmd, struct channel*, 0); + json_for_each_arr(i, channel_id_tok, channel_ids_tok) { + result = param_channel_for_splice(cmd, NULL, buffer, channel_id_tok, + &channel); + if (result) + return result; + tal_arr_expand(&channels, channel); + } + + if (!tal_count(channels)) + return command_fail_badparam(cmd, "channel_ids", buffer, + channel_ids_tok, + "Must specify a channel"); + + if (command_check_only(cmd)) + return command_check_done(cmd); + + for (i = 0; i < tal_count(channels); i++) + subd_send_msg(channels[i]->owner, + take(towire_channeld_abort(NULL))); + + return command_success(cmd, json_stream_success(cmd)); +} + static const struct json_command splice_init_command = { "splice_init", json_splice_init, @@ -2254,6 +2516,18 @@ static const struct json_command splice_signed_command = { }; AUTODATA(json_command, &splice_signed_command); +static const struct json_command stfu_channels_command = { + "stfu_channels", + json_stfu_channels, +}; +AUTODATA(json_command, &stfu_channels_command); + +static const struct json_command abort_channels_command = { + "abort_channels", + json_abort_channels, +}; +AUTODATA(json_command, &abort_channels_command); + static struct command_result *json_dev_feerate(struct command *cmd, const char *buffer, const jsmntok_t *obj UNNEEDED, diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 755a06f9d9d3..902d5b87444b 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -822,6 +822,7 @@ static void NON_NULL_ARGS(1, 2, 4, 5) json_add_channel(struct command *cmd, struct amount_sat peer_funded_sats; const struct peer_update *peer_update; u32 feerate; + bool has_valid_inflights; json_object_start(response, key); json_add_node_id(response, "peer_id", &peer->id); @@ -910,7 +911,15 @@ static void NON_NULL_ARGS(1, 2, 4, 5) json_add_channel(struct command *cmd, json_add_txid(response, "funding_txid", &channel->funding.txid); json_add_num(response, "funding_outnum", channel->funding.n); + has_valid_inflights = false; if (!list_empty(&channel->inflights)) { + struct channel_inflight *inflight; + list_for_each(&channel->inflights, inflight, list) + if (!inflight->splice_locked_memonly) + has_valid_inflights = true; + } + + if (has_valid_inflights) { struct channel_inflight *initial, *inflight; u32 last_feerate, next_feerate; @@ -942,6 +951,8 @@ static void NON_NULL_ARGS(1, 2, 4, 5) json_add_channel(struct command *cmd, json_array_start(response, "inflight"); list_for_each(&channel->inflights, inflight, list) { struct bitcoin_txid txid; + if (inflight->splice_locked_memonly) + continue; json_object_start(response, NULL); json_add_txid(response, "funding_txid", @@ -3214,6 +3225,8 @@ static struct command_result *json_sign_last_tx(struct command *cmd, json_array_start(response, "inflights"); list_for_each(&channel->inflights, inflight, list) { + if (inflight->splice_locked_memonly) + continue; tx = sign_last_tx(cmd, channel, inflight->last_tx, &inflight->last_sig); json_object_start(response, NULL); diff --git a/plugins/Makefile b/plugins/Makefile index 1e2ff2168424..efe64d379d58 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -50,13 +50,15 @@ PLUGIN_SPENDER_SRC := \ plugins/spender/main.c \ plugins/spender/multifundchannel.c \ plugins/spender/multiwithdraw.c \ - plugins/spender/openchannel.c + plugins/spender/openchannel.c \ + plugins/spender/splice.c PLUGIN_SPENDER_HEADER := \ plugins/spender/multifundchannel.h \ plugins/spender/multiwithdraw.h \ plugins/spender/fundchannel.h \ plugins/spender/multifundchannel.h \ - plugins/spender/openchannel.h + plugins/spender/openchannel.h \ + plugins/spender/splice.h PLUGIN_SPENDER_OBJS := $(PLUGIN_SPENDER_SRC:.c=.o) PLUGIN_RECOVER_SRC := plugins/recover.c @@ -153,6 +155,7 @@ PLUGIN_COMMON_OBJS := \ bitcoin/signature.o \ bitcoin/tx.o \ bitcoin/varint.o \ + common/addr.o \ common/amount.o \ common/autodata.o \ common/coin_mvt.o \ @@ -179,6 +182,7 @@ PLUGIN_COMMON_OBJS := \ common/psbt_open.o \ common/pseudorand.o \ common/random_select.o \ + common/splice_script.o \ common/setup.o \ common/status_levels.o \ common/utils.o \ diff --git a/plugins/spender/main.c b/plugins/spender/main.c index 5a94785dacbc..0f4151876ceb 100644 --- a/plugins/spender/main.c +++ b/plugins/spender/main.c @@ -3,6 +3,7 @@ #include #include #include +#include /*~ The spender plugin contains various commands that handle * spending from the onchain wallet. */ @@ -27,6 +28,7 @@ int main(int argc, char **argv) tal_expand(&commands, multiwithdraw_commands, num_multiwithdraw_commands); tal_expand(&commands, fundchannel_commands, num_fundchannel_commands); tal_expand(&commands, multifundchannel_commands, num_multifundchannel_commands); + tal_expand(&commands, splice_commands, num_splice_commands); /* tal_expand(&commands, whatever_commands, num_whatever_commands); */ notifs = tal_arr(NULL, struct plugin_notification, 0); diff --git a/plugins/spender/splice.c b/plugins/spender/splice.c new file mode 100644 index 000000000000..f6963e5e6dca --- /dev/null +++ b/plugins/spender/splice.c @@ -0,0 +1,1449 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct abort_pkg { + struct splice_cmd *splice_cmd; + enum jsonrpc_errcode code; + char *str; +}; + +static void debug_log_to_json(struct json_stream *response, + const char *debug_log) +{ + char **lines = tal_strsplit(tmpctx, debug_log, "\n", STR_NO_EMPTY); + + for (size_t i = 0; lines[i]; i++) + json_add_string(response, NULL, lines[i]); +} + +static struct command_result *make_error(struct command *cmd, + struct abort_pkg *abort_pkg, + const char *phase) +{ + struct splice_cmd *splice_cmd = abort_pkg->splice_cmd; + char *str = abort_pkg->str; + struct json_stream *response = jsonrpc_stream_fail(cmd, + abort_pkg->code, + str ?: phase); + + if (splice_cmd->debug_log) { + json_array_start(response, "log"); + debug_log_to_json(response, splice_cmd->debug_log); + json_array_end(response); + } + + tal_free(abort_pkg); + + return command_finished(cmd, response); +} + +static struct command_result *unreserve_get_result(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *result, + struct abort_pkg *abort_pkg) +{ + struct splice_cmd *splice_cmd = abort_pkg->splice_cmd; + struct json_stream *response; + struct bitcoin_tx *tx; + u8 *tx_bytes; + + if (splice_cmd->wetrun) { + + response = jsonrpc_stream_success(cmd); + if (splice_cmd->psbt) { + json_add_psbt(response, "psbt", splice_cmd->psbt); + + tx = bitcoin_tx_with_psbt(tmpctx, splice_cmd->psbt); + tx_bytes = linearize_tx(tmpctx, tx); + json_add_hex(response, "tx", tx_bytes, + tal_bytelen(tx_bytes)); + json_add_txid(response, "txid", + &splice_cmd->final_txid); + } + + json_array_start(response, "log"); + debug_log_to_json(response, splice_cmd->debug_log); + json_array_end(response); + + tal_free(abort_pkg); + return command_finished(cmd, response); + } + + return make_error(cmd, abort_pkg, "unreserve_get_result"); +} + +static struct command_result *abort_get_result(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *result, + struct abort_pkg *abort_pkg) +{ + struct out_req *req; + struct splice_cmd *splice_cmd = abort_pkg->splice_cmd; + + plugin_log(cmd->plugin, LOG_DBG, + "unreserveinputs(psbt:%p)", splice_cmd->psbt); + + if (!splice_cmd->psbt) + return make_error(cmd, abort_pkg, "abort_get_result"); + + req = jsonrpc_request_start(cmd, "unreserveinputs", + unreserve_get_result, forward_error, + abort_pkg); + + json_add_psbt(req->js, "psbt", splice_cmd->psbt); + + return send_outreq(req); +} + +static struct command_result *do_fail(struct command *cmd, + struct splice_cmd *splice_cmd, + enum jsonrpc_errcode code, + const char *str TAKES) +{ + struct out_req *req; + struct abort_pkg *abort_pkg; + size_t added; + + /* If we encounter an error, wetrun is canceled */ + splice_cmd->wetrun = false; + + plugin_log(cmd->plugin, LOG_DBG, + "splice_error(psbt:%p, splice_cmd_stat:%p)", + splice_cmd->psbt, splice_cmd); + + abort_pkg = tal(cmd->plugin, struct abort_pkg); + abort_pkg->splice_cmd = tal_steal(abort_pkg, splice_cmd); + abort_pkg->str = tal_strdup(abort_pkg, str); + abort_pkg->code = code; + + req = jsonrpc_request_start(cmd, "abort_channels", + abort_get_result, forward_error, abort_pkg); + + added = 0; + json_array_start(req->js, "channel_ids"); + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + if (splice_cmd->actions[i]->channel_id) { + added++; + json_add_channel_id(req->js, NULL, + splice_cmd->actions[i]->channel_id); + } + } + json_array_end(req->js); + + if (!added) { + plugin_log(cmd->plugin, LOG_DBG, + "No channels were stfu'ed, skipping to unreserve" + " (psbt:%p)", splice_cmd->psbt); + return abort_get_result(cmd, NULL, NULL, NULL, abort_pkg); + } + + return send_outreq(req); +} + +static struct command_result *splice_error(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *error, + struct splice_cmd *splice_cmd) +{ + char *str = tal_fmt(NULL, "%s: %.*s", + methodname, + error->end - error->start, + buf + error->start); + + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, take(str)); +} + +struct splice_index_pkg { + struct splice_cmd *splice_cmd; + size_t index; +}; + +static struct command_result *splice_error_pkg(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *error, + struct splice_index_pkg *pkg) +{ + return splice_error(cmd, methodname, buf, error, pkg->splice_cmd); +} + +static struct command_result *calc_in_ppm_and_fee(struct command *cmd, + struct splice_cmd *splice_cmd, + struct amount_sat onchain_fee) +{ + struct splice_script_result *action; + struct amount_sat out_sats = splice_cmd->initial_funds; + bool is_any_paying_fee = false; + + /* First add all sats going into general fund */ + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + if (action->pays_fee) + is_any_paying_fee = true; + if (!amount_sat_add(&out_sats, out_sats, action->out_sat)) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Unable to add out_sats"); + if (action->out_ppm) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Unable to resolve out_ppm"); + } + + /* Now take away all sats being spent by general fund */ + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + if (!amount_sat_sub(&out_sats, out_sats, action->in_sat)) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Unable to sub out_sats"); + } + + /* If no one voulenteers to pay the fee, we take it out of the general + * fund. */ + if (!is_any_paying_fee) { + if (!amount_sat_sub(&out_sats, out_sats, onchain_fee)) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + tal_fmt(tmpctx, + "Unable to take onchain fee %s" + " fromm general funds of %s", + fmt_amount_sat(tmpctx, onchain_fee), + fmt_amount_sat(tmpctx, out_sats))); + } + + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + if (action->in_ppm) { + /* ppm percentage calculation: + * action->in_sat = out_sats * in_ppm / 1000000 */ + assert(amount_sat_is_zero(action->in_sat)); + if (!amount_sat_mul(&action->in_sat, out_sats, action->in_ppm)) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Unable to mul sats & in_ppm"); + action->in_sat = amount_sat_div(action->in_sat, 1000000); + action->in_ppm = 0; + } + + /* If this item pays the fee, subtract it from either their + * in_sats or add it to out_sats. */ + if (action->pays_fee && !amount_sat_is_zero(action->in_sat)) { + if (!amount_sat_sub(&action->in_sat, action->in_sat, + onchain_fee)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Unable to sub fee from" + " item in_sat"); + } + if (action->pays_fee && !amount_sat_is_zero(action->out_sat)) { + if (!amount_sat_add(&action->out_sat, action->out_sat, + onchain_fee)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Unable to add fee to" + " item out_sat"); + } + } + + /* validate result */ + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + if (!action->channel_id) + continue; + if (!amount_sat_is_zero(action->in_sat)) + continue; + if (!amount_sat_is_zero(action->out_sat)) + continue; + if (!amount_sat_is_zero(action->lease_sat)) + continue; + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Each channel action must include non-zero" + " in sats, out sats, or lease sats."); + } + + return NULL; +} + +static struct command_result *continue_splice(struct command *cmd, + struct splice_cmd *splice_cmd); + +static bool json_to_msat_to_sat(const char *buffer, const jsmntok_t *tok, + struct amount_sat *sat) +{ + struct amount_msat msat; + + if (!json_to_msat(buffer, tok, &msat)) + return false; + return amount_msat_to_sat(sat, msat); +} + +static struct splice_script_result *output_wallet(struct splice_cmd *splice_cmd) +{ + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + struct splice_script_result *action = splice_cmd->actions[i]; + if (!action->onchain_wallet) + continue; + if (action->in_ppm || !amount_sat_is_zero(action->in_sat)) + return action; + } + return NULL; +} + +static struct command_result *addpsbt_get_result(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *result, + struct splice_index_pkg *pkg) +{ + struct splice_cmd *splice_cmd = pkg->splice_cmd; + size_t index = pkg->index; + struct splice_script_result *action = splice_cmd->actions[index]; + const jsmntok_t *tok; + struct amount_sat excess_sat; + struct splice_script_result *out_wallet; + + tal_free(pkg); + tok = json_get_member(buf, result, "psbt"); + + tal_free(splice_cmd->psbt); + splice_cmd->psbt = json_to_psbt(splice_cmd, buf, tok); + assert(splice_cmd->psbt); + + tok = json_get_member(buf, result, "excess_msat"); + if (tok) { + if (!json_to_msat_to_sat(buf, tok, &excess_sat)) + return command_fail_badparam(cmd, "addpsbt", buf, tok, + "invalid excess_msat"); + + if (!amount_sat_is_zero(excess_sat)) { + if (!amount_sat_add(&action->out_sat, action->out_sat, + excess_sat)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Unable to add excess sats"); + + out_wallet = output_wallet(splice_cmd); + if (out_wallet) { + if (!out_wallet->in_ppm + && !amount_sat_add(&out_wallet->in_sat, + out_wallet->in_sat, + excess_sat)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Unable to add excess" + " sats to existing" + " wallet output"); + } + else { + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Putting change back into same" + " wallet outpoint not yet" + " supported"); + } + } + } + + tok = json_get_member(buf, result, "emergency_sat"); + if (tok) { + if (!amount_sat_is_zero(splice_cmd->emergency_sat)) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Internal error: two" + " emergency_sat"); + if (!json_to_msat_to_sat(buf, tok, &splice_cmd->emergency_sat)) + return command_fail_badparam(cmd, "addpsbt", buf, tok, + "invalid emergency_sat"); + } + + return continue_splice(splice_cmd->cmd, splice_cmd); +} + +static struct command_result *onchain_wallet_fund(struct command *cmd, + struct splice_cmd *splice_cmd, + size_t index) +{ + struct splice_script_result *action = splice_cmd->actions[index]; + struct splice_cmd_action_state *state = splice_cmd->states[index]; + struct out_req *req; + struct splice_index_pkg *pkg; + const char *command; + bool addinginputs = !amount_sat_is_zero(action->out_sat); + + pkg = tal(cmd->plugin, struct splice_index_pkg); + pkg->splice_cmd = splice_cmd; + pkg->index = index; + + command = "addpsbtoutput"; + if (addinginputs) { + command = "addpsbtinput"; + splice_cmd->wallet_inputs_to_signed++; + /* DTODO track which specific inputs are added and only sign + * those */ + } + + req = jsonrpc_request_start(cmd, command, + addpsbt_get_result, + splice_error_pkg, pkg); + + if (!amount_sat_is_zero(action->out_sat)) { + json_add_sats(req->js, "satoshi", action->out_sat); + assert(splice_cmd->feerate_per_kw); + json_add_u32(req->js, "min_feerate", splice_cmd->feerate_per_kw); + } + else { + json_add_sats(req->js, "satoshi", action->in_sat); + } + + json_add_psbt(req->js, "initialpsbt", splice_cmd->psbt); + json_add_bool(req->js, "add_initiator_serial_ids", true); + if (addinginputs) + json_add_bool(req->js, "mark_our_inputs", true); + + state->state = SPLICE_CMD_DONE; + + return send_outreq(req); +} + +static struct command_result *feerate_get_result(struct command *cmd, + const char *method, + const char *buf, + const jsmntok_t *result, + struct splice_cmd *splice_cmd) +{ + const jsmntok_t *tok = json_get_member(buf, result, "perkw"); + tok = json_get_member(buf, tok, "opening"); + + if (!json_to_u32(buf, tok, &splice_cmd->feerate_per_kw)) + return command_fail_badparam(cmd, "opening", buf, + tok, "invalid u32"); + + if (!splice_cmd->feerate_per_kw) + return command_fail(splice_cmd->cmd, + JSONRPC2_INVALID_PARAMS, + "Failed to load a default feerate"); + + plugin_log(cmd->plugin, LOG_DBG, + "got feerate %"PRIu32" perkw", splice_cmd->feerate_per_kw); + + return continue_splice(splice_cmd->cmd, splice_cmd); +} + +static struct command_result *load_feerate(struct command *cmd, + struct splice_cmd *splice_cmd) +{ + struct out_req *req; + + req = jsonrpc_request_start(cmd, "feerates", + feerate_get_result, splice_error, + splice_cmd); + + json_add_string(req->js, "style", "perkw"); + + return send_outreq(req); +} + +static size_t calc_weight(struct splice_cmd *splice_cmd, + bool simulate_wallet_outputs) +{ + struct splice_script_result *action; + struct wally_psbt *psbt = splice_cmd->psbt; + size_t weight = 0; + size_t extra_inputs = 0; + size_t extra_outputs = 0; + + /* BOLT #2: + * The rest of the transaction bytes' fees are the responsibility of + * the peer who contributed that input or output via `tx_add_input` or + * `tx_add_output`, at the agreed upon `feerate`. + */ + for (size_t i = 0; i < psbt->num_inputs; i++) + weight += psbt_input_get_weight(psbt, i); + + for (size_t i = 0; i < psbt->num_outputs; i++) + weight += psbt_output_get_weight(psbt, i); + + /* Count the splice input & outputs manually */ + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + if (simulate_wallet_outputs && action->onchain_wallet) { + if (!amount_sat_is_zero(action->in_sat) || action->in_ppm) { + weight += bitcoin_tx_output_weight(BITCOIN_SCRIPTPUBKEY_P2TR_LEN); + extra_outputs++; + } + + } else if (splice_cmd->actions[i]->channel_id) { + weight += bitcoin_tx_output_weight(BITCOIN_SCRIPTPUBKEY_P2WSH_LEN); + weight += bitcoin_tx_input_weight(true, + bitcoin_tx_2of2_input_witness_weight()); + extra_inputs++; + extra_outputs++; + } + } + + /* DTODO make a test to confirm weight calculation is correct */ + + /* BOLT #2: + * The *initiator* is responsible for paying the fees for the following fields, + * to be referred to as the `common fields`. + * + * - version + * - segwit marker + flag + * - input count + * - output count + * - locktime + */ + weight += bitcoin_tx_core_weight(psbt->num_inputs + extra_inputs, + psbt->num_outputs + extra_outputs); + + return weight; +} + +static struct command_result *splice_init_get_result(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *result, + struct splice_cmd *splice_cmd) +{ + const jsmntok_t *tok = json_get_member(buf, result, "psbt"); + + tal_free(splice_cmd->psbt); + splice_cmd->psbt = json_to_psbt(splice_cmd, buf, tok); + + return continue_splice(splice_cmd->cmd, splice_cmd); +} + +static struct command_result *splice_init(struct command *cmd, + struct splice_cmd *splice_cmd, + size_t index) +{ + struct splice_script_result *action = splice_cmd->actions[index]; + struct splice_cmd_action_state *state = splice_cmd->states[index]; + struct out_req *req; + + req = jsonrpc_request_start(cmd, "splice_init", + splice_init_get_result, splice_error, + splice_cmd); + + json_add_channel_id(req->js, "channel_id", action->channel_id); + if (!amount_sat_is_zero(action->in_sat)) { + json_add_u64(req->js, "relative_amount", + action->in_sat.satoshis); /* Raw: signed RPC */ + } else if (!amount_sat_is_zero(action->out_sat)) { + json_add_string(req->js, "relative_amount", + tal_fmt(req->js, "-%"PRIu64, + action->out_sat.satoshis)); /* Raw: signed RPC */ + } else { + json_add_sats(req->js, "relative_amount", amount_sat(0)); + } + json_add_psbt(req->js, "initialpsbt", splice_cmd->psbt); + json_add_u32(req->js, "feerate_per_kw", splice_cmd->feerate_per_kw); + json_add_bool(req->js, "skip_stfu", true); + json_add_bool(req->js, "force_feerate", splice_cmd->force_feerate); + + state->state = SPLICE_CMD_INIT; + + return send_outreq(req); +} + +static struct command_result *splice_update_get_result(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *result, + struct splice_index_pkg *pkg) +{ + size_t index = pkg->index; + struct splice_cmd *splice_cmd = pkg->splice_cmd; + struct splice_cmd_action_state *state = splice_cmd->states[index]; + const jsmntok_t *tok; + struct wally_psbt *psbt; + enum splice_cmd_state old_state = state->state; + bool got_sigs; + + tal_free(pkg); + + /* DTODO: juggle serial ids correctly for cross-channel splice */ + tok = json_get_member(buf, result, "psbt"); + psbt = json_to_psbt(splice_cmd, buf, tok); + + if (psbt_contribs_changed(splice_cmd->psbt, psbt)) + for (size_t i = 0; i < tal_count(splice_cmd->states); i++) + if (splice_cmd->actions[i]->channel_id) + splice_cmd->states[i]->state = SPLICE_CMD_UPDATE_NEEDS_CHANGES; + + assert(psbt); + tal_free(splice_cmd->psbt); + splice_cmd->psbt = tal_steal(splice_cmd, psbt); + + tok = json_get_member(buf, result, "signatures_secured"); + if (!json_to_bool(buf, tok, &got_sigs)) + return command_fail_badparam(cmd, "signatures_secured", buf, + tok, "invalid bool"); + + if (old_state != SPLICE_CMD_UPDATE) + state->state = SPLICE_CMD_UPDATE; + else + state->state = got_sigs ? SPLICE_CMD_RECVED_SIGS : SPLICE_CMD_UPDATE_DONE; + + return continue_splice(splice_cmd->cmd, splice_cmd); +} + +static struct command_result *splice_update(struct command *cmd, + struct splice_cmd *splice_cmd, + size_t index) +{ + struct splice_script_result *action = splice_cmd->actions[index]; + struct out_req *req; + struct splice_index_pkg *pkg = tal(cmd->plugin, struct splice_index_pkg); + + pkg->splice_cmd = splice_cmd; + pkg->index = index; + + plugin_log(cmd->plugin, LOG_DBG, + "splice_update(channel_id:%s)", + fmt_channel_id(tmpctx, action->channel_id)); + + req = jsonrpc_request_start(cmd, "splice_update", + splice_update_get_result, splice_error_pkg, + pkg); + + json_add_channel_id(req->js, "channel_id", action->channel_id); + json_add_psbt(req->js, "psbt", splice_cmd->psbt); + + return send_outreq(req); +} + +static struct command_result *signpsbt_get_result(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *result, + struct splice_cmd *splice_cmd) +{ + const jsmntok_t *tok = json_get_member(buf, result, "signed_psbt"); + struct channel_id *channel_ids; + + tal_free(splice_cmd->psbt); + + splice_cmd->psbt = json_to_psbt(splice_cmd, buf, tok); + splice_cmd->wallet_inputs_to_signed = 0; + + /* After signing we add channel_ids to the PSBT for splice_signed */ + channel_ids = tal_arr(NULL, struct channel_id, 0); + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) + if (splice_cmd->actions[i]->channel_id) + tal_arr_expand(&channel_ids, + *splice_cmd->actions[i]->channel_id); + + psbt_set_channel_ids(splice_cmd->psbt, channel_ids); + tal_free(channel_ids); + + return continue_splice(splice_cmd->cmd, splice_cmd); +} + +static struct command_result *signpsbt(struct command *cmd, + struct splice_cmd *splice_cmd) +{ + struct out_req *req; + size_t num_to_be_signed; + + req = jsonrpc_request_start(cmd, "signpsbt", + signpsbt_get_result, splice_error, + splice_cmd); + + /* Use input markers to identify which inputs + * are ours, only sign those */ + json_array_start(req->js, "signonly"); + num_to_be_signed = 0; + for (size_t i = 0; i < splice_cmd->psbt->num_inputs; i++) { + if (psbt_input_is_ours(&splice_cmd->psbt->inputs[i])) { + json_add_num(req->js, NULL, i); + num_to_be_signed++; + } + } + json_array_end(req->js); + + json_add_psbt(req->js, "psbt", splice_cmd->psbt); + + /* If we have no inputs to be signed, skip ahead */ + if (!num_to_be_signed) { + splice_cmd->wallet_inputs_to_signed = 0; + return continue_splice(splice_cmd->cmd, splice_cmd); + } + + return send_outreq(req); +} + +static struct splice_script_result *requires_our_sigs(struct splice_cmd *splice_cmd, + size_t *index, + bool *multiple_require_sigs) +{ + struct splice_script_result *action = NULL; + *index = UINT32_MAX; + *multiple_require_sigs = false; + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + if (splice_cmd->states[i]->state == SPLICE_CMD_UPDATE_DONE) { + /* There can only be one node that requires our sigs */ + if (action) { + *multiple_require_sigs = true; + return NULL; + } + action = splice_cmd->actions[i]; + *index = i; + } + } + return action; +} + +static struct command_result *splice_signed_get_result(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *result, + struct splice_index_pkg *pkg) +{ + size_t index = pkg->index; + struct splice_cmd *splice_cmd = pkg->splice_cmd; + const jsmntok_t *tok; + + tal_free(pkg); + + tok = json_get_member(buf, result, "psbt"); + tal_free(splice_cmd->psbt); + splice_cmd->psbt = json_to_psbt(splice_cmd, buf, tok); + + tok = json_get_member(buf, result, "txid"); + if (!json_to_txid(buf, tok, &splice_cmd->final_txid)) + return command_fail_badparam(cmd, "txid", buf, + tok, "invalid txid"); + + splice_cmd->states[index]->state = SPLICE_CMD_DONE; + + return continue_splice(splice_cmd->cmd, splice_cmd); +} + +static struct command_result *splice_signed(struct command *cmd, + struct splice_cmd *splice_cmd, + size_t index) +{ + struct splice_script_result *action = splice_cmd->actions[index]; + struct out_req *req; + struct splice_index_pkg *pkg; + + pkg = tal(cmd->plugin, struct splice_index_pkg); + pkg->splice_cmd = splice_cmd; + pkg->index = index; + + req = jsonrpc_request_start(cmd, "splice_signed", + splice_signed_get_result, splice_error_pkg, + pkg); + + json_add_channel_id(req->js, "channel_id", action->channel_id); + json_add_psbt(req->js, "psbt", splice_cmd->psbt); + + return send_outreq(req); +} + +static struct command_result *check_emergency_sat(struct command *cmd, + struct splice_cmd *splice_cmd) +{ + struct amount_sat to_wallet = AMOUNT_SAT(0); + if (amount_sat_is_zero(splice_cmd->emergency_sat)) + return NULL; + + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + struct splice_script_result *action = splice_cmd->actions[i]; + if (action->onchain_wallet) + if (!amount_sat_add(&to_wallet, to_wallet, + action->in_sat)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Unable to amount_sat_add" + " wallet amounts for" + " emergency_sat calc"); + } + + if (!amount_sat_greater_eq(to_wallet, splice_cmd->emergency_sat)) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + tal_fmt(tmpctx, + "Amount going to onchain wallet %s is" + " not enough to meet the emergency" + " minimum of %s", + fmt_amount_sat(tmpctx, to_wallet), + fmt_amount_sat(tmpctx, splice_cmd->emergency_sat))); + + return NULL; +} + +static const char *cmd_state_string(enum splice_cmd_state state) +{ + switch (state) { + case SPLICE_CMD_NONE: + return " "; + case SPLICE_CMD_INIT: + return " INIT "; + case SPLICE_CMD_UPDATE: + return " UPDATE "; + case SPLICE_CMD_UPDATE_NEEDS_CHANGES: + return "UPDATE_NEEDS_CHANGES"; + case SPLICE_CMD_UPDATE_DONE: + return " UPDATE_DONE "; + case SPLICE_CMD_RECVED_SIGS: + return " RECVED_SIGS "; + case SPLICE_CMD_DONE: + return " DONE "; + } + return NULL; +} + +static void add_to_debug_log(struct splice_cmd *scmd, const char *phase) +{ + char **log = &scmd->debug_log; + if (!*log) + return; + + tal_append_fmt(log, "#%d: (%s)\n", ++scmd->debug_counter, phase); + + for (size_t i = 0; i < tal_count(scmd->actions); i++) { + struct splice_script_result *action = scmd->actions[i]; + struct splice_cmd_action_state *state = scmd->states[i]; + + tal_append_fmt(log, "[%s] %s\n", + cmd_state_string(state->state), + splice_to_string(tmpctx, action)); + } +} + +static struct command_result *handle_wetrun(struct command *cmd, + struct splice_cmd *splice_cmd) +{ + struct out_req *req; + struct abort_pkg *abort_pkg; + size_t added; + + abort_pkg = tal(cmd->plugin, struct abort_pkg); + abort_pkg->splice_cmd = tal_steal(abort_pkg, splice_cmd); + abort_pkg->str = NULL; + + req = jsonrpc_request_start(cmd, "abort_channels", + abort_get_result, forward_error, abort_pkg); + + added = 0; + json_array_start(req->js, "channel_ids"); + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + if (splice_cmd->actions[i]->channel_id) { + added++; + json_add_channel_id(req->js, NULL, + splice_cmd->actions[i]->channel_id); + } + } + json_array_end(req->js); + + if (!added) + return unreserve_get_result(cmd, NULL, NULL, NULL, abort_pkg); + + return send_outreq(req); +} + +static struct command_result *continue_splice(struct command *cmd, + struct splice_cmd *splice_cmd) +{ + struct splice_script_result *action; + struct splice_cmd_action_state *state; + struct command_result *result; + size_t index; + size_t weight; + struct amount_sat onchain_fee; + bool multiple_require_sigs; + + add_to_debug_log(splice_cmd, "continue_splice"); + + if (!splice_cmd->feerate_per_kw) + return load_feerate(cmd, splice_cmd); + + /* On first pass we add wallet actions that contribute funds */ + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + state = splice_cmd->states[i]; + if (state->state != SPLICE_CMD_NONE) + continue; + if (splice_cmd->actions[i]->onchain_wallet + && !amount_sat_is_zero(splice_cmd->actions[i]->out_sat)) { + state->state = SPLICE_CMD_DONE; + return onchain_wallet_fund(cmd, splice_cmd, i); + } + } + + if (!splice_cmd->fee_calculated) { + splice_cmd->fee_calculated = true; + + /* We calculate the weight simulator wallet outputs */ + weight = calc_weight(splice_cmd, true); + onchain_fee = amount_tx_fee(splice_cmd->feerate_per_kw, weight); + + plugin_log(cmd->plugin, LOG_INFORM, + "Splice fee is %s at %"PRIu32" perkw (%.02f sat/vB) " + "on tx where our personal vbytes are %.02f", + fmt_amount_sat(tmpctx, onchain_fee), + splice_cmd->feerate_per_kw, + 4 * splice_cmd->feerate_per_kw / 1000.0f, + weight / 4.0f); + + result = calc_in_ppm_and_fee(cmd, splice_cmd, onchain_fee); + if (result) + return result; + } + + /* Only after fee calcualtion can we add wallet actions taking funds */ + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + state = splice_cmd->states[i]; + if (state->state != SPLICE_CMD_NONE) + continue; + if (splice_cmd->actions[i]->onchain_wallet + && !amount_sat_is_zero(splice_cmd->actions[i]->in_sat)) { + state->state = SPLICE_CMD_DONE; + return onchain_wallet_fund(cmd, splice_cmd, i); + } + } + + result = check_emergency_sat(cmd, splice_cmd); + if (result) + return result; + + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + state = splice_cmd->states[i]; + if (state->state != SPLICE_CMD_NONE) + continue; + if (!action->channel_id) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Internal error; should not get" + " here with non-channels with state" + " NONE"); + return splice_init(cmd, splice_cmd, i); + } + + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + state = splice_cmd->states[i]; + if (state->state == SPLICE_CMD_INIT + || state->state == SPLICE_CMD_UPDATE_NEEDS_CHANGES) + return splice_update(cmd, splice_cmd, i); + } + + /* It is possible to receive a signature when we do splice_update with + * no changes. Therefore wetrun must abort here to prevent any of our + * peers locking up funds */ + if (splice_cmd->wetrun) + return handle_wetrun(cmd, splice_cmd); + + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + state = splice_cmd->states[i]; + if (state->state == SPLICE_CMD_UPDATE) + return splice_update(cmd, splice_cmd, i); + } + + /* The signpsbt operation also adds channel_ids to psbt */ + if (splice_cmd->wallet_inputs_to_signed) + return signpsbt(cmd, splice_cmd); + + if (requires_our_sigs(splice_cmd, &index, &multiple_require_sigs)) + return splice_signed(cmd, splice_cmd, index); + + if (multiple_require_sigs) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Requested splice is impossible because multiple" + " peers demand they do not sign first. Someone" + " must sign first."); + + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + state = splice_cmd->states[i]; + if (i != index && state->state == SPLICE_CMD_RECVED_SIGS) + return splice_signed(cmd, splice_cmd, i); + } + + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) + assert(splice_cmd->states[i]->state == SPLICE_CMD_DONE); + + add_to_debug_log(splice_cmd, "continue_splice-finished"); + + struct json_stream *response = jsonrpc_stream_success(cmd); + json_add_psbt(response, "psbt", splice_cmd->psbt); + json_add_txid(response, "txid", &splice_cmd->final_txid); + if (splice_cmd->debug_log) { + json_array_start(response, "log"); + debug_log_to_json(response, splice_cmd->debug_log); + json_array_end(response); + } + return command_finished(cmd, response); +} + +static struct command_result *execute_splice(struct command *cmd, + struct splice_cmd *splice_cmd) +{ + struct splice_script_result *action; + struct splice_cmd_action_state *state; + struct wally_psbt_output *output; + u64 serial_id; + int pays_fee; + u8 *scriptpubkey; + + /* Basic validation */ + pays_fee = 0; + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + int dest_count = 0; + action = splice_cmd->actions[i]; + state = splice_cmd->states[i]; + + if (splice_cmd->actions[i]->out_ppm) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Should be no out_ppm on final"); + if (splice_cmd->actions[i]->pays_fee) { + if (pays_fee) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Only one item may pay fee"); + pays_fee++; + } + if (splice_cmd->actions[i]->channel_id) + dest_count++; + if (splice_cmd->actions[i]->bitcoin_address) + dest_count++; + if (splice_cmd->actions[i]->onchain_wallet) + dest_count++; + if (dest_count < 1) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Must specify 1 destination per"); + if (dest_count > 1) + return do_fail(cmd, splice_cmd, JSONRPC2_INVALID_PARAMS, + "Too many destinations per"); + + /* If user specifies both sats in and out, we just use the + * larger of the two and subtract the smaller. */ + if (amount_sat_greater(action->in_sat, action->out_sat)) { + if (!amount_sat_sub(&action->in_sat, action->in_sat, + action->out_sat)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Unable to sub out_sat from" + " in_sat"); + action->out_sat = amount_sat(0); + } else { + if (!amount_sat_sub(&action->out_sat, action->out_sat, + action->in_sat)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Unable to sub in_sat from" + " out_sat"); + action->in_sat = amount_sat(0); + } + } + + add_to_debug_log(splice_cmd, "execute_splice"); + + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + state = splice_cmd->states[i]; + char *bitcoin_address; + + /* Load (only one) feerate if user provided one */ + if (action->feerate_per_kw) { + if (splice_cmd->feerate_per_kw) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Only one item may set" + " feerate"); + splice_cmd->feerate_per_kw = action->feerate_per_kw; + } + + /* Fund out to bitcoin address */ + if (action->bitcoin_address) { + if (!amount_sat_is_zero(action->in_sat)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Cannot fund from bitcoin" + " address"); + if (!decode_scriptpubkey_from_addr(cmd, chainparams, + action->bitcoin_address, + &scriptpubkey)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Bitcoin address" + " unrecognized"); + + /* Reencode scriptpubkey to addr for verification */ + bitcoin_address = encode_scriptpubkey_to_addr(tmpctx, + chainparams, + scriptpubkey); + if (!bitcoin_address) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Bitcoin scriptpubkey failed" + " reencoding for address"); + + if (!strcmp(bitcoin_address, action->bitcoin_address)) + return do_fail(cmd, splice_cmd, + JSONRPC2_INVALID_PARAMS, + "Bitcoin scriptpubkey failed" + " validation for address"); + + output = psbt_append_output(splice_cmd->psbt, + scriptpubkey, + action->in_sat); + + /* DTODO: support dynamic address payouts (percent) */ + + serial_id = psbt_new_output_serial(splice_cmd->psbt, + TX_INITIATOR); + psbt_output_set_serial_id(splice_cmd->psbt, output, + serial_id); + + state->state = SPLICE_CMD_DONE; + + add_to_debug_log(splice_cmd, + "execute_splice-load_btcaddress"); + } + } + + return continue_splice(cmd, splice_cmd); +} + +static struct command_result *adjust_pending_out_ppm(struct splice_script_result **actions, + struct channel_id channel_id, + struct amount_sat available_funds, + struct splice_cmd *splice_cmd) +{ + for (size_t i = 0; i < tal_count(actions); i++) { + if (!actions[i]->channel_id) + continue; + if (!channel_id_eq(actions[i]->channel_id, &channel_id)) + continue; + /* Skip channels not using out_ppm */ + if (!actions[i]->out_ppm) + continue; + + /* For now max (asterisks) means 100% but that may change in the + * future */ + if (actions[i]->out_ppm == UINT32_MAX) + actions[i]->out_ppm = 1000000; + + /* ppm percentage calculation: + * action->out_sat = available_funds * out_ppm / 1000000 */ + if (!amount_sat_mul(&actions[i]->out_sat, available_funds, + actions[i]->out_ppm)) + return command_fail(splice_cmd->cmd, JSONRPC2_INVALID_PARAMS, + "Unable to mul sats(%s) &" + " out_ppm(%"PRIu32") for channel id" + " %s", + fmt_amount_sat(tmpctx, available_funds), + actions[i]->out_ppm, + fmt_channel_id(tmpctx, &channel_id)); + actions[i]->out_sat = amount_sat_div(actions[i]->out_sat, + 1000000); + actions[i]->out_ppm = 0; + } + + return NULL; +} + +static struct command_result *stfu_channels_get_result(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *toks, + struct splice_cmd *splice_cmd) +{ + const jsmntok_t *jchannels, *jchannel; + size_t i; + const char *err; + struct command_result *result; + + jchannels = json_get_member(buf, toks, "channels"); + json_for_each_arr(i, jchannel, jchannels) { + struct channel_id channel_id; + struct amount_sat sat; + + memset(&channel_id, 0, sizeof(channel_id)); + memset(&sat, 0, sizeof(sat)); + + err = json_scan(tmpctx, buf, jchannel, + "{channel_id?:%,available_msat?:%}", + JSON_SCAN(json_to_channel_id, &channel_id), + JSON_SCAN(json_to_msat_to_sat, &sat)); + if (err) + errx(1, "Bad stfu_channels.channels %zu: %s", + i, err); + + result = adjust_pending_out_ppm(splice_cmd->actions, + channel_id, sat, splice_cmd); + if (result) + return result; + } + + return execute_splice(splice_cmd->cmd, splice_cmd); +} + +static struct command_result *splice_dryrun(struct command *cmd, + struct splice_cmd *splice_cmd) +{ + char **lines; + unsigned int i; + struct json_stream *response; + const char *str; + + response = jsonrpc_stream_success(cmd); + json_array_start(response, "dryrun"); + + str = splicearr_to_string(response, splice_cmd->actions); + lines = tal_strsplit(response, take(str), "\n", STR_NO_EMPTY); + for (i = 0; lines[i] != NULL; i++) + json_add_string(response, NULL, lines[i]); + json_array_end(response); + return command_finished(cmd, response); +} + +static struct command_result *handle_splice_cmd(struct command *cmd, + struct splice_cmd *splice_cmd) +{ + struct out_req *req; + + if (splice_cmd->dryrun) + return splice_dryrun(cmd, splice_cmd); + + req = jsonrpc_request_start(cmd, "stfu_channels", + stfu_channels_get_result, + splice_error, splice_cmd); + + json_array_start(req->js, "channel_ids"); + /* We begin by stfu'ing and getting available balance on all MAX reqs */ + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) + if (splice_cmd->actions[i]->channel_id) + json_add_channel_id(req->js, NULL, + splice_cmd->actions[i]->channel_id); + json_array_end(req->js); + + return send_outreq(req); +} + +static struct command_result * +validate_splice_cmd(struct splice_cmd *splice_cmd) +{ + struct splice_script_result *action; + int paying_fee_count = 0; + int channels = 0; + for (size_t i = 0; i < tal_count(splice_cmd->actions); i++) { + action = splice_cmd->actions[i]; + /* Taking fee from onchain wallet requires recursive looping + * since adding more funds adds more input bytes. We don't + * support it for now. */ + if (action->pays_fee && action->onchain_wallet + && action->out_ppm) + return command_fail(splice_cmd->cmd, + JSONRPC2_INVALID_PARAMS, + "Don't support dynamic fee being" + " added to onchain wallet"); + if (action->onchain_wallet && action->out_ppm) + return command_fail(splice_cmd->cmd, + JSONRPC2_INVALID_PARAMS, + "Don't support dynamic wallet" + " funding amounts for now"); + if (action->pays_fee && action->onchain_wallet + && !amount_sat_is_zero(action->out_sat)) + return command_fail(splice_cmd->cmd, + JSONRPC2_INVALID_PARAMS, + "Don't support wallet funding" + " being used for fee"); + if (action->pays_fee) { + if (paying_fee_count) + return command_fail(splice_cmd->cmd, + JSONRPC2_INVALID_PARAMS, + "Only one item may pay the" + " fee"); + paying_fee_count++; + } + if (action->bitcoin_address && action->in_ppm) + return command_fail(splice_cmd->cmd, + JSONRPC2_INVALID_PARAMS, + "Dynamic bitcoin address amounts" + " not supported for now"); + if (action->channel_id) { + if (channels) + return command_fail(splice_cmd->cmd, + JSONRPC2_INVALID_PARAMS, + "Multi-channel splice not" + "supported for now"); + channels++; + } + if (action->bitcoin_address) + return command_fail(splice_cmd->cmd, + JSONRPC2_INVALID_PARAMS, + "Paying out to bitcoin addresses" + " not supported for now."); + } + + return NULL; +} + +static struct command_result *listpeerchannels_get_result(struct command *cmd, + const char *methodname, + const char *buf, + const jsmntok_t *toks, + struct splice_cmd *splice_cmd) +{ + struct splice_script_error *error; + struct splice_script_chan **channels; + struct command_result *result; + const jsmntok_t *jchannels, *jchannel; + char **lines; + struct json_stream *response; + const char *str; + size_t i; + const char *err; + + channels = tal_arr(tmpctx, struct splice_script_chan*, 0); + jchannels = json_get_member(buf, toks, "channels"); + json_for_each_arr(i, jchannel, jchannels) { + tal_arr_expand(&channels, tal(channels, + struct splice_script_chan)); + + err = json_scan(tmpctx, buf, jchannel, + "{peer_id?:%,channel_id?:%}", + JSON_SCAN(json_to_node_id, + &channels[i]->node_id), + JSON_SCAN(json_to_channel_id, + &channels[i]->chan_id)); + if (err) + errx(1, "Bad listpeerchannels.channels %zu: %s", + i, err); + } + + if (splice_cmd->script) { + error = parse_splice_script(splice_cmd, splice_cmd->script, + channels, &splice_cmd->actions); + if (error) { + response = jsonrpc_stream_fail(cmd, + JSONRPC2_INVALID_PARAMS, + "Splice script compile" + " failed"); + + json_array_start(response, "compiler_error"); + + str = fmt_splice_script_compiler_error(response, + splice_cmd->script, + error); + lines = tal_strsplit(response, take(str), "\n", + STR_NO_EMPTY); + for (i = 0; lines[i] != NULL; i++) + json_add_string(response, NULL, lines[i]); + json_array_end(response); + return command_finished(cmd, response); + } + + splice_cmd->states = tal_arr(splice_cmd, + struct splice_cmd_action_state*, + tal_count(splice_cmd->actions)); + + for (i = 0; i < tal_count(splice_cmd->states); i++) { + splice_cmd->states[i] = tal(splice_cmd->states, + struct splice_cmd_action_state); + splice_cmd->states[i]->state = SPLICE_CMD_NONE; + } + } + + assert(splice_cmd->actions); + + result = validate_splice_cmd(splice_cmd); + if (result) + return result; + + return handle_splice_cmd(splice_cmd->cmd, splice_cmd); +} + +static struct command_result * +json_splice(struct command *cmd, const char *buf, const jsmntok_t *params) +{ + struct out_req *req; + const char *script; + const jsmntok_t *json; + struct wally_psbt *psbt; + bool *dryrun, *force_feerate, *debug_log, *wetrun; + struct str_or_arr *str_or_arr; + + if (!param(cmd, buf, params, + p_opt("script_or_json", param_string_or_array, &str_or_arr), + p_opt_def("dryrun", param_bool, &dryrun, false), + p_opt_def("force_feerate", param_bool, &force_feerate, + false), + p_opt_def("debug_log", param_bool, &debug_log, false), + p_opt_dev("dev-wetrun", param_bool, &wetrun, false), + NULL)) + return command_param_failed(); + + if (!str_or_arr) + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "Must pass 'script_or_json'"); + + script = str_or_arr->str; + json = str_or_arr->arr; + + psbt = create_psbt(cmd, 0, 0, 0); + + struct splice_cmd *splice_cmd = tal(cmd, struct splice_cmd); + + splice_cmd->cmd = cmd; + splice_cmd->script = tal_steal(splice_cmd, script); + splice_cmd->psbt = tal_steal(splice_cmd, psbt); + splice_cmd->dryrun = *dryrun; + splice_cmd->wetrun = *wetrun; + splice_cmd->feerate_per_kw = 0; + splice_cmd->force_feerate = *force_feerate; + splice_cmd->wallet_inputs_to_signed = 0; + splice_cmd->fee_calculated = false; + splice_cmd->initial_funds = AMOUNT_SAT(0); + splice_cmd->emergency_sat = AMOUNT_SAT(0); + splice_cmd->debug_log = *debug_log ? tal_strdup(splice_cmd, "") : NULL; + splice_cmd->debug_counter = 0; + memset(&splice_cmd->final_txid, 0, sizeof(splice_cmd->final_txid)); + + /* If script validates as json, parse it as json instead */ + if (json) { + if (!json_to_splice(splice_cmd, buf, json, + &splice_cmd->actions)) + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "splice json failed validation"); + + splice_cmd->states = tal_arr(splice_cmd, + struct splice_cmd_action_state*, + tal_count(splice_cmd->actions)); + + for (size_t i = 0; i < tal_count(splice_cmd->states); i++) { + splice_cmd->states[i] = tal(splice_cmd->states, + struct splice_cmd_action_state); + splice_cmd->states[i]->state = SPLICE_CMD_NONE; + } + } + + req = jsonrpc_request_start(cmd, "listpeerchannels", + listpeerchannels_get_result, + splice_error, splice_cmd); + + return send_outreq(req); +} + +const struct plugin_command splice_commands[] = { + { + "dev-splice", + json_splice + }, +}; +const size_t num_splice_commands = ARRAY_SIZE(splice_commands); diff --git a/plugins/spender/splice.h b/plugins/spender/splice.h new file mode 100644 index 000000000000..4f4e1ad2c348 --- /dev/null +++ b/plugins/spender/splice.h @@ -0,0 +1,59 @@ +#ifndef LIGHTNING_PLUGINS_SPENDER_SPLICE_H +#define LIGHTNING_PLUGINS_SPENDER_SPLICE_H +#include "config.h" + +#include + +extern const struct plugin_command splice_commands[]; +extern const size_t num_splice_commands; + +enum splice_cmd_state { + SPLICE_CMD_NONE = 0, + SPLICE_CMD_INIT, + SPLICE_CMD_UPDATE, + SPLICE_CMD_UPDATE_NEEDS_CHANGES, + SPLICE_CMD_UPDATE_DONE, + SPLICE_CMD_RECVED_SIGS, + SPLICE_CMD_DONE, +}; + +struct splice_cmd_action_state { + enum splice_cmd_state state; +}; + +struct splice_cmd { + /* The plugin-level command. */ + struct command *cmd; + /* Script input by user */ + const char *script; + /* The result of parsing the script or json */ + struct splice_script_result **actions; + /* The states of actions at the same index */ + struct splice_cmd_action_state **states; + /* The active psbt */ + struct wally_psbt *psbt; + /* Output result but don't do any action */ + bool dryrun; + /* Execute the splice and abort at the last moment */ + bool wetrun; + /* Feerate queried from lightningd */ + u32 feerate_per_kw; + /* Override max feerate */ + bool force_feerate; + /* How many wallet inputs have we added to the psbt */ + int wallet_inputs_to_signed; + /* Final result */ + struct bitcoin_txid final_txid; + /* Has the fee been calculated yet */ + bool fee_calculated; + /* The amount of sats provided by the user in the inital psbt */ + struct amount_sat initial_funds; + /* The minimum sats that must go back into the wallet */ + struct amount_sat emergency_sat; + /* A verbose debug log of all the splice states */ + char *debug_log; + /* Counter used for more readable debug logs */ + int debug_counter; +}; + +#endif /* LIGHTNING_PLUGINS_SPENDER_SPLICE_H */ diff --git a/tests/plugins/channeld_fakenet.c b/tests/plugins/channeld_fakenet.c index c9e4f52ecab4..8b7db6605ebd 100644 --- a/tests/plugins/channeld_fakenet.c +++ b/tests/plugins/channeld_fakenet.c @@ -1221,6 +1221,9 @@ static struct io_plan *recv_req(struct io_conn *conn, case WIRE_CHANNELD_SPLICE_FEERATE_ERROR: case WIRE_CHANNELD_SPLICE_FUNDING_ERROR: case WIRE_CHANNELD_SPLICE_ABORT: + case WIRE_CHANNELD_STFU: + case WIRE_CHANNELD_CONFIRMED_STFU: + case WIRE_CHANNELD_ABORT: /* Not supported */ case WIRE_CHANNELD_DEV_REENABLE_COMMIT: case WIRE_CHANNELD_DEV_QUIESCE: diff --git a/tests/test_misc.py b/tests/test_misc.py index 100bfa7a1fd3..2fd0b8009997 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -974,7 +974,7 @@ def test_cli(node_factory): .format(l1.daemon.lightning_dir), 'help']).decode('utf-8') # Test some known output. - assert 'addgossip message\n\naddpsbtoutput' in out + assert 'addgossip message\n\naddpsbtinput' in out # Check JSON id is as expected l1.daemon.wait_for_log(r'jsonrpc#[0-9]*: "cli:help#[0-9]*"\[IN\]') @@ -1178,7 +1178,7 @@ def test_cli_commando(node_factory): .format(l1.daemon.lightning_dir), 'help']).decode('utf-8') # Test some known output. - assert 'addgossip message\n\naddpsbtoutput' in out + assert 'addgossip message\n\naddpsbtinput' in out # Check JSON id is as expected l1.daemon.wait_for_log(r'jsonrpc#[0-9]*: "cli:help#[0-9]*"\[IN\]') @@ -1285,7 +1285,7 @@ def test_daemon_option(node_factory): '--lightning-dir={}' .format(l1.daemon.lightning_dir), 'help']).decode('utf-8') - assert 'addgossip message\n\naddpsbtoutput' in out + assert 'addgossip message\n\naddpsbtinput' in out subprocess.run(['cli/lightning-cli', '--network={}'.format(TEST_NETWORK), diff --git a/tests/test_splice.py b/tests/test_splice.py new file mode 100644 index 000000000000..867e624062bc --- /dev/null +++ b/tests/test_splice.py @@ -0,0 +1,69 @@ +from fixtures import * # noqa: F401,F403 +import pytest +import unittest +from utils import ( + TEST_NETWORK, only_one, wait_for +) + + +@pytest.mark.openchannel('v1') +@pytest.mark.openchannel('v2') +@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') +def test_script_splice_out(node_factory, bitcoind): + l1, l2 = node_factory.line_graph(2, fundamount=1000000, wait_for_announce=True, opts={'experimental-splicing': None}) + # Splice out 100k from first channel, explicitly putting result less fees into onchain wallet + l1.rpc.splice("*:? -> 100000; 100%-fee -> wallet", force_feerate=True, debug_log=True) + p1 = only_one(l1.rpc.listpeerchannels(peer_id=l2.info['id'])['channels']) + p2 = only_one(l2.rpc.listpeerchannels(l1.info['id'])['channels']) + assert p1['inflight'][0]['splice_amount'] == -100000 + assert p1['inflight'][0]['total_funding_msat'] == 900000000 + assert p1['inflight'][0]['our_funding_msat'] == 1000000000 + assert p2['inflight'][0]['splice_amount'] == 0 + assert p2['inflight'][0]['total_funding_msat'] == 900000000 + assert p2['inflight'][0]['our_funding_msat'] == 0 + bitcoind.generate_block(6, wait_for_mempool=1) + l2.daemon.wait_for_log(r'lightningd, splice_locked clearing inflights') + + p1 = only_one(l1.rpc.listpeerchannels(peer_id=l2.info['id'])['channels']) + p2 = only_one(l2.rpc.listpeerchannels(l1.info['id'])['channels']) + assert p1['to_us_msat'] == 900000000 + assert p1['total_msat'] == 900000000 + assert p2['to_us_msat'] == 0 + assert p2['total_msat'] == 900000000 + assert 'inflight' not in p1 + assert 'inflight' not in p2 + + wait_for(lambda: len(l1.rpc.listfunds()['outputs']) == 2) + wait_for(lambda: len(l1.rpc.listfunds()['channels']) == 1) + + +@pytest.mark.openchannel('v1') +@pytest.mark.openchannel('v2') +@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') +def test_script_splice_in(node_factory, bitcoind): + l1, l2 = node_factory.line_graph(2, fundamount=1000000, wait_for_announce=True, opts={'experimental-splicing': None}) + # Splice in 100k sats into first channel, explicitly taking out 200k sats from wallet + # and letting change go automatically back to wallet (100k less onchain fees) + l1.rpc.splice("wallet -> 200000; 100000 -> *:?", force_feerate=True, debug_log=True) + p1 = only_one(l1.rpc.listpeerchannels(peer_id=l2.info['id'])['channels']) + p2 = only_one(l2.rpc.listpeerchannels(l1.info['id'])['channels']) + assert p1['inflight'][0]['splice_amount'] == 100000 + assert p1['inflight'][0]['total_funding_msat'] == 1100000000 + assert p1['inflight'][0]['our_funding_msat'] == 1000000000 + assert p2['inflight'][0]['splice_amount'] == 0 + assert p2['inflight'][0]['total_funding_msat'] == 1100000000 + assert p2['inflight'][0]['our_funding_msat'] == 0 + bitcoind.generate_block(6, wait_for_mempool=1) + l2.daemon.wait_for_log(r'lightningd, splice_locked clearing inflights') + + p1 = only_one(l1.rpc.listpeerchannels(peer_id=l2.info['id'])['channels']) + p2 = only_one(l2.rpc.listpeerchannels(l1.info['id'])['channels']) + assert p1['to_us_msat'] == 1100000000 + assert p1['total_msat'] == 1100000000 + assert p2['to_us_msat'] == 0 + assert p2['total_msat'] == 1100000000 + assert 'inflight' not in p1 + assert 'inflight' not in p2 + + wait_for(lambda: len(l1.rpc.listfunds()['outputs']) == 1) + wait_for(lambda: len(l1.rpc.listfunds()['channels']) == 1) diff --git a/tests/test_splicing.py b/tests/test_splicing.py index bfeb46bb1864..02d3769cb670 100644 --- a/tests/test_splicing.py +++ b/tests/test_splicing.py @@ -23,6 +23,9 @@ def test_splice(node_factory, bitcoind): result = l1.rpc.splice_init(chan_id, 100000, funds_result['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) result = l1.rpc.signpsbt(result['psbt']) result = l1.rpc.splice_signed(chan_id, result['signed_psbt']) @@ -60,6 +63,9 @@ def test_splice_gossip(node_factory, bitcoind): result = l1.rpc.splice_init(chan_id, 100000, funds_result['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) result = l1.rpc.signpsbt(result['psbt']) result = l1.rpc.splice_signed(chan_id, result['signed_psbt']) @@ -118,6 +124,9 @@ def test_splice_listnodes(node_factory, bitcoind): result = l1.rpc.splice_init(chan_id, 100000, funds_result['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) result = l1.rpc.signpsbt(result['psbt']) result = l1.rpc.splice_signed(chan_id, result['signed_psbt']) @@ -151,6 +160,9 @@ def test_splice_out(node_factory, bitcoind): # Pay with fee by subjtracting 5000 from channel balance result = l1.rpc.splice_init(chan_id, -105000, funds_result['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) result = l1.rpc.splice_signed(chan_id, result['psbt']) l2.daemon.wait_for_log(r'CHANNELD_NORMAL to CHANNELD_AWAITING_SPLICE') @@ -189,6 +201,9 @@ def test_invalid_splice(node_factory, bitcoind): with pytest.raises(RpcError) as rpc_error: result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) assert rpc_error.value.error["code"] == 357 assert rpc_error.value.error["message"] == "You provided 1000000000msat but committed to 1100000000msat." @@ -205,6 +220,9 @@ def test_invalid_splice(node_factory, bitcoind): result = l1.rpc.splice_init(chan_id, 100000, funds_result['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) result = l1.rpc.signpsbt(result['psbt']) result = l1.rpc.splice_signed(chan_id, result['signed_psbt']) @@ -242,6 +260,9 @@ def test_commit_crash_splice(node_factory, bitcoind): result = l1.rpc.splice_init(chan_id, -105000, l1.rpc.addpsbtoutput(100000)['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) l1.daemon.wait_for_log(r"Splice initiator: we commit") @@ -256,6 +277,9 @@ def test_commit_crash_splice(node_factory, bitcoind): result = l1.rpc.splice_init(chan_id, -105000, l1.rpc.addpsbtoutput(100000)['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) result = l1.rpc.splice_signed(chan_id, result['psbt']) l2.daemon.wait_for_log(r'CHANNELD_NORMAL to CHANNELD_AWAITING_SPLICE') @@ -303,6 +327,9 @@ def test_splice_stuck_htlc(node_factory, bitcoind, executor): result = l1.rpc.splice_init(chan_id, 100000, funds_result['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) result = l1.rpc.signpsbt(result['psbt']) result = l1.rpc.splice_signed(chan_id, result['signed_psbt']) diff --git a/tests/test_splicing_disconnect.py b/tests/test_splicing_disconnect.py index b236fcfff847..7fdb834f6620 100644 --- a/tests/test_splicing_disconnect.py +++ b/tests/test_splicing_disconnect.py @@ -30,6 +30,9 @@ def test_splice_disconnect_sig(node_factory, bitcoind): result = l1.rpc.splice_init(chan_id, 100000, funds_result['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) result = l1.rpc.signpsbt(result['psbt']) result = l1.rpc.splice_signed(chan_id, result['signed_psbt']) @@ -79,13 +82,10 @@ def test_splice_disconnect_commit(node_factory, bitcoind, executor): funds_result = l1.rpc.fundpsbt("109000sat", "slow", 166, excess_as_change=True) result = l1.rpc.splice_init(chan_id, 100000, funds_result['psbt']) - print("l1 splice_update") result = l1.rpc.splice_update(chan_id, result['psbt']) - print("l1 signpsbt") - result = l1.rpc.signpsbt(result['psbt']) - print("l1 splice_signed") + assert(result['commitments_secured'] is False) - executor.submit(l1.rpc.splice_signed, chan_id, result['signed_psbt']) + executor.submit(l1.rpc.splice_update, chan_id, result['psbt']) print("l2 waiting for dev_disconnect msg") diff --git a/tests/test_splicing_insane.py b/tests/test_splicing_insane.py index ca7883252f12..4f15e603fe1b 100644 --- a/tests/test_splicing_insane.py +++ b/tests/test_splicing_insane.py @@ -13,6 +13,9 @@ def make_pending_splice(node_factory): result = l1.rpc.splice_init(chan_id, 100000, funds_result['psbt']) result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) result = l1.rpc.signpsbt(result['psbt']) result = l1.rpc.splice_signed(chan_id, result['signed_psbt']) diff --git a/wallet/reservation.c b/wallet/reservation.c index dffc48ab2c69..d1df0dc04d2c 100644 --- a/wallet/reservation.c +++ b/wallet/reservation.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -657,6 +658,9 @@ static struct command_result *json_addpsbtoutput(struct command *cmd, struct pubkey pubkey; s64 keyidx; const u8 *b32script; + bool *add_initiator_serial_ids; + struct wally_psbt_output *output; + u64 serial_id; if (!param_check(cmd, buffer, params, p_req("satoshi", param_sat, &amount), @@ -664,6 +668,8 @@ static struct command_result *json_addpsbtoutput(struct command *cmd, p_opt("locktime", param_number, &locktime), p_opt("destination", param_bitcoin_address, &b32script), + p_opt_def("add_initiator_serial_ids", param_bool, + &add_initiator_serial_ids, false), NULL)) return command_param_failed(); @@ -716,7 +722,13 @@ static struct command_result *json_addpsbtoutput(struct command *cmd, } outnum = psbt->num_outputs; - psbt_append_output(psbt, b32script, *amount); + output = psbt_append_output(psbt, b32script, *amount); + + if (*add_initiator_serial_ids) { + serial_id = psbt_new_output_serial(psbt, TX_INITIATOR); + psbt_output_set_serial_id(psbt, output, serial_id); + } + /* Add additional weight of output */ weight = bitcoin_tx_output_weight( chainparams->is_elements ? BITCOIN_SCRIPTPUBKEY_P2WPKH_LEN : BITCOIN_SCRIPTPUBKEY_P2TR_LEN); @@ -735,6 +747,184 @@ static const struct json_command addpsbtoutput_command = { }; AUTODATA(json_command, &addpsbtoutput_command); +static struct command_result *json_addpsbtinput(struct command *cmd, + const char *buffer, + const jsmntok_t *obj UNNEEDED, + const jsmntok_t *params) +{ + struct utxo **utxos; + const struct utxo **excluded; + bool all; + struct amount_sat *req_amount, input, emergency_sat, diff; + u32 current_height, *locktime, *reserve, weight, *min_feerate; + struct json_stream *response; + struct wally_psbt *psbt; + bool *add_initiator_serial_ids, *mark_our_inputs; + size_t inputs_count, psbt_locktime; + u64 serial_id; + + if (!param_check(cmd, buffer, params, + p_req("satoshi", param_sat, &req_amount), + p_opt("initialpsbt", param_psbt, &psbt), + p_opt("locktime", param_number, &locktime), + p_opt("min_feerate", param_feerate, &min_feerate), + p_opt_def("add_initiator_serial_ids", param_bool, + &add_initiator_serial_ids, false), + p_opt_def("mark_our_inputs", param_bool, + &mark_our_inputs, false), + p_opt_def("reserve", param_number, &reserve, + RESERVATION_DEFAULT), + NULL)) + return command_param_failed(); + + if (!psbt) { + if (!locktime) { + locktime = tal(cmd, u32); + *locktime = default_locktime(cmd->ld->topology); + } + psbt = create_psbt(cmd, 0, 0, *locktime); + } else if (locktime) { + return command_fail(cmd, FUNDING_PSBT_INVALID, + "Can't set locktime of an existing" + " {initialpsbt}"); + } + + if (!validate_psbt(psbt)) + return command_fail(cmd, + FUNDING_PSBT_INVALID, + "PSBT failed to validate."); + + if (!req_amount || amount_sat_is_zero(*req_amount)) + return command_fail(cmd, FUND_INPUT_IS_ZERO, "Cannot add input" + " value of zero."); + + if (!min_feerate) { + min_feerate = tal(cmd, u32); + *min_feerate = opening_feerate(cmd->ld->topology); + } + + all = amount_sat_eq(*req_amount, AMOUNT_SAT(-1ULL)); + + current_height = get_block_height(cmd->ld->topology); + + /* We keep adding until we meet their output requirements. */ + utxos = tal_arr(cmd, struct utxo *, 0); + + /* Either uneconomical at this feerate, or already included. */ + excluded = tal_arr(cmd, const struct utxo *, 0); + + input = AMOUNT_SAT(0); + weight = 0; + while (!inputs_sufficient(input, *req_amount, 0, 0, &diff)) { + struct utxo *utxo; + struct amount_sat fee; + u32 utxo_weight; + + utxo = wallet_find_utxo(utxos, cmd->ld->wallet, current_height, + &diff, 0, + minconf_to_maxheight(1, cmd->ld), true, + excluded); + + if (utxo) { + tal_arr_expand(&excluded, utxo); + utxo_weight = utxo_spend_weight(utxo, 0); + fee = amount_tx_fee(*min_feerate, utxo_weight); + + /* Uneconomic to add this utxo, skip it */ + if (!all && amount_sat_greater_eq(fee, utxo->amount)) + continue; + if (utxo_is_csv_locked(utxo, current_height)) + continue; + + tal_arr_expand(&utxos, utxo); + + /* It supplies more input. */ + if (!amount_sat_add(&input, input, utxo->amount)) + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "impossible UTXO value"); + + /* But also adds weight */ + weight += utxo_weight; + continue; + } + + /* If they said "all", we expect to run out of utxos. */ + if (all && tal_count(utxos)) + break; + + /* Since it's possible the lack of utxos is because we haven't + * finished syncing yet, report a sync timing error first */ + if (!topology_synced(cmd->ld->topology)) + return command_fail(cmd, + FUNDING_STILL_SYNCING_BITCOIN, + "Cannot afford: still syncing with" + " bitcoin network..."); + + return command_fail(cmd, FUND_CANNOT_AFFORD, + "Could not afford %s using all %zu" + " available UTXOs: %s short", + all ? "all" + : fmt_amount_sat(tmpctx, *req_amount), + tal_count(utxos), + all ? "all" + : fmt_amount_sat(tmpctx, diff)); + } + + tal_free(excluded); + + /* If rest of wallet has enough funds, than no emergency sats required. */ + if (wallet_has_funds(cmd->ld->wallet, + cast_const2(const struct utxo **, utxos), + get_block_height(cmd->ld->topology), + &cmd->ld->emergency_sat)) + emergency_sat = AMOUNT_SAT(0); + else + emergency_sat = cmd->ld->emergency_sat; + + if (wally_psbt_get_locktime(psbt, &psbt_locktime) != WALLY_OK) + return command_fail(cmd, FUNDING_PSBT_INVALID, + "Unable to load locktime from psbt"); + + inputs_count = psbt->num_inputs; + psbt = psbt_using_utxos(cmd, cmd->ld->wallet, utxos, psbt_locktime, + BITCOIN_TX_RBF_SEQUENCE, psbt); + + if (*add_initiator_serial_ids) { + for (size_t i = inputs_count; i < psbt->num_inputs; i++) { + serial_id = psbt_new_input_serial(psbt, TX_INITIATOR); + psbt_input_set_serial_id(psbt, &psbt->inputs[i], + serial_id); + } + } + + if (*mark_our_inputs) + for (size_t i = inputs_count; i < psbt->num_inputs; i++) + psbt_input_mark_ours(psbt, &psbt->inputs[i]); + + if (command_check_only(cmd)) + return command_check_done(cmd); + + response = json_stream_success(cmd); + json_add_psbt(response, "psbt", psbt); + json_add_num(response, "appended_inputs", + psbt->num_inputs - inputs_count); + json_add_num(response, "estimated_added_weight", weight); + json_add_amount_sat_msat(response, "excess_msat", diff); + json_add_amount_sat_msat(response, "emergency_msat", emergency_sat); + if (reserve) + reserve_and_report(response, cmd->ld->wallet, current_height, + *reserve, utxos); + + return command_success(cmd, response); +} + +static const struct json_command addpsbtinput_command = { + "addpsbtinput", + json_addpsbtinput, + false +}; +AUTODATA(json_command, &addpsbtinput_command); + static struct command_result *param_txout(struct command *cmd, const char *name, const char *buffer,