mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 06:41:44 +01:00
hsmd: add hsmd_preapprove_keysend and check_preapprovekeysend pay modifier
Changelog-added: hsmd: A new message `hsmd_preapprove_keysend` is added. Changelog-added: JSON-RPC: A new command `preapprovekeysend` is added.
This commit is contained in:
parent
f29343d740
commit
a4dc714cdc
13 changed files with 238 additions and 1 deletions
|
@ -47,6 +47,7 @@ enum jsonrpc_errcode {
|
||||||
PAY_STATUS_UNEXPECTED = 211,
|
PAY_STATUS_UNEXPECTED = 211,
|
||||||
PAY_INVOICE_REQUEST_INVALID = 212,
|
PAY_INVOICE_REQUEST_INVALID = 212,
|
||||||
PAY_INVOICE_PREAPPROVAL_DECLINED = 213,
|
PAY_INVOICE_PREAPPROVAL_DECLINED = 213,
|
||||||
|
PAY_KEYSEND_PREAPPROVAL_DECLINED = 214,
|
||||||
|
|
||||||
/* `fundchannel` or `withdraw` errors */
|
/* `fundchannel` or `withdraw` errors */
|
||||||
FUND_MAX_EXCEEDED = 300,
|
FUND_MAX_EXCEEDED = 300,
|
||||||
|
|
|
@ -76,6 +76,7 @@ MANPAGES := doc/lightning-cli.1 \
|
||||||
doc/lightning-parsefeerate.7 \
|
doc/lightning-parsefeerate.7 \
|
||||||
doc/lightning-plugin.7 \
|
doc/lightning-plugin.7 \
|
||||||
doc/lightning-preapproveinvoice.7 \
|
doc/lightning-preapproveinvoice.7 \
|
||||||
|
doc/lightning-preapprovekeysend.7 \
|
||||||
doc/lightning-recoverchannel.7 \
|
doc/lightning-recoverchannel.7 \
|
||||||
doc/lightning-reserveinputs.7 \
|
doc/lightning-reserveinputs.7 \
|
||||||
doc/lightning-sendinvoice.7 \
|
doc/lightning-sendinvoice.7 \
|
||||||
|
|
|
@ -106,6 +106,7 @@ Core Lightning Documentation
|
||||||
lightning-ping <lightning-ping.7.md>
|
lightning-ping <lightning-ping.7.md>
|
||||||
lightning-plugin <lightning-plugin.7.md>
|
lightning-plugin <lightning-plugin.7.md>
|
||||||
lightning-preapproveinvoice <lightning-preapproveinvoice.7.md>
|
lightning-preapproveinvoice <lightning-preapproveinvoice.7.md>
|
||||||
|
lightning-preapprovekeysend <lightning-preapprovekeysend.7.md>
|
||||||
lightning-recoverchannel <lightning-recoverchannel.7.md>
|
lightning-recoverchannel <lightning-recoverchannel.7.md>
|
||||||
lightning-reserveinputs <lightning-reserveinputs.7.md>
|
lightning-reserveinputs <lightning-reserveinputs.7.md>
|
||||||
lightning-sendcustommsg <lightning-sendcustommsg.7.md>
|
lightning-sendcustommsg <lightning-sendcustommsg.7.md>
|
||||||
|
|
61
doc/lightning-preapprovekeysend.7.md
Normal file
61
doc/lightning-preapprovekeysend.7.md
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
lightning-preapprovekeysend -- Ask the HSM to preapprove a keysend payment (low-level)
|
||||||
|
==================================================================
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
|
||||||
|
**preapprovekeysend** *destination* *payment\_hash* *amount\_msat*
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The **preapprovekeysend** RPC command submits the *destination*, *payment\_hash*,
|
||||||
|
and *amount\_msat* parameters to the HSM to check that they are approved as a
|
||||||
|
keysend payment.
|
||||||
|
|
||||||
|
*destination* is a 33 byte, hex-encoded, node ID of the node that the payment should go to.
|
||||||
|
|
||||||
|
*payment\_hash* is the unique identifier of a payment.
|
||||||
|
|
||||||
|
*amount\_msat* is the amount to send in millisatoshi precision; it can
|
||||||
|
be a whole number, or a whole number with suffix `msat` or `sat`, or a
|
||||||
|
three decimal point number with suffix `sat`, or an 1 to 11 decimal
|
||||||
|
point number suffixed by `btc`.
|
||||||
|
|
||||||
|
Generally the **preapprovekeysend** request does not need to be made
|
||||||
|
explicitly, it is automatically generated as part of a **keysend** request.
|
||||||
|
|
||||||
|
By default, the HSM will approve all **preapprovekeysend** requests.
|
||||||
|
|
||||||
|
If a remote signer is being used it might decline an **preapprovekeysend**
|
||||||
|
request because it would exceed velocity controls, is not covered by
|
||||||
|
allowlist controls, was declined manually, or other reasons.
|
||||||
|
|
||||||
|
If a remote signer declines a **preapprovekeysend** request a subsequent
|
||||||
|
attempt to pay the keysend anyway will fail; the signer will refuse to sign
|
||||||
|
the commitment.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
------------
|
||||||
|
|
||||||
|
[comment]: # (GENERATE-FROM-SCHEMA-START)
|
||||||
|
On success, an empty object is returned.
|
||||||
|
|
||||||
|
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
------
|
||||||
|
|
||||||
|
Ken Sedgwick <<ken@bonsai.com>> is mainly responsible.
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
--------
|
||||||
|
|
||||||
|
lightning-keysend(7)
|
||||||
|
|
||||||
|
RESOURCES
|
||||||
|
---------
|
||||||
|
|
||||||
|
Main web site: <https://github.com/ElementsProject/lightning>
|
||||||
|
|
||||||
|
[comment]: # ( SHA256STAMP:735dd61146b04745f1e884037ead662a386fec2c41e2de1a8698d6bb03f63540)
|
|
@ -7,7 +7,8 @@
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"bolt11": {
|
"bolt11": {
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"added": "v23.02"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
27
doc/schemas/preapprovekeysend.request.json
Normal file
27
doc/schemas/preapprovekeysend.request.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"destination",
|
||||||
|
"payment_hash",
|
||||||
|
"amount_msat"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"destination": {
|
||||||
|
"type": "pubkey",
|
||||||
|
"added": "v23.02"
|
||||||
|
},
|
||||||
|
"payment_hash": {
|
||||||
|
"type": "hex",
|
||||||
|
"added": "v23.02",
|
||||||
|
"description": "the hash of the *payment_preimage* which will prove payment",
|
||||||
|
"maxLength": 64,
|
||||||
|
"minLength": 64
|
||||||
|
},
|
||||||
|
"amount_msat": {
|
||||||
|
"type": "msat",
|
||||||
|
"added": "v23.02"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
doc/schemas/preapprovekeysend.schema.json
Normal file
6
doc/schemas/preapprovekeysend.schema.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {}
|
||||||
|
}
|
|
@ -669,6 +669,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
|
||||||
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER:
|
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER:
|
||||||
case WIRE_HSMD_SIGN_BOLT12:
|
case WIRE_HSMD_SIGN_BOLT12:
|
||||||
case WIRE_HSMD_PREAPPROVE_INVOICE:
|
case WIRE_HSMD_PREAPPROVE_INVOICE:
|
||||||
|
case WIRE_HSMD_PREAPPROVE_KEYSEND:
|
||||||
case WIRE_HSMD_ECDH_REQ:
|
case WIRE_HSMD_ECDH_REQ:
|
||||||
case WIRE_HSMD_CHECK_FUTURE_SECRET:
|
case WIRE_HSMD_CHECK_FUTURE_SECRET:
|
||||||
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
|
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
|
||||||
|
@ -710,6 +711,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
|
||||||
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
|
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
|
||||||
case WIRE_HSMD_SIGN_BOLT12_REPLY:
|
case WIRE_HSMD_SIGN_BOLT12_REPLY:
|
||||||
case WIRE_HSMD_PREAPPROVE_INVOICE_REPLY:
|
case WIRE_HSMD_PREAPPROVE_INVOICE_REPLY:
|
||||||
|
case WIRE_HSMD_PREAPPROVE_KEYSEND_REPLY:
|
||||||
return bad_req_fmt(conn, c, c->msg_in,
|
return bad_req_fmt(conn, c, c->msg_in,
|
||||||
"Received an incoming message of type %s, "
|
"Received an incoming message of type %s, "
|
||||||
"which is not a request",
|
"which is not a request",
|
||||||
|
|
|
@ -121,6 +121,16 @@ msgdata,hsmd_preapprove_invoice,invstring,wirestring,
|
||||||
msgtype,hsmd_preapprove_invoice_reply,138
|
msgtype,hsmd_preapprove_invoice_reply,138
|
||||||
msgdata,hsmd_preapprove_invoice_reply,approved,bool,
|
msgdata,hsmd_preapprove_invoice_reply,approved,bool,
|
||||||
|
|
||||||
|
# Preapprove a keysend payment
|
||||||
|
msgtype,hsmd_preapprove_keysend,39
|
||||||
|
msgdata,hsmd_preapprove_keysend,destination,node_id,
|
||||||
|
msgdata,hsmd_preapprove_keysend,payment_hash,sha256,
|
||||||
|
msgdata,hsmd_preapprove_keysend,amount_msat,amount_msat,
|
||||||
|
|
||||||
|
# Result is true if approved, declined if false
|
||||||
|
msgtype,hsmd_preapprove_keysend_reply,139
|
||||||
|
msgdata,hsmd_preapprove_keysend_reply,approved,bool,
|
||||||
|
|
||||||
# Give me ECDH(node-id-secret,point)
|
# Give me ECDH(node-id-secret,point)
|
||||||
msgtype,hsmd_ecdh_req,1
|
msgtype,hsmd_ecdh_req,1
|
||||||
msgdata,hsmd_ecdh_req,point,pubkey,
|
msgdata,hsmd_ecdh_req,point,pubkey,
|
||||||
|
|
|
|
@ -120,6 +120,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
|
||||||
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
|
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
|
||||||
case WIRE_HSMD_SIGN_BOLT12:
|
case WIRE_HSMD_SIGN_BOLT12:
|
||||||
case WIRE_HSMD_PREAPPROVE_INVOICE:
|
case WIRE_HSMD_PREAPPROVE_INVOICE:
|
||||||
|
case WIRE_HSMD_PREAPPROVE_KEYSEND:
|
||||||
case WIRE_HSMD_DERIVE_SECRET:
|
case WIRE_HSMD_DERIVE_SECRET:
|
||||||
return (client->capabilities & HSM_CAP_MASTER) != 0;
|
return (client->capabilities & HSM_CAP_MASTER) != 0;
|
||||||
|
|
||||||
|
@ -151,6 +152,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
|
||||||
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
|
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
|
||||||
case WIRE_HSMD_SIGN_BOLT12_REPLY:
|
case WIRE_HSMD_SIGN_BOLT12_REPLY:
|
||||||
case WIRE_HSMD_PREAPPROVE_INVOICE_REPLY:
|
case WIRE_HSMD_PREAPPROVE_INVOICE_REPLY:
|
||||||
|
case WIRE_HSMD_PREAPPROVE_KEYSEND_REPLY:
|
||||||
case WIRE_HSMD_DERIVE_SECRET_REPLY:
|
case WIRE_HSMD_DERIVE_SECRET_REPLY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -677,6 +679,24 @@ static u8 *handle_preapprove_invoice(struct hsmd_client *c, const u8 *msg_in)
|
||||||
return towire_hsmd_preapprove_invoice_reply(NULL, approved);
|
return towire_hsmd_preapprove_invoice_reply(NULL, approved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*~ lightningd asks us to approve a keysend payment. This stub implementation
|
||||||
|
* is overriden by fully validating signers that need to track keysend
|
||||||
|
* payments. */
|
||||||
|
static u8 *handle_preapprove_keysend(struct hsmd_client *c, const u8 *msg_in)
|
||||||
|
{
|
||||||
|
struct node_id destination;
|
||||||
|
struct sha256 payment_hash;
|
||||||
|
struct amount_msat amount_msat;
|
||||||
|
bool approved;
|
||||||
|
if (!fromwire_hsmd_preapprove_keysend(msg_in, &destination, &payment_hash, &amount_msat))
|
||||||
|
return hsmd_status_malformed_request(c, msg_in);
|
||||||
|
|
||||||
|
/* This stub always approves */
|
||||||
|
approved = true;
|
||||||
|
|
||||||
|
return towire_hsmd_preapprove_keysend_reply(NULL, approved);
|
||||||
|
}
|
||||||
|
|
||||||
/*~ Lightning invoices, defined by BOLT 11, are signed. This has been
|
/*~ Lightning invoices, defined by BOLT 11, are signed. This has been
|
||||||
* surprisingly controversial; it means a node needs to be online to create
|
* surprisingly controversial; it means a node needs to be online to create
|
||||||
* invoices. However, it seems clear to me that in a world without
|
* invoices. However, it seems clear to me that in a world without
|
||||||
|
@ -1592,6 +1612,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
|
||||||
return handle_sign_bolt12(client, msg);
|
return handle_sign_bolt12(client, msg);
|
||||||
case WIRE_HSMD_PREAPPROVE_INVOICE:
|
case WIRE_HSMD_PREAPPROVE_INVOICE:
|
||||||
return handle_preapprove_invoice(client, msg);
|
return handle_preapprove_invoice(client, msg);
|
||||||
|
case WIRE_HSMD_PREAPPROVE_KEYSEND:
|
||||||
|
return handle_preapprove_keysend(client, msg);
|
||||||
case WIRE_HSMD_SIGN_MESSAGE:
|
case WIRE_HSMD_SIGN_MESSAGE:
|
||||||
return handle_sign_message(client, msg);
|
return handle_sign_message(client, msg);
|
||||||
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS:
|
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS:
|
||||||
|
@ -1656,6 +1678,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
|
||||||
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
|
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
|
||||||
case WIRE_HSMD_SIGN_BOLT12_REPLY:
|
case WIRE_HSMD_SIGN_BOLT12_REPLY:
|
||||||
case WIRE_HSMD_PREAPPROVE_INVOICE_REPLY:
|
case WIRE_HSMD_PREAPPROVE_INVOICE_REPLY:
|
||||||
|
case WIRE_HSMD_PREAPPROVE_KEYSEND_REPLY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return hsmd_status_bad_request(client, msg, "Unknown request");
|
return hsmd_status_bad_request(client, msg, "Unknown request");
|
||||||
|
|
|
@ -1853,3 +1853,47 @@ static const struct json_command preapproveinvoice_command = {
|
||||||
"Ask the HSM to preapprove an invoice."
|
"Ask the HSM to preapprove an invoice."
|
||||||
};
|
};
|
||||||
AUTODATA(json_command, &preapproveinvoice_command);
|
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;
|
||||||
|
|
||||||
|
if (!param(cmd, buffer, params,
|
||||||
|
p_req("destination", param_node_id, &destination),
|
||||||
|
p_req("payment_hash", param_sha256, &payment_hash),
|
||||||
|
p_req("amount_msat|msatoshi", param_msat, &amount),
|
||||||
|
NULL))
|
||||||
|
return command_param_failed();
|
||||||
|
|
||||||
|
u8 *msg = towire_hsmd_preapprove_keysend(NULL, destination, payment_hash, *amount);
|
||||||
|
|
||||||
|
if (!wire_sync_write(cmd->ld->hsm_fd, take(msg)))
|
||||||
|
fatal("Could not write to HSM: %s", strerror(errno));
|
||||||
|
|
||||||
|
msg = wire_sync_read(tmpctx, cmd->ld->hsm_fd);
|
||||||
|
if (!fromwire_hsmd_preapprove_keysend_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");
|
||||||
|
|
||||||
|
response = json_stream_success(cmd);
|
||||||
|
return command_success(cmd, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct json_command preapprovekeysend_command = {
|
||||||
|
"preapprovekeysend",
|
||||||
|
"payment",
|
||||||
|
json_preapprovekeysend,
|
||||||
|
"Ask the HSM to preapprove a keysend payment."
|
||||||
|
};
|
||||||
|
AUTODATA(json_command, &preapprovekeysend_command);
|
||||||
|
|
|
@ -258,6 +258,9 @@ bool fromwire_hsmd_sign_bolt12_reply(const void *p UNNEEDED, struct bip340sig *s
|
||||||
/* Generated stub for fromwire_hsmd_preapprove_invoice_reply */
|
/* Generated stub for fromwire_hsmd_preapprove_invoice_reply */
|
||||||
bool fromwire_hsmd_preapprove_invoice_reply(const void *p UNNEEDED, bool *approved UNNEEDED)
|
bool fromwire_hsmd_preapprove_invoice_reply(const void *p UNNEEDED, bool *approved UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_hsmd_preapprove_invoice_reply called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_hsmd_preapprove_invoice_reply called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_hsmd_preapprove_keysend_reply */
|
||||||
|
bool fromwire_hsmd_preapprove_keysend_reply(const void *p UNNEEDED, bool *approved UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_hsmd_preapprove_keysend_reply called!\n"); abort(); }
|
||||||
/* Generated stub for fromwire_hsmd_sign_commitment_tx_reply */
|
/* Generated stub for fromwire_hsmd_sign_commitment_tx_reply */
|
||||||
bool fromwire_hsmd_sign_commitment_tx_reply(const void *p UNNEEDED, struct bitcoin_signature *sig UNNEEDED)
|
bool fromwire_hsmd_sign_commitment_tx_reply(const void *p UNNEEDED, struct bitcoin_signature *sig UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_hsmd_sign_commitment_tx_reply called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_hsmd_sign_commitment_tx_reply called!\n"); abort(); }
|
||||||
|
@ -783,6 +786,9 @@ u8 *towire_hsmd_sign_bolt12(const tal_t *ctx UNNEEDED, const wirestring *message
|
||||||
/* Generated stub for towire_hsmd_preapprove_invoice */
|
/* Generated stub for towire_hsmd_preapprove_invoice */
|
||||||
u8 *towire_hsmd_preapprove_invoice(const tal_t *ctx UNNEEDED, const wirestring *invstring UNNEEDED)
|
u8 *towire_hsmd_preapprove_invoice(const tal_t *ctx UNNEEDED, const wirestring *invstring UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_hsmd_preapprove_invoice called!\n"); abort(); }
|
{ fprintf(stderr, "towire_hsmd_preapprove_invoice called!\n"); abort(); }
|
||||||
|
/* Generated stub for towire_hsmd_preapprove_keysend */
|
||||||
|
u8 *towire_hsmd_preapprove_keysend(const tal_t *ctx UNNEEDED, const struct node_id *destination UNNEEDED, const struct sha256 *payment_hash UNNEEDED, struct amount_msat amount UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_hsmd_preapprove_keysend called!\n"); abort(); }
|
||||||
/* Generated stub for towire_hsmd_sign_commitment_tx */
|
/* Generated stub for towire_hsmd_sign_commitment_tx */
|
||||||
u8 *towire_hsmd_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct node_id *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, u64 commit_num UNNEEDED)
|
u8 *towire_hsmd_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct node_id *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, u64 commit_num UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_hsmd_sign_commitment_tx called!\n"); abort(); }
|
{ fprintf(stderr, "towire_hsmd_sign_commitment_tx called!\n"); abort(); }
|
||||||
|
|
|
@ -107,6 +107,59 @@ REGISTER_PAYMENT_MODIFIER(keysend, struct keysend_data *, keysend_init,
|
||||||
* End of keysend modifier
|
* End of keysend modifier
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* check_preapprovekeysend
|
||||||
|
*
|
||||||
|
* @desc submit the keysend to the HSM for approval, fail the payment if not approved.
|
||||||
|
*
|
||||||
|
* This paymod checks the keysend for approval with the HSM, which might:
|
||||||
|
* - check with the user for specific approval
|
||||||
|
* - enforce velocity controls
|
||||||
|
* - automatically approve the keysend (default)
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct command_result *
|
||||||
|
check_preapprovekeysend_allow(struct command *cmd,
|
||||||
|
const char *buf,
|
||||||
|
const jsmntok_t *result,
|
||||||
|
struct payment *p)
|
||||||
|
{
|
||||||
|
/* On success, an empty object is returned. */
|
||||||
|
payment_continue(p);
|
||||||
|
return command_still_pending(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct command_result *preapprovekeysend_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_preapprovekeysend_start(void *d UNUSED, struct payment *p)
|
||||||
|
{
|
||||||
|
/* Ask the HSM if the keysend is OK to pay */
|
||||||
|
struct out_req *req;
|
||||||
|
req = jsonrpc_request_start(p->plugin, NULL, "preapprovekeysend",
|
||||||
|
&check_preapprovekeysend_allow,
|
||||||
|
&preapprovekeysend_rpc_failure, p);
|
||||||
|
json_add_node_id(req->js, "destination", p->destination);
|
||||||
|
json_add_sha256(req->js, "payment_hash", p->payment_hash);
|
||||||
|
json_add_amount_msat_only(req->js, "amount_msat", p->amount);
|
||||||
|
(void) send_outreq(p->plugin, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_PAYMENT_MODIFIER(check_preapprovekeysend, void *, NULL,
|
||||||
|
check_preapprovekeysend_start);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* End of check_preapprovekeysend modifier
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
static const char *init(struct plugin *p, const char *buf UNUSED,
|
static const char *init(struct plugin *p, const char *buf UNUSED,
|
||||||
const jsmntok_t *config UNUSED)
|
const jsmntok_t *config UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -123,6 +176,7 @@ static const char *init(struct plugin *p, const char *buf UNUSED,
|
||||||
|
|
||||||
struct payment_modifier *pay_mods[] = {
|
struct payment_modifier *pay_mods[] = {
|
||||||
&keysend_pay_mod,
|
&keysend_pay_mod,
|
||||||
|
&check_preapprovekeysend_pay_mod,
|
||||||
&local_channel_hints_pay_mod,
|
&local_channel_hints_pay_mod,
|
||||||
&directpay_pay_mod,
|
&directpay_pay_mod,
|
||||||
&shadowroute_pay_mod,
|
&shadowroute_pay_mod,
|
||||||
|
|
Loading…
Add table
Reference in a new issue