mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-20 13:54:36 +01:00
offers: signatures are now optional.
As per latest spec revision. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-EXPERIMENTAL: BOLT12 offers can now be unsigned, for really short QR codes.
This commit is contained in:
parent
6336d39a95
commit
f9fe814ea3
20 changed files with 130 additions and 61 deletions
|
@ -166,27 +166,6 @@ struct tlv_offer *offer_decode(const tal_t *ctx,
|
|||
const struct feature_set *our_features,
|
||||
const struct chainparams *must_be_chain,
|
||||
char **fail)
|
||||
{
|
||||
struct tlv_offer *offer;
|
||||
|
||||
offer = offer_decode_nosig(ctx, b12, b12len,
|
||||
our_features, must_be_chain, fail);
|
||||
|
||||
if (offer) {
|
||||
*fail = check_signature(ctx, offer->fields,
|
||||
"offer", "signature",
|
||||
offer->node_id, offer->signature);
|
||||
if (*fail)
|
||||
offer = tal_free(offer);
|
||||
}
|
||||
return offer;
|
||||
}
|
||||
|
||||
struct tlv_offer *offer_decode_nosig(const tal_t *ctx,
|
||||
const char *b12, size_t b12len,
|
||||
const struct feature_set *our_features,
|
||||
const struct chainparams *must_be_chain,
|
||||
char **fail)
|
||||
{
|
||||
struct tlv_offer *offer = tlv_offer_new(ctx);
|
||||
const u8 *data;
|
||||
|
@ -208,6 +187,19 @@ struct tlv_offer *offer_decode_nosig(const tal_t *ctx,
|
|||
if (*fail)
|
||||
return tal_free(offer);
|
||||
|
||||
/* BOLT-offers #12:
|
||||
* - if `signature` is present, but is not a valid signature using
|
||||
* `node_id` as described in [Signature Calculation](#signature-calculation):
|
||||
* - MUST NOT respond to the offer.
|
||||
*/
|
||||
if (offer->signature) {
|
||||
*fail = check_signature(ctx, offer->fields,
|
||||
"offer", "signature",
|
||||
offer->node_id, offer->signature);
|
||||
if (*fail)
|
||||
return tal_free(offer);
|
||||
}
|
||||
|
||||
return offer;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,20 +33,13 @@ char *offer_encode(const tal_t *ctx, const struct tlv_offer *bolt12_tlv);
|
|||
* @must_be_chain: if non-NULL, chain to enforce.
|
||||
* @fail: pointer to descriptive error string, set if this returns NULL.
|
||||
*
|
||||
* Note: checks signature!
|
||||
* Note: checks signature if present.
|
||||
*/
|
||||
struct tlv_offer *offer_decode(const tal_t *ctx, const char *b12, size_t b12len,
|
||||
const struct feature_set *our_features,
|
||||
const struct chainparams *must_be_chain,
|
||||
char **fail);
|
||||
|
||||
/* Variant which does not check signature */
|
||||
struct tlv_offer *offer_decode_nosig(const tal_t *ctx,
|
||||
const char *b12, size_t b12len,
|
||||
const struct feature_set *our_features,
|
||||
const struct chainparams *must_be_chain,
|
||||
char **fail);
|
||||
|
||||
/**
|
||||
* invrequest_encode - encode this complete bolt12 invreq TLV into text.
|
||||
*/
|
||||
|
|
|
@ -481,8 +481,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
if (streq(hrp, "lno")) {
|
||||
const struct tlv_offer *offer
|
||||
= offer_decode_nosig(ctx, argv[2], strlen(argv[2]),
|
||||
NULL, NULL, &fail);
|
||||
= offer_decode(ctx, argv[2], strlen(argv[2]),
|
||||
NULL, NULL, &fail);
|
||||
if (!offer)
|
||||
errx(ERROR_BAD_DECODE, "Bad offer: %s", fail);
|
||||
|
||||
|
@ -517,7 +517,7 @@ int main(int argc, char *argv[])
|
|||
print_features(offer->features);
|
||||
if (offer->paths)
|
||||
print_blindedpaths(offer->paths, NULL);
|
||||
if (must_have(offer, signature) && offer->node_id)
|
||||
if (offer->signature && offer->node_id)
|
||||
well_formed &= print_signature("offer", "signature",
|
||||
offer->fields,
|
||||
offer->node_id,
|
||||
|
|
6
doc/lightning-decode.7
generated
6
doc/lightning-decode.7
generated
|
@ -35,10 +35,10 @@ If \fBtype\fR is "bolt12 offer", and \fBvalid\fR is \fItrue\fR:
|
|||
.IP \[bu]
|
||||
\fBnode_id\fR (pubkey32): x-only public key of the offering node
|
||||
.IP \[bu]
|
||||
\fBsignature\fR (bip340sig): BIP-340 signature of the \fInode_id\fR on this offer
|
||||
.IP \[bu]
|
||||
\fBdescription\fR (string): the description of the purpose of the offer
|
||||
.IP \[bu]
|
||||
\fBsignature\fR (bip340sig, optional): BIP-340 signature of the \fInode_id\fR on this offer
|
||||
.IP \[bu]
|
||||
\fBchains\fR (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only):
|
||||
.RS
|
||||
.IP \[bu]
|
||||
|
@ -414,4 +414,4 @@ Rusty Russell \fI<rusty@rustcorp.com.au\fR> is mainly responsible\.
|
|||
|
||||
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
||||
|
||||
\" SHA256STAMP:045cd00ad893483df132bdffd913049bfe43acb152a511accc9f17f87ba06a8d
|
||||
\" SHA256STAMP:cd54af7c631f06b3db72848cdf90951ceb14d89b8bca981dba69244cd2ddbae5
|
||||
|
|
|
@ -27,8 +27,8 @@ On success, an object is returned, containing:
|
|||
If **type** is "bolt12 offer", and **valid** is *true*:
|
||||
- **offer_id** (hex): the id of this offer (merkle hash of non-signature fields) (always 64 characters)
|
||||
- **node_id** (pubkey32): x-only public key of the offering node
|
||||
- **signature** (bip340sig): BIP-340 signature of the *node_id* on this offer
|
||||
- **description** (string): the description of the purpose of the offer
|
||||
- **signature** (bip340sig, optional): BIP-340 signature of the *node_id* on this offer
|
||||
- **chains** (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only):
|
||||
- the genesis blockhash (always 64 characters)
|
||||
- **currency** (string, optional): ISO 4217 code of the currency (missing implies Bitcoin) (always 3 characters)
|
||||
|
@ -183,4 +183,4 @@ RESOURCES
|
|||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
|
||||
[comment]: # ( SHA256STAMP:f0adee97f3b5776059252703efee1b8e244c1141f9f3dd5fe73e3d7ed4d59ab4)
|
||||
[comment]: # ( SHA256STAMP:8ca0b9178b8ea6575cd80291001263dc27f721664648086a7c1a02efcb545ee7)
|
||||
|
|
4
doc/lightning-disableoffer.7
generated
4
doc/lightning-disableoffer.7
generated
|
@ -48,6 +48,8 @@ On success, an object is returned, containing:
|
|||
.IP \[bu]
|
||||
\fBbolt12\fR (string): The bolt12 string representing this offer
|
||||
.IP \[bu]
|
||||
\fBbolt12_unsigned\fR (string): The bolt12 string representing this offer, without signature
|
||||
.IP \[bu]
|
||||
\fBused\fR (boolean): Whether the offer has had an invoice paid / payment made
|
||||
.IP \[bu]
|
||||
\fBlabel\fR (string, optional): The label provided when offer was created
|
||||
|
@ -78,4 +80,4 @@ Rusty Russell \fI<rusty@rustcorp.com.au\fR> is mainly responsible\.
|
|||
|
||||
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
||||
|
||||
\" SHA256STAMP:03b1a12409ad02eca1543d99bafdfbd2d7d2c869e182fba513e3f93fb48a7664
|
||||
\" SHA256STAMP:2383f44a3bcc1023d6619f5ead4c27d7b2bd9a52bd64d00142fd26658a49dd32
|
||||
|
|
|
@ -40,6 +40,7 @@ On success, an object is returned, containing:
|
|||
- **active** (boolean): Whether the offer can produce invoices/payments (always "false")
|
||||
- **single_use** (boolean): Whether the offer is disabled after first successful use
|
||||
- **bolt12** (string): The bolt12 string representing this offer
|
||||
- **bolt12_unsigned** (string): The bolt12 string representing this offer, without signature
|
||||
- **used** (boolean): Whether the offer has had an invoice paid / payment made
|
||||
- **label** (string, optional): The label provided when offer was created
|
||||
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||
|
@ -72,4 +73,4 @@ RESOURCES
|
|||
---------
|
||||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
[comment]: # ( SHA256STAMP:abf340bf35dcefd42fba609b3ae95adb2f74bb5766c68e174a9b8f9114c80202)
|
||||
[comment]: # ( SHA256STAMP:5b96eca3e35f6c556b93db1743c617b59e69058c9421ece9cc99a9c8814c176b)
|
||||
|
|
4
doc/lightning-listoffers.7
generated
4
doc/lightning-listoffers.7
generated
|
@ -41,6 +41,8 @@ On success, an object containing \fBoffers\fR is returned\. It is an array of o
|
|||
.IP \[bu]
|
||||
\fBbolt12\fR (string): the bolt12 encoding of the offer
|
||||
.IP \[bu]
|
||||
\fBbolt12_unsigned\fR (string): the bolt12 encoding of the offer, without signature
|
||||
.IP \[bu]
|
||||
\fBused\fR (boolean): True if an associated invoice has been paid
|
||||
.IP \[bu]
|
||||
\fBlabel\fR (string, optional): the (optional) user-specified label
|
||||
|
@ -82,4 +84,4 @@ Rusty Russell \fI<rusty@rustcorp.com.au\fR> is mainly responsible\.
|
|||
|
||||
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
||||
|
||||
\" SHA256STAMP:7e359219084e648a629b0d43774db17bbfbe693074b817fa5890b7c8bccd1429
|
||||
\" SHA256STAMP:bf83e52cc56aaef876eb1039a6fbbcd9d2e15703c54f33163176c7ba41523261
|
||||
|
|
|
@ -35,6 +35,7 @@ On success, an object containing **offers** is returned. It is an array of obje
|
|||
- **active** (boolean): whether this can still be used
|
||||
- **single_use** (boolean): whether this expires as soon as it's paid
|
||||
- **bolt12** (string): the bolt12 encoding of the offer
|
||||
- **bolt12_unsigned** (string): the bolt12 encoding of the offer, without signature
|
||||
- **used** (boolean): True if an associated invoice has been paid
|
||||
- **label** (string, optional): the (optional) user-specified label
|
||||
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||
|
@ -78,4 +79,4 @@ RESOURCES
|
|||
---------
|
||||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
[comment]: # ( SHA256STAMP:58e9f5aa5808e19e3be151b1c1f1215ec23953b60ab294418aa57426c5bcbd46)
|
||||
[comment]: # ( SHA256STAMP:e2b8508c98e6161c45fca91bceb273e6c2865cec0e1761dde85f8f2dd6670491)
|
||||
|
|
9
doc/lightning-offer.7
generated
9
doc/lightning-offer.7
generated
|
@ -15,6 +15,11 @@ creating one or more invoices\. It automatically enables the processing of
|
|||
an incoming invoice_request, and issuing of invoices\.
|
||||
|
||||
|
||||
Note that it creates two variants of the offer: a signed and an
|
||||
unsigned one (which is smaller)\. Wallets should accept both: the
|
||||
current specification allows either\.
|
||||
|
||||
|
||||
The \fIamount\fR parameter can be the string "any", which creates an offer
|
||||
that can be paid with any amount (e\.g\. a donation)\. Otherwise it can
|
||||
be a positive value in millisatoshi precision; it can be a whole
|
||||
|
@ -112,6 +117,8 @@ On success, an object is returned, containing:
|
|||
.IP \[bu]
|
||||
\fBbolt12\fR (string): the bolt12 encoding of the offer
|
||||
.IP \[bu]
|
||||
\fBbolt12_unsigned\fR (string): the bolt12 encoding of the offer, without a signature
|
||||
.IP \[bu]
|
||||
\fBused\fR (boolean): True if an associated invoice has been paid (always \fIfalse\fR)
|
||||
.IP \[bu]
|
||||
\fBlabel\fR (string, optional): the (optional) user-specified label
|
||||
|
@ -145,4 +152,4 @@ Rusty Russell \fI<rusty@rustcorp.com.au\fR> is mainly responsible\.
|
|||
|
||||
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
||||
|
||||
\" SHA256STAMP:fdc65b544ee660ef7afafb13bc727b859411df072739c4b22973fbc870d785f2
|
||||
\" SHA256STAMP:f7faf86c7cb052200c3b4d6e3d6209afa54600cc7a33e1082583a2766d02a275
|
||||
|
|
|
@ -15,6 +15,10 @@ The **offer** RPC command creates an offer, which is a precursor to
|
|||
creating one or more invoices. It automatically enables the processing of
|
||||
an incoming invoice_request, and issuing of invoices.
|
||||
|
||||
Note that it creates two variants of the offer: a signed and an
|
||||
unsigned one (which is smaller). Wallets should accept both: the
|
||||
current specification allows either.
|
||||
|
||||
The *amount* parameter can be the string "any", which creates an offer
|
||||
that can be paid with any amount (e.g. a donation). Otherwise it can
|
||||
be a positive value in millisatoshi precision; it can be a whole
|
||||
|
@ -95,6 +99,7 @@ On success, an object is returned, containing:
|
|||
- **active** (boolean): whether this can still be used (always *true*)
|
||||
- **single_use** (boolean): whether this expires as soon as it's paid (reflects the *single_use* parameter)
|
||||
- **bolt12** (string): the bolt12 encoding of the offer
|
||||
- **bolt12_unsigned** (string): the bolt12 encoding of the offer, without a signature
|
||||
- **used** (boolean): True if an associated invoice has been paid (always *false*)
|
||||
- **label** (string, optional): the (optional) user-specified label
|
||||
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||
|
@ -123,4 +128,4 @@ RESOURCES
|
|||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
|
||||
[comment]: # ( SHA256STAMP:20c0be7bad73fcf71ccae61c2c5a112c8602216d9d2e9f647f8273fdf4e3ed8b)
|
||||
[comment]: # ( SHA256STAMP:0f9cfd3cc68aaba20af0eee763c93b475016619d960e3f5bbc0b762a809f0fef)
|
||||
|
|
9
doc/lightning-offerout.7
generated
9
doc/lightning-offerout.7
generated
|
@ -17,6 +17,11 @@ offer)\. It automatically enables the accepting and payment of
|
|||
corresponding invoice message (we will only pay once, however!)\.
|
||||
|
||||
|
||||
Note that it creates two variants of the offer: a signed and an
|
||||
unsigned one (which is smaller)\. Wallets should accept both: the
|
||||
current specification allows either\.
|
||||
|
||||
|
||||
The \fIamount\fR parameter can be the string "any", which creates an offer
|
||||
that can be paid with any amount (e\.g\. a donation)\. Otherwise it can
|
||||
be a positive value in millisatoshi precision; it can be a whole
|
||||
|
@ -64,6 +69,8 @@ On success, an object is returned, containing:
|
|||
.IP \[bu]
|
||||
\fBbolt12\fR (string): the bolt12 encoding of the offer
|
||||
.IP \[bu]
|
||||
\fBbolt12_unsigned\fR (string): the bolt12 encoding of the offer, without a signature
|
||||
.IP \[bu]
|
||||
\fBused\fR (boolean): True if an incoming invoice has been paid (always \fIfalse\fR)
|
||||
.IP \[bu]
|
||||
\fBlabel\fR (string, optional): the (optional) user-specified label
|
||||
|
@ -106,4 +113,4 @@ Rusty Russell \fI<rusty@rustcorp.com.au\fR> is mainly responsible\.
|
|||
|
||||
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
||||
|
||||
\" SHA256STAMP:823219aff5dc06ab3b810442048b6cf733210c3eae80567327dc396e5f7987c8
|
||||
\" SHA256STAMP:3de11c6de7905322d9ef748981fc1d4f9ca91f4be46d76af6e9124572853047d
|
||||
|
|
|
@ -18,6 +18,10 @@ send an invoice for us to pay (technically, this is referred to as a
|
|||
offer). It automatically enables the accepting and payment of
|
||||
corresponding invoice message (we will only pay once, however!).
|
||||
|
||||
Note that it creates two variants of the offer: a signed and an
|
||||
unsigned one (which is smaller). Wallets should accept both: the
|
||||
current specification allows either.
|
||||
|
||||
The *amount* parameter can be the string "any", which creates an offer
|
||||
that can be paid with any amount (e.g. a donation). Otherwise it can
|
||||
be a positive value in millisatoshi precision; it can be a whole
|
||||
|
@ -55,6 +59,7 @@ On success, an object is returned, containing:
|
|||
- **active** (boolean): whether this will pay a matching incoming invoice (always *true*)
|
||||
- **single_use** (boolean): whether this expires as soon as it's paid out (always *true*)
|
||||
- **bolt12** (string): the bolt12 encoding of the offer
|
||||
- **bolt12_unsigned** (string): the bolt12 encoding of the offer, without a signature
|
||||
- **used** (boolean): True if an incoming invoice has been paid (always *false*)
|
||||
- **label** (string, optional): the (optional) user-specified label
|
||||
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||
|
@ -92,4 +97,4 @@ RESOURCES
|
|||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
|
||||
[comment]: # ( SHA256STAMP:6db3fdba07f376e697326b3bf1bd74c013084a459cb9f4fe76d23fce58bd58fe)
|
||||
[comment]: # ( SHA256STAMP:2b7e7b543a88a10dbfbca2508e034af79f43ed0845abdb9df1fdf7e28ee33c26)
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
}
|
||||
},
|
||||
"then": {
|
||||
"required": [ "offer_id", "node_id", "signature", "description" ],
|
||||
"required": [ "offer_id", "node_id", "description" ],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": { },
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"required": [ "offer_id", "active", "single_use", "bolt12", "used" ],
|
||||
"required": [ "offer_id", "active", "single_use", "bolt12", "bolt12_unsigned", "used" ],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"offer_id": {
|
||||
|
@ -23,6 +23,10 @@
|
|||
"type": "string",
|
||||
"description": "The bolt12 string representing this offer"
|
||||
},
|
||||
"bolt12_unsigned": {
|
||||
"type": "string",
|
||||
"description": "The bolt12 string representing this offer, without signature"
|
||||
},
|
||||
"used": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the offer has had an invoice paid / payment made"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [ "offer_id", "active", "single_use", "bolt12", "used" ],
|
||||
"required": [ "offer_id", "active", "single_use", "bolt12", "bolt12_unsigned", "used" ],
|
||||
"properties": {
|
||||
"offer_id": {
|
||||
"type": "hex",
|
||||
|
@ -29,6 +29,10 @@
|
|||
"type": "string",
|
||||
"description": "the bolt12 encoding of the offer"
|
||||
},
|
||||
"bolt12_unsigned": {
|
||||
"type": "string",
|
||||
"description": "the bolt12 encoding of the offer, without signature"
|
||||
},
|
||||
"used": {
|
||||
"type": "boolean",
|
||||
"description": "True if an associated invoice has been paid"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [ "offer_id", "active", "single_use", "bolt12", "used" ],
|
||||
"required": [ "offer_id", "active", "single_use", "bolt12", "bolt12_unsigned", "used" ],
|
||||
"properties": {
|
||||
"offer_id": {
|
||||
"type": "hex",
|
||||
|
@ -23,6 +23,10 @@
|
|||
"type": "string",
|
||||
"description": "the bolt12 encoding of the offer"
|
||||
},
|
||||
"bolt12_unsigned": {
|
||||
"type": "string",
|
||||
"description": "the bolt12 encoding of the offer, without a signature"
|
||||
},
|
||||
"used": {
|
||||
"type": "boolean",
|
||||
"enum": [ false ],
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [ "offer_id", "active", "single_use", "bolt12", "used" ],
|
||||
"required": [ "offer_id", "active", "single_use", "bolt12", "bolt12_unsigned", "used" ],
|
||||
"properties": {
|
||||
"offer_id": {
|
||||
"type": "hex",
|
||||
|
@ -24,6 +24,10 @@
|
|||
"type": "string",
|
||||
"description": "the bolt12 encoding of the offer"
|
||||
},
|
||||
"bolt12_unsigned": {
|
||||
"type": "string",
|
||||
"description": "the bolt12 encoding of the offer, without a signature"
|
||||
},
|
||||
"used": {
|
||||
"type": "boolean",
|
||||
"enum": [ false ],
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
static void json_populate_offer(struct json_stream *response,
|
||||
const struct sha256 *offer_id,
|
||||
const char *b12,
|
||||
const char *b12_nosig,
|
||||
const struct json_escape *label,
|
||||
enum offer_status status)
|
||||
{
|
||||
|
@ -21,6 +22,8 @@ static void json_populate_offer(struct json_stream *response,
|
|||
json_add_bool(response, "active", offer_status_active(status));
|
||||
json_add_bool(response, "single_use", offer_status_single(status));
|
||||
json_add_string(response, "bolt12", b12);
|
||||
if (b12_nosig)
|
||||
json_add_string(response, "bolt12_unsigned", b12_nosig);
|
||||
json_add_bool(response, "used", offer_status_used(status));
|
||||
if (label)
|
||||
json_add_escaped_string(response, "label", label);
|
||||
|
@ -33,9 +36,9 @@ static struct command_result *param_b12_offer(struct command *cmd,
|
|||
struct tlv_offer **offer)
|
||||
{
|
||||
char *fail;
|
||||
*offer = offer_decode_nosig(cmd, buffer + tok->start,
|
||||
tok->end - tok->start,
|
||||
cmd->ld->our_features, chainparams, &fail);
|
||||
*offer = offer_decode(cmd, buffer + tok->start,
|
||||
tok->end - tok->start,
|
||||
cmd->ld->our_features, chainparams, &fail);
|
||||
if (!*offer)
|
||||
return command_fail_badparam(cmd, name, buffer, tok, fail);
|
||||
if ((*offer)->signature)
|
||||
|
@ -83,7 +86,7 @@ static struct command_result *json_createoffer(struct command *cmd,
|
|||
struct json_escape *label;
|
||||
struct tlv_offer *offer;
|
||||
struct sha256 merkle;
|
||||
const char *b12str;
|
||||
const char *b12str, *b12str_nosig;
|
||||
bool *single_use;
|
||||
enum offer_status status;
|
||||
struct pubkey32 key;
|
||||
|
@ -112,9 +115,11 @@ static struct command_result *json_createoffer(struct command *cmd,
|
|||
OFFER_ALREADY_EXISTS,
|
||||
"Duplicate offer");
|
||||
}
|
||||
offer->signature = tal_free(offer->signature);
|
||||
b12str_nosig = offer_encode(cmd, offer);
|
||||
|
||||
response = json_stream_success(cmd);
|
||||
json_populate_offer(response, &merkle, b12str, label, status);
|
||||
json_populate_offer(response, &merkle, b12str, b12str_nosig, label, status);
|
||||
return command_success(cmd, response);
|
||||
}
|
||||
|
||||
|
@ -126,6 +131,25 @@ static const struct json_command createoffer_command = {
|
|||
};
|
||||
AUTODATA(json_command, &createoffer_command);
|
||||
|
||||
/* We store strings in the db, so removing signatures is easiest by conversion */
|
||||
static const char *offer_str_nosig(const tal_t *ctx,
|
||||
struct lightningd *ld,
|
||||
const char *b12str)
|
||||
{
|
||||
char *fail;
|
||||
struct tlv_offer *offer = offer_decode(tmpctx, b12str, strlen(b12str),
|
||||
ld->our_features, chainparams,
|
||||
&fail);
|
||||
|
||||
if (!offer) {
|
||||
log_broken(ld->log, "Cannot reparse offerstr from db %s: %s",
|
||||
b12str, fail);
|
||||
return NULL;
|
||||
}
|
||||
offer->signature = tal_free(offer->signature);
|
||||
return offer_encode(ctx, offer);
|
||||
}
|
||||
|
||||
static struct command_result *json_listoffers(struct command *cmd,
|
||||
const char *buffer,
|
||||
const jsmntok_t *obj UNNEEDED,
|
||||
|
@ -153,7 +177,9 @@ static struct command_result *json_listoffers(struct command *cmd,
|
|||
if (b12 && offer_status_active(status) >= *active_only) {
|
||||
json_object_start(response, NULL);
|
||||
json_populate_offer(response,
|
||||
offer_id, b12, label, status);
|
||||
offer_id, b12,
|
||||
offer_str_nosig(tmpctx, cmd->ld, b12),
|
||||
label, status);
|
||||
json_object_end(response);
|
||||
}
|
||||
} else {
|
||||
|
@ -168,7 +194,10 @@ static struct command_result *json_listoffers(struct command *cmd,
|
|||
if (offer_status_active(status) >= *active_only) {
|
||||
json_object_start(response, NULL);
|
||||
json_populate_offer(response,
|
||||
&id, b12, label, status);
|
||||
&id, b12,
|
||||
offer_str_nosig(tmpctx,
|
||||
cmd->ld, b12),
|
||||
label, status);
|
||||
json_object_end(response);
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +242,10 @@ static struct command_result *json_disableoffer(struct command *cmd,
|
|||
status = wallet_offer_disable(wallet, offer_id, status);
|
||||
|
||||
response = json_stream_success(cmd);
|
||||
json_populate_offer(response, offer_id, b12, label, status);
|
||||
json_populate_offer(response, offer_id, b12,
|
||||
offer_str_nosig(tmpctx,
|
||||
cmd->ld, b12),
|
||||
label, status);
|
||||
return command_success(cmd, response);
|
||||
}
|
||||
|
||||
|
|
|
@ -3823,6 +3823,7 @@ def test_offer(node_factory, bitcoind):
|
|||
offer = only_one(l1.rpc.call('listoffers', [ret['offer_id']])['offers'])
|
||||
|
||||
assert offer['bolt12'] == ret['bolt12']
|
||||
assert offer['bolt12_unsigned'] == ret['bolt12_unsigned']
|
||||
assert offer['offer_id'] == ret['offer_id']
|
||||
|
||||
output = subprocess.check_output([bolt12tool, 'decode',
|
||||
|
@ -3831,6 +3832,12 @@ def test_offer(node_factory, bitcoind):
|
|||
assert 'amount' not in output
|
||||
else:
|
||||
assert 'amount' in output
|
||||
output = subprocess.check_output([bolt12tool, 'decode',
|
||||
offer['bolt12_unsigned']]).decode('ASCII')
|
||||
if amount == 'any':
|
||||
assert 'amount' not in output
|
||||
else:
|
||||
assert 'amount' in output
|
||||
|
||||
# Try wrong amount precision:
|
||||
with pytest.raises(RpcError, match='Currency AUD requires 2 minor units'):
|
||||
|
@ -3985,7 +3992,7 @@ 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']})
|
||||
inv2 = l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12_unsigned']})
|
||||
assert inv1 != inv2
|
||||
assert 'next_period' not in inv1
|
||||
assert 'next_period' not in inv2
|
||||
|
@ -4244,9 +4251,8 @@ def test_sendinvoice(node_factory, bitcoind):
|
|||
assert only_one(l1.rpc.call('listoffers', [offer['offer_id']])['offers'])['used'] is False
|
||||
|
||||
# sendinvoice should work.
|
||||
out = l2.rpc.call('sendinvoice', {'offer': offer['bolt12'],
|
||||
out = l2.rpc.call('sendinvoice', {'offer': offer['bolt12_unsigned'],
|
||||
'label': 'test sendinvoice 1'})
|
||||
print(out)
|
||||
assert out['label'] == 'test sendinvoice 1'
|
||||
assert out['description'] == 'simple test'
|
||||
assert 'bolt12' in out
|
||||
|
|
Loading…
Add table
Reference in a new issue