From 009bfb864eb135d2c7a6e87fb591b8959c8db6f5 Mon Sep 17 00:00:00 2001 From: Dan Rusnac Date: Tue, 17 Dec 2024 12:15:30 +0100 Subject: [PATCH] feat: fetch app info --- .../ConnectModal/EcosystemAppsModal.tsx | 25 +++++-- .../hooks/useFetchAppInfo.ts | 69 +++++++++++++++++++ 2 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useFetchAppInfo.ts diff --git a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/components/ConnectModal/EcosystemAppsModal.tsx b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/components/ConnectModal/EcosystemAppsModal.tsx index 1b425af5..54d70160 100644 --- a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/components/ConnectModal/EcosystemAppsModal.tsx +++ b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/components/ConnectModal/EcosystemAppsModal.tsx @@ -3,6 +3,7 @@ import { Button, HStack, + Image, Modal, ModalBody, ModalCloseButton, @@ -10,6 +11,7 @@ import { ModalContentProps, ModalHeader, ModalOverlay, + Text, VStack, useColorMode, useMediaQuery, @@ -19,6 +21,7 @@ import { useWallet } from '../../hooks'; import { useEffect, useState } from 'react'; import { useDAppKitPrivyConfig } from '../../DAppKitPrivyProvider'; import { AppsLogo } from '../../assets'; +import { useFetchAppInfo } from '../../hooks/useFetchAppInfo'; type Props = { isOpen: boolean; @@ -42,9 +45,12 @@ export const EcosystemAppsModal = ({ isOpen, onClose }: Props) => { const { colorMode } = useColorMode(); const isDark = colorMode === 'dark'; - const { authenticated } = usePrivy(); const { privyConfig } = useDAppKitPrivyConfig(); - const ecosystemAppsID = privyConfig?.ecosystemAppsID; + const { data: appsInfo, isLoading } = useFetchAppInfo( + privyConfig?.ecosystemAppsID || [], + ); + + const { authenticated } = usePrivy(); const { loginWithCrossAppAccount, linkCrossAppAccount } = useCrossAppAccounts(); @@ -86,7 +92,7 @@ export const EcosystemAppsModal = ({ isOpen, onClose }: Props) => { justifyContent={'center'} alignItems={'center'} > - Select VeChain App + Select a VeChain App @@ -94,8 +100,8 @@ export const EcosystemAppsModal = ({ isOpen, onClose }: Props) => { - {ecosystemAppsID && - ecosystemAppsID.map((appId) => ( + {appsInfo && + Object.entries(appsInfo).map(([appId, appInfo]) => ( ))} diff --git a/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useFetchAppInfo.ts b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useFetchAppInfo.ts new file mode 100644 index 00000000..173f55cd --- /dev/null +++ b/packages/dapp-kit-react-privy/src/DAppKitPrivyProvider/hooks/useFetchAppInfo.ts @@ -0,0 +1,69 @@ +import { useEffect, useState } from 'react'; + +interface PrivyAppInfo { + id: string; + name: string; + logo_url: string; + icon_url: string | null; + terms_and_conditions_url: string; + privacy_policy_url: string; + theme: string; + accent_color: string; + wallet_auth: boolean; + email_auth: boolean; + google_oauth: boolean; + twitter_oauth: boolean; + // Add other fields as needed +} + +const fetchPrivyAppInfo = async (appId: string): Promise => { + const response = await fetch(`https://auth.privy.io/api/v1/apps/${appId}`, { + headers: { + 'privy-app-id': appId, + }, + }); + + if (!response.ok) { + throw new Error('Failed to fetch Privy app info'); + } + + return response.json(); +}; + +export function useFetchAppInfo(appIds: string | string[]) { + const [data, setData] = useState | null>(null); + const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + if (!appIds) return; + + const fetchData = async () => { + setIsLoading(true); + try { + const ids = Array.isArray(appIds) ? appIds : [appIds]; + const results = await Promise.all( + ids.map((id) => fetchPrivyAppInfo(id)), + ); + + const appInfoMap = Object.fromEntries( + results.map((result, index) => [ids[index], result]), + ); + + setData(appInfoMap); + setError(null); + } catch (err) { + setError( + err instanceof Error ? err : new Error('Unknown error'), + ); + setData(null); + } finally { + setIsLoading(false); + } + }; + + fetchData(); + }, [appIds]); + + return { data, error, isLoading }; +}