FC Barcelona Identity

Sign in with an FCB account (email + OTP on FCB’s hosted page). UTXOS stores the user, creates a non-custodial wallet, and hands it back to your page identical to Google login.

Partner feature. Contact hello@utxos.dev to enable FCB on your project.

Quick start

import { Web3Wallet } from "@utxos/sdk";
 
const wallet = await Web3Wallet.enable({
  projectId: "YOUR_PROJECT_ID",
  appUrl: "https://utxos.dev",   // your UTXOS server URL
  networkId: 0,
  directTo: "fcb",               // skip the provider picker
});
 
// Wallet is non-custodial — UTXOS holds nothing. The user owns the keys.
const address = await wallet.cardano.getChangeAddress();
const user    = wallet.getUser();  // { email, username, provider: "fcb", ... }

That single call:

  1. Opens the UTXOS popup — user signs in on FCB’s page
  2. UTXOS creates (or recovers) the user’s non-custodial wallet
  3. Returns the wallet and user profile to your page

User profile

const user = wallet.getUser();
 
user.email      // "fan@example.com"
user.username   // "John Doe"
user.provider   // "fcb"
user.providerId // Salesforce user ID

The wallet is non-custodial which means UTXOS generates and encrypts the keys on the user’s device. UTXOS never sees the private key; it only stores the encrypted recovery shard.

Full demo setup

Based on the working demo in demo-txsponsor:

Install

npm install @utxos/sdk

Configure environment

NEXT_PUBLIC_UTXOS_PROJECT_ID=your-project-uuid
NEXT_PUBLIC_UTXOS_APP_URL=https://utxos.dev   # or http://localhost:3000 locally
NEXT_PUBLIC_ORIGIN=http://localhost:3000       # your app's origin

Add the /auth callback page

Create pages/auth.tsx (or app/auth/page.tsx). UTXOS redirects here after every OAuth callback.

// pages/auth.tsx
import { useRouter } from "next/router";
import { useEffect } from "react";
import { Web3NonCustodialProvider } from "@utxos/sdk";
 
const provider = new Web3NonCustodialProvider({
  projectId: process.env.NEXT_PUBLIC_UTXOS_PROJECT_ID!,
  appOrigin: window.location.origin,
  googleOauth2ClientId: "",
  twitterOauth2ClientId: "",
  discordOauth2ClientId: "",
  appleOauth2ClientId: "",
});
 
export default function AuthCallback() {
  const router = useRouter();
  useEffect(() => {
    if (!router.isReady) return;
    provider.handleAuthenticationRoute().then((result) => {
      if (result?.error) router.replace("/?error=" + result.error.message);
    });
  }, [router.isReady]);
  return <p>Completing login…</p>;
}

Connect wallet + read user

import { Web3Wallet, EnableWeb3WalletOptions } from "@utxos/sdk";
 
async function connectWithFcb() {
  const wallet = await Web3Wallet.enable({
    projectId: process.env.NEXT_PUBLIC_UTXOS_PROJECT_ID!,
    appUrl:    process.env.NEXT_PUBLIC_UTXOS_APP_URL!,
    networkId: 0,
    directTo: "fcb",
  });
 
  const address = await wallet.cardano.getChangeAddress();
  const user    = wallet.getUser();
 
  console.log(user?.email);    // "fan@example.com"
  console.log(user?.username); // display name from FCB
  console.log(address);        // Cardano address
}

Switch FCB accounts

// Reuse existing FCB session (default)
await Web3Wallet.enable({ ..., directTo: "fcb" });
 
// Force fresh login — shown in the popup as "Use a different account"
// The popup clears FCB SSO before opening the login page.
await Web3Wallet.enable({ ..., directTo: "fcb", newSession: true });

The wallet popup also shows a Continue / Use a different account picker whenever an FCB session already exists.

Whitelist your origin

Go to Project settings → Whitelisted URLs and add your app’s origin (e.g. http://localhost:3001 for local dev, https://your-app.com for production).

⚠️

A missing or mismatched origin returns Refused from the popup. The origin must match exactly (scheme + host + port).

Troubleshooting

ErrorFix
FCB login not enabled for projectContact UTXOS to enable FCB for your project ID
Refused / popup closes immediatelyAdd your app origin to Whitelisted URLs
Redirect URL is not whitelistedSame as above
Always lands on FCB loginNormal — newSession: false by default
Want to switch accountsnewSession: true, or click “Use a different account” in the popup