lightningd: createinvoice low-level invoice creation command.

This takes an unsigned bolt11 (or bolt12 if EXPERIMENTAL_FEATURES) string
and signs it and puts it in the database.

The invoice command could now be moved out to a plugin, in fact.

Changelog-Added: JSON-RPC: `createinvoice` new low-level invoice creation API.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2020-12-14 11:51:48 +10:30 committed by Christian Decker
parent 32d66b2740
commit fab0842d31
11 changed files with 508 additions and 121 deletions

View File

@ -72,6 +72,7 @@ static const errcode_t INVOICE_EXPIRED_DURING_WAIT = 903;
static const errcode_t INVOICE_WAIT_TIMED_OUT = 904;
static const errcode_t INVOICE_NOT_FOUND = 905;
static const errcode_t INVOICE_STATUS_UNEXPECTED = 906;
static const errcode_t INVOICE_OFFER_INACTIVE = 907;
/* Errors from HSM crypto operations. */
static const errcode_t HSM_ECDH_FAILED = 800;

View File

@ -13,6 +13,7 @@ MANPAGES := doc/lightning-cli.1 \
doc/lightning-close.7 \
doc/lightning-connect.7 \
doc/lightning-createonion.7 \
doc/lightning-createinvoice.7 \
doc/lightning-decodepay.7 \
doc/lightning-delexpiredinvoice.7 \
doc/lightning-delinvoice.7 \

View File

@ -34,6 +34,7 @@ c-lightning Documentation
lightning-cli <lightning-cli.1.md>
lightning-close <lightning-close.7.md>
lightning-connect <lightning-connect.7.md>
lightning-createinvoice <lightning-createinvoice.7.md>
lightning-createonion <lightning-createonion.7.md>
lightning-decodepay <lightning-decodepay.7.md>
lightning-delexpiredinvoice <lightning-delexpiredinvoice.7.md>

60
doc/lightning-createinvoice.7 generated Normal file
View File

@ -0,0 +1,60 @@
.TH "LIGHTNING-CREATEINVOICE" "7" "" "" "lightning-createinvoice"
.SH NAME
lightning-createinvoice - Low-level invoice creation
.SH SYNOPSIS
\fBcreateinvoice\fR \fIinvstring\fR \fIpreimage\fR \fIlabel\fR
.SH DESCRIPTION
The \fBcreateinvoice\fR RPC command signs and saves an invoice into the
database\.
The \fIinvstring\fR parameter is of bolt11 form, but without the final
signature appended\. Minimal sanity checks are done\.
The \fIpreimage\fR is the preimage to supply upon successful payment of
the 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\.
.SH RETURN VALUE
On success, an invoice object is returned, as per \fBlistinvoices\fR(7)\.
On failure, an error is returned and no invoice is created\. If the
lightning process fails before responding, the caller should use
\fBlightning-listinvoices\fR(7) to query whether this invoice was created or
not\.
The following error codes may occur:
.RS
.IP \[bu]
-1: Catchall nonspecific error\.
.IP \[bu]
900: An invoice with the given \fIlabel\fR already exists\.
.RE
.SH AUTHOR
Rusty Russell \fI<rusty@rustcorp.com.au\fR> is mainly responsible\.
.SH SEE ALSO
\fBlightning-invoice\fR(7), \fBlightning-listinvoices\fR(7), \fBlightning-delinvoice\fR(7),
\fBlightning-getroute\fR(7), \fBlightning-sendpay\fR(7)\.
.SH RESOURCES
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
\" SHA256STAMP:1b6598e430d416615867dc09604574c62a8ecb47c51a370711da75359ff80ef3

View File

@ -0,0 +1,56 @@
lightning-createinvoice -- Low-level invoice creation
=====================================================
SYNOPSIS
--------
**createinvoice** *invstring* *preimage* *label*
DESCRIPTION
-----------
The **createinvoice** RPC command signs and saves an invoice into the
database.
The *invstring* parameter is of bolt11 form, but without the final
signature appended. Minimal sanity checks are done.
The *preimage* is the preimage to supply upon successful payment of
the invoice.
The *label* 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.
RETURN VALUE
------------
On success, an invoice object is returned, as per listinvoices(7).
On failure, an error is returned and no invoice is created. If the
lightning process fails before responding, the caller should use
lightning-listinvoices(7) to query whether this invoice was created or
not.
The following error codes may occur:
- -1: Catchall nonspecific error.
- 900: An invoice with the given *label* already exists.
AUTHOR
------
Rusty Russell <<rusty@rustcorp.com.au>> is mainly responsible.
SEE ALSO
--------
lightning-invoice(7), lightning-listinvoices(7), lightning-delinvoice(7),
lightning-getroute(7), lightning-sendpay(7).
RESOURCES
---------
Main web site: <https://github.com/ElementsProject/lightning>

View File

@ -10,6 +10,10 @@
#include <common/amount.h>
#include <common/bech32.h>
#include <common/bolt11.h>
#if EXPERIMENTAL_FEATURES
#include <common/bolt12.h>
#include <common/bolt12_merkle.h>
#endif
#include <common/configdir.h>
#include <common/features.h>
#include <common/json_command.h>
@ -428,6 +432,29 @@ static bool hsm_sign_b11(const u5 *u5bytes,
return true;
}
#if EXPERIMENTAL_FEATURES
static void hsm_sign_b12_invoice(struct lightningd *ld,
struct tlv_invoice *invoice)
{
struct sha256 merkle;
u8 *msg;
assert(!invoice->signature);
merkle_tlv(invoice->fields, &merkle);
msg = towire_hsmd_sign_bolt12(NULL, "invoice", "signature", &merkle);
if (!wire_sync_write(ld->hsm_fd, take(msg)))
fatal("Could not write to HSM: %s", strerror(errno));
msg = wire_sync_read(tmpctx, ld->hsm_fd);
invoice->signature = tal(invoice, struct bip340sig);
if (!fromwire_hsmd_sign_bolt12_reply(msg, invoice->signature))
fatal("HSM gave bad sign_invoice_reply %s",
tal_hex(msg, msg));
}
#endif /* EXPERIMENTAL_FEATURES */
static struct command_result *parse_fallback(struct command *cmd,
const char *buffer,
const jsmntok_t *fallback,
@ -920,13 +947,27 @@ static struct command_result *param_chanhints(struct command *cmd,
&(*chanhints)->hints);
}
static struct command_result *param_preimage(struct command *cmd,
const char *name,
const char *buffer,
const jsmntok_t *tok,
struct preimage **preimage)
{
*preimage = tal(cmd, struct preimage);
if (!hex_decode(buffer + tok->start, tok->end - tok->start,
*preimage, sizeof(**preimage)))
return command_fail_badparam(cmd, "preimage",
buffer, tok,
"should be 64 hex digits");
return NULL;
}
static struct command_result *json_invoice(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
const jsmntok_t *fallbacks;
const jsmntok_t *preimagetok;
struct amount_msat *msatoshi_val;
struct invoice_info *info;
const char *desc_val;
@ -934,6 +975,7 @@ static struct command_result *json_invoice(struct command *cmd,
u64 *expiry;
struct sha256 rhash;
struct secret payment_secret;
struct preimage *preimage;
#if DEVELOPER
const jsmntok_t *routes;
#endif
@ -947,7 +989,7 @@ static struct command_result *json_invoice(struct command *cmd,
p_req("description", param_escaped_string, &desc_val),
p_opt_def("expiry", param_time, &expiry, 3600*24*7),
p_opt("fallbacks", param_array, &fallbacks),
p_opt("preimage", param_tok, &preimagetok),
p_opt("preimage", param_preimage, &preimage),
p_opt("exposeprivatechannels", param_chanhints,
&info->chanhints),
#if DEVELOPER
@ -993,17 +1035,9 @@ static struct command_result *json_invoice(struct command *cmd,
}
}
if (preimagetok) {
/* Get secret preimage from user. */
if (!hex_decode(buffer + preimagetok->start,
preimagetok->end - preimagetok->start,
&info->payment_preimage,
sizeof(info->payment_preimage))) {
return command_fail_badparam(cmd, "preimage",
buffer, preimagetok,
"should be 64 hex digits");
}
} else
if (preimage)
info->payment_preimage = *preimage;
else
/* Generate random secret preimage. */
randombytes_buf(&info->payment_preimage,
sizeof(info->payment_preimage));
@ -1441,3 +1475,162 @@ static const struct json_command decodepay_command = {
"Decode {bolt11}, using {description} if necessary"
};
AUTODATA(json_command, &decodepay_command);
/* If we fail because it exists, we also return the clashing invoice */
static struct command_result *fail_exists(struct command *cmd,
const struct json_escape *label)
{
struct json_stream *data;
struct invoice invoice;
struct wallet *wallet = cmd->ld->wallet;
data = json_stream_fail(cmd, INVOICE_LABEL_ALREADY_EXISTS,
"Duplicate label");
if (!wallet_invoice_find_by_label(wallet, &invoice, label))
fatal("Duplicate invoice %s not found any more?",
label->s);
json_add_invoice(data, wallet_invoice_details(cmd, wallet, invoice));
json_object_end(data);
return command_failed(cmd, data);
}
static struct command_result *json_createinvoice(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
const char *invstring;
struct json_escape *label;
struct preimage *preimage;
struct invoice invoice;
struct sha256 payment_hash;
struct json_stream *response;
struct bolt11 *b11;
struct sha256 hash;
u5 *sig;
bool have_n;
char *fail;
if (!param(cmd, buffer, params,
p_req("invstring", param_string, &invstring),
p_req("preimage", param_preimage, &preimage),
p_req("label", param_label, &label),
NULL))
return command_param_failed();
sha256(&payment_hash, preimage, sizeof(*preimage));
b11 = bolt11_decode_nosig(cmd, invstring, cmd->ld->our_features,
NULL, chainparams, &hash, &sig, &have_n,
&fail);
if (b11) {
/* This adds the signature */
char *b11enc = bolt11_encode(cmd, b11, have_n,
hsm_sign_b11, cmd->ld);
if (!b11->description)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Missing description in invoice");
if (!b11->expiry)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Missing expiry in invoice");
if (!wallet_invoice_create(cmd->ld->wallet,
&invoice,
b11->msat,
label,
b11->expiry,
b11enc,
b11->description,
b11->features,
preimage,
&payment_hash,
NULL))
return fail_exists(cmd, label);
notify_invoice_creation(cmd->ld, b11->msat, *preimage, label);
} else {
#if EXPERIMENTAL_FEATURES
struct tlv_invoice *inv;
struct sha256 *local_offer_id;
inv = invoice_decode_nosig(cmd, invstring, strlen(invstring),
cmd->ld->our_features, chainparams,
&fail);
if (inv) {
char *b12enc;
struct amount_msat msat;
const char *desc;
u32 expiry;
enum offer_status status;
if (inv->signature)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"invoice already signed");
hsm_sign_b12_invoice(cmd->ld, inv);
b12enc = invoice_encode(cmd, inv);
if (inv->offer_id
&& wallet_offer_find(tmpctx, cmd->ld->wallet,
inv->offer_id, NULL, &status)) {
if (!offer_status_active(status))
return command_fail(cmd, INVOICE_OFFER_INACTIVE,
"offer not active");
local_offer_id = inv->offer_id;
} else
local_offer_id = NULL;
if (inv->amount)
msat = amount_msat(*inv->amount);
if (inv->relative_expiry)
expiry = *inv->relative_expiry;
else
expiry = 7200;
if (!inv->description)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Missing description in invoice");
desc = tal_strndup(cmd,
cast_signed(char *, inv->description),
tal_bytelen(inv->description));
if (!wallet_invoice_create(cmd->ld->wallet,
&invoice,
inv->amount ? &msat : NULL,
label,
expiry,
b12enc,
desc,
inv->features,
preimage,
&payment_hash,
local_offer_id))
return fail_exists(cmd, label);
notify_invoice_creation(cmd->ld,
inv->amount ? &msat : NULL,
*preimage, label);
} else
#endif /* EXPERIMENTAL_FEATURES */
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Unparsable invoice '%s': %s",
invstring, fail);
}
response = json_stream_success(cmd);
json_add_invoice(response,
wallet_invoice_details(cmd, cmd->ld->wallet, invoice));
return command_success(cmd, response);
}
static const struct json_command createinvoice_command = {
"createinvoice",
"payment",
json_createinvoice,
"Lowlevel command to sign and create invoice {invstring}, resolved with {preimage}, using unique {label}."
};
AUTODATA(json_command, &createinvoice_command);

