mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 07:04:22 +01:00
lightningd: Add signinvoice to sign a BOLT11 invoice.
Though there's already a `createinvoice` command, there are usecases where a
user may want to sign an invoice that they don't yet have the preimage to. For
example, they may have an htlc_accepted plugin that pays to obtain the preimage
from someone else and returns a `{ "result": "resolve", ... }`.
This RPC command addresses this usecase without overly complicating the
semantics of the existing `createinvoice` command.
Changelog-Added: JSON-RPC: `signinvoice` new command to sign BOLT11
invoices.
This commit is contained in:
@@ -84,6 +84,7 @@ MANPAGES := doc/lightning-cli.1 \
|
|||||||
doc/lightning-sendpay.7 \
|
doc/lightning-sendpay.7 \
|
||||||
doc/lightning-setchannel.7 \
|
doc/lightning-setchannel.7 \
|
||||||
doc/lightning-sendcustommsg.7 \
|
doc/lightning-sendcustommsg.7 \
|
||||||
|
doc/lightning-signinvoice.7 \
|
||||||
doc/lightning-signmessage.7 \
|
doc/lightning-signmessage.7 \
|
||||||
doc/lightning-staticbackup.7 \
|
doc/lightning-staticbackup.7 \
|
||||||
doc/lightning-txprepare.7 \
|
doc/lightning-txprepare.7 \
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ Core Lightning Documentation
|
|||||||
lightning-sendpay <lightning-sendpay.7.md>
|
lightning-sendpay <lightning-sendpay.7.md>
|
||||||
lightning-sendpsbt <lightning-sendpsbt.7.md>
|
lightning-sendpsbt <lightning-sendpsbt.7.md>
|
||||||
lightning-setchannel <lightning-setchannel.7.md>
|
lightning-setchannel <lightning-setchannel.7.md>
|
||||||
|
lightning-signinvoice <lightning-signinvoice.7.md>
|
||||||
lightning-signmessage <lightning-signmessage.7.md>
|
lightning-signmessage <lightning-signmessage.7.md>
|
||||||
lightning-signpsbt <lightning-signpsbt.7.md>
|
lightning-signpsbt <lightning-signpsbt.7.md>
|
||||||
lightning-sql <lightning-sql.7.md>
|
lightning-sql <lightning-sql.7.md>
|
||||||
|
|||||||
51
doc/lightning-signinvoice.7.md
Normal file
51
doc/lightning-signinvoice.7.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
lightning-signinvoice -- Low-level invoice signing
|
||||||
|
=====================================================
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
|
||||||
|
**signinvoice** *invstring*
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The **signinvoice** RPC command signs an invoice. Unlike
|
||||||
|
**createinvoice** it does not save the invoice into the database and
|
||||||
|
thus does not require the preimage.
|
||||||
|
|
||||||
|
The *invstring* parameter is of bolt11 form, but the final signature
|
||||||
|
is ignored. Minimal sanity checks are done.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
------------
|
||||||
|
|
||||||
|
[comment]: # (GENERATE-FROM-SCHEMA-START)
|
||||||
|
On success, an object is returned, containing:
|
||||||
|
|
||||||
|
- **bolt11** (string): the bolt11 string
|
||||||
|
|
||||||
|
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||||
|
|
||||||
|
On failure, an error is returned.
|
||||||
|
|
||||||
|
The following error codes may occur:
|
||||||
|
- -1: Catchall nonspecific error.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
------
|
||||||
|
|
||||||
|
Carl Dong <<contact@carldong.me>> is mainly responsible.
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
--------
|
||||||
|
|
||||||
|
lightning-createinvoice(7), lightning-invoice(7), lightning-listinvoices(7),
|
||||||
|
lightning-delinvoice(7), lightning-getroute(7), lightning-sendpay(7),
|
||||||
|
lightning-offer(7).
|
||||||
|
|
||||||
|
RESOURCES
|
||||||
|
---------
|
||||||
|
|
||||||
|
Main web site: <https://github.com/ElementsProject/lightning>
|
||||||
|
|
||||||
|
[comment]: # ( SHA256STAMP:9348784bd3daaed1cd35b29b2e5c91ea17bc8e11bf5bb6e1de9a098241cb74d6)
|
||||||
15
doc/schemas/signinvoice.request.json
Normal file
15
doc/schemas/signinvoice.request.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"added": "v23.02",
|
||||||
|
"required": [
|
||||||
|
"invstring"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"invstring": {
|
||||||
|
"type": "string",
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
doc/schemas/signinvoice.schema.json
Normal file
14
doc/schemas/signinvoice.schema.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"bolt11"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"bolt11": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "the bolt11 string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1897,3 +1897,57 @@ static const struct json_command preapprovekeysend_command = {
|
|||||||
"Ask the HSM to preapprove a keysend payment."
|
"Ask the HSM to preapprove a keysend payment."
|
||||||
};
|
};
|
||||||
AUTODATA(json_command, &preapprovekeysend_command);
|
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(cmd, buffer, params,
|
||||||
|
p_req("invstring", param_string, &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");
|
||||||
|
|
||||||
|
response = json_stream_success(cmd);
|
||||||
|
json_add_invstring(response, b11enc);
|
||||||
|
return command_success(cmd, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct json_command signinvoice_command = {
|
||||||
|
"signinvoice",
|
||||||
|
"payment",
|
||||||
|
json_signinvoice,
|
||||||
|
"Lowlevel command to sign invoice {invstring}."
|
||||||
|
};
|
||||||
|
|
||||||
|
AUTODATA(json_command, &signinvoice_command);
|
||||||
|
|||||||
@@ -533,6 +533,19 @@ def test_waitanyinvoice(node_factory, executor):
|
|||||||
l2.rpc.waitanyinvoice('non-number')
|
l2.rpc.waitanyinvoice('non-number')
|
||||||
|
|
||||||
|
|
||||||
|
def test_signinvoice(node_factory, executor):
|
||||||
|
# Setup
|
||||||
|
l1, l2 = node_factory.line_graph(2)
|
||||||
|
|
||||||
|
# Create an invoice for l1
|
||||||
|
inv1 = l1.rpc.invoice(1000, 'inv1', 'inv1')['bolt11']
|
||||||
|
assert l1.rpc.decodepay(inv1)['payee'] == l1.info['id']
|
||||||
|
|
||||||
|
# Have l2 re-sign the invoice
|
||||||
|
inv2 = l2.rpc.signinvoice(inv1)['bolt11']
|
||||||
|
assert l1.rpc.decodepay(inv2)['payee'] == l2.info['id']
|
||||||
|
|
||||||
|
|
||||||
def test_waitanyinvoice_reversed(node_factory, executor):
|
def test_waitanyinvoice_reversed(node_factory, executor):
|
||||||
"""Test waiting for invoices, where they are paid in reverse order
|
"""Test waiting for invoices, where they are paid in reverse order
|
||||||
to when they are created.
|
to when they are created.
|
||||||
|
|||||||
Reference in New Issue
Block a user