They both will soon be available in [SatShoot](https://satshoot.com) and any Nostr web app using NDK:
quoting
naddr1qq…nyktIntroduction
The e-Cash Cashu protocol has gained remarkable momentum in recent years and officially entered the Nostr ecosystem with the introduction of NIP-60. This specification provides the foundation for Cashu wallets that store their state on the Nostr network and is currently implemented (or under development) in several ecosystem libraries, including nostr-dev-kit (NDK), rust-nostr, and Dart NDK. Several applications have built Cashu wallets using these libraries as well and some of them are quite usable, at least for first experimentation with this novel way of Bitcoin wallets.
The prospect is compelling: a Nostr identity is sufficient to create a native wallet—it's just an event away. Once created, the wallet, balance, and transaction history are linked to your Nostr identity, enabling users to theoretically switch between applications while maintaining wallet continuity. However, this vision remains largely unrealized due to limited ecosystem adoption and incomplete feature support, particularly for Nostr's core zap (nutzap) functionality.
Very likely one reason for the restricted usage of Nostr Cashu wallets is the inherent lack of strong consistency in Nostr as a decentralized network, it does not feel like a safe place to store your Bitcoin. But what if you were able to restore your funds any time in case of loss?
NUT-13 (Deterministic Wallets) to the Rescue
NUT-13 defines the deterministic wallet standard within the Cashu protocol specification. It specifies how wallets can deterministically derive proofs from mints. The specification lends the BIP-39 from Bitcoin for that purpose and defines the derivation path scheme for Cashu wallets, similar to BIP-32. The technical details about how this works can be read in the specifications. For our purposes, it is sufficient to understand that through this mechanism, a wallet can restore its balance with mint collaboration—a core assumption in Cashu. If anything goes wrong, 12 seed words are sufficient to recover access to all funds, a feature that could also be beneficial in the Nostr context.
Bringing NUT-13 to Nostr
As mentioned in the above section, the user would need to keep his seed words at a safe place like with any Bitcoin wallet and would be able to restore the funds in case of loss. For everyday Nostr usage, asking users for seed words, or some other data, on every app or device switch would be impractical. This is precisely what NIP-60 is supposed addresses. Moreover, deterministic wallets must maintain state by tracking the counter value for the next derivation path step, enabling generation of new Cashu proofs from mints.
This proposal extends NIP-60 defining how the wallet seed (generated from the seed words) and the counter state for every mint and key set should be stored in a Nostr event. In NIP-60, kind
17375stores both a private key (used to lock tokens for exclusive spending) and the user's selected mints. To maintain backward compatibility and reduce the risk of affecting existing clients, we introduce a new event kind rather than modifying the existing17375schema: We decided not to alter the schema of this event and instead define a new kind (deterministic wallet event):{ "kind": 17376, "content": nip44_encrypt({ "bip39seed": "hexkey", "counters": { "<normalized-mint1-url>|<keyset=keyset-id-1>": "<counter-1>", "<normalized-mint1-url>|<keyset=keyset-id-2>": "<counter-2>", "<normalized-mint2-url>|<keyset=keyset-id-3>": "<counter-3>", } }), "tags": [], ... }As in the kind 17375, the event content is encrypted according to NIP-44. In the encrypted content the relevant information get stored, the
bip39seedfield contains the 32-byte seed in hexadecimal format. Upon initialization, thecountersmap is empty ({}). The map keys are formed by combining a normalized, unique mint URL with its keyset ID.We identify several advantages in this approach. It is good for backward compatibility with clients already using this NIP. It is possible to extend kind
17375for our purposes in a backward-compatible manner, but with it we would introduce risk to affect existing clients depending on how they are implemented. A new kind reflects also better the separation of concerns, updates to 17376 can not affect the wallet information, reducing risks. Note that wallet mints are now distributed across two events, improving resilience and providing this information for potential wallet restore operations.Wallet implementations must fetch both kind
17375and the new kind17376to initialize their state properly. The Cashu NUT-13 specifies how to proceed to obtain deterministic proofs from the corresponding mint and how to implement the restore process. The counter state for every mint and key set ID must be kept up to date by publishing updates of the kind 17376.Prototype Implementation
This proposal is actively being implemented in a fork of nostr-dev-kit/ndk-wallet and is demonstrated in the latest Satshoot release, Satshoot. A short video demonstration is available here.
In this release, new Satshoot users can create their deterministic Cashu wallet on the wallet page, while existing ones keep their existing non-deterministic one. Currently, the wallet restore functionality is not yet implemented, but users can restore wallets using compatible implementations such as cashu.me or minibits. Our initial tests have been successful so far.
Next Steps
We encourage the Nostr developer community to provide feedback on this proposal, helping to refine and consolidate our approach. Only through broad consensus can Nostr maintain its interoperability promise while evolving.
Our action items for the upcoming time include:
- the implementation for wallet restore in the ndk-wallet fork and the integration in an upcoming Satshoot release,
- a pull request for NIP-60 with the new deterministic wallet kind,
- an integration of the new kind in the nostr-dev-kit library, filed as pull request as well.
This text was written with the Pareto Client.
