Skip to content

Commit

Permalink
invoices: display the payer note if it's for local offer, allow in fe…
Browse files Browse the repository at this point in the history
…tchinvoice.

We don't do it for sendinvoice (yet?).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: `fetchinvoice` can take a payer note, and `listinvoice` will show the payer_notes received.
  • Loading branch information
rustyrussell committed Jul 2, 2021
1 parent febeb60 commit 40e8a20
Show file tree
Hide file tree
Showing 12 changed files with 59 additions and 9 deletions.
4 changes: 3 additions & 1 deletion doc/lightning-createinvoice.7

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion doc/lightning-createinvoice.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ On success, an object is returned, containing:
- **paid_at** (u64, optional): UNIX timestamp of when invoice was paid (**status** *paid* only)
- **payment_preimage** (hex, optional): the proof of payment: SHA256 of this **payment_hash** (always 64 characters)
- **local_offer_id** (hex, optional): the *id* of our offer which created this invoice (**experimental-offers** only). (always 64 characters)
- **payer_note** (string, optional): the optional *payer_note* from invoice_request which created this invoice (**experimental-offers** only).
[comment]: # (GENERATE-FROM-SCHEMA-END)

On failure, an error is returned and no invoice is created. If the
Expand Down Expand Up @@ -72,4 +73,4 @@ RESOURCES

Main web site: <https://github.com/ElementsProject/lightning>

[comment]: # ( SHA256STAMP:948d344d5f589050127bd5181689882c6fad036799fa6ff039a83194ff5fd098)
[comment]: # ( SHA256STAMP:72b3b200462e9e16c72dd5e3281d35d9ec2eded62e6a7d87e9361573c85dcc32)
4 changes: 3 additions & 1 deletion doc/lightning-delinvoice.7

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion doc/lightning-delinvoice.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ On success, an object is returned, containing:

If **bolt12** is present:
- **local_offer_id** (hex, optional): offer for which this invoice was created
- **payer_note** (string, optional): the optional *payer_note* from invoice_request which created this invoice

If **status** is "paid":
- **pay_index** (u64): unique index for this invoice payment
Expand Down Expand Up @@ -71,4 +72,4 @@ RESOURCES

Main web site: <https://github.com/ElementsProject/lightning>

[comment]: # ( SHA256STAMP:62a3bdd502ed0b3b555f3cfda6a0e5f7c2417ce0f5b23202d613216de58a23f3)
[comment]: # ( SHA256STAMP:65c14a16b939461a06d81b0ff41e976ea4c7bf963cccdeba47739fe9ca1658a1)
4 changes: 3 additions & 1 deletion doc/lightning-listinvoices.7

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion doc/lightning-listinvoices.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ On success, an object containing **invoices** is returned. It is an array of ob
- **bolt11** (string, optional): the BOLT11 string (always present unless *bolt12* is)
- **bolt12** (string, optional): the BOLT12 string (always present unless *bolt11* is)
- **local_offer_id** (hex, optional): the *id* of our offer which created this invoice (**experimental-offers** only). (always 64 characters)
- **payer_note** (string, optional): the optional *payer_note* from invoice_request which created this invoice (**experimental-offers** only).

If **status** is "paid":
- **pay_index** (u64): Unique incrementing index for this payment
Expand All @@ -54,4 +55,4 @@ RESOURCES

Main web site: <https://github.com/ElementsProject/lightning>

