#include "config.h"
#include <bitcoin/script.h>
#include <ccan/array_size/array_size.h>
#include <ccan/asort/asort.h>
#include <ccan/json_escape/json_escape.h>
#include <ccan/str/hex/hex.h>
#include <ccan/tal/str/str.h>
#include <common/blindedpath.h>
#include <common/bolt11_json.h>
#include <common/bolt12_id.h>
#include <common/bolt12_merkle.h>
#include <common/clock_time.h>
#include <common/json_command.h>
#include <common/randbytes.h>
#include <common/random_select.h>
#include <common/timeout.h>
#include <hsmd/hsmd_wiregen.h>
#include <lightningd/channel.h>
#include <lightningd/hsm_control.h>
#include <lightningd/invoice.h>
#include <lightningd/notification.h>
#include <lightningd/peer_htlcs.h>
#include <lightningd/plugin_hook.h>
#include <lightningd/routehint.h>
#include <wallet/invoices.h>
#include <wallet/walletrpc.h>

const char *invoice_status_str(enum invoice_status state)
{
	switch (state) {
	case PAID:
		return "paid";
	case EXPIRED:
		return "expired";
	case UNPAID:
		return "unpaid";
	}
	abort();
}

static void json_add_invoice_fields(struct json_stream *response,
				    const struct invoice_details *inv)
{
	json_add_escaped_string(response, "label", inv->label);
	if (inv->invstring)
		json_add_invstring(response, inv->invstring);
	json_add_sha256(response, "payment_hash", &inv->rhash);
	if (inv->msat)
		json_add_amount_msat(response, "amount_msat", *inv->msat);
	json_add_string(response, "status", invoice_status_str(inv->state));
	if (inv->state == PAID) {
		json_add_u64(response, "pay_index", inv->pay_index);
		json_add_amount_msat(response,
				     "amount_received_msat", inv->received);
		json_add_u64(response, "paid_at", inv->paid_timestamp);
		if (inv->paid_outpoint) {
			json_object_start(response, "paid_outpoint");
			json_add_txid(response, "txid", &inv->paid_outpoint->txid);
			json_add_num(response, "outnum", inv->paid_outpoint->n);
			json_object_end(response);
		}
		json_add_preimage(response, "payment_preimage", &inv->r);
	}
	if (inv->description)
		json_add_string(response, "description", inv->description);

	json_add_u64(response, "expires_at", inv->expiry_time);
	if (inv->local_offer_id) {
		char *fail;
		struct tlv_invoice *tinv;

		json_add_sha256(response, "local_offer_id", inv->local_offer_id);

		/* Everyone loves seeing their own payer notes!
		 * Well: they will.  Trust me. */
		tinv = invoice_decode(tmpctx,
				      inv->invstring, strlen(inv->invstring),
				      NULL, NULL, &fail);
		if (tinv && tinv->invreq_payer_note)
			json_add_stringn(response, "invreq_payer_note",
					 tinv->invreq_payer_note,
					 tal_bytelen(tinv->invreq_payer_note));
	}
	json_add_u64(response, "created_index", inv->created_index);
	if (inv->updated_index)
		json_add_u64(response, "updated_index", inv->updated_index);
}

static void json_add_invoice(struct json_stream *response,
			     const char *fieldname,
			     const struct invoice_details *inv)
{
	json_object_start(response, fieldname);
	json_add_invoice_fields(response, inv);
	json_object_end(response);
}

static struct command_result *tell_waiter(struct command *cmd, u64 inv_dbid)
{
	struct json_stream *response;
	const struct invoice_details *details;

	details = invoices_get_details(cmd, cmd->ld->wallet->invoices, inv_dbid);
	if (details->state == PAID) {
		response = json_stream_success(cmd);
		json_add_invoice_fields(response, details);
		return command_success(cmd, response);
	} else {
		response = json_stream_fail(cmd, INVOICE_EXPIRED_DURING_WAIT,
					    "invoice expired during wait");
		json_add_invoice_fields(response, details);
		json_object_end(response);
		return command_failed(cmd, response);
	}
}

static void tell_waiter_deleted(struct command *cmd)
{
	was_pending(command_fail(cmd, LIGHTNINGD,
				 "Invoice deleted during wait"));
}
static void wait_on_invoice(const u64 *inv_dbid, void *cmd)
{
	if (inv_dbid)
		tell_waiter((struct command *) cmd, *inv_dbid);
	else
		tell_waiter_deleted((struct command *) cmd);
}
static void wait_timed_out(struct command *cmd)
{
	was_pending(command_fail(cmd, INVOICE_WAIT_TIMED_OUT,
				 "Timed out while waiting "
				 "for invoice to be paid"));
}

/* We derive invoice secret using 1-way function from payment_preimage
 * (just a different one from the payment_hash!) */
static void invoice_secret(const struct preimage *payment_preimage,
			   struct secret *payment_secret)
{
	struct preimage modified;
	struct sha256 secret;

	modified = *payment_preimage;
	modified.r[0] ^= 1;

	sha256(&secret, modified.r,
	       ARRAY_SIZE(modified.r) * sizeof(*modified.r));
	CROSS_TYPE_ASSIGNMENT(&payment_secret->data, &secret.u.u8);
}

struct invoice_payment_hook_payload {
	struct lightningd *ld;
	/* Set to NULL if it is deleted while waiting for plugin */
	struct htlc_set *set;
	/* What invoice it's trying to pay. */
	const struct json_escape *label;
	/* Outpoint that pays the invoice, if paid on chain. */
	struct bitcoin_outpoint *outpoint;
	/* Amount it's offering. */
	struct amount_msat msat;
	/* Preimage we'll give it if succeeds. */
	struct preimage preimage;
	/* FIXME: Include raw payload! */
};

static void invoice_payment_add_tlvs(struct json_stream *stream,
				     struct htlc_set *hset)
{
	struct htlc_in *hin;
	const struct tlv_payload *tlvs;
	assert(tal_count(hset->inpays) > 0);

	/* Only do this if it's actually an HTLC */
	if ((void *)hset->inpays[0]->fail != (void *)local_fail_in_htlc)
		return;

	/* Pick the first HTLC as representative for the entire set. */
	hin = hset->inpays[0]->arg;

	tlvs = hin->payload->tlv;

	json_array_start(stream, "extratlvs");

	for (size_t i = 0; i < tal_count(tlvs->fields); i++) {
		struct tlv_field *field = &tlvs->fields[i];
		/* If we have metadata attached it is not an extra TLV field. */
		if (field->meta == NULL) {
			json_object_start(stream, NULL);
			json_add_u64(stream, "type", field->numtype);
			json_add_num(stream, "length", field->length);
			json_add_hex_talarr(stream, "value", field->value);
			json_object_end(stream);
		}
	}
	json_array_end(stream);
}

static void
invoice_payment_serialize(struct invoice_payment_hook_payload *payload,
			  struct json_stream *stream,
			  struct plugin *plugin)
{
	json_object_start(stream, "payment");
	json_add_escaped_string(stream, "label", payload->label);
	json_add_preimage(stream, "preimage", &payload->preimage);
	json_add_amount_msat(stream, "msat", payload->msat);

	if (payload->ld->developer && payload->set)
		invoice_payment_add_tlvs(stream, payload->set);
	json_object_end(stream); /* .payment */
}

/* Set times out or HTLC deleted?  Remove set ptr from payload so we
 * know to ignore plugin return */
static void invoice_payload_remove_set(struct htlc_set *set,
				       struct invoice_payment_hook_payload *payload)
{
	assert(payload->set == set);
	payload->set = NULL;
}

/* Returns magic value to send generic incorrect_or_unknown_payment_details */
static const u8 *hook_gives_failmsg(const tal_t *ctx,
				    struct lightningd *ld,
				    const char *buffer,
				    const jsmntok_t *toks)
{
	const jsmntok_t *resulttok;
	const jsmntok_t *t;
	const u8 *failmsg;

	/* No plugin registered on hook at all? */
	if (!buffer)
		return NULL;

	resulttok = json_get_member(buffer, toks, "result");
	if (resulttok) {
		if (json_tok_streq(buffer, resulttok, "continue")) {
			return NULL;
		} else if (json_tok_streq(buffer, resulttok, "reject")) {
			/* htlc_set_fail makes this a per-htlc
			 * incorrect_or_unknown_payment_details */
			return tal_arr(ctx, u8, 0);
		} else
			fatal("Invalid invoice_payment hook result: %.*s",
			      toks[0].end - toks[0].start, buffer);
	}

	t = json_get_member(buffer, toks, "failure_message");
	if (!t) {
		fatal("Missing failure_message in invoice_payment hook result: %.*s",
		      toks[0].end - toks[0].start, buffer);
	}

	failmsg = json_tok_bin_from_hex(ctx, buffer, t);
	if (!failmsg)
		fatal("Invalid invoice_payment_hook failure_message: %.*s",
		      toks[0].end - toks[1].start, buffer);
	return failmsg;
}

static void
invoice_payment_hooks_done(struct invoice_payment_hook_payload *payload STEALS)
{
	u64 inv_dbid;
	struct lightningd *ld = payload->ld;

	tal_del_destructor2(payload->set, invoice_payload_remove_set, payload);
	/* We want to free this, whatever happens. */
	tal_steal(tmpctx, payload);

	/* If invoice gets paid meanwhile (plugin responds out-of-order?) then
	 * we can also fail */
	if (!invoices_find_by_label(ld->wallet->invoices, &inv_dbid, payload->label)) {
		htlc_set_fail(payload->set, NULL);
		return;
	}

	/* Paid or expired in the meantime. */
	if (!invoices_resolve(ld->wallet->invoices, inv_dbid, payload->msat,
			      payload->label, payload->outpoint)) {
		if (payload->set)
			htlc_set_fail(payload->set, NULL);
		return;
	}

	log_info(ld->log, "Resolved invoice '%s' with amount %s in %zu htlcs",
		 payload->label->s,
		 fmt_amount_msat(tmpctx, payload->msat),
		 payload->set ? tal_count(payload->set->inpays) : 0);
	if (payload->set)
		htlc_set_fulfill(payload->set, &payload->preimage);

	notify_invoice_payment(ld, payload->msat, &payload->preimage,
			       payload->label, payload->outpoint);
}

static bool
invoice_payment_deserialize(struct invoice_payment_hook_payload *payload,
			    const char *buffer,
			    const jsmntok_t *toks)
{
	struct lightningd *ld = payload->ld;
	const u8 *failmsg;

	/* If peer dies or something, this can happen. */
	if (!payload->set && !payload->outpoint) {
		log_debug(ld->log, "invoice '%s' paying htlc_in has gone!",
			  payload->label->s);
		return false;
	}

	if (payload->set) {
		/* Did we have a hook result? */
		failmsg = hook_gives_failmsg(NULL, ld, buffer, toks);
		if (failmsg) {
			htlc_set_fail(payload->set, take(failmsg));
			return false;
		}
	}
	return true;
}

REGISTER_PLUGIN_HOOK(invoice_payment,
		     invoice_payment_deserialize,
		     invoice_payment_hooks_done,
		     invoice_payment_serialize,
		     struct invoice_payment_hook_payload *);

const struct invoice_details *
invoice_check_payment(const tal_t *ctx,
		      struct lightningd *ld,
		      const struct sha256 *payment_hash,
		      const struct amount_msat msat,
		      const struct amount_msat *expected_msat_override,
		      const struct secret *payment_secret,
		      const char **err)
{
	u64 inv_dbid;
	const struct invoice_details *details;
	bool bolt12_payment;

	/* BOLT #4:
	 *  - if the payment hash has already been paid:
	 *    - MAY treat the payment hash as unknown.
	 *    - MAY succeed in accepting the HTLC.
	 *...
	 *  - if the payment hash is unknown:
	 *    - MUST fail the HTLC.
	 *    - MUST return an `incorrect_or_unknown_payment_details` error.
	 */
	if (!invoices_find_unpaid(ld->wallet->invoices, &inv_dbid, payment_hash)) {
		if (invoices_find_by_rhash(ld->wallet->invoices, &inv_dbid, payment_hash)) {
			*err = tal_fmt(ctx, "Already paid or expired invoice %s",
				       fmt_sha256(tmpctx, payment_hash));
		} else {
			*err = tal_fmt(ctx, "Unknown invoice %s",
				       fmt_sha256(tmpctx, payment_hash));
		}
		return NULL;
	}

	details = invoices_get_details(ctx, ld->wallet->invoices, inv_dbid);
	bolt12_payment = details->invstring && strstarts(details->invstring, "lni1");

	/* BOLT #4:
	 *  - if the `payment_secret` doesn't match the expected value for that
	 *     `payment_hash`, or the `payment_secret` is required and is not
	 *     present:
	 *    - MUST fail the HTLC.
	 */
	/* For BOLT12: we stash path_secret in this field if it's of
	 * correct length, so it must be present */
	if ((feature_is_set(details->features, COMPULSORY_FEATURE(OPT_VAR_ONION))
	     || bolt12_payment)
	    && !payment_secret) {
		*err = tal_fmt(ctx, "Attempt to pay %s without secret",
			       fmt_sha256(tmpctx, &details->rhash));
		return tal_free(details);
	}

	if (payment_secret) {
		struct secret expected;

		/* FIXME: BOLT 12 should require a *real* secret: a signature of the
		 * request using the payer_id key.  This just means they've
		 * *seen* the invoice! */
		if (bolt12_payment) {
			bolt12_path_secret(&ld->invoicesecret_base,
					   payment_hash,
					   &expected);
		} else
			invoice_secret(&details->r, &expected);
		if (!secret_eq_consttime(payment_secret, &expected)) {
			*err = tal_fmt(ctx, "Attempt to pay %s with wrong %ssecret",
				       fmt_sha256(tmpctx, &details->rhash),
				       bolt12_payment ? "path_" : "payment_");
			return tal_free(details);
		}
	}

	/* BOLT #4:
	 *
	 * An _intermediate hop_ MUST NOT, but the _final node_:
	 *...
	 *   - if the amount paid is less than the amount expected:
	 *     - MUST fail the HTLC.
	 */
	if (details->msat != NULL) {
		struct amount_msat twice;

		/* Override the expected amount. */
		struct amount_msat expected_msat =
			expected_msat_override ? *expected_msat_override : *details->msat;

		if (amount_msat_less(msat, expected_msat)) {
			*err = tal_fmt(ctx, "Attempt to pay %s with amount %s < %s",
				       fmt_sha256(tmpctx, &details->rhash),
				       fmt_amount_msat(tmpctx, msat),
				       fmt_amount_msat(tmpctx, expected_msat));
			return tal_free(details);
		}

		if (amount_msat_add(&twice, expected_msat, expected_msat)
		    && amount_msat_greater(msat, twice)) {
			*err = tal_fmt(ctx, "Attempt to pay %s with amount %s > %s",
				       fmt_sha256(tmpctx, &details->rhash),
				       fmt_amount_msat(tmpctx, msat),
				       fmt_amount_msat(tmpctx, twice));
			/* BOLT #4:
			 *
			 * - if the amount paid is more than twice the amount
			 *   expected:
			 *   - SHOULD fail the HTLC.
			 */
			return tal_free(details);
		}
	}
	return details;
}

void invoice_try_pay(struct lightningd *ld,
		     struct htlc_set *set,
		     const struct invoice_details *details,
		     struct amount_msat msat,
		     const struct bitcoin_outpoint *outpoint)
{
	struct invoice_payment_hook_payload *payload;

	payload = tal(NULL, struct invoice_payment_hook_payload);
	payload->ld = ld;
	payload->label = tal_steal(payload, details->label);
	payload->preimage = details->r;
	payload->msat = msat;
	payload->set = set;
	payload->outpoint = tal_dup_or_null(payload, struct bitcoin_outpoint, outpoint);

	// set is NULL if invoice is being paid on-chain
	if (payload->set)
		tal_add_destructor2(set, invoice_payload_remove_set, payload);
	plugin_hook_call_invoice_payment(ld, NULL, payload);
}

static bool hsm_sign_b11(const u5 *u5bytes,
			 const u8 *hrpu8,
			 secp256k1_ecdsa_recoverable_signature *rsig,
			 struct lightningd *ld)
{
	const u8 *msg;

	msg = hsm_sync_req(tmpctx, ld,
			   take(towire_hsmd_sign_invoice(NULL, u5bytes, hrpu8)));
        if (!fromwire_hsmd_sign_invoice_reply(msg, rsig))
		fatal("HSM gave bad sign_invoice_reply %s",
		      tal_hex(msg, msg));

	return true;
}

static void hsm_sign_b12_invoice(struct lightningd *ld,
				 struct tlv_invoice *invoice)
{
	struct sha256 merkle;
	const u8 *msg;

