Skip to content

Latest commit

 

History

History
1026 lines (790 loc) · 22.3 KB

File metadata and controls

1026 lines (790 loc) · 22.3 KB

📖 API Reference

Complete reference for all hooks, services, and utilities in PassPay.


Table of Contents


Hooks

useLazorkitTransaction

A hook that abstracts LazorKit transaction signing with loading states, error handling, and gasless configuration.

Import

import { useLazorkitTransaction } from "@/hooks";

Interface

interface UseLazorkitTransactionOptions {
  gasless?: boolean;
  paymasterUrl?: string;
  onSuccess?: (signature: string) => void;
  onError?: (error: Error) => void;
}

interface UseLazorkitTransactionReturn {
  execute: (params: ExecuteParams) => Promise<string | null>;
  loading: boolean;
  error: string | null;
  clearError: () => void;
}

interface ExecuteParams {
  instructions: TransactionInstruction[];
  lookupTables?: AddressLookupTableAccount[];
}

Parameters

Parameter Type Default Description
gasless boolean true Enable fee sponsorship via paymaster
paymasterUrl string kora.devnet.lazorkit.com Paymaster service URL
onSuccess (sig: string) => void - Callback when transaction succeeds
onError (error: Error) => void - Callback when transaction fails

Returns

Property Type Description
execute function Execute the transaction
loading boolean Transaction in progress
error string | null Error message if failed
clearError function Reset error state

Example

const { execute, loading, error } = useLazorkitTransaction({
  gasless: true,
  onSuccess: (signature) => {
    console.log("Transaction confirmed:", signature);
    Alert.alert("Success!", `Signature: ${signature.slice(0, 8)}...`);
  },
  onError: (error) => {
    console.error("Transaction failed:", error);
  },
});

// Execute a transaction
const handleTransfer = async () => {
  const instruction = SystemProgram.transfer({
    fromPubkey: wallet,
    toPubkey: recipient,
    lamports: LAMPORTS_PER_SOL * 0.01,
  });

  const signature = await execute({ instructions: [instruction] });

  if (signature) {
    // Transaction succeeded
  }
};

useWalletGuard

A hook that provides wallet connection state and a pre-built "Not Connected" UI component.

Import

import { useWalletGuard } from "@/hooks";

Interface

interface UseWalletGuardReturn {
  isConnected: boolean;
  publicKey: PublicKey | null;
  truncatedAddress: string | null;
  NotConnectedView: React.FC;
}

Returns

Property Type Description
isConnected boolean Whether wallet is connected
publicKey PublicKey | null Connected wallet address
truncatedAddress string | null Shortened address for display
NotConnectedView React.FC Component to show when not connected

Example

export default function TransferScreen() {
  const { isConnected, publicKey, truncatedAddress, NotConnectedView } =
    useWalletGuard();

  // Show connect prompt if not connected
  if (!isConnected) {
    return <NotConnectedView />;
  }

  // Main screen content
  return (
    <View>
      <Text>Connected: {truncatedAddress}</Text>
      {/* ... */}
    </View>
  );
}

useSolBalance

A hook that fetches and manages SOL balance with automatic refresh on screen focus.

Import

import { useSolBalance } from "@/hooks";

Interface

interface UseSolBalanceOptions {
  publicKey: PublicKey | null;
  refreshOnFocus?: boolean;
}

interface UseSolBalanceReturn {
  balance: number | null;
  loading: boolean;
  error: string | null;
  refresh: () => Promise<void>;
}

Parameters

Parameter Type Default Description
publicKey PublicKey | null - Wallet address to check
refreshOnFocus boolean true Auto-refresh when screen gains focus

Returns

Property Type Description
balance number | null Balance in SOL
loading boolean Fetching in progress
error string | null Error message if failed
refresh function Manually trigger refresh

Example

function WalletScreen() {
  const { smartWalletPubkey } = useWallet();
  const { balance, loading, refresh } = useSolBalance({
    publicKey: smartWalletPubkey,
  });

  return (
    <View>
      {loading ? <ActivityIndicator /> : <Text>{balance?.toFixed(4)} SOL</Text>}
      <Button title="Refresh" onPress={refresh} />
    </View>
  );
}

useTransactionHistory

A hook for managing local transaction history with AsyncStorage persistence.

Import

import { useTransactionHistory } from "@/hooks";

Interface

interface Transaction {
  id: string;
  type: "transfer" | "stake" | "memo";
  signature: string;
  amount?: number;
  recipient?: string;
  timestamp: number;
}

interface UseTransactionHistoryReturn {
  history: Transaction[];
  loading: boolean;
  addTransaction: (tx: Omit<Transaction, "id" | "timestamp">) => Promise<void>;
  clearHistory: () => Promise<void>;
  getExplorerUrl: (signature: string) => string;
}

Returns

Property Type Description
history Transaction[] Array of past transactions
loading boolean Loading history from storage
addTransaction function Add new transaction to history
clearHistory function Clear all history
getExplorerUrl function Get Solana Explorer URL

Example

function HistoryScreen() {
  const { history, addTransaction, getExplorerUrl } = useTransactionHistory();

  // Add a transaction after success
  await addTransaction({
    type: "transfer",
    signature: "5xY9...",
    amount: 0.01,
    recipient: "7abc...",
  });

  // Display history
  return (
    <FlatList
      data={history}
      renderItem={({ item }) => (
        <TouchableOpacity
          onPress={() => Linking.openURL(getExplorerUrl(item.signature))}
        >
          <Text>
            {item.type}: {item.amount} SOL
          </Text>
          <Text>{new Date(item.timestamp).toLocaleString()}</Text>
        </TouchableOpacity>
      )}
    />
  );
}

useClipboard

A hook for clipboard operations with haptic feedback.

Import

import { useClipboard } from "@/hooks";

Interface

interface UseClipboardReturn {
  copy: (text: string) => Promise<void>;
  paste: () => Promise<string | null>;
  copied: boolean;
}

Returns

Property Type Description
copy function Copy text to clipboard
paste function Get text from clipboard
copied boolean True briefly after copying

Example

function AddressDisplay({ address }: { address: string }) {
  const { copy, copied } = useClipboard();

  return (
    <TouchableOpacity onPress={() => copy(address)}>
      <Text>{truncateAddress(address)}</Text>
      <Text>{copied ? "Copied!" : "Tap to copy"}</Text>
    </TouchableOpacity>
  );
}

useSession

A hook for managing user session persistence with AsyncStorage.

Import

import { useSession } from "@/hooks";

Interface

interface UseSessionOptions {
  autoRestore?: boolean; // Auto-restore session on mount (default: true)
  autoSync?: boolean; // Auto-sync with wallet connection (default: true)
  sessionExpiryMs?: number; // Session expiry in ms (default: 24 hours)
  expiryWarningMs?: number; // Warning threshold in ms (default: 5 minutes)
  trackAppState?: boolean; // Update activity on foreground (default: true)
}

interface UseSessionReturn {
  session: SessionData | null;
  preferences: UserPreferences;
  isRestoring: boolean;
  isValid: boolean;
  isExpiringSoon: boolean;
  timeRemaining: number;
  createNewSession: (walletAddress?: string) => Promise<SessionData | null>;
  endSession: (keepPreferences?: boolean) => Promise<void>;
  extendCurrentSession: (additionalMs?: number) => Promise<SessionData | null>;
  updatePreferences: (prefs: Partial<UserPreferences>) => Promise<boolean>;
  refresh: () => Promise<void>;
}

Parameters

Parameter Type Default Description
autoRestore boolean true Restore session on mount
autoSync boolean true Sync with wallet connection
sessionExpiryMs number 86400000 (24h) Session duration in milliseconds
expiryWarningMs number 300000 (5min) Warning threshold before expiry
trackAppState boolean true Track app foreground/background

Returns

Property Type Description
session SessionData | null Current session data
preferences UserPreferences User preferences
isRestoring boolean Session restoration in progress
isValid boolean Whether session is valid
isExpiringSoon boolean Session expires within threshold
timeRemaining number Milliseconds until expiry
createNewSession function Create a new session
endSession function End the current session
extendCurrentSession function Extend session duration
updatePreferences function Update user preferences
refresh function Refresh session state from storage

Example

export default function HomeScreen() {
  const {
    session,
    isRestoring,
    isValid,
    isExpiringSoon,
    preferences,
    extendCurrentSession,
    endSession,
  } = useSession();

  if (isRestoring) {
    return <ActivityIndicator />;
  }

  if (!isValid) {
    return <WelcomeScreen />;
  }

  return (
    <View>
      <Text>Welcome, {session?.walletAddress.slice(0, 8)}...</Text>
      {isExpiringSoon && (
        <Button title="Extend Session" onPress={() => extendCurrentSession()} />
      )}
      <Button title="Logout" onPress={() => endSession()} />
    </View>
  );
}

Services

RPC Service

Singleton connection to Solana RPC with caching utilities.

Location

services/rpc.ts

Functions

// Get or create connection singleton
function getConnection(): Connection;

// Get connection with custom endpoint
function getConnection(endpoint?: string): Connection;

// Devnet RPC endpoint constant
const DEVNET_RPC: string;

Example

import { getConnection, DEVNET_RPC } from "@/services/rpc";

