diff --git a/wallet/wallet.c b/wallet/wallet.c index 4048c2da6..f44c772b8 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1125,6 +1125,65 @@ bool wallet_htlcs_reconnect(struct wallet *wallet, return true; } +int wallet_invoice_nextpaid(const tal_t *cxt, + const struct wallet *wallet, + const char *labelz, + char **outlabel, + struct sha256 *outrhash, + u64 *outmsatoshi) +{ + sqlite3_stmt *stmt; + int res; + u64 pay_index; + + /* Generate query. */ + if (labelz) { + /* Find label. */ + stmt = db_prepare(wallet->db, + "SELECT pay_index FROM invoices WHERE label=?;"); + sqlite3_bind_text(stmt, 1, labelz, strlen(labelz), SQLITE_TRANSIENT); + res = sqlite3_step(stmt); + if (res != SQLITE_ROW) { + sqlite3_finalize(stmt); + return -1; + } + pay_index = sqlite3_column_int64(stmt, 0); + sqlite3_finalize(stmt); + + stmt = db_prepare(wallet->db, + "SELECT label, payment_hash, msatoshi FROM invoices" + " WHERE pay_index NOT NULL" + " AND pay_index > ?" + " ORDER BY pay_index ASC LIMIT 1;"); + sqlite3_bind_int64(stmt, 1, pay_index); + } else { + stmt = db_prepare(wallet->db, + "SELECT label, payment_hash, msatoshi FROM invoices" + " WHERE pay_index NOT NULL" + " ORDER BY pay_index ASC LIMIT 1;"); + } + + res = sqlite3_step(stmt); + if (res != SQLITE_ROW) { + /* No paid invoice found. */ + sqlite3_finalize(stmt); + return 0; + } else { + /* Paid invoice found, return data. */ + *outlabel = tal_strndup(cxt, sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0)); + + assert(sqlite3_column_bytes(stmt, 1) == sizeof(struct sha256)); + memcpy(outrhash, sqlite3_column_blob(stmt, 1), sqlite3_column_bytes(stmt, 1)); + + *outmsatoshi = sqlite3_column_int64(stmt, 2); + + sqlite3_finalize(stmt); + return 1; + } + + return -1; +} + /* Acquire the next pay_index. */ static s64 wallet_invoice_next_pay_index(struct db *db) { diff --git a/wallet/wallet.h b/wallet/wallet.h index 5c8ff2a62..ad911c1fa 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -330,6 +330,32 @@ bool wallet_htlcs_reconnect(struct wallet *wallet, struct htlc_in_map *htlcs_in, struct htlc_out_map *htlcs_out); +/** + * wallet_invoice_nextpaid -- Find a paid invoice. + * + * Get the details (label, rhash, msatoshi) of the next paid + * invoice after the invoice with the given label. If label is + * `NULL`, get the details of the first paid invoice. Return -1 + * if label is non-`NULL` and is not found, 0 if no more paid + * invoices after specified invoice (or no paid invoices if label + * is `NULL`), 1 if the next paid invoice was found. + * + * @ctx: Context to create the returned label. + * @wallet: Wallet to query + * @labelz: The label to be queried (zero-terminated), or + * `NULL` if first invoice is to be queried. + * @outlabel: Pointer to label of found paid invoice. Caller + * must free if this function returns 1. + * @outrhash: Pointer to struct rhash to be filled. + * @outmsatoshi: Pointer to number of millisatoshis value to pay. + */ +int wallet_invoice_nextpaid(const tal_t *cxt, + const struct wallet *wallet, + const char *labelz, + char **outlabel, + struct sha256 *outrhash, + u64 *outmsatoshi); + /** * wallet_invoice_save -- Save/update an invoice to the wallet *