Skip to content

Commit 6f0dbbb

Browse files
bolt12: allow to inject payer_metadata
Payer metadata is a field that controls the payer ID provided during the fetchinvoice process. There are use cases where this is highly useful, such as proving that the payer has paid for the correct item. Imagine visiting a merchant's website to pay for multiple offers, where one of these offers is a default offer (with no description and no set amount). In this scenario, the merchant could claim not to have received payment for a specific item. Since the same offer may be used to fetch invoices for different products, there needs to be a way to identify which product the invoice corresponds to. With this commit, it will be possible to inject payer metadata, which helps solve the issue described above. For example, possible payer metadata could be `to_hex(b"{payer_node_id}.{product_id}.{created_at}")`. Changelog-Added: JSON-RPC: `fetchinvoice` allows setting invreq_metadata via `payer_metadata` parameter. Signed-off-by: Vincenzo Palazzo <[email protected]>
1 parent d27aa98 commit 6f0dbbb

File tree

9 files changed

+569
-534
lines changed

9 files changed

+569
-534
lines changed

.msggen.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,7 @@
12481248
"FetchinvoiceRequest": {
12491249
"FetchInvoice.amount_msat": 2,
12501250
"FetchInvoice.offer": 1,
1251+
"FetchInvoice.payer_metadata": 9,
12511252
"FetchInvoice.payer_note": 8,
12521253
"FetchInvoice.quantity": 3,
12531254
"FetchInvoice.recurrence_counter": 4,
@@ -5609,6 +5610,10 @@
56095610
"added": "pre-v0.10.1",
56105611
"deprecated": null
56115612
},
5613+
"FetchInvoice.payer_metadata": {
5614+
"added": "v24.11",
5615+
"deprecated": null
5616+
},
56125617
"FetchInvoice.payer_note": {
56135618
"added": "pre-v0.10.1",
56145619
"deprecated": null

cln-grpc/proto/node.proto

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cln-grpc/src/convert.rs

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cln-rpc/src/model.rs

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contrib/msggen/msggen/schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13425,6 +13425,13 @@
1342513425
"To ask the issuer to include in the fetched invoice."
1342613426
]
1342713427
},
13428+
"payer_metadata": {
13429+
"type": "string",
13430+
"description": [
13431+
"Derive the payer_id from the specified payer_metadata. Please be sure that `payer_metdata` can not be derived by anyone, so put some secret into it."
13432+
],
13433+
"added": "v24.11"
13434+
},
1342813435
"dev_reply_path": {
1342913436
"hidden": true
1343013437
},

contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py

Lines changed: 526 additions & 526 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/schemas/lightning-fetchinvoice.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@
6262
"To ask the issuer to include in the fetched invoice."
6363
]
6464
},
65+
"payer_metadata": {
66+
"type": "string",
67+
"description": [
68+
"Derive the payer_id from the specified payer_metadata. Please be sure that `payer_metdata` can not be derived by anyone, so put some secret into it."
69+
],
70+
"added": "v24.11"
71+
},
6572
"dev_reply_path": {
6673
"hidden": true
6774
},

lightningd/offer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ static struct command_result *prev_payment(struct command *cmd,
376376
" label and offer");
377377
}
378378

379+
/* FIXME(vincenzopalazzo): move this to comm/bolt12.h */
379380
static struct command_result *param_b12_invreq(struct command *cmd,
380381
const char *name,
381382
const char *buffer,

plugins/fetchinvoice.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ struct command_result *json_fetchinvoice(struct command *cmd,
819819
{
820820
struct amount_msat *msat;
821821
const char *rec_label, *payer_note;
822+
u8 *payer_metadata;
822823
struct out_req *req;
823824
struct tlv_invoice_request *invreq;
824825
struct sent *sent = tal(cmd, struct sent);
@@ -835,6 +836,7 @@ struct command_result *json_fetchinvoice(struct command *cmd,
835836
p_opt("recurrence_label", param_string, &rec_label),
836837
p_opt_def("timeout", param_number, &timeout, 60),
837838
p_opt("payer_note", param_string, &payer_note),
839+
p_opt("payer_metadata", param_bin_from_hex, &payer_metadata),
838840
p_opt("dev_path_use_scidd", param_dev_scidd, &sent->dev_path_use_scidd),
839841
p_opt("dev_reply_path", param_dev_reply_path, &sent->dev_reply_path),
840842
NULL))
@@ -938,6 +940,10 @@ struct command_result *json_fetchinvoice(struct command *cmd,
938940
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
939941
"needs recurrence_counter");
940942

943+
if (payer_metadata)
944+
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
945+
"Cannot set payer_metadata for recurring offers");
946+
941947
/* BOLT-offers-recurrence #12:
942948
* - if the offer contained `recurrence_base` with
943949
* `start_any_period` non-zero:
@@ -998,13 +1004,18 @@ struct command_result *json_fetchinvoice(struct command *cmd,
9981004
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
9991005
"unnecessary recurrence_start");
10001006

1001-
/* BOLT-offers #12:
1002-
* - MUST set `invreq_metadata` to an unpredictable series of
1003-
* bytes.
1004-
*/
1005-
invreq->invreq_metadata = tal_arr(invreq, u8, 16);
1006-
randombytes_buf(invreq->invreq_metadata,
1007-
tal_bytelen(invreq->invreq_metadata));
1007+
/* if the payer force to use the payer_metadata */
1008+
if (payer_metadata) {
1009+
invreq->invreq_metadata = tal_steal(invreq, payer_metadata);
1010+
} else {
1011+
/* BOLT-offers #12:
1012+
* - MUST set `invreq_metadata` to an unpredictable series of
1013+
* bytes.
1014+
*/
1015+
invreq->invreq_metadata = tal_arr(invreq, u8, 16);
1016+
randombytes_buf(invreq->invreq_metadata,
1017+
tal_bytelen(invreq->invreq_metadata));
1018+
}
10081019
}
10091020

10101021
/* We derive transient payer_id from invreq_metadata */
@@ -1044,7 +1055,6 @@ struct command_result *json_fetchinvoice(struct command *cmd,
10441055
payer_note,
10451056
strlen(payer_note),
10461057
0);
1047-
10481058
/* Make the invoice request (fills in payer_key and payer_info) */
10491059
req = jsonrpc_request_start(cmd, "createinvoicerequest",
10501060
&invreq_done,

0 commit comments

Comments
 (0)