const connection = getConnection();
const balance = await connection.getBalance(publicKey);

Transfer Service

Utilities for SOL transfer operations.

Location

features/transfer/services/transfer.service.ts

Imports

// Direct import (recommended)
import { createTransferInstruction } from "@/features/transfer/services";

// Backward compatible import
import { createTransferInstruction } from "@/services/transfer";

Functions

/**
 * Create a SOL transfer instruction
 */
function createTransferInstruction(
  fromPubkey: PublicKey,
  toPubkey: PublicKey,
  lamports: number
): TransactionInstruction;

/**
 * Validate a Solana address
 */
function isValidSolanaAddress(address: string): boolean;

/**
 * Convert SOL to lamports
 */
function solToLamports(sol: number): number;

/**
 * Convert lamports to SOL
 */
function lamportsToSol(lamports: number): number;

Example

import {
  createTransferInstruction,
  isValidSolanaAddress,
  solToLamports,
} from "@/services/transfer";

// Validate address
if (!isValidSolanaAddress(recipientAddress)) {
  throw new Error("Invalid address");
}

// Create instruction
const ix = createTransferInstruction(
  wallet,
  new PublicKey(recipientAddress),
  solToLamports(0.01)
);

Staking Service

Utilities for native SOL staking.

Location

features/staking/services/staking.service.ts

Imports

// Direct import (recommended)
import { createStakeAccountInstructions } from "@/features/staking/services";

// Backward compatible import
import { createStakeAccountInstructions } from "@/services/staking";

Functions

/**
 * Create stake account and delegation instructions
 * Uses createAccountWithSeed to avoid extra signers
 */
async function createStakeAccountInstructions(params: {
  walletPubkey: PublicKey;
  lamports: number;
  validatorVoteAccount: PublicKey;
}): Promise<{
  instructions: TransactionInstruction[];
  stakeAccountPubkey: PublicKey;
}>;

/**
 * Get current stake account rent exemption
 */
async function getStakeRentExemption(): Promise<number>;

/**
 * Fetch active validators
 */
async function getValidators(): Promise<ValidatorInfo[]>;

Example

import { createStakeAccountInstructions } from "@/services/staking";

const { instructions, stakeAccountPubkey } =
  await createStakeAccountInstructions({
    walletPubkey: wallet,
    lamports: LAMPORTS_PER_SOL * 1, // 1 SOL
    validatorVoteAccount: validatorPubkey,
  });

// Execute via LazorKit
await execute({ instructions });

Memo Service

Utilities for on-chain memo operations.

Location

features/memo/services/memo.service.ts

Imports

// Direct import (recommended)
import { createMemoInstruction } from "@/features/memo/services";

// Backward compatible import
import { createMemoInstruction } from "@/services/memo";

Functions

/**
 * Create a memo instruction
 */
function createMemoInstruction(
  message: string,
  signer: PublicKey
): TransactionInstruction;

/**
 * Validate memo length
 */
function isValidMemoLength(message: string): boolean;

/**
 * Maximum memo length in bytes
 */
const MAX_MEMO_LENGTH: number; // 566 bytes

Example

import { createMemoInstruction, isValidMemoLength } from "@/services/memo";

if (!isValidMemoLength(message)) {
  throw new Error("Memo too long");
}

const memoIx = createMemoInstruction(message, wallet);
await execute({ instructions: [memoIx] });

Session Service

Utilities for managing user session persistence with AsyncStorage.

Location

features/session/services/session.service.ts

Imports

// Direct import (recommended)
import {
  createSession,
  getSession,
  clearSession,
  hasValidSession,
} from "@/features/session/services";

// Via hooks index
import { useSession } from "@/hooks";

Types

interface SessionData {
  walletAddress: string;
  createdAt: number;
  expiresAt: number;
  lastActivity: number;
  isAuthenticated: boolean;
}

interface UserPreferences {
  theme?: "light" | "dark" | "system";
  showBalance?: boolean;
  notifications?: boolean;
  hapticFeedback?: boolean;
}

Functions

/**
 * Create a new session
 */
async function createSession(
  walletAddress: string,
  config?: { expiryMs?: number }
): Promise<SessionData | null>;

/**
 * Get the current session
 */
async function getSession(): Promise<SessionData | null>;

/**
 * Check if there's a valid session
 */
async function hasValidSession(): Promise<boolean>;

/**
 * Clear the current session
 */
async function clearSession(): Promise<boolean>;

/**
 * Update last activity timestamp
 */
async function updateLastActivity(): Promise<boolean>;

/**
 * Extend session expiry
 */
async function extendSession(
  additionalMs?: number
): Promise<SessionData | null>;

/**
 * Get session time remaining
 */
