import { useCallback } from 'react'; import { usePersSDK } from '../providers/PersSDKProvider'; import type { TokenDTO, TokenMetadataDTO, PaginatedResponseDTO, TokenMetadataFilterOptions, RewardsFilterOptions, StampsFilterOptions } from '@explorins/pers-sdk'; /** * React hook for token operations in the PERS SDK * * Provides methods for fetching various types of tokens including credit, reward, and status tokens. * Supports both general token queries and specific contract-based token retrieval. * * @returns Token hook with methods for token management * * @example * ```typescript * function TokensComponent() { * const { getTokens, getActiveCreditToken, getRewardTokens } = useTokens(); * * const loadTokens = async () => { * try { * const tokens = await getTokens(); * const creditToken = await getActiveCreditToken(); * console.log('Loaded tokens:', tokens); * console.log('Active credit token:', creditToken); * } catch (error) { * console.error('Failed to load tokens:', error); * } * }; * * return ; * } * ``` */ export const useTokens = () => { const { sdk, isInitialized, isAuthenticated } = usePersSDK(); if (!isAuthenticated && isInitialized) { console.warn('SDK not authenticated. Some token operations may fail.'); } /** * Retrieves all tokens available to the current user * * @returns Promise resolving to array of tokens * @throws Error if SDK is not initialized * * @example * ```typescript * const { getTokens } = useTokens(); * const tokens = await getTokens(); * console.log('Available tokens:', tokens); * ``` */ const getTokens = useCallback(async (): Promise> => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.tokens.getTokens(); return result; } catch (error) { console.error('Failed to fetch tokens:', error); throw error; } }, [sdk, isInitialized]); /** * Retrieves the currently active credit token * * @returns Promise resolving to active credit token * @throws Error if SDK is not initialized * * @example * ```typescript * const { getActiveCreditToken } = useTokens(); * const creditToken = await getActiveCreditToken(); * console.log('Active credit token:', creditToken.name); * ``` */ const getActiveCreditToken = useCallback(async (): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.tokens.getActiveCreditToken(); return result; } catch (error) { console.error('Failed to fetch active credit token:', error); throw error; } }, [sdk, isInitialized]); /** * Retrieves all reward tokens available in the system * * @returns Promise resolving to array of reward tokens * @throws Error if SDK is not initialized * * @example * ```typescript * const { getRewardTokens } = useTokens(); * const rewardTokens = await getRewardTokens(); * console.log('Reward tokens:', rewardTokens); * ``` */ const getRewardTokens = useCallback(async (): Promise> => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.tokens.getRewardTokens(); return result; } catch (error) { console.error('Failed to fetch reward tokens:', error); throw error; } }, [sdk, isInitialized]); /** * Retrieves all available token types in the system * * @returns Promise resolving to array of token types * @throws Error if SDK is not initialized * * @example * ```typescript * const { getTokenTypes } = useTokens(); * const types = await getTokenTypes(); * console.log('Token types:', types); * ``` */ const getTokenTypes = useCallback(async (): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.tokens.getTokenTypes(); return result; } catch (error) { console.error('Failed to fetch token types:', error); throw error; } }, [sdk, isInitialized]); /** * Retrieves all status tokens (tokens that represent user status/achievements) * * @returns Promise resolving to array of status tokens * @throws Error if SDK is not initialized * * @example * ```typescript * const { getStatusTokens } = useTokens(); * const statusTokens = await getStatusTokens(); * console.log('Status tokens:', statusTokens); * ``` */ const getStatusTokens = useCallback(async (): Promise> => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.tokens.getStatusTokens(); return result; } catch (error) { console.error('Failed to fetch status tokens:', error); throw error; } }, [sdk, isInitialized]); /** * Retrieves a specific token by its contract address and optional token ID * * @param contractAddress - The contract address of the token * @param contractTokenId - Optional specific token ID within the contract * @returns Promise resolving to the token data * @throws Error if SDK is not initialized * * @example * ```typescript * const { getTokenByContract } = useTokens(); * const token = await getTokenByContract('0x123...', 'token-1'); * console.log('Token from contract:', token); * ``` */ const getTokenByContract = useCallback(async (contractAddress: string, contractTokenId?: string | null): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.tokens.getTokenByContract(contractAddress, contractTokenId); return result; } catch (error) { console.error('Failed to fetch token by contract:', error); throw error; } }, [sdk, isInitialized]); /** * Get all token metadata with filtering and pagination * * Retrieves token metadata (rewards/stamps) with server-side filtering. * Use tokenType: 'ERC1155' for rewards, 'ERC721' for stamps. * * @param options - Filter and pagination options * @returns Promise resolving to paginated token metadata * @throws Error if SDK is not initialized * * @example * ```typescript * const { getTokenMetadata } = useTokens(); * const rewards = await getTokenMetadata({ * tokenType: 'ERC1155', * active: true, * limit: 10 * }); * ``` */ const getTokenMetadata = useCallback(async (options?: TokenMetadataFilterOptions): Promise> => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.tokens.getTokenMetadata(options); return result; } catch (error) { console.error('Failed to fetch token metadata:', error); throw error; } }, [sdk, isInitialized]); /** * Get rewards (ERC1155 token metadata) with filtering and pagination * * Convenience method for fetching reward metadata. Rewards are ERC1155 tokens * that represent collectible items, vouchers, or other redeemable rewards. * * @param options - Filter and pagination options * @returns Promise resolving to paginated reward metadata * @throws Error if SDK is not initialized * * @example * ```typescript * const { getRewards } = useTokens(); * const rewards = await getRewards({ active: true, limit: 10 }); * console.log(`Found ${rewards.pagination.total} rewards`); * ``` */ const getRewards = useCallback(async (options?: RewardsFilterOptions): Promise> => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.tokens.getRewards(options); return result; } catch (error) { console.error('Failed to fetch rewards:', error); throw error; } }, [sdk, isInitialized]); /** * Get stamps (ERC721 token metadata) with filtering and pagination * * Convenience method for fetching stamp metadata. Stamps are ERC721 tokens * that represent achievements, badges, or collectible status markers. * * @param options - Filter and pagination options * @returns Promise resolving to paginated stamp metadata * @throws Error if SDK is not initialized * * @example * ```typescript * const { getStamps } = useTokens(); * const stamps = await getStamps({ active: true, limit: 10 }); * console.log(`Found ${stamps.pagination.total} stamps`); * ``` */ const getStamps = useCallback(async (options?: StampsFilterOptions): Promise> => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.tokens.getStamps(options); return result; } catch (error) { console.error('Failed to fetch stamps:', error); throw error; } }, [sdk, isInitialized]); return { getTokens, getActiveCreditToken, getRewardTokens, getTokenTypes, getStatusTokens, getTokenByContract, getTokenMetadata, getRewards, getStamps, isAvailable: isInitialized && !!sdk?.tokens, }; }; export type TokenHook = ReturnType;