{"id":16936,"library":"xumm-oauth2-pkce","title":"Xumm OAuth2 PKCE Client SDK","description":"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.","status":"active","version":"2.8.7","language":"javascript","source_language":"en","source_url":"git://github.com/XRPL-Labs/XummPkce","tags":["javascript","xrp","xrpl","ledger","xumm","sdk","pkce","oauth2","client","typescript"],"install":[{"cmd":"npm install xumm-oauth2-pkce","lang":"bash","label":"npm"},{"cmd":"yarn add xumm-oauth2-pkce","lang":"bash","label":"yarn"},{"cmd":"pnpm add xumm-oauth2-pkce","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Used internally by `xumm-oauth2-pkce` to interact with the Xumm API after authorization, an instance of which is accessible via `sdk.state().sdk`.","package":"xumm-sdk","optional":false}],"imports":[{"note":"The package is primarily designed for ESM consumption. While UMD builds are available for browsers via CDN, direct Node.js usage should favor ESM imports. It is a named export, not a default export.","wrong":"const XummPkce = require('xumm-oauth2-pkce')","symbol":"XummPkce","correct":"import { XummPkce } from 'xumm-oauth2-pkce'"},{"note":"This type definition specifies the available options for the `XummPkce` constructor. Importing types separately is good practice in TypeScript.","symbol":"XummPkceOptions","correct":"import type { XummPkceOptions } from 'xumm-oauth2-pkce'"}],"quickstart":{"code":"import { XummPkce } from 'xumm-oauth2-pkce';\n\n// Replace with your actual Xumm API key or load from environment\nconst XUMM_API_KEY = process.env.XUMM_API_KEY ?? 'your-xumm-api-key-uuidv4';\n\nconst xumm = new XummPkce(XUMM_API_KEY);\n\nconst handleAuthResult = async () => {\n  const state = await xumm.state();\n  if (state && state.me) {\n    const { sdk, me } = state;\n    console.log(\"Successfully authenticated with Xumm!\");\n    console.log(\"User account:\", me.account);\n    console.log(\"Xumm SDK instance:\", sdk); // This is an instance of xumm-sdk\n    document.getElementById('auth-status')!.innerText = `Authenticated as ${me.account}`;\n    document.getElementById('auth-button')!.innerText = 'Logout';\n  } else {\n    console.log(\"Not authenticated.\");\n    document.getElementById('auth-status')!.innerText = 'Not authenticated.';\n    document.getElementById('auth-button')!.innerText = 'Sign in with Xumm';\n  }\n};\n\n// Listen for retrieved session (e.g., after page refresh or mobile redirect)\nxumm.on(\"retrieved\", handleAuthResult);\n// Listen for new successful authentication\nxumm.on(\"success\", handleAuthResult);\n// Listen for errors\nxumm.on(\"error\", (error) => {\n  console.error(\"Xumm authentication error:\", error);\n  document.getElementById('auth-status')!.innerText = `Authentication failed: ${error.message}`;\n  xumm.logout(); // Clear any partial state\n});\n\n// Check authentication status on page load and set up interaction\ndocument.addEventListener('DOMContentLoaded', async () => {\n  document.body.innerHTML = `\n    <div id=\"app\" style=\"font-family: sans-serif; padding: 20px;\">\n      <h1>Xumm PKCE Auth Demo</h1>\n      <p id=\"auth-status\">Checking authentication status...</p>\n      <button id=\"auth-button\">Loading...</button>\n    </div>\n  `;\n\n  document.getElementById(\"auth-button\")!.onclick = async () => {\n    const currentState = await xumm.state();\n    if (currentState && currentState.me) {\n      await xumm.logout();\n      console.log(\"Logged out.\");\n    } else {\n      console.log(\"Initiating Xumm authorization...\");\n      // For a new sign-in, the authorize() call will redirect or open a popup.\n      // The 'success' event will handle the result.\n      await xumm.authorize();\n    }\n    handleAuthResult(); // Update button and status immediately after action\n  };\n\n  handleAuthResult(); // Initial check\n});","lang":"typescript","description":"This quickstart demonstrates how to initialize `XummPkce`, handle authentication events (success, retrieval, errors), and manage user login/logout state within a simple browser application. It uses both event listeners and `authorize()` for interactive authentication."},"warnings":[{"fix":"Refactor promise-based authorization logic to use the event-driven approach where possible, listening for `success`, `retrieved`, and `error` events to manage application state.","message":"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.","severity":"gotcha","affected_versions":">=1.0"},{"fix":"Avoid setting `implicit: true` unless there's a specific, understood requirement for legacy cross-browser sign-in support. Stick to the default `implicit: false` for enhanced security.","message":"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.","severity":"gotcha","affected_versions":">=1.0"},{"fix":"Always explicitly set `redirectUrl` in the `XummPkce` constructor to match the exact URL Xumm should redirect back to after authorization, and ensure this precisely matches your Xumm application's configuration in the Xumm Developer Console.","message":"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.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Provide a valid Xumm API key (UUID v4 format) as the first argument to the `XummPkce` constructor: `new XummPkce('your-api-key-uuidv4', { ... });`","cause":"The `XummPkce` constructor was called without a valid Xumm API key (UUID v4 string) or with an invalid one.","error":"Error: Missing API Key"},{"fix":"Verify 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).","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.","error":"redirect_uri_mismatch"},{"fix":"For 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.","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.","error":"ReferenceError: XummPkce is not defined"},{"fix":"Handle 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.","cause":"The user explicitly cancelled the authentication flow in the Xumm app, closed the authorization window/tab, or denied the authorization request.","error":"Error: User cancelled authorization"}],"ecosystem":"npm","meta_description":null}