Skip to content

feat(cashu): F2 — config, escrow mode, and conditional boot#758

Merged
grunch merged 6 commits into
feat/cashu-mostro-core-0.12from
feat/cashu-f2-config-escrow-mode
May 30, 2026
Merged

feat(cashu): F2 — config, escrow mode, and conditional boot#758
grunch merged 6 commits into
feat/cashu-mostro-core-0.12from
feat/cashu-f2-config-escrow-mode

Conversation

@AndreaDiazCorreia
Copy link
Copy Markdown
Member

@AndreaDiazCorreia AndreaDiazCorreia commented May 30, 2026

Adds the CashuSettings config struct and EscrowMode enum, wires them into startup validation (Cashu and anti-abuse bonds are mutually exclusive; mint_url must be a valid HTTP/HTTPS URL), and branches the daemon boot path: when [cashu] enabled = true the node starts without LND and routes all actions through a no-LN event loop stub. Lightning behavior is entirely unchanged when the [cashu] block is absent. Includes wizard support for escrow mode selection and a commented [cashu] block in the settings template.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Cashu 2-of-3 multisig escrow mode as an alternative to Lightning hold invoices (disabled by default)
    • Added interactive setup wizard support for Cashu mint configuration
    • Application now supports runtime selection between escrow modes
  • Chores

    • Updated configuration validation to enforce mutual exclusivity of Cashu and anti-abuse bond modes
    • Added Cashu dependency support

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 30, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (1)
  • develop

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 228f1f1a-3c7b-491f-abcd-c8d63232f2e7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR adds Cashu ecash escrow support as an alternative to Lightning-based hold invoices. It introduces configuration types, validation rules, setup wizard prompts, a Cashu-only event loop, and startup-time mode selection between Lightning and Cashu execution paths.

Changes

Cashu Escrow Mode Support

Layer / File(s) Summary
Escrow mode types and configuration schema
src/config/types.rs
EscrowMode enum (Lightning, Cashu) and CashuSettings struct (enabled flag, mint_url) with TOML deserialization tests verify default and parsed values.
Settings struct and mode accessors
src/config/settings.rs, src/config/mod.rs, settings.tpl.toml
Settings gains optional cashu field with CashuSettings and EscrowMode re-exported publicly; methods get_cashu(), is_cashu_enabled(), and escrow_mode() resolve active mode based on configuration.
Configuration validation and test fixtures
src/config/util.rs, src/app/context.rs, src/app/dev_fee.rs, src/app/rate_user.rs, src/lightning/mod.rs
validate_mostro_settings enforces mutual exclusion of cashu and anti_abuse_bond, validates mint_url is non-empty and uses http/https scheme; test settings fixtures across five modules updated with cashu: None.
Interactive setup wizard
src/config/wizard.rs
Wizard prompts user to select escrow mode (Lightning vs Cashu), conditionally collects Cashu mint URL, and validates mint URL scheme; populates Settings with selected mode.
Cashu event loop
src/app.rs
New run_cashu(ctx) async function mirrors the main gift-wrap message loop but routes actions through handle_message_action_no_ln (no LND required); performs identical validation, signature checks, and error handling as Lightning path.
Application startup and mode selection
src/main.rs, Cargo.toml
Startup refactored to build AppContext and start scheduler before mode selection; checks is_cashu_enabled() and returns run_cashu(ctx) immediately if true, otherwise continues to Lightning setup and run(ctx). Adds cdk 0.16 dependency with no defaults.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • MostroP2P/mostro#696: Main PR extends the interactive setup wizard introduced in #696 by adding Cashu "Escrow Mode" prompts and mint URL validation.
  • MostroP2P/mostro#712: Cashu escrow configuration explicitly gates and mutually excludes with the anti_abuse_bond settings introduced in PR #712.

Suggested reviewers

  • grunch
  • arkanoider
  • Catrya

Poem

🐰 A rabbit hops through crypto dreams,
Where Cashu flows like moonlit streams!
No Lightning chain, just ecash grace,
A second path in escrow's race—
Two modes now bloom in Mostro's soul, 🌕✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: adding Cashu configuration, introducing an escrow mode selection mechanism, and implementing conditional boot logic based on the selected mode.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cashu-f2-config-escrow-mode

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0f720c94bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/main.rs
Comment thread src/config/types.rs
@AndreaDiazCorreia
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main.rs (1)

142-155: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix scheduler startup order: avoid LN_STATUS.get().unwrap() before LND init (and in Cashu mode).