	assert(!invoice->signature);

 	merkle_tlv(invoice->fields, &merkle);
	msg = towire_hsmd_sign_bolt12(NULL, "invoice", "signature", &merkle, NULL);

	msg = hsm_sync_req(tmpctx, ld, take(msg));
	invoice->signature = tal(invoice, struct bip340sig);
        if (!fromwire_hsmd_sign_bolt12_reply(msg, invoice->signature))
		fatal("HSM gave bad sign_invoice_reply %s",
		      tal_hex(msg, msg));
}

static struct command_result *parse_fallback(struct command *cmd,
					     const char *buffer,
					     const jsmntok_t *fallback,
					     const u8 **fallback_script)

{
	enum address_parse_result fallback_parse;

	fallback_parse
		= json_to_address_scriptpubkey(cmd,
					       chainparams,
					       buffer, fallback,
					       fallback_script);
	if (fallback_parse == ADDRESS_PARSE_UNRECOGNIZED) {
		return command_fail(cmd, LIGHTNINGD,
				    "Fallback address not valid");
	} else if (fallback_parse == ADDRESS_PARSE_WRONG_NETWORK) {
		return command_fail(cmd, LIGHTNINGD,
				    "Fallback address does not match our network %s",
				    chainparams->network_name);
	}
	return NULL;
}

/*
 * From array of incoming channels [inchan], find suitable ones for
 * a payment-to-us of [amount_needed], using criteria:
 * 1. Channel's peer is known, in state CHANNELD_NORMAL and is online.
 * 2. Channel's peer capacity to pay us is sufficient.
 *
 * Then use weighted reservoir sampling, which makes probing channel balances
 * harder, to choose one channel from the set of suitable channels. It favors
 * channels that have less balance on our side as fraction of their capacity.
 */
static struct route_info **select_inchan(const tal_t *ctx,
					 struct lightningd *ld,
					 struct amount_msat amount_needed,
					 const struct routehint_candidate
					 *candidates)
{
	/* BOLT11 struct wants an array of arrays (can provide multiple routes) */
	struct route_info **r = NULL;
	double total_weight = 0.0;

	/* Collect suitable channels and assign each a weight.  */
	for (size_t i = 0; i < tal_count(candidates); i++) {
		struct amount_msat excess, capacity;
		struct amount_sat cumulative_reserve;
		double excess_frac;

		/* Does the peer have sufficient balance to pay us,
		 * even after having taken into account their reserve? */
		if (!amount_msat_sub(&excess, candidates[i].capacity,
				     amount_needed))
			continue;

		/* Channel balance as seen by our node:

		        |<----------------- capacity ----------------->|
		        .                                              .
		        .             |<------------------ their_msat -------------------->|
		        .             |                                .                   |
		        .             |<----- capacity_to_pay_us ----->|<- their_reserve ->|
		        .             |                                |                   |
		        .             |<- amount_needed --><- excess ->|                   |
		        .             |                                |                   |
		|-------|-------------|--------------------------------|-------------------|
		0       ^             ^                                ^                funding
		   our_reserve     our_msat	*/

		/* Find capacity and calculate its excess fraction */
		if (!amount_sat_add(&cumulative_reserve,
				    candidates[i].c->our_config.channel_reserve,
				    candidates[i].c->channel_info.their_config.channel_reserve)
		    || !amount_sat_to_msat(&capacity, candidates[i].c->funding_sats)
		    || !amount_msat_deduct_sat(&capacity, cumulative_reserve)) {
			log_broken(ld->log, "Channel %s capacity overflow!",
					fmt_short_channel_id(tmpctx, *candidates[i].c->scid));
			continue;
		}

		/* We don't want a 0 probability if 0 excess; it might be the
		 * only one!  So bump it by 1 msat */
		if (!amount_msat_accumulate(&excess, AMOUNT_MSAT(1))) {
			log_broken(ld->log, "Channel %s excess overflow!",
				   fmt_short_channel_id(tmpctx,
							*candidates[i].c->scid));
			continue;
		}
		excess_frac = amount_msat_ratio(excess, capacity);

		if (random_select(excess_frac, &total_weight)) {
			tal_free(r);
			r = tal_arr(ctx, struct route_info *, 1);
			r[0] = tal_dup(r, struct route_info, candidates[i].r);
		}
	}

	return r;
}

static int cmp_rr_number(const struct routehint_candidate *a,
			 const struct routehint_candidate *b,
			 struct lightningd *ld)
{
	if (a->c->rr_number > b->c->rr_number)
		return 1;
	if (a->c->rr_number < b->c->rr_number)
		return -1;

	/* They're unique, so can't be equal */
	log_broken(ld->log, "Two equal candidates %p and %p, channels %p and %p, rr_number %"PRIu64" and %"PRIu64,
		   a, b, a->c, b->c, a->c->rr_number, b->c->rr_number);
	return 0;
}

/** select_inchan_mpp
 *
 * @brief fallback in case select_inchan cannot find a *single*
 * channel capable of accepting the payment as a whole.
 * Also the main routehint-selector if we are completely unpublished
 * (i.e. all our channels are unpublished), since if we are completely
 * unpublished then the payer cannot fall back to just directly routing
 * to us.
 */
static struct route_info **select_inchan_mpp(const tal_t *ctx,
					     struct lightningd *ld,
					     struct amount_msat amount_needed,
					     struct routehint_candidate
					     *candidates)
{
	/* The total amount we have gathered for incoming channels.  */
	struct amount_msat gathered;
	/* Routehint array.  */
	struct route_info **routehints;

	gathered = AMOUNT_MSAT(0);
	routehints = tal_arr(ctx, struct route_info *, 0);

	/* Sort by rr_number, so we get fresh channels. */
	asort(candidates, tal_count(candidates), cmp_rr_number, ld);
	for (size_t i = 0; i < tal_count(candidates); i++) {
		if (amount_msat_greater_eq(gathered, amount_needed))
			break;

		/* Add to current routehints set.  */
		if (!amount_msat_accumulate(&gathered, candidates[i].capacity)) {
			log_broken(ld->log,
				   "Gathered channel capacity overflow: "
				   "%s + %s",
				   fmt_amount_msat(tmpctx, gathered),
				   fmt_amount_msat(tmpctx, candidates[i].capacity));
			continue;
		}
		tal_arr_expand(&routehints,
			       tal_dup(routehints, struct route_info,
				       candidates[i].r));
		/* Put to the back of the round-robin list */
		candidates[i].c->rr_number = ld->rr_counter++;
	}

	return routehints;
}

/* Encapsulating struct while we wait for gossipd to give us incoming channels */
struct chanhints {
	bool expose_all_private;
	struct short_channel_id *hints;
};

struct invoice_info {
	struct command *cmd;
	struct preimage payment_preimage;
	struct bolt11 *b11;
	struct json_escape *label;
	struct chanhints *chanhints;
	bool custom_fallbacks;
};

/* Add routehints based on listincoming results: NULL means success. */
static struct command_result *
add_routehints(struct invoice_info *info,
	       const char *buffer,
	       const jsmntok_t *toks,
	       bool *warning_mpp,
	       bool *warning_capacity,
	       bool *warning_deadends,
	       bool *warning_offline,
	       bool *warning_private_unused)
{
	const struct chanhints *chanhints = info->chanhints;
	bool node_unpublished;
	struct amount_msat avail_capacity, deadend_capacity, offline_capacity,
		private_capacity;
	struct routehint_candidate *candidates;
	struct amount_msat total, needed;

	/* Dev code can force routes. */
	if (info->b11->routes) {
	       *warning_mpp = *warning_capacity = *warning_deadends
		       = *warning_offline = *warning_private_unused
		       = false;
		return NULL;
	}

	candidates = routehint_candidates(tmpctx, info->cmd->ld,
					  buffer, toks,
					  chanhints ? &chanhints->expose_all_private : NULL,
					  chanhints ? chanhints->hints : NULL,
					  &node_unpublished,
					  &avail_capacity,
					  &private_capacity,
					  &deadend_capacity,
					  &offline_capacity);

	/* If they told us to use scids and we couldn't, fail. */
	if (tal_count(candidates) == 0
	    && chanhints && tal_count(chanhints->hints) != 0) {
		return command_fail(info->cmd,
				    INVOICE_HINTS_GAVE_NO_ROUTES,
				    "None of those hints were suitable local channels");
	}

	needed = info->b11->msat ? *info->b11->msat : AMOUNT_MSAT(1);

	/* If we are not completely unpublished, try with reservoir
	 * sampling first.
	 *
	 * Why do we not do this if we are completely unpublished?
	 * Because it is possible that multiple invoices will, by
	 * chance, select the same channel as routehint.
	 * This single channel might not be able to accept all the
	 * incoming payments on all the invoices generated.
	 * If we were published, that is fine because the payer can
	 * fall back to just attempting to route directly.
	 * But if we were unpublished, the only way for the payer to
	 * reach us would be via the routehints we provide, so we
	 * should make an effort to avoid overlapping incoming
	 * channels, which is done by select_inchan_mpp.
	 */
	if (!node_unpublished)
		info->b11->routes = select_inchan(info->b11,
						  info->cmd->ld,
						  needed,
						  candidates);

	/* If we are completely unpublished, or if the above reservoir
	 * sampling fails, select channels by round-robin.  */
	if (tal_count(info->b11->routes) == 0) {
		info->b11->routes = select_inchan_mpp(info->b11,
						      info->cmd->ld,
						      needed,
						      candidates);
		*warning_mpp = (tal_count(info->b11->routes) > 1);
	} else {
		*warning_mpp = false;
	}

	log_debug(info->cmd->ld->log, "needed = %s, avail_capacity = %s, private_capacity = %s, offline_capacity = %s, deadend_capacity = %s",
		  fmt_amount_msat(tmpctx, needed),
		  fmt_amount_msat(tmpctx, avail_capacity),
		  fmt_amount_msat(tmpctx, private_capacity),
		  fmt_amount_msat(tmpctx, offline_capacity),
		  fmt_amount_msat(tmpctx, deadend_capacity));

	if (!amount_msat_add(&total, avail_capacity, offline_capacity)
	    || !amount_msat_accumulate(&total, deadend_capacity)
	    || !amount_msat_accumulate(&total, private_capacity))
		fatal("Cannot add %s + %s + %s + %s",
		      fmt_amount_msat(tmpctx, avail_capacity),
		      fmt_amount_msat(tmpctx, offline_capacity),
		      fmt_amount_msat(tmpctx, deadend_capacity),
		      fmt_amount_msat(tmpctx, private_capacity));

	/* If we literally didn't have capacity at all, warn. */
	*warning_capacity = amount_msat_greater_eq(needed, total);

	/* We only warn about these if we didn't have capacity and
	 * they would have helped. */
	*warning_offline = false;
	*warning_deadends = false;
	*warning_private_unused = false;
	if (amount_msat_greater(needed, avail_capacity)) {
		struct amount_msat tot;

		/* We didn't get enough: would offline have helped? */
		if (!amount_msat_add(&tot, avail_capacity, offline_capacity))
			abort();
		if (amount_msat_greater_eq(tot, needed)) {
			*warning_offline = true;
			goto done;
		}

		/* Hmm, what about deadends? */
		if (!amount_msat_accumulate(&tot, deadend_capacity))
			abort();
		if (amount_msat_greater_eq(tot, needed)) {
			*warning_deadends = true;
			goto done;
		}

		/* What about private channels? */
		if (!amount_msat_accumulate(&tot, private_capacity))
			abort();
		if (amount_msat_greater_eq(tot, needed)) {
			*warning_private_unused = true;
			goto done;
		}
	}

done:
	return NULL;
}

static struct command_result *
invoice_complete(struct invoice_info *info,
		 bool warning_no_listincoming,
		 bool warning_mpp,
		 bool warning_capacity,
		 bool warning_deadends,
		 bool warning_offline,
		 bool warning_private_unused)
{
	struct json_stream *response;
	u64 inv_dbid;
	char *b11enc;
	const struct invoice_details *details;
	struct secret payment_secret;
	struct wallet *wallet = info->cmd->ld->wallet;

	b11enc = bolt11_encode(info, info->b11, false,
			       hsm_sign_b11, info->cmd->ld);

	/* Check duplicate preimage (unlikely unless they specified it!) */
	if (invoices_find_by_rhash(wallet->invoices,
				   &inv_dbid, &info->b11->payment_hash)) {
		return command_fail(info->cmd,
				    INVOICE_PREIMAGE_ALREADY_EXISTS,
				    "preimage already used");
	}

	if (!invoices_create(wallet->invoices,
			     &inv_dbid,
			     info->b11->msat,
			     info->label,
			     info->b11->expiry,
			     b11enc,
			     info->b11->description,
			     info->b11->features,
			     &info->payment_preimage,
			     &info->b11->payment_hash,
			     NULL)) {
		return command_fail(info->cmd, INVOICE_LABEL_ALREADY_EXISTS,
				    "Duplicate label '%s'",
				    info->label->s);
	}

	if (info->cmd->ld->unified_invoices && info->b11->fallbacks && !info->custom_fallbacks) {
		for (size_t i = 0; i < tal_count(info->b11->fallbacks); i++) {
			const u8 *fallback_script = info->b11->fallbacks[i];
			invoices_create_fallback(wallet->invoices, inv_dbid, fallback_script);
		}
	}

	/* Get details */
	details = invoices_get_details(info, wallet->invoices, inv_dbid);

	response = json_stream_success(info->cmd);
	json_add_sha256(response, "payment_hash", &details->rhash);
	json_add_u64(response, "expires_at", details->expiry_time);
	json_add_string(response, "bolt11", details->invstring);
	invoice_secret(&details->r, &payment_secret);
	json_add_secret(response, "payment_secret", &payment_secret);
	json_add_u64(response, "created_index", details->created_index);

	notify_invoice_creation(info->cmd->ld, info->b11->msat,
				&info->payment_preimage, info->label);

	if (warning_no_listincoming)
		json_add_string(response, "warning_listincoming",
				"No listincoming command available, cannot add routehints to invoice");
	if (warning_mpp)
		json_add_string(response, "warning_mpp",
				"The invoice is only payable by MPP-capable payers.");
	if (warning_capacity)
		json_add_string(response, "warning_capacity",
				"Insufficient incoming channel capacity to pay invoice");

	if (warning_deadends)
		json_add_string(response, "warning_deadends",
				"Insufficient incoming capacity, once dead-end peers were excluded");

	if (warning_offline)
		json_add_string(response, "warning_offline",
				"Insufficient incoming capacity, once offline peers were excluded");

	if (warning_private_unused)
		json_add_string(response, "warning_private_unused",
				"Insufficient incoming capacity, once private channels were excluded (try exposeprivatechannels=true?)");

	if (info->cmd->ld->unified_invoices && info->custom_fallbacks)
		json_add_string(response, "warning_custom_fallbacks",
				"WARNING: Not tracking on-chain payments for custom fallback addresses");

	return command_success(info->cmd, response);
}

/* Return from "listincoming". */
static void listincoming_done(const char *buffer,
			      const jsmntok_t *toks,
			      const jsmntok_t *idtok UNUSED,
			      struct invoice_info *info)
{
	struct command_result *ret;
	bool warning_mpp, warning_capacity, warning_deadends, warning_offline, warning_private_unused;

	ret = add_routehints(info, buffer, toks,
			     &warning_mpp,
			     &warning_capacity,
			     &warning_deadends,
			     &warning_offline,
			     &warning_private_unused);
	if (ret)
		return;

	invoice_complete(info,
			 false,
			 warning_mpp,
			 warning_capacity,
			 warning_deadends,
			 warning_offline,
			 warning_private_unused);
}

void invoice_check_onchain_payment(struct lightningd *ld,
				   const u8 *scriptPubKey,
				   struct amount_sat sat,
				   const struct bitcoin_outpoint *outpoint)
{
	u64 inv_dbid;
	const struct invoice_details *details;
	struct amount_msat msat;
	if (!amount_sat_to_msat(&msat, sat))
		abort();
	/* Does this onchain payment fulfill an invoice? */
	if(!invoices_find_by_fallback_script(ld->wallet->invoices, &inv_dbid, scriptPubKey)) {
		return;
	}

	details = invoices_get_details(tmpctx, ld->wallet->invoices, inv_dbid);

	if (amount_msat_less(msat, *details->msat)) {
		// notify_underpaid_onchain_invoice();
		return;
	}

	invoice_try_pay(ld, NULL, details, msat, outpoint);
}

/* Since this is a dev-only option, we will crash if dev-routes is not
 * an array-of-arrays-of-correct-items. */
