start_fake_auth_mint.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //! Binary for starting a fake mint with authentication for testing
  2. //!
  3. //! This binary provides a programmatic way to start a fake mint instance with authentication for testing purposes:
  4. //! 1. Sets up a fake mint instance with authentication using the cdk-mintd library
  5. //! 2. Configures OpenID Connect authentication settings
  6. //! 3. Waits for the mint to be ready and responsive
  7. //! 4. Keeps it running until interrupted (Ctrl+C)
  8. //! 5. Gracefully shuts down on receiving shutdown signal
  9. //!
  10. //! This approach offers better control and integration compared to external scripts,
  11. //! making it easier to run authentication integration tests with consistent configuration.
  12. use std::path::Path;
  13. use std::sync::Arc;
  14. use anyhow::Result;
  15. use bip39::Mnemonic;
  16. use cdk_integration_tests::cli::CommonArgs;
  17. use cdk_integration_tests::shared;
  18. use cdk_mintd::config::AuthType;
  19. use clap::Parser;
  20. use tokio::sync::Notify;
  21. use tokio_util::sync::CancellationToken;
  22. #[derive(Parser)]
  23. #[command(name = "start-fake-auth-mint")]
  24. #[command(about = "Start a fake mint with authentication for testing", long_about = None)]
  25. struct Args {
  26. #[command(flatten)]
  27. common: CommonArgs,
  28. /// Database type (sqlite)
  29. database_type: String,
  30. /// Working directory path
  31. work_dir: String,
  32. /// OpenID discovery URL
  33. openid_discovery: String,
  34. /// Port to listen on (default: 8087)
  35. #[arg(default_value_t = 8087)]
  36. port: u16,
  37. }
  38. /// Start a fake mint with authentication using the library
  39. async fn start_fake_auth_mint(
  40. temp_dir: &Path,
  41. database: &str,
  42. port: u16,
  43. openid_discovery: String,
  44. shutdown: Arc<Notify>,
  45. ) -> Result<tokio::task::JoinHandle<()>> {
  46. println!("Starting fake auth mintd on port {port}");
  47. // Create settings struct for fake mint with auth using shared function
  48. let fake_wallet_config = cdk_mintd::config::FakeWallet {
  49. supported_units: vec![cdk::nuts::CurrencyUnit::Sat, cdk::nuts::CurrencyUnit::Usd],
  50. fee_percent: 0.0,
  51. reserve_fee_min: cdk::Amount::from(1),
  52. min_delay_time: 1,
  53. max_delay_time: 3,
  54. };
  55. let mut settings = shared::create_fake_wallet_settings(
  56. port,
  57. database,
  58. Some(Mnemonic::generate(12)?.to_string()),
  59. None,
  60. Some(fake_wallet_config),
  61. );
  62. // Enable authentication
  63. settings.auth = Some(cdk_mintd::config::Auth {
  64. auth_enabled: true,
  65. openid_discovery,
  66. openid_client_id: "cashu-client".to_string(),
  67. mint_max_bat: 50,
  68. mint: AuthType::Blind,
  69. get_mint_quote: AuthType::Blind,
  70. check_mint_quote: AuthType::Blind,
  71. melt: AuthType::Blind,
  72. get_melt_quote: AuthType::Blind,
  73. check_melt_quote: AuthType::Blind,
  74. swap: AuthType::Blind,
  75. restore: AuthType::Blind,
  76. check_proof_state: AuthType::Blind,
  77. websocket_auth: AuthType::Blind,
  78. });
  79. // Set description for the mint
  80. settings.mint_info.description = "fake test mint with auth".to_string();
  81. let temp_dir = temp_dir.to_path_buf();
  82. let shutdown_clone = shutdown.clone();
  83. // Run the mint in a separate task
  84. let handle = tokio::spawn(async move {
  85. // Create a future that resolves when the shutdown signal is received
  86. let shutdown_future = async move {
  87. shutdown_clone.notified().await;
  88. println!("Fake auth mint shutdown signal received");
  89. };
  90. match cdk_mintd::run_mintd_with_shutdown(
  91. &temp_dir,
  92. &settings,
  93. shutdown_future,
  94. None,
  95. None,
  96. vec![],
  97. )
  98. .await
  99. {
  100. Ok(_) => println!("Fake auth mint exited normally"),
  101. Err(e) => eprintln!("Fake auth mint exited with error: {e}"),
  102. }
  103. });
  104. Ok(handle)
  105. }
  106. #[tokio::main]
  107. async fn main() -> Result<()> {
  108. let args = Args::parse();
  109. // Initialize logging based on CLI arguments
  110. shared::setup_logging(&args.common);
  111. let temp_dir = shared::init_working_directory(&args.work_dir)?;
  112. // Start fake auth mint
  113. let shutdown = shared::create_shutdown_handler();
  114. let shutdown_clone = shutdown.clone();
  115. let handle = start_fake_auth_mint(
  116. &temp_dir,
  117. &args.database_type,
  118. args.port,
  119. args.openid_discovery.clone(),
  120. shutdown_clone,
  121. )
  122. .await?;
  123. let cancel_token = Arc::new(CancellationToken::new());
  124. // Wait for fake auth mint to be ready
  125. if let Err(e) = shared::wait_for_mint_ready_with_shutdown(args.port, 100, cancel_token).await {
  126. eprintln!("Error waiting for fake auth mint: {e}");
  127. return Err(e);
  128. }
  129. println!("Fake auth mint started successfully!");
  130. println!("Fake auth mint: http://127.0.0.1:{}", args.port);
  131. println!("Temp directory: {temp_dir:?}");
  132. println!("Database type: {}", args.database_type);
  133. println!("OpenID Discovery: {}", args.openid_discovery);
  134. println!();
  135. println!("Environment variables needed for tests:");
  136. println!(" CDK_TEST_OIDC_USER=<username>");
  137. println!(" CDK_TEST_OIDC_PASSWORD=<password>");
  138. println!();
  139. println!("You can now run auth integration tests with:");
  140. println!(" cargo test -p cdk-integration-tests --test fake_auth");
  141. println!();
  142. println!("Press Ctrl+C to stop the mint...");
  143. // Wait for Ctrl+C signal
  144. shared::wait_for_shutdown_signal(shutdown).await;
  145. println!("\nReceived Ctrl+C, shutting down mint...");
  146. // Wait for mint to finish gracefully
  147. if let Err(e) = handle.await {
  148. eprintln!("Error waiting for mint to shut down: {e}");
  149. }
  150. println!("Mint shut down successfully");
  151. Ok(())
  152. }