Iris Stack is a modular, permissionless stack for identity, communication, connectivity, storage, social trust, and money. Its FIPS connectivity layer can use carrier adapters at multiple layers: Ethernet, Bluetooth LE, UDP, TCP, WebRTC, Tor, or relays. Nostr provides portable signed identity and publish-subscribe messaging; Hashtree verifies content by hash; viewer-local social graphs supply trust policy; and Cashu provides credit and settlement. Applications combine these layers without treating a platform account, domain, or cloud vendor as an authority.
apps.iris.to catalogs Iris Stack products, including Iris Drive, Chat, Calendar, and Nostr VPN. The Iris Drive native app can resolve Hashtree-published apps through the local iris.localhost resolver and cache their files for offline launch; features that depend on peers or external services still require connectivity.
The numbered order below runs from the network-facing substrate toward applications. Nostr identity and payments cross every layer.
| Position | Component | Role | Replaces |
|---|---|---|---|
| Identity | Nostr | Portable public-key identity and signed event format | Platform account, email address, phone number, domain name, or TLS certificate as identity |
| 1 · datagrams | FIPS | Authenticated datagrams addressed by self-generated public keys, encrypted links, carrier adapters, discovery, routing, and admission | Hierarchically allocated or location-dependent addressing (domain names and IP addresses), plus transport-specific authentication and routing |
| 2 · streams | fips-tcp |
Reliable ordered delivery over FIPS | TCP streams bound to IP endpoints |
| 3a · publish-subscribe | nostr-pubsub |
Subscriptions, signed-event exchange, deduplication, source selection, and real-time policy | Central message broker |
| 3b · private conversations | nostr-double-ratchet |
End-to-end encrypted 1:1 and group Nostr events, multi-device sessions, and asynchronous delivery | Platform messaging service or always-online encrypted connection |
| 3c · content | Hashtree | Hash-addressed files and directories, verification, caching, content routing, apps, releases, history, and Git data | Origin server, CDN, or cloud store as content authority |
| 4a · indexes | @hashtree/index and @hashtree/collection |
Immutable B-trees, canonical records, derived search roots, collection manifests, and local or federated reads | Central database, search service, relay index, or platform API |
| 4b · social context | nostr-social-graph |
Graph traversal, fact events, viewer-local naming, moderation, reputation, and resource-policy inputs | Central profile, ACL, moderation, or reputation database |
| Payments | cashu-service |
Bounded credit, token transfer, useful-service accounting, and settlement adapters | Credit-card processor or platform balance |
| 5 · applications | Products | User experience, authorization, durable state, economics, and explicit outbound peers | Single platform as identity, policy, and egress authority |
Nostr keys provide the portable identity shared by FIPS nodes and application events. Signed events carry profiles, follows, mutes, messages, capability adverts, ratings, release roots, and application-defined facts. Signatures bind an event to its author; each application decides what that author may do.
Fact events give application data a reusable subject–predicate–object shape. A
durable subject can represent a person, organization, place, review, or other
entity; predicates such as name, controls, same_as, or member_of
describe it; and objects supply names, keys, or related entities. Apps can
update or dispute claims and assemble their own trusted view without defining a
new event type for every data model. The signature proves who made a claim, not
that the claim is universally true.
The nostr-social-graph
identity tools use UUID-based rosters and facts so an identity is not tied to a
single key. If a key is lost or compromised, social-graph attestations can
associate a replacement key with the same UUID, preserving the identity.
| Example app | Usage |
|---|---|
| Iris Chat | Uses Nostr identities and owner-signed AppKeys roster fact snapshots to authorize and synchronize linked devices. |
| Iris Contacts | Keeps one UUID subject for a contact while name, controls, and other signed facts describe names, keys, and relationships that may change. |
FIPS (Free Internetworking Peering System) gives each node a self-generated public-key address and authenticated, encrypted datagrams. FIPS is not tied to one OSI layer: carrier adapters present packet delivery, addressing, and MTU to the mesh protocol. An adapter may run over Ethernet, Bluetooth LE, UDP, TCP, Tor, WebRTC, a relay, or another medium. Several carriers can participate in one routed mesh; none is required to be IP-based.
FIPS uses the same public-key type and format as a Nostr public key, so one key can identify both a node and an event author.
Applications address a FIPS identity while the node handles peer discovery, path selection, forwarding, admission, and link health. An IPv6 adapter lets existing IP software reach the same identities; native applications use FIPS service datagrams directly.
fips-tcp
adds reliable, ordered byte streams above FIPS datagrams. It handles loss,
retransmission, ordering, flow control, and congestion control so applications
do not each invent acknowledgements, retries, and “did you get my message?”
schemes. The remote address remains an authenticated FIPS identity.
The stack uses these streams for Hashtree blob transfers, Iris Chat linked-device
sync, Iris Drive synchronization control messages, and nostr-pubsub
inventory/want exchanges.
| Example app | Usage |
|---|---|
| Nostr VPN | Uses FIPS identities for private mesh peers, allowing carriers to change without changing the identity referenced by routes and access policy. |
| Iris Chat | Uses fips-tcp for reliable, ordered linked-device snapshots and control records. |
| Iris Drive | Uses fips-tcp for reliable multi-frame Hashtree transfers and synchronization control messages between authenticated peers, then verifies content by hash above the stream. |
nostr-pubsub
carries ordinary NIP-01
subscriptions and signed events across local indexes, FIPS-connected pub/sub
peers, and optional relays. Its direct-peer wire keeps the NIP-01 filter
semantics and REQ, CLOSE, and EVENT message shapes. An application
subscribes once and applies local policy when choosing sources or accepting
events.
Unlike NIP-01's client–relay topology, the direct protocol does not assign client and server roles. Peers can exchange and forward subscriptions and events in either direction, while standard Nostr relays remain optional routes. A peer only needs a path to another peer; it does not need to expose a public server, register a domain, or obtain a TLS certificate. Signatures decentralize authorship, but peer-to-peer pub/sub is what also decentralizes live delivery.
Across the FIPS-carried peer mesh, matching events use an inventory-first
exchange similar to the bandwidth-saving idea in proposed NIP-114.
A peer first sends an INV containing the event ID—the NIP-01 hash identifying
the event—instead of the complete event. The receiver deduplicates that ID
across peers and subscriptions and sends WANT only if it still needs the
payload; the provider then replies with an ordinary subscription-scoped
EVENT. This avoids resending a complete event that arrived earlier from local
storage or another peer, which is particularly useful when mesh fanout brings
the same inventory along multiple paths.
The nostr-pubsub-social-graph
adapter uses follows, mutes, graph distance, and signed service ratings to admit
incoming events to local storage and fanout and to prefer, throttle, or drop
peer and relay sources. These are viewer-local choices, not network-wide bans.
The same event plane carries social posts and stack coordination events: peer adverts, machine ratings, Hashtree roots, app updates, repository announcements, and service offers. Events announce large content by hash; Hashtree routes carry the bytes.
Discovery adverts are candidates, not authority. Signed, expiring transport
adverts say where a claimed FIPS identity may be reachable over Ethernet,
Bluetooth LE, UDP, WebRTC, or another carrier. Capability adverts say what a
FIPS identity offers—such as Hashtree or nostr-pubsub—and identify the
interface to use.
The client authenticates the remote identity through FIPS, checks the exact capability, and applies its own author, social, and resource policy before using the peer. Seeing an advert alone grants no access or trust.
An existing authenticated FIPS peer is one bootstrap route, not a registry.
Through nostr-pubsub-fips, ordinary subscriptions and signed adverts travel
over that connection. Relays, local indexes, and other pub/sub peers can answer
the same query; no source is mandatory.
| Example app | Usage |
|---|---|
| Iris Chat | Uses peer-to-peer pub/sub for live message subscriptions while retaining optional relay routes. |
| Nostr VPN | Publishes peer, route, and service announcements; an exit node can advertise both its reachable FIPS identity and its offered service. |
nostr-double-ratchet
provides end-to-end encrypted 1:1 and group conversations over Nostr. Direct
sessions use Double Ratchet, protecting earlier messages if a current key is
compromised and recovering future secrecy after fresh ratchet steps. Groups use
per-sender key chains, and AppKeys authorize multiple devices for one identity.
Ciphertexts are Nostr events, so nostr-pubsub peers and ordinary relays can
carry and retain them when participants are not online together. The encrypted
payload can be any app-defined Nostr event—not only a chat line—making the same
primitive useful for private social posts, shared records, and other
group-scoped data.
This design is pairwise-ratchet-first: group sender keys are distributed over authenticated pairwise sessions. Marmot instead uses MLS as a continuous group key-agreement and membership-state protocol.
| Example app | Usage |
|---|---|
| Iris Chat | Uses 1:1 ratchets and group sender keys for encrypted messages across authorized devices, with Nostr routes supporting asynchronous delivery. |
Hashtree
stores files and directories. Files can be split into chunks, while directories
are encoded as manifests. Every encoded file, chunk, or directory manifest is
addressed and independently verified by hash. Hashtree presents one operation—
fetch content by hash—across configured sources. At the protocol layer, anything
that implements that operation is a BlobRoute. Native applications can expose
the router through RoutedStore: reads use those routes, while writes, pins,
limits, and garbage collection stay with one explicit application-owned store.
Same-user native processes may open the same LMDB pool when their layout,
capacity, and pool configuration match, sharing committed immutable blobs
without a daemon. Mutable pins, quotas, and garbage-collection decisions remain
application metadata. Processes that do not share a store use the same read
contract through an authenticated FIPS provider route instead.
Blossom provides compatible HTTP storage for SHA-256-addressed content. Related proposals define client-side CHK encryption (BUD-15), directory manifests (BUD-16), chunked file and directory fanout manifests (BUD-17), and Hashtree references (BUD-18). Together, these BUDs make the encoding canonical: files may be encrypted and chunked, while directories are encoded as manifests. Client-side CHK encryption is the default; each resulting content object remains hash-addressed and independently verifiable. Blossom servers continue to store the underlying content objects.
Local storage, nearby peers, and the wider mesh answer through that interface;
a future paid provider can use the same opaque route boundary. Every response
is verified against the requested hash, and a route miss leaves the other
routes available. No paid Hashtree retrieval route is shipped as of 2026-07-17:
cashu-service supplies the payment and recovery primitives, while their blob
pricing and negotiation protocol remains product work. nostr-pubsub
announces content; Hashtree routes carry the file and directory data.
@hashtree/indexstores immutable B-trees for exact, range, prefix, and lightweight text queries over a content root.@hashtree/collectionadds canonical by-ID records, derived key/search roots, and a manifest.- An indexer may curate centrally and publish snapshots through a signed
mutable
npub/tree; readers can fetch blocks from caches, FIPS peers, or compatible stores, verify them, query locally, mirror the published root, or derive their own root by adding or removing records while reusing unchanged blocks.
Once the root and its blocks are available locally or through mirrors, the snapshot remains readable even if its maintainer goes offline. Unlike a live Nostr relay or centralized database API, answering queries does not require the original indexing service.
This supports reproducible Nostr-relay-like read projections. The publisher defines the available queries and update cadence; applications can query or federate several compatible publishers.
A static web app can be published as a Hashtree directory. Its nhash
identifies one immutable version; a signed npub/tree name can advance to a
new version without invalidating the old one.
A local app runtime can serve executable sites from separate browser origins
such as sitename.npub.iris.localhost or <nhash>.iris.localhost, keeping
unrelated apps from sharing cookies, storage, or service workers. Application
sandboxing remains a separate concern.
hashtree-updater applies the same model to native releases. A signed root
arrives through nostr-pubsub; the app checks the publisher, fetches the
release through its Hashtree routes, verifies the content address, and installs
the matching artifact. Notices and artifacts can come from stack-native peers,
with relay, Blossom, and HTTPS compatibility routes available.
| Example app | Usage |
|---|---|
| Iris Drive | Fetches verified files from a local cache, nearby peer, or remote provider, and serves Hashtree apps from isolated local origins. |
| Iris Audio | Queries shared song, artist, and album collection/search roots directly from the browser. |
| Iris Sites | Catalogs and launches web apps whose signed roots identify versions and whose Hashtree hashes verify the bytes. |
nostr-social-graph
turns follows, mutes, signed facts, and ratings into viewer-relative signals.
Each app chooses whose signals to trust, how far they travel, and how to handle
unknown identities. There is no global trust score.
| Input | Local decision |
|---|---|
| Follows, social distance, and mutes | Prioritize ordinary Nostr posts from authors near the viewer in the social graph; filter feeds, replies, notifications, profiles, and search results. |
| Machine observations and signed peer or service ratings | Prefer healthy FIPS and pub/sub peers, downrank degraded sources, and preserve exploration space for unknown peers. |
| UUID identity rosters, facts, and attestations | Keep identity consistent across keys and devices; rank contextual names and decide which claims an app accepts. |
The nostr-pubsub-social-graph
adapter uses social distance, nearby mutes, and signed service ratings to allow,
throttle, drop, or prioritize Nostr event authors and pub/sub peers.
FIPS
publishes machine-generated peer ratings and can use selected rating authors to
order candidate peers during discovery.
Hashtree uses the graph for crawl scope, relay and storage access, mirror selection, and profile search.
These signals can guide resource scheduling: Hashtree can prioritize socially close or reputable peers, while FIPS can reserve connection slots or bandwidth. Each node controls its schedule and can reserve capacity for unfamiliar peers.
Cryptographic keys are secure addresses but poor human names. Naming is a signed search problem:
- Nostr profiles propose names for public keys.
- Fact events attach
nameclaims to durable UUIDs andcontrolsclaims to keys, preserving identity while keys or names change. - Hashtree stores provide exact tag lookup;
@hashtree/indexor another database can add tokenized search. - Search returns candidates. Viewer-local follows, social distance, explicit trust, and application policy rank them.
Names are signed claims, not registrations. The same string can identify several candidates. Each viewer resolves it through accepted authors, social context, and private petnames while the key or UUID remains stable.
This follows the petname approach described in Zooko's original naming essay and An Introduction to Petname Systems: published nicknames aid discovery; a name becomes a petname only when a viewer adopts a private, unambiguous mapping to a secure identity.
The naming architecture combines Hashtree-backed profile search and social
ranking with nostr-social-memory UUID identities, petnames, aliases, and
multiple keys.
| Example app | Usage |
|---|---|
| Nostr VPN | Uses graph distance, mutes, and signed service ratings for peer and event admission. |
| Iris Contacts | Combines profiles, graph-ranked search, contextual names, and UUID-backed contacts encoded as fact snapshots. |
| Iris Drive | Uses social context to rank profiles, search results, sharing contacts, and candidate providers. |
Cashu is Chaumian ecash for Bitcoin. A mint issues blind-signed bearer tokens; wallets pass them directly, and recipients swap or redeem them with the mint. The mint rejects double-spends but cannot cryptographically link a redeemed token to the withdrawal that created it.
cashu-service
adds sat-denominated useful-service receipts and bounded peer credit to that
token transfer and settlement. A node can accept a peer's credit up to a local
limit, then request settlement through an accepted Cashu mint, Lightning, or
another configured method.
Products choose pricing, credit limits, and settlement methods. The same adapters can meter connectivity, bandwidth, storage, or routing, while free and reciprocal routes remain available.
| Example app | Usage |
|---|---|
| Nostr VPN | Lets an exit node charge for forwarded traffic and settle the balance with Cashu. |
More apps are listed at apps.iris.to.
| Product | Function | Links |
|---|---|---|
| Iris Chat | Encrypted, local-first messaging without phone-number or email signup | Product page · Web app · Source |
| Iris Drive | Offline-first, content-addressed file sync and collaboration across devices, peers, and optional storage providers | Product page · Web app · Native source · Web source |
| Nostr VPN | A private mesh that connects directly when possible, and a public exit-node marketplace when you need an internet route | Product page · Source |
| Iris Contacts | Public-key profiles, social context, and local UUID-backed contacts without a global account directory | Web app · Source |
| Iris Audio | A Hashtree-backed music catalog that demonstrates portable collection and search indexes | Web app · Source |
| Iris Sites | A launcher and isolated browser runtime for web apps published as Hashtree directories | App catalog · Source |
| Iris Git | Git repositories addressed through Nostr and Hashtree; git-remote-htree gives command-line Git fetch and push over htree:// remotes |
Web app · Source · Remote helper |
Current composition names integrations already present in product source and ordinary product paths. Optional or in-progress paths are identified separately and are not presented as shipped defaults.
| Product | Current composition | Optional or in progress |
|---|---|---|
| Iris Chat | Nostr events, nostr-pubsub routing, nostr-double-ratchet messages, FIPS live links, fips-tcp linked-device sync, and Hashtree attachments |
Ordinary Nostr relay routes remain compatible |
| Iris Drive | Hashtree files, directories, adaptive content routes and pooled storage; FIPS authenticated peers and relay/WebRTC bootstrap; fips-tcp file streams; and the native iris.localhost resolver |
Paid storage routes remain optional |
| Nostr VPN | FIPS private and routed mesh, nostr-pubsub control events, and social graph peer policy |
Cashu settlement for paid exits is optional |
| Iris Contacts | Nostr profiles, social graph, and UUID-backed fact snapshots | — |
| Iris Audio | Hashtree media, search indexes and collections, and Nostr mutable-root announcements | FIPS content routes are optional |
| Iris Sites | Hashtree app directories, Nostr mutable roots, isolated web origins, and the Iris Drive resolver | — |
| Iris Git | Nostr repository roots, Hashtree Git data, social graph context, and git-remote-htree |
— |
| Component | Source |
|---|---|
| Iris Stack architecture | iris-stack · GitHub mirror |
| Nostr specifications | nostr-protocol/nips |
| FIPS (Rust) | fips · GitHub mirror |
| FIPS (TypeScript) | fips-ts · GitHub mirror |
| Reliable FIPS streams | fips-tcp · GitHub mirror |
| Decentralized pub/sub | nostr-pubsub · GitHub mirror |
| Content-addressed storage and routing | hashtree · GitHub mirror |
Git remote helper for htree:// URLs |
git-remote-htree · GitHub mirror |
| Content-addressed search indexes | @hashtree/index · GitHub mirror |
| Content-addressed collections | @hashtree/collection · GitHub mirror |
| App updates over Hashtree | hashtree-updater · GitHub mirror |
| Social graph and fact events | nostr-social-graph · GitHub mirror |
| Cashu service primitives | cashu-service |
| Private-message ratchet | nostr-double-ratchet · GitHub mirror |
| Shared web integration | iris-kit · GitHub mirror |
| Iris Stack architecture and integration lab | iris-stack · GitHub mirror |