@jim4565/dapp-wrapper-react
Version: 
React components and hooks for @jim4565/dapp-wrapper with persistent wallet connection
588 lines (576 loc) • 18.1 kB
TypeScript
import React, { ReactNode } from 'react';
interface WalletState {
    address: string | undefined;
    isConnected: boolean;
    isConnecting: boolean;
    isReconnecting: boolean;
    isDisconnecting: boolean;
    error: Error | null;
}
interface WalletActions {
    connect: () => Promise<void>;
    disconnect: () => void;
    reconnect: () => Promise<void>;
}
interface ContractConfig {
    name: string;
    address: string;
    abi: any[];
}
interface ContractInstance {
    address: string;
    abi: any[];
    [key: string]: any;
}
type ContractFunctionType = 'view' | 'pure' | 'nonpayable' | 'payable';
interface ContractReadOptions {
    enabled?: boolean;
    refetchInterval?: number;
    onSuccess?: (data: any) => void;
    onError?: (error: Error) => void;
}
interface ContractWriteOptions {
    onSuccess?: (data: any) => void;
    onError?: (error: Error) => void;
    onSettled?: () => void;
}
interface TransactionState {
    isLoading: boolean;
    isError: boolean;
    isSuccess: boolean;
    error: Error | null;
    data: any;
}
interface TransactionRequest {
    to: string;
    data?: string;
    value?: string;
    gasLimit?: string;
    gasPrice?: string;
}
interface IncentivWalletConfig {
    contracts?: ContractConfig[];
    autoConnect?: boolean;
    reconnectOnMount?: boolean;
    pollingInterval?: number;
}
interface UseIncentivWalletReturn extends WalletState, WalletActions {
    balance: string | undefined;
    isBalanceLoading: boolean;
    refreshBalance: () => Promise<void>;
    isReady: boolean;
    connector: string | undefined;
}
interface UseContractReturn<T = ContractInstance> {
    contract: T | undefined;
    isLoading: boolean;
    error: Error | null;
}
interface UseContractReadReturn<T = any> {
    data: T | undefined;
    isLoading: boolean;
    error: Error | null;
    refetch: () => Promise<void>;
    lastFetched: number;
}
interface UseContractWriteReturn {
    write: (...args: any[]) => void;
    writeAsync: (...args: any[]) => Promise<any>;
    data: any;
    isLoading: boolean;
    error: Error | null;
    reset: () => void;
}
interface UseTransactionReturn extends TransactionState {
    sendTransaction: (txRequest: TransactionRequest) => Promise<any>;
    reset: () => void;
}
interface StoredWalletData {
    address: string | null;
    wasConnected: boolean;
    hasEverConnected: boolean;
    lastConnectedAt: number;
}
declare enum WalletErrorCode {
    USER_REJECTED = 4001,
    UNAUTHORIZED = 4100,
    UNSUPPORTED_METHOD = 4200,
    DISCONNECTED = 4900,
    CHAIN_DISCONNECTED = 4901,
    UNKNOWN_ERROR = -1
}
declare class WalletError extends Error {
    code: WalletErrorCode;
    reason?: string;
    method?: string;
    constructor(message: string, options?: {
        code?: WalletErrorCode;
        reason?: string;
        method?: string;
        cause?: unknown;
    });
}
type WalletActionType = 'SET_CONNECTING' | 'SET_RECONNECTING' | 'SET_CONNECTED' | 'SET_DISCONNECTING' | 'SET_DISCONNECTED' | 'SET_ERROR' | 'CLEAR_ERROR' | 'RESET_STATE';
interface WalletAction {
    type: WalletActionType;
    payload?: any;
}
interface WalletEvent {
    type: 'connect' | 'disconnect' | 'accountsChanged' | 'chainChanged' | 'error';
    data?: any;
}
declare const STORAGE_KEYS: {
    readonly WALLET_ADDRESS: "incentiv_wallet_address";
    readonly WALLET_CONNECTED: "incentiv_wallet_connected";
    readonly EVER_CONNECTED: "incentiv_wallet_ever_connected";
    readonly LAST_CONNECTED_AT: "incentiv_wallet_last_connected";
    readonly CONTRACTS: "incentiv_wallet_contracts";
};
type StorageKey = typeof STORAGE_KEYS[keyof typeof STORAGE_KEYS];
/**
 * Context Interface - wagmi-inspired API
 */
interface IncentivWalletContextValue extends WalletState, WalletActions {
    isReady: boolean;
    connector: string | undefined;
    registerContracts: (contracts: ContractConfig[]) => void;
    getContract: (name: string) => any;
    refreshBalance: () => Promise<void>;
    balance: string | undefined;
    isBalanceLoading: boolean;
}
/**
 * Provider Props
 */
interface IncentivWalletProviderProps {
    children: ReactNode;
    config?: IncentivWalletConfig;
    enableLogging?: boolean;
}
/**
 * IncentivWalletProvider - Professional React Context Provider
 *
 * Implements 3-Tier Reconnection Strategy and provides wagmi-style API
 * for seamless wallet connection management across the entire app.
 */
declare const IncentivWalletProvider: React.FC<IncentivWalletProviderProps>;
/**
 * Hook to use the wallet context
 */
declare const useIncentivWalletContext: () => IncentivWalletContextValue;
/**
 * useIncentivWallet - Main wallet hook (wagmi-inspired)
 *
 * Primary hook for accessing wallet connection state and actions.
 * Provides a clean, type-safe API similar to wagmi's useAccount.
 */
declare function useIncentivWallet(): UseIncentivWalletReturn;
/**
 * useContract - Contract interaction hook
 *
 * Provides access to registered smart contracts with full typing support.
 * Returns the contract instance with all methods available from your @jim4565/dapp-wrapper.
 *
 * WICHTIG: Seit @jim4565/dapp-wrapper v1.x unterstützt dieser Hook sowohl:
 * - view/pure Funktionen: Funktionieren OHNE Wallet-Verbindung
 * - nonpayable/payable Funktionen: Erfordern eine Wallet-Verbindung
 *
 * Die Unterscheidung passiert automatisch basierend auf der ABI stateMutability.
 */
declare function useContract<T = ContractInstance>(contractName: string): UseContractReturn<T>;
/**
 * useContractRead - Read-only contract interactions
 *
 * Optimized hook for contract read operations with automatic refetching.
 *
 * WICHTIG: Dieser Hook ist für view/pure Funktionen optimiert und funktioniert
 * OHNE Wallet-Verbindung. Die @jim4565/dapp-wrapper Bibliothek erkennt automatisch
 * view/pure Funktionen und führt sie direkt mit dem Provider aus.
 */
declare function useContractRead<T = any>(contractName: string, methodName: string, args?: any[], options?: {
    enabled?: boolean;
    refetchInterval?: number;
    onSuccess?: (data: T) => void;
    onError?: (error: Error) => void;
}): {
    data: T | undefined;
    isLoading: boolean;
    error: Error | null;
    refetch: () => Promise<void>;
    lastFetched: number;
};
/**
 * useContractWrite - Write contract interactions
 *
 * Hook for contract write operations with transaction handling.
 *
 * WICHTIG: Dieser Hook ist für nonpayable/payable Funktionen gedacht und erfordert
 * eine Wallet-Verbindung. Die @jim4565/dapp-wrapper Bibliothek prüft automatisch
 * die Wallet-Verbindung für schreibende Operationen.
 */
declare function useContractWrite(contractName: string, methodName: string, options?: {
    onSuccess?: (data: any) => void;
    onError?: (error: Error) => void;
    onSettled?: () => void;
}): {
    write: (...args: any[]) => void;
    writeAsync: (...args: any[]) => Promise<any>;
    data: any;
    isLoading: boolean;
    error: Error | null;
    reset: () => void;
};
/**
 * useTransaction - Transaction handling hook
 *
 * Provides utilities for sending transactions with proper state management,
 * error handling, and success callbacks.
 *
 * WICHTIG: Transaktionen erfordern IMMER eine Wallet-Verbindung, da sie eine
 * Signatur benötigen. Dies ist unabhängig von der neuen view/pure Funktionalität.
 */
declare function useTransaction(options?: {
    onSuccess?: (data: any) => void;
    onError?: (error: Error) => void;
    onSettled?: () => void;
}): UseTransactionReturn;
/**
 * useWaitForTransaction - Wait for transaction confirmation
 *
 * Hook to wait for transaction confirmation with timeout and retry logic.
 */
declare function useWaitForTransaction(options?: {
    timeout?: number;
    confirmations?: number;
    onSuccess?: (receipt: any) => void;
    onError?: (error: Error) => void;
}): {
    waitForTransaction: (txHash: string) => Promise<any>;
    isLoading: boolean;
    error: Error | null;
    receipt: any;
    reset: () => void;
};
/**
 * useSendTransactionAndWait - Combined hook for sending and waiting
 *
 * Convenience hook that combines transaction sending with waiting for confirmation.
 */
declare function useSendTransactionAndWait(options?: {
    timeout?: number;
    confirmations?: number;
    onTxSent?: (txHash: string) => void;
    onSuccess?: (receipt: any) => void;
    onError?: (error: Error) => void;
}): {
    sendTransactionAndWait: (txRequest: TransactionRequest) => Promise<any>;
    isLoading: boolean;
    error: Error | null;
    txHash: string | null;
    receipt: any;
    step: "error" | "confirmed" | "idle" | "sending" | "waiting";
    reset: () => void;
};
/**
 * ConnectButton Props
 */
