diff --git a/earn/src/App.tsx b/earn/src/App.tsx index b43c7b742..1f84c6fff 100644 --- a/earn/src/App.tsx +++ b/earn/src/App.tsx @@ -10,7 +10,7 @@ import WagmiProvider from 'shared/lib/components/WagmiProvider'; import { AccountRiskResult } from 'shared/lib/data/AccountRisk'; import { screenAddress } from 'shared/lib/data/AccountRisk'; import { DEFAULT_CHAIN, PRIVACY_POLICY_URL, TERMS_OF_SERVICE_URL } from 'shared/lib/data/constants/Values'; -import { fetchGeoFencing, GeoFencingResponse } from 'shared/lib/data/GeoFencing'; +import { fetchGeoFencing, GeoFencingInfo } from 'shared/lib/data/GeoFencing'; import { AccountRiskContext, useAccountRisk } from 'shared/lib/data/hooks/UseAccountRisk'; import { useChainDependentState } from 'shared/lib/data/hooks/UseChainDependentState'; import useEffectOnce from 'shared/lib/data/hooks/UseEffectOnce'; @@ -168,7 +168,10 @@ function AppBodyWrapper() { function App() { const [activeChain, setActiveChain] = React.useState(DEFAULT_CHAIN); const [accountRisk, setAccountRisk] = useSafeState({ isBlocked: false, isLoading: true }); - const [geoFencingResponse, setGeoFencingResponse] = React.useState(null); + const [geoFencingInfo, setGeoFencingInfo] = useSafeState({ + isAllowed: false, + isLoading: true, + }); const [lendingPairs, setLendingPairs] = useChainDependentState(null, activeChain.id); const { address: userAddress } = useAccount(); @@ -177,16 +180,13 @@ function App() { const value = { activeChain, setActiveChain }; useEffectOnce(() => { - let mounted = true; (async () => { const result = await fetchGeoFencing(); - if (mounted) { - setGeoFencingResponse(result); - } + setGeoFencingInfo({ + isAllowed: result.isAllowed, + isLoading: false, + }); })(); - return () => { - mounted = false; - }; }); useEffect(() => { @@ -220,7 +220,7 @@ function App() { - + diff --git a/earn/src/data/hooks/UseAvailablePools.ts b/earn/src/data/hooks/UseAvailablePools.ts index 58398464b..38422b84a 100644 --- a/earn/src/data/hooks/UseAvailablePools.ts +++ b/earn/src/data/hooks/UseAvailablePools.ts @@ -46,7 +46,7 @@ export default function useAvailablePools() { const poolContract = new ethers.Contract(addr, uniswapV3PoolAbi, provider); return Promise.all([poolContract.token0(), poolContract.token1(), poolContract.fee()]); }) - ); + ); // TODO: multicall const poolInfoMap = new Map(); poolAddresses.forEach((addr, i) => { diff --git a/prime/src/App.tsx b/prime/src/App.tsx index 1312f75dc..c6ded180b 100644 --- a/prime/src/App.tsx +++ b/prime/src/App.tsx @@ -10,7 +10,7 @@ import WagmiProvider from 'shared/lib/components/WagmiProvider'; import { AccountRiskResult } from 'shared/lib/data/AccountRisk'; import { screenAddress } from 'shared/lib/data/AccountRisk'; import { DEFAULT_CHAIN, PRIVACY_POLICY_URL, TERMS_OF_SERVICE_URL } from 'shared/lib/data/constants/Values'; -import { fetchGeoFencing, GeoFencingResponse } from 'shared/lib/data/GeoFencing'; +import { fetchGeoFencing, GeoFencingInfo } from 'shared/lib/data/GeoFencing'; import { AccountRiskContext, useAccountRisk } from 'shared/lib/data/hooks/UseAccountRisk'; import useEffectOnce from 'shared/lib/data/hooks/UseEffectOnce'; import { GeoFencingContext } from 'shared/lib/data/hooks/UseGeoFencing'; @@ -163,20 +163,20 @@ function App() { const [isChainLoading, setIsChainLoading] = React.useState(true); const [blockNumber, setBlockNumber] = React.useState(null); const [accountRisk, setAccountRisk] = useSafeState({ isBlocked: false, isLoading: true }); - const [geoFencingResponse, setGeoFencingResponse] = React.useState(null); + const [geoFencingInfo, setGeoFencingInfo] = useSafeState({ + isAllowed: false, + isLoading: true, + }); const { address: userAddress } = useAccount(); useEffectOnce(() => { - let mounted = true; (async () => { const result = await fetchGeoFencing(); - if (mounted) { - setGeoFencingResponse(result); - } + setGeoFencingInfo({ + isAllowed: result.isAllowed, + isLoading: false, + }); })(); - return () => { - mounted = false; - }; }); useEffect(() => { @@ -233,7 +233,7 @@ function App() { - + diff --git a/prime/src/components/header/Header.tsx b/prime/src/components/header/Header.tsx index 4cf8f94cf..d01c984a5 100644 --- a/prime/src/components/header/Header.tsx +++ b/prime/src/components/header/Header.tsx @@ -44,7 +44,7 @@ export default function Header(props: HeaderProps) { activeChain={activeChain} checkboxes={checkboxes} setActiveChain={setActiveChain} - isAllowedToInteract={isAllowedToInteract} + isAllowedToInteract={isAllowedToInteract.isAllowed} /> ); diff --git a/prime/src/pages/BorrowAccountsPage.tsx b/prime/src/pages/BorrowAccountsPage.tsx index 72bd47f59..d0bf9f0dc 100644 --- a/prime/src/pages/BorrowAccountsPage.tsx +++ b/prime/src/pages/BorrowAccountsPage.tsx @@ -31,7 +31,7 @@ import { fetchMarginAccountPreviews, MarginAccountPreview, UniswapPoolInfo } fro export default function BorrowAccountsPage() { const { activeChain } = useContext(ChainContext); - const isAllowedToInteract = useGeoFencing(activeChain); + const { isAllowed: isAllowedToInteract, isLoading: isLoadingGeoFencing } = useGeoFencing(activeChain); // MARK: component state // --> transaction modals const [showConfirmModal, setShowConfirmModal] = useState(false); @@ -228,6 +228,12 @@ export default function BorrowAccountsPage() { }) .filter((opt) => opt !== null) as DropdownOption[]; + const loadingElement: JSX.Element = isAllowedToInteract ? ( + + ) : ( + Functionality unavailable in your jurisdiction + ); + return (
@@ -248,10 +254,8 @@ export default function BorrowAccountsPage() {
- {isLoadingMarginAccounts ? ( -
- -
+ {isLoadingMarginAccounts || isLoadingGeoFencing || !isAllowedToInteract ? ( +
{loadingElement}
) : ( )} diff --git a/prime/src/pages/BorrowActionsPage.tsx b/prime/src/pages/BorrowActionsPage.tsx index b4a7d333e..2f9d6c2b0 100644 --- a/prime/src/pages/BorrowActionsPage.tsx +++ b/prime/src/pages/BorrowActionsPage.tsx @@ -167,7 +167,7 @@ type AccountParams = { export default function BorrowActionsPage() { const { activeChain } = useContext(ChainContext); - const isAllowedToInteract = useGeoFencing(activeChain); + const { isAllowed: isAllowedToInteract } = useGeoFencing(activeChain); const navigate = useNavigate(); const params = useParams(); diff --git a/shared/src/data/GeoFencing.ts b/shared/src/data/GeoFencing.ts index 5370ec9b6..d982e36d1 100644 --- a/shared/src/data/GeoFencing.ts +++ b/shared/src/data/GeoFencing.ts @@ -6,6 +6,10 @@ export type GeoFencingResponse = { isAllowed: boolean; }; +export type GeoFencingInfo = GeoFencingResponse & { + isLoading: boolean; +}; + export async function fetchGeoFencing(): Promise { if (isDappnet()) { return { diff --git a/shared/src/data/hooks/UseGeoFencing.ts b/shared/src/data/hooks/UseGeoFencing.ts index 0b855d07a..b3d6763e7 100644 --- a/shared/src/data/hooks/UseGeoFencing.ts +++ b/shared/src/data/hooks/UseGeoFencing.ts @@ -1,12 +1,15 @@ import { createContext, useContext } from 'react'; import { isDevelopment } from '../../util/Utils'; import { Chain } from 'wagmi'; -import { GeoFencingResponse } from '../GeoFencing'; +import { GeoFencingInfo } from '../GeoFencing'; -export const GeoFencingContext = createContext(null); +export const GeoFencingContext = createContext({ + isAllowed: false, + isLoading: true, +}); export function useGeoFencing(activeChain: Chain) { const ctxt = useContext(GeoFencingContext); const isDev = isDevelopment(); - return isDev || ctxt?.isAllowed || Boolean(activeChain.testnet); + return { isAllowed: isDev || ctxt.isAllowed || Boolean(activeChain.testnet), isLoading: ctxt.isLoading }; }