Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some fixes in fetching balances and gases, closes FRONT-363 #1095

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions components/Input/CurrencyFormField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { resolveNetworkRoutesURL } from "../../helpers/routes";
import useWallet from "../../hooks/useWallet";
import { ONE_WEEK } from "./NetworkFormField";
import RouteIcon from "./RouteIcon";
import useBalance from "../../hooks/useBalance";

const BalanceComponent = dynamic(() => import("./dynamic/Balance"), {
loading: () => <></>,
Expand All @@ -34,6 +35,7 @@ const CurrencyFormField: FC<{ direction: SwapDirection }> = ({ direction }) => {
const name = direction === 'from' ? 'fromCurrency' : 'toCurrency';
const query = useQueryState()
const { balances } = useBalancesState()
const { fetchBalance } = useBalance()

const { getAutofillProvider: getProvider } = useWallet()

Expand Down Expand Up @@ -140,6 +142,23 @@ const CurrencyFormField: FC<{ direction: SwapDirection }> = ({ direction }) => {
}, [toCurrency, currencyGroup, name, from, routes, error, isLoading])


const network = direction === 'from' ? from : to
const token = direction === 'from' ? fromCurrency : toCurrency
useEffect(() => {
let balanceGetHandler: any = undefined
if (network && token) {
(async () => {
balanceGetHandler = setInterval(async () => {
await fetchBalance(network, token);
}, 60000)
})()
}
return () => {
clearInterval(balanceGetHandler)
}
}, [network, token])


const handleSelect = useCallback((item: SelectMenuItem<RouteToken>) => {
setFieldValue(name, item.baseObject, true)
}, [name, direction, toCurrency, fromCurrency, from, to])
Expand Down
18 changes: 9 additions & 9 deletions components/Input/dynamic/MinMax.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo } from "react"
import { useCallback, useEffect, useMemo, useState } from "react"
import useWallet from "../../../hooks/useWallet"
import SecondaryButton from "../../buttons/secondaryButton"
import { useFormikContext } from "formik";
Expand All @@ -13,15 +13,15 @@ const MinMax = ({ onAddressGet }: { onAddressGet: (address: string) => void }) =
const { values, setFieldValue } = useFormikContext<SwapFormValues>();
const { fromCurrency, from, destination_address } = values || {};
const { minAllowedAmount, maxAllowedAmount: maxAmountFromApi } = useFee()
const { balances, gases } = useBalancesState()
const { balances, gases, isBalanceLoading, isGasLoading } = useBalancesState()
const query = useQueryState()

const { getAutofillProvider: getProvider } = useWallet()
const provider = useMemo(() => {
return from && getProvider(from)
}, [from, getProvider])

const { fetchNetworkBalances, fetchGas } = useBalance()
const { fetchBalance, fetchGas } = useBalance()

const wallet = provider?.getConnectedWallet(values.from)

Expand Down Expand Up @@ -55,13 +55,13 @@ const MinMax = ({ onAddressGet }: { onAddressGet: (address: string) => void }) =
maxAllowedAmount = Number(maxAmountFromApi) || 0
}

const handleSetMaxAmount = useCallback(async () => {
const handleSetMaxAmount = async () => {
setFieldValue('amount', maxAllowedAmount);
from && fetchNetworkBalances(from);

from && fromCurrency && fetchGas(from, fromCurrency, wallet?.address || destination_address || "");

}, [from, fromCurrency, destination_address, maxAllowedAmount])
if (from && fromCurrency) {
if (!isBalanceLoading) await fetchBalance(from, fromCurrency);
if (!isGasLoading) await fetchGas(from, fromCurrency, destination_address || wallet?.address || "");
}
}

useEffect(() => {
wallet?.address && onAddressGet(wallet.address)
Expand Down
5 changes: 5 additions & 0 deletions components/Swap/Form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { AddressGroup } from "../../Input/Address/AddressPicker";
import { useAsyncModal } from "../../../context/asyncModal";
import { ValidationProvider } from "../../../context/validationErrorContext";
import { TrackEvent } from "../../../pages/_document";
import useBalance from "../../../hooks/useBalance";

type NetworkToConnect = {
DisplayName: string;
Expand Down Expand Up @@ -65,6 +66,7 @@ export default function Form() {
const { getSourceProvider } = useWallet()
const addresses = useAddressesStore(state => state.addresses)
const { getConfirmation } = useAsyncModal();
const { fetchBalance } = useBalance()

const settings = useSettingsState();
const query = useQueryState()
Expand Down Expand Up @@ -169,6 +171,9 @@ export default function Form() {
pollFee(!value)
setShowSwapModal(value)
value && swap?.id ? setSwapPath(swap?.id, router) : removeSwapPath(router)
if (value === false && swap?.source_network) {
fetchBalance(swap?.source_network, swap?.source_token)
}
}, [router, swap])

return <DepositMethodProvider canRedirect onRedirect={() => handleShowSwapModal(false)}>
Expand Down
105 changes: 62 additions & 43 deletions hooks/useBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useBalancesState, useBalancesUpdate } from "../context/balances"
import { Network, NetworkWithTokens, Token } from "../Models/Network"
import { useQueryState } from "../context/query"
import useTonBalance from "../lib/balances/ton/useTonBalance"
import useIsWindowVisible from "./useIsWindowVisible"

export default function useBalanceProvider() {

Expand All @@ -23,7 +24,7 @@ export default function useBalanceProvider() {
useTonBalance()
]

const { balances, gases } = useBalancesState()
const { balances, gases, isBalanceLoading } = useBalancesState()
const query = useQueryState()

const {
Expand All @@ -34,87 +35,105 @@ export default function useBalanceProvider() {
} = useBalancesUpdate()

const { getAutofillProvider } = useWallet()
const isWindowVisible = useIsWindowVisible()

const fetchNetworkBalances = async (network: NetworkWithTokens, address?: string) => {
if (!isWindowVisible) return

const provider = getAutofillProvider(network)
const wallet = provider?.getConnectedWallet(network)
address = address || query.account || wallet?.address

const balance = balances[address || '']?.find(b => b?.network === network?.name)
const isBalanceOutDated = !balance || new Date().getTime() - (new Date(balance.request_time).getTime() || 0) > 10000
const balance = address ? balances[address]?.find(b => b?.network === network?.name) : undefined
const isBalanceOutDated = !balance || (balance.request_time ? (new Date().getTime() - new Date(balance.request_time).getTime() > 15000) : true)

if (network
&& isBalanceOutDated
&& address) {
setIsBalanceLoading(true)

const provider = getBalanceProvider(network)
const networkBalances = await provider?.getNetworkBalances({
networkName: network.name,
address: address,
}) || []

setAllBalances((data) => {
const walletBalances = data[address]
const otherNetworkBalances = walletBalances?.filter(b => b?.network !== network.name) || []
return { ...data, [address]: [...otherNetworkBalances, ...networkBalances] }
})
setIsBalanceLoading(false)
try {
setIsBalanceLoading(true)

const provider = getBalanceProvider(network)
const networkBalances = await provider?.getNetworkBalances({
networkName: network.name,
address: address,
})

if (networkBalances) {
setAllBalances((data) => {
const walletBalances = data[address]
const otherNetworkBalances = walletBalances?.filter(b => b?.network !== network.name) || []
return { ...data, [address]: [...otherNetworkBalances, ...networkBalances] }
})
}

}
catch (e) { console.log(e) }
finally { setIsBalanceLoading(false) }
}
}

const fetchBalance = async (network: Network, token: Token, address?: string) => {
if (!isWindowVisible) return

const provider = getAutofillProvider(network)
const wallet = provider?.getConnectedWallet(network)
address = address || query.account || wallet?.address

const balance = balances[address || '']?.find(b => b?.network === network?.name)
const isBalanceOutDated = !balance || new Date().getTime() - (new Date(balance.request_time).getTime() || 0) > 10000
const balance = balances[address || '']?.find(b => b?.network === network?.name && b?.token === token?.symbol)
const isBalanceOutDated = !balance || (balance.request_time ? (new Date().getTime() - new Date(balance.request_time).getTime() > 15000) : true)

if (network
&& isBalanceOutDated
&& address) {
setIsBalanceLoading(true)

const provider = getBalanceProvider(network)
const balance = await provider?.getBalance({
networkName: network.name,
address: address,
token
})

setAllBalances((data) => {
const walletBalances = data[address]
const filteredBalances = walletBalances?.filter(b => !(b?.network === network?.name && b?.token === token?.symbol)) || []
return { ...data, [address]: filteredBalances?.concat(balance || []) }
})
setIsBalanceLoading(false)

return balance
try {
setIsBalanceLoading(true)

const provider = getBalanceProvider(network)
const newBalance = await provider?.getBalance({
networkName: network.name,
address: address,
token
})

setAllBalances((data) => {
const walletBalances = data[address]
const filteredBalances = walletBalances?.filter(b => !(b?.network === network?.name && b?.token === token?.symbol)) || []
return { ...data, [address]: filteredBalances?.concat(newBalance || []) }
})

return newBalance


}
catch (e) { console.log(e) }
finally { setIsBalanceLoading(false) }
}

return balance
}

const fetchGas = async (network: Network, token: Token, userDestinationAddress: string, recipientAddress?: string) => {

if (!network) {
if (!network || !isWindowVisible) {
return
}

const destination_address = userDestinationAddress as `0x${string}`
const gas = gases[network.name]?.find(g => g?.token === token?.symbol)
const isGasOutDated = !gas || new Date().getTime() - (new Date(gas.request_time).getTime() || 0) > 10000
const isGasOutDated = !gas || (gas.request_time ? (new Date().getTime() - new Date(gas.request_time).getTime() > 15000) : true)

const provider = getAutofillProvider(network)
const wallet = provider?.getConnectedWallet(network)

if (isGasOutDated
if (
isGasOutDated
&& token
&& wallet?.address
&& destination_address) {
setIsGasLoading(true)
&& destination_address
) {
try {
setIsGasLoading(true)

const gasProvider = getBalanceProvider(network)
const gas = gasProvider?.getGas && await gasProvider?.getGas({
address: wallet?.address as `0x${string}`,
Expand All @@ -123,7 +142,7 @@ export default function useBalanceProvider() {
recipientAddress,
isSweeplessTx: wallet.address !== userDestinationAddress,
wallet
}) || []
})

if (gas) {
setAllGases((data) => {
Expand Down
33 changes: 33 additions & 0 deletions hooks/useIsWindowVisible.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useCallback, useEffect, useState } from 'react'

function isVisibilityStateSupported() {
return 'visibilityState' in document
}

function isWindowVisible() {
return !isVisibilityStateSupported() || document.visibilityState !== 'hidden'
}

/**
* Returns whether the window is currently visible to the user.
*/
export default function useIsWindowVisible(): boolean {
const [focused, setFocused] = useState<boolean>(false)
const listener = useCallback(() => {
setFocused(isWindowVisible())
}, [setFocused])

useEffect(() => {
if (!isVisibilityStateSupported()) {
return undefined
}
setFocused(() => isWindowVisible())

document.addEventListener('visibilitychange', listener)
return () => {
document.removeEventListener('visibilitychange', listener)
}
}, [listener])

return focused
}
4 changes: 3 additions & 1 deletion lib/balances/evm/useEVMBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ export default function useEVMBalance(): BalanceProvider {

const gas = await gasProvider.resolveGas()

return [gas!]
if (!gas) return

return [gas]

}
catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
Loading