lnv1_lnv2_swap_tests/
swap_tests.rs

1use devimint::federation::Client;
2use devimint::version_constants::VERSION_0_9_0_ALPHA;
3use devimint::{cmd, util};
4use fedimint_core::core::OperationId;
5use fedimint_lnv2_client::FinalSendOperationState;
6use lightning_invoice::Bolt11Invoice;
7use tracing::info;
8
9#[path = "common.rs"]
10mod common;
11
12#[tokio::main]
13async fn main() -> anyhow::Result<()> {
14    devimint::run_devfed_test()
15        .call(|dev_fed, _process_mgr| async move {
16            if !util::supports_lnv2() {
17                info!("lnv2 is disabled, skipping");
18                return Ok(());
19            }
20
21            let federation = dev_fed.fed().await?;
22
23            let client = federation
24                .new_joined_client("lnv1-lnv2-swap-test-client")
25                .await?;
26
27            federation.pegin_client(10_000, &client).await?;
28
29            let gw_lnd = dev_fed.gw_lnd().await?;
30
31            let gatewayd_version = util::Gatewayd::version_or_default().await;
32            let gateway_cli_version = util::GatewayCli::version_or_default().await;
33
34            if gatewayd_version < *VERSION_0_9_0_ALPHA || gateway_cli_version < *VERSION_0_9_0_ALPHA
35            {
36                info!("Gateway version too old for swap tests, skipping");
37                return Ok(());
38            }
39
40            info!("Pegging-in gateway...");
41            federation.pegin_gateways(1_000_000, vec![gw_lnd]).await?;
42
43            info!("Testing LNv1 client can pay LNv2 invoice...");
44            let lnd_gw_id = gw_lnd.gateway_id.clone();
45            let (invoice, receive_op) = common::receive(&client, &gw_lnd.addr, 1_000_000).await?;
46            send_lnv1(&client, &lnd_gw_id, &invoice.to_string()).await?;
47            common::await_receive_claimed(&client, receive_op).await?;
48
49            info!("Testing LNv2 client can pay LNv1 invoice...");
50            let (invoice, receive_op) = receive_lnv1(&client, &lnd_gw_id, 1_000_000).await?;
51            common::send(
52                &client,
53                &gw_lnd.addr,
54                &invoice.to_string(),
55                FinalSendOperationState::Success,
56            )
57            .await?;
58            await_receive_lnv1(&client, receive_op).await?;
59
60            info!("LNv1 <-> LNv2 swap tests complete!");
61
62            Ok(())
63        })
64        .await
65}
66
67async fn receive_lnv1(
68    client: &Client,
69    gateway_id: &String,
70    amount_msats: u64,
71) -> anyhow::Result<(Bolt11Invoice, OperationId)> {
72    let invoice_response = cmd!(
73        client,
74        "module",
75        "ln",
76        "invoice",
77        amount_msats,
78        "--gateway-id",
79        gateway_id
80    )
81    .out_json()
82    .await?;
83    let invoice = serde_json::from_value::<Bolt11Invoice>(
84        invoice_response
85            .get("invoice")
86            .expect("Invoice should be present")
87            .clone(),
88    )?;
89    let operation_id = serde_json::from_value::<OperationId>(
90        invoice_response
91            .get("operation_id")
92            .expect("OperationId should be present")
93            .clone(),
94    )?;
95    Ok((invoice, operation_id))
96}
97
98async fn send_lnv1(client: &Client, gateway_id: &str, invoice: &str) -> anyhow::Result<()> {
99    let payment_result = cmd!(
100        client,
101        "module",
102        "ln",
103        "pay",
104        invoice,
105        "--gateway-id",
106        gateway_id
107    )
108    .out_json()
109    .await?;
110    assert!(
111        payment_result.get("Success").is_some() || payment_result.get("preimage").is_some(),
112        "LNv1 payment failed: {payment_result:?}"
113    );
114    Ok(())
115}
116
117async fn await_receive_lnv1(client: &Client, operation_id: OperationId) -> anyhow::Result<()> {
118    let lnv1_response = cmd!(client, "await-invoice", operation_id.fmt_full())
119        .out_json()
120        .await?;
121    assert!(lnv1_response.get("total_amount_msat").is_some());
122    Ok(())
123}