async function getSessionTimeRemaining(): Promise<number>;

/**
 * Check if session is about to expire
 */
async function isSessionExpiringSoon(thresholdMs?: number): Promise<boolean>;

/**
 * Save user preferences
 */
async function saveUserPreferences(
  preferences: Partial<UserPreferences>
): Promise<boolean>;

/**
 * Get user preferences
 */
async function getUserPreferences(): Promise<UserPreferences>;

/**
 * Clear all session data
 */
async function clearAllSessionData(keepPreferences?: boolean): Promise<boolean>;

Example

import {
  createSession,
  getSession,
  hasValidSession,
  clearSession,
} from "@/features/session/services";

// Create session after wallet connection
const session = await createSession(walletAddress);

// Check validity
if (await hasValidSession()) {
  console.log("User is authenticated");
}

// Get session data
const currentSession = await getSession();
console.log(`Wallet: ${currentSession?.walletAddress}`);

// Logout
await clearSession();

Utilities

Helpers

Common helper functions used throughout the app.

Location

utils/helpers.ts

Functions

/**
 * Truncate address for display
 * "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"
 * → "7xKX...sAsU"
 */
function truncateAddress(address: string, chars?: number): string;

/**
 * Format SOL amount for display
 * 1.234567890 → "1.2346"
 */
function formatSol(lamports: number, decimals?: number): string;

/**
 * Get Solana Explorer URL for transaction
 */
function getExplorerUrl(
  signature: string,
  cluster?: "mainnet" | "devnet" | "testnet"
): string;

/**
 * Sleep for specified milliseconds
 */
function sleep(ms: number): Promise<void>;

/**
 * Check if string is valid base58
 */
function isBase58(str: string): boolean;

Example

import { truncateAddress, formatSol, getExplorerUrl } from "@/utils/helpers";

// Display
<Text>{truncateAddress(address)}</Text>
<Text>{formatSol(lamports)} SOL</Text>

// Link
const url = getExplorerUrl(signature, "devnet");

Redirect URL

Build deep link URLs for authentication redirects.

Location

utils/redirect-url.ts

Functions

/**
 * Get appropriate redirect URL based on environment
 * Expo Go: exp://192.168.1.x:8081
 * Standalone: passpaymobile://
 */
function getRedirectUrl(path?: string): string;

/**
 * Parse incoming redirect URL
 */
function parseRedirectUrl(url: string): {
  path: string;
  params: Record<string, string>;
};

Example

import { getRedirectUrl } from "@/utils/redirect-url";

// In LazorKitProvider config
const redirectUrl = getRedirectUrl();

// Connect with redirect
await connect({
  redirectUri: getRedirectUrl("/auth-callback"),
});

Types

Common Types

// Transaction type for history
type TransactionType = "transfer" | "stake" | "memo" | "other";

// Network cluster
type Cluster = "mainnet-beta" | "devnet" | "testnet";

// Validator information
interface ValidatorInfo {
  votePubkey: PublicKey;
  nodePubkey: PublicKey;
  commission: number;
  activatedStake: number;
}

// Balance info
interface BalanceInfo {
  lamports: number;
  sol: number;
}

// Transaction status
type TransactionStatus = "pending" | "confirmed" | "failed";

LazorKit Types (from SDK)

// Wallet hook return type
interface UseWalletReturn {
  smartWalletPubkey: PublicKey | null;
  isConnecting: boolean;
  connect: (options: ConnectOptions) => Promise<void>;
  disconnect: () => Promise<void>;
  signAndSendTransaction: (options: SignOptions) => Promise<string>;
  signMessage: (message: Uint8Array) => Promise<Uint8Array>;
}

// Connection options
interface ConnectOptions {
  redirectUri?: string;
}

// Signing options
interface SignOptions {
  instructions: TransactionInstruction[];
  lookupTables?: AddressLookupTableAccount[];
  gasConfig?: {
    type: "paymaster";
    paymasterUrl: string;
  };
  redirectUrl?: string;
}

Constants

Theme Constants

// constants/theme.ts
export const Colors = {
  primary: "#512DA8",
  secondary: "#7C4DFF",
  success: "#4CAF50",
  error: "#F44336",
  warning: "#FF9800",

  background: {
    light: "#FFFFFF",
    dark: "#121212",
  },

  text: {
    light: "#000000",
    dark: "#FFFFFF",
  },
};

Network Constants

// Defined in services
export const DEVNET_RPC = "https://api.devnet.solana.com";
export const MAINNET_RPC = "https://api.mainnet-beta.solana.com";
export const PORTAL_URL = "https://portal.lazor.sh";
export const PAYMASTER_DEVNET = "https://kora.devnet.lazorkit.com";

Related Documentation