BOLTs: update to more recent bolt12 spec.

It's 2b7ad577d7a790b302bd1aa044b22c809c76e49d, which reverts the
point32 changes.

It also restores send_invoice in `invoice`, which we had removed
from spec and put into the recurrence patch.

I originally had implemented compatibility, but other changes
which followed this are far too widespread.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: offers: complete rework of spec from other teams (yay!) breaks previous compatibility (boo!)
This commit is contained in:
Rusty Russell
2022-10-17 11:07:05 +10:30
parent eac8401f84
commit e30ea91908
17 changed files with 89 additions and 193 deletions

View File

@@ -74,7 +74,7 @@ static char *check_features_and_chain(const tal_t *ctx,
bool bolt12_check_signature(const struct tlv_field *fields, bool bolt12_check_signature(const struct tlv_field *fields,
const char *messagename, const char *messagename,
const char *fieldname, const char *fieldname,
const struct point32 *key, const struct pubkey *key,
const struct bip340sig *sig) const struct bip340sig *sig)
{ {
struct sha256 m, shash; struct sha256 m, shash;
@@ -89,7 +89,7 @@ static char *check_signature(const tal_t *ctx,
const struct tlv_field *fields, const struct tlv_field *fields,
const char *messagename, const char *messagename,
const char *fieldname, const char *fieldname,
const struct point32 *node_id, const struct pubkey *node_id,
const struct bip340sig *sig) const struct bip340sig *sig)
{ {
if (!node_id) if (!node_id)

View File

@@ -96,7 +96,7 @@ struct tlv_invoice *invoice_decode_nosig(const tal_t *ctx,
bool bolt12_check_signature(const struct tlv_field *fields, bool bolt12_check_signature(const struct tlv_field *fields,
const char *messagename, const char *messagename,
const char *fieldname, const char *fieldname,
const struct point32 *key, const struct pubkey *key,
const struct bip340sig *sig); const struct bip340sig *sig);
/* Given a single bolt12 chain, does it match? (NULL == bitcoin) */ /* Given a single bolt12 chain, does it match? (NULL == bitcoin) */

View File

@@ -310,8 +310,8 @@ int main(int argc, char *argv[])
/* Now try with an actual offer, with 6 fields. */ /* Now try with an actual offer, with 6 fields. */
struct tlv_offer *offer = offer_decode(tmpctx, struct tlv_offer *offer = offer_decode(tmpctx,
"lno1qcp4256ypqpq86q2pucnq42ngssx2an9wfujqerp0y2pqun4wd68jtn00fkxzcnn9ehhyec6qgqsz83qfwdpl28qqmc78ymlvhmxcsywdk5wrjnj36jryg488qwlrnzyjczs", "lno1qcp4256ypqpq86q2pucnq42ngssx2an9wfujqerp0y2pqun4wd68jtn00fkxzcnn9ehhyec6qgqsz83pqf9e58aguqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2",
strlen("lno1qcp4256ypqpq86q2pucnq42ngssx2an9wfujqerp0y2pqun4wd68jtn00fkxzcnn9ehhyec6qgqsz83qfwdpl28qqmc78ymlvhmxcsywdk5wrjnj36jryg488qwlrnzyjczs"), strlen("lno1qcp4256ypqpq86q2pucnq42ngssx2an9wfujqerp0y2pqun4wd68jtn00fkxzcnn9ehhyec6qgqsz83pqf9e58aguqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2"),
NULL, NULL, &fail); NULL, NULL, &fail);
assert(tal_count(offer->fields) == 6); assert(tal_count(offer->fields) == 6);
@@ -327,10 +327,10 @@ int main(int argc, char *argv[])
fieldwires[3] = tlv(20, "rusty.ozlabs.org", strlen("rusty.ozlabs.org")); fieldwires[3] = tlv(20, "rusty.ozlabs.org", strlen("rusty.ozlabs.org"));
/* recurrence: time_unit = 1, period = 1 */ /* recurrence: time_unit = 1, period = 1 */
fieldwires[4] = tlv(26, "\x01\x01", 2); fieldwires[4] = tlv(26, "\x01\x01", 2);
/* node_id: 4b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605 */ /* node_id: 024b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605 */
fieldwires[5] = tlv(30, "\x4b\x9a\x1f\xa8\xe0\x06\xf1\xe3\x93\x7f\x65\xf6\x6c\x40\x8e\x6d\xa8\xe1\xca\x72\x8e\xa4\x32\x22\xa7\x38\x1d\xf1\xcc\x44\x96\x05", 32); fieldwires[5] = tlv(30, "\x02\x4b\x9a\x1f\xa8\xe0\x06\xf1\xe3\x93\x7f\x65\xf6\x6c\x40\x8e\x6d\xa8\xe1\xca\x72\x8e\xa4\x32\x22\xa7\x38\x1d\xf1\xcc\x44\x96\x05", 33);
json_out("{\"comment\": \"offer test, currency = USD, amount = 1000, description = 10USD every day, issuer = rusty.ozlabs.org, recurrence = time_unit = 1, period = 1, node_id = 4b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605\","); json_out("{\"comment\": \"offer test, currency = USD, amount = 1000, description = 10USD every day, issuer = rusty.ozlabs.org, recurrence = time_unit = 1, period = 1, node_id = 024b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605\",");
json_out("\"tlv\": \"offer\","); json_out("\"tlv\": \"offer\",");
all = concat(fieldwires[0], fieldwires[1], fieldwires[2], all = concat(fieldwires[0], fieldwires[1], fieldwires[2],

View File

@@ -152,9 +152,9 @@ static void print_issuer(const char *issuer)
printf("issuer: %.*s\n", (int)tal_bytelen(issuer), issuer); printf("issuer: %.*s\n", (int)tal_bytelen(issuer), issuer);
} }
static void print_node_id(const struct point32 *node_id) static void print_node_id(const struct pubkey *node_id)
{ {
printf("node_id: %s\n", type_to_string(tmpctx, struct point32, node_id)); printf("node_id: %s\n", type_to_string(tmpctx, struct pubkey, node_id));
} }
static void print_quantity_min(u64 min) static void print_quantity_min(u64 min)
@@ -307,7 +307,7 @@ static void print_refund_for(const struct sha256 *payment_hash)
static bool print_signature(const char *messagename, static bool print_signature(const char *messagename,
const char *fieldname, const char *fieldname,
const struct tlv_field *fields, const struct tlv_field *fields,
const struct point32 *node_id, const struct pubkey *node_id,
const struct bip340sig *sig) const struct bip340sig *sig)
{ {
struct sha256 m, shash; struct sha256 m, shash;
@@ -363,11 +363,11 @@ static bool print_recurrence_counter_with_base(const u32 *recurrence_counter,
return true; return true;
} }
static void print_payer_key(const struct point32 *payer_key, static void print_payer_key(const struct pubkey *payer_key,
const u8 *payer_info) const u8 *payer_info)
{ {
printf("payer_key: %s", printf("payer_key: %s",
type_to_string(tmpctx, struct point32, payer_key)); type_to_string(tmpctx, struct pubkey, payer_key));
if (payer_info) if (payer_info)
printf(" (payer_info %s)", tal_hex(tmpctx, payer_info)); printf(" (payer_info %s)", tal_hex(tmpctx, payer_info));
printf("\n"); printf("\n");

View File

@@ -30,7 +30,7 @@ On success, an object is returned, containing:
If **type** is "bolt12 offer", and **valid** is *true*: 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) - **offer\_id** (hex): the id of this offer (merkle hash of non-signature fields) (always 64 characters)
- **node\_id** (point32): x-only public key of the offering node - **node\_id** (pubkey): public key of the offering node
- **description** (string): the description of the purpose of the offer - **description** (string): the description of the purpose of the offer
- **signature** (bip340sig, optional): BIP-340 signature of the *node_id* on this 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): - **chains** (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only):
@@ -72,7 +72,7 @@ If **type** is "bolt12 offer", and **valid** is *false*:
If **type** is "bolt12 invoice", and **valid** is *true*: If **type** is "bolt12 invoice", and **valid** is *true*:
- **node\_id** (point32): x-only public key of the offering node - **node\_id** (pubkey): public key of the offering node
- **signature** (bip340sig): BIP-340 signature of the *node_id* on this offer - **signature** (bip340sig): BIP-340 signature of the *node_id* on this offer
- **amount\_msat** (msat): the amount in bitcoin - **amount\_msat** (msat): the amount in bitcoin
- **description** (string): the description of the purpose of the offer - **description** (string): the description of the purpose of the offer
@@ -95,7 +95,7 @@ If **type** is "bolt12 invoice", and **valid** is *true*:
- **recurrence\_counter** (u32, optional): the 0-based counter for a recurring payment - **recurrence\_counter** (u32, optional): the 0-based counter for a recurring payment
- **recurrence\_start** (u32, optional): the optional start period for a recurring payment - **recurrence\_start** (u32, optional): the optional start period for a recurring payment
- **recurrence\_basetime** (u32, optional): the UNIX timestamp of the first recurrence period start - **recurrence\_basetime** (u32, optional): the UNIX timestamp of the first recurrence period start
- **payer\_key** (point32, optional): the transient key which identifies the payer - **payer\_key** (pubkey, optional): the transient key which identifies the payer
- **payer\_info** (hex, optional): the payer-provided blob to derive payer_key - **payer\_info** (hex, optional): the payer-provided blob to derive payer_key
- **fallbacks** (array of objects, optional): onchain addresses: - **fallbacks** (array of objects, optional): onchain addresses:
- **version** (u8): Segwit address version - **version** (u8): Segwit address version
@@ -123,7 +123,7 @@ If **type** is "bolt12 invoice", and **valid** is *false*:
If **type** is "bolt12 invoice_request", and **valid** is *true*: If **type** is "bolt12 invoice_request", and **valid** is *true*:
- **offer\_id** (hex): the id of the offer this is requesting (merkle hash of non-signature fields) (always 64 characters) - **offer\_id** (hex): the id of the offer this is requesting (merkle hash of non-signature fields) (always 64 characters)
- **payer\_key** (point32): the transient key which identifies the payer - **payer\_key** (pubkey): the transient key which identifies the payer
- **chain** (hex, optional): which blockchain this invoice_request is for (missing implies bitcoin mainnet only) (always 64 characters) - **chain** (hex, optional): which blockchain this invoice_request is for (missing implies bitcoin mainnet only) (always 64 characters)
- **amount\_msat** (msat, optional): the amount in bitcoin - **amount\_msat** (msat, optional): the amount in bitcoin
- **features** (hex, optional): the array of feature bits for this offer - **features** (hex, optional): the array of feature bits for this offer
@@ -211,4 +211,4 @@ RESOURCES
Main web site: <https://github.com/ElementsProject/lightning> Main web site: <https://github.com/ElementsProject/lightning>
[comment]: # ( SHA256STAMP:610b6f9d61e79b503ff81cc164f79ea90883c6d10f5e7b28555aefabfd6e17bb) [comment]: # ( SHA256STAMP:3348f74162c4a2737f1bc50f1903e7e25484747a1bc9ba7d3cd3f30b57589fdf)

View File

@@ -57,8 +57,8 @@
"minLength": 64 "minLength": 64
}, },
"node_id": { "node_id": {
"type": "point32", "type": "pubkey",
"description": "x-only public key of the offering node" "description": "public key of the offering node"
}, },
"signature": { "signature": {
"type": "bip340sig", "type": "bip340sig",
@@ -325,8 +325,8 @@
"minLength": 64 "minLength": 64
}, },
"node_id": { "node_id": {
"type": "point32", "type": "pubkey",
"description": "x-only public key of the offering node" "description": "public key of the offering node"
}, },
"signature": { "signature": {
"type": "bip340sig", "type": "bip340sig",
@@ -424,7 +424,7 @@
"description": "the UNIX timestamp of the first recurrence period start" "description": "the UNIX timestamp of the first recurrence period start"
}, },
"payer_key": { "payer_key": {
"type": "point32", "type": "pubkey",
"description": "the transient key which identifies the payer" "description": "the transient key which identifies the payer"
}, },
"payer_info": { "payer_info": {
@@ -652,7 +652,7 @@
"description": "the optional start period for a recurring payment" "description": "the optional start period for a recurring payment"
}, },
"payer_key": { "payer_key": {
"type": "point32", "type": "pubkey",
"description": "the transient key which identifies the payer" "description": "the transient key which identifies the payer"
}, },
"payer_info": { "payer_info": {

View File

@@ -57,7 +57,7 @@ static void hsm_sign_b12(struct lightningd *ld,
const char *fieldname, const char *fieldname,
const struct sha256 *merkle, const struct sha256 *merkle,
const u8 *publictweak, const u8 *publictweak,
const struct point32 *key, const struct pubkey *key,
struct bip340sig *sig) struct bip340sig *sig)
{ {
u8 *msg; u8 *msg;
@@ -93,7 +93,7 @@ static struct command_result *json_createoffer(struct command *cmd,
const char *b12str, *b12str_nosig; const char *b12str, *b12str_nosig;
bool *single_use; bool *single_use;
enum offer_status status; enum offer_status status;
struct point32 key; struct pubkey key;
bool created; bool created;
if (!param(cmd, buffer, params, if (!param(cmd, buffer, params,
@@ -109,7 +109,7 @@ static struct command_result *json_createoffer(struct command *cmd,
status = OFFER_MULTIPLE_USE_UNUSED; status = OFFER_MULTIPLE_USE_UNUSED;
merkle_tlv(offer->fields, &merkle); merkle_tlv(offer->fields, &merkle);
offer->signature = tal(offer, struct bip340sig); offer->signature = tal(offer, struct bip340sig);
if (!point32_from_node_id(&key, &cmd->ld->id)) if (!pubkey_from_node_id(&key, &cmd->ld->id))
fatal("invalid own node_id?"); fatal("invalid own node_id?");
hsm_sign_b12(cmd->ld, "offer", "signature", &merkle, NULL, &key, hsm_sign_b12(cmd->ld, "offer", "signature", &merkle, NULL, &key,
offer->signature); offer->signature);
@@ -393,14 +393,14 @@ static struct command_result *param_b12_invreq(struct command *cmd,
static bool payer_key(struct lightningd *ld, static bool payer_key(struct lightningd *ld,
const u8 *public_tweak, size_t public_tweak_len, const u8 *public_tweak, size_t public_tweak_len,
struct point32 *key) struct pubkey *key)
{ {
struct sha256 tweakhash; struct sha256 tweakhash;
payer_key_tweak(&ld->bolt12_base, public_tweak, public_tweak_len, payer_key_tweak(&ld->bolt12_base, public_tweak, public_tweak_len,
&tweakhash); &tweakhash);
key->pubkey = ld->bolt12_base.pubkey; *key = ld->bolt12_base;
return secp256k1_ec_pubkey_tweak_add(secp256k1_ctx, return secp256k1_ec_pubkey_tweak_add(secp256k1_ctx,
&key->pubkey, &key->pubkey,
tweakhash.u.u8) == 1; tweakhash.u.u8) == 1;
@@ -452,7 +452,7 @@ static struct command_result *json_createinvoicerequest(struct command *cmd,
tal_bytelen(invreq->payer_info)); tal_bytelen(invreq->payer_info));
} }
invreq->payer_key = tal(invreq, struct point32); invreq->payer_key = tal(invreq, struct pubkey);
if (!payer_key(cmd->ld, if (!payer_key(cmd->ld,
invreq->payer_info, tal_bytelen(invreq->payer_info), invreq->payer_info, tal_bytelen(invreq->payer_info),
invreq->payer_key)) { invreq->payer_key)) {
@@ -500,7 +500,7 @@ static struct command_result *json_payersign(struct command *cmd,
u8 *tweak; u8 *tweak;
struct bip340sig sig; struct bip340sig sig;
const char *messagename, *fieldname; const char *messagename, *fieldname;
struct point32 key; struct pubkey key;
if (!param(cmd, buffer, params, if (!param(cmd, buffer, params,
p_req("messagename", param_string, &messagename), p_req("messagename", param_string, &messagename),

View File

@@ -204,7 +204,7 @@ static struct command_result *handle_invreq_response(struct command *cmd,
/* BOLT-offers #12: /* BOLT-offers #12:
* - MUST reject the invoice unless `node_id` is equal to the offer. * - MUST reject the invoice unless `node_id` is equal to the offer.
*/ */
if (!point32_eq(sent->offer->node_id, inv->node_id)) { if (!pubkey_eq(sent->offer->node_id, inv->node_id)) {
badfield = "node_id"; badfield = "node_id";
goto badinv; goto badinv;
} }
@@ -556,41 +556,9 @@ static bool can_carry_onionmsg(const struct gossmap *map,
|| gossmap_node_get_feature(map, n, 102) != -1; || gossmap_node_get_feature(map, n, 102) != -1;
} }
enum nodeid_parity {
nodeid_parity_even = SECP256K1_TAG_PUBKEY_EVEN,
nodeid_parity_odd = SECP256K1_TAG_PUBKEY_ODD,
nodeid_parity_unknown = 1,
};
static enum nodeid_parity node_parity(const struct gossmap *gossmap,
const struct gossmap_node *node)
{
struct node_id id;
gossmap_node_get_id(gossmap, node, &id);
return id.k[0];
}
static void node_id_from_point32(struct node_id *nid,
const struct point32 *node32_id,
enum nodeid_parity parity)
{
struct pubkey pk;
assert(parity == SECP256K1_TAG_PUBKEY_EVEN
|| parity == SECP256K1_TAG_PUBKEY_ODD);
pk.pubkey = node32_id->pubkey;
node_id_from_pubkey(nid, &pk);
nid->k[0] = parity;
}
/* Create path to node which can carry onion messages (including
* self); if it can't find one, returns NULL. Fills in nodeid_parity
* for 33rd nodeid byte. */
static struct pubkey *path_to_node(const tal_t *ctx, static struct pubkey *path_to_node(const tal_t *ctx,
struct plugin *plugin, struct plugin *plugin,
const struct point32 *node32_id, const struct pubkey *node_id)
enum nodeid_parity *parity)
{ {
struct route_hop *r; struct route_hop *r;
const struct dijkstra *dij; const struct dijkstra *dij;
@@ -600,21 +568,10 @@ static struct pubkey *path_to_node(const tal_t *ctx,
struct pubkey *nodes; struct pubkey *nodes;
struct gossmap *gossmap = get_gossmap(plugin); struct gossmap *gossmap = get_gossmap(plugin);
/* We try both parities. */ node_id_from_pubkey(&dstid, node_id);
*parity = nodeid_parity_even;
node_id_from_point32(&dstid, node32_id, *parity);
dst = gossmap_find_node(gossmap, &dstid); dst = gossmap_find_node(gossmap, &dstid);
if (!dst) { if (!dst)
*parity = nodeid_parity_odd;
node_id_from_point32(&dstid, node32_id, *parity);
dst = gossmap_find_node(gossmap, &dstid);
if (!dst) {
*parity = nodeid_parity_unknown;
return NULL; return NULL;
}
}
*parity = node_parity(gossmap, dst);
/* If we don't exist in gossip, routing can't happen. */ /* If we don't exist in gossip, routing can't happen. */
node_id_from_pubkey(&local_nodeid, &local_id); node_id_from_pubkey(&local_nodeid, &local_id);
@@ -857,41 +814,11 @@ static struct command_result *connect_failed(struct command *command,
NULL); NULL);
} }
/* Offers contain only a 32-byte id. If we can't find the address, we
* don't know if it's 02 or 03, so we try both. If we're here, we
* failed 02. */
static struct command_result *try_other_parity(struct command *cmd,
const char *buf,
const jsmntok_t *result,
struct connect_attempt *ca)
{
struct out_req *req;
/* Flip parity */
ca->node_id.k[0] = SECP256K1_TAG_PUBKEY_ODD;
/* Path is us -> them, so they're second entry */
if (!pubkey_from_node_id(&ca->sent->path[1], &ca->node_id)) {
/* Should not happen!
* Pieter Wuille points out:
* y^2 = x^3 + 7 mod p
* negating y doesnt change the left hand side
*/
return command_done_err(cmd, LIGHTNINGD,
"Failed: could not convert inverted pubkey?",
NULL);
}
req = jsonrpc_request_start(cmd->plugin, cmd, "connect", connected,
connect_failed, ca);
json_add_node_id(req->js, "id", &ca->node_id);
return send_outreq(cmd->plugin, req);
}
/* We can't find a route, so we're going to try to connect, then just blast it /* We can't find a route, so we're going to try to connect, then just blast it
* to them. */ * to them. */
static struct command_result * static struct command_result *
connect_direct(struct command *cmd, connect_direct(struct command *cmd,
const struct point32 *dst, const struct pubkey *dst,
enum nodeid_parity parity,
struct command_result *(*cb)(struct command *command, struct command_result *(*cb)(struct command *command,
const char *buf, const char *buf,
const jsmntok_t *result, const jsmntok_t *result,
@@ -903,20 +830,7 @@ connect_direct(struct command *cmd,
ca->cb = cb; ca->cb = cb;
ca->sent = sent; ca->sent = sent;
node_id_from_pubkey(&ca->node_id, dst);
if (parity == nodeid_parity_unknown) {
plugin_notify_message(cmd, LOG_INFORM,
"Cannot find route, trying connect to 02/03%s directly",
type_to_string(tmpctx, struct point32, dst));
/* Try even first. */
node_id_from_point32(&ca->node_id, dst, SECP256K1_TAG_PUBKEY_EVEN);
} else {
plugin_notify_message(cmd, LOG_INFORM,
"Cannot find route, trying connect to %02x%s directly",
parity,
type_to_string(tmpctx, struct point32, dst));
node_id_from_point32(&ca->node_id, dst, parity);
}
/* Make a direct path -> dst. */ /* Make a direct path -> dst. */
sent->path = tal_arr(sent, struct pubkey, 2); sent->path = tal_arr(sent, struct pubkey, 2);
@@ -934,14 +848,13 @@ connect_direct(struct command *cmd,
"Cannot find route, but" "Cannot find route, but"
" fetchplugin-noconnect set:" " fetchplugin-noconnect set:"
" trying direct anyway to %s", " trying direct anyway to %s",
type_to_string(tmpctx, struct point32, type_to_string(tmpctx, struct pubkey,
dst)); dst));
return cb(cmd, NULL, NULL, sent); return cb(cmd, NULL, NULL, sent);
} }
req = jsonrpc_request_start(cmd->plugin, cmd, "connect", connected, req = jsonrpc_request_start(cmd->plugin, cmd, "connect", connected,
parity == nodeid_parity_unknown ? connect_failed, ca);
try_other_parity : connect_failed, ca);
json_add_node_id(req->js, "id", &ca->node_id); json_add_node_id(req->js, "id", &ca->node_id);
return send_outreq(cmd->plugin, req); return send_outreq(cmd->plugin, req);
} }
@@ -953,7 +866,6 @@ static struct command_result *invreq_done(struct command *cmd,
{ {
const jsmntok_t *t; const jsmntok_t *t;
char *fail; char *fail;
enum nodeid_parity parity;
/* Get invoice request */ /* Get invoice request */
t = json_get_member(buf, result, "bolt12"); t = json_get_member(buf, result, "bolt12");
@@ -1047,10 +959,9 @@ static struct command_result *invreq_done(struct command *cmd,
} }
sent->path = path_to_node(sent, cmd->plugin, sent->path = path_to_node(sent, cmd->plugin,
sent->offer->node_id, sent->offer->node_id);
&parity);
if (!sent->path) if (!sent->path)
return connect_direct(cmd, sent->offer->node_id, parity, return connect_direct(cmd, sent->offer->node_id,
sendinvreq_after_connect, sent); sendinvreq_after_connect, sent);
return sendinvreq_after_connect(cmd, NULL, NULL, sent); return sendinvreq_after_connect(cmd, NULL, NULL, sent);
@@ -1065,7 +976,6 @@ force_payer_secret(struct command *cmd,
const struct secret *payer_secret) const struct secret *payer_secret)
{ {
struct sha256 merkle, sha; struct sha256 merkle, sha;
enum nodeid_parity parity;
secp256k1_keypair kp; secp256k1_keypair kp;
u8 *msg; u8 *msg;
const u8 *p; const u8 *p;
@@ -1074,7 +984,7 @@ force_payer_secret(struct command *cmd,
if (secp256k1_keypair_create(secp256k1_ctx, &kp, payer_secret->data) != 1) if (secp256k1_keypair_create(secp256k1_ctx, &kp, payer_secret->data) != 1)
return command_fail(cmd, LIGHTNINGD, "Bad payer_secret"); return command_fail(cmd, LIGHTNINGD, "Bad payer_secret");
invreq->payer_key = tal(invreq, struct point32); invreq->payer_key = tal(invreq, struct pubkey);
/* Docs say this only happens if arguments are invalid! */ /* Docs say this only happens if arguments are invalid! */
if (secp256k1_keypair_pub(secp256k1_ctx, if (secp256k1_keypair_pub(secp256k1_ctx,
&invreq->payer_key->pubkey, &invreq->payer_key->pubkey,
@@ -1107,10 +1017,9 @@ force_payer_secret(struct command *cmd,
} }
sent->path = path_to_node(sent, cmd->plugin, sent->path = path_to_node(sent, cmd->plugin,
sent->offer->node_id, sent->offer->node_id);
&parity);
if (!sent->path) if (!sent->path)
return connect_direct(cmd, sent->offer->node_id, parity, return connect_direct(cmd, sent->offer->node_id,
sendinvreq_after_connect, sent); sendinvreq_after_connect, sent);
return sendinvreq_after_connect(cmd, NULL, NULL, sent); return sendinvreq_after_connect(cmd, NULL, NULL, sent);
@@ -1384,7 +1293,6 @@ static struct command_result *createinvoice_done(struct command *cmd,
{ {
const jsmntok_t *invtok = json_get_member(buf, result, "bolt12"); const jsmntok_t *invtok = json_get_member(buf, result, "bolt12");
char *fail; char *fail;
enum nodeid_parity parity;
/* Replace invoice with signed one */ /* Replace invoice with signed one */
tal_free(sent->inv); tal_free(sent->inv);
@@ -1405,10 +1313,9 @@ static struct command_result *createinvoice_done(struct command *cmd,
} }
sent->path = path_to_node(sent, cmd->plugin, sent->path = path_to_node(sent, cmd->plugin,
sent->offer->node_id, sent->offer->node_id);
&parity);
if (!sent->path) if (!sent->path)
return connect_direct(cmd, sent->offer->node_id, parity, return connect_direct(cmd, sent->offer->node_id,
sendinvoice_after_connect, sent); sendinvoice_after_connect, sent);
return sendinvoice_after_connect(cmd, NULL, NULL, sent); return sendinvoice_after_connect(cmd, NULL, NULL, sent);
@@ -1585,7 +1492,7 @@ static struct command_result *json_sendinvoice(struct command *cmd,
* - MUST set `node_id` to the id of the node to send payment to. * - MUST set `node_id` to the id of the node to send payment to.
* - MUST set `description` the same as the offer. * - MUST set `description` the same as the offer.
*/ */
sent->inv->node_id = tal(sent->inv, struct point32); sent->inv->node_id = tal(sent->inv, struct pubkey);
sent->inv->node_id->pubkey = local_id.pubkey; sent->inv->node_id->pubkey = local_id.pubkey;
sent->inv->description sent->inv->description
@@ -1738,34 +1645,23 @@ static struct command_result *json_rawrequest(struct command *cmd,
{ {
struct sent *sent = tal(cmd, struct sent); struct sent *sent = tal(cmd, struct sent);
u32 *timeout; u32 *timeout;
struct node_id *node_id; struct pubkey *node_id;
struct point32 node_id32;
enum nodeid_parity parity;
if (!param(cmd, buffer, params, if (!param(cmd, buffer, params,
p_req("invreq", param_invreq, &sent->invreq), p_req("invreq", param_invreq, &sent->invreq),
p_req("nodeid", param_node_id, &node_id), p_req("nodeid", param_pubkey, &node_id),
p_opt_def("timeout", param_number, &timeout, 60), p_opt_def("timeout", param_number, &timeout, 60),
NULL)) NULL))
return command_param_failed(); return command_param_failed();
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &node_id32.pubkey,
node_id->k, sizeof(node_id->k)))
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Invalid nodeid");
/* This is how long we'll wait for a reply for. */ /* This is how long we'll wait for a reply for. */
sent->wait_timeout = *timeout; sent->wait_timeout = *timeout;
sent->cmd = cmd; sent->cmd = cmd;
sent->offer = NULL; sent->offer = NULL;
sent->path = path_to_node(sent, cmd->plugin, sent->path = path_to_node(sent, cmd->plugin, node_id);
&node_id32,
&parity);
if (!sent->path) { if (!sent->path) {
/* We *do* know parity: they gave it to us! */ return connect_direct(cmd, node_id,
parity = node_id->k[0];
return connect_direct(cmd, &node_id32, parity,
sendinvreq_after_connect, sent); sendinvreq_after_connect, sent);
} }

View File

@@ -17,7 +17,7 @@
#include <plugins/offers_invreq_hook.h> #include <plugins/offers_invreq_hook.h>
#include <plugins/offers_offer.h> #include <plugins/offers_offer.h>
struct point32 id; struct pubkey id;
u16 cltv_final; u16 cltv_final;
bool offers_enabled; bool offers_enabled;
@@ -390,7 +390,7 @@ static void json_add_offer(struct json_stream *js, const struct tlv_offer *offer
} }
if (offer->node_id) if (offer->node_id)
json_add_point32(js, "node_id", offer->node_id); json_add_pubkey(js, "node_id", offer->node_id);
else else
valid = false; valid = false;
@@ -556,7 +556,7 @@ static void json_add_b12_invoice(struct json_stream *js,
} }
if (invoice->payer_key) if (invoice->payer_key)
json_add_point32(js, "payer_key", invoice->payer_key); json_add_pubkey(js, "payer_key", invoice->payer_key);
if (invoice->payer_info) if (invoice->payer_info)
json_add_hex_talarr(js, "payer_info", invoice->payer_info); json_add_hex_talarr(js, "payer_info", invoice->payer_info);
if (invoice->payer_note) if (invoice->payer_note)
@@ -644,7 +644,7 @@ static void json_add_b12_invoice(struct json_stream *js,
} }
/* invoice_decode checked these */ /* invoice_decode checked these */
json_add_point32(js, "node_id", invoice->node_id); json_add_pubkey(js, "node_id", invoice->node_id);
json_add_bip340sig(js, "signature", invoice->signature); json_add_bip340sig(js, "signature", invoice->signature);
json_add_bool(js, "valid", valid); json_add_bool(js, "valid", valid);
@@ -686,7 +686,7 @@ static void json_add_invoice_request(struct json_stream *js,
json_add_u32(js, "recurrence_start", json_add_u32(js, "recurrence_start",
*invreq->recurrence_start); *invreq->recurrence_start);
if (invreq->payer_key) if (invreq->payer_key)
json_add_point32(js, "payer_key", invreq->payer_key); json_add_pubkey(js, "payer_key", invreq->payer_key);
else { else {
json_add_string(js, "warning_invoice_request_missing_payer_key", json_add_string(js, "warning_invoice_request_missing_payer_key",
"invoice_request requires payer_key"); "invoice_request requires payer_key");

View File

@@ -136,15 +136,14 @@ static void set_recurring_inv_expiry(struct tlv_invoice *inv, u64 last_pay)
/* We rely on label forms for uniqueness. */ /* We rely on label forms for uniqueness. */
static void json_add_label(struct json_stream *js, static void json_add_label(struct json_stream *js,
const struct sha256 *offer_id, const struct sha256 *offer_id,
const struct point32 *payer_key, const struct pubkey *payer_key,
const u32 counter) const u32 counter)
{ {
char *label; char *label;
label = tal_fmt(tmpctx, "%s-%s-%u", label = tal_fmt(tmpctx, "%s-%s-%u",
type_to_string(tmpctx, struct sha256, offer_id), type_to_string(tmpctx, struct sha256, offer_id),
type_to_string(tmpctx, struct point32, type_to_string(tmpctx, struct pubkey, payer_key),
payer_key),
counter); counter);
json_add_string(js, "label", label); json_add_string(js, "label", label);
} }
@@ -425,7 +424,7 @@ static struct command_result *check_previous_invoice(struct command *cmd,
*/ */
static bool check_payer_sig(struct command *cmd, static bool check_payer_sig(struct command *cmd,
const struct tlv_invoice_request *invreq, const struct tlv_invoice_request *invreq,
const struct point32 *payer_key, const struct pubkey *payer_key,
const struct bip340sig *sig) const struct bip340sig *sig)
{ {
struct sha256 merkle, sighash; struct sha256 merkle, sighash;
@@ -775,7 +774,7 @@ static struct command_result *listoffers_done(struct command *cmd,
/* FIXME: Insert paths and payinfo */ /* FIXME: Insert paths and payinfo */
ir->inv->issuer = tal_dup_talarr(ir->inv, char, ir->offer->issuer); ir->inv->issuer = tal_dup_talarr(ir->inv, char, ir->offer->issuer);
ir->inv->node_id = tal_dup(ir->inv, struct point32, ir->offer->node_id); ir->inv->node_id = tal_dup(ir->inv, struct pubkey, ir->offer->node_id);
/* BOLT-offers #12: /* BOLT-offers #12:
* - MUST set (or not set) `quantity` exactly as the invoice_request * - MUST set (or not set) `quantity` exactly as the invoice_request
* did. * did.
@@ -786,7 +785,7 @@ static struct command_result *listoffers_done(struct command *cmd,
/* BOLT-offers #12: /* BOLT-offers #12:
* - MUST set `payer_key` exactly as the invoice_request did. * - MUST set `payer_key` exactly as the invoice_request did.
*/ */
ir->inv->payer_key = tal_dup(ir->inv, struct point32, ir->inv->payer_key = tal_dup(ir->inv, struct pubkey,
ir->invreq->payer_key); ir->invreq->payer_key);
/* BOLT-offers #12: /* BOLT-offers #12:

View File

@@ -405,7 +405,7 @@ struct command_result *json_offer(struct command *cmd,
= tal_dup_arr(offer, char, issuer, strlen(issuer), 0); = tal_dup_arr(offer, char, issuer, strlen(issuer), 0);
} }
offer->node_id = tal_dup(offer, struct point32, &id); offer->node_id = tal_dup(offer, struct pubkey, &id);
/* If they specify a different currency, warn if we can't /* If they specify a different currency, warn if we can't
* convert it! */ * convert it! */
@@ -469,7 +469,7 @@ struct command_result *json_offerout(struct command *cmd,
offer->issuer = tal_dup_arr(offer, char, offer->issuer = tal_dup_arr(offer, char,
issuer, strlen(issuer), 0); issuer, strlen(issuer), 0);
offer->node_id = tal_dup(offer, struct point32, &id); offer->node_id = tal_dup(offer, struct pubkey, &id);
req = jsonrpc_request_start(cmd->plugin, cmd, "createoffer", req = jsonrpc_request_start(cmd->plugin, cmd, "createoffer",
check_result, forward_error, check_result, forward_error,

View File

@@ -3,7 +3,7 @@
#include "config.h" #include "config.h"
#include <plugins/libplugin.h> #include <plugins/libplugin.h>
extern struct point32 id; extern struct pubkey id;
extern bool offers_enabled; extern bool offers_enabled;
struct command_result *json_offer(struct command *cmd, struct command_result *json_offer(struct command *cmd,

View File

@@ -1103,10 +1103,8 @@ static struct command_result *json_pay(struct command *cmd,
} else } else
invmsat = NULL; invmsat = NULL;
/* FIXME: gossmap should store as point32 */
p->destination = tal(p, struct node_id); p->destination = tal(p, struct node_id);
gossmap_guess_node_id(get_gossmap(cmd->plugin), b12->node_id, node_id_from_pubkey(p->destination, b12->node_id);
p->destination);
p->payment_hash = tal_dup(p, struct sha256, b12->payment_hash); p->payment_hash = tal_dup(p, struct sha256, b12->payment_hash);
if (b12->recurrence_counter && !label) if (b12->recurrence_counter && !label)
return command_fail( return command_fail(

View File

@@ -4385,7 +4385,7 @@ def test_offer_needs_option(node_factory):
l1.rpc.call('fetchinvoice', {'offer': 'aaaa'}) l1.rpc.call('fetchinvoice', {'offer': 'aaaa'})
# Decode still works though # Decode still works though
assert l1.rpc.decode('lno1qgsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcgqyys5qq7ypnwgkvdr57yzh6h92zg3qctvrm7w38djg67kzcm4yeg8vc4cq633uzqaxlsxzxergsrav494jjrpuy9hcldjeglha57lxvz20fhha6hjwhv69nnzwzjsajntyf0c4z8h9e70dfdlfq8jdvc9rdht8vr955udtg')['valid'] assert l1.rpc.decode('lno1qgsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcgqyys5qq7yypxdeze35wncs2l2u4gfzyrpds00e6yakfrt6ctrw5n9qanzhqr2x8sgp3lqxpxd82j87j67wyff9cd9msgagq8hveftdkx5t3e98gj2x7ac99hhwlpj9yvj79yz3l8gdlmdmhq47ct9pkedfd8naksd8f8gpar')['valid']
def test_offer(node_factory, bitcoind): def test_offer(node_factory, bitcoind):
@@ -5329,13 +5329,13 @@ def test_payerkey(node_factory):
"""payerkey calculation should not change across releases!""" """payerkey calculation should not change across releases!"""
nodes = node_factory.get_nodes(7) nodes = node_factory.get_nodes(7)
expected_keys = ["294ec1cd3f100947fe859d71a42cb87932e36e7771abf2d50b02a7a92be8e4d5", expected_keys = ["02294ec1cd3f100947fe859d71a42cb87932e36e7771abf2d50b02a7a92be8e4d5",
"6a4a3b6b0c694da6f14629ca5140713fc703591a6d8aae5c79ba9b5556fc5723", "026a4a3b6b0c694da6f14629ca5140713fc703591a6d8aae5c79ba9b5556fc5723",
"defd2b1f3004b0145351f469f34512c6fa4d02fe891a977bafdb34fe7b73ea48", "03defd2b1f3004b0145351f469f34512c6fa4d02fe891a977bafdb34fe7b73ea48",
"eccb00c0a3c760465bb69a6297d7cfa5bcbd989d5a88e435bd8d6e4c723013cd", "03eccb00c0a3c760465bb69a6297d7cfa5bcbd989d5a88e435bd8d6e4c723013cd",
"1b4bfa652f0df7498d734b0ca888b4e3b07f59e1a974ec7d4a9d6046e8e5ab92", "021b4bfa652f0df7498d734b0ca888b4e3b07f59e1a974ec7d4a9d6046e8e5ab92",
"fc91d60b061e517f9182e3e40ea14c27df520c51db204f1409ff50e5cf9a5e4d", "03fc91d60b061e517f9182e3e40ea14c27df520c51db204f1409ff50e5cf9a5e4d",
"a3bbda0137722ba62207b9d3e5e6cc2a11e58480f801892093e01383aacb7fb2"] "03a3bbda0137722ba62207b9d3e5e6cc2a11e58480f801892093e01383aacb7fb2"]
for n, k in zip(nodes, expected_keys): for n, k in zip(nodes, expected_keys):
b12 = n.rpc.createinvoicerequest('lnr1qvsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcyyrjjthf4rh99n7equvlrzrlalcacxj4y9hgzxc79yrntrth6mp3nkvssy5mac4pkfq2m3gq4ttajwh097s')['bolt12'] b12 = n.rpc.createinvoicerequest('lnr1qvsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcyyrjjthf4rh99n7equvlrzrlalcacxj4y9hgzxc79yrntrth6mp3nkvssy5mac4pkfq2m3gq4ttajwh097s')['bolt12']

View File

@@ -31,7 +31,7 @@ tlvtype,offer,recurrence_base,28
tlvdata,offer,recurrence_base,start_any_period,byte, tlvdata,offer,recurrence_base,start_any_period,byte,
tlvdata,offer,recurrence_base,basetime,tu64, tlvdata,offer,recurrence_base,basetime,tu64,
tlvtype,offer,node_id,30 tlvtype,offer,node_id,30
tlvdata,offer,node_id,node_id,point32, tlvdata,offer,node_id,node_id,point,
tlvtype,offer,send_invoice,54 tlvtype,offer,send_invoice,54
tlvtype,offer,refund_for,34 tlvtype,offer,refund_for,34
tlvdata,offer,refund_for,refunded_payment_hash,sha256, tlvdata,offer,refund_for,refunded_payment_hash,sha256,
@@ -57,7 +57,7 @@ tlvdata,invoice_request,recurrence_counter,counter,tu32,
tlvtype,invoice_request,recurrence_start,68 tlvtype,invoice_request,recurrence_start,68
tlvdata,invoice_request,recurrence_start,period_offset,tu32, tlvdata,invoice_request,recurrence_start,period_offset,tu32,
tlvtype,invoice_request,payer_key,38 tlvtype,invoice_request,payer_key,38
tlvdata,invoice_request,payer_key,key,point32, tlvdata,invoice_request,payer_key,key,point,
tlvtype,invoice_request,payer_note,39 tlvtype,invoice_request,payer_note,39
tlvdata,invoice_request,payer_note,note,utf8,... tlvdata,invoice_request,payer_note,note,utf8,...
tlvtype,invoice_request,payer_info,50 tlvtype,invoice_request,payer_info,50
@@ -85,20 +85,19 @@ tlvdata,invoice,blinded_capacities,incoming_msat,u64,...
tlvtype,invoice,issuer,20 tlvtype,invoice,issuer,20
tlvdata,invoice,issuer,issuer,utf8,... tlvdata,invoice,issuer,issuer,utf8,...
tlvtype,invoice,node_id,30 tlvtype,invoice,node_id,30
tlvdata,invoice,node_id,node_id,point32, tlvdata,invoice,node_id,node_id,point,
tlvtype,invoice,quantity,32 tlvtype,invoice,quantity,32
tlvdata,invoice,quantity,quantity,tu64, tlvdata,invoice,quantity,quantity,tu64,
tlvtype,invoice,refund_for,34 tlvtype,invoice,refund_for,34
tlvdata,invoice,refund_for,refunded_payment_hash,sha256, tlvdata,invoice,refund_for,refunded_payment_hash,sha256,
tlvtype,invoice,recurrence_counter,36 tlvtype,invoice,recurrence_counter,36
tlvdata,invoice,recurrence_counter,counter,tu32, tlvdata,invoice,recurrence_counter,counter,tu32,
tlvtype,invoice,send_invoice,54
tlvtype,invoice,recurrence_start,68 tlvtype,invoice,recurrence_start,68
tlvdata,invoice,recurrence_start,period_offset,tu32, tlvdata,invoice,recurrence_start,period_offset,tu32,
tlvtype,invoice,recurrence_basetime,64 tlvtype,invoice,recurrence_basetime,64
tlvdata,invoice,recurrence_basetime,basetime,tu64, tlvdata,invoice,recurrence_basetime,basetime,tu64,
tlvtype,invoice,payer_key,38 tlvtype,invoice,payer_key,38
tlvdata,invoice,payer_key,key,point32, tlvdata,invoice,payer_key,key,point,
tlvtype,invoice,payer_note,39 tlvtype,invoice,payer_note,39
tlvdata,invoice,payer_note,note,utf8,... tlvdata,invoice,payer_note,note,utf8,...
tlvtype,invoice,created_at,40 tlvtype,invoice,created_at,40
@@ -115,6 +114,7 @@ tlvtype,invoice,payer_info,50
tlvdata,invoice,payer_info,blob,byte,... tlvdata,invoice,payer_info,blob,byte,...
tlvtype,invoice,refund_signature,52 tlvtype,invoice,refund_signature,52
tlvdata,invoice,refund_signature,payer_signature,bip340sig, tlvdata,invoice,refund_signature,payer_signature,bip340sig,
tlvtype,invoice,send_invoice,54
tlvtype,invoice,replace_invoice,56 tlvtype,invoice,replace_invoice,56
tlvdata,invoice,replace_invoice,payment_hash,sha256, tlvdata,invoice,replace_invoice,payment_hash,sha256,
tlvtype,invoice,signature,240 tlvtype,invoice,signature,240
@@ -123,6 +123,8 @@ subtype,blinded_payinfo
subtypedata,blinded_payinfo,fee_base_msat,u32, subtypedata,blinded_payinfo,fee_base_msat,u32,
subtypedata,blinded_payinfo,fee_proportional_millionths,u32, subtypedata,blinded_payinfo,fee_proportional_millionths,u32,
subtypedata,blinded_payinfo,cltv_expiry_delta,u16, subtypedata,blinded_payinfo,cltv_expiry_delta,u16,
subtypedata,blinded_payinfo,htlc_minimum_msat,u64,
subtypedata,blinded_payinfo,htlc_maximum_msat,u64,
subtypedata,blinded_payinfo,flen,u16, subtypedata,blinded_payinfo,flen,u16,
subtypedata,blinded_payinfo,features,byte,flen subtypedata,blinded_payinfo,features,byte,flen
subtype,fallback_address subtype,fallback_address
1 tlvtype,offer,chains,2
31 tlvdata,offer,recurrence_base,start_any_period,byte,
32 tlvdata,offer,recurrence_base,basetime,tu64,
33 tlvtype,offer,node_id,30
34 tlvdata,offer,node_id,node_id,point32, tlvdata,offer,node_id,node_id,point,
35 tlvtype,offer,send_invoice,54
36 tlvtype,offer,refund_for,34
37 tlvdata,offer,refund_for,refunded_payment_hash,sha256,
57 tlvtype,invoice_request,recurrence_start,68
58 tlvdata,invoice_request,recurrence_start,period_offset,tu32,
59 tlvtype,invoice_request,payer_key,38
60 tlvdata,invoice_request,payer_key,key,point32, tlvdata,invoice_request,payer_key,key,point,
61 tlvtype,invoice_request,payer_note,39
62 tlvdata,invoice_request,payer_note,note,utf8,...
63 tlvtype,invoice_request,payer_info,50
85 tlvtype,invoice,issuer,20
86 tlvdata,invoice,issuer,issuer,utf8,...
87 tlvtype,invoice,node_id,30
88 tlvdata,invoice,node_id,node_id,point32, tlvdata,invoice,node_id,node_id,point,
89 tlvtype,invoice,quantity,32
90 tlvdata,invoice,quantity,quantity,tu64,
91 tlvtype,invoice,refund_for,34
92 tlvdata,invoice,refund_for,refunded_payment_hash,sha256,
93 tlvtype,invoice,recurrence_counter,36
94 tlvdata,invoice,recurrence_counter,counter,tu32,
tlvtype,invoice,send_invoice,54
95 tlvtype,invoice,recurrence_start,68
96 tlvdata,invoice,recurrence_start,period_offset,tu32,
97 tlvtype,invoice,recurrence_basetime,64
98 tlvdata,invoice,recurrence_basetime,basetime,tu64,
99 tlvtype,invoice,payer_key,38
100 tlvdata,invoice,payer_key,key,point32, tlvdata,invoice,payer_key,key,point,
101 tlvtype,invoice,payer_note,39
102 tlvdata,invoice,payer_note,note,utf8,...
103 tlvtype,invoice,created_at,40
114 tlvdata,invoice,payer_info,blob,byte,...
115 tlvtype,invoice,refund_signature,52
116 tlvdata,invoice,refund_signature,payer_signature,bip340sig,
117 tlvtype,invoice,send_invoice,54
118 tlvtype,invoice,replace_invoice,56
119 tlvdata,invoice,replace_invoice,payment_hash,sha256,
120 tlvtype,invoice,signature,240
123 subtypedata,blinded_payinfo,fee_base_msat,u32,
124 subtypedata,blinded_payinfo,fee_proportional_millionths,u32,
125 subtypedata,blinded_payinfo,cltv_expiry_delta,u16,
126 subtypedata,blinded_payinfo,htlc_minimum_msat,u64,
127 subtypedata,blinded_payinfo,htlc_maximum_msat,u64,
128 subtypedata,blinded_payinfo,flen,u16,
129 subtypedata,blinded_payinfo,features,byte,flen
130 subtype,fallback_address

View File

@@ -31,7 +31,7 @@ tlvtype,offer,recurrence_base,28
tlvdata,offer,recurrence_base,start_any_period,byte, tlvdata,offer,recurrence_base,start_any_period,byte,
tlvdata,offer,recurrence_base,basetime,tu64, tlvdata,offer,recurrence_base,basetime,tu64,
tlvtype,offer,node_id,30 tlvtype,offer,node_id,30
tlvdata,offer,node_id,node_id,point32, tlvdata,offer,node_id,node_id,point,
tlvtype,offer,send_invoice,54 tlvtype,offer,send_invoice,54
tlvtype,offer,refund_for,34 tlvtype,offer,refund_for,34
tlvdata,offer,refund_for,refunded_payment_hash,sha256, tlvdata,offer,refund_for,refunded_payment_hash,sha256,
@@ -57,7 +57,7 @@ tlvdata,invoice_request,recurrence_counter,counter,tu32,
tlvtype,invoice_request,recurrence_start,68 tlvtype,invoice_request,recurrence_start,68
tlvdata,invoice_request,recurrence_start,period_offset,tu32, tlvdata,invoice_request,recurrence_start,period_offset,tu32,
tlvtype,invoice_request,payer_key,38 tlvtype,invoice_request,payer_key,38
tlvdata,invoice_request,payer_key,key,point32, tlvdata,invoice_request,payer_key,key,point,
tlvtype,invoice_request,payer_note,39 tlvtype,invoice_request,payer_note,39
tlvdata,invoice_request,payer_note,note,utf8,... tlvdata,invoice_request,payer_note,note,utf8,...
tlvtype,invoice_request,payer_info,50 tlvtype,invoice_request,payer_info,50
@@ -85,20 +85,19 @@ tlvdata,invoice,blinded_capacities,incoming_msat,u64,...
tlvtype,invoice,issuer,20 tlvtype,invoice,issuer,20
tlvdata,invoice,issuer,issuer,utf8,... tlvdata,invoice,issuer,issuer,utf8,...
tlvtype,invoice,node_id,30 tlvtype,invoice,node_id,30
tlvdata,invoice,node_id,node_id,point32, tlvdata,invoice,node_id,node_id,point,
tlvtype,invoice,quantity,32 tlvtype,invoice,quantity,32
tlvdata,invoice,quantity,quantity,tu64, tlvdata,invoice,quantity,quantity,tu64,
tlvtype,invoice,refund_for,34 tlvtype,invoice,refund_for,34
tlvdata,invoice,refund_for,refunded_payment_hash,sha256, tlvdata,invoice,refund_for,refunded_payment_hash,sha256,
tlvtype,invoice,recurrence_counter,36 tlvtype,invoice,recurrence_counter,36
tlvdata,invoice,recurrence_counter,counter,tu32, tlvdata,invoice,recurrence_counter,counter,tu32,
tlvtype,invoice,send_invoice,54
tlvtype,invoice,recurrence_start,68 tlvtype,invoice,recurrence_start,68
tlvdata,invoice,recurrence_start,period_offset,tu32, tlvdata,invoice,recurrence_start,period_offset,tu32,
tlvtype,invoice,recurrence_basetime,64 tlvtype,invoice,recurrence_basetime,64
tlvdata,invoice,recurrence_basetime,basetime,tu64, tlvdata,invoice,recurrence_basetime,basetime,tu64,
tlvtype,invoice,payer_key,38 tlvtype,invoice,payer_key,38
tlvdata,invoice,payer_key,key,point32, tlvdata,invoice,payer_key,key,point,
tlvtype,invoice,payer_note,39 tlvtype,invoice,payer_note,39
tlvdata,invoice,payer_note,note,utf8,... tlvdata,invoice,payer_note,note,utf8,...
tlvtype,invoice,created_at,40 tlvtype,invoice,created_at,40
@@ -115,6 +114,7 @@ tlvtype,invoice,payer_info,50
tlvdata,invoice,payer_info,blob,byte,... tlvdata,invoice,payer_info,blob,byte,...
tlvtype,invoice,refund_signature,52 tlvtype,invoice,refund_signature,52
tlvdata,invoice,refund_signature,payer_signature,bip340sig, tlvdata,invoice,refund_signature,payer_signature,bip340sig,
tlvtype,invoice,send_invoice,54
tlvtype,invoice,replace_invoice,56 tlvtype,invoice,replace_invoice,56
tlvdata,invoice,replace_invoice,payment_hash,sha256, tlvdata,invoice,replace_invoice,payment_hash,sha256,
tlvtype,invoice,signature,240 tlvtype,invoice,signature,240
@@ -123,6 +123,8 @@ subtype,blinded_payinfo
subtypedata,blinded_payinfo,fee_base_msat,u32, subtypedata,blinded_payinfo,fee_base_msat,u32,
subtypedata,blinded_payinfo,fee_proportional_millionths,u32, subtypedata,blinded_payinfo,fee_proportional_millionths,u32,
subtypedata,blinded_payinfo,cltv_expiry_delta,u16, subtypedata,blinded_payinfo,cltv_expiry_delta,u16,
subtypedata,blinded_payinfo,htlc_minimum_msat,u64,
subtypedata,blinded_payinfo,htlc_maximum_msat,u64,
subtypedata,blinded_payinfo,flen,u16, subtypedata,blinded_payinfo,flen,u16,
subtypedata,blinded_payinfo,features,byte,flen subtypedata,blinded_payinfo,features,byte,flen
subtype,fallback_address subtype,fallback_address
1 tlvtype,offer,chains,2
31 tlvdata,offer,recurrence_base,start_any_period,byte,
32 tlvdata,offer,recurrence_base,basetime,tu64,
33 tlvtype,offer,node_id,30
34 tlvdata,offer,node_id,node_id,point32, tlvdata,offer,node_id,node_id,point,
35 tlvtype,offer,send_invoice,54
36 tlvtype,offer,refund_for,34
37 tlvdata,offer,refund_for,refunded_payment_hash,sha256,
57 tlvtype,invoice_request,recurrence_start,68
58 tlvdata,invoice_request,recurrence_start,period_offset,tu32,
59 tlvtype,invoice_request,payer_key,38
60 tlvdata,invoice_request,payer_key,key,point32, tlvdata,invoice_request,payer_key,key,point,
61 tlvtype,invoice_request,payer_note,39
62 tlvdata,invoice_request,payer_note,note,utf8,...
63 tlvtype,invoice_request,payer_info,50
85 tlvtype,invoice,issuer,20
86 tlvdata,invoice,issuer,issuer,utf8,...
87 tlvtype,invoice,node_id,30
88 tlvdata,invoice,node_id,node_id,point32, tlvdata,invoice,node_id,node_id,point,
89 tlvtype,invoice,quantity,32
90 tlvdata,invoice,quantity,quantity,tu64,
91 tlvtype,invoice,refund_for,34
92 tlvdata,invoice,refund_for,refunded_payment_hash,sha256,
93 tlvtype,invoice,recurrence_counter,36
94 tlvdata,invoice,recurrence_counter,counter,tu32,
tlvtype,invoice,send_invoice,54
95 tlvtype,invoice,recurrence_start,68
96 tlvdata,invoice,recurrence_start,period_offset,tu32,
97 tlvtype,invoice,recurrence_basetime,64
98 tlvdata,invoice,recurrence_basetime,basetime,tu64,
99 tlvtype,invoice,payer_key,38
100 tlvdata,invoice,payer_key,key,point32, tlvdata,invoice,payer_key,key,point,
101 tlvtype,invoice,payer_note,39
102 tlvdata,invoice,payer_note,note,utf8,...
103 tlvtype,invoice,created_at,40
114 tlvdata,invoice,payer_info,blob,byte,...
115 tlvtype,invoice,refund_signature,52
116 tlvdata,invoice,refund_signature,payer_signature,bip340sig,
117 tlvtype,invoice,send_invoice,54
118 tlvtype,invoice,replace_invoice,56
119 tlvdata,invoice,replace_invoice,payment_hash,sha256,
120 tlvtype,invoice,signature,240
123 subtypedata,blinded_payinfo,fee_base_msat,u32,
124 subtypedata,blinded_payinfo,fee_proportional_millionths,u32,
125 subtypedata,blinded_payinfo,cltv_expiry_delta,u16,
126 subtypedata,blinded_payinfo,htlc_minimum_msat,u64,
127 subtypedata,blinded_payinfo,htlc_maximum_msat,u64,
128 subtypedata,blinded_payinfo,flen,u16,
129 subtypedata,blinded_payinfo,features,byte,flen
130 subtype,fallback_address

View File

@@ -32,13 +32,12 @@ index 726c3c0a1..a53ca3cdf 100644
tlvtype,invoice_request,payer_key,38 tlvtype,invoice_request,payer_key,38
tlvdata,invoice_request,payer_key,key,point32, tlvdata,invoice_request,payer_key,key,point32,
tlvtype,invoice_request,payer_note,39 tlvtype,invoice_request,payer_note,39
@@ -74,6 +94,13 @@ tlvtype,invoice,quantity,32 @@ -74,6 +94,12 @@ tlvtype,invoice,quantity,32
tlvdata,invoice,quantity,quantity,tu64, tlvdata,invoice,quantity,quantity,tu64,
tlvtype,invoice,refund_for,34 tlvtype,invoice,refund_for,34
tlvdata,invoice,refund_for,refunded_payment_hash,sha256, tlvdata,invoice,refund_for,refunded_payment_hash,sha256,
+tlvtype,invoice,recurrence_counter,36 +tlvtype,invoice,recurrence_counter,36
+tlvdata,invoice,recurrence_counter,counter,tu32, +tlvdata,invoice,recurrence_counter,counter,tu32,
+tlvtype,invoice,send_invoice,54
+tlvtype,invoice,recurrence_start,68 +tlvtype,invoice,recurrence_start,68
+tlvdata,invoice,recurrence_start,period_offset,tu32, +tlvdata,invoice,recurrence_start,period_offset,tu32,
+tlvtype,invoice,recurrence_basetime,64 +tlvtype,invoice,recurrence_basetime,64