Skip to content

antontranelis/web-of-trust

Repository files navigation

Web of Trust

CI npm License: AGPL-3.0

A decentralized trust infrastructure for real-life communities. People meet in person, verify each other's identity via QR code, and build reputation through attestations over time.

No central server sees your data. Everything is end-to-end encrypted and stored locally.

How it works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     VERIFY      β”‚ ──► β”‚   COLLABORATE   β”‚ ──► β”‚     ATTEST      β”‚
β”‚                 β”‚     β”‚                 β”‚     β”‚                 β”‚
β”‚ Confirm identityβ”‚     β”‚ Share encrypted β”‚     β”‚ Build reputationβ”‚
β”‚ by meeting in   β”‚     β”‚ content (tasks, β”‚     β”‚ through real    β”‚
β”‚ person (QR scan)β”‚     β”‚ calendar, maps) β”‚     β”‚ actions         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Verification β‰  Trust. Verification only confirms: "This is really that person." Actual trust is built through attestations over time.

Live Demo

Architecture

7-Adapter System

The system is built on swappable adapters β€” same interfaces, different implementations. This allows experimenting with different CRDT frameworks, messaging protocols, and storage backends without touching application code.

                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚  Your App / Demo  β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  wot-core                                           β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
    β”‚  β”‚ Storage β”‚ β”‚ Reactive β”‚ β”‚ Crypto β”‚ β”‚ Discovery β”‚  β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
    β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
    β”‚   β”‚ Messaging β”‚ β”‚ Replication β”‚ β”‚ Authorization β”‚   β”‚
    β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚ adapter-yjs / adapter-automerge β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚                β”‚                β”‚
        β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ wot-relay β”‚   β”‚  wot-vault β”‚  β”‚ wot-profiles  β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Adapter Purpose Implementation
StorageAdapter Local persistence, CRUD Yjs (default) or Automerge
ReactiveStorageAdapter Live queries, subscriptions Observables on CRDT changes
CryptoAdapter Signing, encryption WebCrypto (Ed25519, X25519, AES-256-GCM)
DiscoveryAdapter Public profile lookup HTTP + offline cache
MessagingAdapter 1:1 message delivery WebSocket Relay (ACK + Outbox)
ReplicationAdapter Encrypted CRDT Spaces Yjs or Automerge + E2EE + GroupKeys
AuthorizationAdapter Capabilities / permissions UCAN-inspired, offline-verifiable

Infrastructure

Three CRDT-agnostic services β€” they only see encrypted bytes, never plaintext:

Service Transport Purpose
wot-relay WebSocket Real-time sync + delivery ACK
wot-vault HTTP Encrypted backup for new device restore
wot-profiles HTTP Public profile discovery (JWS-signed)

Data is also persisted locally in IndexedDB (CompactStore) for offline access.

CRDT Support

Package CRDT Runtime Notes
adapter-yjs Yjs Pure JavaScript (69KB) Default. Fast on all devices.
adapter-automerge Automerge Rust β†’ WASM (1.7MB) Alternative. Heavier on mobile.

Switch at startup with VITE_CRDT=automerge. Both pass the same 11 end-to-end tests. Try the in-browser benchmark to compare on your device.

Identity

  • BIP39 Mnemonic β€” 12-word recovery phrase (German wordlist)
  • Ed25519 β€” Signing (via @noble/ed25519)
  • X25519 β€” Key agreement (ECDH)
  • did:key β€” W3C Decentralized Identifier
  • HKDF Master Key β€” Non-extractable CryptoKey, hardware isolation when available
  • Encrypted seed storage β€” PBKDF2 (600k iterations) + AES-GCM in IndexedDB

End-to-End Encryption

All data is encrypted before it leaves the device. The relay server only sees ciphertext.

  • Symmetric: AES-256-GCM (CRDT updates, group content)
  • Asymmetric: X25519 ECIES (key exchange, 1:1 messages)
  • Envelope Auth: Ed25519-signed message envelopes
  • Group Keys: Per-space key with generation-based rotation

Three Sharing Patterns

  1. Group Spaces β€” CRDT-based collaboration (ReplicationAdapter)
  2. Selective Sharing β€” Item-level encryption keys
  3. 1:1 Delivery β€” Attestations, verifications via Relay

Getting Started

Prerequisites

  • Node.js 22+
  • pnpm 9+

Development

# Install dependencies
pnpm install

# Start demo app (default: Yjs)
pnpm dev:demo

# Start demo app with Automerge
VITE_CRDT=automerge pnpm dev:demo