View File

@ -27,6 +27,16 @@ struct bolt11 *bolt11_decode(const tal_t *ctx UNNEEDED, const char *str UNNEEDED
const struct chainparams *must_be_chain UNNEEDED,
char **fail UNNEEDED)
{ fprintf(stderr, "bolt11_decode called!\n"); abort(); }
/* Generated stub for bolt11_decode_nosig */
struct bolt11 *bolt11_decode_nosig(const tal_t *ctx UNNEEDED, const char *str UNNEEDED,
const struct feature_set *our_features UNNEEDED,
const char *description UNNEEDED,
const struct chainparams *must_be_chain UNNEEDED,
struct sha256 *hash UNNEEDED,
u5 **sig UNNEEDED,
bool *have_n UNNEEDED,
char **fail UNNEEDED)
{ fprintf(stderr, "bolt11_decode_nosig called!\n"); abort(); }
/* Generated stub for bolt11_encode_ */
char *bolt11_encode_(const tal_t *ctx UNNEEDED,
const struct bolt11 *b11 UNNEEDED, bool n_field UNNEEDED,
@ -171,6 +181,9 @@ bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p U
/* Generated stub for fromwire_gossipd_get_incoming_channels_reply */
bool fromwire_gossipd_get_incoming_channels_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct route_info **public_route_info UNNEEDED, bool **public_deadends UNNEEDED, struct route_info **private_route_info UNNEEDED, bool **private_deadends UNNEEDED)
{ fprintf(stderr, "fromwire_gossipd_get_incoming_channels_reply called!\n"); abort(); }
/* Generated stub for fromwire_hsmd_sign_bolt12_reply */
bool fromwire_hsmd_sign_bolt12_reply(const void *p UNNEEDED, struct bip340sig *sig UNNEEDED)
{ fprintf(stderr, "fromwire_hsmd_sign_bolt12_reply called!\n"); abort(); }
/* 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)
{ fprintf(stderr, "fromwire_hsmd_sign_commitment_tx_reply called!\n"); abort(); }
@ -555,6 +568,9 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
/* Generated stub for towire_gossipd_get_incoming_channels */
u8 *towire_gossipd_get_incoming_channels(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_gossipd_get_incoming_channels called!\n"); abort(); }
/* Generated stub for towire_hsmd_sign_bolt12 */
u8 *towire_hsmd_sign_bolt12(const tal_t *ctx UNNEEDED, const wirestring *messagename UNNEEDED, const wirestring *fieldname UNNEEDED, const struct sha256 *merkleroot UNNEEDED)
{ fprintf(stderr, "towire_hsmd_sign_bolt12 called!\n"); abort(); }
/* 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)
{ fprintf(stderr, "towire_hsmd_sign_commitment_tx called!\n"); abort(); }
@ -668,6 +684,14 @@ void wallet_invoice_waitone(const tal_t *ctx UNNEEDED,
void (*cb)(const struct invoice * UNNEEDED, void*) UNNEEDED,
void *cbarg UNNEEDED)
{ fprintf(stderr, "wallet_invoice_waitone called!\n"); abort(); }
/* Generated stub for wallet_offer_find */
char *wallet_offer_find(const tal_t *ctx UNNEEDED,
struct wallet *w UNNEEDED,
const struct sha256 *offer_id UNNEEDED,
const struct json_escape **label UNNEEDED,
enum offer_status *status)
{ fprintf(stderr, "wallet_offer_find called!\n"); abort(); }
/* Generated stub for wallet_peer_delete */
void wallet_peer_delete(struct wallet *w UNNEEDED, u64 peer_dbid UNNEEDED)
{ fprintf(stderr, "wallet_peer_delete called!\n"); abort(); }
@ -722,6 +746,22 @@ bool dev_disconnect_permanent(struct lightningd *ld UNNEEDED)
{ fprintf(stderr, "dev_disconnect_permanent called!\n"); abort(); }
#endif
#if EXPERIMENTAL_FEATURES
/* Generated stub for merkle_tlv */
void merkle_tlv(const struct tlv_field *fields UNNEEDED, struct sha256 *merkle UNNEEDED)
{ fprintf(stderr, "merkle_tlv called!\n"); abort(); }
/* Generated stub for invoice_decode_nosig */
struct tlv_invoice *invoice_decode_nosig(const tal_t *ctx UNNEEDED,
const char *b12 UNNEEDED, size_t b12len UNNEEDED,
const struct feature_set *our_features UNNEEDED,
const struct chainparams *must_be_chain UNNEEDED,
char **fail UNNEEDED)
{ fprintf(stderr, "invoice_decode_nosig called!\n"); abort(); }
/* Generated stub for invoice_encode */
char *invoice_encode(const tal_t *ctx UNNEEDED, const struct tlv_invoice *bolt12_tlv UNNEEDED)
{ fprintf(stderr, "invoice_encode called!\n"); abort(); }
#endif
static void add_candidate(struct routehint_candidate **candidates, int n,
struct channel *c)
{

View File

@ -860,6 +860,12 @@ struct db_query db_postgres_queries[] = {
.placeholders = 0,
.readonly = false,
},
{
.name = "ALTER TABLE payments ADD COLUMN local_offer_id BLOB DEFAULT NULL;",
.query = "ALTER TABLE payments ADD COLUMN local_offer_id BYTEA DEFAULT NULL;",
.placeholders = 0,
.readonly = false,
},
{
.name = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?",
.query = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = $1",
@ -1401,9 +1407,9 @@ struct db_query db_postgres_queries[] = {
.readonly = true,
},
{
.name = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
.query = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);",
.placeholders = 13,
.name = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
.query = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);",
.placeholders = 14,
.readonly = false,
},
{
@ -1419,8 +1425,8 @@ struct db_query db_postgres_queries[] = {
.readonly = false,
},
{
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ? AND partid = ?",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = $1 AND partid = $2",
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? AND partid = ?",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = $1 AND partid = $2",
.placeholders = 2,
.readonly = true,
},
@ -1455,17 +1461,23 @@ struct db_query db_postgres_queries[] = {
.readonly = false,
},
{
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ?;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = $1;",
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ?;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = $1;",
.placeholders = 1,
.readonly = true,
},
{
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;",
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;",
.placeholders = 0,
.readonly = true,
},
{
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = ?;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = $1;",
.placeholders = 1,
.readonly = true,
},
{
.name = "DELETE FROM htlc_sigs WHERE channelid = ?",
.query = "DELETE FROM htlc_sigs WHERE channelid = $1",
@ -1744,10 +1756,10 @@ struct db_query db_postgres_queries[] = {
},
};
#define DB_POSTGRES_QUERY_COUNT 289
#define DB_POSTGRES_QUERY_COUNT 291
#endif /* HAVE_POSTGRES */
#endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */
// SHA256STAMP:83a4b63d1c5566db35ab00e9da60f6c98c04f8bd30800e51cce294dfcb49c9ec
// SHA256STAMP:682d4f3ac081ef003be6eba257a5e5e023fee5169592c760c8878288ee12f212

View File

@ -860,6 +860,12 @@ struct db_query db_sqlite3_queries[] = {
.placeholders = 0,
.readonly = false,
},
{
.name = "ALTER TABLE payments ADD COLUMN local_offer_id BLOB DEFAULT NULL;",
.query = "ALTER TABLE payments ADD COLUMN local_offer_id BLOB DEFAULT NULL;",
.placeholders = 0,
.readonly = false,
},
{
.name = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?",
.query = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?",
@ -1401,9 +1407,9 @@ struct db_query db_sqlite3_queries[] = {
.readonly = true,
},
{
.name = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
.query = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
.placeholders = 13,
.name = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
.query = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
.placeholders = 14,
.readonly = false,
},
{
@ -1419,8 +1425,8 @@ struct db_query db_sqlite3_queries[] = {
.readonly = false,
},
{
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ? AND partid = ?",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ? AND partid = ?",
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? AND partid = ?",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? AND partid = ?",
.placeholders = 2,
.readonly = true,
},
@ -1455,17 +1461,23 @@ struct db_query db_sqlite3_queries[] = {
.readonly = false,
},
{
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ?;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ?;",
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ?;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ?;",
.placeholders = 1,
.readonly = true,
},
{
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;",
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;",
.placeholders = 0,
.readonly = true,
},
{
.name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = ?;",
.query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = ?;",
.placeholders = 1,
.readonly = true,
},
{
.name = "DELETE FROM htlc_sigs WHERE channelid = ?",
.query = "DELETE FROM htlc_sigs WHERE channelid = ?",
@ -1744,10 +1756,10 @@ struct db_query db_sqlite3_queries[] = {
},
};
#define DB_SQLITE3_QUERY_COUNT 289
#define DB_SQLITE3_QUERY_COUNT 291
#endif /* HAVE_SQLITE3 */
#endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */
// SHA256STAMP:83a4b63d1c5566db35ab00e9da60f6c98c04f8bd30800e51cce294dfcb49c9ec
// SHA256STAMP:682d4f3ac081ef003be6eba257a5e5e023fee5169592c760c8878288ee12f212

View File

@ -306,7 +306,10 @@ bool invoices_create(struct invoices *invoices,
db_bind_json_escape(stmt, 4, label);
db_bind_u64(stmt, 5, expiry_time);
db_bind_text(stmt, 6, b11enc);
db_bind_text(stmt, 7, description);
if (!description)
db_bind_null(stmt, 7);
else
db_bind_text(stmt, 7, description);
db_bind_talarr(stmt, 8, features);
if (local_offer_id)
db_bind_sha256(stmt, 9, local_offer_id);

View File

@ -566,67 +566,71 @@ msgstr ""
msgid "ALTER TABLE invoices ADD COLUMN local_offer_id BLOB DEFAULT NULL;"
msgstr ""
#: wallet/db.c:895
#: wallet/db.c:670
msgid "ALTER TABLE payments ADD COLUMN local_offer_id BLOB DEFAULT NULL;"
msgstr ""
#: wallet/db.c:897
msgid "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?"
msgstr ""
#: wallet/db.c:995
#: wallet/db.c:997
msgid "SELECT version FROM version LIMIT 1"
msgstr ""
#: wallet/db.c:1053
#: wallet/db.c:1055
msgid "UPDATE version SET version=?;"
msgstr ""
#: wallet/db.c:1061
#: wallet/db.c:1063
msgid "INSERT INTO db_upgrades VALUES (?, ?);"
msgstr ""
#: wallet/db.c:1073
#: wallet/db.c:1075
msgid "SELECT intval FROM vars WHERE name = 'data_version'"
msgstr ""
#: wallet/db.c:1100
#: wallet/db.c:1102
msgid "SELECT intval FROM vars WHERE name= ? LIMIT 1"
msgstr ""
#: wallet/db.c:1116
#: wallet/db.c:1118
msgid "UPDATE vars SET intval=? WHERE name=?;"
msgstr ""
#: wallet/db.c:1125
#: wallet/db.c:1127
msgid "INSERT INTO vars (name, intval) VALUES (?, ?);"
msgstr ""
#: wallet/db.c:1139
#: wallet/db.c:1141
msgid "UPDATE channels SET feerate_base = ?, feerate_ppm = ?;"
msgstr ""
#: wallet/db.c:1160
#: wallet/db.c:1162
msgid "UPDATE channels SET our_funding_satoshi = funding_satoshi WHERE funder = 0;"
msgstr ""
#: wallet/db.c:1176
#: wallet/db.c:1178
msgid "SELECT type, keyindex, prev_out_tx, prev_out_index, channel_id, peer_id, commitment_point FROM outputs WHERE scriptpubkey IS NULL;"
msgstr ""
#: wallet/db.c:1238
#: wallet/db.c:1240
msgid "UPDATE outputs SET scriptpubkey = ? WHERE prev_out_tx = ? AND prev_out_index = ?"
msgstr ""
#: wallet/db.c:1263
#: wallet/db.c:1265
msgid "SELECT id, funding_tx_id, funding_tx_outnum FROM channels;"
msgstr ""
#: wallet/db.c:1282
#: wallet/db.c:1284
msgid "UPDATE channels SET full_channel_id = ? WHERE id = ?;"
msgstr ""
#: wallet/db.c:1305
#: wallet/db.c:1307
msgid "SELECT c.id, p.node_id, c.last_tx, c.funding_satoshi, c.fundingkey_remote, c.last_sig FROM channels c LEFT OUTER JOIN peers p ON p.id = c.peer_id;"
msgstr ""
#: wallet/db.c:1372
#: wallet/db.c:1374
msgid "UPDATE channels SET last_tx = ? WHERE id = ?;"
msgstr ""
@ -646,47 +650,47 @@ msgstr ""
msgid "INSERT INTO invoices ( payment_hash, payment_key, state , msatoshi, label, expiry_time , pay_index, msatoshi_received , paid_timestamp, bolt11, description, features, local_offer_id) VALUES ( ?, ?, ? , ?, ?, ? , NULL, NULL , NULL, ?, ?, ?, ?);"
msgstr ""
#: wallet/invoices.c:341
#: wallet/invoices.c:344
msgid "SELECT id FROM invoices WHERE label = ?;"
msgstr ""
#: wallet/invoices.c:363
#: wallet/invoices.c:366
msgid "SELECT id FROM invoices WHERE payment_hash = ?;"
msgstr ""
#: wallet/invoices.c:384
#: wallet/invoices.c:387
msgid "SELECT id FROM invoices WHERE payment_hash = ? AND state = ?;"
msgstr ""
#: wallet/invoices.c:408
#: wallet/invoices.c:411
msgid "DELETE FROM invoices WHERE id=?;"
msgstr ""
#: wallet/invoices.c:428
#: wallet/invoices.c:431
msgid "DELETE FROM invoices WHERE state = ? AND expiry_time <= ?;"
msgstr ""
#: wallet/invoices.c:442
#: wallet/invoices.c:445
msgid "SELECT state, payment_key, payment_hash, label, msatoshi, expiry_time, pay_index, msatoshi_received, paid_timestamp, bolt11, description, features FROM invoices ORDER BY id;"
msgstr ""
#: wallet/invoices.c:499
#: wallet/invoices.c:502
msgid "SELECT state FROM invoices WHERE id = ?;"
msgstr ""
#: wallet/invoices.c:517
#: wallet/invoices.c:520
msgid "SELECT local_offer_id FROM invoices WHERE id = ?;"
msgstr ""
#: wallet/invoices.c:549
#: wallet/invoices.c:552
msgid "UPDATE invoices SET state=? , pay_index=? , msatoshi_received=? , paid_timestamp=? WHERE id=?;"
msgstr ""
#: wallet/invoices.c:608
#: wallet/invoices.c:611
msgid "SELECT id FROM invoices WHERE pay_index IS NOT NULL AND pay_index > ? ORDER BY pay_index ASC LIMIT 1;"
msgstr ""
#: wallet/invoices.c:657
#: wallet/invoices.c:660
msgid "SELECT state, payment_key, payment_hash, label, msatoshi, expiry_time, pay_index, msatoshi_received, paid_timestamp, bolt11, description, features, local_offer_id FROM invoices WHERE id = ?;"
msgstr ""
@ -927,218 +931,222 @@ msgid "SELECT status FROM payments WHERE payment_hash=? AND partid = ?;"
msgstr ""
#: wallet/wallet.c:2484
msgid "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
msgid "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:2567
#: wallet/wallet.c:2573
msgid "DELETE FROM payments WHERE payment_hash = ? AND partid = ?"
msgstr ""
#: wallet/wallet.c:2581
#: wallet/wallet.c:2587
msgid "DELETE FROM payments WHERE payment_hash = ?"
msgstr ""
#: wallet/wallet.c:2676
msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ? AND partid = ?"
#: wallet/wallet.c:2688
msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? AND partid = ?"
msgstr ""
#: wallet/wallet.c:2725
#: wallet/wallet.c:2738
msgid "UPDATE payments SET status=? WHERE payment_hash=? AND partid=?"
msgstr ""
#: wallet/wallet.c:2735
#: wallet/wallet.c:2748
msgid "UPDATE payments SET payment_preimage=? WHERE payment_hash=? AND partid=?"
msgstr ""
#: wallet/wallet.c:2745
#: wallet/wallet.c:2758
msgid "UPDATE payments SET path_secrets = NULL , route_nodes = NULL , route_channels = NULL WHERE payment_hash = ? AND partid = ?;"
msgstr ""
#: wallet/wallet.c:2777
#: wallet/wallet.c:2790
msgid "SELECT failonionreply, faildestperm, failindex, failcode, failnode, failchannel, failupdate, faildetail, faildirection FROM payments WHERE payment_hash=? AND partid=?;"
msgstr ""
#: wallet/wallet.c:2844
#: wallet/wallet.c:2857
msgid "UPDATE payments SET failonionreply=? , faildestperm=? , failindex=? , failcode=? , failnode=? , failchannel=? , failupdate=? , faildetail=? , faildirection=? WHERE payment_hash=? AND partid=?;"
msgstr ""
#: wallet/wallet.c:2903
msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ?;"
#: wallet/wallet.c:2916
msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ?;"
msgstr ""
#: wallet/wallet.c:2924
msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;"
#: wallet/wallet.c:2938
msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;"
msgstr ""
#: wallet/wallet.c:2968
#: wallet/wallet.c:2989
msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = ?;"
msgstr ""
#: wallet/wallet.c:3034
msgid "DELETE FROM htlc_sigs WHERE channelid = ?"
msgstr ""
#: wallet/wallet.c:2975
#: wallet/wallet.c:3041
msgid "INSERT INTO htlc_sigs (channelid, signature) VALUES (?, ?)"
msgstr ""
#: wallet/wallet.c:2987
#: wallet/wallet.c:3053
msgid "SELECT blobval FROM vars WHERE name='genesis_hash'"
msgstr ""
#: wallet/wallet.c:3011
#: wallet/wallet.c:3077
msgid "INSERT INTO vars (name, blobval) VALUES ('genesis_hash', ?);"
msgstr ""
#: wallet/wallet.c:3027
#: wallet/wallet.c:3093
msgid "DELETE FROM utxoset WHERE spendheight < ?"
msgstr ""
#: wallet/wallet.c:3035 wallet/wallet.c:3145
#: wallet/wallet.c:3101 wallet/wallet.c:3211
msgid "INSERT INTO blocks (height, hash, prev_hash) VALUES (?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3054
#: wallet/wallet.c:3120
msgid "DELETE FROM blocks WHERE hash = ?"
msgstr ""
#: wallet/wallet.c:3060
#: wallet/wallet.c:3126
msgid "SELECT * FROM blocks WHERE height >= ?;"
msgstr ""
#: wallet/wallet.c:3069
#: wallet/wallet.c:3135
msgid "DELETE FROM blocks WHERE height > ?"
msgstr ""
#: wallet/wallet.c:3081
#: wallet/wallet.c:3147
msgid "UPDATE outputs SET spend_height = ?, status = ? WHERE prev_out_tx = ? AND prev_out_index = ?"
msgstr ""
#: wallet/wallet.c:3098
#: wallet/wallet.c:3164
msgid "UPDATE utxoset SET spendheight = ? WHERE txid = ? AND outnum = ?"
msgstr ""
#: wallet/wallet.c:3120 wallet/wallet.c:3156
#: wallet/wallet.c:3186 wallet/wallet.c:3222
msgid "INSERT INTO utxoset ( txid, outnum, blockheight, spendheight, txindex, scriptpubkey, satoshis) VALUES(?, ?, ?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3180
#: wallet/wallet.c:3246
msgid "SELECT height FROM blocks WHERE height = ?"
msgstr ""
#: wallet/wallet.c:3193
#: wallet/wallet.c:3259
msgid "SELECT txid, spendheight, scriptpubkey, satoshis FROM utxoset WHERE blockheight = ? AND txindex = ? AND outnum = ? AND spendheight IS NULL"
msgstr ""
#: wallet/wallet.c:3235
#: wallet/wallet.c:3301
msgid "SELECT blockheight, txindex, outnum FROM utxoset WHERE spendheight = ?"
msgstr ""
#: wallet/wallet.c:3266 wallet/wallet.c:3426
#: wallet/wallet.c:3332 wallet/wallet.c:3492
msgid "SELECT blockheight FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3276
#: wallet/wallet.c:3342
msgid "INSERT INTO transactions ( id, blockheight, txindex, rawtx) VALUES (?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3297
#: wallet/wallet.c:3363
msgid "UPDATE transactions SET blockheight = ?, txindex = ? WHERE id = ?"
msgstr ""
#: wallet/wallet.c:3314
#: wallet/wallet.c:3380
msgid "INSERT INTO transaction_annotations (txid, idx, location, type, channel) VALUES (?, ?, ?, ?, ?) ON CONFLICT(txid,idx) DO NOTHING;"
msgstr ""
#: wallet/wallet.c:3346
#: wallet/wallet.c:3412
msgid "SELECT type, channel_id FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3362
#: wallet/wallet.c:3428
msgid "UPDATE transactions SET type = ?, channel_id = ? WHERE id = ?"
msgstr ""
#: wallet/wallet.c:3381
#: wallet/wallet.c:3447
msgid "SELECT type FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3404
#: wallet/wallet.c:3470
msgid "SELECT rawtx FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3450
#: wallet/wallet.c:3516
msgid "SELECT blockheight, txindex FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3478
#: wallet/wallet.c:3544
msgid "SELECT id FROM transactions WHERE blockheight=?"
msgstr ""
#: wallet/wallet.c:3497
#: wallet/wallet.c:3563
msgid "INSERT INTO channeltxs ( channel_id, type, transaction_id, input_num, blockheight) VALUES (?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3521
#: wallet/wallet.c:3587
msgid "SELECT DISTINCT(channel_id) FROM channeltxs WHERE type = ?;"
msgstr ""
#: wallet/wallet.c:3542
#: wallet/wallet.c:3608
msgid "SELECT c.type, c.blockheight, t.rawtx, c.input_num, c.blockheight - t.blockheight + 1 AS depth, t.id as txid FROM channeltxs c JOIN transactions t ON t.id = c.transaction_id WHERE c.channel_id = ? ORDER BY c.id ASC;"
msgstr ""
#: wallet/wallet.c:3587
#: wallet/wallet.c:3653
msgid "UPDATE forwarded_payments SET in_msatoshi=?, out_msatoshi=?, state=?, resolved_time=?, failcode=? WHERE in_htlc_id=?"
msgstr ""
#: wallet/wallet.c:3645
#: wallet/wallet.c:3711
msgid "INSERT INTO forwarded_payments ( in_htlc_id, out_htlc_id, in_channel_scid, out_channel_scid, in_msatoshi, out_msatoshi, state, received_time, resolved_time, failcode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3704
#: wallet/wallet.c:3770
msgid "SELECT CAST(COALESCE(SUM(in_msatoshi - out_msatoshi), 0) AS BIGINT)FROM forwarded_payments WHERE state = ?;"
msgstr ""
#: wallet/wallet.c:3728
#: wallet/wallet.c:3794
msgid "SELECT f.state, in_msatoshi, out_msatoshi, hin.payment_hash as payment_hash, in_channel_scid, out_channel_scid, f.received_time, f.resolved_time, f.failcode FROM forwarded_payments f LEFT JOIN channel_htlcs hin ON (f.in_htlc_id = hin.id)"
msgstr ""
#: wallet/wallet.c:3816
#: wallet/wallet.c:3882
msgid "SELECT t.id, t.rawtx, t.blockheight, t.txindex, t.type as txtype, c2.short_channel_id as txchan, a.location, a.idx as ann_idx, a.type as annotation_type, c.short_channel_id FROM transactions t LEFT JOIN transaction_annotations a ON (a.txid = t.id) LEFT JOIN channels c ON (a.channel = c.id) LEFT JOIN channels c2 ON (t.channel_id = c2.id) ORDER BY t.blockheight, t.txindex ASC"
msgstr ""
#: wallet/wallet.c:3910
#: wallet/wallet.c:3976
msgid "INSERT INTO penalty_bases ( channel_id, commitnum, txid, outnum, amount) VALUES (?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3935
#: wallet/wallet.c:4001
msgid "SELECT commitnum, txid, outnum, amount FROM penalty_bases WHERE channel_id = ?"
msgstr ""
#: wallet/wallet.c:3959
#: wallet/wallet.c:4025
msgid "DELETE FROM penalty_bases WHERE channel_id = ? AND commitnum = ?"
msgstr ""
#: wallet/wallet.c:3977
#: wallet/wallet.c:4043
msgid "SELECT 1 FROM offers WHERE offer_id = ?;"
msgstr ""
#: wallet/wallet.c:3990
#: wallet/wallet.c:4056
msgid "INSERT INTO offers ( offer_id, bolt12, label, status) VALUES (?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:4018
#: wallet/wallet.c:4084
msgid "SELECT bolt12, label, status FROM offers WHERE offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4046
#: wallet/wallet.c:4112
msgid "SELECT offer_id FROM offers;"
msgstr ""
#: wallet/wallet.c:4072
#: wallet/wallet.c:4138
msgid "UPDATE offers SET status=? WHERE offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4083
#: wallet/wallet.c:4149
msgid "UPDATE invoices SET state=? WHERE state=? AND local_offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4111
#: wallet/wallet.c:4177
msgid "SELECT status FROM offers WHERE offer_id = ?;"
msgstr ""
@ -1153,4 +1161,4 @@ msgstr ""
#: wallet/test/run-wallet.c:1378
msgid "INSERT INTO channels (id) VALUES (1);"
msgstr ""
# SHA256STAMP:f7e6df1a958f5eeb00dd1ffb0221fab28816a4807908fe904ae913a248b0f98c
# SHA256STAMP:edc18cc0be69eb519707d9442372246c466d08ec7ed12f24584be19ae9032d9b