1141 Commits

Author SHA1 Message Date
C
4e0132875f fix: add proof recovery mechanism for failed wallet operations (#1250)
* fix: add proof recovery mechanism for failed wallet operations

This commit introduces a new `try_proof_operation` helper that wraps wallet
operations (swap, melt) with automatic proof recovery in case of network or
mint failures. When an operation fails, the wallet now attempts to recover by
marking proofs as unspent and swapping them to prevent loss of funds.

Fixes #1180
2025-11-04 20:40:31 -05:00
tsk
d9e001bee6 refactor(cdk): implement saga pattern for melt operations (#1186)
Restructure melt flow into a multi-step saga with compensation-based rollback.
Remove ProofWriter in favor of explicit compensation actions for improved
reliability and clarity in handling partial failures during melt operations.

Breaks down monolithic change processing logic into smaller, focused methods:
- process_change_outputs: orchestrates full change workflow
- validate_change_outputs: checks for already-signed messages
- calculate_change_fee_and_amounts: fetches keyset configuration
- split_change_amount: splits change into denominations
- prepare_blinded_messages_with_amounts: pairs amounts with blinded messages
- store_change_signatures: handles TX2 database operations
2025-11-03 11:40:21 -05:00
codingpeanut157
c68c5288f2 PreMintSecrets: fix into_iter() (#1244)
extracting elements from the vector using `Vec::pop` returns the
elements in the reverse order.
This commits fixes the bug by using `Vec::remove(0)`
2025-11-03 09:19:52 -05:00
C
c6434b88d1 Fix websocket issues and mint quotes (#1246)
* Fix websocket issues and mint quotes

Fixes #1209

When checking with HTTP pulling, mint quotes would ping the ln backend if
needed to get any payment that may not be included, so the mint uses this
chance to correct its database.

This check was missing for database subscriptions
2025-11-02 19:06:03 -05:00
tsk
dd3cb8a83a fix: lnbits fee calc (#1243)
* fix: lnbits fee calc
2025-10-31 12:20:44 -04:00
David Caseria
fb07ec4b85 Include cargo config for cdk-ffi to enforce Android page sizes (#1241) 2025-10-30 09:41:29 -04:00
tsk
ad4df779e3 feat(cdk-lnbits): add websocket reconnection with exponential backoff (#1237)
Implement automatic reconnection logic when LNbits websocket connection is lost, using exponential backoff strategy (1s to 30s max) with automatic resubscription
2025-10-28 21:33:46 -04:00
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
David Caseria
344b81a694 Update FFI Database Objects to Records (#1149) 2025-10-24 13:24:06 -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
Erik
db2764c566 Redesign Lightning invoice creation and display with better UX and status handling (#1184)
---------

Co-authored-by: thesimplekid <tsk@thesimplekid.com>
2025-10-15 09:36:04 +01:00
David Caseria
5caa7d58ed Configure internal Wallets of a MultiMintWallet (#1177) 2025-10-13 09:53:48 +01: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
69650c2ef9 feat: swap tests (#1187) 2025-10-12 23:16:52 +01:00
tsk
7f17c02787 feat: fake wallet store amount paid (#1185)
* feat: fake wallet store amount paid
2025-10-12 21:09:01 +01:00
asmo
5fc38d5980 fi: add ws resource to ProtectedEndpoints (#1178)
* feat: add ws resource to ProtectedEndpoints
2025-10-10 12:53:07 +01:00
C
5ee760a506 Remove the amounts from amounts (#1179) 2025-10-10 10:14:28 +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
3075ac4e59 Read the latest mint quote status in a transaction to avoid race conditions (#1166)
* Read the latest mint quote status in a transaction to avoid race conditions

Fixes #1162

* Reload quote for all cases

* Exit on paid invoices only for bolt11
2025-10-08 21:52:40 +01:00
tsk
cae8768a87 Fix cdk cli readme (#1165)
* docs: update cli read me

* docs: update postgres link
2025-10-08 21:51:57 +01:00
tsk
dab9281d5a chore: nostr-sdk as workspace dep (#1167) 2025-10-08 15:23:42 +01:00
tsk
2c2fce9612 chore: remove ctor (#1168) 2025-10-08 15:18: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
6fe65553a3 fix(database): add parent directory validation before database creation (#1161)
- Add work directory creation check in cdk-cli main
- Add parent directory existence validation in cdk-redb wallet database
- Add parent directory check in cdk-sqlite connection manager
- Add IO error variant to cdk-redb error types for better error handling
2025-10-07 15:19:14 +02:00
tsk
c30a078a12 fix(cashu): skip serializing empty NUT15 settings in mint info (#1158)
Add is_empty method to nut15::Settings and configure skip_serializing_if
attribute to prevent empty NUT15 objects from appearing in serialized
mint info responses.
2025-10-06 20:21:48 +02:00
daywalker90
03309da7c6 mintd: remove non-existent stdout logging from docs (#1159) 2025-10-06 19:39:08 +02: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
David Caseria
a8c35dbef0 Split uniffi types into multiple mods (#1142) 2025-10-05 13:15:33 +02:00
lollerfirst
e581dcbf62 feat: tor isolated circuits (#1064)
fixes + tor feature in cdk-cli

fix: call `clone_with_prefs` to get a new isolation token

format

remove `new_isolated` from Transport trait

fix: remove tor dependencies under wasm32, disallow compilation with tor feature and wasm32

tor_transport in its own file

fixes

fmt

format

tor: implement Transport::resolve_dns_txt for TorAsync using DoH over Tor; fix tor transport trait changes after rebase; remove unused as_str() call for TorToggle in cdk-cli. Ensure compilation with features: tor,bip353

format

remove double reference

format

feat: circuits pool

format

tor_transport: deterministically select Tor client per request using index_for_request(endpoint path + query + payload)\n\n- Add index_for_request(&Url, Option<&[u8]>) using FNV-1a 64-bit (dependency-free)\n- Replace round-robin next_index() usage in request() with deterministic index\n- Adjust request() to accept Option<Vec<u8>> body to hash payload bytes\n- Update http_get/http_post/resolve_dns_txt to call new request signature\n- Keep next_index() as dead_code for potential fallback

tor_transport: implement Default by bootstrapping with default pool size (blocking)\n\n- Default now attempts to use existing Tokio runtime handle, or creates a temporary runtime\n- Preserves previous behavior for async constructors (new/with_pool_size)

tor_transport: fix Default to avoid nested runtime panic by initializing on a new thread when no Handle available\n\n- If a runtime is present, block_on via current handle\n- Otherwise, spawn a new OS thread and create a runtime inside it, then join

tor_transport: rework Default to use block_in_place + background thread runtime to avoid nested block_on inside tokio\n\n- Always create runtime on a separate OS thread; if inside tokio, enter block_in_place first\n- Avoids 'Cannot start a runtime from within a runtime' panic

fix

more fixes

tor_transport: lazy-initialize Tor client pool on first use via ensure_pool; make Default non-blocking and remove runtime gymnastics\n\n- Introduce Inner with OnceCell<Arc<Vec<TorClient>>> and configured size\n- Default/new/with_pool_size now cheap; actual arti bootstrap happens on first request\n- request() calls ensure_pool() and uses deterministic index with pool.len()\n- Keeps deterministic endpoint/method/body affinity and DoH TXT resolution\n\nThis avoids nested-runtime/block_in_place complexity and makes Default trivial.

tor_transport: make DEFAULT_TOR_POOL_SIZE public and support custom pool sizes via TorAsync::with_pool_size() (lazy)}

remove unneeded async

add salt to keyed circuit selection
2025-10-03 15:39:57 +02:00
David Caseria
ca3444939e Add MultiMintWallet check and wait for mint quotes (#1146)
* Add MultiMintWallet check and wait for mint quotes
2025-10-02 12:24:36 +01:00
C
81a47d5d12 Fix bug with websocket close (#1144)
* Fix bug with websocket close

Fixes #1111

* Do not connect to ws if there are no active subscription
2025-10-02 10:12:17 +01: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
benthecarman
144f1da6c5 Allow passing metadata to a melt (#1148) 2025-10-02 10:11:08 +01:00
thesimplekid
9ad5238323 chore: remove min deps after msrv (#1143) 2025-10-01 10:08:46 +01:00
stefanbitcr
166c96ff88 Fix htlc witness deserialization (#1138)
* Add prior signatures if they exist
2025-09-30 14:49:52 +01:00
asmo
cb2e534f81 feat: added postgres to ffi (#1117)
* feat: added postgres to ffi
2025-09-30 14:14:28 +01:00
thesimplekid
5e93529398 fix: show ammounts (#1136) 2025-09-30 09:12:29 +01:00
thesimplekid
f323544040 fix: lnbits msats error (#1134)
* fix: lnbits msats error

* fix: lnbits msats error
2025-09-28 15:24:55 +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
lollerfirst
6d0003a4fc token: add spending-condition inspection helpers and token_secrets() (#1124)
* token: add Token::token_secrets() and spending-condition helpers

- New helpers on Token that do not require mint keysets:
  - spending_conditions()
  - p2pk_pubkeys()
  - p2pk_refund_pubkeys()
  - htlc_hashes()
  - locktimes()
- Introduce token_secrets() to unify V3/V4 proof traversal and avoid duplication
- Bypass short->long keyset-id mapping since only Secret is needed for conditions
- Use &Secret for TryFrom to fix compile error
2025-09-26 20:56:01 +01:00
thesimplekid
676463f730 Revert "feat: remove redis cache (#1096)" (#1129)
This reverts commit be7c83689d.
2025-09-26 14:43:34 +01:00
thesimplekid
05acb914fe feat: remove delete fns for quotes (#1122) 2025-09-26 14:37:43 +01:00
David Caseria
f48660f344 Make Uniffi Records Codable in Swift (#1125) 2025-09-25 18:59:01 +01:00
gudnuf
500d162f67 fix: handle fiat melt amount conversions (#1109)
* fix: handle fiat melt amount conversions

* feat: add check that processor returns quote unit

---------

Co-authored-by: thesimplekid <tsk@thesimplekid.com>
2025-09-25 18:57:54 +01:00
thesimplekid
caba6978e7 refactor(cdk): simplify mint addition in MultiMintWallet (#1121)
Remove unnecessary mint info fetching and keyset refresh during mint addition,
and improve error propagation in token restoration flow
2025-09-25 16:18:37 +01:00
gudnuf
9d4559a47a fix: only settle same unit quote internally (#1115) 2025-09-25 08:57:41 +01:00
thesimplekid
e07a9c8e1e feat(cdk): add WebSocket authentication support (#1116)
* feat(cdk): add WebSocket authentication support with comprehensive configuration

- Add WebSocket auth token injection for client connections
- Implement server-side WebSocket authentication verification
- Add configuration options for per-endpoint WebSocket auth types
- Include comprehensive documentation and example configuration
- Support clear, blind, and no-auth modes for WebSocket endpoin
2025-09-25 08:31:57 +01:00
asmo
f41ce0a3fb optional client identity in grpc payment processor (#1084)
* fix: update TLS configuration to handle missing client certificates gracefully
2025-09-24 14:56:51 +01:00