Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Wallet TransactionDatabase; Create WalletBuilder #581

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
90 changes: 35 additions & 55 deletions crates/cdk-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ use std::sync::Arc;
use anyhow::{bail, Result};
use bip39::rand::{thread_rng, Rng};
use bip39::Mnemonic;
use cdk::cdk_database;
use cdk::cdk_database::WalletDatabase;
use cdk::cdk_database::WalletProofDatabase;
use cdk::nuts::CurrencyUnit;
use cdk::wallet::client::HttpClient;
use cdk::wallet::{MultiMintWallet, Wallet};
use cdk::wallet::{MultiMintWallet, Wallet, WalletBuilder};
use cdk_redb::WalletRedbDatabase;
use cdk_sqlite::WalletSqliteDatabase;
use clap::{Parser, Subcommand};
Expand Down Expand Up @@ -102,24 +102,6 @@ async fn main() -> Result<()> {

fs::create_dir_all(&work_dir)?;

let localstore: Arc<dyn WalletDatabase<Err = cdk_database::Error> + Send + Sync> =
match args.engine.as_str() {
"sqlite" => {
let sql_path = work_dir.join("cdk-cli.sqlite");
let sql = WalletSqliteDatabase::new(&sql_path).await?;

sql.migrate().await;

Arc::new(sql)
}
"redb" => {
let redb_path = work_dir.join("cdk-cli.redb");

Arc::new(WalletRedbDatabase::new(&redb_path)?)
}
_ => bail!("Unknown DB engine"),
};

let seed_path = work_dir.join("seed");

let mnemonic = match fs::metadata(seed_path.clone()) {
Expand All @@ -140,24 +122,40 @@ async fn main() -> Result<()> {
}
};

let mut wallets: Vec<Wallet> = Vec::new();
let mut builder = WalletBuilder::new(mnemonic.to_seed_normalized("").to_vec());

let mints = match args.engine.as_str() {
"sqlite" => {
let sql_path = work_dir.join("cdk-cli.sqlite");
let sql = WalletSqliteDatabase::new(&sql_path).await?;

let mints = localstore.get_mints().await?;
sql.migrate().await;

let db = Arc::new(sql);
builder = builder.proof_db(db.clone()).transaction_db(db.clone());
db.get_mints().await?
}
"redb" => {
let redb_path = work_dir.join("cdk-cli.redb");

let db = Arc::new(WalletRedbDatabase::new(&redb_path)?);
builder = builder.proof_db(db.clone()).transaction_db(db.clone());
db.get_mints().await?
}
_ => bail!("Unknown DB engine"),
};

let mut wallets: Vec<Wallet> = Vec::new();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make something more reusable? A single place to convert a string into the struct, something like this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems like a good idea for another PR.


for (mint_url, _) in mints {
let mut wallet = Wallet::new(
&mint_url.to_string(),
cdk::nuts::CurrencyUnit::Sat,
localstore.clone(),
&mnemonic.to_seed_normalized(""),
None,
)?;
let mut builder = builder.clone();

if let Some(proxy_url) = args.proxy.as_ref() {
let http_client = HttpClient::with_proxy(mint_url, proxy_url.clone(), None, true)?;
wallet.set_client(http_client);
let http_client =
HttpClient::with_proxy(mint_url.clone(), proxy_url.clone(), None, true)?;
builder = builder.client(Arc::new(http_client));
}

wallets.push(wallet);
wallets.push(builder.build(mint_url, CurrencyUnit::Sat)?);
}

let multi_mint_wallet = MultiMintWallet::new(wallets);
Expand All @@ -171,13 +169,7 @@ async fn main() -> Result<()> {
sub_commands::melt::pay(&multi_mint_wallet, sub_command_args).await
}
Commands::Receive(sub_command_args) => {
sub_commands::receive::receive(
&multi_mint_wallet,
localstore,
&mnemonic.to_seed_normalized(""),
sub_command_args,
)
.await
sub_commands::receive::receive(&multi_mint_wallet, builder, sub_command_args).await
}
Commands::Send(sub_command_args) => {
sub_commands::send::send(&multi_mint_wallet, sub_command_args).await
Expand All @@ -189,13 +181,7 @@ async fn main() -> Result<()> {
sub_commands::mint_info::mint_info(args.proxy, sub_command_args).await
}
Commands::Mint(sub_command_args) => {
sub_commands::mint::mint(
&multi_mint_wallet,
&mnemonic.to_seed_normalized(""),
localstore,
sub_command_args,
)
.await
sub_commands::mint::mint(&multi_mint_wallet, builder, sub_command_args).await
}
Commands::MintPending => {
sub_commands::pending_mints::mint_pending(&multi_mint_wallet).await
Expand All @@ -204,13 +190,7 @@ async fn main() -> Result<()> {
sub_commands::burn::burn(&multi_mint_wallet, sub_command_args).await
}
Commands::Restore(sub_command_args) => {
sub_commands::restore::restore(
&multi_mint_wallet,
&mnemonic.to_seed_normalized(""),
localstore,
sub_command_args,
)
.await
sub_commands::restore::restore(&multi_mint_wallet, builder, sub_command_args).await
}
Commands::UpdateMintUrl(sub_command_args) => {
sub_commands::update_mint_url::update_mint_url(&multi_mint_wallet, sub_command_args)
Expand Down
9 changes: 3 additions & 6 deletions crates/cdk-cli/src/sub_commands/mint.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
use std::str::FromStr;
use std::sync::Arc;

use anyhow::Result;
use cdk::amount::SplitTarget;
use cdk::cdk_database::{Error, WalletDatabase};
use cdk::mint_url::MintUrl;
use cdk::nuts::nut00::ProofsMethods;
use cdk::nuts::{CurrencyUnit, MintQuoteState, NotificationPayload};
use cdk::wallet::types::WalletKey;
use cdk::wallet::{MultiMintWallet, Wallet, WalletSubscription};
use cdk::wallet::{MultiMintWallet, WalletBuilder, WalletSubscription};
use cdk::Amount;
use clap::Args;
use serde::{Deserialize, Serialize};
Expand All @@ -29,8 +27,7 @@ pub struct MintSubCommand {

pub async fn mint(
multi_mint_wallet: &MultiMintWallet,
seed: &[u8],
localstore: Arc<dyn WalletDatabase<Err = Error> + Sync + Send>,
builder: WalletBuilder,
sub_command_args: &MintSubCommand,
) -> Result<()> {
let mint_url = sub_command_args.mint_url.clone();
Expand All @@ -43,7 +40,7 @@ pub async fn mint(
{
Some(wallet) => wallet.clone(),
None => {
let wallet = Wallet::new(&mint_url.to_string(), unit, localstore, seed, None)?;
let wallet = builder.build(mint_url.clone(), CurrencyUnit::Sat)?;

multi_mint_wallet.add_wallet(wallet.clone()).await;
wallet
Expand Down
34 changes: 7 additions & 27 deletions crates/cdk-cli/src/sub_commands/receive.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use std::collections::HashSet;
use std::str::FromStr;
use std::sync::Arc;

use anyhow::{anyhow, Result};
use cdk::cdk_database::{self, WalletDatabase};
use cdk::nuts::{SecretKey, Token};
use cdk::util::unix_time;
use cdk::wallet::multi_mint_wallet::MultiMintWallet;
use cdk::wallet::types::WalletKey;
use cdk::wallet::Wallet;
use cdk::wallet::WalletBuilder;
use cdk::Amount;
use clap::Args;
use nostr_sdk::nips::nip04;
Expand Down Expand Up @@ -37,8 +34,7 @@ pub struct ReceiveSubCommand {

pub async fn receive(
multi_mint_wallet: &MultiMintWallet,
localstore: Arc<dyn WalletDatabase<Err = cdk_database::Error> + Send + Sync>,
seed: &[u8],
builder: WalletBuilder,
sub_command_args: &ReceiveSubCommand,
) -> Result<()> {
let mut signing_keys = Vec::new();
Expand All @@ -64,8 +60,7 @@ pub async fn receive(
Some(token_str) => {
receive_token(
multi_mint_wallet,
localstore,
seed,
builder,
token_str,
&signing_keys,
&sub_command_args.preimage,
Expand All @@ -89,18 +84,14 @@ pub async fn receive(
signing_keys.push(nostr_key.clone());

let relays = sub_command_args.relay.clone();
let since = localstore
.get_nostr_last_checked(&nostr_key.public_key())
.await?;

let tokens = nostr_receive(relays, nostr_key.clone(), since).await?;
let tokens = nostr_receive(relays, nostr_key.clone(), None).await?;

let mut total_amount = Amount::ZERO;
for token_str in &tokens {
match receive_token(
multi_mint_wallet,
localstore.clone(),
seed,
builder.clone(),
token_str,
&signing_keys,
&sub_command_args.preimage,
Expand All @@ -115,10 +106,6 @@ pub async fn receive(
}
}
}

localstore
.add_nostr_last_checked(nostr_key.public_key(), unix_time() as u32)
.await?;
total_amount
}
};
Expand All @@ -130,8 +117,7 @@ pub async fn receive(

async fn receive_token(
multi_mint_wallet: &MultiMintWallet,
localstore: Arc<dyn WalletDatabase<Err = cdk_database::Error> + Send + Sync>,
seed: &[u8],
builder: WalletBuilder,
token_str: &str,
signing_keys: &[SecretKey],
preimage: &[String],
Expand All @@ -143,13 +129,7 @@ async fn receive_token(
let wallet_key = WalletKey::new(mint_url.clone(), token.unit().unwrap_or_default());

if multi_mint_wallet.get_wallet(&wallet_key).await.is_none() {
let wallet = Wallet::new(
&mint_url.to_string(),
token.unit().unwrap_or_default(),
localstore,
seed,
None,
)?;
let wallet = builder.build(mint_url.clone(), token.unit().unwrap_or_default())?;
multi_mint_wallet.add_wallet(wallet).await;
}

Expand Down
9 changes: 3 additions & 6 deletions crates/cdk-cli/src/sub_commands/restore.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use std::str::FromStr;
use std::sync::Arc;

use anyhow::Result;
use cdk::cdk_database::{Error, WalletDatabase};
use cdk::mint_url::MintUrl;
use cdk::nuts::CurrencyUnit;
use cdk::wallet::types::WalletKey;
use cdk::wallet::{MultiMintWallet, Wallet};
use cdk::wallet::{MultiMintWallet, WalletBuilder};
use clap::Args;

#[derive(Args)]
Expand All @@ -20,8 +18,7 @@ pub struct RestoreSubCommand {

pub async fn restore(
multi_mint_wallet: &MultiMintWallet,
seed: &[u8],
localstore: Arc<dyn WalletDatabase<Err = Error> + Sync + Send>,
builder: WalletBuilder,
sub_command_args: &RestoreSubCommand,
) -> Result<()> {
let unit = CurrencyUnit::from_str(&sub_command_args.unit)?;
Expand All @@ -33,7 +30,7 @@ pub async fn restore(
{
Some(wallet) => wallet.clone(),
None => {
let wallet = Wallet::new(&mint_url.to_string(), unit, localstore, seed, None)?;
let wallet = builder.build(mint_url, CurrencyUnit::Sat)?;

multi_mint_wallet.add_wallet(wallet.clone()).await;
wallet
Expand Down
12 changes: 11 additions & 1 deletion crates/cdk-common/src/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ mod mint;
#[cfg(feature = "wallet")]
mod wallet;

use cashu::util::hex;
#[cfg(feature = "mint")]
pub use mint::Database as MintDatabase;
#[cfg(feature = "wallet")]
pub use wallet::Database as WalletDatabase;
pub use wallet::{
Database as WalletDatabase, ProofDatabase as WalletProofDatabase, Transaction,
TransactionDatabase as WalletTransactionDatabase, TransactionDirection, TransactionId,
};

/// CDK_database error
#[derive(Debug, thiserror::Error)]
Expand All @@ -31,4 +35,10 @@ pub enum Error {
/// Unknown Quote
#[error("Unknown Quote")]
UnknownQuote,
/// Hex error
#[error(transparent)]
HexError(#[from] hex::Error),
/// Invalid Transaction Direction
#[error("Invalid Transaction Direction")]
InvalidTransactionDirection,
}
Loading
Loading