| 576 | } |
| 577 | |
| 578 | static enum likely_type guess_type(const char *buffer, const jsmntok_t *tok) |
| 579 | { |
| 580 | jsmntok_t tok_copy = *tok; |
| 581 | |
| 582 | if (tok_pull(buffer, &tok_copy, "lno1")) |
| 583 | return LIKELY_BOLT12_OFFER; |
| 584 | if (tok_pull(buffer, &tok_copy, "lni1")) |
| 585 | return LIKELY_BOLT12_INV; |
| 586 | if (tok_pull(buffer, &tok_copy, "lnr1")) |
| 587 | return LIKELY_BOLT12_INVREQ; |
| 588 | if (tok_pull(buffer, &tok_copy, "lnp1")) |
| 589 | return LIKELY_BOLT12_PAYER_PROOF; |
| 590 | if (tok_pull(buffer, &tok_copy, "clnemerg1")) |
| 591 | return LIKELY_EMERGENCY_RECOVER; |
| 592 | /* BOLT #11: |
| 593 | * |
| 594 | * The human-readable part of a Lightning invoice consists of |
| 595 | * two sections: |
| 596 | * |
| 597 | * 1. `prefix`: `ln` + BIP-0173 currency prefix (e.g. `lnbc` |
| 598 | * for Bitcoin mainnet, `lntb` for Bitcoin testnet, `lntbs` |
| 599 | * for Bitcoin signet, and `lnbcrt` for Bitcoin regtest) |
| 600 | * |
| 601 | * 1. `amount`: optional number in that currency, followed by |
| 602 | * an optional `multiplier` letter. The unit encoded here |
| 603 | * is the 'social' convention of a payment unit -- in the |
| 604 | * case of Bitcoin the unit is 'bitcoin' NOT satoshis. |
| 605 | */ |
| 606 | if (tok_pull(buffer, &tok_copy, "lnbcrt") |
| 607 | || tok_pull(buffer, &tok_copy, "lnbc") |
| 608 | || tok_pull(buffer, &tok_copy, "lntbs") |
| 609 | || tok_pull(buffer, &tok_copy, "lntb")) { |
| 610 | /* Now find last '1', which separates hrp from data */ |
| 611 | const char *delim = memrchr(buffer + tok_copy.start, '1', |
| 612 | tok_copy.end - tok_copy.start); |
| 613 | if (!delim) |
| 614 | return LIKELY_OTHER; |
| 615 | |
| 616 | /* BOLT #11: |
| 617 | * The following `multiplier` letters are defined: |
| 618 | * |
| 619 | * * `m` (milli): multiply by 0.001 |
| 620 | * * `u` (micro): multiply by 0.000001 |
| 621 | * * `n` (nano): multiply by 0.000000001 |
| 622 | * * `p` (pico): multiply by 0.000000000001 |
| 623 | */ |
| 624 | delim--; |
| 625 | if (delim > buffer + tok_copy.start |
| 626 | && (tolower(*delim) == 'm' |
| 627 | || tolower(*delim) == 'u' |
| 628 | || tolower(*delim) == 'n' |
| 629 | || tolower(*delim) == 'p')) { |
| 630 | delim--; |
| 631 | } |
| 632 | |
| 633 | while (delim >= buffer + tok_copy.start) { |
| 634 | if (!cisdigit(*delim)) |
| 635 | return LIKELY_OTHER; |