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

Core Integration Guide - Solana

This guide shows how to integrate Alien Solana SSO verification and authentication into any JavaScript/TypeScript project using the core SDK.

Requirements

  • A modern web browser with JavaScript enabled
  • localStorage and sessionStorage support
  • @solana/web3.js ^1.95.0 or higher
  • A registered provider from the dev portal with provider address

Installation

npm install @alien_org/solana-sso-sdk-core @solana/web3.js

Setup

Initialize the Client

import { AlienSolanaSsoClient } from '@alien_org/solana-sso-sdk-core'; const client = new AlienSolanaSsoClient({ ssoBaseUrl: 'https://sso.alien-api.com', providerAddress: 'your-provider-address' });

Configuration Options

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

Authentication Flow

Step 1: Connect Wallet

First, ensure the user has connected their Solana wallet:

import { Connection, PublicKey } from '@solana/web3.js'; // Get user's wallet public key (from wallet adapter or similar) const userPublicKey = new PublicKey('user-wallet-address'); const solanaAddress = userPublicKey.toBase58();

Step 2: Check for Existing Attestation

Before initiating the attestation creation flow, check if the wallet already has an attestation:

const sessionAddress = await client.getAttestation(solanaAddress); if (sessionAddress) { console.log('User is already authenticated! Session:', sessionAddress); // User is authenticated, proceed to app return; } // No attestation found, proceed with creation flow console.log('No attestation found, starting attestation creation...');
const { deep_link, polling_code, expired_at } = await client.generateDeeplink(solanaAddress); // Display QR code with deep_link displayQRCode(deep_link); // Or redirect mobile users window.location.href = deep_link;

The generateDeeplink() method takes the user’s Solana wallet address and returns:

  • deep_link: Link for QR code or mobile redirect
  • polling_code: Code for polling authentication status
  • expired_at: Unix timestamp when polling code expires

Step 4: Poll for Authorization

let pollResponse; const pollInterval = setInterval(async () => { pollResponse = await client.pollAuth(polling_code); if (pollResponse.status === 'authorized') { clearInterval(pollInterval); // Proceed to transaction building console.log('Authorized! Session address:', pollResponse.session_address); } else if (pollResponse.status === 'rejected') { clearInterval(pollInterval); console.error('User rejected authentication'); } else if (pollResponse.status === 'expired') { clearInterval(pollInterval); console.error('Authentication expired'); } // If status is 'pending', continue polling }, 5000);

When status is 'authorized', the response includes:

  • session_address: Session identifier
  • oracle_signature: Signature bytes for verification
  • oracle_public_key: Oracle public key
  • timestamp: Unix timestamp
  • expiry: Expiry timestamp
  • transaction: Pre-built transaction (optional)

Step 5: Build Attestation Transaction

import { Connection, Transaction, sendAndConfirmTransaction } from '@solana/web3.js'; // Create Solana connection const connection = new Connection('https://api.mainnet-beta.solana.com'); // Build attestation transaction const transaction = await client.buildCreateAttestationTransaction({ connection, payerPublicKey: userPublicKey, sessionAddress: pollResponse.session_address!, oracleSignature: new Uint8Array(pollResponse.oracle_signature!), oraclePublicKey: new PublicKey(pollResponse.oracle_public_key!), timestamp: pollResponse.timestamp!, expiry: pollResponse.expiry!, });

Step 6: Sign and Send Transaction

// Sign transaction with user's wallet // (Implementation depends on your wallet integration) const signedTransaction = await wallet.signTransaction(transaction); // Send and confirm transaction const signature = await sendAndConfirmTransaction( connection, signedTransaction, [/* signers if needed */] ); console.log('Attestation created! Signature:', signature);

Step 7: Verify Attestation

After the transaction is confirmed, verify the on-chain attestation:

const sessionAddress = await client.getAttestation(solanaAddress); if (sessionAddress) { console.log('Attestation created successfully! Session:', sessionAddress); } else { console.log('Attestation not found, please try again'); }

Complete Example

import { AlienSolanaSsoClient } from '@alien_org/solana-sso-sdk-core'; import { Connection, PublicKey, Transaction, sendAndConfirmTransaction } from '@solana/web3.js'; const client = new AlienSolanaSsoClient({ ssoBaseUrl: 'https://sso.alien-api.com', providerAddress: 'your-provider-address', }); const connection = new Connection('https://api.mainnet-beta.solana.com'); async function authenticateUser(userWallet: any) { try { const userPublicKey = userWallet.publicKey; const solanaAddress = userPublicKey.toBase58(); // Check if already authenticated const existingSession = await client.getAttestation(solanaAddress); if (existingSession) { console.log('Already authenticated:', existingSession); return; } // Generate deep link const { deep_link, polling_code } = await client.generateDeeplink(solanaAddress); // Display QR code displayQRCode(deep_link); // Poll for authorization const pollInterval = setInterval(async () => { const response = await client.pollAuth(polling_code); if (response.status === 'authorized') { clearInterval(pollInterval); // Build attestation transaction const transaction = await client.buildCreateAttestationTransaction({ connection, payerPublicKey: userPublicKey, sessionAddress: response.session_address!, oracleSignature: new Uint8Array(response.oracle_signature!), oraclePublicKey: new PublicKey(response.oracle_public_key!), timestamp: response.timestamp!, expiry: response.expiry!, }); // Sign transaction const signedTransaction = await userWallet.signTransaction(transaction); // Send transaction const signature = await sendAndConfirmTransaction( connection, signedTransaction, [] ); console.log('Attestation created! Signature:', signature); // Verify attestation const sessionAddress = await client.getAttestation(solanaAddress); console.log('Verified session:', sessionAddress); hideQRCode(); } else if (response.status === 'rejected' || response.status === 'expired') { clearInterval(pollInterval); console.error('Authentication failed:', response.status); hideQRCode(); } }, 5000); } catch (error) { console.error('Authentication error:', error); } } function displayQRCode(deepLink: string) { // Implementation to display QR code } function hideQRCode() { // Implementation to hide QR code }

PDA Derivation Utilities

The SDK provides utility functions for deriving Program Derived Addresses (PDAs):

import { deriveProgramStatePda, deriveCredentialSignerPda, deriveSessionRegistryPda, deriveSessionEntryPda, deriveSolanaEntryPda, deriveAttestationPda, deriveCredentialPda, deriveSchemaPda, } from '@alien_org/solana-sso-sdk-core'; // Example: Derive attestation PDA const [attestationPda, bump] = deriveAttestationPda( credentialAddress, schemaAddress, userPublicKey, sasProgramId );

Error Handling

try { const { deep_link, polling_code } = await client.generateDeeplink(solanaAddress); } catch (error) { console.error('Failed to generate deep link:', error); // Handle network error or server error } try { const transaction = await client.buildCreateAttestationTransaction({ connection, payerPublicKey: userPublicKey, sessionAddress: pollResponse.session_address!, oracleSignature: new Uint8Array(pollResponse.oracle_signature!), oraclePublicKey: new PublicKey(pollResponse.oracle_public_key!), timestamp: pollResponse.timestamp!, expiry: pollResponse.expiry!, }); } catch (error) { console.error('Transaction building failed:', error); // Could be due to missing program state or invalid parameters }

Solana Programs

The SDK interacts with three on-chain programs:

Credential Signer Program

ID: 9cstDz8WWRAFaq1vVpTjfHz6tjgh6SJaqYFeZWi1pFHG

Manages credential signing and verification.

Session Registry Program

ID: DeHa6pyZ2CFSbQQiNMm7FgoCXqmkX6tXG77C4Qycpta6

Stores session entries and maps Solana addresses to sessions.

SAS (Solana Attestation Service)

ID: 22zoJMtdu4tQc2PzL74ZUT7FrwgB1Udec8DdW4yw4BdG

Creates and manages on-chain attestations.

Next Steps

Last updated on