mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-10 15:45:59 +01:00
refactor: cdk-cli use multimint wallet
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
|
||||
### Changed
|
||||
- cdk(wallet): `fn send` returns `Token` so the user can use the struct of convert it to a v3 or v4 string.
|
||||
- cdk(wallet): Publicly export `MultiMintWallet` ([thesimplekid]).
|
||||
|
||||
### Added
|
||||
- cdk(NUT-11): Add `Copy` on `SigFlag` ([thesimplekid]).
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
@@ -6,9 +5,9 @@ use std::sync::Arc;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use bip39::Mnemonic;
|
||||
use cdk::cdk_database;
|
||||
use cdk::cdk_database::WalletDatabase;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::{cdk_database, UncheckedUrl};
|
||||
use cdk::wallet::{MultiMintWallet, Wallet};
|
||||
use cdk_redb::WalletRedbDatabase;
|
||||
use cdk_sqlite::WalletSqliteDatabase;
|
||||
use clap::{Parser, Subcommand};
|
||||
@@ -126,7 +125,7 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
let mut wallets: HashMap<UncheckedUrl, Wallet> = HashMap::new();
|
||||
let mut wallets: Vec<Wallet> = Vec::new();
|
||||
|
||||
let mints = localstore.get_mints().await?;
|
||||
|
||||
@@ -139,49 +138,50 @@ async fn main() -> Result<()> {
|
||||
None,
|
||||
);
|
||||
|
||||
wallets.insert(mint, wallet);
|
||||
wallets.push(wallet);
|
||||
}
|
||||
|
||||
let multi_mint_wallet = MultiMintWallet::new(wallets);
|
||||
|
||||
match &args.command {
|
||||
Commands::DecodeToken(sub_command_args) => {
|
||||
sub_commands::decode_token::decode_token(sub_command_args)
|
||||
}
|
||||
Commands::Balance => sub_commands::balance::balance(wallets).await,
|
||||
Commands::Pay => sub_commands::melt::pay(wallets).await,
|
||||
Commands::Balance => sub_commands::balance::balance(&multi_mint_wallet).await,
|
||||
Commands::Pay => sub_commands::melt::pay(multi_mint_wallet).await,
|
||||
Commands::Receive(sub_command_args) => {
|
||||
sub_commands::receive::receive(
|
||||
wallets,
|
||||
&mnemonic.to_seed_normalized(""),
|
||||
localstore,
|
||||
sub_command_args,
|
||||
)
|
||||
.await
|
||||
sub_commands::receive::receive(&multi_mint_wallet, localstore, sub_command_args).await
|
||||
}
|
||||
Commands::Send(sub_command_args) => {
|
||||
sub_commands::send::send(wallets, sub_command_args).await
|
||||
sub_commands::send::send(&multi_mint_wallet, sub_command_args).await
|
||||
}
|
||||
Commands::CheckSpendable => {
|
||||
sub_commands::check_spent::check_spent(&multi_mint_wallet).await
|
||||
}
|
||||
Commands::CheckSpendable => sub_commands::check_spent::check_spent(wallets).await,
|
||||
Commands::MintInfo(sub_command_args) => {
|
||||
sub_commands::mint_info::mint_info(sub_command_args).await
|
||||
}
|
||||
Commands::Mint(sub_command_args) => {
|
||||
sub_commands::mint::mint(
|
||||
wallets,
|
||||
&multi_mint_wallet,
|
||||
&mnemonic.to_seed_normalized(""),
|
||||
localstore,
|
||||
sub_command_args,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Commands::MintPending => sub_commands::pending_mints::mint_pending(wallets).await,
|
||||
Commands::MintPending => {
|
||||
sub_commands::pending_mints::mint_pending(&multi_mint_wallet).await
|
||||
}
|
||||
Commands::Burn(sub_command_args) => {
|
||||
sub_commands::burn::burn(wallets, sub_command_args).await
|
||||
sub_commands::burn::burn(&multi_mint_wallet, sub_command_args).await
|
||||
}
|
||||
Commands::Restore(sub_command_args) => {
|
||||
sub_commands::restore::restore(wallets, sub_command_args).await
|
||||
sub_commands::restore::restore(&multi_mint_wallet, sub_command_args).await
|
||||
}
|
||||
Commands::UpdateMintUrl(sub_command_args) => {
|
||||
sub_commands::update_mint_url::update_mint_url(wallets, sub_command_args).await
|
||||
sub_commands::update_mint_url::update_mint_url(&multi_mint_wallet, sub_command_args)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use cdk::nuts::CurrencyUnit;
|
||||
use cdk::url::UncheckedUrl;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::wallet::multi_mint_wallet::MultiMintWallet;
|
||||
use cdk::Amount;
|
||||
|
||||
pub async fn balance(wallets: HashMap<UncheckedUrl, Wallet>) -> Result<()> {
|
||||
mint_balances(wallets).await?;
|
||||
pub async fn balance(multi_mint_wallet: &MultiMintWallet) -> Result<()> {
|
||||
mint_balances(multi_mint_wallet).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn mint_balances(
|
||||
wallets: HashMap<UncheckedUrl, Wallet>,
|
||||
) -> Result<Vec<(Wallet, Amount)>> {
|
||||
let mut wallets_vec: Vec<(Wallet, Amount)> = Vec::with_capacity(wallets.capacity());
|
||||
multi_mint_wallet: &MultiMintWallet,
|
||||
) -> Result<Vec<(UncheckedUrl, Amount)>> {
|
||||
let wallets: HashMap<UncheckedUrl, Amount> =
|
||||
multi_mint_wallet.get_balances(&CurrencyUnit::Sat).await?;
|
||||
|
||||
for (i, (mint_url, wallet)) in wallets.iter().enumerate() {
|
||||
let mut wallets_vec = Vec::with_capacity(wallets.capacity());
|
||||
|
||||
for (i, (mint_url, amount)) in wallets.iter().enumerate() {
|
||||
let mint_url = mint_url.clone();
|
||||
let amount = wallet.total_balance().await?;
|
||||
println!("{i}: {mint_url} {amount}");
|
||||
wallets_vec.push((wallet.clone(), amount));
|
||||
wallets_vec.push((mint_url, *amount))
|
||||
}
|
||||
Ok(wallets_vec)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::nuts::CurrencyUnit;
|
||||
use cdk::wallet::multi_mint_wallet::WalletKey;
|
||||
use cdk::wallet::MultiMintWallet;
|
||||
use cdk::{Amount, UncheckedUrl};
|
||||
use clap::Args;
|
||||
|
||||
@@ -12,17 +12,20 @@ pub struct BurnSubCommand {
|
||||
}
|
||||
|
||||
pub async fn burn(
|
||||
wallets: HashMap<UncheckedUrl, Wallet>,
|
||||
multi_mint_wallet: &MultiMintWallet,
|
||||
sub_command_args: &BurnSubCommand,
|
||||
) -> Result<()> {
|
||||
let mut total_burnt = Amount::ZERO;
|
||||
match &sub_command_args.mint_url {
|
||||
Some(mint_url) => {
|
||||
let wallet = wallets.get(mint_url).unwrap();
|
||||
let wallet = multi_mint_wallet
|
||||
.get_wallet(&WalletKey::new(mint_url.clone(), CurrencyUnit::Sat))
|
||||
.await
|
||||
.unwrap();
|
||||
total_burnt = wallet.check_all_pending_proofs().await?;
|
||||
}
|
||||
None => {
|
||||
for wallet in wallets.values() {
|
||||
for wallet in multi_mint_wallet.get_wallets().await {
|
||||
let amount_burnt = wallet.check_all_pending_proofs().await?;
|
||||
total_burnt += amount_burnt;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use cdk::url::UncheckedUrl;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::wallet::MultiMintWallet;
|
||||
|
||||
pub async fn check_spent(wallets: HashMap<UncheckedUrl, Wallet>) -> Result<()> {
|
||||
for wallet in wallets.values() {
|
||||
pub async fn check_spent(multi_mint_wallet: &MultiMintWallet) -> Result<()> {
|
||||
for wallet in multi_mint_wallet.get_wallets().await {
|
||||
let amount = wallet.check_all_pending_proofs().await?;
|
||||
|
||||
println!("Amount marked as spent: {}", amount);
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::str::FromStr;
|
||||
use std::{io, println};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::{Bolt11Invoice, UncheckedUrl};
|
||||
use cdk::nuts::CurrencyUnit;
|
||||
use cdk::wallet::multi_mint_wallet::{MultiMintWallet, WalletKey};
|
||||
use cdk::Bolt11Invoice;
|
||||
|
||||
use crate::sub_commands::balance::mint_balances;
|
||||
|
||||
pub async fn pay(wallets: HashMap<UncheckedUrl, Wallet>) -> Result<()> {
|
||||
let mints_amounts = mint_balances(wallets).await?;
|
||||
pub async fn pay(multi_mint_wallet: MultiMintWallet) -> Result<()> {
|
||||
let mints_amounts = mint_balances(&multi_mint_wallet).await?;
|
||||
|
||||
println!("Enter mint number to melt from");
|
||||
|
||||
@@ -26,6 +26,10 @@ pub async fn pay(wallets: HashMap<UncheckedUrl, Wallet>) -> Result<()> {
|
||||
}
|
||||
|
||||
let wallet = mints_amounts[mint_number].0.clone();
|
||||
let wallet = multi_mint_wallet
|
||||
.get_wallet(&WalletKey::new(wallet, CurrencyUnit::Sat))
|
||||
.await
|
||||
.expect("Known wallet");
|
||||
|
||||
println!("Enter bolt11 invoice request");
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -7,7 +6,8 @@ use cdk::amount::SplitTarget;
|
||||
use cdk::cdk_database::{Error, WalletDatabase};
|
||||
use cdk::nuts::{CurrencyUnit, MintQuoteState};
|
||||
use cdk::url::UncheckedUrl;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::wallet::multi_mint_wallet::WalletKey;
|
||||
use cdk::wallet::{MultiMintWallet, Wallet};
|
||||
use cdk::Amount;
|
||||
use clap::Args;
|
||||
use tokio::time::sleep;
|
||||
@@ -24,21 +24,29 @@ pub struct MintSubCommand {
|
||||
}
|
||||
|
||||
pub async fn mint(
|
||||
wallets: HashMap<UncheckedUrl, Wallet>,
|
||||
multi_mint_wallet: &MultiMintWallet,
|
||||
seed: &[u8],
|
||||
localstore: Arc<dyn WalletDatabase<Err = Error> + Sync + Send>,
|
||||
sub_command_args: &MintSubCommand,
|
||||
) -> Result<()> {
|
||||
let mint_url = sub_command_args.mint_url.clone();
|
||||
let wallet = match wallets.get(&mint_url) {
|
||||
let wallet = match multi_mint_wallet
|
||||
.get_wallet(&WalletKey::new(mint_url.clone(), CurrencyUnit::Sat))
|
||||
.await
|
||||
{
|
||||
Some(wallet) => wallet.clone(),
|
||||
None => Wallet::new(
|
||||
&mint_url.to_string(),
|
||||
CurrencyUnit::Sat,
|
||||
localstore,
|
||||
seed,
|
||||
None,
|
||||
),
|
||||
None => {
|
||||
let wallet = Wallet::new(
|
||||
&mint_url.to_string(),
|
||||
CurrencyUnit::Sat,
|
||||
localstore,
|
||||
seed,
|
||||
None,
|
||||
);
|
||||
|
||||
multi_mint_wallet.add_wallet(wallet.clone()).await;
|
||||
wallet
|
||||
}
|
||||
};
|
||||
|
||||
let quote = wallet
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::{Amount, UncheckedUrl};
|
||||
use cdk::wallet::MultiMintWallet;
|
||||
use cdk::Amount;
|
||||
|
||||
pub async fn mint_pending(wallets: HashMap<UncheckedUrl, Wallet>) -> Result<()> {
|
||||
let mut amount_claimed = Amount::ZERO;
|
||||
for wallet in wallets.values() {
|
||||
let claimed = wallet.check_all_mint_quotes().await?;
|
||||
amount_claimed += claimed;
|
||||
}
|
||||
pub async fn mint_pending(multi_mint_wallet: &MultiMintWallet) -> Result<()> {
|
||||
let amounts = multi_mint_wallet.check_all_mint_quotes(None).await?;
|
||||
|
||||
println!("Amount minted: {amount_claimed}");
|
||||
let amount = amounts.into_values().sum::<Amount>();
|
||||
|
||||
println!("Amount minted: {amount}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use cdk::amount::SplitTarget;
|
||||
use cdk::cdk_database::{Error, WalletDatabase};
|
||||
use cdk::nuts::{CurrencyUnit, SecretKey, Token};
|
||||
use cdk::cdk_database::{self, WalletDatabase};
|
||||
use cdk::nuts::SecretKey;
|
||||
use cdk::util::unix_time;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::{Amount, UncheckedUrl};
|
||||
use cdk::wallet::multi_mint_wallet::MultiMintWallet;
|
||||
use cdk::Amount;
|
||||
use clap::Args;
|
||||
use nostr_sdk::nips::nip04;
|
||||
use nostr_sdk::{Filter, Keys, Kind, Timestamp};
|
||||
@@ -35,9 +34,8 @@ pub struct ReceiveSubCommand {
|
||||
}
|
||||
|
||||
pub async fn receive(
|
||||
wallets: HashMap<UncheckedUrl, Wallet>,
|
||||
seed: &[u8],
|
||||
localstore: Arc<dyn WalletDatabase<Err = Error> + Sync + Send>,
|
||||
multi_mint_wallet: &MultiMintWallet,
|
||||
localstore: Arc<dyn WalletDatabase<Err = cdk_database::Error> + Send + Sync>,
|
||||
sub_command_args: &ReceiveSubCommand,
|
||||
) -> Result<()> {
|
||||
let mut signing_keys = Vec::new();
|
||||
@@ -62,10 +60,8 @@ pub async fn receive(
|
||||
let amount = match &sub_command_args.token {
|
||||
Some(token_str) => {
|
||||
receive_token(
|
||||
multi_mint_wallet,
|
||||
token_str,
|
||||
wallets,
|
||||
seed,
|
||||
&localstore,
|
||||
&signing_keys,
|
||||
&sub_command_args.preimage,
|
||||
)
|
||||
@@ -97,10 +93,8 @@ pub async fn receive(
|
||||
let mut total_amount = Amount::ZERO;
|
||||
for token_str in &tokens {
|
||||
match receive_token(
|
||||
multi_mint_wallet,
|
||||
token_str,
|
||||
wallets.clone(),
|
||||
seed,
|
||||
&localstore,
|
||||
&signing_keys,
|
||||
&sub_command_args.preimage,
|
||||
)
|
||||
@@ -128,29 +122,13 @@ pub async fn receive(
|
||||
}
|
||||
|
||||
async fn receive_token(
|
||||
token_str: &str,
|
||||
wallets: HashMap<UncheckedUrl, Wallet>,
|
||||
seed: &[u8],
|
||||
localstore: &Arc<dyn WalletDatabase<Err = Error> + Sync + Send>,
|
||||
multi_mint_wallet: &MultiMintWallet,
|
||||
token: &str,
|
||||
signing_keys: &[SecretKey],
|
||||
preimage: &[String],
|
||||
) -> Result<Amount> {
|
||||
let token = Token::from_str(token_str)?;
|
||||
let mint_url = token.proofs().iter().next().unwrap().0.clone();
|
||||
|
||||
let wallet = match wallets.get(&mint_url) {
|
||||
Some(wallet) => wallet.clone(),
|
||||
None => Wallet::new(
|
||||
&mint_url.to_string(),
|
||||
CurrencyUnit::Sat,
|
||||
Arc::clone(localstore),
|
||||
seed,
|
||||
None,
|
||||
),
|
||||
};
|
||||
|
||||
let amount = wallet
|
||||
.receive(token_str, SplitTarget::default(), signing_keys, preimage)
|
||||
let amount = multi_mint_wallet
|
||||
.receive(token, signing_keys, preimage)
|
||||
.await?;
|
||||
Ok(amount)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use cdk::nuts::CurrencyUnit;
|
||||
use cdk::url::UncheckedUrl;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::wallet::multi_mint_wallet::WalletKey;
|
||||
use cdk::wallet::MultiMintWallet;
|
||||
use clap::Args;
|
||||
|
||||
#[derive(Args)]
|
||||
@@ -12,11 +12,15 @@ pub struct RestoreSubCommand {
|
||||
}
|
||||
|
||||
pub async fn restore(
|
||||
wallets: HashMap<UncheckedUrl, Wallet>,
|
||||
multi_mint_wallet: &MultiMintWallet,
|
||||
sub_command_args: &RestoreSubCommand,
|
||||
) -> Result<()> {
|
||||
let wallet = wallets
|
||||
.get(&sub_command_args.mint_url)
|
||||
let wallet = multi_mint_wallet
|
||||
.get_wallet(&WalletKey::new(
|
||||
sub_command_args.mint_url.clone(),
|
||||
CurrencyUnit::Sat,
|
||||
))
|
||||
.await
|
||||
.ok_or(anyhow!("Unknown mint url"))?;
|
||||
|
||||
let amount = wallet.restore().await?;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use cdk::amount::SplitTarget;
|
||||
use cdk::nuts::{Conditions, PublicKey, SpendingConditions};
|
||||
use cdk::nuts::{Conditions, CurrencyUnit, PublicKey, SpendingConditions};
|
||||
use cdk::wallet::multi_mint_wallet::WalletKey;
|
||||
use cdk::wallet::types::SendKind;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::{Amount, UncheckedUrl};
|
||||
use cdk::wallet::MultiMintWallet;
|
||||
use cdk::Amount;
|
||||
use clap::Args;
|
||||
|
||||
use crate::sub_commands::balance::mint_balances;
|
||||
@@ -48,10 +48,10 @@ pub struct SendSubCommand {
|
||||
}
|
||||
|
||||
pub async fn send(
|
||||
wallets: HashMap<UncheckedUrl, Wallet>,
|
||||
multi_mint_wallet: &MultiMintWallet,
|
||||
sub_command_args: &SendSubCommand,
|
||||
) -> Result<()> {
|
||||
let mints_amounts = mint_balances(wallets).await?;
|
||||
let mints_amounts = mint_balances(multi_mint_wallet).await?;
|
||||
|
||||
println!("Enter mint number to create token");
|
||||
|
||||
@@ -155,6 +155,10 @@ pub async fn send(
|
||||
};
|
||||
|
||||
let wallet = mints_amounts[mint_number].0.clone();
|
||||
let wallet = multi_mint_wallet
|
||||
.get_wallet(&WalletKey::new(wallet, CurrencyUnit::Sat))
|
||||
.await
|
||||
.expect("Known wallet");
|
||||
|
||||
let send_kind = match (sub_command_args.offline, sub_command_args.tolerance) {
|
||||
(true, Some(amount)) => SendKind::OfflineTolerance(Amount::from(amount)),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use cdk::nuts::CurrencyUnit;
|
||||
use cdk::url::UncheckedUrl;
|
||||
use cdk::wallet::Wallet;
|
||||
use cdk::wallet::multi_mint_wallet::WalletKey;
|
||||
use cdk::wallet::MultiMintWallet;
|
||||
use clap::Args;
|
||||
|
||||
#[derive(Args)]
|
||||
@@ -14,7 +14,7 @@ pub struct UpdateMintUrlSubCommand {
|
||||
}
|
||||
|
||||
pub async fn update_mint_url(
|
||||
wallets: HashMap<UncheckedUrl, Wallet>,
|
||||
multi_mint_wallet: &MultiMintWallet,
|
||||
sub_command_args: &UpdateMintUrlSubCommand,
|
||||
) -> Result<()> {
|
||||
let UpdateMintUrlSubCommand {
|
||||
@@ -22,8 +22,12 @@ pub async fn update_mint_url(
|
||||
new_mint_url,
|
||||
} = sub_command_args;
|
||||
|
||||
let mut wallet = wallets
|
||||
.get(old_mint_url)
|
||||
let mut wallet = multi_mint_wallet
|
||||
.get_wallet(&WalletKey::new(
|
||||
sub_command_args.old_mint_url.clone(),
|
||||
CurrencyUnit::Sat,
|
||||
))
|
||||
.await
|
||||
.ok_or(anyhow!("Unknown mint url"))?
|
||||
.clone();
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ pub mod multi_mint_wallet;
|
||||
pub mod types;
|
||||
pub mod util;
|
||||
|
||||
pub use multi_mint_wallet::MultiMintWallet;
|
||||
pub use types::{MeltQuote, MintQuote, SendKind};
|
||||
|
||||
/// CDK Wallet
|
||||
|
||||
Reference in New Issue
Block a user