Commit Graph

97 Commits

Author SHA1 Message Date
Luke
a40989b6b3 Typo fix (#1217) 2025-10-27 16:06:55 -04:00
tsk
ec6e1e2910 fix: improve Melted error handling and add debug logging (#1213)
Replace .unwrap() with proper error handling using ? operator and add
debug logging to help diagnose fee calculation issues in the melt flow.

Changes:
- Replace .unwrap() with ? for proper error propagation
- Add tracing log for proofs amount, amount, and change amount

feat: nut14-validation
2025-10-26 10:23:41 -04:00
tsk
33c206a310 Swap saga (#1183)
# Implement Saga Pattern for Swap Operations with Recovery Mechanism

## Overview

This PR refactors the swap operation implementation to use the saga pattern - a distributed transaction pattern that provides reliable transaction management through explicit state tracking and compensation-based error handling. The implementation includes a robust recovery mechanism that automatically handles swap operations interrupted by crashes, power loss, or network failures.

## What Changed

**Saga Pattern Implementation:**
- Introduced a strict linear state machine for swaps: `Initial` → `SetupComplete` → `Signed` → `Completed`
- New modular `swap_saga` module with state validation, compensation logic, and saga orchestration
- Automatic rollback of database changes on failure, ensuring atomic swap operations
- Replaced previous swap implementation (`swap.rs`, `blinded_message_writer.rs`) with saga-based approach

**Recovery Mechanism:**
- Added `operation_id` and `operation_kind` columns to database schema for tracking which operation proofs belong to
- New `recover_from_bad_swaps()` method that runs on mint startup to handle incomplete swaps
- For proofs left in `PENDING` state from swap operations:
  - If blind signatures exist: marks proofs as `SPENT` (swap completed but not finalized)
  - If no blind signatures exist: removes proofs from database (swap failed partway through)
- Database migrations included for both PostgreSQL and SQLite
2025-10-22 08:30:33 -05:00
tsk
f173b2da47 feat(cdk): add melt quote state transition validation (#1188)
Add state machine validation for melt quote transitions to prevent
invalid state changes. Includes new error types and validation logic
for Unpaid, Pending, Paid, and Failed states.
2025-10-13 09:21:12 +01:00
tsk
95aa64477a Improve add transaction (#1164)
* 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
2025-10-09 16:20:06 +01:00
C
cdd59359b9 Introduce a generic pubsub mod in cdk-common (#1098)
* pubsub: consolidate into Spec, adopt Arc<SubscriptionId>, and wire through  wallet/mint/WS/FFI

Refactor the pub/sub engine to a single Spec trait, move Event alongside it,
and propagate Arc-backed subscription IDs across the stack. This simplifies
generics, clarifies responsibilities, and preserves coalescing +
latest-on-subscribe semantics.

-   **Single source of truth:** `Spec` owns `Topic`, `Event`, `SubscriptionId`,
    `Context`, new_instance, and fetch_events.
-   **Lean & explicit API:** Remove Topic trait split;
    `Subscriber::send(Event)` carries sub-ID internally.
-   **Performance/ergonomics:** `Arc<SubscriptionId>` avoids heavy clones and
    makes channel/task hops trivial.

-   Introduce `pub_sub/typ.rs` with:
    -   trait `Spec`
    -   trait `Event` colocated with Spec.
-   Remove `pub_sub/event.rs` fold `Event` into `typ.rs`.
-   Make `Pubsub<S>` generic over `Spec` and store `Arc<S>`.
-   The subscriber holds `Arc<SubscriptionId>` and deduplicates the latest
    entry per subscription.
-   SubscriptionRequest: rename SubscriptionName → SubscriptionId; return
    `Arc<...>` from `subscription_name()`.
-   Remote consumer (Transport) now parameterized by `Spec`; control types
    updated:
    -   `StreamCtrl<S>`, `SubscribeMessage<S>`, internal caches keyed by
        `S::Topic`.
-   Mint/wallet:
    -   Mint: `MintPubSubSpec` (Context = `DynMintDatabase`),
        `PubSubManager(Pubsub<MintPubSubSpec>)`.
    -   Wallet: lightweight MintSubTopics Spec with `Context = ()`.
-   IDs go Arc end-to-end:
    -   cdk-axum WS maps `HashMap<Arc<SubId>, JoinHandle<()>>`, publisher sends
        `(Arc<SubId>, NotificationPayload)`.
    -   `subscription::{Params, WalletParams}` now use `Arc<...>`.
    -   cdk-ffi conversions & wallet glue updated.
    -   Integration tests updated for new types.

-   Coalescing unchanged: multiple local subs to the same topic are combined
    into a single remote sub.
-   Backfill via `Spec::fetch_events(topics, Subscriber)`; Subscriber enforces
    latest-only dedupe per subscription.

**Result:** a slimmer, more maintainable pub/sub core that’s easier to embed
across mint, wallet, transports, and FFI without sacrificing performance or
semantics.


---------

Co-authored-by: thesimplekid <tsk@thesimplekid.com>
2025-10-08 09:33:45 +01:00
tsk
c5e5d71701 feat(cdk): add payment request and proof to transaction records (#1155)
Add payment_request and payment_proof fields to Transaction model to store Lightning invoice details and payment preimages. Update database migrations and all transaction creation points across wallet operations (mint, melt, send, receive) to populate these fields.
2025-10-06 14:40:21 +02:00
vnprc
1a493d61f8 feat: optimize SQL balance calculation (#1152)
* 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>
2025-10-06 10:29:57 +02:00
benthecarman
6bffd78233 Make sorting Transactions a stable sort (#1147)
If you had 2 Transactions that had the same timestamp the sort could be
unstable and could cause annoying issues. Now it will compare the ids if
they are equal and should always have a stable sorting implementation
now.
2025-10-02 10:11:47 +01:00
thesimplekid
4b04d10383 Check change unique (#1112)
* 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
2025-09-27 23:51:24 +01:00
thesimplekid
05acb914fe feat: remove delete fns for quotes (#1122) 2025-09-26 14:37:43 +01:00
C
0f0b78c0b0 Include supported amounts instead of assuming the power of 2 (#1055)
* Include supported amounts instead of assuming the power of 2

The mint's signatory defines the amounts and the wallet, and the mint, when
paying, should use them instead of assuming the supported amounts are
2^(0..32), which is not part of the spec.

* Introduce FeeAndAmount struct
2025-09-24 13:02:24 +01:00
asmo
1e6102f494 add FFI types for NUT-04 and NUT-05 (#1101)
* feat: add FFI types and conversion logic for NUT-04 and NUT-05 settings in `cdk-ffi`

* feat: remove auth feature and deafult to having auth

---------

Co-authored-by: thesimplekid <tsk@thesimplekid.com>
2025-09-23 11:44:11 +01:00
thesimplekid
aeafab9a10 fix: config overwrite on start up (#1081)
* fix: config overwrite on start up
2025-09-20 16:49:37 +01:00
thesimplekid
944cf2ae0b fix: error respose detail (#1090) 2025-09-18 20:40:26 +01:00
David Caseria
23cba67c3b MultiMintWallet Refactor (#1001) 2025-09-17 17:27:54 +01:00
thesimplekid
049ce64462 feat(cdk): add amount_mintable method and improve mint quote validation (#1075)
* feat(cdk): add amount_mintable method and improve mint quote validation

- Add MintQuote::amount_mintable() method to calculate available mint amount
- Update mint issue logic to use centralized amount calculation
- Add validation for Bolt11 payment amounts matching quote amounts
- Improve error handling and logging for quote amount mismatches
2025-09-16 17:26:19 +01:00
thesimplekid
5ee405de89 Store last pay index (#1077) 2025-09-16 14:08:43 +01:00
thesimplekid
2dbb418db7 feat: store melt_request (#1045) 2025-09-16 10:55:36 +01:00
gudnuf
2c9333449a fix: replace std::time with instant for wasm (#1060) 2025-09-13 11:12:41 +01:00
C
0bf5325927 Fixed error with wrong placeholder (#1069)
* Fixed error with wrong placeholder

Add concept of schema, so each test is isolated
2025-09-12 17:17:40 +01:00
asmo
75a3e6d2c7 Prometheus crate (#883)
* feat: introduce `cdk-prometheus` crate with Prometheus server and CDK-specific metrics support
2025-09-09 13:26:03 +01:00
C
841e35d70f Reorganize tests, add mint quote/payment coverage, and prevent over-issuing (#1048)
* Add consistent ordering of sql migrations

Also sort the prefix and not only the filenames

* Reorganize tests, add mint quote/payment coverage, and prevent over-issuing

Reorganizes the mint test suite into clear modules, adds comprehensive mint
quote & payment scenarios, enhances the shared test macro, and hardens SQL
logic to forbid issuing more than what’s been paid.

These tests were added:

* Add quote once; reject duplicates.
* Register multiple payments and verify aggregated amount_paid.
* Read parity between DB and in-TX views.
* Reject duplicate payment_id in same and different transactions.
* Reject over-issuing (same TX, different TX, with/without prior payments).

---------

Co-authored-by: thesimplekid <tsk@thesimplekid.com>
2025-09-08 14:55:41 +01:00
thesimplekid
5518ad2654 feat(cdk): add quote_id field to transactions for quote tracking (#1041)
- Add quote_id field to Transaction struct in cdk-common
- Add database migrations for quote_id column in SQLite and PostgreSQL
- Update wallet operations to populate quote_id for mint/melt transactions
- Set quote_id to None for send/receive operations without associated quotes
2025-09-06 19:57:23 +01:00
thesimplekid
9b35158a8a fix: sig error code (#1038) 2025-09-06 16:04:29 +01:00
C
ded165f405 Update the signatory.proto file to match NUT-XXX (#1032)
* Update the signatory.proto file to match NUT-XXX

Source: https://github.com/cashubtc/nuts/pull/250/files

* Add unit tests as requested in https://github.com/cashubtc/cdk/pull/1032#discussion_r2321436860

* Remove unused types from proto file
2025-09-05 19:07:04 -03:00
thesimplekid
c6cff3f6f4 feat(cdk): add generic key-value store functionality for mint databases (#1022)
* feat(cdk): add generic key-value store functionality for mint databases

Implements a comprehensive KV store system with transaction support,
namespace-based organization, and validation for mint databases.

- Add KVStoreDatabase and KVStoreTransaction traits for generic storage
- Include namespace and key validation with ASCII character restrictions
- Add database migrations for kv_store table in SQLite and PostgreSQL
- Implement comprehensive test suite for KV store functionality
- Integrate KV store traits into existing Database and Transaction bounds
2025-09-05 13:58:48 +01:00
thesimplekid
734e62b04a refactor: use quote id to string (#1026) 2025-09-02 10:47:26 +01:00
thesimplekid
6067242793 fix: cdk melt quote track payment method (#1021)
Add payment_method field to MeltQuote struct to track whether quotes use BOLT11 or BOLT12 payment methods. Include database migrations for both SQLite and PostgreSQL to support the new field. Update melt operations to set and use the payment method for proper routing between BOLT11 and BOLT12 endpoints.
2025-09-01 08:39:51 +01:00
thesimplekid
7a71a37eab refactor(payment): replace wait_any_incoming_payment with event-based system (#1019)
Rename wait_any_incoming_payment to wait_payment_event and change return type
from WaitPaymentResponse stream to Event stream. This introduces a new Event
enum that wraps payment responses, making the system more extensible for
future event types.

- Add Event enum with PaymentReceived variant
- Update MintPayment trait method signature
- Refactor all payment backend implementations (LND, CLN, LNBits, fake wallet)
- Update mint and payment processor to handle new event stream forma
2025-08-31 17:26:50 +01:00
lollerfirst
f1118b1c7b compatibility for migrating Nutshell Mints quote ids (#984) 2025-08-27 17:12:35 +01:00
C
218b39a670 Introduce Future Streams for Payments and Minting Proofs (#985)
* Introduce Future Streams for Payments and Minting Proofs

Introduce Future Streams (`ProofStream`, `PaymentStream`) for Payments and
Proofs, an easier to use interface, async friendly, to interact for the mint
waiting for payments of mints for Bolt11 and Bolt12.

---------

Co-authored-by: thesimplekid <tsk@thesimplekid.com>
2025-08-26 11:57:15 +01:00
thesimplekid
9ab86fabfe Cdk ldk node (#904)
* feat: add LDK Node Lightning backend with comprehensive integration

- Add new cdk-ldk-node crate implementing Lightning backend using LDK Node
- Extend MintPayment trait with start/stop methods for processor lifecycle management
- Add LDK Node configuration support to cdk-mintd with chain source and gossip options
- Enhance mint startup/shutdown to properly manage payment processor lifecycle

---------

Co-authored-by: Erik <78821053+swedishfrenchpress@users.noreply.github.com>
2025-08-25 22:06:00 +01:00
thesimplekid
9a3d9b7139 feat: bip353 (#969) 2025-08-21 16:16:48 +01:00
thesimplekid
ecdc78135d refactor(cdk): defer BOLT12 invoice fetching to payment execution (#978)
* refactor(cdk): defer BOLT12 invoice fetching to payment execution

Move BOLT12 invoice generation from quote creation to payment time, make
request_lookup_id optional for offers, and simplify payment structures by
removing unnecessary boxing and intermediate storage of invoices.
2025-08-20 11:20:30 +01:00
Cesar Rodas
29ce2e4f4d Http retry should only happen at Http Error (which are transport errors)
Fixes #939
2025-08-19 10:38:03 -03:00
thesimplekid
d3a3c30d99 feat(cdk): add Bolt12 mint quote subscription support (#976)
* feat(cdk): add Bolt12 mint quote subscription support

Extends subscription to handle Bolt12 payment method alongside existing Bolt11 support across wallet, mint, and CLI components.
2025-08-19 12:01:01 +01:00
C
28a01398fd Add PostgreSQL support for mint and wallet (#878)
* Add PostgreSQL support for mint and wallet

* Fixed bug to avoid empty calls `get_proofs_states`

* Fixed SQL bug

* Avoid redudant clone()

* Add more tests for the storage layer

* Minor enhacements

* Add a generic function to execute db operations

This function would log slow operations and log errors

* Provision a postgres db for tests

* Update deps for msrv

* Add postgres to pipeline

* feat: add psgl to example and docker

* feat: db url fmt

---------

Co-authored-by: thesimplekid <tsk@thesimplekid.com>
2025-08-18 17:45:11 +01:00
thesimplekid
2e424e629f feat: uuid version (#891)
* feat: uuid version

* feat: rustls version
2025-08-18 16:25:24 +01:00
C
f8d58e419f Merge pull request #963 from crodas/feature/wait-for-invoice
Add `wait_for_payment` function in the wallet
2025-08-18 12:57:45 +01:00
vnprc
5b30ca546d fix: implement atomic keyset counter
- remove get_keyset_counter
- update increment_keyset_counter to atomically increment and return counter value
- replace get+increment pattern with atomic increment everywhere
2025-08-15 11:50:33 +01:00
thesimplekid
5d98fdf353 Keyset counter (#950)
* 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
2025-08-13 08:54:45 +01:00
lollerfirst
92eea181fd new secret derivation
Wallet holds `seed` instead of `xpriv`

fix doctest  errors

update examples

adjustments

fix doctests

fix all doctests

Update crates/cdk/src/wallet/multi_mint_wallet.rs

Co-authored-by: thesimplekid <tsk@thesimplekid.com>

fix

remove clone call
2025-08-02 19:36:20 +02:00
Cesar Rodas
349c773406 Introduce cdk-sql-common
The primary purpose of this new crate is to have a common and shared codebase
for all SQL storage systems. It would force us to write standard SQL using best
practices for all databases.

This crate has been extracted from #878
2025-07-29 11:31:23 -03:00
codingpeanut157
29a2866326 TransactionId::from_hex check bytes len before copy_from_slice
avoid panicking when the input does not convert to an [u8;32] byte array
2025-07-28 12:24:03 +02:00
David Caseria
f018465aa6 Refactor MintBuilder (#887)
* Refactor MintBuilder
* Validate azp instead of aud for client id
2025-07-19 18:13:11 +02:00
David Caseria
bd2fbb13f9 Wallet: Check Pending Melt Quotes (#895)
* Add transaction for pending melt

* Check pending melt quotes

* Fix imports
2025-07-17 09:37:38 +02:00
thesimplekid
ae6c107809 feat: bolt12 2025-07-13 18:48:35 +01:00
mountdisk
0e3b23534a chore: fix some minor issues in the comments
Signed-off-by: mountdisk <mountdisk@icloud.com>
2025-06-30 19:33:29 +08:00
C
238b09d56a Split the database trait into read and transactions. (#826)
* Split the database trait into read and transactions.

The transaction traits will encapsulate all database changes and also expect
READ-and-lock operations to read and lock records from the database for
exclusive access, thereby avoiding race conditions.

The Transaction trait expects a `rollback` operation on Drop unless the
transaction has been committed.

* fix: melt quote duplicate error

This change stops a second melt quote from being created
if there is an existing valid melt quote for an invoice already.
If the first melt quote has expired then we allow for a new melt quote to be created.

---------

Co-authored-by: thesimplekid <tsk@thesimplekid.com>
2025-06-28 12:07:47 +01:00