Building a Simple Token Tracker Using Web3 Data APIs
๋น๋ ์ฌ๋ฌ๋ถ ์๋ ํ์ธ์! Token ํํ ๋ฆฌ์ผ์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค ๐
์ด๋ฒ ํํ ๋ฆฌ์ผ์์๋ ๊ฐ๋จํ Token Tracker๋ฅผ ์ค๊ณํ๊ณ ์ง์ ๋ง๋ค์ด๊ฐ๋ ๊ณผ์ ์ ๋ณผ ์ ์์ต๋๋ค.
๋ณธ ํํ ๋ฆฌ์ผ์ ๋ค์๊ณผ ๊ฐ์ ์์๋ก ์งํ๋ฉ๋๋ค!
Step 1. ์๊ตฌ์ฌํญ ์๋ฆฝ ๋ฐ ์ฐ๋ํ API ์ดํด๋ณด๊ธฐ
Step 2. ๊ฐ๋ฐ ํ๊ฒฝ ์ค์ ํ๊ธฐ
Step 3. API ์ฐ๋ํ๊ธฐ
Step 4. ์์ ์ฝ๋๋ก ๋์ ํ์ธํ๊ธฐ
๊ทธ๋ผ ํ๋์ฉ ์งํํด๋ณผ๊น์?
Step 1. ์๊ตฌ์ฌํญ ์๋ฆฝ ๋ฐ ์ฐ๋ํ API ์ดํด๋ณด๊ธฐ
๊ตฌํํ Token Tracker๋ ์๋์ ๊ฐ์ด ๊ฐ๋จํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ก ์ค๊ณํ์ต๋๋ค.
- ๊ธฐ๋ฅ 1. ๊ณ์ ์ฃผ์๋ฅผ ์
๋ ฅํ์ฌ ํด๋น ๊ณ์ ์ด ๋ณด์ ํ๊ณ ์๋ Token์ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค๋ค.
- ๊ธฐ๋ฅ 1-1. ๊ณ์ ์ฃผ์๋ฅผ ์ ๋ ฅํ์ฌ ํด๋น ๊ณ์ ์ด ๋ณด์ ํ๊ณ ์๋ Native Token์ ์๋์ ๋ณด์ฌ์ค๋ค.
- ๊ธฐ๋ฅ 1-2. ๊ณ์ ์ฃผ์๋ฅผ ์ ๋ ฅํ์ฌ ํด๋น ๊ณ์ ์ด ๋ณด์ ํ๊ณ ์๋ Token ๋ชฉ๋ก์ ์กฐํํ์ฌ ๋ณด์ฌ์ค๋ค.
- ๊ธฐ๋ฅ 2. Token ๋ชฉ๋ก์์ ํน์ Token์ ํด๋ฆญํ๋ฉด ํด๋น Token์ ๋ํ Metadata์ ํจ๊ป ์๋ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค๋ค.
- ๊ธฐ๋ฅ 2-1. Token Contract์ Metadata๋ฅผ ํ์ธํ ์ ์๋ค.
- ๊ธฐ๋ฅ 2-2. ํด๋น Token์ด ๊ฑฐ๋๋ ์ด๋ ฅ์ ํ์ธํ ์ ์๋ค.
๊ฐ๋จํ์ง๋ง Token์ ๊ด๋ จ๋ ์ค์ํ ๊ธฐ๋ฅ๋ค์ ๋ชจ๋ ๋ด๊ณ ์๋ค์! ์ด์ Nodit์ Web3 Data API ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ๊ฐ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํด ์ด๋ค API๋ฅผ ์ฌ์ฉํ ์ ์๋์ง ํ์ธํด๋ณผ๊น์?
๊ธฐ๋ฅ 1-1. ๊ณ์ ์ฃผ์๋ฅผ ์
๋ ฅํ์ฌ ํด๋น ๊ณ์ ์ด ๋ณด์ ํ๊ณ ์๋ Native Token์ ์๋์ ๋ณด์ฌ์ค๋ค.
์ด ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํด์๋ ์ฌ์ฉ์๊ฐ Input์ ์ฃผ์๋ฅผ ์ ๋ ฅํ๊ณ [๊ฒ์] ๋ฒํผ์ ํด๋ฆญํ๋ฉด API๋ฅผ ํธ์ถํ์ฌ ์๋ต์ผ๋ก๋ถํฐ ํด๋น ๊ณ์ ์ด ๋ณด์ ํ Native Token์ ์๋์ ์กฐํํด์ผ ํฉ๋๋ค. ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ์ฐ๋ํ ์ ์์ต๋๋ค.
์ด๋ฌํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ API๋ก Web3 Data API์ Token API์ค getNativeBalanceByAccount
๋ผ๋ API๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋ค์! ์๋์ ๊ฐ์ด curl์ ์์ฑํ์ฌ API๋ฅผ ํธ์ถํด ๋ณผ ์ ์์ต๋๋ค.
curl --request POST \
--url https://web3.nodit.io/v1/ethereum/mainnet/native/getNativeBalanceByAccount \
--header 'X-API-KEY: Input_your_API_Key' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"accountAddress": "Input_your_account_address"
}
'
์ ํธ์ถ์ ๋ํ ์๋ต์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. wei ๋จ์๋ก ์๋์ ํ์ธํ ์ ์์ต๋๋ค.
{
"ownerAddress": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"balance": "29435021161388550777"
}
๊ธฐ๋ฅ 1-2. ๊ณ์ ์ฃผ์๋ฅผ ์
๋ ฅํ์ฌ ํด๋น ๊ณ์ ์ด ๋ณด์ ํ๊ณ ์๋ Token ๋ชฉ๋ก์ ์กฐํํ์ฌ ๋ณด์ฌ์ค๋ค.
๊ณ์ ์ด ๋ณด์ ํ Native Token์ ์๋ ์กฐํ์ ๋์ผํ๊ฒ ์ฌ์ฉ์๊ฐ Input์ ์ฃผ์๋ฅผ ์ ๋ ฅํ๊ณ [๊ฒ์] ๋ฒํผ์ ํด๋ฆญํ๋ฉด API๋ฅผ ํธ์ถํ์ฌ ์๋ต์ผ๋ก๋ถํฐ ํด๋น ๊ณ์ ์ด ๋ณด์ ํ Token์ ๋ชฉ๋ก์ ์กฐํํด์ผ ํฉ๋๋ค.
Native Token์ ๋ถ๋ฌ์ค๋ ๋ก์ง๊ณผ ๋์ผํ๋ Native Token์ ์กฐํํ ํ Token ๋ชฉ๋ก์ ๋ถ๋ฌ์ฌ ์ ์๋ API๋ฅผ ํธ์ถํด ๋ชฉ๋ก์ ๋ถ๋ฌ์ค๋ฉด ๋๊ฒ ๋ค์!
Nodit์์๋ getTokensOwnedByAccount
๋ผ๋ API๋ก ํด๋น ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์์ผ๋ฉฐ ์๋์ ๊ฐ์ด curl์ ์์ฑํด API๋ฅผ ํธ์ถํด ๋ณผ ์ ์์ต๋๋ค.
curl --request POST \
--url https://web3.nodit.io/v1/ethereum/mainnet/token/getTokensOwnedByAccount \
--header 'X-API-KEY: Input_your_API_Key' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"accountAddress": "Input_your_account_address"
}
'
์ ํธ์ถ์ ๋ํ ์๋ต์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. balance์ ๊ฒฝ์ฐ, Wei ๋จ์๋ก ์ ๊ณต๋๊ณ ์์ต๋๋ค.
{
"rpp": 20,
"page": 2,
"count": 389,
"items": [
{
"ownerAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
**"balance": "1000000000000000000000000",**
"contract": {
**"address": "0x6B1E3c59561d299Cab1eAa18bbD03eE3fFD2A0C7",**
"deployedTransactionHash": "0x5eacfd6869aac83fd7b74fb1740d24d504daddcf90d61953b47703194a033af1",
"deployedAt": "2023-10-26T16:49:59.000Z",
"deployerAddress": "0x788A0E6c06448723D74efDe653E9d567faA262F5",
"logoUrl": null,
"type": "ERC20",
**"name": "Tether",
"symbol": "USDT",**
"totalSupply": "1000000001000000000000000000",
**"decimals": 18**
}
},
...
]
}
๊ธฐ๋ฅ 2-1. Token Contract์ Metadata๋ฅผ ํ์ธํ ์ ์๋ค.
์ฌ์ฉ์๊ฐ ๋ชฉ๋ก์ Token ์ค ํ ๊ฐ์ง๋ฅผ ์ ํํ๋ฉด Contract์ Metadata์ ๊ฑฐ๋ ์ด๋ ฅ์ ๋ณด์ฌ์ฃผ์ด์ผ ํฉ๋๋ค. ์๋ ๋ค์ด์ด๊ทธ๋จ๊ณผ ๊ฐ์ด ์ฐ๋ํ ์ ์๊ฒ ๋ค์.
Nodit์์ ์ ๊ณตํ๋ getTokenContractMetadataByContracts
API๋ก ํด๋น ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์์ผ๋ฉฐ contractAddress๋ฅผ ์ด์ฉํด ์๋์ ๊ฐ์ด API๋ฅผ ํธ์ถํด๋ณด๊ฒ ์ต๋๋ค.
curl --request POST \
--url https://web3.nodit.io/v1/ethereum/mainnet/token/getTokenContractMetadataByContracts \
--header 'X-API-KEY: Input_your_API_Key' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"contractAddresses": [
"Input_your_contract_address"
]
}
'
์ ํธ์ถ์ ๋ํ ์๋ต์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ๋ฐ์ ์ ์์ต๋๋ค. ์ด ์ค์์ ํ์ํ ๊ฐ์ ์ ํํด ํ๋ฉด์ ๊ตฌํํ ์ ์์ต๋๋ค.
[
{
"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"deployedTransactionHash": "0x2f1c5c2b44f771e942a8506148e256f94f1a464babc938ae0690c6e34cd79190",
"deployedAt": "2017-11-28T00:41:21.000Z",
"deployerAddress": "0x36928500Bc1dCd7af6a2B4008875CC336b927D57",
"logoUrl": "https://cdn.luniverse.io/img/crypto-currencies/ethereum/mainnet/0xdac17f958d2ee523a2206206994597c13d831ec7/64x64.png",
"type": "ERC20",
"name": "Tether USD",
"symbol": "USDT",
"totalSupply": "53981730120396390",
"decimals": 6
}
]
๊ธฐ๋ฅ 2-2. ํด๋น Token์ด ๊ฑฐ๋๋ ์ด๋ ฅ์ ํ์ธํ ์ ์๋ค.
๊ทธ ๋ค์์ ํน์ Token์ ๊ฑฐ๋ ์ด๋ ฅ์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ์ฐจ๋ก ์
๋๋ค. 2-1๊ณผ ๋์ผํ ํธ์ถ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ์ง๋ง ๊ฑฐ๋ ์ด๋ ฅ์ ๋ํ ์ ๋ณด ๋ชฉ๋ก์ ์กฐํํ ์ ์์ด์ผ ํฉ๋๋ค. Nodit์์๋ getTokenTransfersByContract
API๋ฅผ ์ ๊ณตํ๊ณ ์์ผ๋ฉฐ ํด๋น API๋ฅผ ์ด์ฉํด ํน์ Token์ ๊ฑฐ๋ ์ด๋ ฅ์ ์กฐํํด๋ณด๊ฒ ์ต๋๋ค.
curl --request POST \
--url https://web3.nodit.io/v1/ethereum/mainnet/token/getTokenTransfersByContract \
--header 'X-API-KEY: Input_your_API_Key' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"contractAddress": "Input_your_contract_address",
}
'
์ ํธ์ถ์ ๋ํ ์๋ต์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ๋ฐ์ ์ ์์ต๋๋ค. ์ด ์ค์์ ํ์ํ ๊ฐ์ ์ ํํด ํ๋ฉด์ ๊ตฌํํ ์ ์์ต๋๋ค.
{
"rpp": 20,
"cursor": "eyJzb3J0IjpbImJsb2NrX3RpbWVzdGFtcDpkZXNjIiwiYmxvY2tfbnVtYmVyOmRlc2MiLCJsb2dfaW5kZXg6ZGVzYyJdLCJzZWFyY2hBZnRlciI6WzE3MjUwMDg4MTkwMDAsMjA2NDAzOTEsMjAzXX0=",
"items": [
{
"from": "0x0802Dd2EDD3f9faD39A9173B4595be819f201d61",
"to": "0x09DEdfcef409fCaB410D79E2834FAD16554d1B7c",
"value": "10200000",
"timestamp": 1725008831,
"blockNumber": 20640392,
"transactionHash": "0x50793eedb9083a23d3725df8c31d727b0365e004dccf3f58ad9353c391c62088",
"logIndex": 240,
"contract": {
"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"deployedTransactionHash": "0x2f1c5c2b44f771e942a8506148e256f94f1a464babc938ae0690c6e34cd79190",
"deployedAt": "2017-11-28T00:41:21.000Z",
"deployerAddress": "0x36928500Bc1dCd7af6a2B4008875CC336b927D57",
"logoUrl": "https://cdn.luniverse.io/img/crypto-currencies/ethereum/mainnet/0xdac17f958d2ee523a2206206994597c13d831ec7/64x64.png",
"type": "ERC20",
"name": "Tether USD",
"symbol": "USDT",
"totalSupply": "53981730120396390",
"decimals": 6
}
},
...
]
}
Step 2. ๊ฐ๋ฐ ํ๊ฒฝ ์ค์
๊ฐ๋จํ DApp ๊ตฌํ์ ์ํด ์๋ ๊ฐ๋ฐ ํ๊ฒฝ ๊ตฌ์ฑ์ด ํ์ํฉ๋๋ค. ์ค์น๋ฅผ ์ํ ๋์์ด ํ์ํ๋ค๋ฉด ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํด์ฃผ์ธ์.
VS Code Required
์์ค ์ฝ๋ ํธ์ง๊ธฐ๋ก ์ฝ๋๋ฅผ ์์ฝ๊ฒ ์์ฑํ๊ณ ํธ์งํ ์ ์์ต๋๋ค.
Node.js Required
์๋ฐ์คํฌ๋ฆฝํธ ๋ฐํ์ ํ๊ฒฝ์ผ๋ก ํ๋ก๊ทธ๋จ ์คํ์ ์ํด ํ์ํฉ๋๋ค.
git Optional
๋ถ์ฐ ๋ฒ์ ๊ด๋ฆฌ ์์คํ ์ผ๋ก ์์ค ์ฝ๋๋ฅผ ๋ก์ปฌ ํ๊ฒฝ์ ๋ค์ด๋ก๋ ๋ฐ๊ธฐ ์ํด ํ์ํฉ๋๋ค. ์์ ์ฝ๋๋ฅผ ๋ค์ด๋ก๋ ๋ฐ์ ์ ์์ต๋๋ค.
์ด ์ธ์ ์ฌ์ฉ๋ ํ๋ ์์ํฌ, ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ Step 4. ์์ ์ฝ๋์ package.json
ํ์ผ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
Step 3. API ์ฐ๋
์ด๋ฏธ ํ๋ก์ ํธ ๊ตฌํ์ ํ์ํ API๋ค์ ์ดํด๋ณด๊ณ ํธ์ถ ์ ์๋ต์ด ์ด๋ป๊ฒ ์ค๋์ง ํ์ธํ์์ต๋๋ค. ์ด์ ์ด API๋ค์ ์ด์ฉํด ํ๋ก ํธ์๋ ์ฝ๋์ ์ฐ๋ํด ๋ณผ๊น์?
Nodit API Key๋ฅผ ๋ฐ๊ธ ๋ฐ์ผ์ จ๋์?
Nodit API๋ฅผ ํธ์ถํ๊ธฐ ์ํด์๋ Nodit API Key๊ฐ ํ์ํฉ๋๋ค. ์์ง Nodit์ ์์ํ์ง ์์ผ์ จ๋ค๋ฉด ์๋ ๋งํฌ๋ ํ์ด์ง์ ์๋ด์ ๋ฐ๋ผ Nodit ์ฝ์์ ๊ฐ์ ํ๊ณ , ๊ฐ๋ฐ ์ฐ๋์ ์ํ API Key๋ฅผ ๋ฐ๊ธ๋ฐ์๋ณด์ธ์. ์์์ ๋ฌด๋ฃ์ ๋๋ค!
๐ย Nodit Node Quickstart
์ฐ์ Nodit์ API Key์ Protocol, Network๋ฅผ ํ๊ฒฝ ๋ณ์๋ก ์ค์ ํ์ฌ ํ๋์ ํ์ผ์์ ๊ด๋ฆฌํ๋๋ก ํ์์ต๋๋ค.
// .env
VITE_API_KEY=Your_Nodit_API_Key
VITE_PROTOCOL=ethereum
VITE_NETWORK=mainnet
ํ๊ฒฝ ๋ณ์ ํ์ผ์ ์์ฑํ ๊ฐ์ ๋ถ๋ฌ์ HTTP ํต์ ์ ์ด์ฉํด API๋ฅผ ํธ์ถํ ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ฝ๋์ ๋๋ค.
// instance.ts
import axios, { AxiosInstance } from "axios";
const apiKey = import.meta.env.VITE_API_KEY;
const protocol = import.meta.env.VITE_PROTOCOL;
const network = import.meta.env.VITE_NETWORK;
export function createWeb3ApiInstance(): AxiosInstance {
const instance = axios.create({
baseURL: `https://web3.nodit.io/v1/${protocol}/${network}`,
headers: {
"X-API-KEY": `${apiKey}`,
"Content-Type": "application/json",
Accept: "application/json",
},
});
return instance;
}
์์ ์์ฑํ ์ธ์คํด์ค๋ฅผ ์ด์ฉํด API๋ฅผ ํธ์ถํ๋ ํจ์๋ฅผ ๋ง๋ ์ฝ๋์ ๋๋ค.
// useQueries.ts
import { useQuery } from "@tanstack/react-query";
import { createWeb3ApiInstance } from "./instance";
const instance = createWeb3ApiInstance();
export const useGetTokensOwnedByAccount = (
accountAddress: string,
page: number,
rpp = 20
) => {
return useQuery({
queryKey: ["getTokensOwnedByAccount", accountAddress, page, rpp],
queryFn: async () =>
instance.post("token/getTokensOwnedByAccount", {
accountAddress,
withCount: true,
rpp,
page,
}),
retry: false,
staleTime: 1000 * 60 * 5,
});
};
ํ๋ฉด์ ๋
ธ์ถ๋ ํ
์ด๋ธ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค. ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์ฒ๋ฆฌํ ๋ฐ์ดํฐ์ธ ownedTokenByAccountData
๋ฅผ ๋ฐ์ ํ
์ด๋ธ ์์์ ๋ฐ์ธ๋ฉ ํฉ๋๋ค.
//TokenTable.tsx
import {
TokenTableProps,
TokensOwnedByAccountResponse,
} from "./interface";
const TokenTable = ({ ownedTokensByAccountData }: TokenTableProps) => {
return (
<div className="flex flex-col items-center justify-center">
<div className="mt-10 text-2xl font-bold">Token List</div>
{ownedTokenByAccountData && ownedTokenByAccountData.length > 0 ? (
<table className="w-full max-w-7xl table-fixed border-collapse mt-5 mb-10 shadow-xl shadow-black ">
<thead>
<tr className="border-2 border-noditGreen bg-noditGreen text-white ">
<th className="p-5">Number</th>
<th className="p-5">Name</th>
<th className="p-5">Symbol</th>
<th className="p-5">Decimals</th>
<th className="p-5">Balances</th>
</tr>
</thead>
<tbody>
{ownedTokenByAccountData.map(
(item: TokensOwnedByAccountResponse, index: number) => (
<tr
key={item.contract.deployedTransactionHash}
className="border border-noditGreen hover:scale-105 duration-100 cursor-pointer "
>
<th className="font-bold p-5">
{ownedTokenByAccountData.page === 1
? index + 1
: ownedTokenByAccountData.page * 20 + index - 19}
</th>
<th className="font-light p-5">{item.contract.name}</th>
<th className="font-light p-5">{item.contract.symbol}</th>
<th className="font-light p-5">{item.contract.decimals}</th>
<th className="font-light p-5">{item.balance}</th>
</tr>
)
)}
</tbody>
</table>
) : (
<div>This Account doesn't have any Tokens</div>
)}
</div>
);
};
export default TokenTable;
๋ถ๋ชจ ์ปดํฌ๋ํธ์์๋ API์ ๋ฐ์ดํฐ๋ฅผ ํธ์ถํ๊ณ ํ ์ด๋ธ ์ปดํฌ๋ํธ์ API ํธ์ถ ๊ฒฐ๊ณผ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํฉ๋๋ค.
// TokenList.tsx
import React from "react";
import {
useGetTokensOwnedByAccount,
} from "./useQueries";
import { useParams } from "react-router-dom";
import TokenTable from "./components/TokenTable";
const TokenList = (): React.ReactElement => {
const { accountAddress } = useParams();
if (!accountAddress) throw new Error("Check your account address");
const {
isError,
data: getTokensOwnedByAccountData,
isLoading,
} = useGetTokensOwnedByAccount(accountAddress, currentPage);
if (isLoading) return <div>Loading...</div>;
if (isError) return <div>You have to connect node</div>;
return (
<div>
<TokenTable
ownedTokensByAccountData={getTokensOwnedByAccountData?.data}
/>
</div>
);
};
export default TokenList;
์์ ๊ฐ์ด ์์ฑ ํ ์๋ฒ๋ฅผ ์คํํ๋ฉด ์ฌ์ง๊ณผ ๊ฐ์ด ๋ฐ์ดํฐ๋ฅผ ํ๋ฉด์์ ํ์ธํ ์ ์์ต๋๋ค.
Step 4. ์์ ์ฝ๋
์์์ ๊ตฌํํ ๋ด์ฉ์ ํฌํจํ, ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋์ ์์ ํ๋ก์ ํธ๋ฅผ ๊ณต์ ํด ๋๋ฆฝ๋๋ค.
- ์์ค ์ฝ๋ ๋ค์ด๋ก๋ ๋ฐ ์ ๊ทผ
$ git clone https://github.com/Lambda256/Nodit-EVM-Tutorials
$ cd Nodit-EVM-Tutorials
$ cd token_tutorial
- ํ๋ก์ ํธ ์ด๊ธฐํ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
$ npm install
์ฌ์ฉ์๊ฐ ์ด์ฉํ ํ๋กํ ์ฝ๊ณผ ๋คํธ์ํฌ ๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ์์ Nodit API Key๋ฅผ ํ๊ฒฝ ๋ณ์๋ก ์ค์ ํฉ๋๋ค. Nodit API Key์ ํ๋กํ ์ฝ, ๋คํธ์ํฌ์ ๊ฒฝ์ฐ Nodit Console์์ ํ์ธํ ์ ์์ผ๋ฉฐ ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ์ ๋ ฅ๋์ด ์๋ ethereum๊ณผ mainnet ์ธ์๋ ์ฌ์ฉ์๊ฐ ์ฐ๊ฒฐํ ๋ ธ๋๊ฐ ์๋ค๋ฉด ์ด์ฉํ ์ ์์ต๋๋ค.
// .env
VITE_API_KEY=Your_Nodit_API_Key
VITE_PROTOCOL=ethereum
VITE_NETWORK=mainnet
ํ๊ฒฝ ์ค์ ์ ์๋ฃํ ํ ํฐ๋ฏธ๋์ ์๋์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ์ฌ Nodit Token Tutorial์ ์คํํฉ๋๋ค.
$ npm run dev
Congratulation! ๐
Nodit Token Tutorial์ ๋ชจ๋ ์๋ฃํ์์ต๋๋ค! ๋ค๋ฅธ Nodit API๋ฅผ ์ด์ฉํ์ฌ ๋๋ง์ ๊ธฐ๋ฅ์ ์ถ๊ฐํด ๋ณด์ธ์!
๋์ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ๊ฐ์ง Nodit์ API๊ฐ ๊ถ๊ธํ์ ๊ฐ์? ์๋ ๋งํฌ๋ฅผ ๋๋ฌ ํ์ธํด ๋ณด์ธ์!
Updated 2 months ago