mirror of
https://github.com/aljazceru/cdk.git
synced 2026-01-30 10:15:40 +01:00
* chore: Add nutshell wallet integration test script feat: Add MINT_URL configuration for docker container in nutshell wallet integration test script chore: Make nutshell_wallet_itest.sh executable fix: Update MINT_URL to use host.docker.internal for Docker container access feat: Add Docker container startup for Cashu daemon in wallet integration test script chore: Update Docker image to use Docker Hub repository feat: Add cleanup trap to stop Docker container and unset variables feat: Add initial test stub for nutshell wallet mint functionality test: Add Cashu wallet mint integration test feat: Add just command for nutshell wallet integration test refactor: Organize imports and improve code formatting in nutshell wallet test fix: Update Cashu Docker image and test URL for correct container access fix: Update Docker container name and image for Cashu wallet test script fix: Handle Docker container name conflict in nutshell wallet integration test fix: Update Docker image to cashubtc/nutshell:latest in wallet integration test script feat: Add support for running separate Nutshell mint and wallet containers feat: Update Nutshell mint and wallet container configurations for integration testing fix: Update wallet port and container configuration in integration test script chore: Export MINT_URL and WALLET_URL as environment variables fix: Update invoice creation and state checking in nutshell wallet test fix: Update MINT_URL to use host.docker.internal for container access fix: Update nutshell wallet mint test to handle invoice payment state refactor: Improve Nutshell wallet test with better error handling and robustness refactor: Improve code formatting and logging in nutshell wallet test refactor: Replace anyhow with expect for error handling in Nutshell wallet test refactor: Simplify error handling in Nutshell wallet mint test refactor: Replace `?` with `expect()` in Nutshell wallet test refactor: Simplify nutshell wallet test by removing unused code and improving error handling refactor: Extract minting and balance helper functions in nutshell wallet test feat: Add test for Nutshell wallet token swap functionality fix: Trim quotes from token in nutshell wallet swap test refactor: Remove debug print statements and improve code readability refactor: Improve test_nutshell_wallet_melt with payment state checking and balance verification refactor: Update Nutshell wallet integration test script configuration feat: Extract common mint startup function into shared script refactor: Simplify nutshell wallet integration test script and improve startup process feat: Add mintd process termination and test status capture in integration test script refactor: Capitalize env vars and ensure comprehensive cleanup in trap feat: nutshell wallet test * ci: Add test step for Nutshell wallet integration tests * ci: Split Nutshell integration tests into separate jobs * feat: nutshell wallet test * ci: Add Docker setup and increase timeout for Nutshell wallet integration tests * chore: Improve Nutshell wallet integration test script robustness * fix: Remove -i flag from Nix develop and improve Docker accessibility check * fix: payment processor * fix: wallet tests * feat: Add integration shell with Docker and Rust stable for testing * ci: Simplify Nutshell wallet integration test workflow and script * fix: Improve mintd endpoint detection and error handling in integration test script * fix: wallet tests
252 lines
7.8 KiB
Rust
252 lines
7.8 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");
|
|
|
|
println!("Wallet balance: {:?}", balance);
|
|
|
|
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(flavor = "multi_thread", worker_threads = 1)]
|
|
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(flavor = "multi_thread", worker_threads = 1)]
|
|
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;
|
|
|
|
assert_eq!(token_received, send_amount);
|
|
}
|
|
|
|
/// Test the Nutshell wallet's ability to melt tokens to pay a Lightning invoice
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
|
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
|
|
);
|
|
}
|