fedimint_recurringd_tests/
fedimint-recurringd-tests.rs

1use std::ops::ControlFlow;
2
3use devimint::tests::log_binary_versions;
4use devimint::util::poll;
5use devimint::version_constants::VERSION_0_7_0_ALPHA;
6use devimint::{DevFed, cmd};
7use lightning_invoice::Bolt11Invoice;
8use tracing::info;
9
10#[tokio::main]
11async fn main() -> anyhow::Result<()> {
12    devimint::run_devfed_test()
13        .call(|dev_fed, process_mgr| async move {
14            log_binary_versions().await?;
15
16            let DevFed {
17                fed,
18                gw_lnd,
19                gw_ldk_second,
20                recurringd,
21                ..
22            } = dev_fed.to_dev_fed(&process_mgr).await?;
23
24            let fedimint_cli_version = devimint::util::FedimintCli::version_or_default().await;
25
26            if fedimint_cli_version < *VERSION_0_7_0_ALPHA {
27                info!("Skipping recurringd test because fedimint-cli is lower than v0.7.0");
28                return Ok(());
29            }
30
31            // Give the LND Gateway a balance, it's the only GW serving LNv1 and recurringd
32            // is currently LNv1-only
33            fed.pegin_gateways(10_000_000, vec![&gw_lnd]).await?;
34
35            let client = fed.new_joined_client("recurringd-test-client").await?;
36
37            let lnurl = cmd!(
38                client,
39                "module",
40                "ln",
41                "lnurl",
42                "register",
43                recurringd.api_url()
44            )
45            .out_json()
46            .await?["lnurl"]
47                .as_str()
48                .unwrap()
49                .to_owned();
50
51            let lnurl_list = cmd!(client, "module", "ln", "lnurl", "list")
52                .out_json()
53                .await?["codes"]
54                .as_object()
55                .unwrap()
56                .clone();
57
58            assert_eq!(lnurl_list.len(), 1);
59
60            let listed_lnurl = lnurl_list["0"].clone();
61            assert_eq!(listed_lnurl["lnurl"].as_str().unwrap(), &lnurl);
62            assert_eq!(listed_lnurl["last_derivation_index"].as_i64().unwrap(), 0);
63
64            let invoice = cmd!("lnurlp", "--amount", "1000sat", lnurl)
65                .out_string()
66                .await?
67                .parse::<Bolt11Invoice>()
68                .unwrap();
69
70            gw_ldk_second.pay_invoice(invoice.clone()).await?;
71
72            let invoice_op_id = poll("lnurl_receive", || async {
73                cmd!(client, "dev", "wait", "2")
74                    .run()
75                    .await
76                    .map_err(ControlFlow::Break)?;
77
78                let invoice_list = cmd!(client, "module", "ln", "lnurl", "invoices", "0")
79                    .out_json()
80                    .await
81                    .map_err(ControlFlow::Break)?["invoices"]
82                    .as_object()
83                    .unwrap()
84                    .clone();
85
86                if invoice_list.is_empty() {
87                    return Err(ControlFlow::Continue(anyhow::anyhow!(
88                        "No invoice recognized yet"
89                    )));
90                }
91
92                Ok(invoice_list["1"]["operation_id"]
93                    .as_str()
94                    .unwrap()
95                    .to_owned())
96            })
97            .await?;
98
99            let await_invoice_result = cmd!(
100                client,
101                "module",
102                "ln",
103                "lnurl",
104                "await-invoice-paid",
105                invoice_op_id
106            )
107            .out_json()
108            .await?;
109
110            assert_eq!(
111                await_invoice_result["amount_msat"].as_i64().unwrap(),
112                1_000_000
113            );
114            assert_eq!(
115                await_invoice_result["invoice"].as_str().unwrap(),
116                &invoice.to_string()
117            );
118
119            let client_balance = client.balance().await?;
120            assert_eq!(client_balance, 1_000_000);
121            info!("Client balance: {client_balance}");
122
123            Ok(())
124        })
125        .await
126}