The self-hosted backend that powers the M4TR1X network.
🌐 Official site & downloads — nderja.com M4TR1X is distributed only from nderja.com.
When regulators want to enforce identity verification on a social platform, they send a letter to the company that runs the servers. M4TR1X has no such company and no such servers — only nodes run by individuals.
The EU's push toward mandatory identity verification for social platforms — through the DSA, age verification proposals, and digital identity schemes — assumes that social infrastructure has a center: a company, a server, a database to hand over. m4tr1x-node is designed to have none of those things. Anyone can run one. No one owns the network.
Every node that comes online makes the network more resilient and harder to disable by targeting a single point. Running a node is not just using the network — it is the network.
A M4TR1X node is a self-hosted backend that:
- Runs a Nostr relay — receives and stores signed events (posts, messages, metadata) from users
- Runs a Blossom blob store — stores binary content (videos, photos, music) addressed by SHA-256 hash
- Serves HLS video streams — transcodes and segments video for playback
- Hosts photo and story posts — stores and serves image content for feeds and stories
- Runs the AI detector — on-node inference to flag AI-generated video content
All content is stored locally on the node operator's machine. There is no central storage. Content is replicated across nodes according to demand.
Node operators earn 30% of every tip that passes through their node, paid automatically in H8 tokens at the time of the transaction. No invoicing, no withdrawal request.
Operators can also sell H8 for fiat (SEPA transfer or PayPal): configure your IBAN / PayPal address once in /admin → PAGAMENTI, users buy from the token modal in the app, you credit the order with one click after the money arrives. See docs/NODE_OPERATOR.md.
- Node.js 18+
- ffmpeg (for HLS transcoding)
- Minimum 20 GB disk space (more is better)
- A static IP or dynamic DNS (recommended for public-facing nodes)
git clone https://github.com/H8dboy/m4tr1x-node.git
cd m4tr1x-node
npm install
cp .env.example .envEdit .env:
PORT=8080
NODE_NAME=my-node
PUBLIC_NODE_URL=https://node.example.org # how other nodes/phones reach you (optional)
HEAD_NODE_URL=http://<head-node-host>:8090 # node directory (optional)
RELAY_PEERS=ws://<peer-host>:8080/relay # static mesh peers (optional)
ADMIN_KEY=<random hex> # /admin from another machine (optional)Start (headless — npm start launches the desktop client instead):
npm run serverThe node will announce itself to the network and begin accepting connections.
Open http://<node-ip>:8080/app to create the node identity (the wallet that
signs blocks and receives tips) and http://<node-ip>:8080/admin for the
operator panel. Phones use the PWA at /m (install page with APK / iOS instructions: /install).
One-command install (Ubuntu 22.04+ / Debian 12+) — installs Node.js 20 and ffmpeg, configures the node and registers it as a systemd service:
HEAD_NODE_URL=http://<head-host>:8080 NODE_NAME=my-node \
bash scripts/install-node.shEach node runs its own embedded Nostr relay (ws://<node>:4848). The relay
mesh keeps these relays in sync using only standard NIP-01 messages: every
node opens a persistent subscription to its peers' relays and imports their
events into its own relay, where signatures are verified and duplicates are
dropped. Posts, likes, follows, profiles and ledger blocks propagate across
the whole network while every client keeps talking only to its local relay —
no central server in the data path, works over LAN and clearnet today.
Peers are discovered automatically from the head node directory
(HEAD_NODE_URL) and/or configured statically (RELAY_PEERS) — a network
can run with no head node at all.
curl http://localhost:8080/api/v1/mesh/status # sync status per peer
npm run test:mesh # two-node end-to-end test┌──────────────────────────────────────────────────┐
│ m4tr1x-node │
│ │
│ ┌─────────────┐ ┌──────────────────────────┐ │
│ │ Nostr Relay │ │ Blossom Blob Store │ │
│ │ (WebSocket) │ │ (SHA-256 addressed) │ │
│ └──────┬──────┘ └────────────┬─────────────┘ │
│ │ │ │
│ ┌──────▼──────────────────────▼─────────────┐ │
│ │ Express API │ │
│ │ HLS transcoder │ Photo/story handler │ │
│ │ Tip processor │ AI detector bridge │ │
│ └───────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ Tor Hidden Service │ │
│ │ (automatic if TOR_ENABLED=true) │ │
│ └──────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
| Module | Description |
|---|---|
relay/ |
Nostr relay — stores and forwards signed events |
blossom/ |
Blob store — content addressed by SHA-256 |
hls/ |
Video transcoding and segmented streaming |
media/ |
Photo and story post handler |
ai-detector/ |
Bridge to m4tr1x-ai-detector |
tips/ |
H8 token tip processing and operator payout |
tor/ |
Tor hidden service management |
- Node identity: ML-DSA-65 keypair (NIST FIPS-204)
- All content verified by SHA-256 hash before storage
- Nostr events validated against cryptographic signatures before relay
- The node identity (
h8identity.enc) is encrypted at rest with the operator password and unlocked in memory only; the ledger is ML-DSA-65 signed and verified by every peer - Owner privileges never leak through a reverse proxy or the Tor hidden service; browser sessions are same-origin only
If a tor binary is available, the node starts its own Tor (SOCKS on TOR_SOCKS_PORT, default 9050) and a hidden service that maps to a dedicated loopback ingress listener (TOR_INGRESS_PORT, default 18080), so visitors arriving through the .onion never inherit localhost privileges. The .onion address is published to the head directory. To use an existing system Tor instead, point its HiddenServicePort 80 127.0.0.1:18080 and set TOR_HOSTNAME_FILE (see .env.example).
The desktop client lives in this repo: npm start launches Electron with an embedded node (data in the OS user-data folder). Phones: open http://<node-ip>:8080/install on the phone, add the PWA to the home screen, enter the node URL — the app talks to the node over X-Owner-Token after unlocking the wallet.
See docs/NODE_OPERATOR.md for the complete setup guide including firewall configuration, storage management, and performance tuning.
Read CONTRIBUTING.md. Security issues go to SECURITY.md.
MIT — see LICENSE.
Part of the M4TR1X project — built by @H8dboy — Brescia, Italy