Skip to content

Rust

Draft

capsule-sdk is the sanctioned network path for every Capsule client: the upload protocol, sync and download, and the authentication flows. The CLI and TUI link it directly; the Swift and Kotlin bindings are its ffi feature, generated by uniffi. The crate is not published, so its item-level reference is the workspace rustdoc described under Crates. This page is the map to read that rustdoc with.

The typed REST client, capsule_sdk::rest, is generated at build time by spargen from the committed capsule-server/openapi.json: one async method per operation, with typed models and typed errors. It is documented once, as the REST API reference, rather than a second time here.

What the crate writes by hand is orchestration over those generated calls, never a second parser:

  • upload drives the resumable upload state machine, the one protocol too stateful for request-and-response generation. Its contract is Transfer — Upload.
  • sync drives the cursor and anti-rewind state machine over the generated GET /v1/sync operation. Its contract is Sync.
  • directory, upgrade and the receipt fetch in verify are the application/cbor operations the generator cannot lower yet.

A caller authenticates once and then makes typed calls; it never handles a raw token. AuthenticatedClient, in the client module, wraps the generated rest::Client and composes it with the auth session store. Before a request leaves, it refreshes a token that is close to expiry. When the server refuses a token anyway (a revocation, or two clocks that disagree), it refreshes once and replays the request once. A 401 that refuses a credential, such as a wrong password or second-factor code, is returned unchanged. Concurrent refreshes coalesce into one. The model is Authentication.

--features ffi compiles the uniffi-annotated surface the native apps drive: FfiCapsuleClient and FfiSession for the networked flows, FfiWorkspace for the local workspace verbs, and the hardware-signer and key-agreement traits a platform implements. The feature is off by default, so the workspace, the CLI and the server never compile it. mise run gen-bindings builds the feature and generates both languages from the compiled library.