Skip to content

Commit b1abd49

Browse files
committed
feat(useTokenPrice.ts): add hook to fetch a token price from coinGecko API
1 parent 9ed1f8d commit b1abd49

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

lib/useTokenPrice.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { useCallback, useEffect, useRef, useState } from "react"
2+
import { FIATCurrencies } from "./shared.d"
3+
4+
const API_URL = "https://api.coingecko.com/api/v3/simple/price"
5+
const INITIAL_STATE = { usd: 0, jpy: 0, eur: 0 }
6+
const ONE_SEC_IN_MS = 1000
7+
type CallBack = () => void
8+
9+
const useTokenPrice = (
10+
coinGeckoID: string,
11+
intervalInSecs: number = 60
12+
): [FIATCurrencies, CallBack] => {
13+
const timer = useRef(null)
14+
const [price, setPrice] = useState(INITIAL_STATE)
15+
const [count, setCount] = useState(0)
16+
const triggerRefetch = useCallback(function memoizedRefetch() {
17+
setCount((n) => n + 1)
18+
}, [])
19+
useEffect(() => {
20+
clearTimeout(timer.current)
21+
fetch(`${API_URL}?ids=${coinGeckoID}&vs_currencies=usd,eur,jpy`)
22+
.then((r) => r.json())
23+
.then((json) => {
24+
if (coinGeckoID in json) {
25+
setPrice((state) => ({ ...state, ...json[coinGeckoID] }))
26+
}
27+
})
28+
.catch(console.error)
29+
.finally(() => {
30+
// Constrain interval not to be less than 10s
31+
const secs = intervalInSecs < 10 ? 10 : intervalInSecs
32+
setTimeout(triggerRefetch, secs * ONE_SEC_IN_MS)
33+
})
34+
return () => clearTimeout(timer.current)
35+
}, [count])
36+
37+
return [price, triggerRefetch]
38+
}
39+
40+
export default useTokenPrice

0 commit comments

Comments
 (0)