Package-level declarations

Types

Link copied to clipboard
data class AccountConfig(var directory: String, var relay: String, var accounts: String, var provisioning: String, var identifier: String, var device: UByte)

Where to reach a server's account endpoints, plus the credentials to sign in with. Addresses are host:port strings. Used by the account flow (Client.signIn), which signs in and provisions this device under the account's handle (e.g. acme/alice).

Link copied to clipboard
data class Address(var user: String, var device: UInt)

A device's routing address.

Link copied to clipboard

A connected client: one signed-in user on one device. Every call is async. The calls take turns on the client, but a pending receive waits for mail outside that turn, so a send on the same client from another task goes through meanwhile. The Config/AccountConfig constructors below are the address layer under the `Tenant` handle, for callers that know their addresses.

Link copied to clipboard
sealed class ClientException : Exception

Anything that can go wrong, as one case per kind an app can branch on: the same kinds as every other head (decision 0090). Swift sees an enum with a reason on each case; Kotlin a sealed exception class with one subclass per kind. A case may be added, so switch with a default.

Link copied to clipboard
interface ClientInterface

A connected client: one signed-in user on one device. Every call is async. The calls take turns on the client, but a pending receive waits for mail outside that turn, so a send on the same client from another task goes through meanwhile. The Config/AccountConfig constructors below are the address layer under the `Tenant` handle, for callers that know their addresses.

Link copied to clipboard
data class Config(var directory: String, var relay: String, var user: String, var device: UByte)

Where to reach a Tacenta server, and who to connect as. Addresses are host:port strings. This is the pre-account path — register directly under a raw handle; for the account flow use `AccountConfig` with Client.signIn.

Link copied to clipboard
data class Contact(var address: Address)

A resolved contact: another user's addressable handle, from Client.find.

Link copied to clipboard
interface Disposable
Link copied to clipboard

A client's inbound messages one at a time, from Client.inbound: each next is the next message in the order the relay delivered it, awaiting mail when nothing is buffered. It is receive flattened, on the same single-flight wait underneath. Swift iterates it as an AsyncSequence (for try await message in client.inbound()), Kotlin collects asFlow(); both are thin hand-written wrappers over next. It holds the client, so a loop over it keeps the client alive, and releasing both ends the wait. A message goes to whichever next is waiting, so run one loop per client.

Link copied to clipboard

A client's inbound messages one at a time, from Client.inbound: each next is the next message in the order the relay delivered it, awaiting mail when nothing is buffered. It is receive flattened, on the same single-flight wait underneath. Swift iterates it as an AsyncSequence (for try await message in client.inbound()), Kotlin collects asFlow(); both are thin hand-written wrappers over next. It holds the client, so a loop over it keeps the client alive, and releasing both ends the wait. A message goes to whichever next is waiting, so run one loop per client.

Link copied to clipboard
Link copied to clipboard
data class Message(var from: Address, var plaintext: ByteArray)

A decrypted inbound message and the device that sent it.

Link copied to clipboard

What the sign-in found (BR-15): whether the sessions a restored state carried are in use, or were discarded because the state was older than one already seen. Read it with Client.restoreOutcome after any sign-in.

Link copied to clipboard
interface SecureStore

Platform secure storage that holds the wrapping key for sealed state (decision 0078, anchor B). Implemented on the foreign side — iOS/macOS Keychain, Android Keystore — so the key lives where an attacker who can rewrite the state file cannot reach it. That separation is the whole of what sealing is worth: without it, an attacker who rewrites the blob rewrites the key too and the authenticator proves nothing.

Link copied to clipboard

Platform secure storage that holds the wrapping key for sealed state (decision 0078, anchor B). Implemented on the foreign side — iOS/macOS Keychain, Android Keystore — so the key lives where an attacker who can rewrite the state file cannot reach it. That separation is the whole of what sealing is worth: without it, an attacker who rewrites the blob rewrites the key too and the authenticator proves nothing.

Link copied to clipboard

One tenant's handle (decision record 0090): built from the API key and the server's name, it fetches the server's service document once to learn where the services are, and signs users up and in. Nothing above it sees a host or a port. Named Tenant on these heads (see the crate documentation); the same object is Tacenta in Rust and TypeScript.

Link copied to clipboard
interface TenantInterface

One tenant's handle (decision record 0090): built from the API key and the server's name, it fetches the server's service document once to learn where the services are, and signs users up and in. Nothing above it sees a host or a port. Named Tenant on these heads (see the crate documentation); the same object is Tacenta in Rust and TypeScript.

Functions

Link copied to clipboard
fun Inbound.asFlow(): Flow<Message>

This inbound's messages as a Flow: one at a time, as they arrive, from the generated next. It ends only by throwing; cancelling the collector ends it too.

Link copied to clipboard
suspend fun signUp(accounts: String, apiKey: String, username: String, password: String)

Sign up a new user under a tenant. A control-plane action — create the account, then Client.signIn for a connected client. accounts is the account service host:port; apiKey scopes it to the tenant.

Link copied to clipboard
suspend fun signUpTls(accounts: String, serverName: String, apiKey: String, username: String, password: String)

Sign up a new user over TLS to a server presenting serverName, trusting the public web PKI: the address layer's TLS sibling of `sign_up`. An app uses Tenant.signUp, which finds the address itself.