Skip to content
SovereignTechnologyPublic

About

NUTLFIX - NFX: open video over Nostr, iroh and Cashu. (nfxd) Mirror of the ngit repository nostr://npub1s0vtechh66tx7vrwdud8zfyheu9zca7swwfrzd4qu2a4f93mxs6qvn9adx/nfx

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

449 Commits

Folders and files

NFX

Source of truth: nostr://npub1s0vtechh66tx7vrwdud8zfyheu9zca7swwfrzd4qu2a4f93mxs6qvn9adx/nfx — issues and pull requests live there. This GitHub repository is a mirror; push to the Nostr remote, not here.

A Nostr-identified, peer-seeded video network: an open standard with a Rust reference implementation.

NFX lets a creator publish a signed video manifest on Nostr and lets peers seed and watch the video, checking every file against signed hashes. The normative specification is in spec/. The Rust reference implementation in crates/ covers iroh (native), a WebRTC mesh (browsers) and an HTTP origin, which a public deployment puts behind TLS and a CDN. The optional Hypercore profile (NFX-12) and payments (Cashu ecash, per delivered chunk) are specified as drafts.

Status (2026-11-07): NFX 0.1.1 is the latest release (0.1.0 was the first): nfxd and nfx-package for linux-x64 on the Releases page, free video only (release notes; 0.1.0). 0.1.1's relay also searches a video's title. It is tested against the nutflix-pear desktop app in both directions, behind NATs and over TLS relays. The public services on nfx:testnet:1 are an iroh relay, https://iroh.nutflix.xyz/, and a scoped Nostr relay, wss://relay.nutflix.xyz (testnet). The free end-to-end slice (milestone M1: publish, seed, fetch, play; no payments) is built and passed its exit run. That run and the Phase A exit run before it used two hosts on a private network with plain HTTP and WebSocket endpoints; they did not cover NAT traversal, TLS, a CDN or paid delivery. What each run left out: M1, Phase A. The Hypercore profile (NFX-12) is not implemented. Payments are specified (NFX-07); the open-mode contracts, the mock engine and the adversary suite sit in crates/nfx-pay and crates/nfx-pay-wire, behind the lock, and are not deployed. NFX-01 to NFX-06 are Frozen; the status of every document and its freeze milestone is in spec/README.md. Log and resume point: docs/nfx/status.md.

Repository layout

Path What it is
spec/ NFX-01 to NFX-12, the JSON schemas (schemas/) and the regenerable test vectors (test-vectors/)
crates/ The Cargo workspace (edition 2024), with the members below
crates/nfx-proto Wire formats: manifests, beacons, hash lists, canonical JSON, vouchers, gossip envelopes. Pure (no I/O, clock or RNG); builds natively and for wasm32
crates/nfx-node The peer: content store, iroh seeding and fetching, gossip presence, Nostr manifests and beacons, pull-through origin, embeddable scoped relay, browser-mesh tracker and WebRTC bridge, and the Nostr-signaled full-ICE mesh endpoint
crates/nfx-media NFX-05 packaging (ladder planning, CMAF output, content addressing); ships the nfx-package binary
crates/nfx-wasm nfx-proto for browsers: verifies manifests, beacons, hash lists and files from JS
crates/nfxd The headless node: key, publish, delete and run
crates/desktop Tauri 2 desktop viewer on top of the nfxd daemon; its own Cargo workspace, sharing is opt-in
crates/spikes Spike code and tools (s1-iroh, s2-tauri, nfx-verify-store), each its own workspace
crates/ci check.sh, the lock scripts and the CI job definition
crates/nfx-pay-wire, crates/nfx-pay The pay/1 wire and the open-mode payment contracts (NFX-07), with a mock engine and the adversary suite. Locked: see below
web/player The browser test player: hls.js behind a loader that verifies every file with nfx-wasm, plus the WebRTC mesh
web/spikes Browser spike code (s3-mesh, s4-cmaf)
docs/ decisions/ (ADRs) and nfx/ (status, plans, exit runs, reviews, spike write-ups); index in docs/README.md

Quick start

