Architecture
How the SDK is structured — HttpClient, API clients, token lifecycle, and event streams
Layered Design
The SDK is a thin composition of focused clients. MeroJs is the entry point — it owns the HTTP transport and lazily initialises the specialised clients behind property accessors.
Layer 1 — Transport
Layer 2 — API Clients
Layer 3 — Event Streams
Layer 4 — Token Store
Token Lifecycle
The SDK manages JWT tokens reactively — it never proactively refreshes, only reacts to 401 responses.
Authenticate
Call sdk.authenticate() to exchange username + password for an access token and refresh token. Tokens are stored in memory (and in the tokenStore if provided).
Request
Every request reads the current access token and injects it as Authorization: Bearer <token>. The JWT exp claim is parsed to track expiry.
401 → Refresh
When the server returns 401, the HttpClient calls performTokenRefresh() transparently, retries the original request with the new token, and updates the store. Multiple concurrent 401s are deduplicated via a shared refreshPromise.
// 1. Request with access_token → 401
// 2. POST /api/v1/identity/refresh-token
// 3. Store new access_token + refresh_token
// 4. Retry original request with new token
SSO Integration
When your app is opened from Calimero Desktop, the desktop process appends auth tokens to the URL hash. The SDK reads them with parseAuthCallback() and bypasses the normal login flow:
// https://my-app.example.com/#access_token=...&refresh_token=...&node_url=...&application_id=...&context_id=...&context_identity=...
const auth = parseAuthCallback(window.location.hash);
if (auth) {
sdk.setTokenData({ access_token: auth.accessToken, refresh_token: auth.refreshToken, expires_at: 0 });
// expires_at = 0 triggers JWT exp parsing automatically
}
Lazy Initialisation
RpcClient, SseClient, and WsClient are created on first access — no cost if unused:
sdk.rpc // RpcClient (lazy)
sdk.events // SseClient (lazy)
sdk.ws // WsClient (lazy, experimental)
// Always available:
sdk.auth // AuthApiClient
sdk.admin // AdminApiClient
Zero Dependencies
The SDK is built on Web Platform APIs only: