mirror of
https://github.com/aljazceru/cdk.git
synced 2026-01-08 23:45:52 +01:00
* fix(cdk): prevent duplicate blinded message processing with database constraints Add unique constraints on blinded_message column in both PostgreSQL and SQLite databases, and implement application-level checks to prevent duplicate blinded messages from being processed. Also ensure proper cleanup of melt requests after successful processing. * feat: db tests for unique * refactor(cdk-sql): consolidate blinded messages into blind signature table Migrate from separate blinded_messages table to unified blind_signature table. Add signed_time column and make c column nullable to track both pending blind messages (c=NULL) and completed signatures. Update insert/update logic to handle upsert scenarios for blind signature completion. * refactor(cdk-sql): remove unique constraint migration and filter queries for signed messages Remove database-level unique constraint on blinded_message and instead filter queries to only consider messages with signatures (c IS NOT NULL * refactor(database): improve blinded message duplicate detection using database constraints Replace manual duplicate checking with database constraint handling for better reliability and simplified code flow in melt request processing. * refactor(cdk-sql): optimize blind signature processing with batch queries Replace individual queries per blinded message with single batch query and HashMap lookup to eliminate N+1 query performance issue. * fix: signed time to swap sigs * refactor(cdk): split blinded message handling and improve duplicate detection - Split add_melt_request_and_blinded_messages into separate methods - Add blinded messages to database before signing in swap operations - Improve duplicate output detection with proper error handling - Make add_blinded_messages method accept optional quote_id for flexibility * refactor(cdk): add BlindedMessageWriter for improved transaction rollback - Add BlindedMessageWriter component for managing blinded message state - Implement proper rollback mechanisms in swap operations - Add delete_blinded_messages database interface for cleanup - Improve error handling with better state management
CDK (Cashu Development Kit)
ALPHA This library is in early development, the API will change and should be used with caution.
The core implementation of the Cashu protocol for building wallets and mints. It builds upon the primitives defined in the cashu crate and provides higher-level abstractions for working with the Cashu ecosystem.
Crate Feature Flags
The following crate feature flags are available:
| Feature | Default | Description |
|---|---|---|
wallet |
Yes | Enable cashu wallet features |
mint |
Yes | Enable cashu mint wallet features |
auth |
Yes | Enable blind and clear auth |
Implemented NUTs:
See https://github.com/cashubtc/cdk/blob/main/README.md
Components
The crate includes several key modules:
- wallet: Implementation of the Cashu wallet
- mint: Implementation of the Cashu mint
- database: Database abstractions for persistent storage
- payment: Payment processing functionality
- nuts: Implementation of the Cashu NUTs
Usage
Add this to your Cargo.toml:
[dependencies]
cdk = "*"
Example
//! Wallet example with memory store
//! Note: This example requires the "wallet" feature to be enabled (enabled by default)
use std::sync::Arc;
use std::time::Duration;
#[cfg(feature = "wallet")]
use cdk::amount::SplitTarget;
use cdk_sqlite::wallet::memory;
use cdk::nuts::{CurrencyUnit, MintQuoteState};
#[cfg(feature = "wallet")]
use cdk::wallet::Wallet;
#[cfg(feature = "wallet")]
use cdk::wallet::SendOptions;
use cdk::Amount;
use rand::random;
use tokio::time::sleep;
#[tokio::main]
async fn main() {
#[cfg(feature = "wallet")]
{
let seed = random::<[u8; 64]>();
let mint_url = "https://fake.thesimplekid.dev";
let unit = CurrencyUnit::Sat;
let amount = Amount::from(10);
let localstore = memory::empty().await.unwrap();
let wallet = Wallet::new(mint_url, unit, Arc::new(localstore), seed, None).unwrap();
let quote = wallet.mint_quote(amount, None).await.unwrap();
println!("Pay request: {}", quote.request);
loop {
let status = wallet.mint_quote_state("e.id).await.unwrap();
if status.state == MintQuoteState::Paid {
break;
}
println!("Quote state: {}", status.state);
sleep(Duration::from_secs(5)).await;
}
let receive_amount = wallet
.mint("e.id, SplitTarget::default(), None)
.await
.unwrap();
println!("Minted {:?}", receive_amount);
// Send the token
let prepared_send = wallet.prepare_send(Amount::ONE, SendOptions::default()).await.unwrap();
let token = prepared_send.confirm(None).await.unwrap();
println!("{}", token);
}
}
See more examples in the examples folder.
Minimum Supported Rust Version (MSRV)
The cdk library should always compile with any combination of features on Rust 1.75.0.
To build and test with the MSRV you will need to pin the below dependency versions:
cargo update -p async-compression --precise 0.4.3
cargo update -p zstd-sys --precise 2.0.8+zstd.1.5.5
cargo update -p flate2 --precise 1.0.35
cargo update -p home --precise 0.5.5
cargo update -p zerofrom --precise 0.1.5
cargo update -p half --precise 2.4.1
cargo update -p url --precise 2.5.2
# For wasm32-unknown-unknown target
cargo update -p triomphe --precise 0.1.11
License
This project is licensed under the MIT License.