Authentication
Every request the SDK makes carries a JWT access token. This page covers the three ways to obtain that token, and how the SDK keeps it fresh without any work from you.
Password login
Section titled “Password login”The simplest path: exchange a username and password for a token pair. MeroJs
posts to the node’s /auth/token endpoint, stores the returned tokens in memory
(and in your tokenStore, if provided), and attaches the access
token to every subsequent request.
import { MeroJs } from '@calimero-network/mero-js';
const sdk = new MeroJs({ baseUrl: 'http://localhost:2428' });
await sdk.authenticate({ username: 'admin', password: 'your-password' });// sdk.isAuthenticated() === trueYou can also set credentials once in the constructor; they’re used the first time a token is needed:
const sdk = new MeroJs({ baseUrl: 'http://localhost:2428', credentials: { username: 'admin', password: 'your-password' },});await sdk.authenticate(); // uses config.credentialsThe token lifecycle — refresh is automatic
Section titled “The token lifecycle — refresh is automatic”The SDK is reactive: it never proactively refreshes (the node rejects a
refresh while the access token is still valid). Instead, when a request comes
back 401 with x-auth-error: token_expired, the transport refreshes the token
and retries the original request — transparently. Your code only ever sees the
successful result.
Refresh tokens are single-use, so concurrent 401s are deduplicated: the
refresh runs once (guarded by an in-process promise and a Web Lock named
mero-js:token-refresh), and every waiting request retries with the one rotated
token.
Desktop SSO — tokens from the URL hash
Section titled “Desktop SSO — tokens from the URL hash”When your app is opened from Calimero Desktop, the desktop process appends
the tokens to the URL hash instead of asking the user to log in again. Read them
with parseAuthCallback() and apply them with setTokenData().
import { MeroJs, parseAuthCallback } from '@calimero-network/mero-js';
const auth = parseAuthCallback(window.location.hash);if (auth) { // auth.nodeUrl, auth.accessToken, auth.refreshToken, // auth.applicationId, auth.contextId, auth.contextIdentity const sdk = new MeroJs({ baseUrl: auth.nodeUrl }); sdk.setTokenData({ access_token: auth.accessToken, refresh_token: auth.refreshToken, expires_at: 0, // 0 → the SDK reads the exp claim from the JWT itself });
// Strip the tokens from the URL bar (security best practice) history.replaceState(null, '', location.pathname);}The hash fragment format is:
#access_token=…&refresh_token=…&node_url=…&application_id=…&context_id=…&context_identity=…parseAuthCallback is also available as a static method,
MeroJs.parseAuthCallback(url).
The login-redirect flow
Section titled “The login-redirect flow”To start an interactive login (rather than receive a callback), build the
node’s login URL and redirect the browser to it. After the user authenticates,
the node redirects back to your callbackUrl with the token hash above.
import { MeroJs, buildAuthLoginUrl } from '@calimero-network/mero-js';
const url = buildAuthLoginUrl('http://localhost:2428', { callbackUrl: window.location.origin + '/callback', mode: 'login', permissions: ['admin'], packageName: 'my-app',});window.location.href = url;Persistence
Section titled “Persistence”Pass a tokenStore and the SDK persists tokens on login/refresh and restores
them on construction — so a reload stays signed in.
import { MeroJs, LocalStorageTokenStore, MemoryTokenStore } from '@calimero-network/mero-js';
// Browser — survives reloadsconst sdk = new MeroJs({ baseUrl: 'http://localhost:2428', tokenStore: new LocalStorageTokenStore('my-app-tokens'), // default key: 'mero-tokens'});
// Server / ephemeral — no side effects (this is also the default)const server = new MeroJs({ baseUrl: 'http://localhost:2428', tokenStore: new MemoryTokenStore(),});Implement the TokenStore interface (getTokens / setTokens / clear) to
back tokens with anything else — see the reference.
Inspecting and clearing auth state
Section titled “Inspecting and clearing auth state”sdk.isAuthenticated(); // boolean — are tokens present?sdk.getTokenData(); // TokenData | null (useful for debugging)sdk.clearToken(); // drop tokens from memory and the store (sign out)