static struct route_info *unpack_route(const tal_t *ctx,
				       const char *buffer,
				       const jsmntok_t *routetok)
{
	const jsmntok_t *t;
	size_t i;
	struct route_info *route = tal_arr(ctx, struct route_info, routetok->size);

	json_for_each_arr(i, t, routetok) {
		const jsmntok_t *pubkey, *fee_base, *fee_prop, *scid, *cltv;
		struct route_info *r = &route[i];
		u32 cltv_u32;

		pubkey = json_get_member(buffer, t, "id");
		scid = json_get_member(buffer, t, "short_channel_id");
		fee_base = json_get_member(buffer, t, "fee_base_msat");
		fee_prop = json_get_member(buffer, t,
					   "fee_proportional_millionths");
		cltv = json_get_member(buffer, t, "cltv_expiry_delta");

		if (!json_to_node_id(buffer, pubkey, &r->pubkey)
		    || !json_to_short_channel_id(buffer, scid,
						 &r->short_channel_id)
		    || !json_to_number(buffer, fee_base, &r->fee_base_msat)
		    || !json_to_number(buffer, fee_prop,
				       &r->fee_proportional_millionths)
		    || !json_to_number(buffer, cltv, &cltv_u32))
			abort();
		/* We don't have a json_to_u16 */
		r->cltv_expiry_delta = cltv_u32;
	}
	return route;
}

static struct route_info **unpack_routes(const tal_t *ctx,
					 const char *buffer,
					 const jsmntok_t *routestok)
{
	struct route_info **routes;
	const jsmntok_t *t;
	size_t i;

	if (!routestok)
		return NULL;

	routes = tal_arr(ctx, struct route_info *, routestok->size);
	json_for_each_arr(i, t, routestok)
		routes[i] = unpack_route(routes, buffer, t);

	return routes;
}

static struct command_result *param_positive_msat_or_any(struct command *cmd,
							 const char *name,
							 const char *buffer,
							 const jsmntok_t *tok,
							 struct amount_msat **msat)
{
	if (json_tok_streq(buffer, tok, "any")) {
		*msat = NULL;
		return NULL;
	}
	*msat = tal(cmd, struct amount_msat);
	if (parse_amount_msat(*msat, buffer + tok->start, tok->end - tok->start)
	    && !amount_msat_is_zero(**msat))
		return NULL;

	return command_fail_badparam(cmd, name, buffer, tok,
				     "should be positive msat or 'any'");
}

static struct command_result *param_chanhints(struct command *cmd,
					      const char *name,
					      const char *buffer,
					      const jsmntok_t *tok,
					      struct chanhints **chanhints)
{
	bool boolhint;

	*chanhints = tal(cmd, struct chanhints);

	/* Could be simply "true" or "false" */
	if (json_to_bool(buffer, tok, &boolhint)) {
		(*chanhints)->expose_all_private = boolhint;
		(*chanhints)->hints = NULL;
		return NULL;
	}

	(*chanhints)->expose_all_private = true;
	/* Could be a single short_channel_id or an array */
	if (tok->type == JSMN_ARRAY) {
		size_t i;
		const jsmntok_t *t;

		(*chanhints)->hints
			= tal_arr(*chanhints, struct short_channel_id,
				  tok->size);
		json_for_each_arr(i, t, tok) {
			if (!json_to_short_channel_id(buffer, t,
						      &(*chanhints)->hints[i])) {
				return command_fail_badparam(cmd, name, buffer, t,
						    "should be a short channel id");
			}
		}
		return NULL;
	}

	/* Otherwise should be a short_channel_id */
	return param_short_channel_id(cmd, name, buffer, tok,
				      &(*chanhints)->hints);
}

static struct command_result *param_preimage(struct command *cmd,
					     const char *name,
					     const char *buffer,
					     const jsmntok_t *tok,
					     struct preimage **preimage)
{
	*preimage = tal(cmd, struct preimage);
	if (!hex_decode(buffer + tok->start, tok->end - tok->start,
			*preimage, sizeof(**preimage)))
		return command_fail_badparam(cmd, "preimage",
					     buffer, tok,
					     "should be 64 hex digits");
	return NULL;
}

static struct command_result *json_invoice(struct command *cmd,
					   const char *buffer,
					   const jsmntok_t *obj UNNEEDED,
					   const jsmntok_t *params)
{
	const jsmntok_t *fallbacks;
	struct amount_msat *msatoshi_val;
	struct invoice_info *info;
	const char *desc_val;
	const u8 **fallback_scripts = NULL;
	u64 *expiry;
	struct sha256 rhash;
	struct secret payment_secret;
	struct preimage *preimage;
	u32 *cltv;
	struct jsonrpc_request *req;
	struct plugin *plugin;
	bool *hashonly;
	const size_t inv_max_label_len = 128;
	const jsmntok_t *dev_routes;

	info = tal(cmd, struct invoice_info);
	info->cmd = cmd;

	if (!param_check(cmd, buffer, params,
			 p_req("amount_msat", param_positive_msat_or_any, &msatoshi_val),
			 p_req("label", param_label, &info->label),
			 p_req("description", param_escaped_string, &desc_val),
			 p_opt_def("expiry", param_u64, &expiry, 3600*24*7),
			 p_opt("fallbacks", param_array, &fallbacks),
			 p_opt("preimage", param_preimage, &preimage),
			 p_opt("exposeprivatechannels", param_chanhints,
			       &info->chanhints),
			 p_opt_def("cltv", param_number, &cltv,
				   cmd->ld->config.cltv_final),
			 p_opt_def("deschashonly", param_bool, &hashonly, false),
			 p_opt("dev-routes", param_array, &dev_routes),
			 NULL))
		return command_param_failed();

	if (dev_routes && !cmd->ld->developer)
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "dev-routes requires --developer");

	if (strlen(info->label->s) > inv_max_label_len) {
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "Label '%s' over %zu bytes", info->label->s, inv_max_label_len);
	}

	if (strlen(desc_val) > BOLT11_FIELD_BYTE_LIMIT && !*hashonly) {
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "Description greater than %d bytes "
				    "invalid "
				    "(description length %zu)",
				    BOLT11_FIELD_BYTE_LIMIT,
				    strlen(desc_val));
	}

	if (command_check_only(cmd))
		return command_check_done(cmd);

	info->custom_fallbacks = false;
	if (fallbacks) {
		info->custom_fallbacks = true;
		if (cmd->ld->unified_invoices) {
			log_info(cmd->ld->log,
				 "WARNING: Not tracking on-chain payments "
				 "for custom fallback addresses");
		}
		size_t i;
		const jsmntok_t *t;

		fallback_scripts = tal_arr(cmd, const u8 *, fallbacks->size);
		json_for_each_arr(i, t, fallbacks) {
			struct command_result *r;

			r = parse_fallback(cmd, buffer, t, &fallback_scripts[i]);
			if (r)
				return r;
		}
	} else if (cmd->ld->unified_invoices) {
		struct pubkey pubkey;
		const u8 *p2tr;

		fallback_scripts = tal_arr(cmd, const u8 *, 1);

		if (!newaddr_inner(cmd, &pubkey, ADDR_P2TR))
			return command_fail(cmd, LIGHTNINGD, "Keys exhausted ");

		p2tr = scriptpubkey_p2tr(fallback_scripts, &pubkey);
		fallback_scripts[0] = p2tr;
	}

	if (preimage)
		info->payment_preimage = *preimage;
	else
		/* Generate random secret preimage. */
		randbytes(&info->payment_preimage,
			    sizeof(info->payment_preimage));
	/* Generate preimage hash. */
	sha256(&rhash, &info->payment_preimage, sizeof(info->payment_preimage));
	/* Generate payment secret. */
	invoice_secret(&info->payment_preimage, &payment_secret);

	info->b11 = new_bolt11(info, msatoshi_val);
	info->b11->chain = chainparams;
	info->b11->timestamp = clock_time().ts.tv_sec;
	info->b11->payment_hash = rhash;
	info->b11->receiver_id = cmd->ld->our_nodeid;
	info->b11->min_final_cltv_expiry = *cltv;
	info->b11->expiry = *expiry;
	info->b11->description = tal_steal(info->b11, desc_val);
	/* BOLT #11:
	 * * `h` (23): `data_length` 52. 256-bit description of purpose of payment (SHA256).
	 *...
	 * A writer:
	 *...
	 *    - MUST include either exactly one `d` or exactly one `h` field.
	 */
	if (*hashonly) {
		info->b11->description_hash = tal(info->b11, struct sha256);
		sha256(info->b11->description_hash, desc_val, strlen(desc_val));
	} else
		info->b11->description_hash = NULL;
	info->b11->payment_secret = tal_dup(info->b11, struct secret,
					    &payment_secret);
	info->b11->features = tal_dup_talarr(info->b11, u8,
					     cmd->ld->our_features
					     ->bits[BOLT11_FEATURE]);

	info->b11->routes = unpack_routes(info->b11, buffer, dev_routes);

	if (fallback_scripts)
		info->b11->fallbacks = tal_steal(info->b11, fallback_scripts);

	/* We can't generate routehints without listincoming. */
	plugin = find_plugin_for_command(cmd->ld, "listincoming");
	if (!plugin) {
		return invoice_complete(info, true,
					false, false, false, false, false);
	}

	req = jsonrpc_request_start(info, "listincoming",
				    cmd->id,
				    command_logger(cmd),
				    NULL, listincoming_done,
				    info);
	jsonrpc_request_end(req);
	plugin_request_send(plugin, req);
	return command_still_pending(cmd);
}

static const struct json_command invoice_command = {
	"invoice",
	json_invoice,
};
AUTODATA(json_command, &invoice_command);

static void json_add_invoices(struct json_stream *response,
			      struct wallet *wallet,
			      const struct json_escape *label,
			      const struct sha256 *payment_hash,
			      const struct sha256 *local_offer_id,
			      const enum wait_index *listindex,
			      u64 liststart,
			      const u32 *listlimit)
{
	const struct invoice_details *details;
	u64 inv_dbid;

	/* Don't iterate entire db if we're just after one. */
	if (label) {
		if (invoices_find_by_label(wallet->invoices, &inv_dbid, label)) {
			details =
			    invoices_get_details(tmpctx, wallet->invoices, inv_dbid);
			json_add_invoice(response, NULL, details);
		}
	} else if (payment_hash != NULL) {
		if (invoices_find_by_rhash(wallet->invoices, &inv_dbid,
						 payment_hash)) {
			details =
			    invoices_get_details(tmpctx, wallet->invoices, inv_dbid);
			json_add_invoice(response, NULL, details);
		}
	} else {
		struct db_stmt *stmt;

		for (stmt = invoices_first(wallet->invoices,
					   listindex, liststart, listlimit,
					   &inv_dbid);
		     stmt;
		     stmt = invoices_next(wallet->invoices, stmt, &inv_dbid)) {
			details = invoices_get_details(tmpctx,
						       wallet->invoices, inv_dbid);
			/* FIXME: db can filter this better! */
			if (local_offer_id) {
				if (!details->local_offer_id
				    || !sha256_eq(local_offer_id,
						  details->local_offer_id))
					continue;
			}
			json_add_invoice(response, NULL, details);
		}
	}
}

static struct command_result *json_listinvoices(struct command *cmd,
						const char *buffer,
						const jsmntok_t *obj UNNEEDED,
						const jsmntok_t *params)
{
	struct json_escape *label;
	struct json_stream *response;
	struct wallet *wallet = cmd->ld->wallet;
	const char *invstring;
	struct sha256 *payment_hash, *offer_id;
	enum wait_index *listindex;
	u64 *liststart;
	u32 *listlimit;
	char *fail;

	if (!param_check(cmd, buffer, params,
			 p_opt("label", param_label, &label),
			 p_opt("invstring", param_invstring, &invstring),
			 p_opt("payment_hash", param_sha256, &payment_hash),
			 p_opt("offer_id", param_sha256, &offer_id),
			 p_opt("index", param_index, &listindex),
			 p_opt_def("start", param_u64, &liststart, 0),
			 p_opt("limit", param_u32, &listlimit),
			 NULL))
		return command_param_failed();

	/* Yeah, I wasn't sure about this style either.  It's curt though! */
	if (!!label + !!invstring + !!payment_hash + !!offer_id > 1) {
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "Can only specify one of"
				    " {label}, {invstring}, {payment_hash}"
				    " or {offer_id}");
	}
	if (*liststart != 0 && !listindex) {
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "Can only specify {start} with {index}");
	}
	if (listlimit && !listindex) {
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "Can only specify {limit} with {index}");
	}

	/* Extract the payment_hash from the invoice. */
	if (invstring != NULL) {
		struct bolt11 *b11;
		b11 = bolt11_decode(cmd, invstring, cmd->ld->our_features, NULL,
				    NULL, &fail);
		if (b11)
			payment_hash = &b11->payment_hash;
		else {
			struct tlv_invoice *b12
				= invoice_decode(tmpctx, invstring,
						 strlen(invstring),
						 cmd->ld->our_features, NULL,
						 &fail);
			if (!b12 || !b12->invoice_payment_hash) {
				return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
						    "Invalid invstring");
			}
			payment_hash = b12->invoice_payment_hash;
		}
	}

	if (command_check_only(cmd))
		return command_check_done(cmd);

	response = json_stream_success(cmd);
	json_array_start(response, "invoices");
	json_add_invoices(response, wallet, label, payment_hash, offer_id,
			  listindex, *liststart, listlimit);
	json_array_end(response);
	return command_success(cmd, response);
}

static const struct json_command listinvoices_command = {
	"listinvoices",
	json_listinvoices,
};
AUTODATA(json_command, &listinvoices_command);

static struct command_result *json_delinvoice(struct command *cmd,
					      const char *buffer,
					      const jsmntok_t *obj UNNEEDED,
					      const jsmntok_t *params)
{
	u64 inv_dbid;
	struct invoice_details *details;
	struct json_stream *response;
	const char *status, *actual_status;
	struct json_escape *label;
	struct wallet *wallet = cmd->ld->wallet;
	bool *deldesc;

	if (!param_check(cmd, buffer, params,
			 p_req("label", param_label, &label),
			 p_req("status", param_string, &status),
			 p_opt_def("desconly", param_bool, &deldesc, false),
			 NULL))
		return command_param_failed();

	if (!invoices_find_by_label(wallet->invoices, &inv_dbid, label)) {
		return command_fail(cmd, INVOICE_NOT_FOUND, "Unknown invoice");
	}

	details = invoices_get_details(cmd, cmd->ld->wallet->invoices, inv_dbid);

	/* This is time-sensitive, so only call once; otherwise error msg
	 * might not make sense if it changed! */
	actual_status = invoice_status_str(details->state);
	if (!streq(actual_status, status)) {
		struct json_stream *js;
		js = json_stream_fail(cmd, INVOICE_STATUS_UNEXPECTED,
				      tal_fmt(tmpctx,
					      "Invoice status is %s not %s",
					      actual_status, status));
		json_add_string(js, "current_status", actual_status);
		json_add_string(js, "expected_status", status);
		json_object_end(js);
		return command_failed(cmd, js);
	}

	if (*deldesc) {
		if (!details->description)
			return command_fail(cmd, INVOICE_NO_DESCRIPTION,
					    "Invoice description already removed");

		if (command_check_only(cmd))
			return command_check_done(cmd);

		if (!invoices_delete_description(wallet->invoices, inv_dbid,
						 details->label, details->description)) {
			log_broken(cmd->ld->log,
				   "Error attempting to delete description of invoice %"PRIu64,
				   inv_dbid);
			/* FIXME: allocate a generic DATABASE_ERROR code.  */
			return command_fail(cmd, LIGHTNINGD, "Database error");
		}
		details->description = tal_free(details->description);
	} else {
		if (command_check_only(cmd))
			return command_check_done(cmd);

		if (!invoices_delete(wallet->invoices, inv_dbid,
				     details->state,
				     details->label,
				     details->invstring)) {
			log_broken(cmd->ld->log,
				   "Error attempting to remove invoice %"PRIu64,
				   inv_dbid);
			/* FIXME: allocate a generic DATABASE_ERROR code.  */
			return command_fail(cmd, LIGHTNINGD, "Database error");
		}
	}

	response = json_stream_success(cmd);
	json_add_invoice_fields(response, details);
	return command_success(cmd, response);
}

static const struct json_command delinvoice_command = {
	"delinvoice",
	json_delinvoice,
};
AUTODATA(json_command, &delinvoice_command);

