Peer SDK v2 and a rebuilt developer portal
Peer SDK v1 had one good idea: every peer is a VaultysID, addressed by its DID, and two peers prove who they are to each other before they talk. Almost everything around that idea got in your way. You told us, and a full review of the published 1.0.1 package confirmed it.
v2 is the answer. It's a rewrite, and the developer portal was rebuilt with it. This post goes through what you reported, what changed, and what's still missing.
What you told us
The reports fell into four groups.
It didn't install cleanly. v1.0.1 couldn't be loaded by Node.js at all: require() and import both failed with ERR_MODULE_NOT_FOUND. Its runtime dependencies (peerjs, yjs, msgpack and others) were only listed as dev dependencies, and the main entry pulled in fs and path, so browser apps needed Node polyfills.
Identity was trusted before it was verified. This was the serious one. An incoming connection's DID came from what the caller claimed. Messages could flow, and be attributed to a DID, before the handshake finished. Anyone could connect, and the identity's secret key was written in clear text to storage.
Offline delivery wasn't durable. The "pending messages" queue lived in memory and was lost on reload. Sending never opened a connection by itself, so messages to a peer you hadn't connected to manually waited forever. There were no delivery receipts.
The docs described an SDK that didn't exist. The README and the old portal showed calls like setupVaultysPeerSDK() with no identity and sdk.connect(), which didn't match the package. Some pages also made security claims the code didn't back up.
What changed in v2
One entry point, and the identity comes from you
import { createPeer, indexedDBStore } from "@vaultys/peer-sdk";
import { peerjsTransport } from "@vaultys/peer-sdk/peerjs";
const peer = await createPeer({
identity, // a VaultysId you created and stored yourself
transport: peerjsTransport(),
store: indexedDBStore(),
});
await peer.contacts.add(bobDid, { name: "Bob" });
await peer.send(bobDid, { text: "Hello, Bob" });
peer.on("message", ({ from, body }) => console.log(from, body));
PeerService, VaultysPeer, the event bus and the setup helpers are gone. createPeer() gives you contacts, messages, custom protocols and typed events. The SDK never stores your identity's secret. Where you keep it is your decision, and the quickstart shows one way.
Nothing flows before the handshake
A session only exists once the mutual VaultysID handshake has succeeded. There's no "connected but not yet verified" state to forget about. The from on a message is the DID the sender proved, not the one it claimed.
Every frame after the handshake is encrypted with a per-session key that only the two identities can derive, so the relay that introduces peers can't read or alter traffic. The security model explains exactly how, and also what isn't covered yet.
Strangers are refused by default
Only your contacts can connect to you. To accept other peers, pass an acceptIncoming policy, and it will only ever see DIDs that have already been proven.
Messages survive reloads
send() writes the message to your store, opens a connection if needed, retries until the recipient is reachable, and emits delivered when the other side acknowledges it. With indexedDBStore() or fileStore() on Node, undelivered messages survive a reload or a restart.
It loads everywhere
v2 ships ESM and CommonJS builds with declared dependencies. The core depends only on msgpack. Transports, collaboration and Node helpers are separate entry points, so you only install what you use:
| Import | For |
|---|---|
@vaultys/peer-sdk | createPeer, stores, the in-memory network for tests |
@vaultys/peer-sdk/peerjs | WebRTC through a PeerJS relay |
@vaultys/peer-sdk/yjs | Shared documents and presence with Yjs |
@vaultys/peer-sdk/node | File store and WebRTC for Node.js |
memoryNetwork() also lets you run two peers in one script with no relay, which makes unit tests deterministic.
A portal built around code that runs
The old portal had grown pages for an API that never shipped. We removed them and rewrote the rest against v2:
- Concepts: identity and trust, sessions and transports, delivery, and a security model that says what isn't protected as plainly as what is.
- Guides: messaging, custom protocols, collaboration with Yjs, storage, relays, Node.js and testing.
- Migrating from v1: a side-by-side example, a full API mapping, and the behavior changes that will catch you out.
- Playground: create an identity, then open a second tab and try P2P chat, a shared canvas, or an M-of-N launch ceremony where several identities must sign before anything happens.
The homepage now separates the two products: VaultysID for identity on its own, and the Peer SDK when identities need to exchange data directly.
What's not there yet
- v2 isn't on npm. It's a pre-release (
2.0.0-alpha).npm install @vaultys/peer-sdkstill gives you v1. Until we publish, build it from source and link it. - v1 and v2 peers can't talk to each other. The handshake and wire format changed, so upgrade every app that communicates together.
- Data isn't migrated. Contacts have to be re-added, and v1 message history isn't read.
- No forward secrecy yet. Session keys mix in the static identity keys. Ephemeral key exchange is planned.
- Calls aren't in v2.0.
makeCalland friends from v1 have no replacement yet. - Groups are up to you. Keep the member list in your app and send to each member.
Keep the reports coming
Most of what changed in v2 started as an issue or a message from someone who hit a wall. If something in the docs doesn't match what the code does, that's a bug. Tell us on GitHub or Discord.
To get started, try the quickstart. It takes you to two peers exchanging a verified, encrypted message in a few minutes.