本文是一个关于如何使用Helius的DAS API构建Solana钱包前端应用的教程,详细介绍了各个步骤,包括设置项目、创建组件、通过API获取数据等。文章提供了示例代码和额外资源,旨在帮助开发者掌握使用Next.js框架的实际应用。
6分钟阅读
2024年2月2日
在本教程中,我们将构建一个前端应用程序,以使用 Helios 的 DAS API 显示 Solana 钱包的内容。我们将展示各种代币类型及其详细信息,包括元数据、集合信息和可替代代币价格。
本教程将通过分解所需的步骤,指导你构建类似于 Galleria 的应用程序。
DAS API 是 Helius 提供的开源规范和系统。该 API 提供一个简单的接口,用于与 Solana 区块链上的数字资产进行交互。它支持各种代币类型,包括可替代代币、常规 NFT 和压缩 NFT,并提供像索引链外元数据等功能。
要获取 Helius API 密钥,请访问 Helius 开发者门户。以下是获取入门的方法:
使用 Tailwind 创建一个新的 Next.js 应用
代码
npx create-next-app@latest helius-portfolio --typescript --eslint
使用以下配置:
这将允许我们使用 Tailwind CSS 进行样式设计,以及使用新的 App 路由。
代码
cd helius-portfolio
在应用程序目录中创建一个 components
文件夹,以保持结构的组织性。
SearchBar 组件(components/SearchBar.js
):
该组件处理用户输入的钱包地址。它利用 useState
Hook管理地址状态,并在表单提交时为空间使用 useRouter
进行导航。该表单使用 Tailwind CSS 类样式设计,以实现流畅的外观。
TokenCard 组件(components/TokenCard.js
):
此组件旨在显示代币信息。它会根据代币类型有条件地渲染不同的布局,并利用来自 ../types/Token
的 Token
和 Attribute
类型。
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 (
<form onSubmit={handleSubmit}>
<input
onChange={(e) => 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"
/>
<button type="submit">Search</button>
</form>
);
}
TokenCard 组件:
此组件解析来自 API 的代币数据,并在每个代币卡上显示相关信息。
在下面的例子中,我们展示了一些基本信息,例如每个可替代代币的图像、符号、数量和价值。对于非可替代代币,我们展示图像、名称、描述和属性。你可以提取 API 提供的任何信息并在卡片上显示。
一个例子是显示 cNFTs 的压缩特定信息或者显示铭刻资产的铭刻信息。要了解你可以使用的具体信息,你可以查看 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 (
<div>
{/* 其他代币信息 */}
{tokenType === "fungible" ? (
<div>
<p>{token.content.metadata.symbol}</p>
{/* {token.content.metadata.description} */}
<p>Amount: {token.token_info.balance}</p>
{token.token_info.price_info?.total_price ? (
<p>Value: ${token.token_info.price_info.total_price}</p>
) : null}
</div>
) : (
<div>
<p>{token.content.metadata.name}</p>
<p>{token.content.metadata.description}</p>
{token.content.metadata?.attributes?.map(
(attribute: Attribute, index: number) => (
<p key={index}>{attribute.trait_type}: {attribute.value}</p>
)
)}
</div>
)}
</div>
);
}
export default TokenCard;
我们将使用 DAS API 中的 searchAssets
方法来获取代币数据。此方法灵活,允许我们指定钱包地址和代币类型等标准。
创建一个 lib
文件夹:
lib
文件夹,用于 API 调用。searchAssets.ts
文件。API 调用函数(lib/searchAssets.ts
):
代码
interface Tokens {
items: any[];
}
const fetchTokens = async (walletAddress: string): Promise<Tokens> => {
const url = `https://mainnet.helius-rpc.com/?api-key=`;
console.log(
`开始为钱包地址 ${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(
`钱包地址 ${walletAddress} 返回的数据:`,
data.result
);
return { items: data.result };
} catch (error) {
console.error("获取代币时出错:", error);
return { items: [] };
}
};
export default fetchTokens;
设置代币类型
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[]; // 或 any[]
royalty: Royalty;
creators: Creator[]; // 或 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<string, any>;
links: Record<string, any>;
}
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 {}
我们将把 API 响应分类为可替代和非可替代代币。使用 Token Card 组件,这些代币将被显示。一个切换按钮允许用户在这两种代币类型之间切换。
代码
"use client";
import React from "react";
import SearchBar from "./components/searchBar";
export default function Home() {
return (
<>
<h1>Solana Portfolio Viewer</h1>
<p>{"Built with Helius's DAS API"}</p>
<SearchBar />
</>
);
}
我们将利用 Next.js 中的动态路由为单个钱包地址提供服务。这通过允许轻松导航和 URL 分享来增强用户体验。
设置一个名为 [wallet]
的目录,方括号启用动态路由。完成后,创建一个名为 page.tsx
的文件,其中包含所有动态加载页面的业务逻辑。
代币页面设置(pages/[wallet]/page.tsx
):
该页面显示与 URL 中的钱包地址相关的代币。它进行 API 调用以获取代币数据,并使用 Token Card 组件显示它。
代码
"use client";
import React, { useState, useEffect } from "react";
import fetchTokens from "../lib/searchAssets";
import TokenCard from "../components/tokenCard";
import { Token } from "../types/Token";
interface Tokens {
items: Token[];
}
interface PageProps {
params: {
wallet: string;
};
}
export default function Page({ params }: PageProps) {
const [tokens, setTokens] = useState<Tokens | null>(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 (
<>
<h2>Portfolio Viewer</h2>
<p>{params.wallet}</p>
<button onClick={() => setTokenType("fungible")}>Fungible Tokens</button>
<button onClick={() => setTokenType("nonFungible")}>Non-Fungible Tokens</button>
{displayedTokens.length > 0 ? (
<div>
{displayedTokens.map((token, index) => (
<TokenCard key={index} token={token} tokenType={tokenType} />
))}
</div>
) : (
<p>Loading...</p>
)}
</>
);
}
在完成以上所有设置后,你的项目目录结构应如下所示:
Tailwind CSS 将是我们的样式框架。其实用优先的方法使我们能够快速对组件进行样式设计,同时确保一致和响应式的设计。你可以使用 Tailwind 根据你的需求自定义你的应用程序。
运行你的 Next.js 应用程序以进行本地测试:
代码
npm run dev
通过输入不同的钱包地址进行测试,确保正确的数据被显示。
我们将使用 Vercel 部署我们的应用程序。Vercel 提供免费的托管,并提供有价值的分析和见解,因此是托管 Next.js 应用程序的理想选择。你可以在 https://vercel.com/ 上设置此服务。
祝贺你完成本教程!我们希望你发现它的信息量很大。
DAS API 是一个非常强大且快速的工具,使你能够从链上检索代币数据。
此投资组合查看器是该 API 能力的一个优秀示例。
我们希望你能够将这个基本网站转变为一些伟大的东西。如果你有任何问题,请不要犹豫,加入我们的 Discord 并直接问我们!
你可以在这里找到完整的代码:https://github.com/helius-labs/galleria
要深入了解 Next.js、Solana 区块链和 API 集成,可以浏览以下资源:
本指南为使用 Next.js 构建基于区块链的应用程序以及使用 DAS API 与 Solana 区块链进行交互提供了坚实的基础。
- 原文链接: helius.dev/blog/build-a-...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!