static struct command_result *json_waitanyinvoice(struct command *cmd,
						  const char *buffer,
						  const jsmntok_t *obj UNNEEDED,
						  const jsmntok_t *params)
{
	u64 *pay_index;
	u64 *timeout;
	struct wallet *wallet = cmd->ld->wallet;

	if (!param(cmd, buffer, params,
		   p_opt_def("lastpay_index", param_u64, &pay_index, 0),
		   p_opt("timeout", &param_u64, &timeout),
		   NULL))
		return command_param_failed();

	/*~ We allocate the timeout and the wallet-waitanyinvoice
	 * in the cmd context, so whichever one manages to complete
	 * the command first (and destroy the cmd context)
	 * auto-cancels the other, is not tal amazing?
	 */
	if (timeout)
		(void) new_reltimer(cmd->ld->timers, cmd,
				    time_from_sec(*timeout),
				    &wait_timed_out, cmd);

	/* Set command as pending. We do not know if
	 * wallet_invoice_waitany will return immediately
	 * or not, so indicating pending is safest.  */
	fixme_ignore(command_still_pending(cmd));

	/* Find next paid invoice. */
	invoices_waitany(cmd, wallet->invoices, *pay_index,
			 &wait_on_invoice, (void*) cmd);

	return command_its_complicated("wallet_invoice_waitany might complete"
				       " immediately, but we also call it as a"
				       " callback so plumbing through the return"
				       " is non-trivial.");
}


static const struct json_command waitanyinvoice_command = {
	"waitanyinvoice",
	json_waitanyinvoice,
};
AUTODATA(json_command, &waitanyinvoice_command);

/* Wait for an incoming payment matching the `label` in the JSON
 * command.  This will either return immediately if the payment has
 * already been received or it may add the `cmd` to the list of
 * waiters, if the payment is still pending.
 */
static struct command_result *json_waitinvoice(struct command *cmd,
					       const char *buffer,
					       const jsmntok_t *obj UNNEEDED,
					       const jsmntok_t *params)
{
	u64 inv_dbid;
	const struct invoice_details *details;
	struct wallet *wallet = cmd->ld->wallet;
	struct json_escape *label;

	if (!param_check(cmd, buffer, params,
			 p_req("label", param_label, &label),
			 NULL))
		return command_param_failed();

	if (!invoices_find_by_label(wallet->invoices, &inv_dbid, label)) {
		return command_fail(cmd, LIGHTNINGD, "Label not found");
	}
	if (command_check_only(cmd))
		return command_check_done(cmd);

	details = invoices_get_details(cmd, cmd->ld->wallet->invoices, inv_dbid);

	/* If paid or expired return immediately */
	if (details->state == PAID || details->state == EXPIRED) {
		return tell_waiter(cmd, inv_dbid);
	} else {
		/* There is an unpaid one matching, let's wait... */
		fixme_ignore(command_still_pending(cmd));
		invoices_waitone(cmd, wallet->invoices, inv_dbid,
				 &wait_on_invoice, (void *) cmd);
		return command_its_complicated("wallet_invoice_waitone might"
					       " complete immediately");
	}
}

static const struct json_command waitinvoice_command = {
	"waitinvoice",
	json_waitinvoice,
};
AUTODATA(json_command, &waitinvoice_command);

/* If we fail because it exists, we also return the clashing invoice */
static struct command_result *fail_exists(struct command *cmd,
					  const struct json_escape *label)
{
	struct json_stream *data;
	u64 inv_dbid;
	struct wallet *wallet = cmd->ld->wallet;

	data = json_stream_fail(cmd, INVOICE_LABEL_ALREADY_EXISTS,
				"Duplicate label");
	if (!invoices_find_by_label(wallet->invoices, &inv_dbid, label))
		fatal("Duplicate invoice %s not found any more?",
		      label->s);

	json_add_invoice_fields(data,
				invoices_get_details(cmd, wallet->invoices, inv_dbid));
	json_object_end(data);

	return command_failed(cmd, data);
}

/* This is only if we're a public node; otherwise, the offers plugin
 * will have populated a real blinded path */
static void add_stub_blindedpath(const tal_t *ctx,
				 struct lightningd *ld,
				 struct tlv_invoice *inv)
{
	struct blinded_path *path;
	struct privkey path_key;
	struct tlv_encrypted_data_tlv *tlv;

	path = tal(NULL, struct blinded_path);
	sciddir_or_pubkey_from_pubkey(&path->first_node_id, &ld->our_pubkey);
	randbytes(&path_key, sizeof(path_key));
	if (!pubkey_from_privkey(&path_key, &path->first_path_key))
		abort();
	path->path = tal_arr(path, struct blinded_path_hop *, 1);
	path->path[0] = tal(path->path, struct blinded_path_hop);

	/* A message in a bottle to ourselves: match it with
	 * the invoice: we assume the payment_hash is unique! */
	tlv = tlv_encrypted_data_tlv_new(tmpctx);
	tlv->path_id = bolt12_path_id(inv,
				      &ld->invoicesecret_base,
				      inv->invoice_payment_hash);

	path->path[0]->encrypted_recipient_data
		= encrypt_tlv_encrypted_data(path->path[0],
					     &path_key,
					     &path->first_node_id.pubkey,
					     tlv,
					     NULL,
					     &path->path[0]->blinded_node_id);

	inv->invoice_paths = tal_arr(inv, struct blinded_path *, 1);
	inv->invoice_paths[0] = tal_steal(inv->invoice_paths, path);

	/* BOLT #12:
	 *  - MUST include `invoice_paths` containing one or more paths to the node.
	 *  - MUST specify `invoice_paths` in order of most-preferred to least-preferred if it has a preference.
	 *  - MUST include `invoice_blindedpay` with exactly one `blinded_payinfo` for each `blinded_path` in `paths`, in order.
	 */
	inv->invoice_blindedpay = tal_arr(inv, struct blinded_payinfo *, 1);
	inv->invoice_blindedpay[0] = tal(inv->invoice_blindedpay,
					 struct blinded_payinfo);
	inv->invoice_blindedpay[0]->fee_base_msat = 0;
	inv->invoice_blindedpay[0]->fee_proportional_millionths = 0;
	inv->invoice_blindedpay[0]->cltv_expiry_delta = ld->config.cltv_final;
	inv->invoice_blindedpay[0]->htlc_minimum_msat = AMOUNT_MSAT(0);
	inv->invoice_blindedpay[0]->htlc_maximum_msat = AMOUNT_MSAT(21000000 * MSAT_PER_BTC);
	inv->invoice_blindedpay[0]->features = NULL;

	/* Recalc ->fields */
	tlv_update_fields(inv, tlv_invoice, &inv->fields);
}

