diff --git a/CHANGELOG.md b/CHANGELOG.md index b83f5803e..c69beb6bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - JSON API: `listchannels` now takes a `source` option to filter by node id. - JSON API: New command `paystatus` gives detailed information on `pay` commands. - JSON API: `getroute` `riskfactor` argument is simplified; `pay` now defaults to setting it to 10. +- JSON API: `sendpay` now takes a `bolt11` field, and it's returned in `listpayments` and `waitsendpay`. - pylightning: New class 'Millisatoshi' can be used for JSON API, and new '_msat' fields are turned into this on reading. - 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) diff --git a/doc/lightning-sendpay.7 b/doc/lightning-sendpay.7 index 8e2e02d0e..d0d3df391 100644 --- a/doc/lightning-sendpay.7 +++ b/doc/lightning-sendpay.7 @@ -28,10 +28,10 @@ .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" -lightning-sendpay \- Command for sending a payment via a route\&. +lightning-sendpay \- Low\-level command for sending a payment via a route\&. .SH "SYNOPSIS" .sp -\fBsendpay\fR \fIroute\fR \fIpayment_hash\fR [\fIdescription\fR] [\fImsatoshi\fR] +\fBsendpay\fR \fIroute\fR \fIpayment_hash\fR [\fIdescription\fR] [\fImsatoshi\fR] [\fIbolt11\fR] .SH "DESCRIPTION" .sp The \fBsendpay\fR RPC command attempts to send funds associated with the given \fIpayment_hash\fR, along a route to the final destination in the route\&. @@ -40,7 +40,7 @@ Generally, a client would call lightning\-getroute(7) to resolve a route, then u .sp The response will occur when the payment is on its way to the destination\&. The \fBsendpay\fR RPC command does not wait for definite success or definite failure of the payment\&. Instead, use the \fBwaitsendpay\fR RPC command to poll or wait for definite success or definite failure\&. .sp -The \fIdescription\fR parameter, if provided, will be returned in \fIwaitsendpay\fR and \fIlistpayments\fR results\&. +The \fIdescription\fR and \fIbolt11\fR parameters, if provided, will be returned in \fIwaitsendpay\fR and \fIlistpayments\fR results\&. .sp The \fImsatoshi\fR amount, if provided, is the amount that will be recorded as the target payment value\&. If not specified, it will be the final amount to the destination\&. If specified, then the final amount at the destination must be from the specified \fImsatoshi\fR to twice the specified \fImsatoshi\fR, inclusive\&. This is intended to obscure payments by overpaying slightly at the destination; the actual target payment is what should be specified as the \fImsatoshi\fR argument\&. \fImsatoshi\fR is in millisatoshi precision; it can be a whole number, or a whole number ending in \fImsat\fR or \fIsat\fR, or a number with three decimal places ending in \fIsat\fR, or a number with 1 to 11 decimal places ending in \fIbtc\fR\&. .sp diff --git a/doc/lightning-sendpay.7.txt b/doc/lightning-sendpay.7.txt index 1e674e7c2..e83d27abb 100644 --- a/doc/lightning-sendpay.7.txt +++ b/doc/lightning-sendpay.7.txt @@ -4,11 +4,11 @@ LIGHTNING-SENDPAY(7) NAME ---- -lightning-sendpay - Command for sending a payment via a route. +lightning-sendpay - Low-level command for sending a payment via a route. SYNOPSIS -------- -*sendpay* 'route' 'payment_hash' ['description'] ['msatoshi'] +*sendpay* 'route' 'payment_hash' ['description'] ['msatoshi'] ['bolt11'] DESCRIPTION ----------- @@ -27,7 +27,7 @@ definite failure of the payment. Instead, use the *waitsendpay* RPC command to poll or wait for definite success or definite failure. -The 'description' parameter, if provided, will be returned in +The 'description' and 'bolt11' parameters, if provided, will be returned in 'waitsendpay' and 'listpayments' results. The 'msatoshi' amount, if provided, is the amount that will be @@ -44,7 +44,6 @@ be a whole number, or a whole number ending in 'msat' or 'sat', or a number with three decimal places ending in 'sat', or a number with 1 to 11 decimal places ending in 'btc'. - Once a payment has succeeded, calls to *sendpay* with the same 'payment_hash' but a different 'msatoshi' or destination will fail; this prevents accidental multiple payments. diff --git a/lightningd/pay.c b/lightningd/pay.c index f879f2830..8d18a080a 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -101,6 +101,8 @@ json_add_payment_fields(struct json_stream *response, sizeof(*t->payment_preimage)); if (t->description) json_add_string(response, "description", t->description); + if (t->bolt11) + json_add_string(response, "bolt11", t->bolt11); } static struct command_result *sendpay_success(struct command *cmd, @@ -580,7 +582,8 @@ send_payment(struct lightningd *ld, const struct sha256 *rhash, const struct route_hop *route, struct amount_msat msat, - const char *description TAKES) + const char *description TAKES, + const char *b11str TAKES) { const u8 *onion; u8 sessionkey[32]; @@ -720,6 +723,10 @@ send_payment(struct lightningd *ld, payment->description = tal_strdup(payment, description); else payment->description = NULL; + if (b11str != NULL) + payment->bolt11 = tal_strdup(payment, b11str); + else + payment->bolt11 = NULL; /* We write this into db when HTLC is actually sent. */ wallet_payment_setup(ld->wallet, payment); @@ -743,7 +750,7 @@ static struct command_result *json_sendpay(struct command *cmd, struct sha256 *rhash; struct route_hop *route; struct amount_msat *msat; - const char *description; + const char *description, *b11str; struct command_result *res; if (!param(cmd, buffer, params, @@ -751,6 +758,7 @@ static struct command_result *json_sendpay(struct command *cmd, p_req("payment_hash", param_sha256, &rhash), p_opt("description", param_escaped_string, &description), p_opt("msatoshi", param_msat, &msat), + p_opt("bolt11", param_string, &b11str), NULL)) return command_param_failed(); @@ -836,7 +844,7 @@ static struct command_result *json_sendpay(struct command *cmd, res = send_payment(cmd->ld, cmd, rhash, route, msat ? *msat : route[routetok->size-1].amount, - description); + description, b11str); if (res) return res; return command_still_pending(cmd); diff --git a/wallet/db.c b/wallet/db.c index b7197d363..45332c3ec 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -359,6 +359,8 @@ char *dbmigrations[] = { /* Fix dangling peers with no channels. */ "DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);", "ALTER TABLE outputs ADD scriptpubkey BLOB;", + /* Keep bolt11 string for payments. */ + "ALTER TABLE payments ADD bolt11 TEXT;", NULL, }; diff --git a/wallet/wallet.c b/wallet/wallet.c index f70b04f47..b25652236 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1722,8 +1722,9 @@ void wallet_payment_store(struct wallet *wallet, " route_nodes," " route_channels," " msatoshi_sent," - " description" - ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); + " description," + " bolt11" + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); sqlite3_bind_int(stmt, 1, payment->status); sqlite3_bind_sha256(stmt, 2, &payment->payment_hash); @@ -1745,6 +1746,13 @@ void wallet_payment_store(struct wallet *wallet, else sqlite3_bind_null(stmt, 10); + if (payment->bolt11 != NULL) + sqlite3_bind_text(stmt, 11, payment->bolt11, + strlen(payment->bolt11), + SQLITE_TRANSIENT); + else + sqlite3_bind_null(stmt, 11); + db_exec_prepared(wallet->db, stmt); tal_free(payment); @@ -1804,6 +1812,12 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx, else payment->description = NULL; + if (sqlite3_column_type(stmt, 12) != SQLITE_NULL) + payment->bolt11 = tal_strdup(payment, + (const char *)sqlite3_column_text(stmt, 12)); + else + payment->bolt11 = NULL; + return payment; } @@ -1811,7 +1825,7 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx, #define PAYMENT_FIELDS \ "id, status, destination, msatoshi, payment_hash, timestamp, " \ "payment_preimage, path_secrets, route_nodes, route_channels, " \ - "msatoshi_sent, description " + "msatoshi_sent, description, bolt11 " struct wallet_payment * wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet, diff --git a/wallet/wallet.h b/wallet/wallet.h index ebb1338ea..30f45df7b 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -224,6 +224,8 @@ struct wallet_payment { struct secret *path_secrets; struct pubkey *route_nodes; struct short_channel_id *route_channels; + /* bolt11 string; NULL for old payments. */ + const char *bolt11; /* The description of the payment. Must support `tal_len` */ const char *description;