Skip to content

marmot-protocol/marmot-ts

Repository files navigation

marmot-ts

TypeScript implementation of the Marmot protocol - bringing end-to-end encrypted group messaging to Nostr using MLS (Messaging Layer Security).

Warning

This library is currently in Alpha and under heavy development. The API is subject to breaking changes without notice. It relies heavily on ts-mls for MLS cryptographic guarantees. Do not use in production yet.

This library provides the building blocks for creating secure, decentralized group chat applications on Nostr. It wraps ts-mls with Nostr-specific functionality, similar to how MDK wraps OpenMLS.

Features

  • 🔐 End-to-end encrypted group messaging using MLS protocol
  • 🌐 Decentralized - groups operate across Nostr relays
  • 🔑 Key package management - handle identity, publishing, rotation, and invitations
  • 📦 Storage-agnostic - bring your own GenericKeyValueStore backend (LocalForage, IndexedDB, SQLite, in-memory, etc.)
  • 🔌 Network-agnostic - works with any Nostr client library
  • 📱 Cross-platform - works in browsers and Node.js (v20+)

Installation

npm install @internet-privacy/marmot-ts
# or
pnpm add @internet-privacy/marmot-ts

Marmot Protocol Compliance

Currently, marmot-ts supports the following Marmot Improvement Proposals (MIPs):

MIP Description Status
MIP-00 Introduction and Basic Operations ✅ Supported
MIP-01 Network Transport & Relay Communication ✅ Supported
MIP-02 Identities and Keys ✅ Supported
MIP-03 Group State & Memberships ✅ Supported

Documentation

Comprehensive documentation is available in the documentation/ directory:

  • Getting Started - A fast track to initializing the library.
  • Architecture - High-level component overview and Nostr/MLS integration mapping.
  • MarmotClient - Deep dive into the main entry point class, its sub-managers, and identity management.
  • Bytes-First Storage - Explaining the storage-agnostic philosophy and group state hydration.
  • Ingest Methods - Handling incoming messages and network input robustly.
  • Examples - Concise snippets for group creation, invitations, sending messages, and more.

Quick Start Overview

To begin using the client, you need an EventSigner (e.g. from applesauce-core), a NostrNetworkInterface implementation, and two GenericKeyValueStore backends — one for serialized group state bytes and one for key package metadata.

import { MarmotClient } from "@internet-privacy/marmot-ts";
import localforage from "localforage";

const client = new MarmotClient({
  signer: yourNostrSigner,
  // Any GenericKeyValueStore<SerializedClientState>. A LocalForage instance
  // works directly because it already implements the getItem/setItem/keys API.
  groupStateStore: localforage.createInstance({ name: "marmot-groups" }),
  // Any GenericKeyValueStore<StoredKeyPackage> for key package metadata.
  keyPackageStore: localforage.createInstance({ name: "marmot-keypackages" }),
  // Your NostrNetworkInterface implementation (publish, request, subscription, getUserInboxRelays).
  network: yourNetworkInterface,
  // Optional: stable slot identifier for addressable (kind 30443) key packages.
  clientId: "my-app-desktop",
});

const group = await client.groups.create("My Secret Group", {
  description: "A private discussion",
  relays: ["wss://relay.example.com"],
  // Optional: add additional admins (the creator is always included automatically)
  adminPubkeys: ["<other-admin-pubkey-hex>"],
  // Optional: override MLS ciphersuite
  ciphersuite: "MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519",
});

See Getting Started and Examples for full usage instructions.

Development

pnpm install   # Install dependencies
pnpm build     # Compile TypeScript
pnpm test      # Run tests (watch mode)
pnpm format    # Format code with Prettier

About

TypeScript implementation of the Marmot protocol

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors