Authentication
Learn how to authenticate users with passkeys using @oviato/sdk
@oviato/sdk provides three authentication methods: smart authentication, explicit login, and explicit registration. This guide covers all authentication flows.
Authentication Methods
Smart Authentication (Recommended)
The authenticate() function automatically detects whether the user is new or returning:
import { authenticate } from "@oviato/sdk";
const result = await authenticate({
username: "alice", // optional: pre-fill username
});
if (result.status === "success") {
console.log("Connected:", result.data.address);
console.log("Username:", result.data.username);
console.log("Network:", result.data.network);
}When to use: Most of the time. This provides the best user experience.
Explicit Login
For returning users who already have a passkey:
import { login } from "@oviato/sdk";
const result = await login({
username: "alice", // optional: pre-fill username
});
if (result.status === "success") {
console.log("Logged in:", result.data.address);
}When to use: When you know the user already has an account (e.g., they clicked "Login" instead of "Sign Up").
Explicit Registration
For new users creating an account:
import { register } from "@oviato/sdk";
const result = await register({
username: "bob", // required for registration
});
if (result.status === "success") {
console.log("Registered:", result.data.address);
}When to use: When you have separate sign-up and login flows.
Authentication Options
Pre-filling Username
You can pre-fill the username field:
await authenticate({
username: "alice@ovi.id",
});Without Pre-filled Username
Let users enter their own username:
await authenticate();
// Opens modal with empty username fieldResponse Handling
All authentication methods return a BridgeResponse object:
type BridgeResponse<T> = {
status: "success" | "error";
data?: T;
message?: string;
};Success Response
const result = await authenticate();
if (result.status === "success") {
console.log("Session data:", result.data);
// result.data contains UserSession
}Error Handling
const result = await authenticate();
if (result.status === "error") {
console.error("Authentication failed:", result.message);
// Handle specific errors
if (result.message.includes("cancelled")) {
console.log("User cancelled authentication");
} else if (result.message.includes("timeout")) {
console.log("Authentication timed out");
}
}Session Data
After successful authentication, access the session:
import { getSession } from "@oviato/sdk";
const session = getSession();
if (session) {
console.log("Username:", session.username);
console.log("Address:", session.address);
console.log("Public Key:", session.publicKey);
console.log("Network:", session.network);
console.log("HD Keys:", session.hdKeys);
}Session Type
type UserSession = {
username: string; // OVI.ID username
address: string; // Current network address
publicKey: string; // Current network public key
network: string; // Active network
networkType: string; // Network type (e.g., 'utxo', 'evm')
networkEnvironment: string; // Environment ('mainnet', 'testnet')
hdKeys: {
mainnet: string; // Mainnet HD public key
testnet: string; // Testnet HD public key
};
auth?: {
token: string; // RPC auth token
expires: string; // Token expiration (ISO 8601)
};
};Checking Authentication Status
import { isAuthenticated, getSession } from "@oviato/sdk";
// Quick check
if (isAuthenticated()) {
console.log("User is authenticated");
}
// With session data
const session = getSession();
if (session) {
console.log("User is authenticated as:", session.username);
}Logout
Clear the user session:
import { clearSession } from "@oviato/sdk";
// Logout user
clearSession();
// Verify logout
console.log("Authenticated:", isAuthenticated()); // falseComplete Authentication Example
Here's a complete example with all authentication flows:
import {
initialize,
authenticate,
login,
register,
getSession,
isAuthenticated,
clearSession,
} from "@oviato/sdk";
// Initialize SDK
await initialize({
appId: "your-app-id",
network: "bitcoinmainnet",
});
// Check if already authenticated
if (isAuthenticated()) {
const session = getSession();
console.log("Already logged in as:", session.username);
} else {
// Authenticate user
const result = await authenticate();
if (result.status === "success") {
const session = getSession();
console.log("Successfully authenticated!");
console.log("Username:", session.username);
console.log("Address:", session.address);
} else {
console.error("Authentication failed:", result.message);
}
}
// Later: logout
function handleLogout() {
clearSession();
console.log("Logged out");
}Framework-Specific Examples
Vue 3
<script setup>
import { ref } from "vue";
import { authenticate, getSession, clearSession } from "@oviato/sdk";
const session = ref(getSession());
const isLoading = ref(false);
const error = ref(null);
const handleAuth = async () => {
isLoading.value = true;
error.value = null;
const result = await authenticate();
if (result.status === "success") {
session.value = getSession();
} else {
error.value = result.message;
}
isLoading.value = false;
};
const handleLogout = () => {
clearSession();
session.value = null;
};
</script>
<template>
<div>
<div v-if="error" class="error">{{ error }}</div>
<div v-if="session">
<p>Welcome, {{ session.username }}!</p>
<p>Address: {{ session.address }}</p>
<button @click="handleLogout">Logout</button>
</div>
<div v-else>
<button @click="handleAuth" :disabled="isLoading">
{{ isLoading ? "Connecting..." : "Connect Wallet" }}
</button>
</div>
</div>
</template>Svelte
<script>
import { authenticate, getSession, clearSession } from '@oviato/sdk';
let session = getSession();
let isLoading = false;
let error = null;
const handleAuth = async () => {
isLoading = true;
error = null;
const result = await authenticate();
if (result.status === 'success') {
session = getSession();
} else {
error = result.message;
}
isLoading = false;
};
const handleLogout = () => {
clearSession();
session = null;
};
</script>
{#if error}
<div class="error">{error}</div>
{/if}
{#if session}
<div>
<p>Welcome, {session.username}!</p>
<p>Address: {session.address}</p>
<button on:click={handleLogout}>Logout</button>
</div>
{:else}
<button on:click={handleAuth} disabled={isLoading}>
{isLoading ? 'Connecting...' : 'Connect Wallet'}
</button>
{/if}WebAuthn / Passkeys
Oviato uses WebAuthn for secure, passwordless authentication:
How It Works
- Registration: Creates a new passkey tied to the user's device
- Authentication: Uses the passkey to verify the user's identity
- Signing: Uses the passkey to sign messages and transactions
Browser Support
WebAuthn is supported in:
- Chrome 67+
- Safari 14+
- Firefox 60+
- Edge 18+
Requirements
- HTTPS: Required in production (localhost works for development)
- Biometrics: Touch ID, Face ID, or security key
- User Gesture: Must be triggered by user interaction (button click)
Troubleshooting
"WebAuthn not supported"
Ensure:
- Using HTTPS (required in production)
- Browser supports WebAuthn
- Device has biometric hardware or security key
"User cancelled"
User closed the authentication dialog or cancelled biometric prompt.
"Username already exists"
When using register(), the username is already taken. Try login() instead or use authenticate() for auto-detection.
"No passkey found"
When using login(), no passkey exists for this username. User should register() first or use authenticate().
Session not persisting
Check:
- Cookies are enabled
- LocalStorage is accessible
- Domain is in allowed domains list (dashboard)
- Using HTTPS in production
Security Best Practices
1. Verify Session on Server
Never trust client-side session data alone. Use the auth.token for server-side verification:
const session = getSession();
// Send token to your backend
fetch("/api/verify", {
headers: {
Authorization: `Bearer ${session.auth.token}`,
},
});2. Check Token Expiration
const session = getSession();
if (session?.auth) {
const expiresAt = new Date(session.auth.expires);
const now = new Date();
if (now > expiresAt) {
console.warn("Auth token expired, re-authenticate");
clearSession();
}
}3. Handle Network Changes
When users switch networks, re-authenticate if needed:
import { switchNetwork } from "@oviato/sdk";
const result = await switchNetwork("ethmainnet");
if (result.status === "success") {
// Session automatically updated
const session = getSession();
console.log("New network:", session.network);
console.log("New address:", session.address);
}Next Steps
- Wallet Operations - Learn about signing and transactions