
Cara membuat Penampil Portofolio Solana dengan Next.js dan DAS API Helius
Daftar Isi
Tujuan
Dalam tutorial ini, kita akan membuat aplikasi front-end untuk menampilkan isi dompet Solana menggunakan DAS API dari Helius. Kita akan menampilkan berbagai jenis token beserta informasi terperincinya, termasuk metadata, informasi koleksi, dan harga token fungibel.
Tutorial ini akan memandu Anda membuat aplikasi yang serupa dengan Galleria dengan menguraikan langkah-langkah yang diperlukan.
Prasyarat
- Kunci API Helius.
- Memahami React.
- Berpengalaman menggunakan Next.js.
Ikhtisar Teknologi yang Digunakan
- Next.js: Framework React untuk membuat aplikasi dengan rendering sisi server.
- DAS API dari Helius: API lengkap untuk mengakses data token Solana.
- Vercel: Platform untuk meng-host aplikasi Next.js.
- Tailwind CSS: Framework CSS berbasis utilitas untuk penataan gaya.
Menyiapkan Proyek
DAS API
DAS API adalah spesifikasi dan sistem sumber terbuka yang ditawarkan oleh Helius. API ini menyediakan antarmuka sederhana untuk berinteraksi dengan aset digital di blockchain Solana. DAS API mendukung berbagai jenis token, termasuk token fungibel, NFT reguler, dan NFT terkompresi, serta menawarkan fitur seperti pengindeksan metadata off-chain.
Menyiapkan Kunci API
Untuk mendapatkan kunci API Helius, kunjungi Portal Developer Helius. Berikut cara memulainya:
- Buat akun menggunakan dompet Solana, akun Google, atau akun GitHub.
- Setelah masuk, Anda akan diminta membuat kunci API.
- Simpan kunci ini dengan aman karena kita akan menggunakannya untuk melakukan panggilan API.
Membuat Aplikasi Next.js
Langkah 1: Menyiapkan Proyek Next.js Anda
Buat Aplikasi Next.js Baru dengan Tailwind
npx create-next-app@latest helius-portfolio --typescript --eslintGunakan konfigurasi berikut:
Dengan ini, kita dapat menggunakan Tailwind CSS untuk penataan gaya sekaligus menggunakan App router baru.
cd helius-portfolioLangkah 2: Membuat Komponen
Buat folder components di direktori app agar strukturnya tetap tertata.
Komponen SearchBar (components/SearchBar.js):
Komponen ini menangani input alamat dompet dari pengguna. Komponen ini menggunakan hook useState untuk mengelola state alamat dan useRouter untuk navigasi setelah formulir dikirim. Formulir ini ditata menggunakan class Tailwind CSS agar terlihat modern.
Komponen TokenCard (components/TokenCard.js):
Komponen ini dirancang untuk menampilkan informasi token. Komponen ini merender tata letak yang berbeda secara kondisional untuk token fungibel dan nonfungibel, serta menggunakan tipe Token dan Attribute dari ../types/Token.
Komponen SearchBar:
components/searchBar.ts
import { useRouter } from "next/navigation";
import React, { useState } from "react";
export default function SearchBar() {
const router = useRouter();
const [address, setAddress] = useState("");
function handleSubmit(event: React.FormEvent) {
event.preventDefault();
router.push(`/${address}`);
}
return (
setAddress(e.target.value)}
className="border-2 border-gray-300 rounded-md w-full text-center px-4 py-2 mb-4 flex-grow text-black"
/>
Search
);
}Komponen TokenCard:
Komponen ini mengurai data token dari API dan menampilkan informasi yang relevan pada setiap kartu token.
Dalam contoh di bawah ini, kita menampilkan beberapa informasi dasar seperti gambar, simbol, jumlah, dan nilai setiap token fungibel. Untuk Token Nonfungibel, kita menampilkan gambar, nama, deskripsi, dan atribut. Anda dapat mengambil informasi apa pun yang disediakan oleh API dan menampilkannya pada kartu.
Contohnya adalah menampilkan informasi khusus kompresi untuk cNFT atau informasi inscription untuk aset yang memiliki inscription. Untuk mempelajari lebih lanjut informasi spesifik yang dapat Anda gunakan, lihat dokumentasi DAS.
"use client";
import React from "react";
import { Token, Attribute } from "../types/Token";
interface TokenCardProps {
token: Token;
tokenType: string;
}
const TokenCard = ({ token, tokenType }: TokenCardProps) => {
return (
{/* Other token information */}
{tokenType === "fungible" ? (
{token.content.metadata.symbol}
{/* {token.content.metadata.description} */}
Amount:{token.token_info.balance}
{token.token_info.price_info?.total_price ? (
Value: ${token.token_info.price_info.total_price}
) : null}
) : (
{token.content.metadata.name}
{token.content.metadata.description}
{token.content.metadata?.attributes?.map(
(attribute: Attribute, index: number) => (
{attribute.trait_type}: {attribute.value}
)
)}
)}
);
}
export default TokenCard;Langkah 3: Mengambil Data dari DAS
Kita akan menggunakan metode searchAssets dari DAS API untuk mengambil data token. Metode ini fleksibel sehingga kita dapat menentukan kriteria seperti alamat dompet dan jenis token.
Membuat folder lib:
- Buat folder
libdi direktori app untuk panggilan API. - Buat file
searchAssets.tsdi dalamnya.
Fungsi Panggilan API (lib/searchAssets.ts):
- Fungsi ini mengambil token berdasarkan alamat dompet.
- Fungsi ini menangani potensi error dan mencatat respons untuk debugging
interface Tokens {
items: any[];
}
const fetchTokens = async (walletAddress: string): Promise => {
const url = `https://mainnet.helius-rpc.com/?api-key=`;
console.log(
`Starting search for tokens for wallet address: ${walletAddress}`
);
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: "my-id",
method: "searchAssets",
params: {
ownerAddress: walletAddress,
tokenType: "all",
displayOptions: {
showCollectionMetadata: true,
},
},
}),
});
const data = await response.json();
console.log(
`Data returned for wallet address ${walletAddress}:`,
data.result
);
return { items: data.result };
} catch (error) {
console.error("Error fetching tokens:", error);
return { items: [] };
}
};
export default fetchTokens;Siapkan tipe token
- Kita perlu menyiapkan tipe untuk respons dari DAS API. Ini adalah praktik yang baik saat menggunakan TypeScript. Anda dapat membuat folder bernama types dan file bernama
token.ts
export interface ApiResponse {
total: number;
limit: number;
cursor?: string;
items: Token[];
}
export interface Token {
interface: string;
id: string;
content: Content;
authorities: Authority[];
compression: Compression;
grouping: Grouping[]; // or any[]
royalty: Royalty;
creators: Creator[]; // or any[]
ownership: Ownership;
supply: Supply | null | number;
mutable: boolean;
burnt: boolean;
token_info: TokenInfo;
mint_extensions: MintExtensions;
inscription: Inscription;
spl20?: Spl20;
}
export interface Content {
$schema: string;
json_uri: string;
files: any[];
metadata: Record;
links: Record;
}
export interface Authority {
address: string;
scopes: string[];
}
export interface Compression {
eligible: boolean;
compressed: boolean;
data_hash: string;
creator_hash: string;
asset_hash: string;
tree: string;
seq: number;
leaf_id: number;
}
export interface Grouping {
group_key: string;
group_value: string;
collection_metadata: CollectionMetadata;
}
export interface Royalty {
royalty_model: string;
target: string | null;
percent: number;
basis_points: number;
primary_sale_happened: boolean;
locked: boolean;
}
export interface Creator {
address: string;
share: number;
verified: boolean;
}
export interface Ownership {
frozen: boolean;
delegated: boolean;
delegate: null | string;
ownership_model: string;
owner: string;
}
export interface Supply {
print_max_supply: number;
print_current_supply: number;
edition_nonce: number;
}
export interface TokenInfo {
symbol: string;
balance: number;
supply: number;
decimals: number;
token_program: string;
associated_token_address: string;
price_info: PriceInfo;
}
export interface Inscription {
order: number;
size: number;
contentType: string;
encoding: string;
validationHash: string;
inscriptionDataAccount: string;
}
export interface Spl20 {
p: string;
op: string;
tick: string;
amt: string;
}
export interface File {
uri: string;
cdn_uri: string;
mime: string;
}
export interface Metadata {
attributes: Attribute[];
description: string;
name: string;
symbol: string;
}
export interface Attribute {
value: string;
trait_type: string;
}
export interface CollectionMetadata {
name: string;
symbol: string;
image: string;
description: string;
external_url: string;
}
export interface PriceInfo {
price_per_token: number;
total_price: number;
currency: string;
}
export interface MintExtensions {}Langkah 4: Menampilkan Informasi Token
Kita akan mengategorikan respons API menjadi token fungibel dan nonfungibel. Token tersebut akan ditampilkan menggunakan komponen TokenCard. Tombol pengalih memungkinkan pengguna beralih di antara kedua jenis token.
Mengintegrasikan Komponen pada Halaman Pencarian
- Halaman Pencarian (pages/index.ts)
- Halaman landing memiliki Bilah Pencarian tempat pengguna dapat memasukkan alamat dompet.
- Halaman ini ditata dengan Tailwind CSS agar desainnya bersih dan responsif.
"use client";
import React from "react";
import SearchBar from "./components/searchBar";
export default function Home() {
return (
Solana Portfolio Viewer
{"Built with Helius's DAS API"}
);
}Menyiapkan Halaman Token
Kita akan menggunakan route dinamis di Next.js untuk setiap alamat dompet. Ini meningkatkan pengalaman pengguna karena memudahkan navigasi dan berbagi URL.
Siapkan direktori bernama [wallet]. Tanda kurung siku mengaktifkan routing dinamis. Setelah selesai, buat file bernama page.tsx yang akan memuat semua logika bisnis untuk seluruh halaman yang dimuat secara dinamis.
Penyiapan Halaman Token (pages/[wallet]/page.tsx):
Halaman ini menampilkan token yang terkait dengan alamat dompet dalam URL. Halaman ini melakukan panggilan API untuk mengambil data token dan menampilkannya menggunakan komponen TokenCard.
"use client";
import React, { useState, useEffect } from "react";
import fetchTokens from "../lib/searchAssets";
import TokenCard from "../components/tokenCard";
import { Token, Attribute } from "../types/Token";
interface Tokens {
items: Token[];
}
interface PageProps {
params: {
wallet: string;
};
}
export default function Page({ params }: PageProps) {
const [tokens, setTokens] = useState(null);
const [tokenType, setTokenType] = useState("fungible");
useEffect(() => {
fetchTokens(params.wallet).then(setTokens).catch(console.error);
}, [params.wallet]);
console.log("tokens", tokens);
const fungibleTokens = tokens
? tokens.items.filter(
(token) =>
token.interface === "FungibleToken" ||
token.interface === "FungibleAsset"
)
: [];
const nonFungibleTokens = tokens
? tokens.items.filter(
(token) =>
token.interface !== "FungibleToken" &&
token.interface !== "FungibleAsset"
)
: [];
const displayedTokens =
tokenType === "fungible" ? fungibleTokens : nonFungibleTokens;
return (
Portfolio Viewer
{params.wallet}
setTokenType("fungible")}
>
Fungible Tokens
setTokenType("nonFungible")}
>
Non-Fungible Tokens
{displayedTokens.length > 0 ? (
{displayedTokens.map((token) => (
))}
) : (
Loading...
)}
);
}Setelah semua ini disiapkan, direktori proyek Anda akan terlihat seperti berikut:
Langkah 5: Menata Gaya Aplikasi
Tailwind CSS akan menjadi framework penataan gaya kita. Pendekatan berbasis utilitasnya memungkinkan kita menata komponen dengan cepat sekaligus memastikan desain yang konsisten dan responsif. Anda dapat menggunakan Tailwind untuk menyesuaikan aplikasi sesuka Anda.
Langkah 6: Menguji Aplikasi
Jalankan aplikasi Next.js Anda untuk mengujinya secara lokal:
npm run devLakukan pengujian dengan memasukkan alamat dompet yang berbeda dan pastikan data yang benar ditampilkan.
Deployment
Kita akan men-deploy aplikasi menggunakan Vercel. Vercel menawarkan hosting gratis serta menyediakan analitik dan insight yang bermanfaat, sehingga menjadi pilihan ideal untuk meng-host aplikasi Next.js. Anda dapat menyiapkannya di https://vercel.com/.
Kesimpulan
Selamat telah menyelesaikan tutorial ini! Kami harap tutorial ini bermanfaat bagi Anda.
DAS API adalah alat yang sangat andal dan cepat untuk mengambil data token dari chain.
Penampil portofolio ini adalah contoh yang sangat baik dari kemampuan API tersebut.
Kami harap Anda dapat mengembangkan situs dasar yang telah dibuat menjadi sesuatu yang luar biasa. Jika memiliki pertanyaan, jangan ragu bergabung ke Discord kami dan bertanya langsung kepada kami!
Anda dapat menemukan kode lengkapnya di sini: https://github.com/helius-labs/galleria
Referensi Pembelajaran Lanjutan
Untuk memperdalam pemahaman Anda tentang Next.js, blockchain Solana, dan integrasi API, jelajahi referensi berikut:
Panduan ini memberikan fondasi yang kuat untuk membuat aplikasi berbasis blockchain dengan Next.js dan berinteraksi dengan blockchain Solana menggunakan DAS API.
Artikel Terkait
Berlangganan Helius
Ikuti perkembangan terbaru dalam pengembangan Solana dan dapatkan pembaruan saat kami memublikasikan postingan


