Ten minutes, end to end
There is a runnable version of all of this:
git clone https://github.com/rishabhshuklax/skm && cd skmnpm cinpm run build && npm run exampleIt stands up a relay, links a second device without moving a private key, shares a graph with another member, rejects a forged author, rotates a stolen laptop out, and then prints what the relay’s database actually holds.
The server
Section titled “The server”import Fastify from 'fastify';import { openDb, registerRelay, SqliteDirectory } from '@skm/relay';
const db = openDb('data/relay.db');const app = Fastify();
await registerRelay(app, { db, directory: new SqliteDirectory(db), authenticate: async (req) => { const session = await mySessions.verify(req); // The token must name the member AND the device it was issued to. return session ? { memberId: session.userId, deviceId: session.deviceId } : null; },});
await app.listen({ port: 8787 });The device
Section titled “The device”import { SkmEngine, HttpTransport, bestStore, IdbKeyStore, defineKinds } from '@skm/client';import { z } from 'zod';
const engine = await SkmEngine.open({ memberId: me.id, deviceId: localStorage.getItem('skm-device') ?? SkmEngine.newDeviceId(), transport: new HttpTransport({ baseUrl: '/api/skm', credentials: 'same-origin' }), store: await bestStore({ name: me.id }), keyStore: new IdbKeyStore(), kinds: defineKinds({ note: z.object({ body: z.string().max(10_000) }), task: z.object({ title: z.string(), done: z.boolean() }), }),});
await engine.openGraph('u', { create: true }); // my own graphengine.startAutoSync();
await engine.put('u', { kind: 'note', data: { body: 'hello' } });const notes = await engine.listKind('u', 'note'); // typed, local, instantThat is a working end-to-end encrypted app. Everything below is detail.