@@ -1519,28 +1519,60 @@ mod tests {
1519
1519
}
1520
1520
1521
1521
#[ 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 } ;
1525
1524
use crate :: ln:: msgs:: DecodeError ;
1526
1525
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
-
1536
1526
#[ test]
1537
1527
fn parses_bech32_encoded_offers ( ) {
1538
1528
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" ,
1544
1576
] ;
1545
1577
for encoded_offer in & offers {
1546
1578
if let Err ( e) = encoded_offer. parse :: < Offer > ( ) {
@@ -1550,48 +1582,155 @@ mod bech32_tests {
1550
1582
}
1551
1583
1552
1584
#[ 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
+ ) ;
1568
1591
1569
- }
1592
+ // Malformed: unknown even TLV type 78
1593
+ assert_eq ! (
1594
+ "lno1pgz5znzfgdz3vggzqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpysgr0u2xq4dh3kdevrf4zg6hx8a60jv0gxe0ptgyfc6xkryqqqqqqqq" . parse:: <Offer >( ) ,
1595
+ Err ( Bolt12ParseError :: Decode ( DecodeError :: UnknownRequiredFeature ) ) ,
1596
+ ) ;
1570
1597
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
+ ) ;
1579
1603
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
+ ) ;
1588
1609
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
+ ) ;
1596
1735
}
1597
1736
}
0 commit comments