Files
quicproquo/docs/sdk/typescript.md
Christian Nennemann cbb76af6b1 docs(sdk): add comprehensive SDK documentation and wire format reference
Covers all official SDKs (Rust, Go, Python, TypeScript, C FFI),
the v2 wire format with method ID tables, authentication flow,
and a build-your-own-SDK guide with implementation checklist.
2026-03-04 20:55:24 +01:00

3.7 KiB

TypeScript SDK

The TypeScript SDK provides a browser-compatible client with WASM-based crypto.

Location: sdks/typescript/

Installation

npm install quicproquo

Quick Start

import { QpqClient } from "quicproquo";

// Connect via WebSocket bridge
const client = await QpqClient.connect({
  addr: "ws://127.0.0.1:5002",
});

const status = await client.health();
console.log("Server:", status);

// Set session token (obtained via OPAQUE externally)
client.setSessionToken(token);

// Resolve user
const peerKey = await client.resolveUser("bob");

// Create channel
const { channelId, wasNew } = await client.createChannel(peerKey);

// Send message
const seq = await client.send(peerKey, new TextEncoder().encode("hello"));

// Receive messages
const messages = await client.receive(myKey);
for (const msg of messages) {
  console.log(`[${msg.seq}] ${new TextDecoder().decode(msg.data)}`);
}

client.close();

Offline Crypto

The SDK includes WASM-compiled crypto primitives that work without a server:

const client = await QpqClient.offline();

// Ed25519 identity
const { seed, publicKey } = client.generateIdentity();
const sig = client.sign(seed, message);
const valid = client.verify(publicKey, message, sig);

// Hybrid KEM (X25519 + ML-KEM-768)
const kp = client.hybridGenerateKeypair();
const ciphertext = client.hybridEncrypt(kp.publicKey, plaintext);
const decrypted = client.hybridDecrypt(kp.blob, ciphertext);

// Safety numbers
const safetyNumber = client.computeSafetyNumber(keyA, keyB);

// Sealed sender
const sealed = client.seal(seed, payload);
const unsealed = client.unseal(sealed);

// Message padding
const padded = client.padMessage(data);
const unpadded = client.unpadMessage(padded);

API

RPC Methods

Method Description
QpqClient.connect(opts) Connect via WebSocket
QpqClient.offline() Crypto-only mode
client.health() Health check
client.resolveUser(username) Look up identity key
client.createChannel(peerKey) Create DM channel
client.send(recipientKey, payload) Send message
client.sendWithTTL(recipientKey, payload, ttl) Disappearing message
client.receive(recipientKey) Fetch messages
client.deleteAccount() Delete account
client.close() Disconnect

Crypto Methods

Method Description
client.generateIdentity() Generate Ed25519 keypair
client.identityPublicKey(seed) Derive public key
client.sign(seed, message) Ed25519 sign
client.verify(publicKey, message, sig) Ed25519 verify
client.hybridGenerateKeypair() Generate hybrid keypair
client.hybridEncrypt(pk, plaintext) Hybrid encrypt
client.hybridDecrypt(blob, ciphertext) Hybrid decrypt
client.computeSafetyNumber(keyA, keyB) Safety number
client.seal(seed, payload) Sealed sender
client.unseal(envelope) Unseal
client.padMessage(data) Pad message
client.unpadMessage(data) Unpad message

Architecture

The TypeScript SDK uses a WebSocket bridge proxy because browsers cannot open raw QUIC connections. The bridge translates JSON-over-WebSocket to Cap'n Proto RPC:

Browser  ─── WebSocket ───►  Bridge Proxy  ─── QUIC/capnp ───►  Server

Crypto operations (Ed25519, hybrid KEM, sealed sender) run entirely in WASM, compiled from the Rust quicproquo-core crate.

Structure

File Purpose
src/client.ts High-level client API
src/transport.ts WebSocket transport with auto-reconnect
src/crypto.ts WASM crypto bindings
src/types.ts TypeScript interfaces
wasm-crypto/ Rust WASM crypto source