Building with Passport
Stamps API
Passport Embed
Quick start

Passport Embed - Quick Start

Get up and running with Passport Embed in just a few minutes. This section provides a beginner-friendly setup for both React and non-React environments, covering the essential configuration and a simple integration example.

Obtain Your Credentials

If you haven't already, please generate an API key and a Scorer ID by following the steps in our getting access guide. You will also need to reach out to the Passport team (opens in a new tab) to gain access to the Passport Embed product.

Installing and Importing

Here's the simplest way to render the widget in a React app.

Step 1. Install the NPM package:

Add the Passport Embed React package to your project:

npm install @human-tech/passport-embed
# or
yarn add @human-tech/passport-embed

Step 2. Import the component in your React code and render it where appropriate.

First we'll provide you a code example, then we'll break down each prop.

import { PassportScoreWidget, DarkTheme, LightTheme, usePassportScore } from "@passportxyz/passport-embed";
 
const PASSPORT_API_KEY = "<YOUR_API_KEY>";
const PASSPORT_SCORER_ID="<YOUR_SCORER_ID>";
 
function MyPage() {
  const { passingScore } = usePassportScore({
    apiKey: PASSPORT_API_KEY,
    scorerId: PASSPORT_SCORER_ID,
    address: userAddress
  });
  
const signMessage = async (message: string): Promise<string> => {
  const accounts = await window.ethereum.request({ method: "eth_requestAccounts" });
  return await window.ethereum.request({
    method: "personal_sign",
    params: [message, accounts[0]]
  });
};
 
  return (
    <PassportScoreWidget 
      apiKey={PASSPORT_API_KEY}
      scorerId={PASSPORT_SCORER_ID}
      address={userAddress} 
      generateSignatureCallback={signMessage} 
      theme={isDarkMode ? DarkTheme : LightTheme}
    />
  );
}

This minimal example renders the Passport widget.

At a minimum, you should pass your apiKey, the scorerId, the user's address (if already known), and a generateSignatureCallback function (described below) that will be called to sign any required messages.

If you don't already have the user's address, you can optionally pass a connectWalletCallback function (described below) to prompt the user to connect their wallet via your connection flow.

You can optionally set a theme prop to apply a dark or light theme.

A final note that we provide a React hook called usePassportScore() that fetches the user's score and tells you whether they've passed the threshold — so you can reactively show or hide content in your app. But — frontend values can be spoofed, so don’t trust it for sensitive program protection. Instead, use passingScore as a signal to trigger a backend verification request via the Passport API. The Passport API will actually confirm the score server-side, meaning you can confidently unlock protected features based on the user's score.

Example signature callback for OAuth Stamps

The Passport Stamps product includes several OAuth-based Stamps (e.g. GitHub, Twitter, Discord) that users can verify to build up their score.

These Stamps require a signature to confirm that the user completing the OAuth verification also controls the wallet address they’re associating with the Stamp.

The following function can be included in your code to prompt the user to sign a challenge message with their wallet, proving wallet ownership and allowing the Passport backend to bind the OAuth identity to the correct address. This function should then be passed to the generateSignatureCallback prop:

const signMessage = async (message: string): Promise<string> => {
  const accounts = await window.ethereum.request({ method: "eth_requestAccounts" });
  return await window.ethereum.request({
    method: "personal_sign",
    params: [message, accounts[0]]
  });
};

Example connect wallet callback

If you don't already have the user's wallet address, you can pass a connectWalletCallback function to prompt the user to connect their wallet.

This is only necessary if:

  • You aren't already managing wallet connection elsewhere in your app, and
  • You're not using a wallet abstraction like Reown AppKit, which automatically provides the connected wallet address via a hook (e.g. account?.address).

Here's an example of a simple function that could be passed to the connectWalletCallback prop:

const connectWallet = async () => {
  const accounts = await window.ethereum.request({ method: "eth_requestAccounts" });
  return accounts[0];
};

Next step