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 serviceconfig.providerAddress(string, required): Your provider addressconfig.pollingInterval(number, optional): Polling interval in milliseconds (default: 5000)config.credentialSignerProgramId(string, optional): Credential Signer program IDconfig.sessionRegistryProgramId(string, optional): Session Registry program IDconfig.sasProgramId(string, optional): SAS program IDconfig.credentialAuthority(string, optional): Credential authority public keyconfig.credentialName(string, optional): Credential nameconfig.schemaName(string, optional): Schema nameconfig.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(): UseSolanaAuthReturnReturn 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
generateDeeplink()
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 fromgenerateDeeplink()
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(): voidSide Effects:
- Updates
authstate 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(): voidExample:
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.ElementExample:
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 addressalien-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:
- After successful attestation creation, session address is cached
- Grace period timestamp is stored in localStorage
- During 60 seconds,
verifyAttestation()returns cached value immediately - After 60 seconds, verification runs against on-chain state
- 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 attestationUsage 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
- API Reference - Core - Complete API documentation for Core SDK.
- React Integration Guide - For React applications.
- Demo App - Example implementation and source code.