diff --git a/common/bolt12.c b/common/bolt12.c index 9cff0ab88..8768d7bcb 100644 --- a/common/bolt12.c +++ b/common/bolt12.c @@ -422,3 +422,24 @@ struct tlv_invoice *invoice_decode(const tal_t *ctx, } return invoice; } + +bool bolt12_has_invoice_prefix(const char *str) +{ + return strstarts(str, "lni1") || strstarts(str, "LNI1"); +} + +bool bolt12_has_request_prefix(const char *str) +{ + return strstarts(str, "lnr1") || strstarts(str, "LNR1"); +} + +bool bolt12_has_offer_prefix(const char *str) +{ + return strstarts(str, "lno1") || strstarts(str, "LNO1"); +} + +bool bolt12_has_prefix(const char *str) +{ + return bolt12_has_invoice_prefix(str) || bolt12_has_offer_prefix(str) || + bolt12_has_request_prefix(str); +} diff --git a/common/bolt12.h b/common/bolt12.h index 797c5b64b..841afa513 100644 --- a/common/bolt12.h +++ b/common/bolt12.h @@ -122,4 +122,25 @@ void offer_period_paywindow(const struct tlv_offer_recurrence *recurrence, u64 basetime, u64 period_idx, u64 *period_start, u64 *period_end); + +/** + * Preliminary prefix check to see if the string might be a bolt12 invoice. + */ +bool bolt12_has_invoice_prefix(const char *str); + +/** + * Preliminary prefix check to see if the string might be a bolt12 request. + */ +bool bolt12_has_request_prefix(const char *str); + +/** + * Preliminary prefix check to see if the string might be a bolt12 offer. + */ +bool bolt12_has_offer_prefix(const char *str); + +/** + * Preliminary prefix check to see if the string might be a bolt12 string. + */ +bool bolt12_has_prefix(const char *str); + #endif /* LIGHTNING_COMMON_BOLT12_H */ diff --git a/plugins/pay.c b/plugins/pay.c index 9062cf4d1..b4c86f96c 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -1961,7 +1961,7 @@ static struct command_result *json_paymod(struct command *cmd, struct payment *p; const char *b11str; struct bolt11 *b11; - char *fail; + char *b11_fail, *b12_fail; u64 *maxfee_pct_millionths; u32 *maxdelay; struct amount_msat *exemptfee, *msat; @@ -1973,7 +1973,6 @@ static struct command_result *json_paymod(struct command *cmd, u64 invexpiry; struct sha256 *local_offer_id; const struct tlv_invoice *b12; - bool is_b12; #if DEVELOPER bool *use_shadow; #endif @@ -2004,16 +2003,14 @@ static struct command_result *json_paymod(struct command *cmd, p = payment_new(cmd, cmd, NULL /* No parent */, paymod_mods); p->invstring = tal_steal(p, b11str); - is_b12 = strlen(b11str) > 3 && - (strstarts(b11str, "lni") || strstarts(b11str, "lno") || - strstarts(b11str, "lnr")); - - b11 = bolt11_decode(cmd, b11str, plugin_feature_set(cmd->plugin), NULL, - chainparams, &fail); - if (!is_b12) { + if (!bolt12_has_prefix(b11str)) { + b11 = + bolt11_decode(cmd, b11str, plugin_feature_set(cmd->plugin), + NULL, chainparams, &b11_fail); if (b11 == NULL) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Invalid bolt11: %s", fail); + "Invalid bolt11: %s", b11_fail); + invmsat = b11->msat; invexpiry = b11->timestamp + b11->expiry; @@ -2038,11 +2035,10 @@ static struct command_result *json_paymod(struct command *cmd, } else { b12 = invoice_decode(cmd, b11str, strlen(b11str), plugin_feature_set(cmd->plugin), - chainparams, &fail); + chainparams, &b12_fail); if (b12 == NULL) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Invalid bolt12: %s", fail); - + "Invalid bolt12: %s", b12_fail); if (!exp_offers) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "experimental-offers disabled");