diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 3794aa684..d9b2bccc7 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -3809,87 +3809,6 @@ static void payee_incoming_limit_step_cb(void *d UNUSED, struct payment *p) REGISTER_PAYMENT_MODIFIER(payee_incoming_limit, void *, NULL, payee_incoming_limit_step_cb); -/***************************************************************************** - * check_preapproveinvoice - * - * @desc submit the invoice to the HSM for approval, fail the payment if not approved. - * - * This paymod checks the invoice for approval with the HSM, which might: - * - check with the user for specific approval - * - enforce velocity controls - * - automatically approve the invoice (default) - */ - -static struct command_result * -check_preapproveinvoice_allow(struct command *cmd, - const char *buf, - const jsmntok_t *result, - struct payment *p) -{ - /* On success, an empty object is returned. */ -// struct preapproveinvoice_data *d - - struct preapproveinvoice_data *d = payment_mod_check_preapproveinvoice_get_data(payment_root(p)); - d->approved = true; - paymod_log(p, LOG_DBG, "Result from preapproveinvoice: allow"); - payment_continue(p); - return command_still_pending(cmd); -} - -static struct command_result *preapproveinvoice_rpc_failure(struct command *cmd, - const char *buffer, - const jsmntok_t *toks, - struct payment *p) -{ - payment_abort(p, - "Failing payment due to a failed RPC call: %.*s", - toks->end - toks->start, buffer + toks->start); - return command_still_pending(cmd); -} - -static void check_preapproveinvoice_start(struct preapproveinvoice_data *d UNUSED, struct payment *p) -{ - struct payment *root = payment_root(p); - - struct preapproveinvoice_data *data = - payment_mod_check_preapproveinvoice_get_data(root); - /* If the root payment was used to send the - * `preapproveinvoice` message to the signer, we don't need to - * do that again. */ - if (data->approved) { - return payment_continue(p); - } - - paymod_log(p, LOG_DBG, "Calling preapproveinvoice on signer for payment=%"PRIu64, root->id); - /* Ask the HSM if the invoice is OK to pay */ - struct out_req *req; - req = jsonrpc_request_start(p->plugin, NULL, "preapproveinvoice", - &check_preapproveinvoice_allow, - &preapproveinvoice_rpc_failure, p); - /* FIXME: rename parameter to invstring */ - json_add_string(req->js, "bolt11", p->invstring); - (void) send_outreq(p->plugin, req); -} - -static struct preapproveinvoice_data* preapproveinvoice_data_init(struct payment *p) -{ - struct preapproveinvoice_data *d; - /* Only keep state on the root. We will use the root's flag - * for all payments. */ - if (p == payment_root(p)) { - d = tal(p, struct preapproveinvoice_data); - d->approved = false; - return d; - } else { - return NULL; - } -} - -REGISTER_PAYMENT_MODIFIER(check_preapproveinvoice, - struct preapproveinvoice_data *, - preapproveinvoice_data_init, - check_preapproveinvoice_start); - static struct route_exclusions_data * route_exclusions_data_init(struct payment *p) { diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index f5247ae7b..40b0b8422 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -435,10 +435,6 @@ struct route_exclusions_data { struct route_exclusion **exclusions; }; -struct preapproveinvoice_data { - bool approved; -}; - /* List of globally available payment modifiers. */ REGISTER_PAYMENT_MODIFIER_HEADER(retry, struct retry_mod_data); REGISTER_PAYMENT_MODIFIER_HEADER(routehints, struct routehints_data); @@ -460,7 +456,6 @@ REGISTER_PAYMENT_MODIFIER_HEADER(local_channel_hints, void); * each of those channels can bear. */ REGISTER_PAYMENT_MODIFIER_HEADER(payee_incoming_limit, void); REGISTER_PAYMENT_MODIFIER_HEADER(route_exclusions, struct route_exclusions_data); -REGISTER_PAYMENT_MODIFIER_HEADER(check_preapproveinvoice, struct preapproveinvoice_data); struct payment *payment_new(tal_t *ctx, struct command *cmd, diff --git a/plugins/pay.c b/plugins/pay.c index e44897105..4dc12c5ef 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -970,7 +970,6 @@ payment_listsendpays_previous(struct command *cmd, const char *buf, } struct payment_modifier *paymod_mods[] = { - &check_preapproveinvoice_pay_mod, /* NOTE: The order in which these four paymods are executed is * significant! * local_channel_hints *must* execute first before route_exclusions @@ -1010,6 +1009,32 @@ static void destroy_payment(struct payment *p) list_del(&p->list); } +static struct command_result * +preapproveinvoice_succeed(struct command *cmd, + const char *buf, + const jsmntok_t *result, + struct payment *p) +{ + struct out_req *req; + + /* Now we can conclude `check` command */ + if (command_check_only(cmd)) { + return command_check_done(cmd); + } + + list_add_tail(&payments, &p->list); + tal_add_destructor(p, destroy_payment); + /* We're keeping this around now */ + tal_steal(cmd->plugin, p); + + req = jsonrpc_request_start(cmd->plugin, cmd, "listsendpays", + payment_listsendpays_previous, + payment_listsendpays_previous, p); + + json_add_sha256(req->js, "payment_hash", p->payment_hash); + return send_outreq(cmd->plugin, req); +} + static struct command_result *json_pay(struct command *cmd, const char *buf, const jsmntok_t *params) @@ -1036,7 +1061,7 @@ static struct command_result *json_pay(struct command *cmd, /* If any of the modifiers need to add params to the JSON-RPC call we * would add them to the `param()` call below, and have them be * initialized directly that way. */ - if (!param(cmd, buf, params, + if (!param_check(cmd, buf, params, /* FIXME: parameter should be invstring now */ p_req("bolt11", param_invstring, &b11str), p_opt("amount_msat", param_msat, &msat), @@ -1279,16 +1304,19 @@ static struct command_result *json_pay(struct command *cmd, tal_free(dev_use_shadow); p->label = tal_steal(p, label); - list_add_tail(&payments, &p->list); - tal_add_destructor(p, destroy_payment); - /* We're keeping this around now */ - tal_steal(cmd->plugin, p); - req = jsonrpc_request_start(cmd->plugin, cmd, "listsendpays", - payment_listsendpays_previous, - payment_listsendpays_previous, p); - - json_add_sha256(req->js, "payment_hash", p->payment_hash); + /* Now preapprove, then start payment. */ + if (command_check_only(cmd)) { + req = jsonrpc_request_start(p->plugin, cmd, "check", + &preapproveinvoice_succeed, + &forward_error, p); + json_add_string(req->js, "command_to_check", "preapproveinvoice"); + } else { + req = jsonrpc_request_start(p->plugin, cmd, "preapproveinvoice", + &preapproveinvoice_succeed, + &forward_error, p); + } + json_add_string(req->js, "bolt11", p->invstring); return send_outreq(cmd->plugin, req); }