Merka is a free, open-source, censorship-resistant marketplace built on the Nostr protocol. It allows anyone in the world to buy, sell, and trade goods and services without relying on any central server, company, or intermediary.
π Open Merka Web App directly in your browser.
No accounts with companies. No phone numbers. No email addresses. Just your cryptographic identity β yours alone, forever.
"Merka is the open market. Global by nature. Human by essence."
| Feature | Description |
|---|---|
| π¦ Buy & Sell | Post marketplace listings on the Nostr network tagged with #Merka |
| π Global Feed | Browse real-time listings from traders around the world |
| π₯ Follow Network | Build a personal network of trusted buyers and sellers |
| π Search Users | Find any user by npub, hex pubkey, name, NIP-05 address or bio text |
| π Private Messaging | End-to-end encrypted direct messages (NIP-17 + NIP-44) |
| π Search | Full-text search across the decentralized network (NIP-50) |
| π 15 Languages | Fully localized: EN, PT, ES, IT, DE, HI, JA, ZH, AR, RU, FR, TR, FA, VI, UK |
| β‘ Lightning Zaps | Generate BOLT11 invoices in-app, scan QR code, or pay via WebLN wallet extension β full NIP-57 flow |
| βΏ Bitcoin On-chain | Accept Bitcoin on-chain payments alongside Lightning β both in the same payment modal |
| π Relay Management | Add, remove and monitor relays in real time. NIP-65 relay lists published to Nostr |
| π± PWA | Installable progressive web app β works on any device, no app store needed |
| π·οΈ Custom Tags | Filter and categorize listings with custom hashtags |
Merka is built entirely on open standards and open-source libraries, with no external UI framework and no backend.
| Technology | Role |
|---|---|
| Nostr Protocol | Decentralized relay-based messaging |
| nostr-tools v2.23 | Nostr implementation library |
| Bitcoin / Lightning Network | Payments and value transfer |
| NIP | Description |
|---|---|
| NIP-01 | Basic protocol β kind:0 profiles, kind:1 posts |
| NIP-02 | Follow lists (kind:3) |
| NIP-04 | Legacy encrypted DMs (kind:4) β maintained for compatibility |
| NIP-17 | Private direct messages with gift wrap (kind:1059) |
| NIP-19 | Bech32 entity encoding β npub, nsec, note1 |
| NIP-25 | Reactions β kind:7 likes |
| NIP-44 | ChaCha20-Poly1305 authenticated encryption for DMs |
| NIP-49 | Password-protected private keys (ncryptsec1 format) |
| NIP-50 | Full-text relay search |
| NIP-57 | Lightning Zaps β kind:9734 zap request, kind:9735 receipt, LNURL-pay, BOLT11 invoice generation |
| NIP-65 | User relay lists (kind:10002) β published on relay changes |
| Technology | Role |
|---|---|
| React 19 + TypeScript | UI framework |
| Vite 7 | Build tool and dev server |
| Custom CSS | No UI framework β glass-panel/purple design system |
@fontsource/outfit |
Self-hosted fonts (no Google Fonts CDN) |
react-qr-code |
QR code generation for Zap and donation addresses |
| Tool | Role |
|---|---|
| Vitest 4 | Test runner β fast, Vite-native |
| @testing-library/react | Component testing β behavior-driven |
| @testing-library/user-event | Realistic user interaction simulation |
| jsdom | Browser environment for tests |
Coverage: 379 tests across 12 test files covering all Nostr protocol functions, UI components, modals, hooks, i18n completeness (15 languages), and security boundaries.
npm test # run all tests
npm run test:watch # watch mode
npm run test:coverage # coverage reportMerka connects to 6 well-known public relays by default:
relay.damus.io, relay.primal.net, nos.lol, nostr.wine, purplepag.es, relay.snort.social
Security and privacy are first-class citizens in Merka. Here is what is built in:
Your Nostr private key (nsec) never leaves your device. Merka stores it locally using NIP-49 encryption β you can set a password so even if someone accesses your browser storage, they cannot use your key without it.
All direct messages use NIP-17 gift wrap + NIP-44 (ChaCha20-Poly1305) β a modern authenticated encryption scheme that is significantly stronger than the deprecated NIP-04 (AES-CBC) used by older Nostr clients:
- Authenticated: messages cannot be tampered without detection
- Gift wrap (NIP-17): hides sender, receiver, and real timestamp from relay operators
- Strong primitives: ChaCha20-Poly1305 via libsodium-compatible APIs
A strict CSP header prevents:
- Loading scripts or styles from external sources
- Clickjacking and injection attacks
- Unauthorized WebSocket connections to untrusted hosts
All external links are validated against an https:// / http:// allowlist before rendering. Dangerous protocols (javascript:, data:, vbscript:, etc.) are silently dropped.
When auto-discovering relays from the network, Merka only connects to a curated allowlist of known trusted relay domains β preventing relay injection attacks from malicious relay lists.
Merka does not load any external images β including profile pictures from Nostr profiles. Profile pictures are replaced by a deterministic text avatar derived from the last 2 characters of the user's public key. This completely eliminates tracking pixel attacks, where a malicious user could discover the IP address of anyone who views their posts.
Merka has no backend, no analytics, no cookies, and no accounts. Everything runs in your browser and communicates directly with Nostr relays via WebSocket. Your data belongs to you.
A full security audit was performed covering:
- Private key exposure risks
- XSS and content injection
- Relay trust model
- Cryptographic correctness (NIP-44 vs NIP-04)
- Content Security Policy
- Unsafe URL protocols
All identified issues are resolved. See docs/security-audit.md for the full report.
# 1. Clone the repository
git clone https://github.com/YOUR_USERNAME/merka.git
cd merka
# 2. Install dependencies
npm install
# 3. Start the development server
npm run dev
# Open http://localhost:5173
# 4. Build for production
npm run build
# 5. Preview the production build
npm run previewRequirements: Node.js 18+, npm 9+
.
βββ src/
β βββ App.tsx # Root orchestrator β auth, modal routing, state
β βββ config/
β β βββ constants.ts # APP_GUID, MERKA_PUBKEY, donation addresses
β β βββ constants.test.ts
β βββ hooks/
β β βββ useNostrAuth.ts # Login, logout, NIP-49 protection, 30-day session
β β βββ useRelays.ts # Real-time relay health monitoring
β βββ services/nostr/
β β βββ nostr.ts # Entry point β re-exports + publish functions
β β βββ pool.ts # Shared SimplePool instance
β β βββ relayHealth.ts # RELAYS list, health monitoring
β β βββ messaging.ts # DMs: NIP-17/44 gift wrap
β β βββ auth.ts # createKeys, loginWithKey, fetchProfile, follow lists
β β βββ zap.ts # NIP-57: LNURL-pay, zap request, BOLT11 invoice
β β βββ nostr.test.ts
β β βββ nostr-extended.test.ts
β βββ pages/
β β βββ Login/Login.tsx # Key creation + login screen
β β βββ Feed/
β β βββ Feed.tsx # Main feed β subscribe, post, reactions
β β βββ ProfilePanel.tsx # Edit profile (name, bio, lud16, BTC address, NIP-05)
β β βββ ProfilePanel.test.tsx
β β βββ ChatHistoryPanel.tsx # DM history with unread badge
β β βββ KeyWarningModal.tsx # Secure nsec display after key creation
β β βββ ZapModal.tsx # β‘ Lightning + βΏ Bitcoin payment modal (tabs, BOLT11, QR)
β β βββ ZapModal.test.tsx
β βββ components/
β β βββ feed/
β β β βββ NoteCard.tsx # Note card + AuthorProfile popup (copy npub)
β β β βββ NoteCard.test.tsx
β β βββ chat/
β β β βββ ChatPanel.tsx # Real-time encrypted DM panel
β β β βββ ChatPanel.test.tsx
β β βββ ui/icons.tsx # All SVG icons inline
β β βββ modals/
β β βββ about/ # AboutMerka, AboutNostr
β β βββ donate/ # DonateModal, WalletGuide
β β βββ network/
β β β βββ NetworkListModal.tsx # Followers/Following + search by npub/hex
β β β βββ RelaySettingsModal.tsx # Add/remove relays + confirm before delete
β β β βββ RelaySettingsModal.test.tsx
β β βββ security/
β β βββ KeyProtectionModal.tsx # NIP-49 password setup
β β βββ UnlockKeyModal.tsx # NIP-49 decrypt on login
β β βββ KeyProtectionModal.test.tsx
β β βββ UnlockKeyModal.test.tsx
β βββ i18n/
β β βββ translations.ts # 15 languages: EN PT ES IT DE HI JA ZH AR RU FR TR FA VI UK
β β βββ translations.test.ts
β βββ styles/
β βββ index.css # Full design system β glassmorphism, purple theme
βββ public/
β βββ manifest.json # PWA manifest
βββ docs/
βββ FEATURES.md # Nostr roadmap & feature backlog
βββ security-audit.md # Full security audit report
Merka is open source and contributions are welcome.
- Report bugs β open an issue describing steps to reproduce
- Suggest features β open an issue explaining the use case
- Submit a PR β fork, create a branch, code, test, pull request
Please follow the existing conventions:
- TypeScript strict mode β no
anywithout justification - No external UI libraries β custom CSS only
- All visible text must use
t.keyfromsrc/i18n/translations.ts - New i18n keys must be added to all 15 languages
- Run
npm testβ all 379 tests must pass - Run
npm run buildbefore submitting β zero TypeScript errors required
Merka is free software built with passion for a better, open internet. If it helps you, please consider supporting the original creator:
| Method | Address |
|---|---|
| β‘ Lightning (Zap) | smarteranswer31@walletofsatoshi.com |
| βΏ Bitcoin (on-chain) | bc1qxdmvlzvm4p9tle5vxfh0tyns3lwryet8886vrv |
| π£ Nostr | npub16djn9xucugk5wp76x0trhvy5eldv3juzwq92jng72ax26puzeyls327tm6 |
If you fork or deploy your own version of Merka, please keep the donation addresses visible in the app's "About Merka" screen so the original creator continues to receive support from the community.
This project is licensed under the MIT License β see LICENSE.md for full details.
You are free to use, copy, modify, merge, publish, distribute, sublicense, and sell copies of this software. The only requirement is to keep the copyright notice and permission notice in all copies or substantial portions of the software.
Built with β€οΈ on the Nostr protocol Β· No borders Β· No intermediaries Β· No barriers