* fix(wallet): move transaction ID calculation before database operations
* fix(sql): remove on ys from on conflict transaction insert
Since the id is created from the ys we know that if there is a conflict
the ys are the same and do not need to be updated.
* feat: bench for transactio id
* chore: fmt
* feat: optimize SQL balance calculation
replace proof-fetching approach with SUM aggregation
- add get_balance() method to Database trait
- implement SQL SUM aggregation in cdk-sql-common
- update total_balance() to use get_balance() instead of get_unspent_proofs()
- redb impl maintains existing behavior
---------
Co-authored-by: thesimplekid <tsk@thesimplekid.com>
Co-authored-by: Cesar Rodas <cesar@rodasm.com.py>
* feat: refresh keysets
* fix(cdk): resolve keyset counter skipping index 0 in deterministic secret generation
- Modified Database::get_keyset_counter to return u32 instead of Option<u32>
- Added database migrations to increment existing keyset counters by 1
- Removed counter increment logic from wallet operations to use actual counter value
- Ensures deterministic secret generation starts from index 0 instead of skipping it
* feat: add keyset u32 mapping migration and duplicate handling
- Add new database migration (version 3) to include u32 representation for keysets
- Implement migration for both redb and SQL databases
- Add duplicate detection and handling for keyset entries
- Create unique index constraint for keyset_u32 column in SQL
- Update keyset storage to include u32 identifiers
- Handle backwards compatibility for existing databases
* chore: clippy
* refactor(cashu): simplify keyset ID verification logic
- Consolidate match expression into a single expression
- Use direct comparison with ensure_cdk macro
- Improve readability of keyset ID validation
* refactor(cdk): rename `fetch_keyset_keys` to `load_keyset_keys` for clarity
- Renamed `fetch_keyset_keys` to `load_keyset_keys` across multiple modules to better reflect its behavior of loading keys from local storage or fetching from mint when missing.
- Added debug logging to indicate when keys are being fetched from the mint.
- Simplified key loading logic in `update_mint_keysets` by removing redundant existence checks.
* chore: remove unused vec
* Fix SQLite race condition
Bug: https://github.com/crodas/cdk/actions/runs/15732950296/job/44339804072#step:5:1853
Reason: When melting in parallel, many update the melt status and attempt to
add proofs and they fail when adding the proof and the rollback code kicks in.
The loser process removes all the proofs, and the winner process has no proof
later on.
Fix: Modify `update_melt_quote_state` requirements and implementation to allow
only one winner.
This will be solved by design with a transaction writer trait
* Remove `melt_request`
Fixes#809
* Remove `get_melt_request` from db trait
Bug: https://github.com/cashubtc/cdk/actions/runs/15683152414/job/44190084378?pr=822#step:5:19212
Reason: a race condition between removing proofs while melting and the quote states being updated.
Solution:
1. Error on duplicate proofs
2. Read quote when updating to avoid race conditions and rollbacks
Real solution: A transaction trait in the storage layer. That is coming next
Add a strict set of updates to prevent incorrect state changes and correct
usage. Supporting the transaction at the trait level prevented some cases, but
having a strict set of state change flows is better.
This bug was found while developing the signatory. The keys are read from
memory, triggering race conditions at the database, and some `Pending` states
are selected (instead of just selecting `Unspent`).
This PR also introduces a set of generic database tests to be executed for all
database implementations, this test suite will make sure writing and
maintaining new database drivers
* feat: Add created_time and paid_time fields to MintQuote struct
* feat: Add serde default of 0 for created_time in MintQuote
* feat: Add created_time and paid_time to MintQuote and MeltQuote structs
* feat: Add paid_time update when setting melt quote state to Paid
* fix: Update melt quote state with current Unix timestamp
* feat: Add paid_time update for mint quote when state is set to Paid
* feat: Add issued_time field to MintQuote conversion from SQLite row
* feat: Add issued_time tracking for MintQuoteState::Issued state
* feat: Add migration script for mint time of quotes
* feat: Add timestamp columns to mint_quote and melt_quote tables
* feat: Add timestamp columns to `add_mint_quote` method
* refactor: Improve code formatting and readability in mint quote state update logic
* feat: Add created_time and paid_time columns to melt_quote query
* feat: time on mint and melt quotes
* feat: Add migration script for mint created time signature
feat: Add created_time column to blind_signature table
feat: Add created_time to blind_signature insertion
feat: Add created_time column to proof table and update insert query
feat: time on mint and melt quotes
* feat: Add new table to track blind signature creation time
* feat: Add timestamp tracking for proofs in ReDB database
* feat: redb proof time
* chore: fmt
- MintKeysDatabase
- MintQuotesDatabase
- MintProofsDatabase
- MintSignaturesDatabase
This commit splits the MintDatabase trait with 30+ methods into a series
of smaller traits, each dedicate to a specific subsystem of the mint
service.