Skip to content

cashu feature implies cdk/npubcash, pulling the nostr stack into builds that never use it #104

Description

@hash-money

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions