diff --git a/src/components/Sponsor/Web3Donation/components/Conversion/Conversion.tsx b/src/components/Sponsor/Web3Donation/components/Conversion/Conversion.tsx
index 5b948192..a0bc7a07 100644
--- a/src/components/Sponsor/Web3Donation/components/Conversion/Conversion.tsx
+++ b/src/components/Sponsor/Web3Donation/components/Conversion/Conversion.tsx
@@ -1,6 +1,6 @@
-import { type ReactElement } from 'react'
+import { useEffect, type ReactElement, useState } from 'react'
import styles from './Conversion.module.css'
-import type { GetToken } from '../../api/getTokens'
+import type { GetToken } from '../../hooks/useTokens'
export function Conversion({
amount,
@@ -9,12 +9,25 @@ export function Conversion({
amount: string
token: GetToken | undefined
}): ReactElement {
- const dollar = token?.price?.usd
- ? (Number(amount) * token?.price?.usd).toFixed(2)
- : '0.00'
- const euro = token?.price?.eur
- ? (Number(amount) * token?.price?.eur).toFixed(2)
- : '0.00'
+ const [dollar, setDollar] = useState('0.00')
+ const [euro, setEuro] = useState('0.00')
+
+ useEffect(() => {
+ if (!token?.price || !amount) {
+ setDollar('0.00')
+ setEuro('0.00')
+ return
+ }
+
+ const dollar = token?.price?.usd
+ ? (Number(amount) * token?.price?.usd).toFixed(2)
+ : '0.00'
+ const euro = token?.price?.eur
+ ? (Number(amount) * token?.price?.eur).toFixed(2)
+ : '0.00'
+ setDollar(dollar)
+ setEuro(euro)
+ }, [token?.price, amount])
return (
diff --git a/src/components/Sponsor/Web3Donation/components/Input/InputGroup.tsx b/src/components/Sponsor/Web3Donation/components/Input/InputGroup.tsx
index df706729..d264382e 100644
--- a/src/components/Sponsor/Web3Donation/components/Input/InputGroup.tsx
+++ b/src/components/Sponsor/Web3Donation/components/Input/InputGroup.tsx
@@ -4,7 +4,7 @@ import { Conversion } from '../Conversion'
import styles from './InputGroup.module.css'
import { TokenSelect } from '../Tokens'
import config from '@config/blog.config'
-import type { GetToken } from '../../api/getTokens'
+import type { GetToken } from '../../hooks/useTokens'
export function InputGroup({
amount,
@@ -23,7 +23,10 @@ export function InputGroup({
<>
-
+
{
token: GetToken | undefined
diff --git a/src/components/Sponsor/Web3Donation/components/Tokens/TokenSelect.tsx b/src/components/Sponsor/Web3Donation/components/Tokens/TokenSelect.tsx
index aff0c99f..0074c898 100644
--- a/src/components/Sponsor/Web3Donation/components/Tokens/TokenSelect.tsx
+++ b/src/components/Sponsor/Web3Donation/components/Tokens/TokenSelect.tsx
@@ -2,17 +2,22 @@ import * as Select from '@radix-ui/react-select'
import './TokenSelect.css'
import { Token } from './Token'
import { ChevronDown, ChevronsDown, ChevronsUp } from '@images/components/react'
-import { useTokens } from '../../hooks/useTokens'
+import { useTokens } from '../../hooks/useTokens/useTokens'
import { TokenLoading } from './TokenLoading'
-import type { GetToken } from '../../api/getTokens'
import { useEffect } from 'react'
+import type { GetToken } from '../../hooks/useTokens'
+import { useAccount, useNetwork } from 'wagmi'
export function TokenSelect({
+ selectedToken,
setTokenSelected
}: {
+ selectedToken: GetToken | undefined
setTokenSelected: React.Dispatch
>
}) {
const { data: tokens, isLoading } = useTokens()
+ const { chain } = useNetwork()
+ const { address } = useAccount()
const items = tokens?.map((token) => (
@@ -24,12 +29,16 @@ export function TokenSelect({
setTokenSelected(token)
}
- // set default token data
- useEffect(() => handleValueChange('0x0'), [])
+ // Set default token data to native token
+ useEffect(() => {
+ if (!chain?.id || !address || !tokens) return
- return tokens ? (
+ handleValueChange('0x0')
+ }, [chain?.id, address, tokens])
+
+ return (
handleValueChange(value)}
disabled={!tokens || isLoading}
>
@@ -63,5 +72,5 @@ export function TokenSelect({
- ) : null
+ )
}
diff --git a/src/components/Sponsor/Web3Donation/api/getTokens.ts b/src/components/Sponsor/Web3Donation/hooks/useTokens/getTokens.ts
similarity index 57%
rename from src/components/Sponsor/Web3Donation/api/getTokens.ts
rename to src/components/Sponsor/Web3Donation/hooks/useTokens/getTokens.ts
index b48a5982..24e79ef3 100644
--- a/src/components/Sponsor/Web3Donation/api/getTokens.ts
+++ b/src/components/Sponsor/Web3Donation/hooks/useTokens/getTokens.ts
@@ -1,26 +1,15 @@
-export type GetToken = {
- address: `0x${string}`
- balance: number | undefined
- chainId: number
- name: string | null
- symbol: string | null
- decimals: number | null
- logo: string | null
- price: {
- usd: number | null
- eur: number | null
- }
-}
+import type { GetToken } from './types'
export async function getTokens(
address: `0x${string}`,
- chainId: number
+ chainId: number,
+ signal?: AbortSignal
): Promise {
if (!address || !chainId) return []
// const url = `http://localhost:3000/api/balance?address=${address}&chainId=${chainId}`
const url = `https://web3.kremalicious.com/api/balance?address=${address}&chainId=${chainId}`
- const response = await fetch(url)
+ const response = await fetch(url, { signal })
const json: GetToken[] = await response.json()
if (!json) console.error(response.statusText)
diff --git a/src/components/Sponsor/Web3Donation/hooks/useTokens/index.tsx b/src/components/Sponsor/Web3Donation/hooks/useTokens/index.tsx
new file mode 100644
index 00000000..e1d38f28
--- /dev/null
+++ b/src/components/Sponsor/Web3Donation/hooks/useTokens/index.tsx
@@ -0,0 +1,2 @@
+export * from './useTokens'
+export * from './types'
diff --git a/src/components/Sponsor/Web3Donation/hooks/useTokens/types.ts b/src/components/Sponsor/Web3Donation/hooks/useTokens/types.ts
new file mode 100644
index 00000000..6eec3674
--- /dev/null
+++ b/src/components/Sponsor/Web3Donation/hooks/useTokens/types.ts
@@ -0,0 +1,13 @@
+export type GetToken = {
+ address: `0x${string}`
+ balance: number | undefined
+ chainId: number
+ name: string | null
+ symbol: string | null
+ decimals: number | null
+ logo: string | null
+ price: {
+ usd: number | null
+ eur: number | null
+ }
+}
diff --git a/src/components/Sponsor/Web3Donation/hooks/useTokens.tsx b/src/components/Sponsor/Web3Donation/hooks/useTokens/useTokens.tsx
similarity index 50%
rename from src/components/Sponsor/Web3Donation/hooks/useTokens.tsx
rename to src/components/Sponsor/Web3Donation/hooks/useTokens/useTokens.tsx
index 79a64b30..616a0084 100644
--- a/src/components/Sponsor/Web3Donation/hooks/useTokens.tsx
+++ b/src/components/Sponsor/Web3Donation/hooks/useTokens/useTokens.tsx
@@ -1,6 +1,7 @@
import { useState, useEffect } from 'react'
import { useAccount, useNetwork } from 'wagmi'
-import { getTokens, type GetToken } from '../api/getTokens'
+import { getTokens } from './getTokens'
+import type { GetToken } from './types'
export function useTokens() {
const { address } = useAccount()
@@ -11,23 +12,35 @@ export function useTokens() {
const [isError, setIsError] = useState()
useEffect(() => {
+ const abortController = new AbortController()
+ const { signal } = abortController
+
async function init() {
- if (!address || !chain) return
+ if (!address || !chain?.id) return
setIsLoading(true)
try {
- const tokens = await getTokens(address, chain.id)
+ const tokens = await getTokens(address, chain.id, signal)
setData(tokens)
setIsLoading(false)
- } catch (error) {
+ } catch (error: any) {
setIsError(true)
setIsLoading(false)
- console.error((error as Error).message)
+ if ((error as Error).name !== 'AbortError') {
+ console.error((error as Error).message)
+ }
}
}
init()
- }, [address, chain])
+
+ return () => {
+ abortController.abort()
+ setData(undefined)
+ setIsLoading(undefined)
+ setIsError(undefined)
+ }
+ }, [address, chain?.id])
return { data, isLoading, isError }
}
diff --git a/src/components/Sponsor/Web3Donation/index.tsx b/src/components/Sponsor/Web3Donation/index.tsx
index 4f6c72a8..096a60a4 100644
--- a/src/components/Sponsor/Web3Donation/index.tsx
+++ b/src/components/Sponsor/Web3Donation/index.tsx
@@ -6,7 +6,7 @@ import Alert, { getTransactionMessage } from './components/Alert/Alert'
import { InputGroup } from './components/Input'
import styles from './index.module.css'
import { SendNative, SendErc20 } from './components/Send'
-import type { GetToken } from './api/getTokens'
+import type { GetToken } from './hooks/useTokens'
export default function Web3Donation(): ReactElement {
const { address: account } = useAccount()