Session Management
Token lifecycle, automatic refresh, session reconnection, and device key management
Session Management
The Nero MPC SDK handles the complete lifecycle of authenticated sessions: token storage, automatic refresh, session status tracking, and device identification.
Token Structure
The SDK manages three token types:
| Token | Purpose | Lifetime | Storage |
|---|---|---|---|
accessToken | API authentication | Short-lived (15-60 min) | Encrypted |
refreshToken | Obtain new access tokens | Long-lived (days/weeks) | Encrypted |
dappShare | Session reconnection | Persistent | Encrypted |
An expiresAt timestamp (in milliseconds) indicates access token expiration.
Token Storage and Encryption
Tokens are encrypted using the device key via AES-256-GCM before storage. The default storage key is nero:tokens, customizable through the storagePrefix configuration option.
Token Management Methods
| Class | Method | Purpose |
|---|---|---|
NeroMpcSDK | storeTokens(tokens) | Encrypt and persist tokens |
NeroMpcSDK | loadStoredTokens() | Load and decrypt tokens |
NeroMpcSDK | clearStoredTokens() | Remove tokens from storage |
APIClient | setTokens(tokens) | Set tokens in memory |
APIClient | getTokens() | Retrieve current tokens |
APIClient | clearTokens() | Clear tokens from memory |
Automatic Token Refresh
The SDK automatically refreshes access tokens before expiration to maintain uninterrupted sessions.
Token expiry checking occurs on every authenticated request with a 60-second trigger threshold before expiration. The SDK uses a refreshPromise member to prevent concurrent refresh attempts. If refresh fails, tokens are cleared and the SDK transitions to an unauthenticated state.
The refresh endpoint is POST /api/v2/session/refresh via SessionAPI.refresh().
const sdk = new NeroMpcSDK({ backendUrl: "..." });
await sdk.init();
if (sdk.isAuthenticated) {
// Session restored and tokens will auto-refresh
}Session Status and Reconnection
Checking Status
The getSessionStatus() method queries the backend via SessionAPI.status(), returning a SessionStatus object containing active session information including expiration and associated devices.
Session Reconnection
Session reconnection restores a session using the dappShare token. This is useful for cross-device scenarios or storage migration.
Parameters:
dappShare(optional): The dApp share token; uses stored token if not provided
Returns SessionReconnectResult containing:
tokens: New access and refresh tokensuser: User informationsessionLifetime: Session duration in seconds
Device Key Lifecycle
Device keys serve as persistent device identifiers and encryption keys for local token storage.
Key properties:
- Generated via
crypto.getRandomValues()producing random hex strings - Storage priority: IndexedDB > localStorage > in-memory (ephemeral)
- Automatic migration from localStorage to IndexedDB when available
- Storage key:
nero:device_key(customizable viastoragePrefix)
Resolution Sequence
On initialization, the SDK loads or generates a stable per-device encryption key:
- IndexedDB under key
"device_key" - Legacy localStorage fallback under
"{storagePrefix}:device_key" - New cryptographically random key generation if neither exists
The device key is registered with APIClient via setDeviceId() and passed to ClientKeyManager.
Device Fingerprinting
A DeviceFingerprint object is created during authentication containing navigator.userAgent for browser/platform identification. This fingerprint is sent as deviceId for security tracking.
Session Initialization Sequence
During sdk.init(), the SDK performs:
- Load or generate device key
- Initialize
ClientKeyManagerwith device key - Load stored tokens from encrypted storage
- If tokens exist, validate by fetching current user via
getCurrentUser() - If valid, initialize wallet and emit
'initialized' - If invalid, clear tokens and emit
'initialized'
Session Termination
Logout Process
The logout() method terminates sessions with comprehensive cleanup:
- Revoke dApp share session via
SessionAPI.revoke() - Call backend logout endpoint via
AuthAPI.logout()(POST /api/v2/auth/logout) - Clear all in-memory state variables
- Reset connection state machine
- Clear tokens from memory and storage
- Disconnect EIP-1193 provider
- Disconnect WebSocket client
- Emit
'logout'event
Key shares stored by ClientKeyManager are preserved during logout, allowing future recovery and reconnection.
Disconnect vs Logout
| Method | Session State | Tokens | Key Shares | Provider |
|---|---|---|---|---|
disconnect() | Cleared | Cleared | Preserved | Disconnected |
logout() | Cleared | Cleared | Preserved | Disconnected |
The disconnect() method internally calls logout() for consistent cleanup.
Session Events
The SDK emits events throughout the session lifecycle:
| Event | Trigger | Data |
|---|---|---|
initialized | SDK initialization complete | undefined |
login | User authenticated | { user: User } |
logout | Session terminated | undefined |
connected | Provider connected | { chainId: number } |
disconnected | Provider disconnected | undefined |
sdk.on('login', ({ user }) => {
console.log(`User logged in: ${user.id}`);
});
sdk.on('logout', () => {
console.log('Session terminated');
});
sdk.on('initialized', () => {
console.log('SDK ready');
});Session State Properties
The SDK exposes session state through computed properties:
| Property | Type | Description |
|---|---|---|
isAuthenticated | boolean | True if user is set and apiClient has tokens |
isLoggedIn | boolean | Alias for isAuthenticated |
user | User | null | Current authenticated user object |
state | NeroSDKState | Complete SDK state including session info |