Преглед на файлове

feat: mintd db features (#977)

thesimplekid преди 1 месец
родител
ревизия
6f25620f06
променени са 6 файла, в които са добавени 140 реда и са изтрити 42 реда
  1. 14 6
      .github/workflows/ci.yml
  2. 1 1
      crates/cdk-integration-tests/Cargo.toml
  3. 9 6
      crates/cdk-mintd/Cargo.toml
  4. 29 0
      crates/cdk-mintd/build.rs
  5. 83 29
      crates/cdk-mintd/src/lib.rs
  6. 4 0
      crates/cdk-mintd/src/main.rs

+ 14 - 6
.github/workflows/ci.yml

@@ -122,12 +122,20 @@ jobs:
             --bin cdk-mintd,
             --bin cdk-mintd --features redis,
             --bin cdk-mintd --features sqlcipher,
-            --bin cdk-mintd --no-default-features --features lnd,
-            --bin cdk-mintd --no-default-features --features cln,
-            --bin cdk-mintd --no-default-features --features lnbits,
-            --bin cdk-mintd --no-default-features --features fakewallet,
-            --bin cdk-mintd --no-default-features --features grpc-processor,
-            --bin cdk-mintd --no-default-features --features "management-rpc lnd",
+            --bin cdk-mintd --no-default-features --features lnd --features sqlite,
+            --bin cdk-mintd --no-default-features --features cln --features postgres,
+            --bin cdk-mintd --no-default-features --features lnbits --features sqlite,
+            --bin cdk-mintd --no-default-features --features fakewallet --features sqlite,
+            --bin cdk-mintd --no-default-features --features grpc-processor --features sqlite,
+            --bin cdk-mintd --no-default-features --features "management-rpc lnd sqlite",
+            --bin cdk-mintd --no-default-features --features cln --features sqlite,
+            --bin cdk-mintd --no-default-features --features lnd --features postgres,
+            --bin cdk-mintd --no-default-features --features lnbits --features postgres,
+            --bin cdk-mintd --no-default-features --features fakewallet --features postgres,
+            --bin cdk-mintd --no-default-features --features grpc-processor --features postgres,
+            --bin cdk-mintd --no-default-features --features "management-rpc cln postgres",
+            --bin cdk-mintd --no-default-features --features "auth sqlite fakewallet",
+            --bin cdk-mintd --no-default-features --features "auth postgres lnd",
             --bin cdk-mint-cli,
           ]
     steps:

+ 1 - 1
crates/cdk-integration-tests/Cargo.toml

@@ -28,7 +28,7 @@ cdk-sqlite = { workspace = true }
 cdk-redb = { workspace = true }
 cdk-fake-wallet = { workspace = true }
 cdk-common = { workspace = true, features = ["mint", "wallet", "auth"] }
-cdk-mintd = { workspace = true, features = ["cln", "lnd", "fakewallet", "grpc-processor", "auth", "lnbits", "management-rpc"] }
+cdk-mintd = { workspace = true, features = ["cln", "lnd", "fakewallet", "grpc-processor", "auth", "lnbits", "management-rpc", "sqlite", "postgres"] }
 futures = { workspace = true, default-features = false, features = [
     "executor",
 ] }

+ 9 - 6
crates/cdk-mintd/Cargo.toml

@@ -11,7 +11,10 @@ rust-version.workspace = true
 readme = "README.md"
 
 [features]
-default = ["management-rpc", "cln", "lnd", "lnbits", "fakewallet", "grpc-processor", "auth"]
+default = ["management-rpc", "cln", "lnd", "lnbits", "fakewallet", "grpc-processor", "sqlite"]
+# Database features - at least one must be enabled
+sqlite = ["dep:cdk-sqlite"]
+postgres = ["dep:cdk-postgres"]
 # Ensure at least one lightning backend is enabled
 management-rpc = ["cdk-mint-rpc"]
 cln = ["dep:cdk-cln"]
@@ -19,11 +22,11 @@ lnd = ["dep:cdk-lnd"]
 lnbits = ["dep:cdk-lnbits"]
 fakewallet = ["dep:cdk-fake-wallet"]
 grpc-processor = ["dep:cdk-payment-processor", "cdk-signatory/grpc"]
-sqlcipher = ["cdk-sqlite/sqlcipher"]
+sqlcipher = ["sqlite", "cdk-sqlite/sqlcipher"]
 # MSRV is not committed to with swagger enabled
 swagger = ["cdk-axum/swagger", "dep:utoipa", "dep:utoipa-swagger-ui"]
 redis = ["cdk-axum/redis"]
-auth = ["cdk/auth", "cdk-sqlite/auth", "cdk-axum/auth"]
+auth = ["cdk/auth", "cdk-axum/auth", "cdk-sqlite?/auth", "cdk-postgres?/auth"]
 
 [dependencies]
 anyhow.workspace = true
@@ -33,9 +36,9 @@ cdk = { workspace = true, features = [
     "mint",
 ] }
 cdk-sqlite = { workspace = true, features = [
-    "mint",
-] }
-cdk-postgres = { workspace = true, features = ["mint"]}
+    "mint"
+], optional = true }
+cdk-postgres = { workspace = true, features = ["mint"], optional = true }
 cdk-cln = { workspace = true, optional = true }
 cdk-lnbits = { workspace = true, optional = true }
 cdk-lnd = { workspace = true, optional = true }

+ 29 - 0
crates/cdk-mintd/build.rs

@@ -0,0 +1,29 @@
+fn main() {
+    // Check that at least one database feature is enabled
+    let has_database = cfg!(feature = "sqlite") || cfg!(feature = "postgres");
+
+    if !has_database {
+        panic!(
+            "cdk-mintd requires at least one database backend to be enabled.\n\
+             Available database features: sqlite, postgres\n\
+             Example: cargo build --features sqlite"
+        );
+    }
+
+    // Check that at least one Lightning backend is enabled
+    let has_lightning_backend = cfg!(feature = "cln")
+        || cfg!(feature = "lnd")
+        || cfg!(feature = "lnbits")
+        || cfg!(feature = "fakewallet")
+        || cfg!(feature = "grpc-processor");
+
+    if !has_lightning_backend {
+        panic!(
+            "cdk-mintd requires at least one Lightning backend to be enabled.\n\
+             Available Lightning backends: cln, lnd, lnbits, fakewallet, grpc-processor\n\
+             Example: cargo build --features \"sqlite fakewallet\""
+        );
+    }
+
+    println!("cargo:rerun-if-changed=build.rs");
+}

+ 83 - 29
crates/cdk-mintd/src/lib.rs

@@ -39,9 +39,11 @@ use cdk::nuts::{AuthRequired, Method, ProtectedEndpoint, RoutePath};
 use cdk::nuts::{ContactInfo, MintVersion, PaymentMethod};
 use cdk::types::QuoteTTL;
 use cdk_axum::cache::HttpCache;
+#[cfg(feature = "postgres")]
 use cdk_postgres::{MintPgAuthDatabase, MintPgDatabase};
-#[cfg(feature = "auth")]
+#[cfg(all(feature = "auth", feature = "sqlite"))]
 use cdk_sqlite::mint::MintSqliteAuthDatabase;
+#[cfg(feature = "sqlite")]
 use cdk_sqlite::MintSqliteDatabase;
 use cli::CLIArgs;
 use config::{AuthType, DatabaseEngine, LnBackend};
