A web-based Nostr client built into the ExtFW framework. Feature overview, NIP support, and comparison with other clients.
Web Client · Open Architecture · Self-hostedNoxtr is a web-based Nostr client integrated into the ExtFW framework. It runs as a module within a self-hosted website, combining Nostr protocol access with server-side features like user accounts, Lightning address hosting, and NIP-05 identity verification.
It is designed as a single-page application with no external JavaScript frameworks — vanilla JS with a lightweight DOM helper (wquery).
Runs on your own server (Apache/nginx, PHP, MySQL/SQLite). You control your data, your relay list, and your Lightning endpoints.
No React, no Vue, no npm, no build step. Vanilla JavaScript organized in a few per-area files (core, Mostro, on-chain). Crypto via noble-secp256k1 and noble-ciphers, vendored in the repo (no CDN).
NIP-05 verification and LNURL-pay Lightning addresses are auto-configured from your server's user accounts.
Supports NIP-07 browser extensions, nsec private key entry, NIP-46 Nostr Connect (remote signing with QR, e.g. with signer.noxtr.net), and npub read-only mode. If the remote signer is not responding, requests are re-sent automatically for up to 90s with an on-screen notice.
Buy and sell Bitcoin directly with other people, no inter/mediaries: over Lightning via the Mostro protocol, or on-chain with a 2-of-3 Taproot escrow (NostrEscrow). Order book, encrypted chat, disputes with arbitration and notifications, all inside the client.
100% anonymous registration with Nostr: no email, no password, no personal data. In P2P trades, full privacy mode by default (ephemeral keys per trade, no linkage between trades) with optional reputation.
Nostr Implementation Possibilities (NIPs) supported by Noxtr:
| Kind | Description | Usage |
|---|---|---|
| 0 | Profile Metadata | Name, avatar, banner, about, nip05, lud16 |
| 1 | Text Note | Main feed content, hashtags, mentions |
| 3 | Contact List | Follow/unfollow, petnames, relay hints |
| 4 | Encrypted DM (NIP-04) | AES-CBC with IV, decrypted via NIP-07, NIP-46 or privkey |
| 5 | Deletion | Delete own notes and own channel messages (kind 42) |
| 6 | Repost | Repost notes |
| 7 | Reaction | Like/unlike notes |
| 13 | Seal (NIP-17) | Inner gift wrap layer for private DMs |
| 14 | Rumor (NIP-17) / Mostro v2 transport | In DMs: plain message wrapped in the seal. In Mostro: NIP-44 encrypted direct message to the robot, signed with the trade key |
| 40 | Channel Create | NIP-28 public chat channel |
| 41 | Channel Metadata | Channel name, about, picture |
| 42 | Channel Message | Messages in public channels (own messages deletable via kind 5) |
| 1059 | Gift wrap (NIP-59) | Outer encrypted envelope for NIP-17 DMs and Mostro messages. Hides sender and recipient |
| 1063 | File Metadata (NIP-94) | Returned by NIP-96 servers on upload: URL, hash, mime, dimensions |
| 1984 | Report | NIP-56 spam reports |
| 9802 | Highlight (NIP-84) | Highlighted quotes with comment/context, integrated in the feed |
| 9734 | Zap Request | Lightning payment metadata |
| 9735 | Zap Receipt | Payment confirmation from server |
| 23194 | NWC request (NIP-47) | Encrypted (NIP-04) request from client to NWC wallet: pay_invoice, get_balance, etc. |
| 23195 | NWC response (NIP-47) | Encrypted response from wallet with result or error |
| 24133 | Nostr Connect | NIP-46 remote signing |
| 27235 | HTTP Auth (NIP-98) | Authentication event for NIP-96 uploads and web login |
| 30023 | Article (NIP-23) | Long-form content: mixed into feed with “Read” badge, full Markdown view, article composer |
| 38383 | P2P Order (NIP-69) | Bitcoin buy/sell orders from Mostro robots. P2P ₿ tab with order listing, plain-language explanation per order, and guided buy flow |
| 38385 | Mostro instance status | Heartbeat with daemon version, transport protocol_version, limits, fee and bond policy. Feeds the v1/v2 label and each instance's info sheet |
| 38386 | Mostro public dispute | Public dispute state (initiated / in-progress) |
| 39383-39389 | NostrEscrow (on-chain) | Offers, trade state, disputes, arbitration and funding for on-chain P2P trading with Taproot escrow |
Global, Following, Followers, Topics (hashtag subscriptions), and Hot (engagement-ranked trending).
Encrypted DMs via NIP-04 (AES-CBC) and NIP-17 with gift wrap (NIP-59 + NIP-44 XChaCha20-Poly1305). Both share the same tab, visually distinguished by 🔒 for NIP-17. Conversation threads, local DB cache, decryption via NIP-07 extension, NIP-46 or nsec.
Connect to Nostr Wallet Connect compatible wallets (Alby, Mutiny, Phoenix, Coinos, etc.). Configure your nostrwalletconnect:// URI once and pay zaps and Mostro hold invoices automatically from your own wallet, bypassing BTCPay. Dedicated WebSocket to NWC relay, NIP-04 encryption, 30s timeout.
Images attached to notes are uploaded to external NIP-96 servers (nostr.build by default, configurable in the Relays tab). Auto-discovery of capabilities via /.well-known/nostr/nip96.json. Auth via NIP-98 (kind 27235) signed with the user's key. Multi-server support with fallback chain.
Create, join, and chat in public channels. Channel metadata, pinning, invite links, and creator-only settings. Delete own messages (NIP-09).
Long-form content (kind 30023) mixed into the feed with a “Read” badge and deduplication. Full Markdown view. Composer with title, summary, image, and tag fields.
Full thread view with root/reply markers, reply counts, chronological ordering, and permalinks.
NIP-57 zaps with internal balance transfers between registered users and external BTCPay invoices via LNURL-pay.
Self-hosted Lightning infrastructure via BTCPay Server. LNURL-pay endpoint serves invoices, creates BOLT11 payment requests, and processes zap receipts (kind 9735) with server-side Schnorr signatures. Received sats accumulate in user balance for internal transfers or withdrawal.
NIP-50 text search with multi-relay fallback. Profile search via @username. Entity detection for npub/note/nevent.
Subscribe to hashtags (#bitcoin, #nostr, etc.) and filter your feed. Suggested topics, bulk toggle, hot filter.
Bookmark notes locally. Mute users with optional NIP-56 spam reporting. Unmute management in settings.
Embedded images (lazy-loaded), video players, YouTube/Vimeo embeds. Dead domain detection with 24h TTL auto-retry.
Edit name, bio, avatar, banner. NIP-05 and Lightning address auto-configured from server account.
Add/remove/toggle relays. Live connection status. Exponential backoff reconnection. Subscription rebalancing.
Dedicated tab for buying Bitcoin without inter/mediaries using the Mostro protocol over Nostr. Displays sell orders (kind 38383, NIP-69) with a plain-language explanation for each. Guided flow: take order → encrypted DM to robot → submit Lightning receive invoice → get sats. No Lightning node required; works with Phoenix, Breez, Zeus.
Parse and render AR mesh network profile broadcasts (ar_profile, ar_collaboration) as visual cards with avatar, location, and social actions.
An impartial comparison of Noxtr against established Nostr clients. Each client has different strengths — this table aims to be factual, not promotional.
| Noxtr | Damus | Amethyst | Primal | Snort | Iris | Coracle | Nostur | |
|---|---|---|---|---|---|---|---|---|
| Platform | Web | iOS | Android | Web/iOS/Android | Web | Web/Multi | Web (PWA) | iOS/macOS |
| Open source | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Self-hosted | ✓ | — | — | — | ✓ | ✓ | ✓ | — |
| No build step required | ✓ | n/a | n/a | — | — | — | — | n/a |
| Documented NIPs | 18 | ~15 | 60+ | ~20 | 42 | ~15 | ~15 | ~15 |
| NIP | Noxtr | Damus | Amethyst | Primal | Snort | Iris | Coracle | Nostur | |
|---|---|---|---|---|---|---|---|---|---|
| 01 | Basic protocol | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 02 | Contact list | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 04 | Encrypted DMs (legacy) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | read | ✓ |
| 05 | DNS identity | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 07 | Browser signer | ✓ | n/a | n/a | ✓ | ✓ | ✓ | ✓ | n/a |
| 09 | Event deletion | ✓ | ~ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 10 | Reply threading | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 17 | Private DMs (gift wrap) | ✓ | ~ | ✓ | — | ✓ | ✓ | ✓ | ✓ |
| 19 | Bech32 entities | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 23 | Long-form content (articles) | ✓ | — | ✓ | ✓ | ✓ | — | — | — |
| 25 | Reactions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 28 | Public channels | ✓ | — | ✓ | — | ✓ | — | — | — |
| 44 | Versioned encryption | ✓ | ~ | ✓ | — | ✓ | ✓ | ✓ | ✓ |
| 46 | Nostr Connect | ✓ | — | ~ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 47 | Nostr Wallet Connect | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 50 | Search | ✓ | ~ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 57 | Lightning Zaps | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 65 | Relay list metadata | ✓ | ✓ | ~ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 94 | File metadata | ✓ | — | ✓ | — | ~ | — | ~ | — |
| 96 | HTTP file storage | ✓ | — | ✓ | — | ✓ | — | ✓ | — |
| Not yet implemented in Noxtr | |||||||||
| 29 | Relay-based groups | — | — | ~ | — | — | — | — | — |
| 35 | Torrents | — | — | — | — | — | — | — | — |
| 51 | Lists (mute, pin, bookmarks, sets) | — | ~ | ✓ | ~ | ✓ | ~ | ✓ | ✓ |
| 72 | Moderated communities | — | — | ✓ | — | — | — | ✓ | — |
| 78 | Custom app data | — | — | ~ | — | ~ | — | ~ | — |
| Feature | Noxtr | Damus | Amethyst | Primal | Snort | Iris | Coracle | Nostur |
|---|---|---|---|---|---|---|---|---|
| Modern DMs (NIP-17/44) | ✓ | ~ | ✓ | — | ✓ | ✓ | ✓ | ✓ |
| Built-in wallet | balance | Coinos | — | ✓ | — | Cashu | — | — |
| Profile search (@user) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Public channels (NIP-28) | ✓ | — | ✓ | — | ✓ | — | — | — |
| Trending / Hot feed | ✓ | — | ✓ | ✓ | ✓ | — | — | — |
| Topic/hashtag subscriptions | ✓ | — | ✓ | ~ | ~ | — | — | ~ |
| NIP-05 hosting | ✓ | — | — | premium | paid | — | — | — |
| Lightning address hosting | ✓ | — | — | ✓ | paid | — | — | — |
| Multiple accounts | logout/login | — | ✓ | — | ✓ | — | ✓ | ✓ |
| Long-form content (NIP-23) | ✓ | — | ✓ | ✓ | ✓ | — | — | — |
| Communities (NIP-72) | — | — | ✓ | — | — | — | ✓ | — |
| File upload (NIP-96) | ✓ | — | ✓ | — | ✓ | — | ✓ | — |
| File metadata (NIP-94) | ✓ | — | ✓ | — | ~ | — | ~ | — |
| Nostr Wallet Connect (NIP-47) | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Synced lists (NIP-51) | — | ~ | ✓ | ~ | ✓ | ~ | ✓ | ✓ |
| Relay-based groups (NIP-29) | — | — | ~ | — | — | — | — | — |
| App data on relay (NIP-78) | — | — | ~ | — | ~ | — | ~ | — |
| Torrents (NIP-35) | — | — | — | — | — | — | — | — |
| BTCPay Server integration | ✓ | — | — | — | — | — | — | — |
| Buy Bitcoin P2P (Mostro) | unique | — | — | — | — | — | — | — |
| AR profile rendering | unique | — | — | — | — | — | — | — |
Areas where Noxtr is behind other clients:
Noxtr includes native support for Mostro, a peer-to-peer Bitcoin exchange protocol built on top of Nostr. You can buy or sell Bitcoin directly with other people, with no inter/mediaries or custodians, paying by bank transfer, cash, or any other agreed method.
The P2P ₿ tab in the navigation bar gives you access to the live order book with all available offers.
You can add and enable several Mostro instances (robots) in the chips bar of the P2P tab. The order book aggregates offers from all active instances; when creating an offer you choose which instance it is published to.
protocol_version tag of its status event, kind 38385).No prior Bitcoin experience needed. You only need a Lightning wallet on your phone (Phoenix, Breez, Zeus, Wallet of Satoshi…).
user@wallet.com) or a bolt11 invoice generated from your wallet — that is where you will receive the sats.If the seller’s wallet or the robot’s node cannot route the payment to your address, the trade card will show a field to enter an alternative Lightning address. Your sats are always safe with the robot.
If you already use the Mostro Mobile app, you can import your identity into Noxtr without creating a new account:
m/44'/1237'/38383'/0/0).This imports your identity (same key and therefore the same accumulated reputation). Trades started in Mostro Mobile are not recovered automatically: each interface manages its own trade sessions.
After completing a trade you can rate the counterpart from 1 to 5 stars. Ratings received appear in your reputation card (⭐ average · number of trades). Mostro robots publish each user’s accumulated reputation alongside their order book entries.
By default Noxtr operates in full privacy mode (ephemeral keys per trade, no linkage between trades). To accumulate reputation, enable the ⭐ Reputation toggle: your trades become tied to your Nostr identity. Requires local nsec login (not possible with an extension or remote signer, because the identity proof requires signing outside the standard event format).
If something goes wrong in a trade in the active or fiat-sent state (the counterpart does not respond, fails to send the money, denies receiving a confirmed payment…), you can open a dispute. Disputes are resolved by a human administrator of the Mostro robot.
active or fiat-sent.dispute action to the robot.disputed with a dispute ID visible in the card.admin-took-dispute action and a new direct chat panel with the admin appears below the trade card.The Cancel dispute button (visible if you opened it and no admin is assigned yet) only hides it from your local list: the Mostro protocol has no way to withdraw a dispute, so on the robot it stays open until an admin resolves it.
If the counterpart asks for a cooperative cancellation on an active trade and you disagree, you can press Dispute instead of accepting the cancellation.
Your disputes are listed at /noxtr/disputes: dispute ID, public status (initiated / in-progress), initiator, assigned admin, and last update.
To send messages to the robot, wss://relay.mostro.network must be active in the user’s relay list. The order book works with any general relay, but communication with the robot requires that specific relay. Noxtr adds it automatically as a default relay for new installations.
Noxtr does not require the server to run a Lightning node for the Mostro flow. The Lightning wallet belongs to the end user (Phoenix, Breez, Zeus, etc.). BTCPay Server is only needed for the zap system and profile Lightning addresses, not for Mostro.
Active trades are stored in NSTR_TRADES and Mostro events in NSTR_EVENTS. Both tables are created automatically. Reputation data is calculated from NSTR_EVENTS with no extra table.
Besides the Lightning flow with Mostro, Noxtr supports on-chain P2P trades via NostrEscrow: funds are deposited into a 2-of-3 Taproot escrow address (buyer, seller and arbitrator), with no custodial robot.
39383-39389 are provisional until an eventual submission to the official NIPs repository.
The Monitor is a PHP process that runs in the background on the server and watches active Mostro trades even when no user has the web app open. It listens to Nostr relays continuously and acts whenever it receives relevant events.
If the site administrator has the Monitor running, you will receive automatic alerts whenever something happens in your trades:
| Event | Notification received |
|---|---|
| Someone takes your published order | Email: “Your order #XXXXXXXX has been taken” |
| The robot asks you to pay the hold invoice (selling BTC) | Email: “You must pay the hold invoice” |
| The buyer confirms they sent the fiat (selling BTC) | Email: “The buyer has sent the payment” |
| The trade completes | Email: “Trade completed” |
| The counterpart opens a dispute | Email + Telegram: “⚠️ The counterpart has opened a dispute” |
| You opened a dispute | Email + Telegram: confirmation “You have opened a dispute” |
| An admin took the dispute | Email + Telegram: “🛡️ An admin took the dispute — open the web app to chat with them” |
| New private message in your inbox | Telegram (if you have the bot linked) |
Each notification is sent once per trade and event type — no spam.
/start CODE command shown on that screen (Copy button), open Telegram, go to the site bot's chat and send it as a message.The Monitor is managed from the web admin panel (/noxtr/server_admin) via the Start / Stop / Status buttons, or directly from the server console:
php /path/index.php noxtr/server/action=monitor --verbose
To keep it running in the background:
nohup php /path/index.php noxtr/server/action=monitor > /var/log/monitor.log 2>&1 &
The Monitor has its own Nostr identity. Authorized administrators can send it plain-text commands via DM from any Nostr client (including Noxtr). Its npub appears in the startup message and in the web panel.
| Command | Action |
|---|---|
ping | Checks the channel is responding. Returns pong. |
status | Version, watched trades, uptime, relays. |
trades | Live order book (options: age 4h, amount 50 EUR, status pending). |
relays | Relays connected in the current session. |
email | Sends a test email to the admin. |
reload | Reconnects to relays without restarting the process. |
stop | Stops the process cleanly. |
help | Full contextual help. |
In addition to watching user trades, the Monitor notifies the administrator of every new order that appears in the Mostro order book (v2-transport instances only; obsolete v1 instances are ignored) and of every new on-chain offer. It can be toggled with the notify-new-offers on|off command.
To receive new-order notifications via Telegram, the administrator must have the bot linked and their Nostr pubkey added to admin_pubkeys in the Monitor configuration.
admin_pubkeys can send commands. Events are verified cryptographically with Schnorr signatures. Commands older than 5 minutes are automatically ignored.
| Component | Technology |
|---|---|
| Frontend | Vanilla JavaScript (single IIFE), wquery DOM helper |
| Backend | PHP (ExtFW framework module) |
| Database | MySQL or SQLite (dual-compatible SQL) |
| Web server | Apache (mod_rewrite) or nginx |
| Cryptography | noble-secp256k1 (BIP-340 Schnorr), noble-ciphers (XChaCha20-Poly1305), Web Crypto API (AES-CBC, HKDF) |
| Lightning | BTCPay Server (LNURL-pay, BOLT11 invoices) |
| Storage | Server DB (contacts, topics, bookmarks, DMs, relays, muted, channels, NIP-96 servers, NWC URI) + localStorage/IndexedDB (keys, UI state). Image attachments upload to external NIP-96 servers — not to the PHP server |
Features queued without a defined date. The canonical source lives in _modules_/noxtr/BACKLOG.md within the repository.
Make lists (topics, bookmarks, muted, channels, relays) portable between Nostr clients and between Noxtr instances via kinds 10000-10015. Today lists live only in local DB; manual export/import covers migration. NIP-51 would add continuous bidirectional sync.
Custom NIP proposal (not standardized) for decentralized directory of ed2k servers and ed2k links. Kinds 2010 (server) and 2011 (file). Full spec (draft): NIP-ED2K.md.
Simple implementation of kind 2003 with magnet/name/size tags. Postponed: ecosystem is mostly empty today (0 kind 2003 events on active relays). Would make sense alongside NIP-ED2K in a unified "file sharing" tab.
Subreddit-style communities with cryptographic moderation. Kinds 34550 (definition) and 4550 (moderator approval). Separate tab from Channels (NIP-28). Useful for curated forum-style feeds.
Encrypt sensitive columns of the CLI_USER table in the browser, so the server never sees personal data in plaintext. Requires upfront design (which columns, which key, what happens if user loses it).