mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-21 14:44:46 +01:00
251 lines
7.6 KiB
Rust
251 lines
7.6 KiB
Rust
use std::time::Duration;
|
|
|
|
use cdk_fake_wallet::create_fake_invoice;
|
|
use reqwest::Client;
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_json::Value;
|
|
use tokio::time::sleep;
|
|
|
|
/// Response from the invoice creation endpoint
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
struct InvoiceResponse {
|
|
payment_request: String,
|
|
checking_id: Option<String>,
|
|
}
|
|
|
|
/// Maximum number of attempts to check invoice payment status
|
|
const MAX_PAYMENT_CHECK_ATTEMPTS: u8 = 20;
|
|
/// Delay between payment status checks in milliseconds
|
|
const PAYMENT_CHECK_DELAY_MS: u64 = 500;
|
|
/// Default test amount in satoshis
|
|
const DEFAULT_TEST_AMOUNT: u64 = 10000;
|
|
|
|
/// Helper function to mint tokens via Lightning invoice
|
|
async fn mint_tokens(base_url: &str, amount: u64) -> String {
|
|
let client = Client::new();
|
|
|
|
// Create an invoice for the specified amount
|
|
let invoice_url = format!("{}/lightning/create_invoice?amount={}", base_url, amount);
|
|
|
|
let invoice_response = client
|
|
.post(&invoice_url)
|
|
.send()
|
|
.await
|
|
.expect("Failed to send invoice creation request")
|
|
.json::<InvoiceResponse>()
|
|
.await
|
|
.expect("Failed to parse invoice response");
|
|
|
|
println!("Created invoice: {}", invoice_response.payment_request);
|
|
|
|
invoice_response.payment_request
|
|
}
|
|
|
|
/// Helper function to wait for payment confirmation
|
|
async fn wait_for_payment_confirmation(base_url: &str, payment_request: &str) {
|
|
let client = Client::new();
|
|
let check_url = format!(
|
|
"{}/lightning/invoice_state?payment_request={}",
|
|
base_url, payment_request
|
|
);
|
|
|
|
let mut payment_confirmed = false;
|
|
|
|
for attempt in 1..=MAX_PAYMENT_CHECK_ATTEMPTS {
|
|
println!(
|
|
"Checking invoice state (attempt {}/{})...",
|
|
attempt, MAX_PAYMENT_CHECK_ATTEMPTS
|
|
);
|
|
|
|
let response = client
|
|
.get(&check_url)
|
|
.send()
|
|
.await
|
|
.expect("Failed to send payment check request");
|
|
|
|
if response.status().is_success() {
|
|
let state: Value = response
|
|
.json()
|
|
.await
|
|
.expect("Failed to parse payment state response");
|
|
println!("Payment state: {:?}", state);
|
|
|
|
if let Some(result) = state.get("result") {
|
|
if result == 1 {
|
|
payment_confirmed = true;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
println!("Failed to check payment state: {}", response.status());
|
|
}
|
|
|
|
sleep(Duration::from_millis(PAYMENT_CHECK_DELAY_MS)).await;
|
|
}
|
|
|
|
if !payment_confirmed {
|
|
panic!("Payment not confirmed after maximum attempts");
|
|
}
|
|
}
|
|
|
|
/// Helper function to get the current wallet balance
|
|
async fn get_wallet_balance(base_url: &str) -> u64 {
|
|
let client = Client::new();
|
|
let balance_url = format!("{}/balance", base_url);
|
|
|
|
let balance_response = client
|
|
.get(&balance_url)
|
|
.send()
|
|
.await
|
|
.expect("Failed to send balance request");
|
|
|
|
let balance: Value = balance_response
|
|
.json()
|
|
.await
|
|
.expect("Failed to parse balance response");
|
|
|
|
balance["balance"]
|
|
.as_u64()
|
|
.expect("Could not parse balance as u64")
|
|
}
|
|
|
|
/// Test the Nutshell wallet's ability to mint tokens from a Lightning invoice
|
|
#[tokio::test]
|
|
async fn test_nutshell_wallet_mint() {
|
|
// Get the wallet URL from environment variable
|
|
let base_url = std::env::var("WALLET_URL").expect("Wallet url is not set");
|
|
|
|
// Step 1: Create an invoice and mint tokens
|
|
let amount = DEFAULT_TEST_AMOUNT;
|
|
let payment_request = mint_tokens(&base_url, amount).await;
|
|
|
|
// Step 2: Wait for the invoice to be paid
|
|
wait_for_payment_confirmation(&base_url, &payment_request).await;
|
|
|
|
// Step 3: Check the wallet balance
|
|
let available_balance = get_wallet_balance(&base_url).await;
|
|
|
|
// Verify the balance is at least the amount we minted
|
|
assert!(
|
|
available_balance >= amount,
|
|
"Balance should be at least {} but was {}",
|
|
amount,
|
|
available_balance
|
|
);
|
|
}
|
|
|
|
/// Test the Nutshell wallet's ability to mint tokens from a Lightning invoice
|
|
#[tokio::test]
|
|
async fn test_nutshell_wallet_swap() {
|
|
// Get the wallet URL from environment variable
|
|
let base_url = std::env::var("WALLET_URL").expect("Wallet url is not set");
|
|
|
|
// Step 1: Create an invoice and mint tokens
|
|
let amount = DEFAULT_TEST_AMOUNT;
|
|
let payment_request = mint_tokens(&base_url, amount).await;
|
|
|
|
// Step 2: Wait for the invoice to be paid
|
|
wait_for_payment_confirmation(&base_url, &payment_request).await;
|
|
|
|
let send_amount = 100;
|
|
let send_url = format!("{}/send?amount={}", base_url, send_amount);
|
|
let client = Client::new();
|
|
|
|
let response: Value = client
|
|
.post(&send_url)
|
|
.send()
|
|
.await
|
|
.expect("Failed to send payment check request")
|
|
.json()
|
|
.await
|
|
.expect("Valid json");
|
|
|
|
// Extract the token and remove the surrounding quotes
|
|
let token_with_quotes = response
|
|
.get("token")
|
|
.expect("Missing token")
|
|
.as_str()
|
|
.expect("Token is not a string");
|
|
let token = token_with_quotes.trim_matches('"');
|
|
|
|
let receive_url = format!("{}/receive?token={}", base_url, token);
|
|
|
|
let response: Value = client
|
|
.post(&receive_url)
|
|
.send()
|
|
.await
|
|
.expect("Failed to receive request")
|
|
.json()
|
|
.await
|
|
.expect("Valid json");
|
|
|
|
let balance = response
|
|
.get("balance")
|
|
.expect("Bal in response")
|
|
.as_u64()
|
|
.expect("Valid num");
|
|
let initial_balance = response
|
|
.get("initial_balance")
|
|
.expect("Bal in response")
|
|
.as_u64()
|
|
.expect("Valid num");
|
|
|
|
let token_received = balance - initial_balance;
|
|
|
|
let fee = 1;
|
|
assert_eq!(token_received, send_amount - fee);
|
|
}
|
|
|
|
/// Test the Nutshell wallet's ability to melt tokens to pay a Lightning invoice
|
|
#[tokio::test]
|
|
async fn test_nutshell_wallet_melt() {
|
|
// Get the wallet URL from environment variable
|
|
let base_url = std::env::var("WALLET_URL").expect("Wallet url is not set");
|
|
|
|
// Step 1: Create an invoice and mint tokens
|
|
let amount = DEFAULT_TEST_AMOUNT;
|
|
let payment_request = mint_tokens(&base_url, amount).await;
|
|
|
|
// Step 2: Wait for the invoice to be paid
|
|
wait_for_payment_confirmation(&base_url, &payment_request).await;
|
|
|
|
// Get initial balance
|
|
let initial_balance = get_wallet_balance(&base_url).await;
|
|
println!("Initial balance: {}", initial_balance);
|
|
|
|
// Step 3: Create a fake invoice to pay
|
|
let payment_amount = 1000; // 1000 sats
|
|
let fake_invoice = create_fake_invoice(payment_amount, "Test payment".to_string());
|
|
let pay_url = format!("{}/lightning/pay_invoice?bolt11={}", base_url, fake_invoice);
|
|
let client = Client::new();
|
|
|
|
// Step 4: Pay the invoice
|
|
let _response: Value = client
|
|
.post(&pay_url)
|
|
.send()
|
|
.await
|
|
.expect("Failed to send pay request")
|
|
.json()
|
|
.await
|
|
.expect("Failed to parse pay response");
|
|
|
|
let final_balance = get_wallet_balance(&base_url).await;
|
|
println!("Final balance: {}", final_balance);
|
|
|
|
assert!(
|
|
initial_balance > final_balance,
|
|
"Balance should decrease after payment"
|
|
);
|
|
|
|
let balance_difference = initial_balance - final_balance;
|
|
println!("Balance decreased by: {}", balance_difference);
|
|
|
|
// The balance difference should be at least the payment amount
|
|
assert!(
|
|
balance_difference >= (payment_amount / 1000),
|
|
"Balance should decrease by at least the payment amount ({}) but decreased by {}",
|
|
payment_amount,
|
|
balance_difference
|
|
);
|
|
}
|