@@ -1519,28 +1519,60 @@ mod tests {
15191519}
15201520
15211521#[ cfg( test) ]
1522- mod bech32_tests {
1523- use super :: { Bolt12ParseError , Offer } ;
1524- use bitcoin:: bech32;
1522+ mod bolt12_tests {
1523+ use super :: { Bolt12ParseError , Bolt12SemanticError , Offer } ;
15251524 use crate :: ln:: msgs:: DecodeError ;
15261525
1527- #[ test]
1528- fn encodes_offer_as_bech32_without_checksum ( ) {
1529- let encoded_offer = "lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" ;
1530- let offer = dbg ! ( encoded_offer. parse:: <Offer >( ) . unwrap( ) ) ;
1531- let reencoded_offer = offer. to_string ( ) ;
1532- dbg ! ( reencoded_offer. parse:: <Offer >( ) . unwrap( ) ) ;
1533- assert_eq ! ( reencoded_offer, encoded_offer) ;
1534- }
1535-
15361526 #[ test]
15371527 fn parses_bech32_encoded_offers ( ) {
15381528 let offers = [
1539- // BOLT 12 test vectors
1540- "lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" ,
1541- "l+no1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" ,
1542- "lno1pqps7sjqpgt+yzm3qv4uxzmtsd3jjqer9wd3hy6tsw3+5k7msjzfpy7nz5yqcn+ygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd+5xvxg" ,
1543- "lno1pqps7sjqpgt+ yzm3qv4uxzmtsd3jjqer9wd3hy6tsw3+ 5k7msjzfpy7nz5yqcn+\n ygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd+\r \n 5xvxg" ,
1529+ // Minimal bolt12 offer
1530+ "lno1pgx9getnwss8vetrw3hhyuckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" ,
1531+
1532+ // for testnet
1533+ "lno1qgsyxjtl6luzd9t3pr62xr7eemp6awnejusgf6gw45q75vcfqqqqqqq2p32x2um5ypmx2cm5dae8x93pqthvwfzadd7jejes8q9lhc4rvjxd022zv5l44g6qah82ru5rdpnpj" ,
1534+
1535+ // for bitcoin (redundant)
1536+ "lno1qgsxlc5vp2m0rvmjcxn2y34wv0m5lyc7sdj7zksgn35dvxgqqqqqqqq2p32x2um5ypmx2cm5dae8x93pqthvwfzadd7jejes8q9lhc4rvjxd022zv5l44g6qah82ru5rdpnpj" ,
1537+
1538+ // for bitcoin or liquidv1
1539+ "lno1qfqpge38tqmzyrdjj3x2qkdr5y80dlfw56ztq6yd9sme995g3gsxqqm0u2xq4dh3kdevrf4zg6hx8a60jv0gxe0ptgyfc6xkryqqqqqqqq9qc4r9wd6zqan9vd6x7unnzcss9mk8y3wkklfvevcrszlmu23kfrxh49px20665dqwmn4p72pksese" ,
1540+
1541+ // with metadata
1542+ "lno1qsgqqqqqqqqqqqqqqqqqqqqqqqqqqzsv23jhxapqwejkxar0wfe3vggzamrjghtt05kvkvpcp0a79gmy3nt6jsn98ad2xs8de6sl9qmgvcvs" ,
1543+
1544+ // with amount
1545+ "lno1pqpzwyq2p32x2um5ypmx2cm5dae8x93pqthvwfzadd7jejes8q9lhc4rvjxd022zv5l44g6qah82ru5rdpnpj" ,
1546+
1547+ // with currency
1548+ "lno1qcp4256ypqpzwyq2p32x2um5ypmx2cm5dae8x93pqthvwfzadd7jejes8q9lhc4rvjxd022zv5l44g6qah82ru5rdpnpj" ,
1549+
1550+ // with expiry
1551+ "lno1pgx9getnwss8vetrw3hhyucwq3ay997czcss9mk8y3wkklfvevcrszlmu23kfrxh49px20665dqwmn4p72pksese" ,
1552+
1553+ // with issuer
1554+ "lno1pgx9getnwss8vetrw3hhyucjy358garswvaz7tmzdak8gvfj9ehhyeeqgf85c4p3xgsxjmnyw4ehgunfv4e3vggzamrjghtt05kvkvpcp0a79gmy3nt6jsn98ad2xs8de6sl9qmgvcvs" ,
1555+
1556+ // with quantity
1557+ "lno1pgx9getnwss8vetrw3hhyuc5qyz3vggzamrjghtt05kvkvpcp0a79gmy3nt6jsn98ad2xs8de6sl9qmgvcvs" ,
1558+
1559+ // with unlimited (or unknown) quantity
1560+ "lno1pgx9getnwss8vetrw3hhyuc5qqtzzqhwcuj966ma9n9nqwqtl032xeyv6755yeflt235pmww58egx6rxry" ,
1561+
1562+ // with single quantity (weird but valid)
1563+ "lno1pgx9getnwss8vetrw3hhyuc5qyq3vggzamrjghtt05kvkvpcp0a79gmy3nt6jsn98ad2xs8de6sl9qmgvcvs" ,
1564+
1565+ // with feature
1566+ "lno1pgx9getnwss8vetrw3hhyucvp5yqqqqqqqqqqqqqqqqqqqqkyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" ,
1567+
1568+ // with blinded path via Bob (0x424242...), blinding 020202...
1569+ "lno1pgx9getnwss8vetrw3hhyucs5ypjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qzqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgqpqqqqqqqqqqqqqqqqqqqqqqqqqqqzqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqqzq3zyg3zyg3zyg3vggzamrjghtt05kvkvpcp0a79gmy3nt6jsn98ad2xs8de6sl9qmgvcvs" ,
1570+
1571+ // ... and with second blinded path via Carol (0x434343...), blinding 020202...
1572+ "lno1pgx9getnwss8vetrw3hhyucsl5q5yqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trspqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqqsqqqqqqqqqqqqqqqqqqqqqqqqqqpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsqpqg3zyg3zyg3zygz0uc7h32x9s0aecdhxlk075kn046aafpuuyw8f5j652t3vha2yqrsyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsqzqqqqqqqqqqqqqqqqqqqqqqqqqqqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqqyzyg3zyg3zyg3zzcss9mk8y3wkklfvevcrszlmu23kfrxh49px20665dqwmn4p72pksese" ,
1573+
1574+ // unknown odd field
1575+ "lno1pgx9getnwss8vetrw3hhyuckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxfppf5x2mrvdamk7unvvs" ,
15441576 ] ;
15451577 for encoded_offer in & offers {
15461578 if let Err ( e) = encoded_offer. parse :: < Offer > ( ) {
@@ -1550,48 +1582,155 @@ mod bech32_tests {
15501582 }
15511583
15521584 #[ test]
1553- fn fails_parsing_bech32_encoded_offers_with_invalid_continuations ( ) {
1554- let offers = [
1555- // BOLT 12 test vectors
1556- "lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg+" ,
1557- "lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg+ " ,
1558- "+lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" ,
1559- "+ lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" ,
1560- "ln++o1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" ,
1561- ] ;
1562- for encoded_offer in & offers {
1563- match encoded_offer. parse :: < Offer > ( ) {
1564- Ok ( _) => panic ! ( "Valid offer: {}" , encoded_offer) ,
1565- Err ( e) => assert_eq ! ( e, Bolt12ParseError :: InvalidContinuation ) ,
1566- }
1567- }
1585+ fn fails_parsing_bech32_encoded_offers ( ) {
1586+ // Malformed: fields out of order
1587+ assert_eq ! (
1588+ "lno1zcssyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszpgz5znzfgdzs" . parse:: <Offer >( ) ,
1589+ Err ( Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
1590+ ) ;
15681591
1569- }
1592+ // Malformed: unknown even TLV type 78
1593+ assert_eq ! (
1594+ "lno1pgz5znzfgdz3vggzqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpysgr0u2xq4dh3kdevrf4zg6hx8a60jv0gxe0ptgyfc6xkryqqqqqqqq" . parse:: <Offer >( ) ,
1595+ Err ( Bolt12ParseError :: Decode ( DecodeError :: UnknownRequiredFeature ) ) ,
1596+ ) ;
15701597
1571- #[ test]
1572- fn fails_parsing_bech32_encoded_offer_with_invalid_hrp ( ) {
1573- let encoded_offer = "lni1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" ;
1574- match encoded_offer. parse :: < Offer > ( ) {
1575- Ok ( _) => panic ! ( "Valid offer: {}" , encoded_offer) ,
1576- Err ( e) => assert_eq ! ( e, Bolt12ParseError :: InvalidBech32Hrp ) ,
1577- }
1578- }
1598+ // Malformed: empty
1599+ assert_eq ! (
1600+ "lno1" . parse:: <Offer >( ) ,
1601+ Err ( Bolt12ParseError :: InvalidSemantics ( Bolt12SemanticError :: MissingDescription ) ) ,
1602+ ) ;
15791603
1580- #[ test]
1581- fn fails_parsing_bech32_encoded_offer_with_invalid_bech32_data ( ) {
1582- let encoded_offer = "lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxo" ;
1583- match encoded_offer. parse :: < Offer > ( ) {
1584- Ok ( _) => panic ! ( "Valid offer: {}" , encoded_offer) ,
1585- Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Bech32 ( bech32:: Error :: InvalidChar ( 'o' ) ) ) ,
1586- }
1587- }
1604+ // Malformed: truncated at type
1605+ assert_eq ! (
1606+ "lno1pg" . parse:: <Offer >( ) ,
1607+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1608+ ) ;
15881609
1589- #[ test]
1590- fn fails_parsing_bech32_encoded_offer_with_invalid_tlv_data ( ) {
1591- let encoded_offer = "lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxgqqqqq" ;
1592- match encoded_offer. parse :: < Offer > ( ) {
1593- Ok ( _) => panic ! ( "Valid offer: {}" , encoded_offer) ,
1594- Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
1595- }
1610+ // Malformed: truncated in length
1611+ assert_eq ! (
1612+ "lno1pt7s" . parse:: <Offer >( ) ,
1613+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1614+ ) ;
1615+
1616+ // Malformed: truncated after length
1617+ assert_eq ! (
1618+ "lno1pgpq" . parse:: <Offer >( ) ,
1619+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1620+ ) ;
1621+
1622+ // Malformed: truncated in description
1623+ assert_eq ! (
1624+ "lno1pgpyz" . parse:: <Offer >( ) ,
1625+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1626+ ) ;
1627+
1628+ // Malformed: invalid offer_chains length
1629+ assert_eq ! (
1630+ "lno1qgqszzs9g9xyjs69zcssyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsz" . parse:: <Offer >( ) ,
1631+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1632+ ) ;
1633+
1634+ // Malformed: truncated currency UTF-8
1635+ assert_eq ! (
1636+ "lno1qcqcqzs9g9xyjs69zcssyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsz" . parse:: <Offer >( ) ,
1637+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1638+ ) ;
1639+
1640+ // Malformed: invalid currency UTF-8
1641+ assert_eq ! (
1642+ "lno1qcpgqsg2q4q5cj2rg5tzzqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqg" . parse:: <Offer >( ) ,
1643+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1644+ ) ;
1645+
1646+ // Malformed: truncated description UTF-8
1647+ assert_eq ! (
1648+ "lno1pgqcq93pqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqy" . parse:: <Offer >( ) ,
1649+ Err ( Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
1650+ ) ;
1651+
1652+ // Malformed: invalid description UTF-8
1653+ assert_eq ! (
1654+ "lno1pgpgqsgkyypqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs" . parse:: <Offer >( ) ,
1655+ Err ( Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
1656+ ) ;
1657+
1658+ // Malformed: truncated offer_paths
1659+ assert_eq ! (
1660+ "lno1pgz5znzfgdz3qqgpzcssyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsz" . parse:: <Offer >( ) ,
1661+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1662+ ) ;
1663+
1664+ // Malformed: zero num_hops in blinded_path
1665+ assert_eq ! (
1666+ "lno1pgz5znzfgdz3qqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsqzcssyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsz" . parse:: <Offer >( ) ,
1667+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1668+ ) ;
1669+
1670+ // Malformed: truncated onionmsg_hop in blinded_path
1671+ assert_eq ! (
1672+ "lno1pgz5znzfgdz3qqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqspqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqgkyypqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs" . parse:: <Offer >( ) ,
1673+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1674+ ) ;
1675+
1676+ // Malformed: bad first_node_id in blinded_path
1677+ assert_eq ! (
1678+ "lno1pgz5znzfgdz3qqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqspqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqgqzcssyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsz" . parse:: <Offer >( ) ,
1679+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1680+ ) ;
1681+
1682+ // Malformed: bad blinding in blinded_path
1683+ assert_eq ! (
1684+ "lno1pgz5znzfgdz3qqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcpqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqgqzcssyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsz" . parse:: <Offer >( ) ,
1685+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1686+ ) ;
1687+
1688+ // Malformed: bad blinded_node_id in onionmsg_hop
1689+ assert_eq ! (
1690+ "lno1pgz5znzfgdz3qqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqspqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqgqzcssyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsz" . parse:: <Offer >( ) ,
1691+ Err ( Bolt12ParseError :: Decode ( DecodeError :: ShortRead ) ) ,
1692+ ) ;
1693+
1694+ // Malformed: truncated issuer UTF-8
1695+ assert_eq ! (
1696+ "lno1pgz5znzfgdz3yqvqzcssyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsz" . parse:: <Offer >( ) ,
1697+ Err ( Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
1698+ ) ;
1699+
1700+ // Malformed: invalid issuer UTF-8
1701+ assert_eq ! (
1702+ "lno1pgz5znzfgdz3yq5qgytzzqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqg" . parse:: <Offer >( ) ,
1703+ Err ( Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
1704+ ) ;
1705+
1706+ // Malformed: invalid offer_node_id
1707+ assert_eq ! (
1708+ "lno1pgz5znzfgdz3vggzqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcrqvps" . parse:: <Offer >( ) ,
1709+ Err ( Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
1710+ ) ;
1711+
1712+ // Contains type >= 80
1713+ assert_eq ! (
1714+ "lno1pgz5znzfgdz3vggzqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgp9qgr0u2xq4dh3kdevrf4zg6hx8a60jv0gxe0ptgyfc6xkryqqqqqqqq" . parse:: <Offer >( ) ,
1715+ Err ( Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
1716+ ) ;
1717+
1718+ // TODO: Resolved in spec https://github.com/lightning/bolts/pull/798/files#r1334851959
1719+ // Contains unknown feature 22
1720+ assert ! (
1721+ "lno1pgx9getnwss8vetrw3hhyucvqdqqqqqkyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg" . parse:: <Offer >( ) . is_ok( )
1722+ ) ;
1723+
1724+ // Missing offer_description
1725+ assert_eq ! (
1726+ "lno1zcss9mk8y3wkklfvevcrszlmu23kfrxh49px20665dqwmn4p72pksese" . parse:: <Offer >( ) ,
1727+ Err ( Bolt12ParseError :: InvalidSemantics ( Bolt12SemanticError :: MissingDescription ) ) ,
1728+ ) ;
1729+
1730+ // Missing offer_node_id"
1731+ assert_eq ! (
1732+ "lno1pgx9getnwss8vetrw3hhyuc" . parse:: <Offer >( ) ,
1733+ Err ( Bolt12ParseError :: InvalidSemantics ( Bolt12SemanticError :: MissingSigningPubkey ) ) ,
1734+ ) ;
15961735 }
15971736}
0 commit comments