# Start landing page
pnpm dev:landing

# Run tests
pnpm test              # all packages
pnpm test:e2e          # Playwright E2E tests

# Build
pnpm build:core

Monorepo Structure

web-of-trust/
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ wot-core/            # @web_of_trust/core β€” Core library
β”‚   β”œβ”€β”€ adapter-yjs/         # @web_of_trust/adapter-yjs β€” Yjs CRDT adapter (default)
β”‚   β”œβ”€β”€ adapter-automerge/   # @web_of_trust/adapter-automerge β€” Automerge CRDT adapter
β”‚   β”œβ”€β”€ wot-relay/           # WebSocket Relay Server (Node.js, SQLite)
β”‚   β”œβ”€β”€ wot-vault/           # Encrypted Document Store (HTTP, SQLite)
β”‚   └── wot-profiles/        # Public Profile Service (HTTP, SQLite, JWS)
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ demo/                # Demo App (React 19, i18n, Dark Mode)
β”‚   β”œβ”€β”€ benchmark/           # CRDT Benchmark (Yjs vs Automerge)
β”‚   └── landing/             # Landing Page
└── docs/                    # Architecture docs & specifications

Packages

Package Description Links
@web_of_trust/core Core library β€” identity, crypto, adapters, services npm
@web_of_trust/adapter-yjs Yjs CRDT adapter (default) β€” pure JS, 76x faster on mobile
@web_of_trust/adapter-automerge Automerge CRDT adapter — Rust→WASM
wot-relay WebSocket Relay Server β€” message forwarding, delivery ACK, SQLite
wot-vault Encrypted Document Store β€” append-only, capability auth, SQLite
wot-profiles Public Profile Service β€” JWS verification, REST API, SQLite

Quick Start (Code)

// Core β€” identity, crypto, messaging
import {
  WotIdentity,
  WebCryptoAdapter,
  HttpDiscoveryAdapter,
  WebSocketMessagingAdapter,
  OutboxMessagingAdapter,
  ProfileService,
  EncryptedSyncService,
  GroupKeyService,
} from '@web_of_trust/core'

// CRDT adapter β€” choose one
import { YjsReplicationAdapter } from '@web_of_trust/adapter-yjs'
// or: import { AutomergeReplicationAdapter } from '@web_of_trust/adapter-automerge'

// Create identity from 12 magic words
const identity = new WotIdentity()
await identity.create('my-passphrase', true)
console.log(identity.getDid()) // did:key:z6Mk...

Tests

Package Tests Framework
wot-core 392 Vitest 4.1.0
wot-relay 24 Vitest 4.1.0
wot-vault 27 Vitest 4.1.0
wot-profiles 25 Vitest 4.1.0
Demo (Unit) 59 Vitest 4.1.0
Demo (E2E) 7 Playwright
Total 534

All 11 E2E tests pass with both CRDT adapters (Yjs and Automerge).

Demo App Features

  • Onboarding β€” Create identity with 12 Magic Words + passphrase
  • Recovery β€” Restore identity from seed on any device
  • QR Verification β€” In-person identity verification via camera
  • Contacts β€” Manage verified contacts
  • Attestations β€” Attest skills/properties, receive, publish
  • Spaces β€” Encrypted group collaboration (CRDT)
  • Profile Sync β€” JWS-signed profiles published to wot-profiles
  • Public Profile β€” Viewable without login
  • Multi-Device β€” Sync via Relay + Vault
  • Offline-First β€” Local data, offline banner, outbox queue
  • i18n β€” German + English
  • Dark Mode β€” Fully supported
  • Debug Panel β€” Persistence metrics, relay status, CRDT info

Documentation

Note: Most specification documents are in German. The implementation status is documented in English in CURRENT_IMPLEMENTATION.md.

Document Description
Current Implementation What's built, what works, architecture decisions
NLNet Application Funding application (NGI Zero Commons Fund)
Adapter Architecture v2 7-adapter specification
Framework Evaluation 16 frameworks evaluated
DID Methods Comparison 6 DID methods evaluated (did:key confirmed)
Vault Sync Architecture Three sync patterns
Social Recovery Shamir Secret Sharing concept
Threat Model STRIDE analysis
Encryption Protocol E2E encryption design

Related Projects

  • Real Life Stack β€” Modular app toolkit for local communities, built on Web of Trust

Contributing

We're looking for:

  • Communities who want to try it
  • Feedback on UX and concept
  • Developers who want to build with us

License

AGPL-3.0

About

A digital infrastructure for real communities. Decentralized, encrypted, self-sovereign.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors