Zapplepay
Zapplepay is not a full wallet, not a social client and not just an old Damus workaround. It is a small service that watches Nostr reactions and asks a connected Lightning wallet to pay.
The joke is a payment rail
Zapplepay began with a joke sharp enough to become infrastructure. In June 2023 Apple pushed Damus, the iOS Nostr client, toward removing note-level Bitcoin zaps because Apple treated those payments as a way to pay for digital content outside its in-app purchase system. Damus kept profile-level tipping, but the simple act of zapping a specific post was pulled back on iOS. Two weeks later Zapple Pay appeared with a very Nostr answer: if the app store blocks the explicit zap button, let the user publish an ordinary reaction event and let a separate service do the Lightning payment outside the client.
That is why the old tagline, "zap from any client", is more precise than it first sounds. Zapplepay does not need Damus to own the payment flow. It does not need Primal, Nostur, Amethyst or another client to ship a special button. It needs the client to publish a normal Nostr reaction by the user, and it needs the user to have given Zapplepay a wallet connection that is allowed to pay invoices. Once those two facts exist, the client becomes almost incidental. A reaction is enough of a signal.
The official site still explains the mechanism in plain product language: enter your npub, choose the emoji that should trigger payment, set the amount in sats and connect a wallet through NWC or the newer Nostr Wallet Auth flow. The front page defaults toward the same social gestures that made the service famous: Damus users were trained around a hang-loose reaction, Primal users around a heart reaction, and the app lets you choose from a small set of common emojis or enter your own custom trigger.
The funny part matters because it explains the product taste. Zapplepay is not trying to feel like a bank. It is a web page with a yellow apple logo, a big AutoZaps button and a form. Under that light surface sits a server that watches relays, finds reactions from configured pubkeys, maps the reaction content to the configured trigger and then pushes a payment request through the user's wallet permission. That little bridge is why the project belongs on the wallet shelf instead of only the app shelf.
There is also an important cultural lesson here. Zapplepay shows how Nostr turns weak-looking public data into usable coordination. A reaction event is not just a like; it is signed by the user's key, relayed independently and understandable to any software that speaks the protocol. If another service wants to interpret that event as a command, it can. This is powerful, but it also means readers should think in terms of capabilities, not vibes. The protocol does not care whether the reaction was meant as applause, a joke, a payment instruction or all three. The service that listens to it decides what happens next.
What you actually configure
The user-facing configuration is deliberately tiny. The current homepage asks for "your npub" and explains that Zapple Pay will subscribe to reaction events on that npub. It asks for a trigger emoji. It asks for a zap amount, described as the number of sats to zap per reaction. Then it asks the user to connect a wallet. There is an automatic NWA connection component, plus a manual NWC textarea for pasting a traditional `nostr+walletconnect://` string.
That form tells you almost everything about the product. Zapplepay is not a custody account. It does not ask you to deposit sats. It does not ask for an nsec. It does not sign your social events. It asks for the public identity it should watch and for a wallet permission that can pay. The payment authority is delegated by the wallet connection, not by the Nostr account itself.
The frontend source confirms the payload. The `set-user` request sends a hex pubkey converted from the user's npub, the sat amount, the selected emoji, optional donation records and either an NWC string or an `auth_id` returned by the NWA pairing flow. It also contains two hard-coded donation pubkeys for Damus and OpenSats if the user chooses to add those extra recipients. The public bundle currently points at `api.zapplepay.com`, and the live API accepts `POST /set-user` while rejecting a plain GET on that route with a 405 response, which is a good quick sign that the public form and backend route match.
The backend README says the same thing in API terms. `POST /set-user` creates a zap config with `npub`, `amount_sats`, optional `emoji`, optional donations and exactly one wallet credential path: either `nwc` or `auth_id`, not both. That exclusivity matters. A manually pasted NWC string gives the service the wallet connection directly. An NWA auth id points to a wallet-auth record the server created and later linked when the wallet confirmed the connection.
Once saved, the backend can return the user's current configs through `GET /get-user/:npub` or a single emoji config through `GET /get-user/:npub/:emoji`. It also exposes delete routes for a whole user, one emoji config or a subscription. Those delete routes are less visible in the minimal frontend, but they are present in the backend code. The gap between API capability and visible product surface is part of the current state of the app: the machinery is richer than the form.
On June 7, 2026, the live `/count` endpoint returned 50 users, 75 zap configs, 0 subscription configs, 4,261 confirmed zap events, 771 unconfirmed zap events and 126,980 sats in recorded zap total. That is not a giant consumer network. It is also not a dead demo. It is a small, real service with enough usage to justify care and enough narrowness to justify caution.
The stack under the sticker
Zapplepay has two public codebases. The backend lives under `benthecarman/zapple-pay-backend`; the frontend lives under `futurepaul/zapple-pay-frontend`. The backend repository was created on July 3, 2023, is written in Rust, had 16 stars, 3 forks and 4 open issues when checked, and had last been pushed on March 28, 2025 while GitHub showed recent repository activity in March 2026. The frontend repository was created on July 4, 2023, is TypeScript, MIT-licensed, had 3 stars, 4 forks and 1 open issue, and had last been pushed on January 15, 2024.
The backend is not mysterious. `Cargo.toml` names the binary `zapple-pay` and pulls in Axum, Diesel with Postgres, Diesel migrations, `nostr` and `nostr-sdk`, `lnurl-rs`, `lightning-invoice`, Bitcoin libraries, Tokio and CORS middleware. The server creates a Postgres pool, runs migrations, derives or loads server keys, starts an HTTP router and starts background handlers. That is closer to a small payment daemon than a static website.
The router exposes `/.well-known/nostr.json`, `/wallet-auth`, `/check-wallet-auth`, `/set-user`, `/create-subscription`, delete routes, `/count`, `/relays`, `/migrate-emojis`, `get-user` routes and subscription lookup routes. The public NIP-05 document on both `www.zapplepay.com` and `api.zapplepay.com` maps `_` and `zapplepay` to the hex pubkey `71bfa9cbf84110de617e959021b08c69524fcaa1033ffd062abd0ae2657ba24c`, which converts to the Zapple Pay npub shown in the AutoZap source.
The listener is the core. It builds a Nostr SDK client, connects to configured relays, adds relay URLs learned from stored NWC strings, always adds the default auth relay `wss://relay.damus.io`, and subscribes to filters for the authors and wallet keys it cares about. The list of event kinds includes reactions, text notes, live event messages, wallet connect responses and parameterized replaceable kind 33194 events for wallet auth responses. Incoming events are verified before handling.
The reaction path is the product's original heart. A configured user publishes a reaction or compatible text event. The listener checks the author, checks tags, finds the event being reacted to, maps the emoji, looks up the user's matching zap config, finds the target's LNURL or lightning address from Nostr profile metadata, asks the wallet to pay and stores a zap event record. The exact details branch through helpers, caches and database models, but the shape is direct: public Nostr event in, NWC payment request out.
The relay footprint also says something about real users. The live `/relays` endpoint returned `wss://relay.getalby.com/v1` for most stored NWC connections, plus `wss://relay.damus.io/`, `wss://relay.minibits.cash/` and one Primal NWC relay. That distribution fits the product's history: early users came from Damus/Nostr zap culture, but practical wallet connectivity now often runs through Alby and other NWC providers.
Wallet auth and the budget line
Nostr Wallet Connect, standardized as NIP-47, is the baseline: an app receives a `nostr+walletconnect://` URI containing a wallet service pubkey, a relay and a dedicated secret. The app sends encrypted payment requests over a relay. The wallet processes the request and returns an encrypted response. For a service like Zapplepay, that means the server does not need the user's wallet seed, but it can request payments within whatever permission the wallet grants.
The newer path in Zapplepay is Nostr Wallet Auth, the `nostr+walletauth://` flow that the app labels NWA. The frontend generates an NWA URI from `/wallet-auth`, displays it as a QR code and polls `/check-wallet-auth?id=...` every three seconds. If the wallet completes the pairing, the frontend receives the auth id and submits the Zapplepay form. The UI specifically names Mutiny as an NWA-compatible wallet and includes an "Open in Mutiny Wallet" button that appends the NWA URI to Mutiny's settings connection URL.
The live `/wallet-auth` endpoint shows the flow plainly. A request without budget parameters returns JSON with an `id` and a `nostr+walletauth://...` URI using `relay=wss://relay.damus.io/`, a short secret, `required_commands=pay_invoice` and an identity pubkey. A request with `amount=420` and `time_period=month` adds `budget=420/month`. A request with an explicit identity uses that pubkey in the URI. This is the permission line readers should look for. The app should only be able to pay invoices if the wallet grants `pay_invoice`, and a budgeted connection should limit the damage if the service or configuration is wrong.
The backend stores wallet-auth rows with a derived pubkey, later records the wallet's user pubkey and relay, and uses the auth index to derive the NWC secret it needs for later payment requests. That is a clever design, but it is still a server-side delegation system. You are trusting the Zapplepay backend to store and use the delegated capability correctly, and you are trusting your wallet to enforce the permission and budget you approved.
This is why manual NWC is more sensitive than it looks. Pasting a broad NWC string into a third-party service is a real permission grant. If the string is unlimited or hard to revoke, you have effectively handed the service a remote-control payment button. If the string is scoped to `pay_invoice`, budgeted tightly and revocable inside your wallet, the risk is more bounded. Zapplepay's own UI nudges toward connection flows that can be constrained, but the manual textarea exists and should be used with the smallest permission you can make work.
NIP-57 is the other half of the story. A zap is not just a Lightning payment; it is the social receipt around that payment. The service needs to discover a recipient's zap endpoint from profile data, pay a Lightning invoice and let the Nostr ecosystem observe or display the zap receipt. That public proof is the thing users wanted back when Apple pressed Damus to remove note zaps. It is also the thing that makes zaps legible across clients.
AutoZaps show the larger idea
The AutoZaps button is easy to treat as a side feature, but it exposes Zapplepay's broader thesis. Reactions are one trigger. A subscription schedule is another. In both cases, a Nostr identity and a wallet connection become a small programmable payment rule.
The backend README documents `POST /create-subscription` with `npub`, `to_npub`, `amount_sats`, `time_period` and either NWC or auth id. It accepts periods such as minute, hour, day, week, month and year in the backend model, while the visible frontend focuses on day, week and month. A background subscription handler finds configs that need payment, groups them by relay, asks wallets to pay, records zap events and updates `last_paid` when successful. It also prunes old unpaid subscription records after several missed periods.
The AutoZap frontend route fetches trending zappees from `https://primal-cache.mutinywallet.com/api` using the `explore_global_mostzapped_4h` request, turns profile events into clickable AutoZap pages and lets a sender configure recurring support for a selected recipient. The FAQ is plain: zaps tip friends on Nostr, NWC connects a wallet to a client, and AutoZaps uses NWC to ping a wallet with a zap request at a regular interval. To stop a subscription, the FAQ tells users to delete the NWC item from their wallet.
That last sentence is the whole design philosophy. Zapplepay can create a rule, but the wallet is the ultimate circuit breaker. If the user revokes the connection, the service loses the ability to pay. This is exactly how open payment automation should feel: the app can ask, the wallet can refuse, the user can cut the wire.
The live counts showed zero active subscription configs on June 7, 2026, so AutoZaps appears to be more of an available mechanism than a heavily used live product. That does not make it irrelevant. It makes it a useful proof of where NWC-based apps go next: creator subscriptions, scheduled zaps, lightweight patronage, small venue rewards, event bounties and other rules that do not require every social client to become a payments company.
Team, history and maintenance
Zapplepay is strongly tied to the Mutiny Wallet circle. CoinDesk reported that the service went live on July 6, 2023 and named Ben Carman and Paul Miller as the two Bitcoin developers behind it. Forbes India, The Bitcoin Manual and other follow-on coverage repeated the same history: Carman and Miller were associated with Mutiny Wallet, and Zapplepay was presented as independent from Damus even though it was a direct response to the Damus app-store fight.
NostrApps links the Zapplepay listing's "By" field to the npub for benthecarman. Njump shows that profile as `npub1u8lnhlw5usp3t9vmpz60ejpyt649z33hu82wc2hpv6m5xdqmuxhs46turz`, with website `https://benthecarman.com`, NIP-05, and the short bio "dev at spiral". The backend repository is under `benthecarman`. The frontend repository is under `futurepaul`, matching Paul Miller's public handle. This is enough to treat the app as a public builder project, not an anonymous payment page.
The Mutiny background explains both the strength and the fragility. Mutiny was announced as a private, self-custodial Bitcoin wallet with Tony Giorgio, Ben Carman and Paul Miller as founders. Its own launch post described a browser-based Lightning node and a product direction built around privacy, web distribution and app-store resistance. That is exactly the environment where Zapplepay makes sense: a team already thinking about wallets that cannot be blocked by native app stores, and about Nostr Wallet Connect as a way to bring Lightning payments into apps without handing every app your wallet.
Mutiny later announced that its hosted wallet would shut down at the end of 2024 while remaining self-hostable. That does not automatically kill Zapplepay, and the current Zapplepay API still responds. But it does change the risk reading. One of the wallets named in the Zapplepay UI is no longer the same mainstream hosted product it was in 2023. A live service that depends on wallet integrations, relays and background workers needs maintenance, monitoring and an exit path for users.
The repositories show mixed maintenance signals. The backend has real code, migrations, tests and live API alignment; it was pushed in 2025 and still had repository activity in 2026. The frontend appears older, with its last push in early 2024, and the `/autozap` server route returned 504 during this check even though the bundled client-side route and API code still exist. That is not a reason to erase the app. It is a reason to write about it honestly: Zapplepay is an important, working idea with a small live footprint, a public backend, a dated frontend and some signs of operational rough edges.
The risk is the permission
The safest way to understand Zapplepay is to separate the three identities involved. Your Nostr account signs the reaction. Your wallet authorizes payment. Zapplepay watches for the reaction and asks the wallet to pay. Those are not the same key, and they should not be mentally collapsed.
The Nostr side is public by design. If you react to a note, that reaction can be observed by relays, clients and services. If Zapplepay treats one emoji as a payment instruction, anyone watching can infer that the reaction may trigger money. If the zap receipt is public, the payment itself becomes part of the social object. This is the point of zaps, but it is not private.
The wallet side is permissioned by design. A well-scoped NWC or NWA connection should grant only the command Zapplepay needs, usually `pay_invoice`, with a tight budget and an easy revocation path. A badly scoped connection can be dangerous. The service's backend can make payment requests whenever it sees matching triggers, and a bug, compromised server, leaked connection string or malicious configuration can turn a cute emoji into a recurring expense.
The service side is custodial in a different sense. Zapplepay does not custody your sats, but it does hold automation state: your watched pubkey, chosen emoji, sat amount, donation targets, subscription configs and either an NWC string or an auth-linked capability. That data lives in its database. The backend uses Postgres migrations and models for users, zap configs, subscription configs, wallet auth and zap events. Deleting or rotating a wallet connection is therefore as important as deleting an account record.
For a casual user, the right testing pattern is simple. Use a fresh wallet connection, not your broad everyday wallet permission. Grant only `pay_invoice`. Set a tiny budget. Use a tiny sat amount. Trigger one zap. Confirm the wallet, the recipient, the note and the receipt. Then revoke the connection and verify that future reactions no longer pay. If that sounds too fussy for a playful app, remember what the app does: it turns a public gesture into money movement.
For builders, Zapplepay is still one of the clearest demonstrations of what Nostr Wallet Connect can do. It shows that app-store rules can be routed around by moving payment authority out of the native client. It shows that a signed public event can act as an automation trigger. It shows that Nostr apps can be small, weird and composable instead of monolithic. It also shows the bill for that power: the user must understand permissions, the wallet must enforce them, the service must be reliable, and the ecosystem must make revocation obvious.
That is why Zapplepay deserves a serious article even if the interface looks like a joke. It is a tiny application with a large lesson. Nostr is not only about replacing social feeds. It is about making messages, identities and value flows interoperable enough that a reaction in one client can become a Lightning payment through another service and a wallet the client never controlled. That is the good version. The bad version is the same sentence with sloppy permissions. The difference is operational discipline.
Sources worth opening
These are the primary and secondary sources used for this profile: live product pages, API endpoints, public code, Nostr identity pages, NIP references, NWC documentation and contemporaneous coverage of the Damus/Apple context.
- Zapple Pay official website
- Zapple Pay live frontend bundle
- Zapple Pay live route bundle
- Zapple Pay shared live bundle with NWA and Nostr helpers
- Zapple Pay logo asset
- Zapple Pay website NIP-05 document
- Zapple Pay API NIP-05 document
- Zapple Pay live count endpoint
- Zapple Pay live relay endpoint
- Zapple Pay live wallet-auth endpoint
- Zapple Pay live wallet-auth endpoint with budget example
- Zapplepay on NostrApps
- benthecarman Nostr profile on Njump
- benthecarman/zapple-pay-backend repository
- Zapple Pay backend README
- Zapple Pay backend Cargo.toml
- Zapple Pay backend main.rs
- Zapple Pay backend routes.rs
- Zapple Pay backend listener.rs
- Zapple Pay backend subscription handler
- Zapple Pay backend wallet-auth URI helper
- Zapple Pay backend wallet_auth model
- futurepaul/zapple-pay-frontend repository
- Zapple Pay frontend package.json
- Zapple Pay frontend home route
- Zapple Pay frontend NWA component
- Zapple Pay AutoZap index route
- Zapple Pay AutoZap profile route
- Zapple Pay frontend walletAuth API helper
- Zapple Pay AutoZap FAQ component
- Zapple Pay frontend NIP-05 source file
- CoinDesk on Zapple Pay and Damus
- Yahoo mirror of CoinDesk Zapple Pay coverage
- Forbes India on Zapple Pay and Apple restrictions
- The Bitcoin Manual explanation of Zapple Pay
- No Bullshit Bitcoin Zapple Pay guide pointer
- TFTC Zapple Pay setup guide
- Yahoo/CoinDesk on Mutiny and app-store-resistant wallets
- Mutiny introduction and founder context
- Mutiny shutdown announcement
- Nostr Wallet Connect public site
- NWC traditional connection flow docs
- Alby developer guide for NWC and NWA
- NIP-47: Nostr Wallet Connect
- NIP-57: Lightning Zaps
- Apple App Review Guidelines
- CoinDesk on the Damus zap dispute with Apple
- Damus App Store listing
- Mutiny app URL used by Zapple Pay NWA flow
- Alby NWC connection service referenced by Zapple Pay
- Damus relay reference for wss://relay.damus.io