interface ConnectButtonProps {
    /** Custom text for connect state */
    connectText?: string;
    /** Custom text for connecting state */
    connectingText?: string;
    /** Custom text for reconnecting state */
    reconnectingText?: string;
    /** Custom text for disconnect action */
    disconnectText?: string;
    /** Show address when connected */
    showAddress?: boolean;
    /** Show balance when connected */
    showBalance?: boolean;
    /** Custom CSS class */
    className?: string;
    /** Custom styles */
    style?: React.CSSProperties;
    /** Show full address instead of truncated */
    showFullAddress?: boolean;
    /** Custom onClick handler (overrides default behavior) */
    onClick?: () => void;
    /** Disabled state */
    disabled?: boolean;
    /** Size variant */
    size?: 'small' | 'medium' | 'large';
    /** Color variant */
    variant?: 'primary' | 'secondary' | 'outline';
}
/**
 * ConnectButton - Professional wallet connection button
 *
 * Handles all connection states and provides a clean UX for wallet interaction.
 * Follows modern Web3 patterns with proper loading states and error handling.
 */
declare const ConnectButton: React.FC<ConnectButtonProps>;
/**
 * Simplified ConnectButton without styling (unstyled version)
 */
declare const ConnectButtonUnstyled: React.FC<ConnectButtonProps>;
/**
 * WalletStatus Props
 */
interface WalletStatusProps {
    /** Show balance in the status */
    showBalance?: boolean;
    /** Currency symbol for balance */
    symbol?: string;
    /** Balance decimal places */
    balanceDecimals?: number;
    /** Show full address instead of truncated */
    showFullAddress?: boolean;
    /** Show connection status text */
    showStatus?: boolean;
    /** Custom CSS class */
    className?: string;
    /** Custom styles */
    style?: React.CSSProperties;
    /** Orientation of the status display */
    orientation?: 'horizontal' | 'vertical';
    /** Size variant */
    size?: 'small' | 'medium' | 'large';
}
/**
 * WalletStatus - Professional wallet status display
 *
 * Shows current wallet connection state, address, balance, and other relevant information.
 * Provides different display modes and styling options.
 */
declare const WalletStatus: React.FC<WalletStatusProps>;
/**
 * Minimal WalletStatus - Simplified version
 */
declare const WalletStatusMinimal: React.FC<{
    className?: string;
    style?: React.CSSProperties;
}>;
/**
 * WalletStatusCard - Card-style display
 */
declare const WalletStatusCard: React.FC<{
    className?: string;
    style?: React.CSSProperties;
}>;
/**
 * PersistenceService - MetaMask-style LocalStorage Management
 *
 * Handles secure storage and retrieval of wallet connection data
 * with proper error handling and data validation.
 */
declare class PersistenceService {
    private static readonly VERSION;
    private static readonly STORAGE_PREFIX;
    /**
     * Save wallet connection data securely
     */
    static saveWalletData(address: string): void;
    /**
     * Load stored wallet connection data
     */
    static loadWalletData(): StoredWalletData;
    /**
     * Clear all wallet-related data
     */
    static clearWalletData(): void;
    /**
     * Save contract configurations
     */
    static saveContracts(contracts: ContractConfig[]): void;
    /**
     * Load contract configurations
     */
    static loadContracts(): {
        name: string;
        address: string;
        hasABI: boolean;
    }[];
    /**
     * Check if wallet should auto-reconnect
     *
     * Returns true only if:
     * 1. User has ever connected before (prevents popup for first-time users)
     * 2. Was connected in last session
     * 3. Has valid stored address
     * 4. Connection is not too old
     */
    static shouldAutoReconnect(): boolean;
    /**
     * Get storage usage statistics
     */
    static getStorageStats(): {
        totalItems: number;
        totalSize: number;
        items: any[];
    };
    /**
     * Validate if address format is correct
     */
    private static isValidAddress;
    /**
     * Get empty wallet data structure
     */
    private static getEmptyWalletData;
    /**
     * Check if localStorage is available
     */
    static isStorageAvailable(): boolean;
    /**
     * Migrate data from old storage format (if needed)
     */
    static migrateStorageIfNeeded(): void;
}
/**
 * IncentivWalletService - Professional wrapper around @jim4565/dapp-wrapper
 *
 * Provides MetaMask-style connection patterns and 3-tier reconnection strategy
 * for seamless integration with React components.
 */
