diff --git a/CHANGELOG.md b/CHANGELOG.md
index c9396dbd0..b01141d6f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- JSON API: `fundchannel` and `withdraw` now have a new parameter `minconf` that limits coinselection to outputs that have at least `minconf` confirmations (default 1). (#2380)
- JSON API: `listfunds` now displays addresses for all outputs owned by the wallet (#2387)
- JSON API: `waitsendpay` and `sendpay` output field `label` as specified by `sendpay` call.
+- JSON API: `listpays` command for higher-level payment view than `listpayments`, especially important with multi-part-payments coming.
### Changed
diff --git a/doc/Makefile b/doc/Makefile
index 78449841e..bd771ce22 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -21,6 +21,7 @@ MANPAGES := doc/lightning-cli.1 \
doc/lightning-listfunds.7 \
doc/lightning-listinvoices.7 \
doc/lightning-listpayments.7 \
+ doc/lightning-listpays.7 \
doc/lightning-listpeers.7 \
doc/lightning-newaddr.7 \
doc/lightning-pay.7 \
@@ -29,7 +30,6 @@ MANPAGES := doc/lightning-cli.1 \
doc/lightning-waitanyinvoice.7 \
doc/lightning-waitsendpay.7 \
doc/lightning-withdraw.7
-
doc-all: $(MANPAGES)
diff --git a/doc/lightning-listpays.7 b/doc/lightning-listpays.7
new file mode 100644
index 000000000..0904b68c8
--- /dev/null
+++ b/doc/lightning-listpays.7
@@ -0,0 +1,108 @@
+'\" t
+.\" Title: lightning-listpays
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1
+.\" Date: 02/23/2019
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "LIGHTNING\-LISTPAYS" "7" "02/23/2019" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+lightning-listpays \- Command for querying payment status
+.SH "SYNOPSIS"
+.sp
+\fBlistpays\fR [bolt11]
+.SH "DESCRIPTION"
+.sp
+The \fBlistpay\fR RPC command gets the status of all \fIpay\fR commands, or a single one if \fIbolt11\fR is specified\&.
+.SH "RETURN VALUE"
+.sp
+On success, an array of objects is returned\&. Each object contains:
+.PP
+\fIbolt11\fR
+.RS 4
+the
+\fIbolt11\fR
+argument given to
+\fIpay\fR
+(see below for exceptions)\&.
+.RE
+.PP
+\fIstatus\fR
+.RS 4
+one of
+\fIcomplete\fR,
+\fIfailed\fR
+or
+\fIpending\fR\&.
+.RE
+.PP
+\fIpayment_preimage\fR
+.RS 4
+(if
+\fIstatus\fR
+is
+\fIcomplete\fR) proves payment was received\&.
+.RE
+.PP
+\fIlabel\fR
+.RS 4
+optional
+\fIlabel\fR, if provided to
+\fIpay\fR\&.
+.RE
+.PP
+\fIamount_sent_msat\fR
+.RS 4
+total amount sent, in "NNNmsat" format\&.
+.RE
+.sp
+For old payments (pre\-0\&.7) we didn\(cqt save the \fIbolt11\fR string, so in its place are three other fields:
+.PP
+\fIpayment_hash\fR
+.RS 4
+the hash of the
+\fIpayment_preimage\fR
+which will prove payment\&.
+.RE
+.PP
+\fIdestination\fR
+.RS 4
+the final destination of the payment\&.
+.RE
+.PP
+\fIamount_msat\fR
+.RS 4
+the amount the destination received, in "NNNmsat" format\&.
+.RE
+.sp
+These three can all be extracted from \fIbolt11\fR, hence are obsolete\&.
+.SH "AUTHOR"
+.sp
+Rusty Russell is mainly responsible\&.
+.SH "SEE ALSO"
+.sp
+lightning\-pay(7), lightning\-paystatus(7), lightning\-listpayments(7)\&.
+.SH "RESOURCES"
+.sp
+Main web site: https://github\&.com/ElementsProject/lightning
diff --git a/doc/lightning-listpays.7.txt b/doc/lightning-listpays.7.txt
new file mode 100644
index 000000000..7155c37c7
--- /dev/null
+++ b/doc/lightning-listpays.7.txt
@@ -0,0 +1,49 @@
+LIGHTNING-LISTPAYS(7)
+=====================
+:doctype: manpage
+
+NAME
+----
+lightning-listpays - Command for querying payment status
+
+SYNOPSIS
+--------
+*listpays* [bolt11]
+
+DESCRIPTION
+-----------
+
+The *listpay* RPC command gets the status of all 'pay' commands, or a single
+one if 'bolt11' is specified.
+
+RETURN VALUE
+------------
+On success, an array of objects is returned. Each object contains:
+
+'bolt11':: the 'bolt11' argument given to 'pay' (see below for exceptions).
+'status':: one of 'complete', 'failed' or 'pending'.
+'payment_preimage':: (if 'status' is 'complete') proves payment was received.
+'label':: optional 'label', if provided to 'pay'.
+'amount_sent_msat':: total amount sent, in "NNNmsat" format.
+
+For old payments (pre-0.7) we didn't save the 'bolt11' string, so in
+its place are three other fields:
+
+'payment_hash':: the hash of the 'payment_preimage' which will prove payment.
+'destination':: the final destination of the payment.
+'amount_msat':: the amount the destination received, in "NNNmsat" format.
+
+These three can all be extracted from 'bolt11', hence are obsolete.
+//FIXME:Enumerate errors
+
+AUTHOR
+------
+Rusty Russell is mainly responsible.
+
+SEE ALSO
+--------
+lightning-pay(7), lightning-paystatus(7), lightning-listpayments(7).
+
+RESOURCES
+---------
+Main web site: https://github.com/ElementsProject/lightning
diff --git a/doc/lightning-pay.7 b/doc/lightning-pay.7
index 57b3091e8..0158e6a84 100644
--- a/doc/lightning-pay.7
+++ b/doc/lightning-pay.7
@@ -40,7 +40,7 @@ The \fIlabel\fR field is used to attach a label to payments, and is returned in
.sp
The response will occur when the payment fails or succeeds\&. Once a payment has succeeded, calls to \fBpay\fR with the same \fIbolt11\fR will succeed immediately\&.
.sp
-The command will keep finding routes and retrying the payment until it succeeds, or the given \fIretry_for\fR seconds passes\&. Note that the command may stop retrying while a pending payment is ongoing, which you need to monitor with \fBlistpayments\fR or \fBwaitsendpay\fR\&. \fIretry_for\fR defaults to 60 seconds and can only be an integer\&.
+The command will keep finding routes and retrying the payment until it succeeds, or the given \fIretry_for\fR seconds passes\&. Note that the command may stop retrying while a pending payment is ongoing, which you need to monitor with \fBlistpays\fR\&. \fIretry_for\fR defaults to 60 seconds and can only be an integer\&.
.sp
When using \fIlightning\-cli\fR, you may skip optional parameters by using \fInull\fR\&. Alternatively, use \fB\-k\fR option to provide parameters by name\&.
.SH "RANDOMIZATION"
@@ -102,9 +102,7 @@ The following error codes may occur:
.IP \(bu 2.3
.\}
200\&. Payment timed out while a payment is in progress\&. Monitor the status of that payment with
-\fIlistpayments\fR
-command, or wait for that payment to complete with
-\fIpay\fR
+\fIlistpays\fR
command\&.
.RE
.sp
@@ -267,7 +265,7 @@ The \fIdata\fR field of errors will include statistics \fIgetroute_tries\fR and
Rusty Russell is mainly responsible\&.
.SH "SEE ALSO"
.sp
-lightning\-listpayments(7), lightning\-decodepay(7), lightning\-listinvoice(7), lightning\-delinvoice(7), lightning\-getroute(7), lightning\-invoice(7)\&.
+lightning\-listpays(7), lightning\-decodepay(7), lightning\-listinvoice(7), lightning\-delinvoice(7), lightning\-getroute(7), lightning\-invoice(7)\&.
.SH "RESOURCES"
.sp
Main web site: https://github\&.com/ElementsProject/lightning
diff --git a/doc/lightning-pay.7.txt b/doc/lightning-pay.7.txt
index 067dc5a65..3d2b79db3 100644
--- a/doc/lightning-pay.7.txt
+++ b/doc/lightning-pay.7.txt
@@ -40,7 +40,7 @@ succeed immediately.
The command will keep finding routes and retrying the payment until
it succeeds, or the given 'retry_for' seconds passes.
Note that the command may stop retrying while a pending payment is
-ongoing, which you need to monitor with *listpayments* or *waitsendpay*.
+ongoing, which you need to monitor with *listpays*.
'retry_for' defaults to 60 seconds and can only be an integer.
When using 'lightning-cli', you may skip optional parameters by using
@@ -91,8 +91,7 @@ The following error codes may occur:
* -1. Catchall nonspecific error.
* 200. Payment timed out while a payment is in progress. Monitor
- the status of that payment with 'listpayments' command, or
- wait for that payment to complete with 'pay' command.
+ the status of that payment with 'listpays' command.
* 201. Already paid with this 'hash' using different amount or
destination.
* 203. Permanent failure at destination. The 'data' field of
@@ -145,7 +144,7 @@ Rusty Russell is mainly responsible.
SEE ALSO
--------
-lightning-listpayments(7), lightning-decodepay(7),
+lightning-listpays(7), lightning-decodepay(7),
lightning-listinvoice(7), lightning-delinvoice(7),
lightning-getroute(7), lightning-invoice(7).
diff --git a/plugins/pay.c b/plugins/pay.c
index 893187fad..e36653409 100644
--- a/plugins/pay.c
+++ b/plugins/pay.c
@@ -1,4 +1,5 @@
#include
+#include
#include
#include
#include
@@ -1093,6 +1094,90 @@ static struct command_result *handle_paystatus(struct command *cmd,
return command_success(cmd, ret);
}
+static const jsmntok_t *copy_member(char **ret,
+ const char *buf,
+ const jsmntok_t *result,
+ const char *membername,
+ const char *term)
+{
+ const jsmntok_t *m = json_get_member(buf, result, membername);
+ if (m)
+ tal_append_fmt(ret, "'%s': %.*s%s",
+ membername,
+ json_tok_full_len(m), json_tok_full(buf, m),
+ term);
+ return m;
+}
+
+static struct command_result *listpayments_done(struct command *cmd,
+ const char *buf,
+ const jsmntok_t *result,
+ char *b11str)
+{
+ size_t i;
+ const jsmntok_t *t, *arr;
+ char *ret;
+ bool some = false;
+
+ arr = json_get_member(buf, result, "payments");
+ if (!arr || arr->type != JSMN_ARRAY)
+ return command_fail(cmd, LIGHTNINGD,
+ "Unexpected non-array result from listpayments");
+
+ ret = tal_fmt(cmd, "{ 'pays': [");
+ json_for_each_arr(i, t, arr) {
+ const jsmntok_t *status;
+
+ if (some)
+ tal_append_fmt(&ret, ",\n");
+ some = true;
+
+ tal_append_fmt(&ret, "{");
+ /* Old payments didn't have bolt11 field */
+ if (!copy_member(&ret, buf, t, "bolt11", ",")) {
+ if (b11str) {
+ /* If it's a single query, we can fake it */
+ tal_append_fmt(&ret, "'bolt11': '%s',", b11str);
+ } else {
+ copy_member(&ret, buf, t, "payment_hash", ",");
+ copy_member(&ret, buf, t, "destination", ",");
+ copy_member(&ret, buf, t, "amount_msat", ",");
+ }
+ }
+
+ status = copy_member(&ret, buf, t, "status", ",");
+ if (status && json_tok_streq(buf, status, "complete"))
+ copy_member(&ret, buf, t, "payment_preimage", ",");
+ copy_member(&ret, buf, t, "label", ",");
+ copy_member(&ret, buf, t, "amount_sent_msat", "");
+ tal_append_fmt(&ret, "}");
+ }
+ tal_append_fmt(&ret, "] }");
+ return command_success(cmd, ret);
+}
+
+static struct command_result *handle_listpays(struct command *cmd,
+ const char *buf,
+ const jsmntok_t *params)
+{
+ const char *b11str, *paramstr;
+
+ /* FIXME: would be nice to parse as a bolt11 so check worked in future */
+ if (!param(cmd, buf, params,
+ p_opt("bolt11", param_string, &b11str),
+ NULL))
+ return NULL;
+
+ if (b11str)
+ paramstr = tal_fmt(tmpctx, "'bolt11' : '%s'", b11str);
+ else
+ paramstr = "";
+ return send_outreq(cmd, "listpayments",
+ listpayments_done, forward_error,
+ cast_const(char *, b11str),
+ "%s", paramstr);
+}
+
static void init(struct plugin_conn *rpc)
{
const char *field;
@@ -1117,6 +1202,11 @@ static const struct plugin_command commands[] = { {
"Detail status of attempts to pay {bolt11}, or all",
"Covers both old payments and current ones.",
handle_paystatus
+ }, {
+ "listpays",
+ "List result of payment {bolt11}, or all",
+ "Covers old payments (failed and succeeded) and current ones.",
+ handle_listpays
}
};