Skip to main content

Auth API

The Auth API provides 6 methods for authenticating users via email OTP or wallet signature, refreshing sessions, fetching the current user, and signing out.

Methods

MethodParametersReturnsDescription
sendEmailOtp(email)email: stringApiResponse<{ sent: boolean }>Sends a one-time password to the given email address.
verifyEmailOtp(email, otp)email: string, otp: stringApiResponse<EngineAuthResponse>Verifies the OTP and returns tokens plus user profile.
authWithWallet(walletAddress, signature, message)walletAddress: string, signature: string, message: stringApiResponse<EngineAuthResponse>Authenticates via a signed message from the user's wallet.
refreshToken(refreshToken)refreshToken: stringApiResponse<EngineAuthResponse>Exchanges a refresh token for a new access/refresh token pair.
getCurrentUser()--ApiResponse<User>Returns the profile of the currently authenticated user.
signOut()--ApiResponse<{ success: boolean }>Invalidates the current session on the server.

Types

EngineAuthResponse

interface EngineAuthResponse {
/** JWT access token. Pass to engine.setAccessToken(). */
accessToken: string;
/** Refresh token for obtaining new access tokens. */
refreshToken: string;
/** Access token expiry in seconds from now. */
expiresIn: number;
/** Authenticated user profile. */
user: User;
}

User

interface User {
id: string;
email?: string;
walletAddress?: string;
displayName?: string;
avatarUrl?: string;
role: 'user' | 'admin';
createdAt: string;
updatedAt: string;
}

Email OTP Flow

Step 1 -- Send OTP

const res = await engine.sendEmailOtp('user@example.com');

if (res.success) {
console.log('OTP sent');
} else {
console.error('Failed to send OTP:', res.error);
}

Step 2 -- Verify OTP

const authRes = await engine.verifyEmailOtp('user@example.com', '482901');

if (authRes.success && authRes.data) {
// Store tokens
engine.setAccessToken(authRes.data.accessToken);
// Persist refresh token for later
await secureStore.set('refreshToken', authRes.data.refreshToken);
console.log('Welcome', authRes.data.user.displayName);
}

Wallet Signature Flow

// 1. Generate a sign-in message (app-defined)
const message = `Sign in to ONE\nNonce: ${crypto.randomUUID()}`;

// 2. Have the user sign the message with their wallet
const signature = await walletClient.signMessage({ message });

// 3. Send to the engine for verification
const authRes = await engine.authWithWallet(
walletClient.account.address,
signature,
message
);

if (authRes.success && authRes.data) {
engine.setAccessToken(authRes.data.accessToken);
}

Token Refresh

Access tokens expire after expiresIn seconds. Use the refresh token to obtain new credentials without requiring the user to re-authenticate.

const stored = await secureStore.get('refreshToken');
const res = await engine.refreshToken(stored);

if (res.success && res.data) {
engine.setAccessToken(res.data.accessToken);
await secureStore.set('refreshToken', res.data.refreshToken);
}

Get Current User

Fetch the authenticated user's profile at any time:

const userRes = await engine.getCurrentUser();

if (userRes.success && userRes.data) {
console.log('User ID:', userRes.data.id);
console.log('Email:', userRes.data.email);
console.log('Role:', userRes.data.role);
}

Sign Out

Invalidate the current session server-side:

const res = await engine.signOut();

if (res.success) {
// Clear local state
engine.setAccessToken('');
await secureStore.delete('refreshToken');
}

Error Cases

Scenarioerror String
Invalid or expired OTP"invalid_otp"
Email not found"user_not_found"
Invalid wallet signature"invalid_signature"
Expired refresh token"token_expired"
No access token set"unauthorized"

Next Steps