uniswap-interface-uncensored/src/hooks/usePositionTokenURI.ts
2021-04-29 11:18:56 -05:00

76 lines
1.8 KiB
TypeScript

import { BigNumber } from 'ethers'
import JSBI from 'jsbi'
import { useMemo } from 'react'
import { NEVER_RELOAD, useSingleCallResult } from '../state/multicall/hooks'
import { useV3NFTPositionManagerContract } from './useContract'
type TokenId = number | JSBI | BigNumber
const STARTS_WITH = 'data:application/json;base64,'
type UsePositionTokenURIResult =
| {
valid: true
loading: false
result: {
name: string
description: string
image: string
}
}
| {
valid: false
loading: false
}
| {
valid: true
loading: true
}
export function usePositionTokenURI(tokenId: TokenId | undefined): UsePositionTokenURIResult {
const contract = useV3NFTPositionManagerContract()
const inputs = useMemo(() => [tokenId instanceof BigNumber ? tokenId.toHexString() : tokenId?.toString(16)], [
tokenId,
])
const { result, error, loading, valid } = useSingleCallResult(contract, 'tokenURI', inputs, NEVER_RELOAD, 1_600_000)
return useMemo(() => {
if (error || !valid || !tokenId) {
return {
valid: false,
loading: false,
}
}
if (loading) {
return {
valid: true,
loading: true,
}
}
if (!result) {
return {
valid: false,
loading: false,
}
}
const [tokenURI] = result as [string]
if (!tokenURI || !tokenURI.startsWith(STARTS_WITH))
return {
valid: false,
loading: false,
}
try {
const json = JSON.parse(atob(tokenURI.slice(STARTS_WITH.length)))
return {
valid: true,
loading: false,
result: json,
}
} catch (error) {
return { valid: false, loading: false }
}
}, [error, loading, result, tokenId, valid])
}