declare class IncentivWalletService {
    private wrapper;
    private isInitialized;
    private eventListeners;
    constructor();
    /**
     * Initialize with IncentivWrapper instance
     */
    initialize(wrapperInstance?: any): Promise<void>;
    /**
     * 3-TIER RECONNECTION STRATEGY
     * Following MetaMask and wagmi best practices
     */
    /**
     * TIER 1: Silent Connection Check
     * Check if SDK already has an active session without triggering any popups
     */
    checkSilentConnection(): Promise<string | null>;
    /**
     * TIER 2: Session Restore
     * Try to restore previous session without user interaction
     */
    tryRestoreSession(expectedAddress: string): Promise<boolean>;
    /**
     * TIER 3: Full Connect
     * Complete connection flow with user interaction (popup)
     */
    connect(): Promise<string>;
    /**
     * Get wallet balance with multiple fallback strategies
     */
    getBalance(address?: string): Promise<string>;
    /**
     * Get contract instance
     */
    getContract(contractName: string): ContractInstance | null;
    /**
     * Register contracts with the wrapper
     */
    registerContracts(contracts: ContractConfig[]): void;
    /**
     * Send transaction through wrapper
     */
    sendTransaction(txRequest: any): Promise<any>;
    /**
     * Disconnect wallet
     */
    disconnect(): void;
    /**
     * Check if wallet is connected
     */
    isConnected(): boolean;
    /**
     * Get current user address
     */
    getUserAddress(): Promise<string | null>;
    /**
     * Event handling (MetaMask-style)
     */
    on(event: string, callback: Function): void;
    off(event: string, callback: Function): void;
    private emit;
    /**
     * Initialize event handlers for wrapper events
     */
    private initializeEventHandlers;
    /**
     * Extract address from wrapper with multiple fallback strategies
     */
    private extractAddressFromWrapper;
    /**
     * Debug wrapper state for troubleshooting
     */
    private debugWrapperState;
    /**
     * Normalize and validate Ethereum address with flexible handling
     * Handles various formats that MetaMask/wallets might return
     */
    private normalizeAndValidateAddress;
    /**
     * Legacy method for backward compatibility
     */
    private isValidAddress;
    /**
     * Cleanup resources
     */
    destroy(): void;
}
/**
 * Initial Wallet State
 */
declare const initialWalletState: WalletState;
/**
 * Wallet State Reducer
 *
 * Follows Redux patterns for predictable state management
 * with proper error handling and loading states.
 */
declare function walletReducer(state: WalletState, action: WalletAction): WalletState;
/**
 * Action Creators - Type-safe action creation
 */
declare const walletActions: {
    setConnecting: () => WalletAction;
    setReconnecting: () => WalletAction;
    setConnected: (address: string) => WalletAction;
    setDisconnecting: () => WalletAction;
    setDisconnected: (error?: Error) => WalletAction;
    setError: (error: Error) => WalletAction;
    clearError: () => WalletAction;
    resetState: (keepError?: boolean) => WalletAction;
};
/**
 * Selector functions for derived state
 */
declare const walletSelectors: {
    /**
     * Check if any loading state is active
     */
    isLoading: (state: WalletState) => boolean;
    /**
     * Check if wallet is ready for transactions
     */
    isReady: (state: WalletState) => boolean;
    /**
     * Get formatted address for display
     */
    getDisplayAddress: (state: WalletState) => string;
    /**
     * Check if error should be displayed to user
     */
    shouldShowError: (state: WalletState) => boolean;
    /**
     * Get user-friendly error message
     */
    getErrorMessage: (state: WalletState) => string;
    /**
     * Get current connection status
     */
    getConnectionStatus: (state: WalletState) => string;
};
export { ConnectButton, ConnectButtonUnstyled, IncentivWalletProvider, IncentivWalletService, PersistenceService, STORAGE_KEYS, WalletError, WalletErrorCode, WalletStatus, WalletStatusCard, WalletStatusMinimal, initialWalletState, useIncentivWallet as useAccount, useContract, useContractRead, useContractWrite, useIncentivWallet, useIncentivWalletContext, useSendTransactionAndWait, useTransaction, useWaitForTransaction, walletActions, walletReducer, walletSelectors };
export type { ConnectButtonProps, ContractConfig, ContractFunctionType, ContractInstance, ContractReadOptions, ContractWriteOptions, IncentivWalletConfig, StorageKey, StoredWalletData, TransactionRequest, TransactionState, UseContractReadReturn, UseContractReturn, UseContractWriteReturn, UseIncentivWalletReturn, UseTransactionReturn, WalletAction, WalletActionType, WalletActions, WalletEvent, WalletState, WalletStatusProps };