Join Nostr
2025-11-06 08:24:37 UTC

Five on Nostr: NUT13 seeds and NUT14 HTLCs make #Cashu #ecash safe. Nostr NIP60-61 make ecash ...

NUT13 seeds and NUT14 HTLCs make #Cashu #ecash safe. Nostr NIP60-61 make ecash ubiquitous and allow zaps to build verifiable Reputation.

They both will soon be available in [SatShoot](https://satshoot.com) and any Nostr web app using NDK:

Introduction

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 17375 stores 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 existing 17375 schema: 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 bip39seed field contains the 32-byte seed in hexadecimal format. Upon initialization, the counters map 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 17375 for 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 17375 and the new kind 17376 to 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.