diff --git a/integrationtests/tests/tests.rs b/integrationtests/tests/tests.rs index 5afeb8e4..0d3a1328 100644 --- a/integrationtests/tests/tests.rs +++ b/integrationtests/tests/tests.rs @@ -4,10 +4,10 @@ use moksha_wallet::client::CashuClient; use moksha_wallet::http::CrossPlatformHttpClient; use moksha_wallet::localstore::sqlite::SqliteLocalStore; use moksha_wallet::wallet::WalletBuilder; -use mokshamint::database::postgres::PostgresDB; + use mokshamint::lightning::lnbits::LnbitsLightningSettings; use mokshamint::lightning::LightningType; -use mokshamint::mint::Mint; +use mokshamint::mint::MintBuilder; use reqwest::Url; use std::collections::HashMap; use std::thread; @@ -45,17 +45,13 @@ pub fn test_integration() -> anyhow::Result<()> { ), }; - let db = PostgresDB::new(&db_config) - .await - .expect("Could not create db"); - db.migrate().await; - let mint = Mint::builder() + let mint = MintBuilder::new() .with_private_key("my_private_key".to_string()) .with_server(Some(ServerConfig { host_port: "127.0.0.1:8686".parse().expect("invalid address"), ..Default::default() })) - .with_db(Some(db)) + .with_db(Some(db_config)) .with_lightning(LightningType::Lnbits(LnbitsLightningSettings::new( "my_admin_key", "http://127.0.0.1:6100", diff --git a/moksha-mint/src/bin/moksha-mint.rs b/moksha-mint/src/bin/moksha-mint.rs index e221ff9f..7e14a484 100644 --- a/moksha-mint/src/bin/moksha-mint.rs +++ b/moksha-mint/src/bin/moksha-mint.rs @@ -1,8 +1,4 @@ -use mokshamint::{ - config::{DatabaseConfig, MintConfig}, - database::postgres::PostgresDB, - mint::MintBuilder, -}; +use mokshamint::{config::MintConfig, mint::MintBuilder}; use std::{env, fmt}; #[tokio::main] @@ -30,22 +26,15 @@ pub async fn main() -> anyhow::Result<()> { btconchain_backend, lightning_backend, tracing, + database, } = MintConfig::read_config_with_defaults(); - // FIXME - let db_config = DatabaseConfig { - db_url: env::var("MINT_DB_URL").expect("MINT_DB_URL not set"), - }; - - let db = PostgresDB::new(&db_config).await?; - db.migrate().await; - let mint = MintBuilder::new() .with_mint_info(Some(info)) .with_server(Some(server)) .with_private_key(privatekey) .with_derivation_path(derivation_path) - .with_db(Some(db)) + .with_db(Some(database)) .with_lightning(lightning_backend.expect("lightning not set")) .with_btc_onchain(btconchain_backend) .with_fee(Some(lightning_fee)) diff --git a/moksha-mint/src/config.rs b/moksha-mint/src/config.rs index 315688fe..03fdd4cb 100644 --- a/moksha-mint/src/config.rs +++ b/moksha-mint/src/config.rs @@ -75,6 +75,7 @@ pub struct MintConfig { pub btconchain_backend: Option, pub lightning_backend: Option, pub tracing: Option, + pub database: DatabaseConfig, } impl From<(Opts, LightningType, Option)> for MintConfig { @@ -88,6 +89,7 @@ impl From<(Opts, LightningType, Option)> for MintConfig { btconchain_backend: btc, lightning_backend: Some(ln), tracing: opts.tracing, + database: opts.database, } } } @@ -127,6 +129,7 @@ impl MintConfig { info: MintInfoConfig, lightning_fee: LightningFeeConfig, server: ServerConfig, + database: DatabaseConfig, btconchain_backend: Option, lightning_backend: Option, tracing: Option, @@ -140,6 +143,7 @@ impl MintConfig { btconchain_backend, lightning_backend, tracing, + database, } } } diff --git a/moksha-mint/src/mint.rs b/moksha-mint/src/mint.rs index ee97959a..9999bc1a 100644 --- a/moksha-mint/src/mint.rs +++ b/moksha-mint/src/mint.rs @@ -74,10 +74,6 @@ where } } - pub fn builder() -> MintBuilder { - MintBuilder::new() - } - pub fn fee_reserve(&self, amount_msat: u64) -> u64 { let fee_percent = self.config.lightning_fee.fee_percent as f64 / 100.0; let fee_reserve = (amount_msat as f64 * fee_percent) as u64; @@ -289,14 +285,15 @@ where } #[derive(Debug, Default)] -pub struct MintBuilder -where - DB: Database, -{ +// pub struct MintBuilder +// where +// DB: Database, +pub struct MintBuilder { private_key: Option, derivation_path: Option, lightning_type: Option, - db: Option, + + db_config: Option, fee_config: Option, mint_info_settings: Option, server_config: Option, @@ -304,16 +301,16 @@ where tracing_config: Option, } -impl MintBuilder -where - DB: Database, -{ +// impl MintBuilder +// where +// DB: Database, +impl MintBuilder { pub fn new() -> Self { MintBuilder { private_key: None, derivation_path: None, lightning_type: None, - db: None, + db_config: None, fee_config: None, mint_info_settings: None, server_config: None, @@ -322,8 +319,8 @@ where } } - pub fn with_db(mut self, db: Option) -> Self { - self.db = db; + pub fn with_db(mut self, db_config: Option) -> Self { + self.db_config = db_config; self } @@ -367,7 +364,7 @@ where self } - pub async fn build(self) -> Result, MokshaMintError> { + pub async fn build(self) -> Result, MokshaMintError> { let ln: Arc = match self.lightning_type.clone() { Some(LightningType::Lnbits(lnbits_settings)) => Arc::new(LnbitsLightning::new( lnbits_settings.admin_key.expect("LNBITS_ADMIN_KEY not set"), @@ -418,13 +415,16 @@ where )), _ => None, }; + let db_config = self.db_config.expect("db-config not set"); + let db = PostgresDB::new(&db_config).await?; + db.migrate().await; Ok(Mint::new( ln, self.lightning_type .clone() .expect("Lightning backend not set"), - self.db.expect("Database not set"), + db, // FIXME simplify config creation MintConfig::new( self.private_key.expect("private-key not set"), @@ -432,6 +432,7 @@ where self.mint_info_settings.unwrap_or_default(), self.fee_config.expect("fee-config not set"), self.server_config.unwrap_or_default(), + db_config, self.btc_onchain_config, self.lightning_type, self.tracing_config, @@ -498,7 +499,7 @@ mod tests { async fn test_mint_empty() -> anyhow::Result<()> { let mut lightning = MockLightning::new(); lightning.expect_is_invoice_paid().returning(|_| Ok(true)); - let mint = create_mint_from_mocks(Some(create_mock_mint().await?), Some(lightning)).await?; + let mint = create_mint_from_mocks(Some(create_mock_db().await?), Some(lightning)).await?; let mut tx = mint.db.begin_tx().await?; let outputs = vec![]; @@ -520,7 +521,7 @@ mod tests { async fn test_mint_valid() -> anyhow::Result<()> { let mut lightning = MockLightning::new(); lightning.expect_is_invoice_paid().returning(|_| Ok(true)); - let mint = create_mint_from_mocks(Some(create_mock_mint().await?), Some(lightning)).await?; + let mint = create_mint_from_mocks(Some(create_mock_db().await?), Some(lightning)).await?; let outputs = create_blinded_msgs_from_fixture("blinded_messages_40.json".to_string())?; let mut tx = mint.db.begin_tx().await?; @@ -586,52 +587,61 @@ mod tests { Ok(()) } - // FIXME - // #[tokio::test] - // /// melt 20 sats with 60 tokens and receive 40 tokens as change - // async fn test_melt_overpay() -> anyhow::Result<()> { - // use lightning_invoice::Bolt11Invoice as LNInvoice; - - // let mut lightning = MockLightning::new(); - - // lightning.expect_decode_invoice().returning(|_| { - // Ok( - // // 20 sat - // LNInvoice::from_str("lnbc200n1pj9eanxsp5agdl4rd0twdljpcgmg67dwj9mseu5m4lwfhslkws4uh4m5f5pcrqpp5lvspx676rykr64l02s97wjztcxe355qck0naydrsvvkqw42cc35sdq2f38xy6t5wvxqzjccqpjrzjq027t9tsc6jn5ve2k6gnn689unn8h239juuf9s3ce09aty6ed73t5z7nqsqqsygqqyqqqqqqqqqqqqgq9q9qyysgqs5msn4j9v53fq000zhw0gulkcx2dlnfdt953v2ur7z765jj3m0fx6cppkpjwntq5nsqm273u4eevva508pvepg8mh27sqcd29sfjr4cq255a40").expect("invalid invoice") - // ) - // }); - // lightning.expect_pay_invoice().returning(|_| { - // Ok(PayInvoiceResult { - // payment_hash: "hash".to_string(), - // total_fees: 2, - // }) - // .map_err(|_err: LightningError| MokshaMintError::InvoiceNotFound("".to_string())) - // }); - - // let mint = Mint::new( - // // "TEST_PRIVATE_KEY".to_string(), - // // "0/0/0/0".to_string(), - // Arc::new(lightning), - // LightningType::Lnbits(Default::default()), - // Arc::new(create_mock_db_get_used_proofs()), - // Default::default(), - // Default::default(), - // Some(Arc::new(MockBtcOnchain::default())), - // ); - - // let tokens = create_token_from_fixture("token_60.cashu".to_string())?; - // let invoice = "some invoice".to_string(); - // let change = - // create_blinded_msgs_from_fixture("blinded_messages_blank_4000.json".to_string())?; - - // let (paid, _payment_hash, change) = mint - // .melt_bolt11(invoice, 4, &tokens.proofs(), &change, &mint.keyset_legacy) - // .await?; - - // assert!(paid); - // assert!(change.total_amount() == 2); - // Ok(()) - // } + #[tokio::test] + /// melt 20 sats with 60 tokens and receive 40 tokens as change + async fn test_melt_overpay() -> anyhow::Result<()> { + use lightning_invoice::Bolt11Invoice as LNInvoice; + + let mut lightning = MockLightning::new(); + + lightning.expect_decode_invoice().returning(|_| { + Ok( + // 20 sat + LNInvoice::from_str("lnbc200n1pj9eanxsp5agdl4rd0twdljpcgmg67dwj9mseu5m4lwfhslkws4uh4m5f5pcrqpp5lvspx676rykr64l02s97wjztcxe355qck0naydrsvvkqw42cc35sdq2f38xy6t5wvxqzjccqpjrzjq027t9tsc6jn5ve2k6gnn689unn8h239juuf9s3ce09aty6ed73t5z7nqsqqsygqqyqqqqqqqqqqqqgq9q9qyysgqs5msn4j9v53fq000zhw0gulkcx2dlnfdt953v2ur7z765jj3m0fx6cppkpjwntq5nsqm273u4eevva508pvepg8mh27sqcd29sfjr4cq255a40").expect("invalid invoice") + ) + }); + lightning.expect_pay_invoice().returning(|_| { + Ok(PayInvoiceResult { + payment_hash: "hash".to_string(), + total_fees: 2, + }) + .map_err(|_err: LightningError| MokshaMintError::InvoiceNotFound("".to_string())) + }); + + let db = create_mock_db_get_used_proofs().await?; + + let mint = Mint::new( + // "TEST_PRIVATE_KEY".to_string(), + // "0/0/0/0".to_string(), + Arc::new(lightning), + LightningType::Lnbits(Default::default()), + db, + Default::default(), + Default::default(), + Some(Arc::new(MockBtcOnchain::default())), + ); + + let tokens = create_token_from_fixture("token_60.cashu".to_string())?; + let invoice = "some invoice".to_string(); + let change = + create_blinded_msgs_from_fixture("blinded_messages_blank_4000.json".to_string())?; + + let mut tx = mint.db.begin_tx().await?; + let (paid, _payment_hash, change) = mint + .melt_bolt11( + &mut tx, + invoice, + 4, + &tokens.proofs(), + &change, + &mint.keyset_legacy, + ) + .await?; + + assert!(paid); + assert!(change.total_amount() == 2); + Ok(()) + } // FIXME refactor helper functions fn create_token_from_fixture(fixture: String) -> Result { @@ -702,7 +712,7 @@ mod tests { .await?) } - async fn create_mock_mint() -> anyhow::Result { + async fn create_mock_db() -> anyhow::Result { // FIXME start postgres db and use different port Ok(PostgresDB::new(&DatabaseConfig { db_url: "postgres://localhost:5432".to_string(),