static struct command_result *json_createinvoice(struct command *cmd,
						 const char *buffer,
						 const jsmntok_t *obj UNNEEDED,
						 const jsmntok_t *params)
{
	const char *invstring;
	struct json_escape *label;
	struct preimage *preimage;
	u64 inv_dbid;
	struct sha256 payment_hash;
	struct json_stream *response;
	struct bolt11 *b11;
	struct sha256 hash;
	const u5 *sig;
	bool have_n;
	char *fail;

	if (!param_check(cmd, buffer, params,
			 p_req("invstring", param_invstring, &invstring),
			 p_req("label", param_label, &label),
			 p_req("preimage", param_preimage, &preimage),
			 NULL))
		return command_param_failed();

	sha256(&payment_hash, preimage, sizeof(*preimage));
	b11 = bolt11_decode_nosig(cmd, invstring, cmd->ld->our_features,
				  NULL, chainparams, &hash, &sig, &have_n,
				  &fail);
	if (b11) {
		/* This adds the signature */
		char *b11enc = bolt11_encode(cmd, b11, have_n,
					     hsm_sign_b11, cmd->ld);

		if (!b11->description)
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "Missing description in invoice");

		if (!b11->expiry)
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "Missing expiry in invoice");

		if (!sha256_eq(&payment_hash, &b11->payment_hash))
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "Incorrect preimage");

		if (command_check_only(cmd))
			return command_check_done(cmd);

		if (!invoices_create(cmd->ld->wallet->invoices,
				     &inv_dbid,
				     b11->msat,
				     label,
				     b11->expiry,
				     b11enc,
				     b11->description,
				     b11->features,
				     preimage,
				     &payment_hash,
				     NULL))
			return fail_exists(cmd, label);

		notify_invoice_creation(cmd->ld, b11->msat, preimage, label);
	} else {
		struct tlv_invoice *inv;
		struct sha256 offer_id, *local_offer_id;
		char *b12enc;
		struct amount_msat msat;
		const char *desc;
		u32 expiry;
		enum offer_status status;

		inv = invoice_decode_minimal(cmd, invstring, strlen(invstring),
					     cmd->ld->our_features, chainparams,
					     &fail);
		if (!inv)
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "Unparsable invoice '%s': %s",
					    invstring, fail);

		/* BOLT #12:
		 * A writer of an invoice:
		 *...
		 *   - MUST include `invoice_paths` containing one or more paths
		 *    to the node.
		 */
		/* If they don't create a blinded path, add a simple one so we
		 * can recognize payments (bolt12 doesn't use
		 * payment_secret) */
		if (!inv->invoice_paths)
			add_stub_blindedpath(cmd, cmd->ld, inv);

		if (inv->signature)
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "invoice already signed");
		hsm_sign_b12_invoice(cmd->ld, inv);
		b12enc = invoice_encode(cmd, inv);

		if (inv->offer_issuer_id || inv->offer_paths) {
			invoice_offer_id(inv, &offer_id);
			if (wallet_offer_find(tmpctx, cmd->ld->wallet,
					      &offer_id, NULL, &status)) {
				if (!offer_status_active(status))
					return command_fail(cmd,
							    INVOICE_OFFER_INACTIVE,
							    "offer not active");
				local_offer_id = &offer_id;
			} else
				local_offer_id = NULL;
		} else
			local_offer_id = NULL;

		/* BOLT #12:
		 * A writer of an invoice:
		 *...
		 * - MUST set `invoice_amount` to the minimum amount it will
		 *   accept, in units of the minimal lightning-payable unit
		 *   (e.g. milli-satoshis for bitcoin) for `invreq_chain`.
		 */
		if (!inv->invoice_amount)
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "Missing invoice_amount in invoice");
		msat = amount_msat(*inv->invoice_amount);

		if (inv->invoice_relative_expiry)
			expiry = *inv->invoice_relative_expiry;
		else
			expiry = BOLT12_DEFAULT_REL_EXPIRY;

		if (!inv->invoice_payment_hash)
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "Missing payment_hash in invoice");
		if (!sha256_eq(&payment_hash, inv->invoice_payment_hash))
			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
					    "Incorrect preimage");

		if (command_check_only(cmd))
			return command_check_done(cmd);

		if (inv->offer_description)
			desc = tal_strndup(cmd,
					   inv->offer_description,
					   tal_bytelen(inv->offer_description));
		else
			desc = NULL;

		if (!invoices_create(cmd->ld->wallet->invoices,
				     &inv_dbid,
				     &msat,
				     label,
				     expiry,
				     b12enc,
				     desc,
				     inv->invoice_features,
				     preimage,
				     &payment_hash,
				     local_offer_id))
			return fail_exists(cmd, label);

		notify_invoice_creation(cmd->ld, &msat,	preimage, label);
	}

	response = json_stream_success(cmd);
	json_add_invoice_fields(response,
				invoices_get_details(cmd, cmd->ld->wallet->invoices,
						     inv_dbid));
	return command_success(cmd, response);
}

static const struct json_command createinvoice_command = {
	"createinvoice",
	json_createinvoice,
};

AUTODATA(json_command, &createinvoice_command);

static struct command_result *json_preapproveinvoice(struct command *cmd,
						     const char *buffer,
						     const jsmntok_t *obj UNNEEDED,
						     const jsmntok_t *params)
{
	const char *invstring;
	struct json_stream *response;
	bool approved;
	u8 *req;
	const u8 *msg;

	if (!param_check(cmd, buffer, params,
			 /* FIXME: parameter should be invstring now */
			 p_req("bolt11", param_invstring, &invstring),
		   NULL))
		return command_param_failed();

	/* Old version didn't have `bool check_only` at end */
	if (!hsm_capable(cmd->ld, WIRE_HSMD_PREAPPROVE_INVOICE_CHECK)) {
		/* We can't just check this, so "succeed".  Log message for
		 * tests though */
		if (command_check_only(cmd)) {
			log_debug(cmd->ld->log, "hsmd too old to check preapprove");
			return command_check_done(cmd);
		}
		req = towire_hsmd_preapprove_invoice(NULL, invstring);
	} else {
		req = towire_hsmd_preapprove_invoice_check(NULL, invstring,
							   command_check_only(cmd));
	}

	msg = hsm_sync_req(tmpctx, cmd->ld, take(req));

	/* These are identical, but use separate numbers for clarity */
        if (!fromwire_hsmd_preapprove_invoice_reply(msg, &approved)
	    && !fromwire_hsmd_preapprove_invoice_check_reply(msg, &approved)) {
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "HSM gave bad preapprove_invoice_reply %s", tal_hex(msg, msg));
	}

	if (!approved)
		return command_fail(cmd, PAY_INVOICE_PREAPPROVAL_DECLINED, "invoice was declined");

	if (command_check_only(cmd))
		return command_check_done(cmd);

	response = json_stream_success(cmd);
	return command_success(cmd, response);
}

static const struct json_command preapproveinvoice_command = {
	"preapproveinvoice",
	json_preapproveinvoice,
};
AUTODATA(json_command, &preapproveinvoice_command);

static struct command_result *json_preapprovekeysend(struct command *cmd,
						     const char *buffer,
						     const jsmntok_t *obj UNNEEDED,
						     const jsmntok_t *params)
{
	struct node_id *destination;
	struct sha256 *payment_hash;
	struct amount_msat *amount;
	struct json_stream *response;
	bool approved;
	const u8 *msg;
	u8 *req;

	if (!param_check(cmd, buffer, params,
			 p_req("destination", param_node_id, &destination),
			 p_req("payment_hash", param_sha256, &payment_hash),
			 p_req("amount_msat", param_msat, &amount),
			 NULL))
		return command_param_failed();

	if (!hsm_capable(cmd->ld, WIRE_HSMD_PREAPPROVE_KEYSEND_CHECK)) {
		/* We can't just check this, so "succeed".  Log message for
		 * tests though */
		if (command_check_only(cmd)) {
			log_debug(cmd->ld->log, "hsmd too old to check preapprove");
			return command_check_done(cmd);
		}
		req = towire_hsmd_preapprove_keysend(NULL, destination, payment_hash, *amount);
	} else {
		req = towire_hsmd_preapprove_keysend_check(NULL, destination, payment_hash,
							   *amount, command_check_only(cmd));
	}

	msg = hsm_sync_req(tmpctx, cmd->ld, take(req));

	/* These are identical, but use separate numbers for clarity */
        if (!fromwire_hsmd_preapprove_keysend_reply(msg, &approved)
	    && !fromwire_hsmd_preapprove_keysend_check_reply(msg, &approved)) {
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "HSM gave bad preapprove_keysend_reply %s", tal_hex(msg, msg));
	}

	if (!approved)
		return command_fail(cmd, PAY_KEYSEND_PREAPPROVAL_DECLINED, "keysend was declined");

	if (command_check_only(cmd))
		return command_check_done(cmd);

	response = json_stream_success(cmd);
	return command_success(cmd, response);
}

static const struct json_command preapprovekeysend_command = {
	"preapprovekeysend",
	json_preapprovekeysend,
};
AUTODATA(json_command, &preapprovekeysend_command);

static struct command_result *json_signinvoice(struct command *cmd,
						 const char *buffer,
						 const jsmntok_t *obj UNNEEDED,
						 const jsmntok_t *params)
{
	const char *invstring;
	struct json_stream *response;
	struct bolt11 *b11;
	struct sha256 hash;
	const u5 *sig;
	bool have_n;
	char *fail;

	if (!param_check(cmd, buffer, params,
			 p_req("invstring", param_invstring, &invstring),
			 NULL))
		return command_param_failed();

	b11 = bolt11_decode_nosig(cmd, invstring, cmd->ld->our_features,
				  NULL, chainparams, &hash, &sig, &have_n,
				  &fail);

	if (!b11)
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "Unparsable invoice '%s': %s",
				    invstring, fail);

	/* This adds the signature */
	char *b11enc = bolt11_encode(cmd, b11, have_n,
				     hsm_sign_b11, cmd->ld);

        /* BOLT #11:
         * A writer:
         *...
         *    - MUST include either exactly one `d` or exactly one `h` field.
         */
	if (!b11->description && !b11->description_hash)
		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
				    "Missing description in invoice");

	if (command_check_only(cmd))
		return command_check_done(cmd);

	response = json_stream_success(cmd);
	json_add_invstring(response, b11enc);
	return command_success(cmd, response);
}

static const struct json_command signinvoice_command = {
	"signinvoice",
	json_signinvoice,
};

AUTODATA(json_command, &signinvoice_command);
