mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 10:46:58 +01:00
invoice: allow numeric labels again.
Fixes: #1291 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
dc25e3a6df
commit
a85ead7058
5 changed files with 63 additions and 16 deletions
|
@ -2,12 +2,12 @@
|
||||||
.\" Title: lightning-invoice
|
.\" Title: lightning-invoice
|
||||||
.\" Author: [see the "AUTHOR" section]
|
.\" Author: [see the "AUTHOR" section]
|
||||||
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
||||||
.\" Date: 01/16/2018
|
.\" Date: 03/28/2018
|
||||||
.\" Manual: \ \&
|
.\" Manual: \ \&
|
||||||
.\" Source: \ \&
|
.\" Source: \ \&
|
||||||
.\" Language: English
|
.\" Language: English
|
||||||
.\"
|
.\"
|
||||||
.TH "LIGHTNING\-INVOICE" "7" "01/16/2018" "\ \&" "\ \&"
|
.TH "LIGHTNING\-INVOICE" "7" "03/28/2018" "\ \&" "\ \&"
|
||||||
.\" -----------------------------------------------------------------
|
.\" -----------------------------------------------------------------
|
||||||
.\" * Define some portability stuff
|
.\" * Define some portability stuff
|
||||||
.\" -----------------------------------------------------------------
|
.\" -----------------------------------------------------------------
|
||||||
|
@ -38,9 +38,9 @@ The \fBinvoice\fR RPC command creates the expectation of a payment of a given am
|
||||||
.sp
|
.sp
|
||||||
The \fImsatoshi\fR can be the string "any", which creates an invoice that can be paid with any amount\&.
|
The \fImsatoshi\fR can be the string "any", which creates an invoice that can be paid with any amount\&.
|
||||||
.sp
|
.sp
|
||||||
The \fIlabel\fR must be unique; it is never revealed to other nodes on the lightning network, but it can be used to query the status of this invoice\&.
|
The \fIlabel\fR must be a unique string or number (which is treated as a string, so "01" is different from "1"); it is never revealed to other nodes on the lightning network, but it can be used to query the status of this invoice\&.
|
||||||
.sp
|
.sp
|
||||||
The \fIdescription\fR is a short description of purpose of payment, e\&.g\&. \fI1 cup of coffee\fR\&. This value is encoded into the BOLT11 invoice and is viewable by any node you send this invoice to\&.
|
The \fIdescription\fR is a short description of purpose of payment, e\&.g\&. \fI1 cup of coffee\fR\&. This value is encoded into the BOLT11 invoice and is viewable by any node you send this invoice to\&. It must be UTF\-8, and cannot use \fI\eu\fR JSON escape codes\&.
|
||||||
.sp
|
.sp
|
||||||
The \fIexpiry\fR is optionally the number of seconds the invoice is valid for\&. If no value is provided the default of 3600 (1 Hour) is used\&.
|
The \fIexpiry\fR is optionally the number of seconds the invoice is valid for\&. If no value is provided the default of 3600 (1 Hour) is used\&.
|
||||||
.SH "RETURN VALUE"
|
.SH "RETURN VALUE"
|
||||||
|
|
|
@ -19,9 +19,10 @@ lightning daemon can use to pay this invoice.
|
||||||
The 'msatoshi' can be the string "any", which creates an invoice
|
The 'msatoshi' can be the string "any", which creates an invoice
|
||||||
that can be paid with any amount.
|
that can be paid with any amount.
|
||||||
|
|
||||||
The 'label' must be a unique string; it is never revealed to other nodes on
|
The 'label' must be a unique string or number (which is treated as a
|
||||||
the lightning network, but it can be used to query the status of this
|
string, so "01" is different from "1"); it is never revealed to other
|
||||||
invoice.
|
nodes on the lightning network, but it can be used to query the status
|
||||||
|
of this invoice.
|
||||||
|
|
||||||
The 'description' is a short description of purpose of payment,
|
The 'description' is a short description of purpose of payment,
|
||||||
e.g. '1 cup of coffee'. This value is encoded into the BOLT11 invoice
|
e.g. '1 cup of coffee'. This value is encoded into the BOLT11 invoice
|
||||||
|
|
2
external/libwally-core
vendored
2
external/libwally-core
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 8e6d990b5e62ff4d1c9bc68af29423cc98a232fa
|
Subproject commit 770c572db76e7730dd2c8481c78aaf02682b1c1a
|
|
@ -104,6 +104,29 @@ static bool hsm_sign_b11(const u5 *u5bytes,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We allow a string, or a literal number, for labels */
|
||||||
|
static struct json_escaped *json_tok_label(const tal_t *ctx,
|
||||||
|
const char *buffer,
|
||||||
|
const jsmntok_t *tok)
|
||||||
|
{
|
||||||
|
struct json_escaped *label;
|
||||||
|
|
||||||
|
label = json_tok_escaped_string(ctx, buffer, tok);
|
||||||
|
if (label)
|
||||||
|
return label;
|
||||||
|
|
||||||
|
/* Allow literal numbers */
|
||||||
|
if (tok->type != JSMN_PRIMITIVE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (int i = tok->start; i < tok->end; i++)
|
||||||
|
if (!cisdigit(buffer[i]))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return json_escaped_string_(ctx, buffer + tok->start,
|
||||||
|
tok->end - tok->start);
|
||||||
|
}
|
||||||
|
|
||||||
static void json_invoice(struct command *cmd,
|
static void json_invoice(struct command *cmd,
|
||||||
const char *buffer, const jsmntok_t *params)
|
const char *buffer, const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
|
@ -148,9 +171,9 @@ static void json_invoice(struct command *cmd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* label */
|
/* label */
|
||||||
label_val = json_tok_escaped_string(cmd, buffer, label);
|
label_val = json_tok_label(cmd, buffer, label);
|
||||||
if (!label_val) {
|
if (!label_val) {
|
||||||
command_fail(cmd, "label '%.*s' not a string",
|
command_fail(cmd, "label '%.*s' not a string or number",
|
||||||
label->end - label->start, buffer + label->start);
|
label->end - label->start, buffer + label->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -306,9 +329,9 @@ static void json_listinvoice_internal(struct command *cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labeltok) {
|
if (labeltok) {
|
||||||
label = json_tok_escaped_string(cmd, buffer, labeltok);
|
label = json_tok_label(cmd, buffer, labeltok);
|
||||||
if (!label) {
|
if (!label) {
|
||||||
command_fail(cmd, "label '%.*s' is not a string",
|
command_fail(cmd, "label '%.*s' is not a string or number",
|
||||||
labeltok->end - labeltok->start,
|
labeltok->end - labeltok->start,
|
||||||
buffer + labeltok->start);
|
buffer + labeltok->start);
|
||||||
return;
|
return;
|
||||||
|
@ -374,9 +397,9 @@ static void json_delinvoice(struct command *cmd,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
label = json_tok_escaped_string(cmd, buffer, labeltok);
|
label = json_tok_label(cmd, buffer, labeltok);
|
||||||
if (!label) {
|
if (!label) {
|
||||||
command_fail(cmd, "label '%.*s' not a string",
|
command_fail(cmd, "label '%.*s' is not a string or number",
|
||||||
labeltok->end - labeltok->start,
|
labeltok->end - labeltok->start,
|
||||||
buffer + labeltok->start);
|
buffer + labeltok->start);
|
||||||
return;
|
return;
|
||||||
|
@ -567,9 +590,9 @@ static void json_waitinvoice(struct command *cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search for invoice */
|
/* Search for invoice */
|
||||||
label = json_tok_escaped_string(cmd, buffer, labeltok);
|
label = json_tok_label(cmd, buffer, labeltok);
|
||||||
if (!label) {
|
if (!label) {
|
||||||
command_fail(cmd, "label '%.*s' is not a string",
|
command_fail(cmd, "label '%.*s' is not a string or number",
|
||||||
labeltok->end - labeltok->start,
|
labeltok->end - labeltok->start,
|
||||||
buffer + labeltok->start);
|
buffer + labeltok->start);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -475,6 +475,29 @@ class LightningDTests(BaseLightningDTests):
|
||||||
b11 = l1.rpc.decodepay(inv['bolt11'])
|
b11 = l1.rpc.decodepay(inv['bolt11'])
|
||||||
assert b11['description'] == weird_desc
|
assert b11['description'] == weird_desc
|
||||||
|
|
||||||
|
# Can delete by weird label.
|
||||||
|
l1.rpc.delinvoice(weird_label, "unpaid")
|
||||||
|
|
||||||
|
# We can also use numbers as labels.
|
||||||
|
weird_label = 25
|
||||||
|
weird_desc = '"'
|
||||||
|
l1.rpc.invoice(123000, weird_label, weird_desc)
|
||||||
|
# FIXME: invoice RPC should return label!
|
||||||
|
|
||||||
|
# Can find by this label.
|
||||||
|
inv = l1.rpc.listinvoices(weird_label)['invoices'][0]
|
||||||
|
assert inv['label'] == str(weird_label)
|
||||||
|
|
||||||
|
# Can find this in list.
|
||||||
|
inv = l1.rpc.listinvoices()['invoices'][0]
|
||||||
|
assert inv['label'] == str(weird_label)
|
||||||
|
|
||||||
|
b11 = l1.rpc.decodepay(inv['bolt11'])
|
||||||
|
assert b11['description'] == weird_desc
|
||||||
|
|
||||||
|
# Can delete by weird label.
|
||||||
|
l1.rpc.delinvoice(weird_label, "unpaid")
|
||||||
|
|
||||||
def test_invoice_expiry(self):
|
def test_invoice_expiry(self):
|
||||||
l1, l2 = self.connect()
|
l1, l2 = self.connect()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue