npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@humanity-org/react-sdk

v0.0.2

Published

React components and hooks for Humanity Protocol OAuth and verification

Downloads

179

Readme

npm License: MIT Node


Table of Contents

  1. Installation
  2. Quick Start
  3. Components
  4. Hooks
  5. TypeScript Types
  6. Error Handling
  7. Testing
  8. Theming
  9. Production Checklist
  10. License

Installation

npm install @humanity-org/react-sdk
# or
yarn add @humanity-org/react-sdk
# or
pnpm add @humanity-org/react-sdk

Quick Start

1. Wrap your app with HumanityProvider

import { HumanityProvider } from '@humanity-org/react-sdk'

function App() {
  return (
    <HumanityProvider
      clientId="hp_xxx"
      redirectUri="https://yourapp.com/callback"
      environment="production"
    >
      <YourApp />
    </HumanityProvider>
  )
}

2. Add a login button

import { HumanityConnect } from '@humanity-org/react-sdk'

function LoginPage() {
  return (
    <HumanityConnect
      scopes={['openid', 'profile', 'identity:read']}
      onSuccess={(result) => console.log('Logged in!', result)}
    />
  )
}

3. Access user data and gate content

import { useAuth, HumanityGate } from '@humanity-org/react-sdk'

function Dashboard() {
  const { user, isAuthenticated, logout } = useAuth()

  if (!isAuthenticated) return <div>Please log in</div>

  return (
    <div>
      <h1>Welcome, {user?.name}!</h1>
      <HumanityGate
        preset="ageOver21"
        fallback={<p>Age verification required</p>}
      >
        <PremiumContent />
      </HumanityGate>
      <button onClick={logout}>Sign Out</button>
    </div>
  )
}

Components

All components must be rendered inside a <HumanityProvider>.

HumanityProvider

The root context provider. Wraps your entire application.

<HumanityProvider
  clientId="hp_xxx"
  redirectUri="https://app.com/callback"
  environment="production"
  storage="memory"
  theme="system"
  onError={(err) => console.error(err)}
>
  <App />
</HumanityProvider>

Props

| Prop | Type | Default | Description | | ------------- | ------------------------------------------------ | -------------- | ---------------------------------------------------------------------------- | | clientId | string | required | Your Humanity application client ID. | | redirectUri | string | required | OAuth callback URI registered in the developer portal. | | environment | 'production' \| 'sandbox' | 'production' | Which Humanity API environment to use. | | storage | 'memory' \| 'localStorage' \| 'sessionStorage' | 'memory' | Token storage strategy. memory is most secure (tokens cleared on refresh). | | theme | 'light' \| 'dark' \| 'system' | 'system' | Controls built-in component theming. | | baseUrl | string | — | Advanced override for custom API base URL. | | onError | (error: HumanityReactError) => void | — | Global error handler called for auth/verification errors. |


HumanityConnect

OAuth login button that handles the full authentication flow.

<HumanityConnect
  scopes={['openid', 'profile', 'identity:read']}
  mode="popup"
  variant="primary"
  size="md"
  label="Sign in with Humanity"
  onSuccess={(result) => handleLogin(result)}
  onError={(error) => console.error(error)}
/>

Props

| Prop | Type | Default | Description | | ----------- | --------------------------------------- | ------------------------- | -------------------------------------------------- | | scopes | string[] | ['openid', 'profile'] | OAuth scopes to request. | | mode | 'popup' \| 'redirect' | 'popup' | OAuth flow type. | | onSuccess | (result: AuthResult) => void | — | Called after successful authentication. | | onError | (error: HumanityReactError) => void | — | Called on authentication error. | | onLoading | (loading: boolean) => void | — | Called when loading state changes. | | variant | 'primary' \| 'secondary' \| 'outline' | 'primary' | Button visual variant. | | size | 'sm' \| 'md' \| 'lg' | 'md' | Button size. | | label | string | 'Sign in with Humanity' | Button label text. | | disabled | boolean | false | Disable the button. | | className | string | — | Additional CSS class. | | style | React.CSSProperties | — | Inline styles. | | children | React.ReactNode | — | Custom children (replaces default button content). |


HumanityVerify

One-click verification against a single preset.

<HumanityVerify
  preset="ageOver21"
  onVerified={(result) => {
    if (result.verified) grantAccess()
  }}
/>

Props

| Prop | Type | Default | Description | | ------------ | --------------------------------------- | ------------ | -------------------------------------------- | | preset | string | required | Preset key to verify (e.g. 'ageOver21'). | | onVerified | (result: VerificationResult) => void | — | Called after verification completes. | | onError | (error: HumanityReactError) => void | — | Called on verification error. | | label | string | — | Custom button label. | | variant | 'primary' \| 'secondary' \| 'outline' | 'primary' | Button visual variant. | | size | 'sm' \| 'md' \| 'lg' | 'md' | Button size. | | autoVerify | boolean | false | Trigger verification automatically on mount. |


HumanityGate

Conditionally renders children when a preset is verified; shows a fallback otherwise.

<HumanityGate
  preset="kycPassed"
  fallback={<CompleteKYC />}
  loadingFallback={<Spinner />}
>
  <AgeRestrictedContent />
</HumanityGate>

Multiple presets (require all by default):

<HumanityGate
  preset={['kyc_passed', 'accredited_investor']}
  match="all"
  fallback={<CompleteVerification />}
>
  <InvestorDashboard />
</HumanityGate>

Props

| Prop | Type | Default | Description | | ----------------- | ----------------- | ------------ | -------------------------------------------------------------------- | | preset | string | required | Single preset key; gate passes when it's verified. | | presets | string[] | — | Multiple presets. Use with requireAll for AND/OR logic. | | requireAll | boolean | true | When true, all presets must pass. When false, any one is enough. | | fallback | React.ReactNode | — | Rendered when the gate condition is not met. | | loadingFallback | React.ReactNode | — | Rendered while verification is in progress. |


HumanityProfile

Displays the authenticated user's profile with optional verification badges.

<HumanityProfile
  variant="card"
  showAvatar={true}
  showBadges={true}
  showFields={['email', 'humanity_score']}
/>

Props

| Prop | Type | Default | Description | | ------------ | --------------------------------- | -------- | -------------------------- | | variant | 'card' \| 'inline' \| 'minimal' | 'card' | Display variant. | | showAvatar | boolean | true | Show user avatar. | | showBadges | boolean | true | Show verification badges. | | showFields | string[] | — | Profile fields to display. | | className | string | — | Additional CSS class. |


HumanityErrorBoundary

React error boundary for catching and displaying errors in the Humanity component tree.

<HumanityErrorBoundary
  fallback={(error) => <p>Something went wrong: {error.message}</p>}
>
  <HumanityConnect />
</HumanityErrorBoundary>

Props

| Prop | Type | Description | | ---------- | ----------------------------------------------- | ------------------------------------- | | fallback | (error: Error) => React.ReactNode | Render function for the error state. | | onError | (error: Error, info: React.ErrorInfo) => void | Called when a child component throws. | | children | React.ReactNode | The component tree to protect. |


Hooks

useHumanity()

Full-access hook to the entire context. Throws if called outside a <HumanityProvider>.

const {
  user,
  accessToken,
  authStatus,
  isAuthenticated,
  isLoading,
  error,
  login,
  logout,
  refreshToken,
  verify,
  verifyMultiple,
} = useHumanity()

useAuth()

Auth-focused hook that selects only authentication state and operations. Thin wrapper around useHumanity().

import { useAuth } from '@humanity-org/react-sdk'

function LoginButton() {
  const { isAuthenticated, login, logout, isLoading } = useAuth()

  if (isLoading) return <Spinner />
  if (isAuthenticated) return <button onClick={logout}>Sign Out</button>
  return <button onClick={() => login()}>Sign In</button>
}

Returns

| Field | Type | Description | | ----------------- | --------------------------------------------------- | -------------------------------------------- | | authStatus | 'loading' \| 'authenticated' \| 'unauthenticated' | Tri-state auth status. | | isAuthenticated | boolean | Shorthand: authStatus === 'authenticated'. | | isLoading | boolean | Shorthand: authStatus === 'loading'. | | user | UserProfile \| null | Current user profile, or null. | | accessToken | string \| null | Current access token, or null. | | error | HumanityReactError \| null | Most recent auth error, or null. | | login | (options?: LoginOptions) => Promise<AuthResult> | Initiate OAuth login flow. | | logout | () => Promise<void> | Log out and revoke tokens. | | refreshToken | () => Promise<AuthResult> | Manually refresh the access token. | | getAccessToken | () => string \| null | Get the current access token synchronously. |


useVerification()

Runs preset verifications against the Humanity Protocol API. Returns a discriminated union status for type-safe state narrowing.

import { useVerification } from '@humanity-org/react-sdk'

function AgeCheck() {
  const { verify, status, result, isLoading } = useVerification()

  return (
    <div>
      <button onClick={() => verify('ageOver21')} disabled={isLoading}>
        Check Age
      </button>
      {status === 'success' && (
        <p>{result.verified ? '✅ Verified' : '❌ Not verified'}</p>
      )}
      {status === 'error' && <p>Verification failed</p>}
    </div>
  )
}

Returns

| Field | Type | Description | | ---------------- | ------------------------------------------------------ | ---------------------------------------------------------------- | | status | 'idle' \| 'loading' \| 'success' \| 'error' | Discriminated union status. Narrow with switch/if. | | result | VerificationResult \| null | Verification result when status === 'success'; null otherwise. | | error | HumanityReactError \| null | Error when status === 'error'; null otherwise. | | isLoading | boolean | True while a request is in-flight. | | verify | (preset: string) => Promise<VerificationResult> | Verify a single preset. | | verifyMultiple | (presets: string[]) => Promise<VerificationResult[]> | Verify multiple presets at once. | | reset | () => void | Reset to idle state. |


usePresets()

Manages multiple preset verifications. Stores results in an internal map for easy per-preset access.

import { usePresets } from '@humanity-org/react-sdk'
import { useEffect } from 'react'

function Dashboard() {
  const { verifyAll, isVerified, getResult, isLoading } = usePresets()

  useEffect(() => {
    verifyAll(['ageOver18', 'kycPassed'])
  }, [verifyAll])

  if (isLoading) return <Spinner />

  return (
    <div>
      <p>Age 18+: {isVerified('ageOver18') ? '✅' : '❌'}</p>
      <p>KYC: {isVerified('kycPassed') ? '✅' : '❌'}</p>
    </div>
  )
}

Returns

| Field | Type | Description | | ------------ | ------------------------------------------------------ | ------------------------------------------------ | | status | 'idle' \| 'loading' \| 'success' \| 'error' | Discriminated union status. | | results | Map<string, VerificationResult> | Map of preset key → verification result. | | error | HumanityReactError \| null | Error when status === 'error'; null otherwise. | | isLoading | boolean | True while a verification batch is in-flight. | | verifyAll | (presets: string[]) => Promise<VerificationResult[]> | Verify a batch of presets; stores all results. | | getResult | (preset: string) => VerificationResult \| undefined | Get the cached result for a specific preset. | | isVerified | (preset: string) => boolean | Quick check: is the given preset verified? | | reset | () => void | Clear all stored results. |


useCredentialUpdates()

Polls the Humanity Protocol API for credential updates. Useful for keeping verification status in sync.

import { useCredentialUpdates } from '@humanity-org/react-sdk'

function CredentialDashboard() {
  const { data, isLoading, error, refetch } = useCredentialUpdates({
    pollInterval: 30_000,
    enabled: true,
  })

  if (isLoading && !data) return <Spinner />
  if (error) return <p>Failed to load credentials</p>

  return (
    <div>
      <p>Credentials: {data?.credentials.length ?? 0}</p>
      <button onClick={refetch}>Refresh</button>
    </div>
  )
}

Options

| Option | Type | Default | Description | | -------------- | --------- | ------- | ------------------------------------------------------- | | pollInterval | number | 0 | Polling interval in milliseconds. 0 disables polling. | | enabled | boolean | true | Whether polling is active. |

Returns

| Field | Type | Description | | ----------- | ---------------------------- | ----------------------------------- | | data | CredentialUpdates \| null | Latest credential updates, or null. | | isLoading | boolean | True while a request is in-flight. | | error | HumanityReactError \| null | Most recent error, or null. | | refetch | () => Promise<void> | Manually trigger a fetch. |


TypeScript Types

All types are exported from @humanity-org/react-sdk.

Key types

// Auth state
type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated'
type Environment = 'production' | 'sandbox'
type StorageStrategy = 'memory' | 'localStorage' | 'sessionStorage'
type OAuthMode = 'popup' | 'redirect'

// User profile (returned after login)
interface UserProfile {
  sub: string // Unique user ID
  email?: string
  name?: string
  humanity_score?: number
  // ...additional fields from granted scopes
}

// Auth operation result
interface AuthResult {
  user: UserProfile
  accessToken: string
  // ...token metadata
}

// Verification result
interface VerificationResult {
  preset: string
  verified: boolean
  status: 'valid' | 'expired' | 'pending' | 'unavailable'
  expiresAt?: string
}

// Preset status
type PresetStatus = 'valid' | 'expired' | 'pending' | 'unavailable'

Error Handling

The SDK exports typed error classes for precise error handling:

import {
  isHumanityError,
  type HumanityReactError,
} from '@humanity-org/react-sdk'

function handleError(err: unknown) {
  if (isHumanityError(err)) {
    console.error('Humanity error:', {
      message: err.message,
      code: err.code,
      status: err.status,
    })
  }
}

Using the global error handler:

<HumanityProvider
  clientId="hp_xxx"
  redirectUri="https://app.com/callback"
  onError={(error) => {
    Sentry.captureException(error)
  }}
>
  <App />
</HumanityProvider>

Wrapping with an error boundary:

<HumanityErrorBoundary
  fallback={(error) => <ErrorPage message={error.message} />}
>
  <HumanityConnect onError={handleError} />
</HumanityErrorBoundary>

Error utilities

| Export | Description | | ----------------- | ---------------------------------------------------------------- | | isHumanityError | Type guard: returns true if the value is a HumanityReactError. | | createError | Factory for typed SDK errors. | | normalizeError | Converts any thrown value into a HumanityReactError. | | parseOAuthError | Parses OAuth error parameters from a callback URL. |


Testing

Use MockHumanityProvider for unit tests without real API calls:

import { MockHumanityProvider } from '@humanity-org/react-sdk/testing'

test('shows dashboard when authenticated', () => {
  render(
    <MockHumanityProvider
      user={{ sub: 'test-123', email: '[email protected]', name: 'Test User' }}
      isAuthenticated={true}
    >
      <Dashboard />
    </MockHumanityProvider>,
  )

  expect(screen.getByText('Welcome, Test User!')).toBeInTheDocument()
})

test('shows login when unauthenticated', () => {
  render(
    <MockHumanityProvider isAuthenticated={false}>
      <Dashboard />
    </MockHumanityProvider>,
  )

  expect(screen.getByText('Please log in')).toBeInTheDocument()
})

Theming

Customize component appearance with CSS variables:

:root {
  --humanity-primary: #000000;
  --humanity-primary-hover: #222222;
  --humanity-success: #10b981;
  --humanity-error: #ef4444;
  --humanity-border-radius: 8px;
  --humanity-font-family: inherit;
}

Set theme="dark" or theme="light" on <HumanityProvider> to control the built-in theme; theme="system" (default) follows the OS preference.


Production Checklist

Before going live:

  • [ ] OAuth popup flow works end-to-end across all supported browsers
  • [ ] Redirect URI is registered for both sandbox and production environments
  • [ ] Required scopes match what the user is prompted to grant
  • [ ] storage="memory" is used (or you understand the XSS risk of localStorage)
  • [ ] Error cases handled: expired tokens, revoked access, popup blocked
  • [ ] <HumanityErrorBoundary> wraps authentication-critical UI
  • [ ] onError global handler is configured for error monitoring
  • [ ] baseUrl and environment point to production, not sandbox
  • [ ] Client ID is correct for the production application

License

MIT