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;