Documentation
Complete guide to integrating Key-Rex authentication into your website
New to Key-Rex? Sign in with your Lightning wallet and complete the setup wizard to get your integration code and access your personalized dashboard with account-specific examples.
Already integrated? Your backend needs a required update. See the existing customer migration guide.
Quick Start Guide
Get Key-Rex working on your website in just a few minutes. This guide covers the essential steps.
Step 1: Get Your Integration Code
- Sign in with your Lightning wallet and complete the setup wizard to access your dashboard (or create an account if you haven't)
- Go to the "My Integration Code" tab in your dashboard
- Copy the integration code provided
Step 2: Add Code to Your Website
Paste the integration code into your HTML, just before the closing </body> tag:
<body> <!-- Your website content --> <!-- Key-Rex Integration Code --> <script src="https://yourdomain.com/embed?siteId=YOUR_SITE_ID"></script> <!-- Note: KeyRex.init() is optional - script auto-initializes when DOM is ready --> <script>KeyRex.init();</script> </body>
Step 3: Add and Verify Your Domain
- Go to the "Domains" tab in your dashboard
- Add your website domain (e.g.,
example.com) - Verify domain ownership by adding the DNS TXT record shown in the dashboard (production domains require verification)
- Click "Verify" after adding the DNS record (wait 5-10 minutes for DNS propagation)
- Add both www and non-www versions if you use both (each requires separate verification)
Note: Test domains like localhost and 127.0.0.1 are automatically allowed for development and don't require verification.
Step 4: Set Up Backend Integration
When a user authenticates, Key-Rex calls your onSuccess(xpub, token) callback with a signed login token. You need to:
- Create a nonce and set
KeyRex.noncebefore login - Send the token to your backend and verify it (signature, issuer, audience = your siteId, expiry, nonce, jti)
- Create a session using the token's
subclaim as the user ID
Never create a session from the raw xpub. It is not a secret.
See the Backend Integration section for the full example. Already a customer? See the migration guide.
✓ That's It!
Your Key-Rex button should now appear on your website. Visitors can click it to sign in with their Lightning wallets. Continue reading for framework-specific examples and advanced configuration.
Prerequisites
What you need before integrating Key-Rex into your website.
1. Key-Rex Account
You need a Key-Rex account to get your integration code. Sign up for free - no credit card required.
- Sign in with a compatible Lightning wallet
- Complete the onboarding wizard
- Get your unique Site ID from the dashboard
2. Backend Server
Key-Rex requires a backend server to receive authentication data. You need:
- A server that can receive HTTP POST requests
- Ability to create and manage user sessions
- Database or storage for user records
- CORS configured on your backend to allow requests from your frontend domain (Key-Rex handles its own CORS automatically)
Options: Node.js/Express, Python/Flask, PHP, Ruby on Rails, serverless functions (Vercel, AWS Lambda, etc.), or any backend that can handle HTTP requests.
Note: Key-Rex handles CORS for its own API endpoints automatically. The CORS requirement above is for your own backend endpoint that receives the xpub from your frontend.
3. Website Domain
You need to know the domain(s) where you'll use Key-Rex:
- Production domain (e.g.,
example.com) - Both www and non-www versions if you use both
- Any staging or test domains (or use auto-allowed test domains)
Note: Test domains like localhost and 127.0.0.1 are automatically allowed for development - no need to add them or verify them.
4. Lightning Wallet (For Testing)
To test your integration, you'll need a Lightning wallet:
- Desktop: A browser extension wallet (recommended for WebLN testing)
- Mobile: A mobile Lightning wallet app
- Wallet must support LNURL-auth protocol
Featured Wallets — Coming Soon
Partner wallets will be showcased here
⚠️ Important Requirements
- Your website must have HTTPS in production (required for secure authentication)
- Your backend must be able to handle CORS requests from your frontend domain
- You must be able to modify your website's HTML to add the integration code
Integration Checklist
Use this checklist to ensure your integration is complete and working correctly.
Integration Guide
Detailed step-by-step guide for integrating Key-Rex into your website.
1. Basic HTML Integration
The simplest way to add Key-Rex is to include the script tags in your HTML:
<!DOCTYPE html> <html> <head> <title>My Website</title> </head> <body> <h1>Welcome to My Website</h1> <!-- Your website content --> <!-- Key-Rex Integration --> <script src="https://yourdomain.com/embed?siteId=YOUR_SITE_ID"></script> <!-- Note: KeyRex.init() is optional - script auto-initializes when DOM is ready --> <script>KeyRex.init();</script> </body> </html>
Important: Replace YOUR_SITE_ID with your actual Site ID from your dashboard. The script automatically initializes when the DOM is ready, but including Key-Rex.init() is recommended for explicit control.
2. Set Up Success and Error Callbacks
You need to handle authentication success and errors. Set up callbacks before the script loads:
<!-- Set up callbacks BEFORE loading the script -->
<script>
window.KeyRex = window.KeyRex || {};
// Ask YOUR backend for a one-time nonce for this login attempt
fetch('/api/keyrex/nonce', { method: 'POST' })
.then(r => r.json())
.then(({ nonce }) => { window.KeyRex.nonce = nonce; });
window.KeyRex.onSuccess = function(xpub, token) {
// Send only the signed token to your backend (never the xpub)
fetch('/api/auth/keyrex', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token })
})
.then(response => response.json())
.then(data => {
// Redirect to dashboard or update UI
window.location.href = '/dashboard';
})
.catch(error => {
console.error('Auth error:', error);
});
};
window.KeyRex.onError = function(error) {
console.error('Key-Rex error:', error);
alert('Authentication failed: ' + error.message);
};
</script>
<!-- Then load the Key-Rex script -->
<script src="https://yourdomain.com/embed?siteId=YOUR_SITE_ID"></script>
<script>KeyRex.init();</script>3. Custom Container Placement
By default, the Key-Rex button is appended to the <body>. To place it in a specific location, add an element with id="keyrex-container":
<div id="login-section"> <h2>Sign In</h2> <div id="keyrex-container"></div> <!-- Key-Rex button will appear here --> </div> <script src="https://yourdomain.com/embed?siteId=YOUR_SITE_ID"></script> <script>KeyRex.init();</script>
Framework Examples
Choose your framework below to see a complete integration example. All examples follow the same pattern: create a nonce, set up callbacks, load the script, and verify the signed login token in your backend (see Backend Integration).
React Integration
Example of integrating Key-Rex into a React application.
import { useEffect } from 'react';
function LoginPage() {
useEffect(() => {
// Set up callbacks
window.KeyRex = window.KeyRex || {};
// Ask YOUR backend for a one-time nonce for this login attempt
fetch('/api/keyrex/nonce', { method: 'POST' })
.then(r => r.json())
.then(({ nonce }) => { window.KeyRex.nonce = nonce; });
window.KeyRex.onSuccess = function(xpub, token) {
// Send only the signed token to your backend (never the xpub)
fetch('/api/auth/keyrex', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token })
})
.then(response => response.json())
.then(data => {
window.location.href = '/dashboard';
});
};
window.KeyRex.onError = function(error) {
console.error('Auth error:', error);
};
// Load Key-Rex script
const script = document.createElement('script');
script.src = 'https://yourdomain.com/embed?siteId=YOUR_SITE_ID';
script.async = true;
// Script auto-initializes when loaded
document.body.appendChild(script);
return () => {
// Cleanup
if (document.body.contains(script)) {
document.body.removeChild(script);
}
};
}, []);
return (
<div>
<h1>Login Page</h1>
<div id="keyrex-container"></div>
</div>
);
}
export default LoginPage;Vue Integration
Example of integrating Key-Rex into a Vue application.
<template>
<div>
<h1>Login Page</h1>
<div id="keyrex-container"></div>
</div>
</template>
<script setup>
import { onMounted, onUnmounted } from 'vue';
onMounted(() => {
// Set up callbacks
window.KeyRex = window.KeyRex || {};
// Ask YOUR backend for a one-time nonce for this login attempt
fetch('/api/keyrex/nonce', { method: 'POST' })
.then(r => r.json())
.then(({ nonce }) => { window.KeyRex.nonce = nonce; });
window.KeyRex.onSuccess = function(xpub, token) {
// Send only the signed token to your backend (never the xpub)
fetch('/api/auth/keyrex', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token })
})
.then(response => response.json())
.then(data => {
window.location.href = '/dashboard';
});
};
window.KeyRex.onError = function(error) {
console.error('Auth error:', error);
};
// Load Key-Rex script
const script = document.createElement('script');
script.src = 'https://yourdomain.com/embed?siteId=YOUR_SITE_ID';
script.async = true;
// Script auto-initializes when loaded
document.body.appendChild(script);
});
onUnmounted(() => {
// Cleanup
const scripts = document.querySelectorAll('script[src*="embed"]');
scripts.forEach(script => script.remove());
});
</script>Next.js Integration
Example of integrating Key-Rex into a Next.js application (App Router).
'use client';
import { useEffect } from 'react';
export default function LoginPage() {
useEffect(() => {
// Set up callbacks
window.KeyRex = window.KeyRex || {};
// Ask YOUR backend for a one-time nonce for this login attempt
fetch('/api/keyrex/nonce', { method: 'POST' })
.then(r => r.json())
.then(({ nonce }) => { window.KeyRex.nonce = nonce; });
window.KeyRex.onSuccess = function(xpub, token) {
// Send only the signed token to your backend (never the xpub)
fetch('/api/auth/keyrex', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token })
})
.then(response => response.json())
.then(data => {
window.location.href = '/dashboard';
});
};
window.KeyRex.onError = function(error) {
console.error('Auth error:', error);
};
// Load Key-Rex script
const script = document.createElement('script');
script.src = 'https://yourdomain.com/embed?siteId=YOUR_SITE_ID';
script.async = true;
// Script auto-initializes when loaded
document.body.appendChild(script);
return () => {
// Cleanup
if (document.body.contains(script)) {
document.body.removeChild(script);
}
};
}, []);
return (
<div>
<h1>Login Page</h1>
<div id="keyrex-container"></div>
</div>
);
}Plain HTML Integration
Simple HTML example for static websites or basic integrations.
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
<h1>Welcome</h1>
<!-- Set up callbacks BEFORE loading script -->
<script>
window.KeyRex = window.KeyRex || {};
// Ask YOUR backend for a one-time nonce for this login attempt
fetch('/api/keyrex/nonce', { method: 'POST' })
.then(r => r.json())
.then(({ nonce }) => { window.KeyRex.nonce = nonce; });
window.KeyRex.onSuccess = function(xpub, token) {
// Send only the signed token to your backend (never the xpub)
fetch('/api/auth/keyrex', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token })
})
.then(response => response.json())
.then(data => {
window.location.href = '/dashboard';
});
};
window.KeyRex.onError = function(error) {
console.error('Auth error:', error);
alert('Authentication failed');
};
</script>
<!-- Load Key-Rex script -->
<script src="https://yourdomain.com/embed?siteId=YOUR_SITE_ID"></script>
<!-- Note: KeyRex.init() is optional - script auto-initializes when DOM is ready -->
<script>KeyRex.init();</script>
<!-- Optional: Place button in specific location -->
<div id="keyrex-container"></div>
</body>
</html>Backend Integration
Key-Rex gives your site a short-lived signed login token for every login. Your backend verifies it, then creates the session. The identifier (xpub) is not a secret, so never create a session from it alone.
How it works
- Create a nonce per login attempt on your backend (at least 128 bits of randomness, characters
A-Z a-z 0-9 _ -, 16 to 128 long). Store it in the visitor's pre-login session and setwindow.KeyRex.noncebefore the user clicks login. - Receive the token.
onSuccess(xpub, token)provides a signed JWT as the second argument. Send only thetokento your backend. - Verify the token on your backend using Key-Rex's public keys at
/.well-known/jwks.json(cache them). Check: algorithm is ES256 only;issis the Key-Rex base URL;audis your own siteId; not expired;noncematches the one you stored (then discard it);jtinot seen before. - Create the session using the token's
subclaim as the user ID. It is unique per user per site. - Test that a bare identifier, a token for another site, an expired token, a wrong nonce and a replayed token are all rejected.
Frontend
// 1. Ask YOUR backend for a fresh nonce (it stores it in the visitor's session)
const { nonce } = await fetch('/api/keyrex/nonce', { method: 'POST' }).then(r => r.json());
window.KeyRex.nonce = nonce;
// 2. Send only the signed token to your backend
window.KeyRex.onSuccess = function(xpub, token) {
fetch('/api/auth/keyrex', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token })
});
};Backend (Node.js, using jose)
import crypto from 'crypto';
import { createRemoteJWKSet, jwtVerify } from 'jose';
const KEYREX = process.env.KEYREX_BASE_URL; // e.g. https://key-rex.com
const SITE_ID = process.env.KEYREX_SITE_ID; // your own siteId
const jwks = createRemoteJWKSet(new URL(KEYREX + '/.well-known/jwks.json'));
app.post('/api/keyrex/nonce', (req, res) => {
req.session.keyrexNonce = crypto.randomBytes(24).toString('base64url');
res.json({ nonce: req.session.keyrexNonce });
});
async function verifyKeyRexToken(token, expectedNonce) {
const { payload } = await jwtVerify(token, jwks, {
issuer: KEYREX,
audience: SITE_ID,
algorithms: ['ES256'],
clockTolerance: 5,
});
if (!expectedNonce || payload.nonce !== expectedNonce) {
throw new Error('nonce mismatch');
}
if (await seenJti(payload.jti)) throw new Error('token replayed');
await rememberJti(payload.jti, payload.exp);
return payload; // payload.sub = user ID for your site
}
app.post('/api/auth/keyrex', async (req, res) => {
try {
const expected = req.session.keyrexNonce;
req.session.keyrexNonce = null; // single use
const claims = await verifyKeyRexToken(req.body.token, expected);
const user = await findOrCreateUserBySub(claims.sub);
req.session.userId = user.id;
res.json({ success: true });
} catch (e) {
res.status(401).json({ error: 'Invalid login token' });
}
});Security: never log tokens, and keep tokens out of URLs where possible. Existing customer? See the migration guide.
Database Schema Example
Store the token's sub claim as the user's Key-Rex identifier:
-- Users table CREATE TABLE users ( id SERIAL PRIMARY KEY, keyrex_sub VARCHAR(255) UNIQUE NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_login TIMESTAMP ); -- Sessions table (if using database sessions) CREATE TABLE sessions ( id VARCHAR(255) PRIMARY KEY, user_id INTEGER REFERENCES users(id), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, expires_at TIMESTAMP );
How Authentication Works
Understanding how Key-Rex authentication works helps you integrate it correctly. This section explains the technical flow - you can skip it if you just want to get started.
WebLN (Browser Extension) Flow
- User clicks Key-Rex button on your website
- Script detects WebLN extension in browser
- Extension prompts user to approve sign-in request
- User approves in extension
- Extension returns signature directly to script
- Script calls your
Key-Rex.onSuccess(xpub, token)callback - Your backend verifies the token and creates the user session
Best UX: This is the fastest flow - one click, instant authentication. Works on desktop browsers with WebLN extensions.
QR Code Flow (Desktop Popup)
- User clicks Key-Rex button on your website
- No WebLN detected - script opens popup window with QR code
- User scans QR code with mobile Lightning wallet
- Wallet authenticates and calls Key-Rex callback server
- Popup detects authentication via polling
- Popup sends the login token to main window via postMessage
- Script calls your
Key-Rex.onSuccess(xpub, token)callback - Your backend verifies the token and creates the user session
Note: If popup is blocked, script automatically falls back to full-page redirect (same as mobile flow).
QR Code Flow (Mobile Redirect)
- User clicks Key-Rex button on mobile device
- Script detects mobile device and uses full-page redirect
- Page redirects to Key-Rex QR code page
- User scans QR code with another device or switches to wallet app
- Wallet authenticates and calls Key-Rex callback server
- QR page detects authentication and redirects back to your site
- Redirect includes the login token in a URL parameter:
?keyrex_token=... - Script detects the token in the URL and calls your
Key-Rex.onSuccess(xpub, token)callback - URL parameter is automatically cleaned up
- Your backend verifies the token and creates the user session
API Reference
Complete reference for the Key-Rex JavaScript API.
Key-Rex.init()
Description: Initializes the Key-Rex button. The script automatically calls this when the DOM is ready, but you can call it manually if needed.
Note: This is optional - the script auto-initializes when the DOM is ready. Including it explicitly doesn't hurt and can be useful for explicit control.
// Auto-initialization (recommended) <script src="https://yourdomain.com/embed?siteId=YOUR_SITE_ID"></script> // Script auto-initializes when DOM is ready // Manual initialization (optional) KeyRex.init();
Key-Rex.onSuccess(xpub, token)
Description: Callback function called when authentication succeeds. Receives the user's xpub (a non-secret identifier, deprecated for authentication) and a signed login token (JWT). send only the token to your backend and verify it; see Backend Integration.
window.KeyRex.onSuccess = function(xpub, token) {
// Send only the signed token to your backend (never the xpub)
fetch('/api/auth/keyrex', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token })
})
.then(response => response.json())
.then(data => {
// Handle successful authentication
window.location.href = '/dashboard';
});
};Key-Rex.onError(error)
Description: Callback function called when authentication fails or an error occurs.
window.KeyRex.onError = function(error) {
console.error('Key-Rex error:', error);
// Handle error (show message to user, etc.)
alert('Authentication failed: ' + error.message);
};Configuration
Key-Rex configuration is managed server-side through your dashboard. Most settings are standardized for consistency.
Server-Managed Configuration
The following settings are managed in your dashboard and fetched automatically:
- Button Text: Standardized to "Sign in with Key-Rex"
- Footer Text: Standardized branding
- Featured Wallets: Partner wallet list (managed by admin)
- Integration Toggle: Enable/disable authentication across all domains
Note: These settings are standardized to ensure consistent user experience. If you need custom branding, contact support for enterprise options.
Container Placement
Control where the Key-Rex button appears by using a container element:
<!-- Button will appear in this container --> <div id="keyrex-container"></div> <!-- If no container found, button is appended to <body> --> <script src="https://yourdomain.com/embed?siteId=YOUR_SITE_ID"></script> <script>KeyRex.init();</script>
Best Practices
Follow these best practices for a secure and reliable integration.
Security
- Never create a session from a bare xpub. Always verify the signed login token (and its nonce) on your backend
- Use HTTPS for all authentication requests
- Implement proper session management with secure, HTTP-only cookies
- Never rely on the identifier alone - use your own user IDs mapped to the token's sub claim
User Experience
- Set up callbacks before loading the script to avoid race conditions
- Provide clear error messages if authentication fails
- Test on both desktop and mobile devices
- Handle both WebLN and QR code flows gracefully
Performance
- Load the script asynchronously to avoid blocking page render
- Only include the script on pages that need authentication
- Use container placement for better control over button location
Testing & Debugging
Tips for testing your Key-Rex integration and debugging common issues.
Browser Console Commands
Open browser Developer Tools (F12) and use these commands:
// Check if KeyRex is loaded
KeyRex
// Check if button exists
document.getElementById('keyrex-button')
// Check for a login token in URL (mobile redirect)
new URLSearchParams(window.location.search).get('keyrex_token')
// Check for cookies (Note: Key-Rex cookies are httpOnly and won't appear here)
// Use DevTools → Application → Cookies to view httpOnly cookies
document.cookie.split(';').filter(c => c.includes('keyrex'))
// Test popup blocking
window.open('about:blank', 'test', 'width=100,height=100')Common Issues
- Button doesn't appear: Check browser console for errors, verify script loads in Network tab
- Domain not authorized: Add your domain in the dashboard Domains tab and verify it via DNS TXT record
- onSuccess not called: Verify callback is set before script loads
- CORS errors: Configure your backend to allow requests from your frontend domain
Testing Checklist
- Test on desktop browser with a WebLN extension
- Test on desktop browser without WebLN (should show QR popup)
- Test on mobile device (should redirect to QR page)
- Test with popup blocker enabled (should fallback to redirect)
- Verify the token is received in the onSuccess callback
- Verify your backend verifies the token and creates a session
- Test session persistence across page reloads
Error Handling
How to handle errors and provide good user experience when authentication fails.
Setting Up Error Callbacks
Always set up an error callback to handle authentication failures gracefully:
window.KeyRex.onError = function(error) {
console.error('Key-Rex error:', error);
// Handle specific error types
if (error.message.includes('Invalid siteId')) {
// Site ID is wrong - show message to developer
console.error('Check your siteId in the integration code');
} else if (error.message.includes('domain is not authorized') || error.message.includes('not authorized — add it')) {
// Domain not added - show user-friendly message
alert('This website is not configured for authentication. Please contact the website owner.');
} else if (error.message.includes('disabled')) {
// Integration disabled
alert('Authentication is currently disabled. Please try again later.');
} else if (error.message.includes('timed out')) {
// Authentication timeout
alert('Authentication timed out. Please try again.');
} else {
// Generic error
alert('Authentication failed. Please try again or contact support.');
}
};Common Error Messages
"Invalid siteId"
Cause: Site ID in integration code is incorrect
Fix: Copy the exact code from your dashboard
"This domain is not authorized — add it in your dashboard"
Cause: Domain not added to dashboard or not verified
Fix: Add your domain in the Domains tab and verify it via DNS TXT record
"Integration is disabled"
Cause: Integration toggle is off
Fix: Enable integration in dashboard
"Failed to load configuration"
Cause: Config API request failed
Fix: Check network connection and try again
"Authentication timed out"
Cause: User took too long or wallet didn't respond
Fix: Try authenticating again
"Invalid signature"
Cause: Wallet signature verification failed
Fix: Try a different wallet or restart current wallet
User-Friendly Error Messages
Show user-friendly messages instead of technical errors:
window.KeyRex.onError = function(error) {
// Map technical errors to user-friendly messages
const userMessages = {
'Invalid siteId': 'This website is not properly configured. Please contact support.',
'domain is not authorized': 'This website is not authorized for authentication. Please contact the website owner.',
'not authorized — add it': 'This website is not authorized for authentication. Please contact the website owner.',
'disabled': 'Authentication is temporarily unavailable. Please try again later.',
'timed out': 'Authentication took too long. Please try again.',
'Invalid signature': 'Authentication failed. Please try again with your wallet.',
};
// Find matching message or use generic
let message = 'Authentication failed. Please try again.';
for (const [key, value] of Object.entries(userMessages)) {
if (error.message.includes(key)) {
message = value;
break;
}
}
// Show to user (customize based on your UI)
showNotification(message, 'error');
};Advanced Features
Advanced features and customization options.
postMessage API
On desktop, the popup window communicates with the main window using postMessage. You can listen for these messages:
window.addEventListener('message', function(event) {
if (event.data && event.data.type === 'keyrex-auth-success') {
const token = event.data.token; // verify on your backend
// Handle authentication
} else if (event.data && event.data.type === 'keyrex-auth-error') {
const error = event.data.error;
// Handle error
} else if (event.data && event.data.type === 'keyrex-popup-closed') {
// User closed the popup without completing authentication
}
});Login Token Retrieval Methods
The signed login token can be delivered in multiple ways:
- URL Parameters: Mobile/redirect flow includes
?keyrex_token=...in URL (removed from the address bar automatically) - postMessage: Desktop popup sends the token via postMessage
- Cookies: Fallback method using cookies (automatically cleaned up)
The Key-Rex script handles all these methods automatically and calls your onSuccess callback with the token. Always verify it on your backend.
Account Linking & User Management
How to link Key-Rex authentication to existing user accounts.
Linking to Existing Accounts
If you already have user accounts, you can link Key-Rex authentication to them:
- User signs in with existing method (email/password, etc.)
- User clicks "Link Lightning Wallet" button
- User authenticates with Key-Rex
- Store the token's
subin the user's account record - Future sign-ins can use either method
Creating New Accounts
For new users signing in with Key-Rex:
- User clicks Key-Rex button and authenticates
- Your backend receives the login token and verifies it
- Check if a user exists with the token's
sub - If not, create a new user account with that
sub - Create session and redirect to dashboard
Common Use Cases
Examples of how Key-Rex can be used in different scenarios.
Standalone Authentication
Use Key-Rex as the only authentication method. Users sign in exclusively with Lightning wallets.
Alternative Authentication
Offer Key-Rex alongside traditional authentication (email/password). Users can choose their preferred method.
Account Linking
Allow existing users to link their Lightning wallet to their account for faster future sign-ins.
Frequently Asked Questions
Common questions about Key-Rex integration.
Do I need to call Key-Rex.init()?
No, it's optional. The script automatically initializes when the DOM is ready. However, including it explicitly is recommended for better control and compatibility with some frameworks.
Can I customize the button appearance?
The button appearance is standardized for consistency. If you need custom branding, contact support for enterprise options.
What if a user doesn't have a Lightning wallet?
Users need a Lightning wallet to use Key-Rex. You can provide links to download compatible wallets or offer alternative authentication methods alongside Key-Rex.
Is the user identifier unique per user?
Yes. The token's sub claim is unique per wallet and per site, so the same wallet has a different sub on every site. Use it as a linked identifier on your own user record. Never treat it as a secret or as proof of login by itself; always verify the token.
Quick Reference
Quick reference guide for common tasks.
Basic Integration
<script src="https://yourdomain.com/embed?siteId=YOUR_SITE_ID"></script> <script>KeyRex.init();</script>
With Callbacks
window.KeyRex.nonce = nonceFromYourBackend;
window.KeyRex.onSuccess = (xpub, token) => {
// Send token to your backend for verification
};
window.KeyRex.onError = (error) => {
// Handle error
};Container Placement
<div id="keyrex-container"></div>
Backend Endpoint
POST /api/auth/keyrex
Body: { token: "<signed JWT>" }Ready to Get Started?
Sign in with your Lightning wallet and complete the setup wizard to get your integration code and access your personalized dashboard.
Get Your Integration Code