Skip to Content
⚙️ Core SDKAuthentication

Authentication

JWT token management, login flows, and authenticated requests with @embarkai/core/auth.

The auth module handles the full authentication lifecycle: logging in via multiple providers, managing JWT tokens with automatic refresh, and making authenticated API requests.

Configuration

Configure the JWT module with your TSS service URL and (optionally) a project ID. The module manages tokens via a singleton jwtTokenManager with its own storage; pick storage explicitly only when you create a custom manager (see JwtTokenManager below).

import { configureJwtModule } from '@embarkai/core' configureJwtModule({ tssUrl: 'https://api.embarkai.io', projectId: 'your-project-id', // optional })

In React apps, Provider from @embarkai/ui-kit calls configureJwtModule for you — don’t call it manually in frontend code.

Login Methods

Login with User ID

The simplest login method — authenticates directly with a user identifier:

import { loginWithUserId } from '@embarkai/core' const response = await loginWithUserId('user_abc123') console.log('Access Token:', response.accessToken) console.log('Has Keyshare:', response.hasKeyshare) console.log('Is New User:', response.isNewUser)

Login with Email

Two-step email verification flow:

import { loginWithEmail } from '@embarkai/core' // Step 1: Request a verification code (sent to user's inbox) // Step 2: Submit the code const response = await loginWithEmail('user@example.com', '123456') console.log('User ID:', response.userId)

Login with Telegram

Authenticate using Telegram login widget data:

import { loginWithTelegram } from '@embarkai/core' const response = await loginWithTelegram({ id: 123456789, first_name: 'Alice', last_name: 'Doe', // optional username: 'alice', // optional photo_url: 'https://...', // optional auth_date: 1700000000, hash: 'telegram_auth_hash...', }) // Suppress automatic token persistence (useful for server-side flows) await loginWithTelegram(telegramData, { skipTokenSave: true })

All login helpers (loginWithUserId, loginWithEmail, loginWithTelegram) accept an optional { skipTokenSave?: boolean } second argument.

Login Response

All login methods return a LoginResponse:

FieldTypeDescription
accessTokenstringShort-lived JWT for API calls
refreshTokenstringLong-lived token for refreshing access
userIdstringUnique user identifier
expiresInnumberToken TTL in seconds
hasKeysharebooleanWhether the user has a TSS keyshare on the server
isNewUserboolean | undefinedtrue on first login
avatarstring | nullUser avatar URL
displayNamestring | nullUser display name
providersstring[]Linked auth providers

Token Management

JwtTokenManager

The JwtTokenManager class stores tokens and handles automatic refresh. Use the singleton or create your own instance:

import { jwtTokenManager, createJwtTokenManager, MemoryStorage } from '@embarkai/core' // Singleton (uses built-in default storage) const isLoggedIn = await jwtTokenManager.isAuthenticated() const header = await jwtTokenManager.getAuthHeader() // → { Authorization: 'Bearer eyJ...' } // Custom instance with explicit storage backend const manager = createJwtTokenManager(new MemoryStorage())

Key methods:

MethodReturnsDescription
getAccessToken()Promise<string | null>Current access token
getRefreshToken()Promise<string | null>Current refresh token
getUserId()Promise<string | null>Authenticated user ID
isTokenExpired()Promise<boolean>Check if access token is expired
isAuthenticated()Promise<boolean>Check if user has valid tokens
refreshAccessToken()Promise<JwtTokens>Force a token refresh
getAuthHeader()Promise<object>Get Authorization header object
clearTokens()Promise<void>Remove all stored tokens

Token Storage

Implement the TokenStorage interface for custom storage backends:

import type { TokenStorage } from '@embarkai/core' class SecureStorage implements TokenStorage { async getItem(key: string): Promise<string | null> { return await encrypted.get(key) } async setItem(key: string, value: string): Promise<void> { await encrypted.set(key, value) } async removeItem(key: string): Promise<void> { await encrypted.delete(key) } }

Built-in adapters: LocalStorageAdapter (browser localStorage) and MemoryStorage (in-memory, non-persistent — pass it to createJwtTokenManager(new MemoryStorage()) for tests or server-side flows).

Utility Functions

Verify a Token

import { verifyToken } from '@embarkai/core' const result = await verifyToken() if (result.valid) { console.log('User:', result.userId) console.log('Session:', result.sessionId) console.log('Has Keyshare:', result.hasKeyshare) }

Ensure Valid Token

Automatically refreshes the token if expired. Throws if refresh fails:

import { ensureValidToken } from '@embarkai/core' await ensureValidToken() // Access token is now guaranteed to be valid

Get Valid Tokens

Returns current tokens, refreshing first if needed:

import { getValidTokens } from '@embarkai/core' const tokens = await getValidTokens() console.log('User:', tokens.userId) console.log('Expires at:', new Date(tokens.expiresAt * 1000))

Authenticated Fetch

A drop-in wrapper around fetch that injects the Authorization header and auto-refreshes expired tokens:

import { authenticatedFetch } from '@embarkai/core' const res = await authenticatedFetch('https://api.lumiapassport.com/me') const user = await res.json()

Logout

Clears all stored tokens:

import { logout } from '@embarkai/core' await logout()

Sync Keyshare Status

Re-checks whether the server holds a keyshare for the current user and updates stored token metadata:

import { syncKeyshareStatus } from '@embarkai/core' await syncKeyshareStatus()

Next Steps

  • Server Wallets — create and manage MPC wallets after authentication
  • Vault Backup — back up keyshares with password encryption
  • Bundler — submit UserOperations with authenticated sessions
Last updated on