1 #include <bitcoin/address.h>
2 #include <bitcoin/base58.h>
3 #include <bitcoin/feerate.h>
4 #include <bitcoin/psbt.h>
5 #include <bitcoin/script.h>
6 #include <ccan/json_escape/json_escape.h>
7 #include <ccan/str/hex/hex.h>
8 #include <ccan/tal/str/str.h>
9 #include <common/bech32.h>
10 #include <common/json_command.h>
11 #include <common/json_helpers.h>
12 #include <common/json_tok.h>
13
param_array(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,const jsmntok_t ** arr)14 struct command_result *param_array(struct command *cmd, const char *name,
15 const char *buffer, const jsmntok_t *tok,
16 const jsmntok_t **arr)
17 {
18 if (tok->type == JSMN_ARRAY) {
19 *arr = tok;
20 return NULL;
21 }
22
23 return command_fail_badparam(cmd, name, buffer, tok, "should be an array");
24 }
25
param_bool(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,bool ** b)26 struct command_result *param_bool(struct command *cmd, const char *name,
27 const char *buffer, const jsmntok_t *tok,
28 bool **b)
29 {
30 *b = tal(cmd, bool);
31 if (json_to_bool(buffer, tok, *b))
32 return NULL;
33 return command_fail_badparam(cmd, name, buffer, tok,
34 "should be 'true' or 'false'");
35 }
36
param_millionths(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,uint64_t ** num)37 struct command_result *param_millionths(struct command *cmd, const char *name,
38 const char *buffer,
39 const jsmntok_t *tok, uint64_t **num)
40 {
41 *num = tal(cmd, uint64_t);
42 if (json_to_millionths(buffer, tok, *num))
43 return NULL;
44
45 return command_fail_badparam(cmd, name, buffer, tok,
46 "should be a non-negative floating-point number");
47 }
48
param_escaped_string(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,const char ** str)49 struct command_result *param_escaped_string(struct command *cmd,
50 const char *name,
51 const char * buffer,
52 const jsmntok_t *tok,
53 const char **str)
54 {
55 if (tok->type == JSMN_STRING) {
56 struct json_escape *esc;
57 /* jsmn always gives us ~ well-formed strings. */
58 esc = json_escape_string_(cmd, buffer + tok->start,
59 tok->end - tok->start);
60 *str = json_escape_unescape(cmd, esc);
61 if (*str)
62 return NULL;
63 }
64 return command_fail_badparam(cmd, name, buffer, tok,
65 "should be a string (without \\u)");
66 }
67
param_string(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,const char ** str)68 struct command_result *param_string(struct command *cmd, const char *name,
69 const char * buffer, const jsmntok_t *tok,
70 const char **str)
71 {
72 *str = tal_strndup(cmd, buffer + tok->start,
73 tok->end - tok->start);
74 return NULL;
75 }
76
param_ignore(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,const void * unused)77 struct command_result *param_ignore(struct command *cmd, const char *name,
78 const char *buffer, const jsmntok_t *tok,
79 const void *unused)
80 {
81 return NULL;
82 }
83
param_label(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct json_escape ** label)84 struct command_result *param_label(struct command *cmd, const char *name,
85 const char * buffer, const jsmntok_t *tok,
86 struct json_escape **label)
87 {
88 /* We accept both strings and number literals here. */
89 *label = json_escape_string_(cmd, buffer + tok->start, tok->end - tok->start);
90 if (*label && (tok->type == JSMN_STRING || json_tok_is_num(buffer, tok)))
91 return NULL;
92
93 return command_fail_badparam(cmd, name, buffer, tok,
94 "should be a string or number");
95 }
96
param_number(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,unsigned int ** num)97 struct command_result *param_number(struct command *cmd, const char *name,
98 const char *buffer, const jsmntok_t *tok,
99 unsigned int **num)
100 {
101 *num = tal(cmd, unsigned int);
102 if (json_to_number(buffer, tok, *num))
103 return NULL;
104
105 return command_fail_badparam(cmd, name, buffer, tok,
106 "should be an integer");
107 }
108
param_sha256(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct sha256 ** hash)109 struct command_result *param_sha256(struct command *cmd, const char *name,
110 const char *buffer, const jsmntok_t *tok,
111 struct sha256 **hash)
112 {
113 *hash = tal(cmd, struct sha256);
114 if (hex_decode(buffer + tok->start,
115 tok->end - tok->start,
116 *hash, sizeof(**hash)))
117 return NULL;
118
119 return command_fail_badparam(cmd, name, buffer, tok,
120 "should be a 32 byte hex value");
121 }
122
param_u64(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,uint64_t ** num)123 struct command_result *param_u64(struct command *cmd, const char *name,
124 const char *buffer, const jsmntok_t *tok,
125 uint64_t **num)
126 {
127 *num = tal(cmd, uint64_t);
128 if (json_to_u64(buffer, tok, *num))
129 return NULL;
130
131 return command_fail_badparam(cmd, name, buffer, tok,
132 "should be an unsigned 64 bit integer");
133 }
134
param_tok(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,const jsmntok_t ** out)135 struct command_result *param_tok(struct command *cmd, const char *name,
136 const char *buffer, const jsmntok_t * tok,
137 const jsmntok_t **out)
138 {
139 *out = tok;
140 return NULL;
141 }
142
param_msat(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct amount_msat ** msat)143 struct command_result *param_msat(struct command *cmd, const char *name,
144 const char *buffer, const jsmntok_t *tok,
145 struct amount_msat **msat)
146 {
147 *msat = tal(cmd, struct amount_msat);
148 if (parse_amount_msat(*msat, buffer + tok->start, tok->end - tok->start))
149 return NULL;
150
151 return command_fail_badparam(cmd, name, buffer, tok,
152 "should be a millisatoshi amount");
153 }
154
param_sat(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct amount_sat ** sat)155 struct command_result *param_sat(struct command *cmd, const char *name,
156 const char *buffer, const jsmntok_t *tok,
157 struct amount_sat **sat)
158 {
159 *sat = tal(cmd, struct amount_sat);
160 if (parse_amount_sat(*sat, buffer + tok->start, tok->end - tok->start))
161 return NULL;
162
163 return command_fail_badparam(cmd, name, buffer, tok,
164 "should be a satoshi amount");
165 }
166
param_sat_or_all(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct amount_sat ** sat)167 struct command_result *param_sat_or_all(struct command *cmd, const char *name,
168 const char *buffer, const jsmntok_t *tok,
169 struct amount_sat **sat)
170 {
171 if (json_tok_streq(buffer, tok, "all")) {
172 *sat = tal(cmd, struct amount_sat);
173 **sat = AMOUNT_SAT(-1ULL);
174 return NULL;
175 }
176 return param_sat(cmd, name, buffer, tok, sat);
177 }
178
param_node_id(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct node_id ** id)179 struct command_result *param_node_id(struct command *cmd, const char *name,
180 const char *buffer, const jsmntok_t *tok,
181 struct node_id **id)
182 {
183 *id = tal(cmd, struct node_id);
184 if (json_to_node_id(buffer, tok, *id))
185 return NULL;
186
187 return command_fail_badparam(cmd, name, buffer, tok,
188 "should be a node id");
189 }
190
param_channel_id(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct channel_id ** cid)191 struct command_result *param_channel_id(struct command *cmd, const char *name,
192 const char *buffer, const jsmntok_t *tok,
193 struct channel_id **cid)
194 {
195 *cid = tal(cmd, struct channel_id);
196 if (json_to_channel_id(buffer, tok, *cid))
197 return NULL;
198
199 return command_fail_badparam(cmd, name, buffer, tok,
200 "should be a channel id");
201 }
202
param_short_channel_id(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct short_channel_id ** scid)203 struct command_result *param_short_channel_id(struct command *cmd,
204 const char *name,
205 const char *buffer,
206 const jsmntok_t *tok,
207 struct short_channel_id **scid)
208 {
209 *scid = tal(cmd, struct short_channel_id);
210 if (json_to_short_channel_id(buffer, tok, *scid))
211 return NULL;
212
213 return command_fail_badparam(cmd, name, buffer, tok,
214 "should be a short_channel_id of form NxNxN");
215 }
216
param_secret(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct secret ** secret)217 struct command_result *param_secret(struct command *cmd, const char *name,
218 const char *buffer, const jsmntok_t *tok,
219 struct secret **secret)
220 {
221 *secret = tal(cmd, struct secret);
222 if (hex_decode(buffer + tok->start,
223 tok->end - tok->start,
224 *secret, sizeof(**secret)))
225 return NULL;
226
227 return command_fail_badparam(cmd, name, buffer, tok,
228 "should be a 32 byte hex value");
229 }
230
param_bin_from_hex(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,u8 ** bin)231 struct command_result *param_bin_from_hex(struct command *cmd, const char *name,
232 const char *buffer, const jsmntok_t *tok,
233 u8 **bin)
234 {
235 *bin = json_tok_bin_from_hex(cmd, buffer, tok);
236 if (bin != NULL)
237 return NULL;
238
239 return command_fail_badparam(cmd, name, buffer, tok,
240 "should be a hex value");
241 }
242
param_hops_array(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct sphinx_hop ** hops)243 struct command_result *param_hops_array(struct command *cmd, const char *name,
244 const char *buffer, const jsmntok_t *tok,
245 struct sphinx_hop **hops)
246 {
247 const jsmntok_t *hop, *payloadtok, *pubkeytok;
248 struct sphinx_hop h;
249 size_t i;
250 if (tok->type != JSMN_ARRAY) {
251 return command_fail_badparam(cmd, name, buffer, tok,
252 "should be an array of hops");
253 }
254
255 *hops = tal_arr(cmd, struct sphinx_hop, 0);
256
257 json_for_each_arr(i, hop, tok) {
258 payloadtok = json_get_member(buffer, hop, "payload");
259 pubkeytok = json_get_member(buffer, hop, "pubkey");
260
261 if (!pubkeytok)
262 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
263 "Hop %zu does not have a pubkey", i);
264
265 if (!payloadtok)
266 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
267 "Hop %zu does not have a payload", i);
268
269 h.raw_payload = json_tok_bin_from_hex(*hops, buffer, payloadtok);
270 if (!json_to_pubkey(buffer, pubkeytok, &h.pubkey))
271 return command_fail_badparam(cmd, name, buffer, pubkeytok,
272 "should be a pubkey");
273
274 if (!h.raw_payload)
275 return command_fail_badparam(cmd, name, buffer,
276 payloadtok,
277 "should be hex");
278
279 tal_arr_expand(hops, h);
280 }
281
282 if (tal_count(*hops) == 0) {
283 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
284 "At least one hop must be specified.");
285 }
286
287 return NULL;
288 }
289
param_secrets_array(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct secret ** secrets)290 struct command_result *param_secrets_array(struct command *cmd,
291 const char *name, const char *buffer,
292 const jsmntok_t *tok,
293 struct secret **secrets)
294 {
295 size_t i;
296 const jsmntok_t *s;
297 struct secret secret;
298
299 if (tok->type != JSMN_ARRAY) {
300 return command_fail_badparam(cmd, name, buffer, tok,
301 "should be an array of secrets");
302 }
303
304 *secrets = tal_arr(cmd, struct secret, 0);
305 json_for_each_arr(i, s, tok) {
306 if (!hex_decode(buffer + s->start, s->end - s->start, &secret,
307 sizeof(secret)))
308 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
309 "'%s[%zu]' should be a 32 byte hex "
310 "value, not '%.*s'",
311 name, i, s->end - s->start,
312 buffer + s->start);
313
314 tal_arr_expand(secrets, secret);
315 }
316 return NULL;
317 }
318
param_feerate_val(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,u32 ** feerate_per_kw)319 struct command_result *param_feerate_val(struct command *cmd,
320 const char *name, const char *buffer,
321 const jsmntok_t *tok,
322 u32 **feerate_per_kw)
323 {
324 jsmntok_t base = *tok;
325 enum feerate_style style;
326 unsigned int num;
327
328 if (json_tok_endswith(buffer, tok,
329 feerate_style_name(FEERATE_PER_KBYTE))) {
330 style = FEERATE_PER_KBYTE;
331 base.end -= strlen(feerate_style_name(FEERATE_PER_KBYTE));
332 } else if (json_tok_endswith(buffer, tok,
333 feerate_style_name(FEERATE_PER_KSIPA))) {
334 style = FEERATE_PER_KSIPA;
335 base.end -= strlen(feerate_style_name(FEERATE_PER_KSIPA));
336 } else
337 style = FEERATE_PER_KBYTE;
338
339 if (!json_to_number(buffer, &base, &num)) {
340 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
341 "'%s' should be an integer with optional perkw/perkb, not '%.*s'",
342 name, base.end - base.start,
343 buffer + base.start);
344 }
345
346 *feerate_per_kw = tal(cmd, u32);
347 **feerate_per_kw = feerate_from_style(num, style);
348 if (**feerate_per_kw < FEERATE_FLOOR)
349 **feerate_per_kw = FEERATE_FLOOR;
350 return NULL;
351 }
352
353 /**
354 * segwit_addr_net_decode - Try to decode a Bech32 address and detect
355 * testnet/mainnet/regtest/signet
356 *
357 * This processes the address and returns a string if it is a Bech32
358 * address specified by BIP173. The string is set whether it is
359 * testnet or signet (both "tb"), mainnet ("bc"), regtest ("bcrt")
360 * It does not check, witness version and program size restrictions.
361 *
362 * Out: witness_version: Pointer to an int that will be updated to contain
363 * the witness program version (between 0 and 16 inclusive).
364 * witness_program: Pointer to a buffer of size 40 that will be updated
365 * to contain the witness program bytes.
366 * witness_program_len: Pointer to a size_t that will be updated to
367 * contain the length of bytes in witness_program.
368 * In: addrz: Pointer to the null-terminated address.
369 * Returns string containing the human readable segment of bech32 address
370 */
segwit_addr_net_decode(int * witness_version,uint8_t * witness_program,size_t * witness_program_len,const char * addrz,const struct chainparams * chainparams)371 static const char *segwit_addr_net_decode(int *witness_version,
372 uint8_t *witness_program,
373 size_t *witness_program_len,
374 const char *addrz,
375 const struct chainparams *chainparams)
376 {
377 if (segwit_addr_decode(witness_version, witness_program,
378 witness_program_len, chainparams->bip173_name,
379 addrz))
380 return chainparams->bip173_name;
381 else
382 return NULL;
383 }
384
385 enum address_parse_result
json_to_address_scriptpubkey(const tal_t * ctx,const struct chainparams * chainparams,const char * buffer,const jsmntok_t * tok,const u8 ** scriptpubkey)386 json_to_address_scriptpubkey(const tal_t *ctx,
387 const struct chainparams *chainparams,
388 const char *buffer,
389 const jsmntok_t *tok, const u8 **scriptpubkey)
390 {
391 struct bitcoin_address destination;
392 int witness_version;
393 /* segwit_addr_net_decode requires a buffer of size 40, and will
394 * not write to the buffer if the address is too long, so a buffer
395 * of fixed size 40 will not overflow. */
396 uint8_t witness_program[40];
397 size_t witness_program_len;
398
399 char *addrz;
400 const char *bip173;
401
402 bool parsed;
403 bool right_network;
404 u8 addr_version;
405
406 parsed =
407 ripemd160_from_base58(&addr_version, &destination.addr,
408 buffer + tok->start, tok->end - tok->start);
409
410 if (parsed) {
411 if (addr_version == chainparams->p2pkh_version) {
412 *scriptpubkey = scriptpubkey_p2pkh(ctx, &destination);
413 return ADDRESS_PARSE_SUCCESS;
414 } else if (addr_version == chainparams->p2sh_version) {
415 *scriptpubkey =
416 scriptpubkey_p2sh_hash(ctx, &destination.addr);
417 return ADDRESS_PARSE_SUCCESS;
418 } else {
419 return ADDRESS_PARSE_WRONG_NETWORK;
420 }
421 /* Insert other parsers that accept pointer+len here. */
422 }
423
424 /* Generate null-terminated address. */
425 addrz = tal_dup_arr(ctx, char, buffer + tok->start, tok->end - tok->start, 1);
426 addrz[tok->end - tok->start] = '\0';
427
428 bip173 = segwit_addr_net_decode(&witness_version, witness_program,
429 &witness_program_len, addrz, chainparams);
430 if (bip173) {
431 bool witness_ok;
432
433 /* We know the rules for v0, rest remain undefined */
434 if (witness_version == 0) {
435 witness_ok = (witness_program_len == 20 ||
436 witness_program_len == 32);
437 } else
438 witness_ok = true;
439
440 if (witness_ok) {
441 *scriptpubkey = scriptpubkey_witness_raw(ctx, witness_version,
442 witness_program, witness_program_len);
443 parsed = true;
444 right_network = streq(bip173, chainparams->bip173_name);
445 }
446 }
447 /* Insert other parsers that accept null-terminated string here. */
448
449 tal_free(addrz);
450
451 if (parsed) {
452 if (right_network)
453 return ADDRESS_PARSE_SUCCESS;
454 else
455 return ADDRESS_PARSE_WRONG_NETWORK;
456 }
457
458 return ADDRESS_PARSE_UNRECOGNIZED;
459 }
460
param_txid(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct bitcoin_txid ** txid)461 struct command_result *param_txid(struct command *cmd,
462 const char *name,
463 const char *buffer,
464 const jsmntok_t *tok,
465 struct bitcoin_txid **txid)
466 {
467 *txid = tal(cmd, struct bitcoin_txid);
468 if (json_to_txid(buffer, tok, *txid))
469 return NULL;
470 return command_fail_badparam(cmd, name, buffer, tok,
471 "should be a txid");
472 }
473
param_bitcoin_address(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,const u8 ** scriptpubkey)474 struct command_result *param_bitcoin_address(struct command *cmd,
475 const char *name,
476 const char *buffer,
477 const jsmntok_t *tok,
478 const u8 **scriptpubkey)
479 {
480 /* Parse address. */
481 switch (json_to_address_scriptpubkey(cmd,
482 chainparams,
483 buffer, tok,
484 scriptpubkey)) {
485 case ADDRESS_PARSE_UNRECOGNIZED:
486 return command_fail(cmd, LIGHTNINGD,
487 "Could not parse destination address, "
488 "%s should be a valid address",
489 name ? name : "address field");
490 case ADDRESS_PARSE_WRONG_NETWORK:
491 return command_fail(cmd, LIGHTNINGD,
492 "Destination address is not on network %s",
493 chainparams->network_name);
494 case ADDRESS_PARSE_SUCCESS:
495 return NULL;
496 }
497 abort();
498 }
499
param_psbt(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct wally_psbt ** psbt)500 struct command_result *param_psbt(struct command *cmd,
501 const char *name,
502 const char *buffer,
503 const jsmntok_t *tok,
504 struct wally_psbt **psbt)
505 {
506 *psbt = psbt_from_b64(cmd, buffer + tok->start, tok->end - tok->start);
507 if (*psbt)
508 return NULL;
509
510 return command_fail_badparam(cmd, name, buffer, tok,
511 "Expected a PSBT");
512 }
513
param_outpoint_arr(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct bitcoin_outpoint ** outpoints)514 struct command_result *param_outpoint_arr(struct command *cmd,
515 const char *name,
516 const char *buffer,
517 const jsmntok_t *tok,
518 struct bitcoin_outpoint **outpoints)
519 {
520 size_t i;
521 const jsmntok_t *curr;
522 if (tok->type != JSMN_ARRAY) {
523 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
524 "Could not decode the outpoint array for %s: "
525 "\"%s\" is not a valid outpoint array.",
526 name, json_strdup(tmpctx, buffer, tok));
527 }
528
529 *outpoints = tal_arr(cmd, struct bitcoin_outpoint, tok->size);
530
531 json_for_each_arr(i, curr, tok) {
532 if (!json_to_outpoint(buffer, curr, &(*outpoints)[i]))
533 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
534 "Could not decode outpoint \"%.*s\", "
535 "expected format: txid:output",
536 json_tok_full_len(curr), json_tok_full(buffer, curr));
537 }
538 return NULL;
539 }
540
param_extra_tlvs(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct tlv_field ** fields)541 struct command_result *param_extra_tlvs(struct command *cmd, const char *name,
542 const char *buffer,
543 const jsmntok_t *tok,
544 struct tlv_field **fields)
545 {
546 size_t i;
547 const jsmntok_t *curr;
548 struct tlv_field *f, *temp;
549
550 if (tok->type != JSMN_OBJECT) {
551 return command_fail(
552 cmd, JSONRPC2_INVALID_PARAMS,
553 "Could not decode the TLV object from %s: "
554 "\"%s\" is not a valid JSON object.",
555 name, json_strdup(tmpctx, buffer, tok));
556 }
557
558 temp = tal_arr(cmd, struct tlv_field, tok->size);
559 json_for_each_obj(i, curr, tok) {
560 f = &temp[i];
561 if (!json_to_u64(buffer, curr, &f->numtype)) {
562 return command_fail(
563 cmd, JSONRPC2_INVALID_PARAMS,
564 "\"%s\" is not a valid numeric TLV type.",
565 json_strdup(tmpctx, buffer, curr));
566 }
567 f->value = json_tok_bin_from_hex(temp, buffer, curr + 1);
568
569 if (f->value == NULL) {
570 return command_fail(
571 cmd, JSONRPC2_INVALID_PARAMS,
572 "\"%s\" is not a valid hex encoded TLV value.",
573 json_strdup(tmpctx, buffer, curr));
574 }
575 f->length = tal_bytelen(f->value);
576 f->meta = NULL;
577 }
578 *fields = temp;
579 return NULL;
580 }
581
param_routehint(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct route_info ** ri)582 struct command_result *param_routehint(struct command *cmd, const char *name,
583 const char *buffer, const jsmntok_t *tok,
584 struct route_info **ri)
585 {
586 size_t i;
587 const jsmntok_t *curr;
588 const char *err;
589
590 if (tok->type != JSMN_ARRAY) {
591 return command_fail(
592 cmd, JSONRPC2_INVALID_PARAMS,
593 "Routehint %s (\"%s\") is not an array of hop objects",
594 name, json_strdup(tmpctx, buffer, tok));
595 }
596
597 *ri = tal_arr(cmd, struct route_info, tok->size);
598 json_for_each_arr(i, curr, tok) {
599 struct route_info *e = &(*ri)[i];
600 struct amount_msat temp;
601
602 err = json_scan(tmpctx, buffer, curr,
603 "{id:%,scid:%,feebase:%,feeprop:%,expirydelta:%}",
604 JSON_SCAN(json_to_node_id, &e->pubkey),
605 JSON_SCAN(json_to_short_channel_id, &e->short_channel_id),
606 JSON_SCAN(json_to_msat, &temp),
607 JSON_SCAN(json_to_u32, &e->fee_proportional_millionths),
608 JSON_SCAN(json_to_u16, &e->cltv_expiry_delta)
609 );
610 e->fee_base_msat =
611 temp.millisatoshis; /* Raw: internal conversion. */
612 if (err != NULL) {
613 return command_fail(
614 cmd, JSONRPC2_INVALID_PARAMS,
615 "Error parsing routehint %s[%zu]: %s", name, i,
616 err);
617 }
618 }
619 return NULL;
620 }
621
622 struct command_result *
param_routehint_array(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct route_info *** ris)623 param_routehint_array(struct command *cmd, const char *name, const char *buffer,
624 const jsmntok_t *tok, struct route_info ***ris)
625 {
626 size_t i;
627 const jsmntok_t *curr;
628 char *element_name;
629 struct command_result *err;
630 if (tok->type != JSMN_ARRAY) {
631 return command_fail(
632 cmd, JSONRPC2_INVALID_PARAMS,
633 "Routehint array %s (\"%s\") is not an array",
634 name, json_strdup(tmpctx, buffer, tok));
635 }
636
637 *ris = tal_arr(cmd, struct route_info *, 0);
638 json_for_each_arr(i, curr, tok) {
639 struct route_info *element;
640 element_name = tal_fmt(cmd, "%s[%zu]", name, i);
641 err = param_routehint(cmd, element_name, buffer, curr, &element);
642 if (err != NULL) {
643 return err;
644 }
645 tal_arr_expand(ris, element);
646
647 tal_free(element_name);
648 }
649 return NULL;
650 }
651
param_lease_hex(struct command * cmd,const char * name,const char * buffer,const jsmntok_t * tok,struct lease_rates ** rates)652 struct command_result *param_lease_hex(struct command *cmd,
653 const char *name,
654 const char *buffer,
655 const jsmntok_t *tok,
656 struct lease_rates **rates)
657 {
658 *rates = lease_rates_fromhex(cmd, buffer + tok->start,
659 tok->end - tok->start);
660 if (!*rates)
661 return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
662 "Could not decode '%s' %.*s",
663 name, json_tok_full_len(tok),
664 json_tok_full(buffer, tok));
665 return NULL;
666 }
667