Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ nostr-sdk = { version = "0.44.1", default-features = false, features = [
"nip59"
]}

cdk-strike = { path = "./crates/cdk-strike", version = "=0.14.0" }



Expand Down
2 changes: 1 addition & 1 deletion crates/cdk-integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,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", "sqlite", "postgres", "ldk-node", "prometheus"] }
cdk-mintd = { workspace = true, features = ["cln", "lnd", "fakewallet", "grpc-processor", "auth", "lnbits", "management-rpc", "sqlite", "postgres", "ldk-node", "prometheus", "strike"] }
futures = { workspace = true, default-features = false, features = [
"executor",
] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ fn create_ldk_settings(
mint_management_rpc: None,
prometheus: None,
auth: None,
strike: None,
}
}

Expand Down
3 changes: 3 additions & 0 deletions crates/cdk-integration-tests/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ pub fn create_fake_wallet_settings(
mint_management_rpc: None,
auth: None,
prometheus: Some(Default::default()),
strike: None,
}
}

Expand Down Expand Up @@ -288,6 +289,7 @@ pub fn create_cln_settings(
mint_management_rpc: None,
auth: None,
prometheus: Some(Default::default()),
strike: None,
}
}

Expand Down Expand Up @@ -336,5 +338,6 @@ pub fn create_lnd_settings(
mint_management_rpc: None,
auth: None,
prometheus: Some(Default::default()),
strike: None,
}
}
8 changes: 7 additions & 1 deletion crates/cdk-mintd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ rust-version.workspace = true
readme = "README.md"

[features]
default = ["management-rpc", "cln", "lnd", "lnbits", "fakewallet", "grpc-processor", "sqlite"]
default = ["management-rpc", "cln", "lnd", "lnbits", "fakewallet", "grpc-processor", "sqlite", "strike"]
# Database features - at least one must be enabled
sqlite = ["dep:cdk-sqlite"]
postgres = ["dep:cdk-postgres"]
Expand All @@ -30,6 +30,9 @@ redis = ["cdk-axum/redis"]
auth = ["cdk/auth", "cdk-axum/auth", "cdk-sqlite?/auth", "cdk-postgres?/auth"]
prometheus = ["cdk/prometheus", "dep:cdk-prometheus", "cdk-sqlite?/prometheus", "cdk-axum/prometheus"]

# Agicash Fork additions
strike = ["dep:cdk-strike"]

[dependencies]
anyhow.workspace = true
async-trait.workspace = true
Expand Down Expand Up @@ -69,6 +72,9 @@ home.workspace = true
utoipa = { workspace = true, optional = true }
utoipa-swagger-ui = { version = "9.0.0", features = ["axum"], optional = true }

# Agicash Fork additions
cdk-strike = { workspace = true, optional = true }

[lints]
workspace = true

Expand Down
8 changes: 7 additions & 1 deletion crates/cdk-mintd/example.config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ max_connections = 20
connection_timeout_seconds = 10

[ln]
# Required ln backend `cln`, `lnd`, `fakewallet`, 'lnbits', 'ldknode'
# Required ln backend `cln`, `lnd`, `fakewallet`, 'lnbits', 'ldknode', 'strike'
ln_backend = "fakewallet"
# min_mint=1
# max_mint=500000
Expand Down Expand Up @@ -175,6 +175,12 @@ max_delay_time = 3
# the get_settings() response. The mint will automatically create routes
# for these methods (e.g., /v1/mint/quote/paypal, /v1/mint/paypal, etc.)

# [strike]
# api_key = "your_strike_api_key_here"
# supported_units = ["sat"]
# Optional: Override webhook URL when mint is behind NAT or has different internal/external URLs
# webhook_url = "https://your-public-domain.com"

# [auth]
# Set to true to enable authentication features (defaults to false)
# auth_enabled = false
Expand Down
17 changes: 17 additions & 0 deletions crates/cdk-mintd/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ pub enum LnBackend {
LdkNode,
#[cfg(feature = "grpc-processor")]
GrpcProcessor,
#[cfg(feature = "strike")]
Strike,
}

impl std::str::FromStr for LnBackend {
Expand All @@ -157,6 +159,8 @@ impl std::str::FromStr for LnBackend {
"ldk-node" | "ldknode" => Ok(LnBackend::LdkNode),
#[cfg(feature = "grpc-processor")]
"grpcprocessor" => Ok(LnBackend::GrpcProcessor),
#[cfg(feature = "strike")]
"strike" => Ok(LnBackend::Strike),
_ => Err(format!("Unknown Lightning backend: {s}")),
}
}
Expand Down Expand Up @@ -424,6 +428,17 @@ fn default_grpc_port() -> u16 {
50051
}

#[cfg(feature = "strike")]
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Strike {
pub api_key: String,
pub supported_units: Vec<CurrencyUnit>,
/// Optional webhook URL base. If not set, uses the mint's info.url.
/// Set this when your mint runs behind NAT or has different internal/external URLs.
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
#[serde(rename_all = "lowercase")]
pub enum DatabaseEngine {
Expand Down Expand Up @@ -574,6 +589,8 @@ pub struct Settings {
pub auth: Option<Auth>,
#[cfg(feature = "prometheus")]
pub prometheus: Option<Prometheus>,
#[cfg(feature = "strike")]
pub strike: Option<Strike>,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
Expand Down
8 changes: 8 additions & 0 deletions crates/cdk-mintd/src/env_vars/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ mod lnd;
mod management_rpc;
#[cfg(feature = "prometheus")]
mod prometheus;
#[cfg(feature = "strike")]
mod strike;

use std::env;
use std::str::FromStr;
Expand Down Expand Up @@ -55,6 +57,8 @@ pub use management_rpc::*;
pub use mint_info::*;
#[cfg(feature = "prometheus")]
pub use prometheus::*;
#[cfg(feature = "strike")]
pub use strike::*;

use crate::config::{DatabaseEngine, LnBackend, Settings};

Expand Down Expand Up @@ -149,6 +153,10 @@ impl Settings {
self.grpc_processor =
Some(self.grpc_processor.clone().unwrap_or_default().from_env());
}
#[cfg(feature = "strike")]
LnBackend::Strike => {
self.strike = Some(self.strike.clone().unwrap_or_default().from_env());
}
LnBackend::None => bail!("Ln backend must be set"),
#[allow(unreachable_patterns)]
_ => bail!("Selected Ln backend is not enabled in this build"),
Expand Down
35 changes: 35 additions & 0 deletions crates/cdk-mintd/src/env_vars/strike.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! Strike environment variables

use std::env;

use cdk::nuts::CurrencyUnit;

use crate::config::Strike;

pub const ENV_STRIKE_API_KEY: &str = "CDK_MINTD_STRIKE_API_KEY";
pub const ENV_STRIKE_SUPPORTED_UNITS: &str = "CDK_MINTD_STRIKE_SUPPORTED_UNITS";
pub const ENV_STRIKE_WEBHOOK_URL: &str = "CDK_MINTD_STRIKE_WEBHOOK_URL";

impl Strike {
pub fn from_env(mut self) -> Self {
if let Ok(api_key) = env::var(ENV_STRIKE_API_KEY) {
self.api_key = api_key;
}

if let Ok(units_str) = env::var(ENV_STRIKE_SUPPORTED_UNITS) {
let units: Vec<CurrencyUnit> = units_str
.split(',')
.filter_map(|unit| unit.trim().parse().ok())
.collect();
if !units.is_empty() {
self.supported_units = units;
}
}

if let Ok(webhook_url) = env::var(ENV_STRIKE_WEBHOOK_URL) {
self.webhook_url = Some(webhook_url);
}

self
}
}
56 changes: 48 additions & 8 deletions crates/cdk-mintd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ use cdk::nuts::nut00::KnownMethod;
feature = "lnd",
feature = "ldk-node",
feature = "fakewallet",
feature = "grpc-processor"
feature = "grpc-processor",
feature = "strike"
))]
use cdk::nuts::nut17::SupportedMethods;
use cdk::nuts::nut19::{CachedEndpoint, Method as NUT19Method, Path as NUT19Path};
#[cfg(any(
feature = "cln",
feature = "lnbits",
feature = "lnd",
feature = "ldk-node"
feature = "ldk-node",
feature = "strike"
))]
use cdk::nuts::CurrencyUnit;
#[cfg(feature = "auth")]
Expand Down Expand Up @@ -347,12 +349,12 @@ async fn configure_mint_builder(
runtime: Option<std::sync::Arc<tokio::runtime::Runtime>>,
work_dir: &Path,
kv_store: Option<Arc<dyn KVStore<Err = cdk::cdk_database::Error> + Send + Sync>>,
) -> Result<MintBuilder> {
) -> Result<(MintBuilder, Vec<Router>)> {
// Configure basic mint information
let mint_builder = configure_basic_info(settings, mint_builder);

// Configure lightning backend
let mint_builder =
let (mint_builder, additional_routers) =
configure_lightning_backend(settings, mint_builder, runtime, work_dir, kv_store).await?;

// Extract configured payment methods from mint_builder
Expand All @@ -368,7 +370,7 @@ async fn configure_mint_builder(
// Configure caching with payment methods
let mint_builder = configure_cache(settings, mint_builder, &payment_methods);

Ok(mint_builder)
Ok((mint_builder, additional_routers))
}

/// Configures basic mint information (name, contact info, descriptions, etc.)
Expand Down Expand Up @@ -447,7 +449,7 @@ async fn configure_lightning_backend(
_runtime: Option<std::sync::Arc<tokio::runtime::Runtime>>,
work_dir: &Path,
_kv_store: Option<Arc<dyn KVStore<Err = cdk::cdk_database::Error> + Send + Sync>>,
) -> Result<MintBuilder> {
) -> Result<(MintBuilder, Vec<Router>)> {
let mint_melt_limits = MintMeltLimits {
mint_min: settings.ln.min_mint,
mint_max: settings.ln.max_mint,
Expand Down Expand Up @@ -586,6 +588,41 @@ async fn configure_lightning_backend(
)
.await?;
}
#[cfg(feature = "strike")]
LnBackend::Strike => {
let strike_settings = settings.clone().strike.expect("Checked at config load");
tracing::info!(
"Using Strike backend with supported units: {:?}",
strike_settings.supported_units
);

let mut webhook_routers = Vec::new();

for unit in &strike_settings.supported_units {
let kv_store = _kv_store
.clone()
.ok_or_else(|| anyhow!("KV store is required for Strike backend"))?;
let (strike, webhook_router) = strike_settings
.setup(settings, unit.clone(), kv_store)
.await?;

webhook_routers.push(webhook_router);

#[cfg(feature = "prometheus")]
let strike = MetricsMintPayment::new(strike);

mint_builder = configure_backend_for_unit(
settings,
mint_builder,
unit.clone(),
mint_melt_limits,
Arc::new(strike),
)
.await?;
}

return Ok((mint_builder, webhook_routers));
}
LnBackend::None => {
tracing::error!(
"Payment backend was not set or feature disabled. {:?}",
Expand All @@ -595,7 +632,7 @@ async fn configure_lightning_backend(
}
};

Ok(mint_builder)
Ok((mint_builder, vec![]))
}

/// Helper function to configure a mint builder with a lightning backend for a specific currency unit
Expand Down Expand Up @@ -1370,7 +1407,7 @@ pub async fn run_mintd_with_shutdown(
}
};

let mint_builder =
let (mint_builder, additional_routers) =
configure_mint_builder(settings, maybe_mint_builder, runtime, work_dir, Some(kv)).await?;
#[cfg(feature = "auth")]
let (mint_builder, auth_localstore) =
Expand All @@ -1384,6 +1421,9 @@ pub async fn run_mintd_with_shutdown(

let mint = Arc::new(mint);

let mut routers = routers;
routers.extend(additional_routers);

start_services_with_shutdown(
mint.clone(),
settings,
Expand Down
Loading