@internet-privacy/marmot-ts
v0.5.1
Published
Marmot protocol implementation in TypeScript
Readme
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
GenericKeyValueStorebackend (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-tsMarmot 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