Observation
cashu implies cdk/npubcash, so every build with the Cashu trusted tier also compiles the nostr client/relay stack — even when npubcash is never configured.
cashu = ["cdk", "cdk/npubcash", "serde", "serde_json"]
Measured on cdk 0.16.0 with default-features = false (the way orange-sdk depends on it), counting crates in cargo tree -e normal:
| cdk features |
nostr crates in tree |
["wallet"] |
0 |
["wallet", "npubcash"] |
11 |
The 11 are nostr, nostr-sdk, nostr-relay-pool, nostr-database, nostr-gossip, and their support crates. cdk already gates this correctly — npubcash = ["nostr", "dep:cdk-npubcash", …] and plain wallet pulls none of it — so the coupling is introduced by the cashu feature line above, not by cdk.
It is real shipped code for us, not just a lockfile entry: nostr and cdk-npubcash compile into our Android libwallet_ffi.so, with NPUBCASH_URL empty.
To be clear about what this is not
While chasing this I found 11 open RUSTSEC advisories against nostr/nostr-relay-pool, including RUSTSEC-2026-0224 ("verification cache poisoning allows forged Nostr events to bypass signature verification") and RUSTSEC-2026-0226 ("wallet event parsers accept unauthenticated events").
That turned out to be our problem, not yours — our lockfile was stale at nostr 0.44.2 / nostr-relay-pool 0.44.0. A plain cargo update moves them to 0.44.8 / 0.44.3, both semver-compatible, and clears all 11. Already done on our side. I'm not asking you to fix a security bug, and nothing here is urgent.
Suggested change
Make npubcash opt-in, so consumers who want the Cashu tier without the nostr stack can have it:
cashu = ["cdk", "serde", "serde_json"]
npubcash = ["cashu", "cdk/npubcash"]
Happy to send that as a PR if you want it — it's a two-line change plus whatever your uniffi feature should do with it (presumably npubcash joins that list, since the bundled bindings expose the npubcash API).
Priority, honestly
Low, for us. Our production target is the Spark tier, so we can simply not enable cashu; this bites our signet/Cashu staging builds, where it's unused network-facing surface plus a recurring advisory-triage tax on code we never call. Filing it as data rather than a request — entirely your call whether the split is worth making.
Observation
cashuimpliescdk/npubcash, so every build with the Cashu trusted tier also compiles the nostr client/relay stack — even when npubcash is never configured.Measured on cdk 0.16.0 with
default-features = false(the way orange-sdk depends on it), counting crates incargo tree -e normal:["wallet"]["wallet", "npubcash"]The 11 are
nostr,nostr-sdk,nostr-relay-pool,nostr-database,nostr-gossip, and their support crates. cdk already gates this correctly —npubcash = ["nostr", "dep:cdk-npubcash", …]and plainwalletpulls none of it — so the coupling is introduced by thecashufeature line above, not by cdk.It is real shipped code for us, not just a lockfile entry:
nostrandcdk-npubcashcompile into our Androidlibwallet_ffi.so, withNPUBCASH_URLempty.To be clear about what this is not
While chasing this I found 11 open RUSTSEC advisories against
nostr/nostr-relay-pool, including RUSTSEC-2026-0224 ("verification cache poisoning allows forged Nostr events to bypass signature verification") and RUSTSEC-2026-0226 ("wallet event parsers accept unauthenticated events").That turned out to be our problem, not yours — our lockfile was stale at
nostr 0.44.2/nostr-relay-pool 0.44.0. A plaincargo updatemoves them to0.44.8/0.44.3, both semver-compatible, and clears all 11. Already done on our side. I'm not asking you to fix a security bug, and nothing here is urgent.Suggested change
Make npubcash opt-in, so consumers who want the Cashu tier without the nostr stack can have it:
Happy to send that as a PR if you want it — it's a two-line change plus whatever your
uniffifeature should do with it (presumablynpubcashjoins that list, since the bundled bindings expose the npubcash API).Priority, honestly
Low, for us. Our production target is the Spark tier, so we can simply not enable
cashu; this bites our signet/Cashu staging builds, where it's unused network-facing surface plus a recurring advisory-triage tax on code we never call. Filing it as data rather than a request — entirely your call whether the split is worth making.