@@ -243,19 +245,21 @@ pub fn load_settings(work_dir: &Path, config_path: Option<PathBuf>) -> Result<co
 
 async fn setup_database(
     settings: &config::Settings,
-    work_dir: &Path,
-    db_password: Option<String>,
+    _work_dir: &Path,
+    _db_password: Option<String>,
 ) -> Result<(
     Arc<dyn MintDatabase<cdk_database::Error> + Send + Sync>,
     Arc<dyn MintKeysDatabase<Err = cdk_database::Error> + Send + Sync>,
 )> {
     match settings.database.engine {
+        #[cfg(feature = "sqlite")]
         DatabaseEngine::Sqlite => {
-            let db = setup_sqlite_database(work_dir, db_password).await?;
+            let db = setup_sqlite_database(_work_dir, _db_password).await?;
             let localstore: Arc<dyn MintDatabase<cdk_database::Error> + Send + Sync> = db.clone();
             let keystore: Arc<dyn MintKeysDatabase<Err = cdk_database::Error> + Send + Sync> = db;
             Ok((localstore, keystore))
         }
+        #[cfg(feature = "postgres")]
         DatabaseEngine::Postgres => {
             // Get the PostgreSQL configuration, ensuring it exists
             let pg_config = settings.database.postgres.as_ref().ok_or_else(|| {
@@ -266,16 +270,33 @@ async fn setup_database(
                 bail!("PostgreSQL URL is required. Set it in config file [database.postgres] section or via CDK_MINTD_POSTGRES_URL/CDK_MINTD_DATABASE_URL environment variable");
             }
 
+            #[cfg(feature = "postgres")]
             let pg_db = Arc::new(MintPgDatabase::new(pg_config.url.as_str()).await?);
+            #[cfg(feature = "postgres")]
             let localstore: Arc<dyn MintDatabase<cdk_database::Error> + Send + Sync> =
                 pg_db.clone();
-            let keystore: Arc<dyn MintKeysDatabase<Err = cdk_database::Error> + Send + Sync> =
-                pg_db;
-            Ok((localstore, keystore))
+            #[cfg(feature = "postgres")]
+            let keystore: Arc<
+                dyn MintKeysDatabase<Err = cdk_database::Error> + Send + Sync,
+            > = pg_db;
+            #[cfg(feature = "postgres")]
+            return Ok((localstore, keystore));
+
+            #[cfg(not(feature = "postgres"))]
+            bail!("PostgreSQL support not compiled in. Enable the 'postgres' feature to use PostgreSQL database.")
+        }
+        #[cfg(not(feature = "sqlite"))]
+        DatabaseEngine::Sqlite => {
+            bail!("SQLite support not compiled in. Enable the 'sqlite' feature to use SQLite database.")
+        }
+        #[cfg(not(feature = "postgres"))]
+        DatabaseEngine::Postgres => {
+            bail!("PostgreSQL support not compiled in. Enable the 'postgres' feature to use PostgreSQL database.")
         }
     }
 }
 
+#[cfg(feature = "sqlite")]
 async fn setup_sqlite_database(
     work_dir: &Path,
     _password: Option<String>,
@@ -529,8 +550,17 @@ async fn configure_backend_for_unit(
         mint_builder.set_unit_fee(&unit, input_fee)?;
     }
 
-    let nut17_supported = SupportedMethods::default_bolt11(unit);
-    mint_builder = mint_builder.with_supported_websockets(nut17_supported);
+    #[cfg(any(
+        feature = "cln",
+        feature = "lnbits",
+        feature = "lnd",
+        feature = "fakewallet",
+        feature = "grpc-processor"
+    ))]
+    {
+        let nut17_supported = SupportedMethods::default_bolt11(unit);
+        mint_builder = mint_builder.with_supported_websockets(nut17_supported);
+    }
 
     Ok(mint_builder)
 }
@@ -550,7 +580,7 @@ fn configure_cache(settings: &config::Settings, mint_builder: MintBuilder) -> Mi
 #[cfg(feature = "auth")]
 async fn setup_authentication(
     settings: &config::Settings,
-    work_dir: &Path,
+    _work_dir: &Path,
     mut mint_builder: MintBuilder,
     _password: Option<String>,
 ) -> Result<MintBuilder> {
@@ -559,29 +589,53 @@ async fn setup_authentication(
         let auth_localstore: Arc<
             dyn cdk_database::MintAuthDatabase<Err = cdk_database::Error> + Send + Sync,
         > = match settings.database.engine {
+            #[cfg(feature = "sqlite")]
             DatabaseEngine::Sqlite => {
-                let sql_db_path = work_dir.join("cdk-mintd-auth.sqlite");
-                #[cfg(not(feature = "sqlcipher"))]
-                let sqlite_db = MintSqliteAuthDatabase::new(&sql_db_path).await?;
-                #[cfg(feature = "sqlcipher")]
-                let sqlite_db = {
-                    // Get password from command line arguments for sqlcipher
-                    MintSqliteAuthDatabase::new((sql_db_path, _password.unwrap())).await?
-                };
-
-                Arc::new(sqlite_db)
+                #[cfg(feature = "sqlite")]
+                {
+                    let sql_db_path = _work_dir.join("cdk-mintd-auth.sqlite");
+                    #[cfg(not(feature = "sqlcipher"))]
+                    let sqlite_db = MintSqliteAuthDatabase::new(&sql_db_path).await?;
+                    #[cfg(feature = "sqlcipher")]
+                    let sqlite_db = {
+                        // Get password from command line arguments for sqlcipher
+                        MintSqliteAuthDatabase::new((sql_db_path, _password.unwrap())).await?
+                    };
+
+                    Arc::new(sqlite_db)
+                }
+                #[cfg(not(feature = "sqlite"))]
+                {
+                    bail!("SQLite support not compiled in. Enable the 'sqlite' feature to use SQLite database.")
+                }
             }
+            #[cfg(feature = "postgres")]
             DatabaseEngine::Postgres => {
-                // Get the PostgreSQL configuration, ensuring it exists
-                let pg_config = settings.database.postgres.as_ref().ok_or_else(|| {
-                    anyhow!("PostgreSQL configuration is required when using PostgreSQL engine")
-                })?;
-
-                if pg_config.url.is_empty() {
-                    bail!("PostgreSQL URL is required for auth database. Set it in config file [database.postgres] section or via CDK_MINTD_POSTGRES_URL/CDK_MINTD_DATABASE_URL environment variable");
+                #[cfg(feature = "postgres")]
+                {
+                    // Get the PostgreSQL configuration, ensuring it exists
+                    let pg_config = settings.database.postgres.as_ref().ok_or_else(|| {
+                        anyhow!("PostgreSQL configuration is required when using PostgreSQL engine")
+                    })?;
+
+                    if pg_config.url.is_empty() {
+                        bail!("PostgreSQL URL is required for auth database. Set it in config file [database.postgres] section or via CDK_MINTD_POSTGRES_URL/CDK_MINTD_DATABASE_URL environment variable");
+                    }
+
+                    Arc::new(MintPgAuthDatabase::new(pg_config.url.as_str()).await?)
                 }
-
-                Arc::new(MintPgAuthDatabase::new(pg_config.url.as_str()).await?)
+                #[cfg(not(feature = "postgres"))]
+                {
+                    bail!("PostgreSQL support not compiled in. Enable the 'postgres' feature to use PostgreSQL database.")
+                }
+            }
+            #[cfg(not(feature = "sqlite"))]
+            DatabaseEngine::Sqlite => {
+                bail!("SQLite support not compiled in. Enable the 'sqlite' feature to use SQLite database.")
+            }
+            #[cfg(not(feature = "postgres"))]
+            DatabaseEngine::Postgres => {
+                bail!("PostgreSQL support not compiled in. Enable the 'postgres' feature to use PostgreSQL database.")
             }
         };
 

+ 4 - 0
crates/cdk-mintd/src/main.rs

@@ -14,6 +14,10 @@ compile_error!(
     "At least one lightning backend feature must be enabled: cln, lnbits, lnd, fakewallet, or grpc-processor"
 );
 
+// Ensure at least one database backend is enabled at compile time
+#[cfg(not(any(feature = "sqlite", feature = "postgres")))]
+compile_error!("At least one database backend feature must be enabled: sqlite or postgres");
+
 use anyhow::Result;
 use cdk_mintd::cli::CLIArgs;
 use cdk_mintd::{get_work_directory, load_settings};