main.rs calls start_scheduler(ctx.clone()).await before either LN_STATUS.set(...) (Lightning) or any Cashu-mode initialization/exit. In scheduler.rs, start_scheduler awaits job_info_event_send(...), and that function immediately does let ln_status = LN_STATUS.get().unwrap();, so:

  • Cashu mode will panic because it returns before LN_STATUS.set runs.
  • Lightning mode can also panic/race because the scheduler runs before LN_STATUS.set(ln_status) at main.rs:153.

Move start_scheduler after LN_STATUS.set(...), or make job_info_event_send not unwrap when LN_STATUS isn’t available in the current mode (e.g., gate it on Settings::is_cashu_enabled() / conditional LN_STATUS access).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main.rs` around lines 142 - 155, The scheduler is started before
LN_STATUS is ever set, causing job_info_event_send to call
LN_STATUS.get().unwrap() and panic in Cashu mode or race in Lightning mode; fix
by either (A) moving start_scheduler(ctx.clone()).await in main.rs to after
LN_STATUS.set(ln_status) (i.e., after LndConnector::new().await,
ln_client.get_node_info().await and LnStatus::from_get_info_response are used
and LN_STATUS.set(...) succeeds), or (B) make job_info_event_send/its caller
guard LN_STATUS.get() access (check Settings::is_cashu_enabled() or handle None
instead of unwrap) so Cashu mode and pre-set scheduler startup do not unwrap a
missing LN_STATUS. Ensure references to start_scheduler, job_info_event_send,
LN_STATUS.set, Settings::is_cashu_enabled, run_cashu, and LndConnector::new are
updated accordingly.
🧹 Nitpick comments (2)
src/app.rs (1)

398-484: 🏗️ Heavy lift

run_cashu duplicates the entire run event loop, including security-critical validation.

The body of run_cashu (408-483) is a line-for-line copy of run (304-395); the only difference is the dispatch call (handle_message_action_no_ln vs handle_message_action). This duplicates the POW check, NIP-59 unwrap, 10s replay window, inner-signature enforcement, and check_trade_index logic. Any future fix to these checks must be applied in two places, which is an easy place for the two paths to silently diverge.

Consider extracting the shared loop and parameterizing the dispatch step (e.g., an optional &mut LndConnector, an enum, or a closure), so both modes share one validated path.

♻️ Sketch: single loop parameterized by mode
enum EventMode<'a> {
    Lightning(&'a mut LndConnector),
    Cashu,
}

async fn run_loop(ctx: AppContext, mut mode: EventMode<'_>) -> Result<()> {
    let my_keys = ctx.keys();
    let client = ctx.nostr_client();
    let pow = ctx.settings().mostro.pow;
    // ... shared validation ...
    // dispatch:
    let res = match &mut mode {
        EventMode::Lightning(ln) => {
            handle_message_action(&action, message.clone(), &unwrapped, my_keys, ln, &ctx).await
        }
        EventMode::Cashu => {
            handle_message_action_no_ln(&action, message.clone(), &unwrapped, my_keys, &ctx).await
        }
    };
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app.rs` around lines 398 - 484, run_cashu duplicates the entire run event
loop (POW check, unwrap_message, replay window, inner-signature check,
check_trade_index) differing only by the dispatch call; extract the shared logic
into a single parameterized loop and call it from both modes. Create a new
function (e.g., run_loop or similar) that takes AppContext plus a dispatch-mode
parameter (an enum like EventMode or a closure) and moves the common validation
and event iteration there, keeping the existing symbols unwrap_message,
check_trade_index, and inner_message verification unchanged; then have run call
the new loop with a mode that invokes handle_message_action and run_cashu call
it with a mode that invokes handle_message_action_no_ln. Ensure error handling
(manage_errors, warning_msg, MostroError downcast) remains identical inside the
shared loop.
src/config/wizard.rs (1)

378-388: ⚡ Quick win

Add a unit test for validate_mint_url.

The other validators (validate_nsec, validate_relays, validate_file_exists) have co-located tests, but this new public validator does not. A small test would lock down the http/https-only contract and reject cases (invalid URL, ws:///wss://, missing scheme).

💚 Suggested test
#[test]
fn test_validate_mint_url() {
    assert!(validate_mint_url("https://mint.example.com").is_ok());
    assert!(validate_mint_url("http://localhost:3338").is_ok());
    assert!(validate_mint_url("wss://mint.example.com").is_err());
    assert!(validate_mint_url("not a url").is_err());
    assert!(validate_mint_url("").is_err());
}
As per coding guidelines: "Co-locate tests in their modules under `mod tests` blocks with descriptive names".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config/wizard.rs` around lines 378 - 388, Add a co-located unit test for
the public function validate_mint_url in the same module: create a mod tests
block with a descriptive test function (e.g., test_validate_mint_url) that
asserts ok for "https://mint.example.com" and "http://localhost:3338" and
asserts Err for "wss://mint.example.com", "not a url", and the empty string to
lock down the http/https-only contract; place the test alongside the other
validator tests in this file and run cargo test to verify.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/config/util.rs`:
- Around line 80-98: The current validation uses nostr_sdk::Url::parse and
.scheme() which are not available in nostr-sdk 0.44.1; update the block that
checks settings.cashu (and the cashu.mint_url variable) to parse the mint_url
with url::Url::parse instead and then call url.scheme() to validate
"http"/"https" (preserve the same error messages and
MostroInternalErr/ServiceError::IOError handling), i.e., replace
nostr_sdk::Url::parse(...) and parsed.scheme() usages with
url::Url::parse(&cashu.mint_url) and url.scheme() respectively.

---

Outside diff comments:
In `@src/main.rs`:
- Around line 142-155: The scheduler is started before LN_STATUS is ever set,
causing job_info_event_send to call LN_STATUS.get().unwrap() and panic in Cashu
mode or race in Lightning mode; fix by either (A) moving
start_scheduler(ctx.clone()).await in main.rs to after LN_STATUS.set(ln_status)
(i.e., after LndConnector::new().await, ln_client.get_node_info().await and
LnStatus::from_get_info_response are used and LN_STATUS.set(...) succeeds), or
(B) make job_info_event_send/its caller guard LN_STATUS.get() access (check
Settings::is_cashu_enabled() or handle None instead of unwrap) so Cashu mode and
pre-set scheduler startup do not unwrap a missing LN_STATUS. Ensure references
to start_scheduler, job_info_event_send, LN_STATUS.set,
Settings::is_cashu_enabled, run_cashu, and LndConnector::new are updated
accordingly.

---

Nitpick comments:
In `@src/app.rs`:
- Around line 398-484: run_cashu duplicates the entire run event loop (POW
check, unwrap_message, replay window, inner-signature check, check_trade_index)
differing only by the dispatch call; extract the shared logic into a single
parameterized loop and call it from both modes. Create a new function (e.g.,
run_loop or similar) that takes AppContext plus a dispatch-mode parameter (an
enum like EventMode or a closure) and moves the common validation and event
iteration there, keeping the existing symbols unwrap_message, check_trade_index,
and inner_message verification unchanged; then have run call the new loop with a
mode that invokes handle_message_action and run_cashu call it with a mode that
invokes handle_message_action_no_ln. Ensure error handling (manage_errors,
warning_msg, MostroError downcast) remains identical inside the shared loop.

In `@src/config/wizard.rs`:
- Around line 378-388: Add a co-located unit test for the public function
validate_mint_url in the same module: create a mod tests block with a
descriptive test function (e.g., test_validate_mint_url) that asserts ok for
"https://mint.example.com" and "http://localhost:3338" and asserts Err for
"wss://mint.example.com", "not a url", and the empty string to lock down the
http/https-only contract; place the test alongside the other validator tests in
this file and run cargo test to verify.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7d8342ab-614e-4546-9753-0d7254cf999c

📥 Commits

Reviewing files that changed from the base of the PR and between 1e0ef08 and 23bfef1.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • Cargo.toml
  • settings.tpl.toml
  • src/app.rs
  • src/app/context.rs
  • src/app/dev_fee.rs
  • src/app/rate_user.rs
  • src/config/mod.rs
  • src/config/settings.rs
  • src/config/types.rs
  • src/config/util.rs
  • src/config/wizard.rs
  • src/lightning/mod.rs
  • src/main.rs

Comment thread src/config/util.rs
@AndreaDiazCorreia
Copy link
Copy Markdown
Member Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 78120fcc9f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/app.rs Outdated
Comment thread src/main.rs
Copy link
Copy Markdown

@ermeme ermeme Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Changes Requested

Critical

  • Cashu mode is not usable yet: the new no-LN loop still delegates TakeBuy / TakeSell / AddInvoice into the legacy helpers, and those helpers eventually call show_hold_invoice() / LndConnector::new(). A no-LND Cashu deployment will still fail on the normal trade path instead of using Cashu escrow.

Warnings

  • The full scheduler still starts before the mode check, so LND-backed jobs are spawned in Cashu mode as well. job_process_bond_payouts() will keep retrying a Lightning connection in the background when LND is absent.

Looks Good

  • Cashu config validation is doing the right thing: it rejects invalid URLs, enforces http/https, and blocks cashu + anti_abuse_bond together.

Comment thread src/app.rs Outdated
Comment thread src/main.rs
Copy link
Copy Markdown

@ermeme ermeme Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Changes Requested

Cashu mode is not ready to merge yet. The new boot path still isn't truly LND-free, and the normal trade flow in Cashu mode still routes into Lightning-only helpers.

Please gate the LND-backed scheduler jobs and replace the remaining Lightning hold-invoice path before approval.

Comment thread src/app.rs Outdated
Comment thread src/main.rs
Block TakeSell/TakeBuy/AddInvoice in run_cashu event loop with CantDo(InvalidAction) until escrow wiring lands (F4+). Skip job_process_dev_fee_payment and job_process_bond_payouts when is_cashu_enabled() so they don't attempt LND calls in Cashu-only mode.
@AndreaDiazCorreia
Copy link
Copy Markdown
Member Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be874b9802

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/wizard.rs
} else {
println!("\n--- Cashu Mint Configuration ---\n");
let cashu = prompt_cashu_settings()?;
(LightningSettings::default(), Some(cashu))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid zero-interval LN retry loop in Cashu wizard

When the guided wizard is used to create a Cashu config, this stores LightningSettings::default(), whose payment_retries_interval is 0. Cashu startup still calls start_scheduler before entering run_cashu, and job_retry_failed_payments unconditionally uses that lightning interval in tokio::time::sleep(Duration::from_secs(interval)); with the wizard-generated Cashu config this becomes a zero-duration sleep, causing a tight DB polling/logging loop and possible repeated LND attempts if failed payments exist. Populate the normal lightning scheduler defaults even for Cashu, or skip the LN-only scheduler jobs in Cashu mode.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@ermeme ermeme Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Changes Requested

You fixed the two big blockers from the previous revision: Cashu trade actions are no longer routed into the Lightning hold-invoice path, and the two LND-heavy scheduler jobs are now skipped in Cashu mode. Good.

There are still two issues I would want changed before approving:

  1. job_cancel_orders() still initializes LndConnector unconditionally during scheduler startup, so a Cashu-only node still touches LND on boot.
  2. In Cashu mode, Release, Cancel, AdminCancel, and AdminSettle still fall through to the no-op branch instead of returning an explicit CantDo. That is a silent success for escrow-dependent actions.

Please gate or remove the remaining LND startup path, and reject unsupported escrow actions explicitly.

Comment thread src/app.rs Outdated
Comment thread src/scheduler.rs
…ip retry_failed_payments and cancel_orders scheduler jobs in Cashu mode

Extend the F2 CantDo(InvalidAction) block to Release/Cancel/AdminCancel/AdminSettle (all require LN invoice handling until escrow wiring lands in F4+). Skip job_retry_failed_payments and job_cancel_orders when is_cashu_enabled() so they don't attempt LND calls in Cashu-only mode.
@AndreaDiazCorreia
Copy link
Copy Markdown
Member Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7dd7c15c4e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/app.rs Outdated
Comment on lines +460 to +466
Action::TakeSell
| Action::TakeBuy
| Action::AddInvoice
| Action::Release
| Action::Cancel
| Action::AdminCancel
| Action::AdminSettle => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prevent unfillable Cashu orders

When Cashu mode is enabled, Action::NewOrder is still routed through handle_message_action_no_ln, so makers can publish orders, but this branch rejects every take/add-invoice path and also rejects Cancel. Those orders are visible on the book but no taker can fill them, and the maker cannot remove a pending order except by waiting for expiry. Either reject NewOrder while the Cashu trade flow is still a stub, or allow the non-LN pending cancel path so users don't create stuck orders.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@ermeme ermeme Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the latest commit. The two previous blockers are addressed: Cashu mode no longer routes escrow/LND-dependent trade actions into the Lightning path, and the scheduler now skips the LND-backed jobs in Cashu mode. No remaining blockers from my side.

Extend the F2 CantDo(InvalidAction) block to include Action::NewOrder. Without escrow backend wired, allowing order creation would produce orders that can never be filled or cancelled, giving peers a confusing experience. Rejecting NewOrder up front provides a clear error instead.
Copy link
Copy Markdown

@ermeme ermeme Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the latest commit. Blocking NewOrder in Cashu mode is the right call here: it avoids publishing orders that cannot be taken or canceled until the escrow backend exists. No blockers from my side.

@grunch grunch merged commit cad57c8 into feat/cashu-mostro-core-0.12 May 30, 2026
6 checks passed
@grunch grunch deleted the feat/cashu-f2-config-escrow-mode branch May 30, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants