Skip to Content
⚠️ Note: Some details in this documentation may not be fully accurate yet.

API Reference - React (Solana)

Complete API documentation for @alien_org/solana-sso-sdk-react.

AlienSolanaSsoProvider

Context provider component that wraps your application and provides Solana authentication state.

Props

interface AlienSolanaSsoProviderProps { config: AlienSolanaSsoClientConfig; children: React.ReactNode; }

Configuration:

  • config.ssoBaseUrl (string, required): Base URL of the SSO service
  • config.providerAddress (string, required): Your provider address
  • config.pollingInterval (number, optional): Polling interval in milliseconds (default: 5000)
  • config.credentialSignerProgramId (string, optional): Credential Signer program ID
  • config.sessionRegistryProgramId (string, optional): Session Registry program ID
  • config.sasProgramId (string, optional): SAS program ID
  • config.credentialAuthority (string, optional): Credential authority public key
  • config.credentialName (string, optional): Credential name
  • config.schemaName (string, optional): Schema name
  • config.schemaVersion (number, optional): Schema version

Example:

import { AlienSolanaSsoProvider } from '@alien_org/solana-sso-sdk-react'; import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react'; function App() { return ( <ConnectionProvider endpoint="https://api.mainnet-beta.solana.com"> <WalletProvider wallets={[]} autoConnect> <AlienSolanaSsoProvider config={{ ssoBaseUrl: 'https://sso.alien-api.com', providerAddress: 'your-provider-address', }} > <YourApp /> </AlienSolanaSsoProvider> </WalletProvider> </ConnectionProvider> ); }

useSolanaAuth Hook

Hook that provides access to Solana authentication state and methods. Must be used within AlienSolanaSsoProvider and Solana wallet adapter providers.

function useSolanaAuth(): UseSolanaAuthReturn

Return Value

interface UseSolanaAuthReturn { client: AlienSolanaSsoClient; auth: SolanaAuthState; wallet: SolanaWalletAdapter; connectionAdapter: SolanaConnectionAdapter; queryClient: QueryClient; generateDeeplink: (solanaAddress: string) => Promise<SolanaLinkResponse>; pollAuth: (pollingCode: string) => Promise<SolanaPollResponse>; verifyAttestation: (solanaAddress: string) => Promise<string | null>; logout: () => void; openModal: () => void; closeModal: () => void; isModalOpen: boolean; }

Properties

client

Direct access to the AlienSolanaSsoClient instance.

const { client } = useSolanaAuth(); const sessionAddress = await client.getAttestation(walletAddress);

auth

Current Solana authentication state.

interface SolanaAuthState { sessionAddress: string | null; }

Example:

const { auth } = useSolanaAuth(); if (auth.sessionAddress) { console.log('User is authenticated! Session:', auth.sessionAddress); }

wallet

Solana wallet adapter from context (from @solana/wallet-adapter-react).

const { wallet } = useSolanaAuth(); if (wallet.publicKey) { console.log('Wallet connected:', wallet.publicKey.toBase58()); } // Sign transaction const signedTx = await wallet.signTransaction(transaction);

connectionAdapter

Solana connection adapter from context (from @solana/wallet-adapter-react).

const { connectionAdapter } = useSolanaAuth(); const balance = await connectionAdapter.connection.getBalance(wallet.publicKey);

queryClient

React Query client instance for advanced usage.

const { queryClient } = useSolanaAuth(); queryClient.invalidateQueries(['some-key']);

Methods

Generates attestation creation deep link and polling code for a Solana address. Use this when the wallet doesn’t have an attestation yet.

async generateDeeplink(solanaAddress: string): Promise<SolanaLinkResponse>

Parameters:

  • solanaAddress (string): User’s Solana wallet public key (base58 string)

Returns:

{ deep_link: string; polling_code: string; expired_at: number; }

Example:

const { wallet, generateDeeplink } = useSolanaAuth(); const handleSignIn = async () => { if (!wallet.publicKey) return; const { deep_link, polling_code } = await generateDeeplink( wallet.publicKey.toBase58() ); console.log('Deep link:', deep_link); };

pollAuth()

Polls for attestation creation status.

async pollAuth(pollingCode: string): Promise<SolanaPollResponse>

Parameters:

  • pollingCode (string): Polling code from generateDeeplink()

Returns:

{ status: 'pending' | 'authorized' | 'rejected' | 'expired'; transaction?: string; oracle_signature?: number[]; oracle_public_key?: string; timestamp?: number; expiry?: number; session_address?: string; }

Example:

const { pollAuth } = useSolanaAuth(); const response = await pollAuth(polling_code); if (response.status === 'authorized') { console.log('Session address:', response.session_address); }

verifyAttestation()

Checks if a Solana wallet has an attestation on-chain. This is the primary method to verify if a user is authenticated.

async verifyAttestation(solanaAddress: string): Promise<string | null>

Parameters:

  • solanaAddress (string): User’s Solana wallet public key (base58 string)

Returns: Promise<string | null> - Session address or null if not found

Grace Period:

  • Returns cached session address immediately within 60-second grace period after attestation creation
  • After grace period, verifies on-chain attestation

Example:

const { wallet, verifyAttestation } = useSolanaAuth(); const sessionAddress = await verifyAttestation(wallet.publicKey.toBase58()); if (sessionAddress) { console.log('User is authenticated:', sessionAddress); // User already has attestation, skip attestation creation flow } else { console.log('No attestation found, need to create one'); // Start attestation creation flow }

logout()

Clears authentication state and storage.

logout(): void

Side Effects:

  • Updates auth state to remove session address
  • Removes session data from localStorage
  • Clears grace period cache

Example:

const { logout } = useSolanaAuth(); <button onClick={logout}>Logout</button>

openModal() / closeModal()

Control the built-in Solana sign-in modal.

openModal(): void closeModal(): void

Example:

const { openModal, closeModal, isModalOpen } = useSolanaAuth(); <button onClick={openModal}>Sign In</button> {isModalOpen && <button onClick={closeModal}>Close</button>}

isModalOpen

Boolean indicating if the sign-in modal is currently open.

const { isModalOpen } = useSolanaAuth(); console.log('Modal open:', isModalOpen);

Components

SolanaSignInButton

Pre-styled button component that opens the Solana sign-in modal.

function SolanaSignInButton(): JSX.Element

Example:

import { SolanaSignInButton } from '@alien_org/solana-sso-sdk-react'; import { useWallet } from '@solana/wallet-adapter-react'; import { WalletMultiButton } from '@solana/wallet-adapter-react-ui'; function LoginPage() { const { connected } = useWallet(); if (!connected) { return ( <div> <h1>Connect Your Wallet</h1> <WalletMultiButton /> </div> ); } return ( <div> <h1>Sign In with Alien</h1> <SolanaSignInButton /> </div> ); }

Styling:

The button has default styles but can be customized via CSS:

button.alien-solana-sso-signin-button { /* Your custom styles */ }

SolanaSignInModal

Modal component for the attestation creation flow. Automatically rendered by AlienSolanaSsoProvider.

This component:

  • Checks if attestation already exists (if yes, authenticates immediately)
  • Displays QR code with deep link (if no attestation)
  • Handles polling automatically
  • Builds attestation transaction
  • Prompts user to sign transaction
  • Creates on-chain attestation
  • Shows loading and error states

Controlling the modal:

const { openModal, closeModal } = useSolanaAuth(); // Open modal openModal(); // Close modal closeModal();

Types

AlienSolanaSsoClientConfig

interface AlienSolanaSsoClientConfig { ssoBaseUrl: string; providerAddress: string; pollingInterval?: number; credentialSignerProgramId?: string; sessionRegistryProgramId?: string; sasProgramId?: string; credentialAuthority?: string; credentialName?: string; schemaName?: string; schemaVersion?: number; }

SolanaAuthState

interface SolanaAuthState { sessionAddress: string | null; }

SolanaLinkResponse

interface SolanaLinkResponse { deep_link: string; polling_code: string; expired_at: number; }

SolanaPollResponse

interface SolanaPollResponse { status: 'pending' | 'authorized' | 'rejected' | 'expired'; transaction?: string; oracle_signature?: number[]; oracle_public_key?: string; timestamp?: number; expiry?: number; session_address?: string; }

Storage Keys

The SDK uses the following localStorage keys:

  • alien-sso_solana_authed_address: Stores which wallet address is authenticated (used to restore auth state on page reload)
  • alien-sso_session_address: Cached session address
  • alien-sso_attestation_created_at: Timestamp of attestation creation (for 60-second grace period to handle RPC indexing delays)

Grace Period Mechanism

The provider implements a 60-second grace period after attestation creation to handle RPC indexing delays:

How it works:

  1. After successful attestation creation, session address is cached
  2. Grace period timestamp is stored in localStorage
  3. During 60 seconds, verifyAttestation() returns cached value immediately
  4. After 60 seconds, verification runs against on-chain state
  5. If on-chain verification fails after grace period, session is cleared

Example:

// After attestation is created // Session address is available immediately const sessionAddress = await verifyAttestation(walletAddress); // Returns cached value within 60 seconds // After 60 seconds const sessionAddress = await verifyAttestation(walletAddress); // Queries on-chain attestation

Usage Examples

Basic Authentication Flow

import { AlienSolanaSsoProvider, useSolanaAuth, SolanaSignInButton } from '@alien_org/solana-sso-sdk-react'; import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react'; import { WalletMultiButton } from '@solana/wallet-adapter-react-ui'; import { useWallet } from '@solana/wallet-adapter-react'; import { clusterApiUrl } from '@solana/web3.js'; function App() { const endpoint = clusterApiUrl('mainnet-beta'); return ( <ConnectionProvider endpoint={endpoint}> <WalletProvider wallets={[]} autoConnect> <AlienSolanaSsoProvider config={{ ssoBaseUrl: 'https://sso.alien-api.com', providerAddress: 'your-provider-address', }} > <Dashboard /> </AlienSolanaSsoProvider> </WalletProvider> </ConnectionProvider> ); } function Dashboard() { const { connected } = useWallet(); const { auth, logout } = useSolanaAuth(); if (!connected) { return ( <div> <h1>Connect Wallet</h1> <WalletMultiButton /> </div> ); } if (!auth.sessionAddress) { return ( <div> <h1>Sign In</h1> <SolanaSignInButton /> </div> ); } return ( <div> <h1>Dashboard</h1> <p>Session: {auth.sessionAddress}</p> <button onClick={logout}>Logout</button> </div> ); }

Protected Route

import { useSolanaAuth } from '@alien_org/solana-sso-sdk-react'; import { useWallet } from '@solana/wallet-adapter-react'; import { Navigate } from 'react-router-dom'; function ProtectedRoute({ children }: { children: React.ReactNode }) { const { connected } = useWallet(); const { auth } = useSolanaAuth(); if (!connected) { return <Navigate to="/connect-wallet" replace />; } if (!auth.sessionAddress) { return <Navigate to="/sign-in" replace />; } return <>{children}</>; }

Verify Attestation on Mount

import { useSolanaAuth } from '@alien_org/solana-sso-sdk-react'; import { useWallet } from '@solana/wallet-adapter-react'; import { useEffect, useState } from 'react'; function App() { const { publicKey } = useWallet(); const { verifyAttestation, auth } = useSolanaAuth(); const [isVerifying, setIsVerifying] = useState(true); useEffect(() => { const verify = async () => { if (publicKey) { await verifyAttestation(publicKey.toBase58()); } setIsVerifying(false); }; verify(); }, [publicKey]); if (isVerifying) { return <div>Verifying authentication...</div>; } return auth.sessionAddress ? <Dashboard /> : <LoginPage />; }

Error Handling

All async methods can throw errors. Handle them appropriately:

const { wallet, generateDeeplink, verifyAttestation } = useSolanaAuth(); try { const { deep_link, polling_code } = await generateDeeplink( wallet.publicKey.toBase58() ); } catch (error) { console.error('Failed to generate deep link:', error); } try { const sessionAddress = await verifyAttestation( wallet.publicKey.toBase58() ); } catch (error) { console.error('Attestation verification failed:', error); }

Next Steps

Last updated on