diff --git a/.env b/.env index f228f8356..d059346fd 100644 --- a/.env +++ b/.env @@ -58,3 +58,6 @@ VITE_APP_WALLET_CONNECT_PROJECT_ID="" # FEATURE FLAGS (Must equal "ON") VITE_APP_FLAG_DEVELOPMENT_MODE="" VITE_APP_FLAG_DEMO_MODE="" + +# Use legacy Netlify balances backend +VITE_APP_USE_LEGACY_BACKEND="" diff --git a/package.json b/package.json index 890a5ed9d..9ef26aceb 100644 --- a/package.json +++ b/package.json @@ -66,10 +66,10 @@ "pretty": "prettier . --write", "pretty:check": "prettier . --check", "dev": "vite --force", - "dev:netlify": "netlify dev", + "dev:netlify": "VITE_APP_USE_LEGACY_BACKEND=true netlify dev", "start": "vite start", "preview": "vite preview", - "build": "NODE_OPTIONS=--max-old-space-size=8192 vite build", + "build": "VITE_APP_USE_LEGACY_BACKEND=true NODE_OPTIONS=--max-old-space-size=8192 vite build", "build:cf": "vite build && vite build --mode page-function", "graphql:build": "graphclient build", "graphql:dev-server": "graphclient serve-dev", diff --git a/src/providers/App/hooks/useBalancesAPI.ts b/src/providers/App/hooks/useBalancesAPI.ts index 1b5220cdb..6e09ad7e1 100644 --- a/src/providers/App/hooks/useBalancesAPI.ts +++ b/src/providers/App/hooks/useBalancesAPI.ts @@ -4,6 +4,15 @@ import { Address } from 'viem'; import { DefiBalance, NFTBalance, TokenBalance } from '../../../types'; import { useNetworkConfigStore } from '../../NetworkConfig/useNetworkConfigStore'; +type BalanceResponse = { + tokens?: { data: TokenBalance[] }; + nfts?: { data: NFTBalance[] }; + defi?: { data: DefiBalance[] }; + error?: string; +}; + +const USE_LEGACY_BACKEND = import.meta.env.VITE_APP_USE_LEGACY_BACKEND === 'true'; + export default function useBalancesAPI() { const { chain, @@ -11,36 +20,64 @@ export default function useBalancesAPI() { } = useNetworkConfigStore(); const { t } = useTranslation('treasury'); - const getTokenBalances = useCallback( - async (address: Address): Promise<{ data?: TokenBalance[]; error?: string }> => { + const fetchBalancesNew = useCallback( + async (address: Address, flavors: string[]): Promise => { try { - const balancesResponse = await fetch( - `/.netlify/functions/tokenBalances?address=${address}&network=${chain.id}`, - ); - const balancesResponseBody = await balancesResponse.json(); - return balancesResponseBody; + const params = new URLSearchParams(); + params.append('address', address); + params.append('network', chain.id.toString()); + flavors.forEach(flavor => params.append('flavor', flavor)); + + const response = await fetch(`/api/balances?${params}`); + return await response.json(); } catch (e) { - console.error('Error while fetching treasury token balances', e); + console.error('Error while fetching balances', e); return { error: t('errorFetchingBalances') }; } }, - [chain, t], + [chain.id, t], ); - const getNFTBalances = useCallback( - async (address: Address): Promise<{ data?: NFTBalance[]; error?: string }> => { + const fetchBalancesLegacy = useCallback( + async ( + address: Address, + type: 'token' | 'nft' | 'defi', + ): Promise<{ data?: any; error?: string }> => { try { + const endpoint = + type === 'token' ? 'tokenBalances' : type === 'nft' ? 'nftBalances' : 'defiBalances'; const balancesResponse = await fetch( - `/.netlify/functions/nftBalances?address=${address}&network=${chain.id}`, + `/.netlify/functions/${endpoint}?address=${address}&network=${chain.id}`, ); - const balancesResponseBody = await balancesResponse.json(); - return balancesResponseBody; + return await balancesResponse.json(); } catch (e) { - console.error('Error while fetching treasury NFT balances', e); + console.error(`Error while fetching treasury ${type} balances`, e); return { error: t('errorFetchingBalances') }; } }, - [chain, t], + [chain.id, t], + ); + + const getTokenBalances = useCallback( + async (address: Address): Promise<{ data?: TokenBalance[]; error?: string }> => { + if (USE_LEGACY_BACKEND) { + return fetchBalancesLegacy(address, 'token'); + } + const response = await fetchBalancesNew(address, ['tokens']); + return { data: response.tokens?.data, error: response.error }; + }, + [fetchBalancesNew, fetchBalancesLegacy], + ); + + const getNFTBalances = useCallback( + async (address: Address): Promise<{ data?: NFTBalance[]; error?: string }> => { + if (USE_LEGACY_BACKEND) { + return fetchBalancesLegacy(address, 'nft'); + } + const response = await fetchBalancesNew(address, ['nfts']); + return { data: response.nfts?.data, error: response.error }; + }, + [fetchBalancesNew, fetchBalancesLegacy], ); const getDeFiBalances = useCallback( @@ -48,18 +85,13 @@ export default function useBalancesAPI() { if (!deFiSupported) { return { data: [] }; } - try { - const balancesResponse = await fetch( - `/.netlify/functions/defiBalances?address=${address}&network=${chain.id}`, - ); - const balancesResponseBody = await balancesResponse.json(); - return balancesResponseBody; - } catch (e) { - console.error('Error while fetching treasury DeFi balances', e); - return { error: t('errorFetchingBalances') }; + if (USE_LEGACY_BACKEND) { + return fetchBalancesLegacy(address, 'defi'); } + const response = await fetchBalancesNew(address, ['defi']); + return { data: response.defi?.data, error: response.error }; }, - [chain, t, deFiSupported], + [deFiSupported, fetchBalancesNew, fetchBalancesLegacy], ); return { getTokenBalances, getNFTBalances, getDeFiBalances }; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index b47032e8f..61822dfb3 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -5,6 +5,7 @@ // Netlify (or a local `.env.local` file) will override these environment variables. interface ImportMetaEnv { readonly PACKAGE_VERSION: string; + readonly VITE_APP_USE_LEGACY_BACKEND: string; readonly VITE_APP_NAME: string; diff --git a/vite.config.mts b/vite.config.mts index a2f6b8d32..8f9c9320d 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -6,7 +6,11 @@ import packageJson from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react(), checker({ typescript: true }), viteWranglerSpa()], + plugins: [ + react(), + checker({ typescript: true }), + process.env.VITE_APP_USE_LEGACY_BACKEND !== 'true' ? viteWranglerSpa() : null, + ], server: { port: 3000, },