React dApp에서 최신 자산 가격 검색
31940 단어 tutorialweb3reactjavascript
BTC/USD
을 앱에 표시해야 한다면 어떻게 해야 할까요? 또는 사용자의 잔액을 ETH
에서 BTC
로 변환하시겠습니까? 아니면 Elon Musk 팬 사이트를 구축하고 최신 Tesla( TSLA
) 주가 업데이트를 제공하고 싶습니까?오늘 우리는 Chainlink을 사용하여 단일 호출로 최신 자산 가격을 검색하고 React Context을 사용하여 앱 구성 요소에 제공합니다.
체인링크 데이터 피드
가장 쉽고 빠른 방법은 Chainlink에서 제공하는 데이터 피드를 사용하는 것입니다.
ETH/USD
쌍을 예로 사용하겠습니다.먼저 우리 쌍이 호출할 계약 주소를 찾아야 합니다. Chainlink에서 지원하는 모든 쌍에 편리한 address's list이 있습니다.
우리의 경우 주소는
0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
입니다.최신 가격을 가져오는 함수를 작성해 봅시다. 이를 위해서는 주소로 계약을 호출하고 ABI을 제공해야 합니다. Ethers.js 라이브러리를 사용하여 도움을 받을 것입니다( Web3.js 을 사용할 수도 있습니다. 여기서는 중요하지 않습니다).
// getLatestPrice.ts
import { providers, Contract, BigNumber } from 'ethers'
const provider = new providers.JsonRpcProvider("https://mainnet.infura.io/v3/<infura_project_id>")
const aggregatorV3InterfaceABI = [{ "inputs": [], "name": "decimals", "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "description", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint80", "name": "_roundId", "type": "uint80" }], "name": "getRoundData", "outputs": [{ "internalType": "uint80", "name": "roundId", "type": "uint80" }, { "internalType": "int256", "name": "answer", "type": "int256" }, { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "latestRoundData", "outputs": [{ "internalType": "uint80", "name": "roundId", "type": "uint80" }, { "internalType": "int256", "name": "answer", "type": "int256" }, { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "version", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }]
const ETH_USD_RATE_ADDRESS = '0x9326BFA02ADD2366b30bacB125260Af641031331'
const priceFeed = new Contract(ETH_USD_RATE_ADDRESS, aggregatorV3InterfaceABI, provider)
export function getLatestPrice(): Promise<BigNumber[]> {
const priceFeed = new Contract(ETH_USD_RATE_ADDRESS, aggregatorV3InterfaceABI, provider)
return priceFeed.latestRoundData()
}
자산 가격 컨텍스트
앱 내에서 최신 가격 데이터를 사용하려면 주기적으로 가격을 업데이트하고 구성 요소에 값을 제공하는 컨텍스트를 만들어야 합니다.
// AssetPriceContext.ts
import { utils } from 'ethers'
import { createContext, useEffect, useRef, useState } from 'react'
import { getLatestPrice } from './getLatestPrice'
interface ContextProps {
conversionDate: number | null;
conversionRate: number | null;
}
const UPDATE_INTERVAL_TIMEOUT = 180000 // 3 minutes
export const DEFAULT_CONTEXT: ContextProps = {
conversionDate: null,
conversionRate: null,
}
export const AssetPriceContext = createContext<ContextProps>(DEFAULT_CONTEXT)
export const useAssetPrice = (): ContextProps => {
const [state, setState] = useState<ContextState>(DEFAULT_CONTEXT)
const updateInterval = useRef<ReturnType<typeof setTimeout>>()
const updateAssetPrice= async () => {
let conversionDate = null
let conversionRate = null
try {
const roundData = await getLatestPrice()
conversionDate = Number(roundData[3].toString()) * 1000
conversionRate = Number(utils.formatUnits(roundData[1], 8))
} catch (error) {
console.log(error)
}
setState({conversionDate, conversionRate })
}
const startUpdate = async () => {
stopUpdate()
await updateAssetPrice()
updateInterval.current = setInterval(async () => {
await updateAssetPrice()
}, UPDATE_INTERVAL_TIMEOUT)
}
const stopUpdate = () => {
if (updateInterval.current) {
clearInterval(updateInterval.current)
}
}
useEffect(() => {
startUpdate()
return stopUpdate
}, [])
return state
}
구성 요소에서 사용
이제 최신 가격을 사용할 준비가 되었습니다. 먼저 컨텍스트를 앱에 연결해 보겠습니다.
// App.tsx
import { AssetPriceContext, useAssetPrice } from './AssetPriceContext'
import { EthBalance } from './EthBalance'
export default function App() {
const assetPrice = useAssetPrice()
return (
<AssetPriceContext.Provider value={assetPrice}>
<div>
<h1>Chainlink Data Feeds example</h1>
<EthBalance />
</div>
</AssetPriceContext.Provider>
);
}
그리고 잔액을 ETH에서 USD로 변환하는 간단한 구성 요소를 만듭니다.
// EthBalance.tsx
import React, { useContext } from 'react'
import { AssetPriceContext } from './AssetPriceContext'
const BALANCE_ETH = 1
export const EthBalance: React.FC = () => {
const { conversionRate, conversionDate } = useContext(AssetPriceContext)
const balanceUSD = conversionRate ? BALANCE_ETH * conversionRate : '...'
const updatedAt = conversionDate
? new Intl.DateTimeFormat(undefined, { dateStyle: 'full', timeStyle: 'medium' }).format(new Date(conversionDate))
: '...'
return (
<div>
<p>
My balance is {BALANCE_ETH} ETH / {balanceUSD} USD
</p>
<p>
Updated at {updatedAt}
</p>
</div>
)
}
결과는 다음과 같습니다.
My balance is 1 ETH / 1557 USD
Updated at Saturday, 11 June 2022 at 22:29:16
결론
체인링크 데이터 피드는 사용이 비교적 간단하지만 dApp을 실제 데이터에 연결하는 강력한 도구입니다. 추가 읽기 가능here
이 튜토리얼이 즐거우셨기를 바라며 계속 지켜봐 주시기 바랍니다.
Reference
이 문제에 관하여(React dApp에서 최신 자산 가격 검색), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/murashow/retrieving-latest-asset-prices-in-your-react-dapp-23i9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)