Clone from Nostr (needs ngit's git-remote-nostr) or, instead, from the GitHub mirror:

git clone nostr://npub1s0vtechh66tx7vrwdud8zfyheu9zca7swwfrzd4qu2a4f93mxs6qvn9adx/nfx
# or: git clone https://github.com/SovereignTechnology/nfx
cd nfx

Prerequisites: a Rust toolchain at least as new as rust-version in crates/Cargo.toml; for the player, the wasm32-unknown-unknown target, wasm-pack and Node; for packaging, ffmpeg and ffprobe on PATH (or NFX_FFMPEG and NFX_FFPROBE). The versions CI uses are pinned in .github/workflows/ci.yml.

repo=$PWD                                  # the root of the clone
cargo build --release --locked --manifest-path crates/Cargo.toml -p nfxd -p nfx-media
export PATH="$repo/crates/target/release:$PATH"
work=$(mktemp -d); echo "$work"            # a scratch directory for the demo files
cd "$work"
cp /path/to/any-video.mp4 clip.mp4         # any local video that ffmpeg can read

Package the clip, create a key, and run a node that seeds it. --embed-relay and --origin take ip:port; a bare :port is refused.

nfx-package clip.mp4 --video nfx:testnet:1:my-video --out pkg   # pkg/store, pkg/nfx.json
pub=$(nfxd key new node.key | head -n 1)   # prints the public key as hex, then as npub
A=38504:$pub:nfx:testnet:1:my-video        # the manifest address
nfxd run --key node.key --store pkg/store --seed "$A" \
  --embed-relay 127.0.0.1:7447 --origin 127.0.0.1:3473

nfx-package makes one rendition by default: 720p, or the clip's own size when it is smaller. A size is the picture's short side, so 720p is 1280x720, or 720x1280 for a portrait clip. While the network is small, each extra rendition is another set of segments to store and another browser swarm to split viewers across (nutflix-pear#97 tracks a fuller default). --renditions picks the sizes instead, from those the clip offers: the tiers 2160p, 1440p, 1080p, 720p, 480p and 360p up to its size, and its own size (--renditions 2160p for one 4K rendition, --renditions 1080p,720p,360p for the old three-size ladder). Nothing is upscaled: a size the clip does not offer is refused.

In a second terminal, change to the scratch directory printed above and set repo (the clone root) and PATH again. Publish the manifest to the embedded relay. It prints the address, and the node then logs <address>: Seeding. Then serve the browser test player, which listens on 0.0.0.0:3471:

nfxd publish --key node.key --relay ws://127.0.0.1:7447 --package pkg --title "My video"
cd "$repo/web/player" && npm ci --ignore-scripts && npm run serve
# open http://127.0.0.1:3471/?a=<address>&relay=ws://127.0.0.1:7447&origin=http://127.0.0.1:3473

A node binds iroh to a random UDP port, and peers on the internet reach it through an iroh relay (--iroh-relay) or by hole-punching. A host that can forward one UDP port to itself, a home router's port forward or a DNAT in front of a VM, can be dialled directly instead:

nfxd run --key node.key --store pkg/store --seed "$A" --embed-relay 127.0.0.1:7447 \
  --iroh-bind 0.0.0.0:7843 --iroh-external 203.0.113.7:7843

Here 203.0.113.7:7843 stands for the public address and port forwarded to the host's UDP port 7843. Tickets and beacons then name that address and leave out the host's private ones.

--embed-tracker and --bridge <ip:port> add the browser mesh (NFX-10): the bridge serves the video to browsers over WebRTC, and its address is the one candidate they are told. Behind a DNAT, bind --bridge to the host's own address and pass the public one as --bridge-public (for example --bridge-public 203.0.113.7:7844); --bridge-max-peers (default 64) caps the browsers it serves at once.

A node behind a NAT, a home node say, serves browsers with no tracker and no forwarded port through the mesh endpoint (NFX-10 §6): --mesh-relay <url> (1 to 8 general Nostr relays; a scoped relay refuses the signaling kind) turns it on, and --mesh-stun <ip:port> names a public node's --stun so it learns its public mapping. Browsers that play a rendition it holds meet it in that rendition's room, and both ends punch through their NATs with full ICE:

nfxd run --key node.key --store pkg/store --seed "$A" --relay wss://relay.example \
  --mesh-relay wss://general-relay.example --mesh-stun 203.0.113.7:3478

Joining a room tells anyone present there the node's candidate addresses, its public mapping included, as a tracker's swarm would. --mesh-bind fixes its UDP port and --mesh-max-peers (default 16) caps its connections.

Checks

PYTHON=/path/to/venv/bin/python crates/ci/check.sh

check.sh stops at the first failing step. The step list, what each one needs and the environment switches are in CONTRIBUTING.md. CI runs what check.sh runs. The browser end-to-end suites (npm run e2e and npm run e2e:mesh in web/player, ./e2e.sh in crates/desktop) are separate.

CI and the lock

CI runs on GitHub Actions (.github/workflows/ci.yml) as two jobs: lock, and check, which runs crates/ci/check.sh. crates/ci/gitlab-ci.yml holds the same two jobs for GitLab and is dormant.

The money code (crates/nfx-pay, crates/nfx-pay-wire and the paths listed in crates/ci/check-locked.sh) is locked: every file is pinned by hash in crates/ci/locked.sha256, and the lock fails any change that is not re-pinned after review. The rule and its history are in docs/nfx/m2-plan.md.

Documentation

The demo

NFX grew beside a TypeScript demo, a Pear-runtime desktop app under the name nutflix, which is a different design (ADR 0006). Until 2026-10-11 this repository mirrored the demo's tree. The mirror was removed (ADR 0008, amendment of that date): the demo lives in its own repository, nutflix-demo, and the snapshot that was mirrored here stays reachable under the tag demo-base:

git show demo-base:README.md

Older records under docs/ that name packages/, scripts/ or docs/plan/ mean the demo's tree at that tag.

Contributing, security, licence

See CONTRIBUTING.md, CODE_OF_CONDUCT.md and SECURITY.md (how to report a vulnerability).

Copyright (C) 2026 sovtech. Code is AGPL-3.0-or-later: see LICENSE. The specification text in spec/ is public domain (CC0): see spec/README.md.

About

NUTLFIX - NFX: open video over Nostr, iroh and Cashu. (nfxd) Mirror of the ngit repository nostr://npub1s0vtechh66tx7vrwdud8zfyheu9zca7swwfrzd4qu2a4f93mxs6qvn9adx/nfx

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages