2 extern crate lightning;
3 extern crate lightning_invoice;
4 extern crate secp256k1;
7 use bitcoin::address::WitnessVersion;
8 use bitcoin::{PubkeyHash, ScriptHash};
9 use bitcoin::hashes::hex::FromHex;
10 use bitcoin::hashes::{sha256, Hash};
11 use lightning::ln::PaymentSecret;
12 use lightning::routing::gossip::RoutingFees;
13 use lightning::routing::router::{RouteHint, RouteHintHop};
14 use lightning_invoice::*;
15 use secp256k1::PublicKey;
16 use secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
17 use std::collections::HashSet;
18 use std::time::Duration;
19 use std::str::FromStr;
21 fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
24 "lnbc1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq9qrsgq357wnc5r2ueh7ck6q93dj32dlqnls087fxdwk8qakdyafkq3yap9us6v52vjjsrvywa6rt52cm9r9zqt8r2t7mlcwspyetp5h2tztugp9lfyql".to_owned(),
25 InvoiceBuilder::new(Currency::Bitcoin)
26 .duration_since_epoch(Duration::from_secs(1496314658))
27 .payment_secret(PaymentSecret([0x11; 32]))
28 .payment_hash(sha256::Hash::from_str(
29 "0001020304050607080900010203040506070809000102030405060708090102"
31 .description("Please consider supporting this project".to_owned())
35 RecoverableSignature::from_compact(
36 &<Vec<u8>>::from_hex("8d3ce9e28357337f62da0162d9454df827f83cfe499aeb1c1db349d4d81127425e434ca29929406c23bba1ae8ac6ca32880b38d4bf6ff874024cac34ba9625f1").unwrap(),
37 RecoveryId::from_i32(1).unwrap()
40 false, // Same features as set in InvoiceBuilder
41 false, // No unknown fields
44 "lnbc2500u1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpu9qrsgquk0rl77nj30yxdy8j9vdx85fkpmdla2087ne0xh8nhedh8w27kyke0lp53ut353s06fv3qfegext0eh0ymjpf39tuven09sam30g4vgpfna3rh".to_owned(),
45 InvoiceBuilder::new(Currency::Bitcoin)
46 .amount_milli_satoshis(250_000_000)
47 .duration_since_epoch(Duration::from_secs(1496314658))
48 .payment_secret(PaymentSecret([0x11; 32]))
49 .payment_hash(sha256::Hash::from_str(
50 "0001020304050607080900010203040506070809000102030405060708090102"
52 .description("1 cup coffee".to_owned())
53 .expiry_time(Duration::from_secs(60))
57 RecoverableSignature::from_compact(
58 &<Vec<u8>>::from_hex("e59e3ffbd3945e4334879158d31e89b076dff54f3fa7979ae79df2db9dcaf5896cbfe1a478b8d2307e92c88139464cb7e6ef26e414c4abe33337961ddc5e8ab1").unwrap(),
59 RecoveryId::from_i32(1).unwrap()
62 false, // Same features as set in InvoiceBuilder
63 false, // No unknown fields
66 "lnbc2500u1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpu9qrsgqhtjpauu9ur7fw2thcl4y9vfvh4m9wlfyz2gem29g5ghe2aak2pm3ps8fdhtceqsaagty2vph7utlgj48u0ged6a337aewvraedendscp573dxr".to_owned(),
67 InvoiceBuilder::new(Currency::Bitcoin)
68 .amount_milli_satoshis(250_000_000)
69 .duration_since_epoch(Duration::from_secs(1496314658))
70 .payment_secret(PaymentSecret([0x11; 32]))
71 .payment_hash(sha256::Hash::from_str(
72 "0001020304050607080900010203040506070809000102030405060708090102"
74 .description("ナンセンス 1杯".to_owned())
75 .expiry_time(Duration::from_secs(60))
79 RecoverableSignature::from_compact(
80 &<Vec<u8>>::from_hex("bae41ef385e0fc972977c7ea42b12cbd76577d2412919da8a8a22f9577b6507710c0e96dd78c821dea16453037f717f44aa7e3d196ebb18fbb97307dcb7336c3").unwrap(),
81 RecoveryId::from_i32(1).unwrap()
84 false, // Same features as set in InvoiceBuilder
85 false, // No unknown fields
88 "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qrsgq7ea976txfraylvgzuxs8kgcw23ezlrszfnh8r6qtfpr6cxga50aj6txm9rxrydzd06dfeawfk6swupvz4erwnyutnjq7x39ymw6j38gp7ynn44".to_owned(),
89 InvoiceBuilder::new(Currency::Bitcoin)
90 .amount_milli_satoshis(2_000_000_000)
91 .duration_since_epoch(Duration::from_secs(1496314658))
92 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
93 .payment_secret(PaymentSecret([0x11; 32]))
94 .payment_hash(sha256::Hash::from_str(
95 "0001020304050607080900010203040506070809000102030405060708090102"
100 RecoverableSignature::from_compact(
101 &<Vec<u8>>::from_hex("f67a5f696648fa4fb102e1a07b230e54722f8e024cee71e80b4847ac191da3fb2d2cdb28cc32344d7e9a9cf5c9b6a0ee0582ae46e9938b9c81e344a4dbb5289d").unwrap(),
102 RecoveryId::from_i32(1).unwrap()
105 false, // Same features as set in InvoiceBuilder
106 false, // No unknown fields
109 "lntb20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygshp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfpp3x9et2e20v6pu37c5d9vax37wxq72un989qrsgqdj545axuxtnfemtpwkc45hx9d2ft7x04mt8q7y6t0k2dge9e7h8kpy9p34ytyslj3yu569aalz2xdk8xkd7ltxqld94u8h2esmsmacgpghe9k8".to_owned(),
110 InvoiceBuilder::new(Currency::BitcoinTestnet)
111 .amount_milli_satoshis(2_000_000_000)
112 .duration_since_epoch(Duration::from_secs(1496314658))
113 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
114 .payment_secret(PaymentSecret([0x11; 32]))
115 .payment_hash(sha256::Hash::from_str(
116 "0001020304050607080900010203040506070809000102030405060708090102"
118 .fallback(Fallback::PubKeyHash(PubkeyHash::from_slice(&[49, 114, 181, 101, 79, 102, 131, 200, 251, 20, 105, 89, 211, 71, 206, 48, 60, 174, 76, 167]).unwrap()))
122 RecoverableSignature::from_compact(
123 &<Vec<u8>>::from_hex("6ca95a74dc32e69ced6175b15a5cc56a92bf19f5dace0f134b7d94d464b9f5cf6090a18d48b243f289394d17bdf89466d8e6b37df5981f696bc3dd5986e1bee1").unwrap(),
124 RecoveryId::from_i32(1).unwrap()
127 false, // Same features as set in InvoiceBuilder
128 false, // No unknown fields
131 "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzq9qrsgqdfjcdk6w3ak5pca9hwfwfh63zrrz06wwfya0ydlzpgzxkn5xagsqz7x9j4jwe7yj7vaf2k9lqsdk45kts2fd0fkr28am0u4w95tt2nsq76cqw0".to_owned(),
132 InvoiceBuilder::new(Currency::Bitcoin)
133 .amount_milli_satoshis(2_000_000_000)
134 .duration_since_epoch(Duration::from_secs(1496314658))
135 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
136 .payment_secret(PaymentSecret([0x11; 32]))
137 .payment_hash(sha256::Hash::from_str(
138 "0001020304050607080900010203040506070809000102030405060708090102"
140 .fallback(Fallback::PubKeyHash(PubkeyHash::from_slice(&[4, 182, 31, 125, 193, 234, 13, 201, 148, 36, 70, 76, 196, 6, 77, 197, 100, 217, 30, 137]).unwrap()))
141 .private_route(RouteHint(vec![RouteHintHop {
142 src_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex(
143 "029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255"
144 ).unwrap()).unwrap(),
145 short_channel_id: (66051 << 40) | (263430 << 16) | 1800,
146 fees: RoutingFees { base_msat: 1, proportional_millionths: 20 },
147 cltv_expiry_delta: 3,
148 htlc_maximum_msat: None, htlc_minimum_msat: None,
150 src_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex(
151 "039e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255"
152 ).unwrap()).unwrap(),
153 short_channel_id: (197637 << 40) | (395016 << 16) | 2314,
154 fees: RoutingFees { base_msat: 2, proportional_millionths: 30 },
155 cltv_expiry_delta: 4,
156 htlc_maximum_msat: None, htlc_minimum_msat: None,
161 RecoverableSignature::from_compact(
162 &<Vec<u8>>::from_hex("6a6586db4e8f6d40e3a5bb92e4df5110c627e9ce493af237e20a046b4e86ea200178c59564ecf892f33a9558bf041b6ad2cb8292d7a6c351fbb7f2ae2d16b54e").unwrap(),
163 RecoveryId::from_i32(0).unwrap()
166 false, // Same features as set in InvoiceBuilder
167 false, // No unknown fields
170 "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygshp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppj3a24vwu6r8ejrss3axul8rxldph2q7z99qrsgqz6qsgww34xlatfj6e3sngrwfy3ytkt29d2qttr8qz2mnedfqysuqypgqex4haa2h8fx3wnypranf3pdwyluftwe680jjcfp438u82xqphf75ym".to_owned(),
171 InvoiceBuilder::new(Currency::Bitcoin)
172 .amount_milli_satoshis(2_000_000_000)
173 .duration_since_epoch(Duration::from_secs(1496314658))
174 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
175 .payment_secret(PaymentSecret([0x11; 32]))
176 .payment_hash(sha256::Hash::from_str(
177 "0001020304050607080900010203040506070809000102030405060708090102"
179 .fallback(Fallback::ScriptHash(ScriptHash::from_slice(&[143, 85, 86, 59, 154, 25, 243, 33, 194, 17, 233, 185, 243, 140, 223, 104, 110, 160, 120, 69]).unwrap()))
183 RecoverableSignature::from_compact(
184 &<Vec<u8>>::from_hex("16810439d1a9bfd5a65acc61340dc92448bb2d456a80b58ce012b73cb5202438020500c9ab7ef5573a4d174c811f669885ae27f895bb3a3be52c243589f87518").unwrap(),
185 RecoveryId::from_i32(1).unwrap()
188 false, // Same features as set in InvoiceBuilder
189 false, // No unknown fields
192 "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygshp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppqw508d6qejxtdg4y5r3zarvary0c5xw7k9qrsgqt29a0wturnys2hhxpner2e3plp6jyj8qx7548zr2z7ptgjjc7hljm98xhjym0dg52sdrvqamxdezkmqg4gdrvwwnf0kv2jdfnl4xatsqmrnsse".to_owned(),
193 InvoiceBuilder::new(Currency::Bitcoin)
194 .amount_milli_satoshis(2_000_000_000)
195 .duration_since_epoch(Duration::from_secs(1496314658))
196 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
197 .payment_secret(PaymentSecret([0x11; 32]))
198 .payment_hash(sha256::Hash::from_str(
199 "0001020304050607080900010203040506070809000102030405060708090102"
201 .fallback(Fallback::SegWitProgram { version: WitnessVersion::V0,
202 program: vec![117, 30, 118, 232, 25, 145, 150, 212, 84, 148, 28, 69, 209, 179, 163, 35, 241, 67, 59, 214]
207 RecoverableSignature::from_compact(
208 &<Vec<u8>>::from_hex("5a8bd7b97c1cc9055ee60cf2356621f8752248e037a953886a1782b44a58f5ff2d94e6bc89b7b514541a3603bb33722b6c08aa1a3639d34becc549a99fea6eae").unwrap(),
209 RecoveryId::from_i32(0).unwrap()
212 false, // Same features as set in InvoiceBuilder
213 false, // No unknown fields
216 "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygshp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfp4qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q9qrsgq9vlvyj8cqvq6ggvpwd53jncp9nwc47xlrsnenq2zp70fq83qlgesn4u3uyf4tesfkkwwfg3qs54qe426hp3tz7z6sweqdjg05axsrjqp9yrrwc".to_owned(),
217 InvoiceBuilder::new(Currency::Bitcoin)
218 .amount_milli_satoshis(2_000_000_000)
219 .duration_since_epoch(Duration::from_secs(1496314658))
220 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
221 .payment_secret(PaymentSecret([0x11; 32]))
222 .payment_hash(sha256::Hash::from_str(
223 "0001020304050607080900010203040506070809000102030405060708090102"
225 .fallback(Fallback::SegWitProgram { version: WitnessVersion::V0,
226 program: vec![24, 99, 20, 60, 20, 197, 22, 104, 4, 189, 25, 32, 51, 86, 218, 19, 108, 152, 86, 120, 205, 77, 39, 161, 184, 198, 50, 150, 4, 144, 50, 98]
231 RecoverableSignature::from_compact(
232 &<Vec<u8>>::from_hex("2b3ec248f80301a421817369194f012cdd8af8df1c279981420f9e901e20fa3309d791e11355e609b59ce4a220852a0cd55ab862b1785a83b206c90fa74d01c8").unwrap(),
233 RecoveryId::from_i32(1).unwrap()
236 false, // Same features as set in InvoiceBuilder
237 false, // No unknown fields
240 "lnbc9678785340p1pwmna7lpp5gc3xfm08u9qy06djf8dfflhugl6p7lgza6dsjxq454gxhj9t7a0sd8dgfkx7cmtwd68yetpd5s9xar0wfjn5gpc8qhrsdfq24f5ggrxdaezqsnvda3kkum5wfjkzmfqf3jkgem9wgsyuctwdus9xgrcyqcjcgpzgfskx6eqf9hzqnteypzxz7fzypfhg6trddjhygrcyqezcgpzfysywmm5ypxxjemgw3hxjmn8yptk7untd9hxwg3q2d6xjcmtv4ezq7pqxgsxzmnyyqcjqmt0wfjjq6t5v4khxsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsxqyjw5qcqp2rzjq0gxwkzc8w6323m55m4jyxcjwmy7stt9hwkwe2qxmy8zpsgg7jcuwz87fcqqeuqqqyqqqqlgqqqqn3qq9q9qrsgqrvgkpnmps664wgkp43l22qsgdw4ve24aca4nymnxddlnp8vh9v2sdxlu5ywdxefsfvm0fq3sesf08uf6q9a2ke0hc9j6z6wlxg5z5kqpu2v9wz".to_owned(),
241 InvoiceBuilder::new(Currency::Bitcoin)
242 .amount_milli_satoshis(967878534)
243 .duration_since_epoch(Duration::from_secs(1572468703))
244 .payment_secret(PaymentSecret([0x11; 32]))
245 .payment_hash(sha256::Hash::from_str(
246 "462264ede7e14047e9b249da94fefc47f41f7d02ee9b091815a5506bc8abf75f"
248 .expiry_time(Duration::from_secs(604800))
249 .min_final_cltv_expiry_delta(10)
250 .description("Blockstream Store: 88.85 USD for Blockstream Ledger Nano S x 1, \"Back In My Day\" Sticker x 2, \"I Got Lightning Working\" Sticker x 2 and 1 more items".to_owned())
251 .private_route(RouteHint(vec![RouteHintHop {
252 src_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex(
253 "03d06758583bb5154774a6eb221b1276c9e82d65bbaceca806d90e20c108f4b1c7"
254 ).unwrap()).unwrap(),
255 short_channel_id: (589390 << 40) | (3312 << 16) | 1,
256 fees: RoutingFees { base_msat: 1000, proportional_millionths: 2500 },
257 cltv_expiry_delta: 40,
258 htlc_maximum_msat: None, htlc_minimum_msat: None,
263 RecoverableSignature::from_compact(
264 &<Vec<u8>>::from_hex("1b1160cf6186b55722c1ac7ea502086baaccaabdc76b326e666b7f309d972b15069bfca11cd365304b36f48230cc12f3f13a017aab65f7c165a169df32282a58").unwrap(),
265 RecoveryId::from_i32(1).unwrap()
268 false, // Same features as set in InvoiceBuilder
269 false, // No unknown fields
272 "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqqsgq2a25dxl5hrntdtn6zvydt7d66hyzsyhqs4wdynavys42xgl6sgx9c4g7me86a27t07mdtfry458rtjr0v92cnmswpsjscgt2vcse3sgpz3uapa".to_owned(),
273 InvoiceBuilder::new(Currency::Bitcoin)
274 .amount_milli_satoshis(2_500_000_000)
275 .duration_since_epoch(Duration::from_secs(1496314658))
276 .payment_secret(PaymentSecret([0x11; 32]))
277 .payment_hash(sha256::Hash::from_str(
278 "0001020304050607080900010203040506070809000102030405060708090102"
280 .description("coffee beans".to_owned())
284 RecoverableSignature::from_compact(
285 &<Vec<u8>>::from_hex("5755469bf4b8e6b6ae7a1308d5f9bad5c82812e0855cd24fac242aa323fa820c5c551ede4faeabcb7fb6d5a464ad0e35c86f615589ee0e0c250c216a662198c1").unwrap(),
286 RecoveryId::from_i32(1).unwrap()
289 true, // Different features than set in InvoiceBuilder
290 false, // No unknown fields
293 "LNBC25M1PVJLUEZPP5QQQSYQCYQ5RQWZQFQQQSYQCYQ5RQWZQFQQQSYQCYQ5RQWZQFQYPQDQ5VDHKVEN9V5SXYETPDEESSP5ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYGS9Q5SQQQQQQQQQQQQQQQQSGQ2A25DXL5HRNTDTN6ZVYDT7D66HYZSYHQS4WDYNAVYS42XGL6SGX9C4G7ME86A27T07MDTFRY458RTJR0V92CNMSWPSJSCGT2VCSE3SGPZ3UAPA".to_owned(),
294 InvoiceBuilder::new(Currency::Bitcoin)
295 .amount_milli_satoshis(2_500_000_000)
296 .duration_since_epoch(Duration::from_secs(1496314658))
297 .payment_secret(PaymentSecret([0x11; 32]))
298 .payment_hash(sha256::Hash::from_str(
299 "0001020304050607080900010203040506070809000102030405060708090102"
301 .description("coffee beans".to_owned())
305 RecoverableSignature::from_compact(
306 &<Vec<u8>>::from_hex("5755469bf4b8e6b6ae7a1308d5f9bad5c82812e0855cd24fac242aa323fa820c5c551ede4faeabcb7fb6d5a464ad0e35c86f615589ee0e0c250c216a662198c1").unwrap(),
307 RecoveryId::from_i32(1).unwrap()
310 true, // Different features than set in InvoiceBuilder
311 false, // No unknown fields
314 "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqqsgq2qrqqqfppnqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqppnqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqhpnqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqhp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqspnqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqnp5qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqnpkqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqz599y53s3ujmcfjp5xrdap68qxymkqphwsexhmhr8wdz5usdzkzrse33chw6dlp3jhuhge9ley7j2ayx36kawe7kmgg8sv5ugdyusdcqzn8z9x".to_owned(),
315 InvoiceBuilder::new(Currency::Bitcoin)
316 .amount_milli_satoshis(2_500_000_000)
317 .duration_since_epoch(Duration::from_secs(1496314658))
318 .payment_secret(PaymentSecret([0x11; 32]))
319 .payment_hash(sha256::Hash::from_str(
320 "0001020304050607080900010203040506070809000102030405060708090102"
322 .description("coffee beans".to_owned())
326 RecoverableSignature::from_compact(
327 &<Vec<u8>>::from_hex("150a5252308f25bc2641a186de87470189bb003774326beee33b9a2a720d1584386631c5dda6fc3195f97464bfc93d2574868eadd767d6da1078329c4349c837").unwrap(),
328 RecoveryId::from_i32(0).unwrap()
331 true, // Different features than set in InvoiceBuilder
332 true, // Some unknown fields
334 ( // Older version of the payment metadata test with a payment_pubkey set
335 "lnbc10m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdp9wpshjmt9de6zqmt9w3skgct5vysxjmnnd9jx2mq8q8a04uqnp4q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhv66sp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q2gqqqqqqsgqy9gw6ymamd20jumvdgpfphkhp8fzhhdhycw36egcmla5vlrtrmhs9t7psfy3hkkdqzm9eq64fjg558znccds5nhsfmxveha5xe0dykgpspdha0".to_owned(),
336 InvoiceBuilder::new(Currency::Bitcoin)
337 .amount_milli_satoshis(1_000_000_000)
338 .duration_since_epoch(Duration::from_secs(1496314658))
339 .payment_hash(sha256::Hash::from_str(
340 "0001020304050607080900010203040506070809000102030405060708090102"
342 .description("payment metadata inside".to_owned())
343 .payment_metadata(<Vec<u8>>::from_hex("01fafaf0").unwrap())
344 .require_payment_metadata()
345 .payee_pub_key(PublicKey::from_slice(&<Vec<u8>>::from_hex(
346 "03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad"
347 ).unwrap()).unwrap())
348 .payment_secret(PaymentSecret([0x11; 32]))
352 RecoverableSignature::from_compact(
353 &<Vec<u8>>::from_hex("2150ed137ddb54f9736c6a0290ded709d22bddb7261d1d6518dffb467c6b1eef02afc182491bdacd00b65c83554c914a1c53c61b0a4ef04eccccdfb4365ed259").unwrap(),
354 RecoveryId::from_i32(1).unwrap()
357 false, // Different features than set in InvoiceBuilder
358 true, // Some unknown fields
361 "lnbc10m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdp9wpshjmt9de6zqmt9w3skgct5vysxjmnnd9jx2mq8q8a04uqsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q2gqqqqqqsgq7hf8he7ecf7n4ffphs6awl9t6676rrclv9ckg3d3ncn7fct63p6s365duk5wrk202cfy3aj5xnnp5gs3vrdvruverwwq7yzhkf5a3xqpd05wjc".to_owned(),
362 InvoiceBuilder::new(Currency::Bitcoin)
363 .amount_milli_satoshis(1_000_000_000)
364 .duration_since_epoch(Duration::from_secs(1496314658))
365 .payment_hash(sha256::Hash::from_str(
366 "0001020304050607080900010203040506070809000102030405060708090102"
368 .description("payment metadata inside".to_owned())
369 .payment_metadata(<Vec<u8>>::from_hex("01fafaf0").unwrap())
370 .require_payment_metadata()
371 .payment_secret(PaymentSecret([0x11; 32]))
375 RecoverableSignature::from_compact(
376 &<Vec<u8>>::from_hex("f5d27be7d9c27d3aa521bc35d77cabd6bda18f1f61716445b19e27e4e17a887508ea8de5a8e1d94f561248f65434e61a221160dac1f1991b9c0f1057b269d898").unwrap(),
377 RecoveryId::from_i32(1).unwrap()
380 false, // Different features than set in InvoiceBuilder
381 true, // Some unknown fields
388 fn invoice_deserialize() {
389 for (serialized, deserialized, ignore_feature_diff, ignore_unknown_fields) in get_test_tuples() {
390 eprintln!("Testing invoice {}...", serialized);
391 let parsed = serialized.parse::<SignedRawBolt11Invoice>().unwrap();
393 let (parsed_invoice, _, parsed_sig) = parsed.into_parts();
394 let (deserialized_invoice, _, deserialized_sig) = deserialized.into_parts();
396 assert_eq!(deserialized_sig, parsed_sig);
397 assert_eq!(deserialized_invoice.hrp, parsed_invoice.hrp);
398 assert_eq!(deserialized_invoice.data.timestamp, parsed_invoice.data.timestamp);
400 let mut deserialized_hunks: HashSet<_> = deserialized_invoice.data.tagged_fields.iter().collect();
401 let mut parsed_hunks: HashSet<_> = parsed_invoice.data.tagged_fields.iter().collect();
402 if ignore_feature_diff {
403 deserialized_hunks.retain(|h|
404 if let RawTaggedField::KnownSemantics(TaggedField::Features(_)) = h { false } else { true });
405 parsed_hunks.retain(|h|
406 if let RawTaggedField::KnownSemantics(TaggedField::Features(_)) = h { false } else { true });
408 if ignore_unknown_fields {
409 parsed_hunks.retain(|h|
410 if let RawTaggedField::UnknownSemantics(_) = h { false } else { true });
412 assert_eq!(deserialized_hunks, parsed_hunks);
414 Bolt11Invoice::from_signed(serialized.parse::<SignedRawBolt11Invoice>().unwrap()).unwrap();
419 fn test_bolt_invalid_invoices() {
420 // Tests the BOLT 11 invalid invoice test vectors
421 assert_eq!(Bolt11Invoice::from_str(
422 "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q4psqqqqqqqqqqqqqqqqsgqtqyx5vggfcsll4wu246hz02kp85x4katwsk9639we5n5yngc3yhqkm35jnjw4len8vrnqnf5ejh0mzj9n3vz2px97evektfm2l6wqccp3y7372"
423 ), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::InvalidFeatures)));
424 assert_eq!(Bolt11Invoice::from_str(
425 "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrnt"
426 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::InvalidChecksum))));
427 assert_eq!(Bolt11Invoice::from_str(
428 "pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny"
429 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::MissingSeparator))));
430 assert_eq!(Bolt11Invoice::from_str(
431 "LNBC2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny"
432 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::MixedCase))));
433 assert_eq!(Bolt11Invoice::from_str(
434 "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqwgt7mcn5yqw3yx0w94pswkpq6j9uh6xfqqqtsk4tnarugeektd4hg5975x9am52rz4qskukxdmjemg92vvqz8nvmsye63r5ykel43pgz7zq0g2"
435 ), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::InvalidSignature)));
436 assert_eq!(Bolt11Invoice::from_str(
437 "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6na6hlh"
438 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::TooShortDataPart)));
439 assert_eq!(Bolt11Invoice::from_str(
440 "lnbc2500x1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqrrzc4cvfue4zp3hggxp47ag7xnrlr8vgcmkjxk3j5jqethnumgkpqp23z9jclu3v0a7e0aruz366e9wqdykw6dxhdzcjjhldxq0w6wgqcnu43j"
441 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::UnknownSiPrefix)));
442 assert_eq!(Bolt11Invoice::from_str(
443 "lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgq0lzc236j96a95uv0m3umg28gclm5lqxtqqwk32uuk4k6673k6n5kfvx3d2h8s295fad45fdhmusm8sjudfhlf6dcsxmfvkeywmjdkxcp99202x"
444 ), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::ImpreciseAmount)));