Browse Source
Our new "decode" command will also handle bolt11. We make a few cleanups: 1. Avoid type_to_string() in JSON, instead use format functions directly. 2. Don't need to escape description now that JSON core does that for us. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>ppa
Rusty Russell
4 years ago
11 changed files with 151 additions and 136 deletions
@ -0,0 +1,129 @@ |
|||
#include <bitcoin/address.h> |
|||
#include <bitcoin/base58.h> |
|||
#include <bitcoin/chainparams.h> |
|||
#include <bitcoin/script.h> |
|||
#include <common/bech32.h> |
|||
#include <common/bolt11.h> |
|||
#include <common/bolt11_json.h> |
|||
#include <common/json.h> |
|||
#include <common/json_helpers.h> |
|||
#include <common/json_stream.h> |
|||
|
|||
static void json_add_fallback(struct json_stream *response, |
|||
const char *fieldname, |
|||
const u8 *fallback, |
|||
const struct chainparams *chain) |
|||
{ |
|||
struct bitcoin_address pkh; |
|||
struct ripemd160 sh; |
|||
struct sha256 wsh; |
|||
|
|||
json_object_start(response, fieldname); |
|||
if (is_p2pkh(fallback, &pkh)) { |
|||
json_add_string(response, "type", "P2PKH"); |
|||
json_add_string(response, "addr", |
|||
bitcoin_to_base58(tmpctx, chain, &pkh)); |
|||
} else if (is_p2sh(fallback, &sh)) { |
|||
json_add_string(response, "type", "P2SH"); |
|||
json_add_string(response, "addr", |
|||
p2sh_to_base58(tmpctx, chain, &sh)); |
|||
} else if (is_p2wpkh(fallback, &pkh)) { |
|||
char out[73 + strlen(chain->bip173_name)]; |
|||
json_add_string(response, "type", "P2WPKH"); |
|||
if (segwit_addr_encode(out, chain->bip173_name, 0, |
|||
(const u8 *)&pkh, sizeof(pkh))) |
|||
json_add_string(response, "addr", out); |
|||
} else if (is_p2wsh(fallback, &wsh)) { |
|||
char out[73 + strlen(chain->bip173_name)]; |
|||
json_add_string(response, "type", "P2WSH"); |
|||
if (segwit_addr_encode(out, chain->bip173_name, 0, |
|||
(const u8 *)&wsh, sizeof(wsh))) |
|||
json_add_string(response, "addr", out); |
|||
} |
|||
json_add_hex_talarr(response, "hex", fallback); |
|||
json_object_end(response); |
|||
} |
|||
|
|||
void json_add_bolt11(struct json_stream *response, |
|||
const struct bolt11 *b11) |
|||
{ |
|||
json_add_string(response, "currency", b11->chain->bip173_name); |
|||
json_add_u64(response, "created_at", b11->timestamp); |
|||
json_add_u64(response, "expiry", b11->expiry); |
|||
json_add_node_id(response, "payee", &b11->receiver_id); |
|||
if (b11->msat) |
|||
json_add_amount_msat_compat(response, *b11->msat, |
|||
"msatoshi", "amount_msat"); |
|||
if (b11->description) |
|||
json_add_string(response, "description", b11->description); |
|||
if (b11->description_hash) |
|||
json_add_sha256(response, "description_hash", |
|||
b11->description_hash); |
|||
json_add_num(response, "min_final_cltv_expiry", |
|||
b11->min_final_cltv_expiry); |
|||
if (b11->payment_secret) |
|||
json_add_secret(response, "payment_secret", |
|||
b11->payment_secret); |
|||
if (b11->features) |
|||
json_add_hex_talarr(response, "features", b11->features); |
|||
if (tal_count(b11->fallbacks)) { |
|||
json_array_start(response, "fallbacks"); |
|||
for (size_t i = 0; i < tal_count(b11->fallbacks); i++) |
|||
json_add_fallback(response, NULL, |
|||
b11->fallbacks[i], b11->chain); |
|||
json_array_end(response); |
|||
} |
|||
|
|||
if (tal_count(b11->routes)) { |
|||
size_t i, n; |
|||
|
|||
json_array_start(response, "routes"); |
|||
for (i = 0; i < tal_count(b11->routes); i++) { |
|||
json_array_start(response, NULL); |
|||
for (n = 0; n < tal_count(b11->routes[i]); n++) { |
|||
json_object_start(response, NULL); |
|||
json_add_node_id(response, "pubkey", |
|||
&b11->routes[i][n].pubkey); |
|||
json_add_short_channel_id(response, |
|||
"short_channel_id", |
|||
&b11->routes[i][n] |
|||
.short_channel_id); |
|||
json_add_u64(response, "fee_base_msat", |
|||
b11->routes[i][n].fee_base_msat); |
|||
json_add_u64(response, "fee_proportional_millionths", |
|||
b11->routes[i][n].fee_proportional_millionths); |
|||
json_add_num(response, "cltv_expiry_delta", |
|||
b11->routes[i][n] |
|||
.cltv_expiry_delta); |
|||
json_object_end(response); |
|||
} |
|||
json_array_end(response); |
|||
} |
|||
json_array_end(response); |
|||
} |
|||
|
|||
if (!list_empty(&b11->extra_fields)) { |
|||
struct bolt11_field *extra; |
|||
|
|||
json_array_start(response, "extra"); |
|||
list_for_each(&b11->extra_fields, extra, list) { |
|||
char *data = tal_arr(NULL, char, tal_count(extra->data)+1); |
|||
size_t i; |
|||
|
|||
for (i = 0; i < tal_count(extra->data); i++) |
|||
data[i] = bech32_charset[extra->data[i]]; |
|||
data[i] = '\0'; |
|||
json_object_start(response, NULL); |
|||
json_add_string(response, "tag", |
|||
tal_fmt(data, "%c", extra->tag)); |
|||
json_add_string(response, "data", data); |
|||
tal_free(data); |
|||
json_object_end(response); |
|||
} |
|||
json_array_end(response); |
|||
} |
|||
|
|||
json_add_sha256(response, "payment_hash", &b11->payment_hash); |
|||
|
|||
json_add_string(response, "signature", fmt_signature(tmpctx, &b11->sig)); |
|||
} |
@ -0,0 +1,10 @@ |
|||
#ifndef LIGHTNING_COMMON_BOLT11_JSON_H |
|||
#define LIGHTNING_COMMON_BOLT11_JSON_H |
|||
#include "config.h" |
|||
|
|||
struct bolt11; |
|||
struct json_stream; |
|||
|
|||
void json_add_bolt11(struct json_stream *response, |
|||
const struct bolt11 *b11); |
|||
#endif /* LIGHTNING_COMMON_BOLT11_JSON_H */ |
Loading…
Reference in new issue