Bankify
Bankify is a small but important experiment: it translates between Cashu mint operations and Nostr Wallet Connect so a Cashu mint can behave like a Lightning wallet for apps.
A wallet bridge, not a normal wallet brand
Bankify looks like a wallet if you only open the demo page. There is a balance, a Send button, a Receive button and a button that creates an NWC connection. That surface is intentionally plain. The project is better understood as a translator that sits between two worlds: Cashu mints on one side and Nostr Wallet Connect clients on the other.
The wallet behavior is the important part. Bankify handles money state, creates invoices, pays invoices and answers NWC wallet requests, but the funds ultimately depend on the selected Cashu mint and the Bankify runtime that controls the ecash proofs.
A safe mental model is simple: Bankify is an experimental wallet-service bridge. It can make a Cashu mint behave like a Lightning wallet for compatible apps. It is not the same thing as a mature mobile wallet, a self-custodial node, a NIP-60 wallet state implementation or a hosted payment account.
What Bankify actually does
The Bankify README describes the project as a library that connects Cashu mints to NWC so app users can access the Lightning Network. The mechanism is not mysterious. Cashu mints support minting and melting ecash tokens. NWC clients expect wallet commands such as get balance, make invoice, pay invoice and list transactions. Bankify implements the glue between those surfaces.
When the user receives, Bankify requests a Lightning invoice from the selected mint and later turns the paid quote into ecash. When the user sends, Bankify spends ecash through the mint and asks the mint to pay a Lightning invoice. The NWC layer makes those actions available to an external app through a connection string instead of forcing the app to integrate directly with the mint API.
That makes Bankify unusually useful as an explanatory project. It shows that a wallet service does not have to be a Lightning node. It can be a program that controls a custodial ecash balance at a mint and speaks the NWC language to apps. The tradeoff is clear: the money path depends on the mint, the browser or server runtime and the NWC connection secret.
Why Super Testnet built it
Super Testnet framed Bankify as a response to a practical gap. In the announcement and README, the complaint is that too few custodial web wallets supported Nostr Wallet Connect. Alby was moving away from shared custodial wallets, Mutiny Wallet had announced a shutdown path, and Cashu.me was one of the remaining examples. Bankify is the quick experiment that asks what happens if any Cashu mint can become the wallet backend.
That origin matters because Bankify is not trying to win by brand polish. It is trying to prove a shape. If a mint can issue and melt ecash over standardized endpoints, and if NWC gives apps a standardized wallet-command layer, then a relatively small JavaScript program can translate between them. The result is not magic. It is an adapter.
Super Testnet's broader work often lives in this zone: small experiments that make a Bitcoin or Nostr primitive easier to see. Bankify follows that pattern. It is short enough to inspect, direct enough to test and risky enough that the README spends real space warning users not to treat the browser demo like a savings account.
Cashu minting and melting are the money engine
The Cashu side matters because Bankify is not holding a Lightning channel itself. Cashu is a Chaumian ecash protocol for Bitcoin. A wallet pays a mint, receives signed ecash tokens, stores those tokens locally and later spends them. The mint sees issued and redeemed tokens, but the blind-signature model is designed so the mint does not have a normal account database that maps every token to a user identity.
In Cashu language, minting is the receive side. NUT-04 defines the general minting flow: the wallet asks the mint for a quote, receives a payment request, pays it and then asks the mint to issue signed tokens. NUT-23 specializes this for BOLT11 Lightning invoices, which is the flow Bankify uses when it presents a receive action.
Melting is the send side. NUT-05 defines the general melt flow: the wallet asks the mint for a quote to pay an external request, provides ecash proofs and the mint pays the destination if the quote succeeds. NUT-23 again explains the BOLT11 version. Bankify turns those mint and melt primitives into the wallet verbs an NWC client expects.
NWC is the control surface
Nostr Wallet Connect gives Bankify its app-facing control surface. NWC lets an app communicate with a wallet service over Nostr relays using public-key cryptography and encrypted request-response events. The app does not need custody of user funds. It needs a connection string and permissioned wallet methods.
Bankify creates that connection string and runs the wallet-service side. In code, it listens for NWC request events, decrypts the command, performs the Cashu-side action and sends an encrypted response. The README points users to NWC's reference API and says Bankify supports six methods: get_info, get_balance, make_invoice, pay_invoice, lookup_invoice and list_transactions.
Cashu is the money-state backend. NWC is the app-facing control surface. Bankify is the middle process that makes the two systems speak enough of each other's language to be useful.
The demo app is intentionally tiny
The live demo at supertestnet.github.io/bankify is almost austere: a balance, Send, Receive, connection status and a button to create an NWC connection. The page asks the user to choose a Cashu mint from bitcoinmints.com, warns against Fedimint-style strings that begin with fed1, rejects non-HTTPS mint URLs and then creates the NWC connection.
That small interface is not a design failure. It is the point of the demo. Bankify is showing the minimum viable wallet bridge rather than building a whole consumer experience around contacts, recovery, profile metadata, currency display, onboarding, support and store distribution. The most important user artifact is the NWC string.
The demo also reveals implementation choices worth noticing. The README example defaults to wss://nostrue.com as a relay, while the demo code uses wss://nostr.mom when creating a connection. The page persists connection state and ecash proofs in browser localStorage. It offers a destroy connection button, but that does not turn the demo into a hardened wallet.
Browser storage is the sharpest warning
The Bankify README and Stacker News announcement are unusually direct about the browser demo. It stores private keys and ecash notes unencrypted in localStorage. Browser extensions, malicious scripts or anyone with local browser access may be able to read that data. A user who clears browser storage may delete the money state. That is not a small footnote.
This warning changes the recommended use. The web app is suitable for tiny tests, demonstrations and protocol learning. It is not suitable for money a user is not prepared to lose. Bankify demonstrates what is possible; it does not pretend the browser storage model is production-grade custody.
The risk also affects app builders. If a builder tells users to paste a Bankify NWC string into a social client, the client may later request payments while the browser tab is closed. In the browser version, the service is not always online. A wallet service that only exists while a tab is open is a teaching tool first and an operations tool only in very narrow cases.
The Node.js file changes uptime, not the mint trust
Bankify includes bankify_for_nodejs.js, a larger file that integrates the Nostr helper code directly and can run on a server or in a Node.js application. The README suggests this path for developers who want to run Bankify outside a webpage or who need the NWC service available when a browser is closed.
That matters for use cases like zaps. A Nostr client may send NWC commands at the moment a user interacts with a post, not when the Bankify tab is conveniently open. A server-side Bankify process can stay online and listen for requests. That makes the system more operationally plausible than the demo tab.
It does not remove the Cashu trust assumptions. The selected mint still holds the backing funds. The server still stores wallet state. The NWC connection secret still needs protection. The code still carries the README warning that mint responses are not validated in the way the author would like. Node.js changes availability; it does not transform Bankify into a self-custodial Lightning node.
The supported NWC surface is deliberately narrow
Bankify does not implement every NWC method. The README says it supports get_info, get_balance, make_invoice, pay_invoice, lookup_invoice and list_transactions. That set is enough for many wallet integrations because it covers basic discovery, balance display, receiving, paying and transaction history. It does not cover every newer or richer wallet-service command.
The code reflects that limited scope. It listens for NWC request events, checks the method and builds responses for the supported commands. For make_invoice it checks amount formatting, creates mint-side receive state and returns invoice data. For pay_invoice it handles a BOLT11 invoice, records transaction state and returns a preimage after success. For list_transactions it builds a history from local state.
This narrowness is not necessarily bad. A bridge can begin with the methods it can implement honestly. Still, not every app that supports NWC will work perfectly with Bankify. Apps that need keysend, multipay, advanced notifications, hold invoices or long-running reliability guarantees may need another wallet service.
Relays and connection strings are part of the wallet
NWC uses Nostr relays as the message transport, and Bankify makes that visible. The connection string carries the wallet service public key, relay URL and secret. The app sends encrypted requests to the wallet service through the relay, and the wallet service sends encrypted responses back. The relay is not holding the money, but it is still part of the payment workflow.
That means relay choice matters. If the relay is down, slow, blocked or filtered in an unexpected way, the NWC interaction can fail even while the Cashu mint itself is working. Bankify defaults and demo choices give a working starting point, not a universal uptime promise. A serious test should try more than one relay and watch failure behavior.
Connection-string hygiene matters too. An NWC secret is not a decoration. If it leaks, another party may be able to issue commands within the permissions that the wallet service recognizes. Safer use means small permissions, clear labels, limited balances and revocation paths.
Cashu privacy is real but not free
Cashu's appeal is not only small payments. It is the privacy model of blinded ecash. A mint should not learn the full linkage between issuance and redemption in the same way an account-based custodian does. That makes Cashu interesting for Nostr, where public identity and public social graphs can otherwise make payment behavior feel too exposed.
Bankify inherits some of that promise and some of its limits. The ecash tokens live with the user-side software, but the mint still has power. The README states the custodial risk bluntly: a mint can steal, disappear, be hacked or be shut down. The user has a bearer-token-like object, but the backing value depends on the mint honoring redemption.
Bankify adds another privacy caveat. The README says the software does not validate mint responses and that a mint could track a user by giving an invalid proof and watching when it is spent. That is a specific technical warning, not a generic privacy sermon. Bankify is useful for understanding tradeoffs, not for blindly recommending a privacy solution.
How Bankify relates to NIP-60
NIP-60 defines a Cashu wallet state pattern for Nostr. It uses replaceable and encrypted events to let wallet information, token proofs and optional spending history live across relays. That is a different design goal from Bankify. NIP-60 asks how a Cashu wallet can store and synchronize its state through Nostr. Bankify asks how a Cashu mint can be exposed to NWC clients as a wallet service.
That distinction matters in real use. Bankify does not become a NIP-60 wallet merely because Cashu and Nostr are both involved. Its public README and code center on NWC commands, mint and melt flows, connection strings and the demo web wallet. NIP-60 is useful context because it shows a more Nostr-native Cashu wallet direction.
A future product could combine these ideas: Cashu token state stored or synchronized through Nostr, NWC used for app permissions, and stronger validation and encryption around local wallet data. Bankify is not that finished stack. It is a practical bridge that helps developers see where the pieces touch.
Where Bankify is useful
Bankify is useful for builders who want to understand NWC without running a full Lightning node. A developer can choose a Cashu mint, create an NWC string, test get_info, make_invoice, pay_invoice and list_transactions, and learn where the wallet-service boundary sits. That is valuable even if the final product later uses Alby Hub, LNbits, CLN, LND, Phoenixd or another service.
It is also useful for experiments around low-friction app payments. A small prototype can show how an app requests payment powers from a wallet, how invoices appear, how a relay participates and how failures look. The small size of Bankify makes those moving pieces easier to inspect than in a full wallet stack.
A third use is ecosystem pressure. Bankify demonstrates that Cashu mints can be made app-facing through NWC. That may encourage proper wallet implementations, better Cashu-NWC bridges, more careful mint selection and stronger UI around budgets, storage and validation. A good experiment does not have to be the final answer to change what builders consider possible.
Where Bankify should not be used
The browser demo should not be used as a serious daily wallet. The project says that itself. Unencrypted localStorage, tab-dependent uptime, mint custody, browser-extension exposure and non-validation of mint responses are enough to make meaningful balances inappropriate. If the user wants a durable wallet, this is the wrong place to park funds.
Bankify should also not be used as the hidden wallet behind an app for unsuspecting users. If an app integrates it, the app should explain the mint trust model and storage model clearly. Otherwise the app is smuggling a custodial ecash dependency into a Nostr payment flow that users may mistake for self-custody.
Finally, Bankify should not be described as a complete replacement for mature NWC wallet services. Alby Hub, Lightning node plugins, hosted NWC services and serious mobile wallets solve different parts of the problem. Bankify is excellent for learning and prototypes. It is not a general answer to wallet reliability, support, recovery, compliance, liquidity and user education.
How to test Bankify without fooling yourself
Start with an amount you are willing to lose. Open the demo, choose a Cashu mint with an HTTPS URL, create the NWC connection and copy the string into an NWC tester or a low-risk compatible app. Check get_info and get_balance before trying payment actions. If the connection fails, inspect the relay and browser tab before blaming the mint.
Then test receiving and paying with tiny amounts. Create an invoice, pay it from another wallet, watch whether Bankify updates the balance, and then pay a small BOLT11 invoice out. Record what happens if the tab closes, if browser storage is cleared and if the selected relay is changed. Those failure tests are more instructive than one happy-path payment.
If you test the Node.js file, treat the server like wallet infrastructure. Protect the environment, keep balances tiny, read the code, log failures, understand where state is stored and be ready for mint-specific behavior. Bankify is small enough that a builder can inspect the path from NWC command to Cashu call. That inspection is part of responsible use.
What to check before connecting it to an app
First check the mint. Look at who runs it, how long it has been online, which NUTs it supports, whether it has working Lightning liquidity, how other users describe reliability and what happens if the mint disappears. Bankify can translate wallet actions, but it cannot make a weak mint safe.
Then check the runtime. In the browser demo, keys and ecash notes live in localStorage and the NWC service depends on the tab being available. In Node.js, the service can stay online, but the server becomes wallet infrastructure. The machine, logs, backups, environment and access control all matter.
Finally test failure before adding real value. Use tiny balances, disconnect and reconnect the NWC string, close the tab, change relays, try a mint outage, watch invoice failures and confirm how revocation works. A bridge that feels fine on the happy path can behave very differently once the relay, mint or local storage layer misbehaves.
Sources worth opening
Start with the Bankify repository and live demo, then read the NWC specification, Cashu NUTs, NIP-47, NIP-60 and the public announcement threads that explain why Super Testnet built it as an experiment rather than a finished wallet.
- Bankify GitHub repository
- Bankify live demo
- Bankify README raw file
- Bankify browser library source
- Bankify Node.js source
- Bankify demo page source
- Bankify Nostr helper source
- Bankify GitHub repository API metadata
- Bankify GitHub contents API
- Bankify GitHub commits API
- Super Testnet project site
- Stacker News Bankify announcement
- No Bullshit Bitcoin Bankify release note
- getAlby awesome-nwc list
- Nostr Wallet Connect official site
- NWC documentation introduction
- NWC reference API overview
- NIP-47 Nostr Wallet Connect
- Cashu official site
- Cashu NUT specifications
- NUT-04 Minting tokens
- NUT-05 Melting tokens
- NUT-08 Overpaid Lightning fees
- NUT-23 BOLT11
- NIP-60 Cashu wallets
- OpenSats Cashu project page
- Bitcoin Mints directory
- Super Testnet NWC tester
- supertestnet/nwcjs
- supertestnet/blind-sig-js
- Alby shared-wallet phaseout FAQ
- Alby AMA on Stacker News
- Mutiny Wallet shutdown post





