pub struct MultiMintWallet { /* private fields */ }Expand description
Multi Mint Wallet
A wallet that manages multiple mints but supports only one currency unit. This simplifies the interface by removing the need to specify both mint and unit.
§Examples
§Creating and using a multi-mint wallet
// Create a multi-mint wallet with a database
// For real usage, you would use cdk_sqlite::wallet::memory::empty().await? or similar
let seed = [0u8; 64]; // Use a secure random seed in production
let database = cdk_sqlite::wallet::memory::empty().await?;
let wallet = MultiMintWallet::new(
Arc::new(database),
seed,
CurrencyUnit::Sat,
).await?;
// Add mints to the wallet
let mint_url1: MintUrl = "https://mint1.example.com".parse()?;
let mint_url2: MintUrl = "https://mint2.example.com".parse()?;
wallet.add_mint(mint_url1.clone()).await?;
wallet.add_mint(mint_url2).await?;
// Check total balance across all mints
let balance = wallet.total_balance().await?;
println!("Total balance: {} sats", balance);
// Send tokens from a specific mint
let prepared = wallet.prepare_send(
mint_url1,
Amount::from(100),
Default::default()
).await?;
let token = prepared.confirm(None).await?;Implementations§
Source§impl MultiMintWallet
impl MultiMintWallet
Sourcepub async fn new(
localstore: Arc<dyn WalletDatabase<Err = Error> + Send + Sync>,
seed: [u8; 64],
unit: CurrencyUnit,
) -> Result<Self, Error>
pub async fn new( localstore: Arc<dyn WalletDatabase<Err = Error> + Send + Sync>, seed: [u8; 64], unit: CurrencyUnit, ) -> Result<Self, Error>
Create a new MultiMintWallet for a specific currency unit
Sourcepub async fn new_with_proxy(
localstore: Arc<dyn WalletDatabase<Err = Error> + Send + Sync>,
seed: [u8; 64],
unit: CurrencyUnit,
proxy_url: Url,
) -> Result<Self, Error>
pub async fn new_with_proxy( localstore: Arc<dyn WalletDatabase<Err = Error> + Send + Sync>, seed: [u8; 64], unit: CurrencyUnit, proxy_url: Url, ) -> Result<Self, Error>
Create a new MultiMintWallet with proxy configuration
All wallets in this MultiMintWallet will use the specified proxy. This allows you to route all mint connections through a proxy server.
Sourcepub async fn add_mint(&self, mint_url: MintUrl) -> Result<(), Error>
pub async fn add_mint(&self, mint_url: MintUrl) -> Result<(), Error>
Adds a mint to this MultiMintWallet
Creates a wallet for the specified mint using default or global settings.
For custom configuration, use add_mint_with_config().
Sourcepub async fn add_mint_with_config(
&self,
mint_url: MintUrl,
config: WalletConfig,
) -> Result<(), Error>
pub async fn add_mint_with_config( &self, mint_url: MintUrl, config: WalletConfig, ) -> Result<(), Error>
Adds a mint to this MultiMintWallet with custom configuration
The provided configuration is used to create the wallet with custom connectors and settings. Configuration is stored within the Wallet instance itself.
Sourcepub async fn set_mint_config(
&self,
mint_url: MintUrl,
config: WalletConfig,
) -> Result<(), Error>
pub async fn set_mint_config( &self, mint_url: MintUrl, config: WalletConfig, ) -> Result<(), Error>
Set or update configuration for a mint
If the wallet already exists, it will be updated with the new config. If the wallet doesn’t exist, it will be created with the specified config.
Sourcepub async fn set_auth_client(
&self,
mint_url: &MintUrl,
auth_wallet: Option<AuthWallet>,
) -> Result<(), Error>
pub async fn set_auth_client( &self, mint_url: &MintUrl, auth_wallet: Option<AuthWallet>, ) -> Result<(), Error>
Set the auth client (AuthWallet) for a specific mint
This allows updating the auth wallet for an existing mint wallet without recreating it.
Sourcepub async fn remove_mint(&self, mint_url: &MintUrl)
pub async fn remove_mint(&self, mint_url: &MintUrl)
Remove mint from MultiMintWallet
Sourcepub async fn get_wallets(&self) -> Vec<Wallet>
pub async fn get_wallets(&self) -> Vec<Wallet>
Get Wallets from MultiMintWallet
Sourcepub async fn get_wallet(&self, mint_url: &MintUrl) -> Option<Wallet>
pub async fn get_wallet(&self, mint_url: &MintUrl) -> Option<Wallet>
Get Wallet from MultiMintWallet
Sourcepub fn unit(&self) -> &CurrencyUnit
pub fn unit(&self) -> &CurrencyUnit
Get the currency unit for this wallet
Sourcepub async fn get_balances(&self) -> Result<BTreeMap<MintUrl, Amount>, Error>
pub async fn get_balances(&self) -> Result<BTreeMap<MintUrl, Amount>, Error>
Get wallet balances for all mints
Sourcepub async fn list_transactions(
&self,
direction: Option<TransactionDirection>,
) -> Result<Vec<Transaction>, Error>
pub async fn list_transactions( &self, direction: Option<TransactionDirection>, ) -> Result<Vec<Transaction>, Error>
List transactions
Sourcepub async fn total_balance(&self) -> Result<Amount, Error>
pub async fn total_balance(&self) -> Result<Amount, Error>
Get total balance across all wallets (since all wallets use the same currency unit)
Sourcepub async fn prepare_send(
&self,
mint_url: MintUrl,
amount: Amount,
opts: MultiMintSendOptions,
) -> Result<PreparedSend, Error>
pub async fn prepare_send( &self, mint_url: MintUrl, amount: Amount, opts: MultiMintSendOptions, ) -> Result<PreparedSend, Error>
Prepare to send tokens from a specific mint with optional transfer from other mints
This method ensures that sends always happen from only one mint. If the specified
mint doesn’t have sufficient balance and allow_transfer is enabled in options,
it will first transfer funds from other mints to the target mint.
Sourcepub async fn transfer(
&self,
source_mint_url: &MintUrl,
target_mint_url: &MintUrl,
mode: TransferMode,
) -> Result<TransferResult, Error>
pub async fn transfer( &self, source_mint_url: &MintUrl, target_mint_url: &MintUrl, mode: TransferMode, ) -> Result<TransferResult, Error>
Transfer funds from a single source wallet to target mint using Lightning Network (melt/mint)
This function properly accounts for fees by handling different transfer modes:
- ExactReceive: Target receives exactly the specified amount, source pays amount + fees
- FullBalance: All source balance is transferred, target receives balance - fees
Sourcepub async fn mint_quote(
&self,
mint_url: &MintUrl,
amount: Amount,
description: Option<String>,
) -> Result<MintQuote, Error>
pub async fn mint_quote( &self, mint_url: &MintUrl, amount: Amount, description: Option<String>, ) -> Result<MintQuote, Error>
Mint quote for wallet
Sourcepub async fn check_mint_quote(
&self,
mint_url: &MintUrl,
quote_id: &str,
) -> Result<MintQuote, Error>
pub async fn check_mint_quote( &self, mint_url: &MintUrl, quote_id: &str, ) -> Result<MintQuote, Error>
Check a specific mint quote status
Sourcepub async fn check_all_mint_quotes(
&self,
mint_url: Option<MintUrl>,
) -> Result<Amount, Error>
pub async fn check_all_mint_quotes( &self, mint_url: Option<MintUrl>, ) -> Result<Amount, Error>
Check all mint quotes If quote is paid, wallet will mint
Sourcepub async fn mint(
&self,
mint_url: &MintUrl,
quote_id: &str,
conditions: Option<SpendingConditions>,
) -> Result<Proofs, Error>
pub async fn mint( &self, mint_url: &MintUrl, quote_id: &str, conditions: Option<SpendingConditions>, ) -> Result<Proofs, Error>
Mint a specific quote
Sourcepub async fn wait_for_mint_quote(
&self,
mint_url: &MintUrl,
quote_id: &str,
split_target: SplitTarget,
conditions: Option<SpendingConditions>,
timeout_secs: u64,
) -> Result<Proofs, Error>
pub async fn wait_for_mint_quote( &self, mint_url: &MintUrl, quote_id: &str, split_target: SplitTarget, conditions: Option<SpendingConditions>, timeout_secs: u64, ) -> Result<Proofs, Error>
Wait for a mint quote to be paid and automatically mint the proofs
Sourcepub async fn receive(
&self,
encoded_token: &str,
opts: MultiMintReceiveOptions,
) -> Result<Amount, Error>
pub async fn receive( &self, encoded_token: &str, opts: MultiMintReceiveOptions, ) -> Result<Amount, Error>
Receive token with multi-mint options
This method can:
- Receive tokens from trusted mints (already added to the wallet)
- Optionally receive from untrusted mints by adding them to the wallet
- Optionally transfer tokens from untrusted mints to a trusted mint (and remove the untrusted mint)
§Examples
// Receive from a trusted mint
let token = "cashuAey...";
let amount = wallet
.receive(token, MultiMintReceiveOptions::default())
.await?;
// Receive from untrusted mint and add it to the wallet
let options = MultiMintReceiveOptions::default().allow_untrusted(true);
let amount = wallet.receive(token, options).await?;
// Receive from untrusted mint, transfer to trusted mint, then remove untrusted mint
let trusted_mint: MintUrl = "https://trusted.mint".parse()?;
let options = MultiMintReceiveOptions::default().transfer_to_mint(Some(trusted_mint));
let amount = wallet.receive(token, options).await?;Sourcepub async fn verify_token_p2pk(
&self,
token: &Token,
conditions: SpendingConditions,
) -> Result<(), Error>
pub async fn verify_token_p2pk( &self, token: &Token, conditions: SpendingConditions, ) -> Result<(), Error>
Verify token matches p2pk conditions
Sourcepub async fn verify_token_dleq(&self, token: &Token) -> Result<(), Error>
pub async fn verify_token_dleq(&self, token: &Token) -> Result<(), Error>
Verifys all proofs in token have valid dleq proof
Sourcepub async fn melt_quote(
&self,
mint_url: &MintUrl,
bolt11: String,
options: Option<MeltOptions>,
) -> Result<MeltQuote, Error>
pub async fn melt_quote( &self, mint_url: &MintUrl, bolt11: String, options: Option<MeltOptions>, ) -> Result<MeltQuote, Error>
Create a melt quote for a specific mint
Sourcepub async fn melt_with_mint(
&self,
mint_url: &MintUrl,
quote_id: &str,
) -> Result<Melted, Error>
pub async fn melt_with_mint( &self, mint_url: &MintUrl, quote_id: &str, ) -> Result<Melted, Error>
Melt (pay invoice) from a specific mint using a quote ID
Sourcepub async fn mpp_melt_quote(
&self,
bolt11: String,
mint_amounts: Vec<(MintUrl, Amount)>,
) -> Result<Vec<(MintUrl, MeltQuote)>, Error>
pub async fn mpp_melt_quote( &self, bolt11: String, mint_amounts: Vec<(MintUrl, Amount)>, ) -> Result<Vec<(MintUrl, MeltQuote)>, Error>
Create MPP (Multi-Path Payment) melt quotes from multiple mints
This function allows manual specification of which mints and amounts to use for MPP. Returns a vector of (MintUrl, MeltQuote) pairs.
Sourcepub async fn mpp_melt(
&self,
quotes: Vec<(MintUrl, String)>,
) -> Result<Vec<(MintUrl, Melted)>, Error>
pub async fn mpp_melt( &self, quotes: Vec<(MintUrl, String)>, ) -> Result<Vec<(MintUrl, Melted)>, Error>
Execute MPP melts using previously obtained quotes
Sourcepub async fn melt(
&self,
bolt11: &str,
options: Option<MeltOptions>,
max_fee: Option<Amount>,
) -> Result<Melted, Error>
pub async fn melt( &self, bolt11: &str, options: Option<MeltOptions>, max_fee: Option<Amount>, ) -> Result<Melted, Error>
Melt (pay invoice) with automatic wallet selection (deprecated, use specific mint functions for better control)
Automatically selects the best wallet to pay from based on:
- Available balance
- Fees
§Examples
// Pay a lightning invoice from any mint with sufficient balance
let invoice = "lnbc100n1p...";
let result = wallet.melt(invoice, None, None).await?;
println!("Paid {} sats, fee was {} sats", result.amount, result.fee_paid);Sourcepub async fn swap(
&self,
amount: Option<Amount>,
conditions: Option<SpendingConditions>,
) -> Result<Option<Proofs>, Error>
pub async fn swap( &self, amount: Option<Amount>, conditions: Option<SpendingConditions>, ) -> Result<Option<Proofs>, Error>
Swap proofs with automatic wallet selection
Sourcepub async fn consolidate(&self) -> Result<Amount, Error>
pub async fn consolidate(&self) -> Result<Amount, Error>
Consolidate proofs from multiple wallets into fewer, larger proofs This can help reduce the number of proofs and optimize wallet performance
Sourcepub async fn mint_blind_auth(
&self,
mint_url: &MintUrl,
amount: Amount,
) -> Result<Proofs, Error>
pub async fn mint_blind_auth( &self, mint_url: &MintUrl, amount: Amount, ) -> Result<Proofs, Error>
Mint blind auth tokens for a specific mint
This is a convenience method that calls the underlying wallet’s mint_blind_auth.
Sourcepub async fn get_unspent_auth_proofs(
&self,
mint_url: &MintUrl,
) -> Result<Vec<AuthProof>, Error>
pub async fn get_unspent_auth_proofs( &self, mint_url: &MintUrl, ) -> Result<Vec<AuthProof>, Error>
Get unspent auth proofs for a specific mint
This is a convenience method that calls the underlying wallet’s get_unspent_auth_proofs.
Sourcepub async fn set_cat(
&self,
mint_url: &MintUrl,
cat: String,
) -> Result<(), Error>
pub async fn set_cat( &self, mint_url: &MintUrl, cat: String, ) -> Result<(), Error>
Set Clear Auth Token (CAT) for authentication at a specific mint
This is a convenience method that calls the underlying wallet’s set_cat.
Sourcepub async fn set_refresh_token(
&self,
mint_url: &MintUrl,
refresh_token: String,
) -> Result<(), Error>
pub async fn set_refresh_token( &self, mint_url: &MintUrl, refresh_token: String, ) -> Result<(), Error>
Set refresh token for authentication at a specific mint
This is a convenience method that calls the underlying wallet’s set_refresh_token.
Sourcepub async fn refresh_access_token(
&self,
mint_url: &MintUrl,
) -> Result<(), Error>
pub async fn refresh_access_token( &self, mint_url: &MintUrl, ) -> Result<(), Error>
Refresh CAT token for a specific mint
This is a convenience method that calls the underlying wallet’s refresh_access_token.
Sourcepub async fn fetch_mint_info(
&self,
mint_url: &MintUrl,
) -> Result<Option<MintInfo>, Error>
pub async fn fetch_mint_info( &self, mint_url: &MintUrl, ) -> Result<Option<MintInfo>, Error>
Query mint for current mint information
This is a convenience method that calls the underlying wallet’s fetch_mint_info.
Sourcepub async fn melt_bip353_quote(
&self,
mint_url: &MintUrl,
bip353_address: &str,
amount_msat: impl Into<Amount>,
) -> Result<MeltQuote, Error>
pub async fn melt_bip353_quote( &self, mint_url: &MintUrl, bip353_address: &str, amount_msat: impl Into<Amount>, ) -> Result<MeltQuote, Error>
Melt Quote for BIP353 human-readable address
This method resolves a BIP353 address (e.g., “alice@example.com”) to a Lightning offer and then creates a melt quote for that offer at the specified mint.
§Arguments
mint_url- The mint to use for creating the melt quotebip353_address- Human-readable address in the format “user@domain.com”amount_msat- Amount to pay in millisatoshis
§Returns
A MeltQuote that can be used to execute the payment
Sourcepub async fn melt_lightning_address_quote(
&self,
mint_url: &MintUrl,
lightning_address: &str,
amount_msat: impl Into<Amount>,
) -> Result<MeltQuote, Error>
pub async fn melt_lightning_address_quote( &self, mint_url: &MintUrl, lightning_address: &str, amount_msat: impl Into<Amount>, ) -> Result<MeltQuote, Error>
Melt Quote for Lightning address
This method resolves a Lightning address (e.g., “alice@example.com”) to a Lightning invoice and then creates a melt quote for that invoice at the specified mint.
§Arguments
mint_url- The mint to use for creating the melt quotelightning_address- Lightning address in the format “user@domain.com”amount_msat- Amount to pay in millisatoshis
§Returns
A MeltQuote that can be used to execute the payment
Sourcepub async fn melt_human_readable_quote(
&self,
mint_url: &MintUrl,
address: &str,
amount_msat: impl Into<Amount>,
) -> Result<MeltQuote, Error>
pub async fn melt_human_readable_quote( &self, mint_url: &MintUrl, address: &str, amount_msat: impl Into<Amount>, ) -> Result<MeltQuote, Error>
Get a melt quote for a human-readable address
This method accepts a human-readable address that could be either a BIP353 address or a Lightning address. It intelligently determines which to try based on mint support:
- If the mint supports Bolt12, it tries BIP353 first
- Falls back to Lightning address only if BIP353 DNS resolution fails
- If BIP353 resolves but fails at the mint, it does NOT fall back to Lightning address
- If the mint doesn’t support Bolt12, it tries Lightning address directly
§Arguments
mint_url- The mint to use for creating the melt quoteaddress- Human-readable address (BIP353 or Lightning address)amount_msat- Amount to pay in millisatoshis
Source§impl MultiMintWallet
impl MultiMintWallet
Sourcepub async fn create_request(
&self,
params: CreateRequestParams,
) -> Result<(PaymentRequest, Option<NostrWaitInfo>), Error>
pub async fn create_request( &self, params: CreateRequestParams, ) -> Result<(PaymentRequest, Option<NostrWaitInfo>), Error>
Create a NUT-18 PaymentRequest from high-level parameters.
Why:
- Ensures the CLI and SDKs construct requests consistently using wallet context.
- Advertises available mints for the chosen unit so payers can select compatible proofs.
- Optionally embeds a transport; Nostr is preferred to reduce IP exposure for the payer.
Behavior summary (focus on rationale rather than steps):
- Uses
unitto discover mints with balances as a hint to senders (helps route payments without leaking more data than necessary). - Translates P2PK/multisig and HTLC inputs (pubkeys/num_sigs/hash/preimage) into a NUT-10 secret request so the receiver can enforce spending constraints.
- For
transport == "nostr", generates ephemeral keys and an nprofile pointing at the chosen relays; returnsNostrWaitInfoso callers can wait for the incoming payment without coupling construction and reception logic. - For
transport == "http", attaches the provided endpoint; fornoneor unknown, omits transports to let the caller deliver out-of-band.
Returns:
(PaymentRequest, Some(NostrWaitInfo))whentransport == "nostr".(PaymentRequest, None)otherwise.
Errors when:
unitcannot be parsed, relay URLs are invalid, or P2PK/HTLC parameters are malformed.
Notes:
- Sets
single_use = trueto discourage replays. - Ephemeral Nostr keys are intentional; keep
NostrWaitInfoonly as long as needed for reception.
Sourcepub async fn wait_for_nostr_payment(
&self,
info: NostrWaitInfo,
) -> Result<Amount>
pub async fn wait_for_nostr_payment( &self, info: NostrWaitInfo, ) -> Result<Amount>
Wait for a Nostr payment for the previously constructed PaymentRequest and receive it into the wallet.
Trait Implementations§
Source§impl Clone for MultiMintWallet
impl Clone for MultiMintWallet
Source§fn clone(&self) -> MultiMintWallet
fn clone(&self) -> MultiMintWallet
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for MultiMintWallet
impl !RefUnwindSafe for MultiMintWallet
impl Send for MultiMintWallet
impl Sync for MultiMintWallet
impl Unpin for MultiMintWallet
impl !UnwindSafe for MultiMintWallet
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request