Skip to main content

lnv1_lnv2_swap_tests/
swap_tests.rs

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