Xumm OAuth2 PKCE Client SDK
The `xumm-oauth2-pkce` JavaScript SDK facilitates client-side only OAuth2 Authorization Code with PKCE (Proof Key for Code Exchange) flow for the Xumm ecosystem. Currently at version 2.8.7, this package provides a secure method for web applications to authenticate users with Xumm without requiring a backend server for token exchange. It is actively maintained and typically follows a release cadence tied to Xumm ecosystem updates. Key differentiators include its focus on client-side security via PKCE, out-of-the-box handling of browser redirects and session persistence (using `localStorage` by default), and offering both event-driven and promise-based APIs. It integrates seamlessly into browser environments, abstracting away the complexities of the OAuth2 PKCE flow for Xumm users, and ships with TypeScript types for enhanced development experience.
Common errors
-
Error: Missing API Key
cause The `XummPkce` constructor was called without a valid Xumm API key (UUID v4 string) or with an invalid one.fixProvide a valid Xumm API key (UUID v4 format) as the first argument to the `XummPkce` constructor: `new XummPkce('your-api-key-uuidv4', { ... });` -
redirect_uri_mismatch
cause The `redirectUrl` configured in the `XummPkce` constructor (or its default `document.location.href`) does not exactly match the `redirectUrl` registered for your application in the Xumm Developer Console.fixVerify that the `redirectUrl` option passed to `XummPkce` precisely matches the redirect URL configured for your application in the Xumm Developer Console. Pay close attention to trailing slashes, subdomains, and protocols (http/https). -
ReferenceError: XummPkce is not defined
cause Occurs when attempting to use `XummPkce` in a browser environment without properly loading the library via a script tag, or when using CommonJS `require` syntax in an ESM-only context.fixFor browser usage without a bundler, ensure `<script src="https://xumm.app/assets/cdn/xumm-oauth2-pkce.min.js"></script>` is loaded before your script attempts to use `XummPkce`. For module-based projects, use `import { XummPkce } from 'xumm-oauth2-pkce';` and ensure your bundler/runtime supports ESM. -
Error: User cancelled authorization
cause The user explicitly cancelled the authentication flow in the Xumm app, closed the authorization window/tab, or denied the authorization request.fixHandle this gracefully in your application's error callback (e.g., `sdk.on('error', (err) => { /* display message to user */ })`). This is an expected user action and not typically a technical fault, so clear any pending UI states.
Warnings
- gotcha Prioritize the event-based API (`.on('success', ...)`) over the promise-based (`.authorize().then(...)`) for future compatibility, as explicitly recommended by the library maintainers. The promise will resolve, but state changes are best observed via events.
- gotcha Enabling the `implicit` option (setting `implicit: true` in `XummPkceOptions`) reduces security by allowing cross-browser sign-in without a fresh PKCE challenge, making it susceptible to some attack vectors. Only use if absolutely necessary and fully understand the implications.
- gotcha The `redirectUrl` option defaults to `document.location.href`. If your application navigates away from the root path or uses complex routing that changes `document.location.href`, ensure this URL is explicitly set in the constructor and correctly configured in both the Xumm app and your constructor to prevent authorization flow failures.
Install
-
npm install xumm-oauth2-pkce -
yarn add xumm-oauth2-pkce -
pnpm add xumm-oauth2-pkce
Imports
- XummPkce
const XummPkce = require('xumm-oauth2-pkce')import { XummPkce } from 'xumm-oauth2-pkce' - XummPkceOptions
import type { XummPkceOptions } from 'xumm-oauth2-pkce'
Quickstart
import { XummPkce } from 'xumm-oauth2-pkce';
// Replace with your actual Xumm API key or load from environment
const XUMM_API_KEY = process.env.XUMM_API_KEY ?? 'your-xumm-api-key-uuidv4';
const xumm = new XummPkce(XUMM_API_KEY);
const handleAuthResult = async () => {
const state = await xumm.state();
if (state && state.me) {
const { sdk, me } = state;
console.log("Successfully authenticated with Xumm!");
console.log("User account:", me.account);
console.log("Xumm SDK instance:", sdk); // This is an instance of xumm-sdk
document.getElementById('auth-status')!.innerText = `Authenticated as ${me.account}`;
document.getElementById('auth-button')!.innerText = 'Logout';
} else {
console.log("Not authenticated.");
document.getElementById('auth-status')!.innerText = 'Not authenticated.';
document.getElementById('auth-button')!.innerText = 'Sign in with Xumm';
}
};
// Listen for retrieved session (e.g., after page refresh or mobile redirect)
xumm.on("retrieved", handleAuthResult);
// Listen for new successful authentication
xumm.on("success", handleAuthResult);
// Listen for errors
xumm.on("error", (error) => {
console.error("Xumm authentication error:", error);
document.getElementById('auth-status')!.innerText = `Authentication failed: ${error.message}`;
xumm.logout(); // Clear any partial state
});
// Check authentication status on page load and set up interaction
document.addEventListener('DOMContentLoaded', async () => {
document.body.innerHTML = `
<div id="app" style="font-family: sans-serif; padding: 20px;">
<h1>Xumm PKCE Auth Demo</h1>
<p id="auth-status">Checking authentication status...</p>
<button id="auth-button">Loading...</button>
</div>
`;
document.getElementById("auth-button")!.onclick = async () => {
const currentState = await xumm.state();
if (currentState && currentState.me) {
await xumm.logout();
console.log("Logged out.");
} else {
console.log("Initiating Xumm authorization...");
// For a new sign-in, the authorize() call will redirect or open a popup.
// The 'success' event will handle the result.
await xumm.authorize();
}
handleAuthResult(); // Update button and status immediately after action
};
handleAuthResult(); // Initial check
});