[comment]: # ( SHA256STAMP:cc6d7b4549d2ab905ab18041f34d13143e4ffed2bb6cc7c1df0307800e59a2fa)
[comment]: # ( SHA256STAMP:99dd5cb3f84e8201903e531b601a04dafde3f6eae3f582b538caea7fac20aad0)
4 changes: 4 additions & 0 deletions doc/schemas/createinvoice.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
"description": "the *id* of our offer which created this invoice (**experimental-offers** only).",
"maxLength": 64,
"minLength": 64
},
"payer_note": {
"type": "string",
"description": "the optional *payer_note* from invoice_request which created this invoice (**experimental-offers** only)."
}
}
}
6 changes: 6 additions & 0 deletions doc/schemas/delinvoice.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@
"local_offer_id": {
"type": "hex",
"description": "offer for which this invoice was created"
},
"payer_note": {
"type": "string",
"description": "the optional *payer_note* from invoice_request which created this invoice"
}
}
},
Expand Down Expand Up @@ -111,6 +115,7 @@
"amount_msat": { },
"description": { },
"payment_hash": { },
"payer_note": { },
"local_offer_id": { },
"pay_index": {
"type": "u64",
Expand Down Expand Up @@ -145,6 +150,7 @@
"payment_hash": { },
"expires_at": { },
"pay_index": { },
"payer_note": { },
"local_offer_id": { }
}
}
Expand Down
6 changes: 6 additions & 0 deletions doc/schemas/listinvoices.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
"description": "the *id* of our offer which created this invoice (**experimental-offers** only).",
"maxLength": 64,
"minLength": 64
},
"payer_note": {
"type": "string",
"description": "the optional *payer_note* from invoice_request which created this invoice (**experimental-offers** only)."
}
},
"allOf": [
Expand All @@ -79,6 +83,7 @@
"bolt11": { },
"bolt12": { },
"local_offer_id": { },
"payer_note": { },
"expires_at": { },
"pay_index": {
"type": "u64",
Expand Down Expand Up @@ -115,6 +120,7 @@
"bolt11": { },
"bolt12": { },
"local_offer_id": { },
"payer_note": { },
"expires_at": { }
}
}
Expand Down
16 changes: 15 additions & 1 deletion lightningd/invoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,22 @@ static void json_add_invoice(struct json_stream *response,
json_add_string(response, "description", inv->description);

json_add_u64(response, "expires_at", inv->expiry_time);
if (inv->local_offer_id)
if (inv->local_offer_id) {
char *fail;
struct tlv_invoice *tinv;

json_add_sha256(response, "local_offer_id", inv->local_offer_id);

/* Everyone loves seeing their own payer notes!
* Well: they will. Trust me. */
tinv = invoice_decode(tmpctx,
inv->invstring, strlen(inv->invstring),
NULL, NULL, &fail);
if (tinv && tinv->payer_note)
json_add_stringn(response, "payer_note",
tinv->payer_note,
tal_bytelen(tinv->payer_note));
}
}

static struct command_result *tell_waiter(struct command *cmd,
Expand Down
9 changes: 8 additions & 1 deletion plugins/fetchinvoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ static struct command_result *json_fetchinvoice(struct command *cmd,
const jsmntok_t *params)
{
struct amount_msat *msat;
const char *rec_label;
const char *rec_label, *payer_note;
struct out_req *req;
struct tlv_invoice_request *invreq;
struct sent *sent = tal(cmd, struct sent);
Expand All @@ -847,6 +847,7 @@ static struct command_result *json_fetchinvoice(struct command *cmd,
&invreq->recurrence_start),
p_opt("recurrence_label", param_string, &rec_label),
p_opt_def("timeout", param_number, &timeout, 60),
p_opt("payer_note", param_string, &payer_note),
NULL))
return command_param_failed();

Expand Down Expand Up @@ -997,6 +998,12 @@ static struct command_result *json_fetchinvoice(struct command *cmd,
invreq->features
= plugin_feature_set(cmd->plugin)->bits[BOLT11_FEATURE];

/* invreq->payer_note is not a nul-terminated string! */
if (payer_note)
invreq->payer_note = tal_dup_arr(invreq, utf8,
payer_note, strlen(payer_note),
0);

/* Make the invoice request (fills in payer_key and payer_info) */
req = jsonrpc_request_start(cmd->plugin, cmd, "createinvoicerequest",
&invreq_done,
Expand Down
6 changes: 5 additions & 1 deletion tests/test_pay.py
Original file line number Diff line number Diff line change
Expand Up @@ -3992,7 +3992,8 @@ def test_fetchinvoice(node_factory, bitcoind):
'description': 'simple test'})

inv1 = l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12']})
inv2 = l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12_unsigned']})
inv2 = l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12_unsigned'],
'payer_note': 'Thanks for the fish!'})
assert inv1 != inv2
assert 'next_period' not in inv1
assert 'next_period' not in inv2
Expand All @@ -4005,6 +4006,9 @@ def test_fetchinvoice(node_factory, bitcoind):
# listinvoices will show these on l3
assert [x['local_offer_id'] for x in l3.rpc.listinvoices()['invoices']] == [offer1['offer_id'], offer1['offer_id']]

assert 'payer_note' not in only_one(l3.rpc.call('listinvoices', {'invstring': inv1['invoice']})['invoices'])
assert only_one(l3.rpc.call('listinvoices', {'invstring': inv2['invoice']})['invoices'])['payer_note'] == 'Thanks for the fish!'

# We can also set the amount explicitly, to tip.
inv1 = l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12'], 'msatoshi': 3})
assert l1.rpc.call('decode', [inv1['invoice']])['amount_msat'] == 3
Expand Down

0 comments on commit 40e8a20

Please sign in to comment.