
Solana 开发 101:使用 DAS API 获取合集中的所有 NFT
概述
数字资产标准 (DAS) API 是一个新发布的接口,用于统一处理 Solana 上的常规资产和压缩资产(代币、NFT 等)。随着压缩资产的推出,Solana 开发者现在可以更高效地检索与钱包、合集或权限方关联的所有资产,无需使用多个端点。DAS API 还在后台建立了索引,可为开发者提供性能最佳的调用。有了 DAS,你无需执行耗时的 gPA 调用,从而简化信息检索流程。在 getAssetsByOwner 端点中,你可以使用特定合集的链上合集 ID,访问属于该合集的所有资产的元数据和链下信息。
本教程将演示如何使用 DAS API 检索 Mad Lads 合集的资产信息。你可以查看 GitHub 仓库,跟随我们当前的代码库进行操作。你还可以查阅完整的 DAS API 文档,了解更多信息。
前置条件
- 已安装 Node.js(使用内置 fetch 需要 v18.0 或更高版本)。
- 对 JavaScript 有基本了解。
设置环境
- 为此项目创建一个名为 collection 的文件夹。
- 在 collection 文件夹中创建一个名为 assetList.js 的文件。我们将在此文件中编写函数。
- 在我们的 开发者门户中创建 API 密钥。前往 RPCs 并复制 Mainnet RPC 链接,本教程会将其用作 URL 变量。
- 获取一个演示合集的已认证合集 ID 以进行测试。本例将使用 Mad Lads,其合集 ID 为
J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w。查看特定 NFT 时,你可以在 Magic Eden 等市场中找到链上合集地址。
如果没有链上合集 ID,你需要使用其他 DAS 方法检索结果。
操作步骤
下面介绍如何使用 DAS API 检索 NFT 合集的资产信息。
1. 创建 getAssetsByGroup 函数
首先,创建一个函数来检索与合集相关的所有资产。我们会将向 DAS API 发出的 POST 请求嵌套在此函数中。
首先创建一个异步函数:
const { promises : fs } = require("fs");
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByGroup = async () => {
// Code goes here.
};
getAssetsByGroup();在此部分中,我们导入了用于处理文件系统操作的 fs 模块,指定了 RPC URL,并声明了 getAssetsByGroup 函数。
请务必将 <api-key> 替换为你从开发者门户获取的 API 密钥。
2. 创建发送至 DAS 的 POST 请求
接下来定义 getAssetsByGroup 函数,并指定起始页面和请求返回参数。我们将使用 fetch 函数,以便与我们的方法文档保持一致。
console.time('getAssetsByGroup');
let page = 1;
let assetList = [];我们使用 console.time('getAssetsByGroup') 启动计时器,并初始化当前页面变量和一个用于存储已获取资产的空数组。
我们使用 fetch 和 await,向指定的 url 端点发送异步 POST 请求:
try {
while (page) {
const response = await fetch(url, {
method: 'POST',接下来进入 while 循环。只要 page 变量不为 false,该循环就会继续从 API 获取数据。
然后使用 fetch 和 await 执行异步操作并发送 HTTP 请求。我们指定 API 端点的 url,并将方法设置为 'POST'。这表示我们会在请求正文中向服务器发送数据。
headers: {
'Content-Type': 'application/json',
},在请求标头中,我们将 'Content-Type' 设置为 'application/json'。这会告知服务器我们正在发送 JSON 数据。
body: JSON.stringify({
jsonrpc: '2.0',
id: 'my-id',
method: 'getAssetsByGroup',
params: {
groupKey: 'collection',
groupValue: 'J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w',
page: page,
limit: 1000,
},
}),随后,我们配置请求正文。它是一个 JSON 对象,我们会将其字符串化为可发送到端点的格式。我们在此定义 groupKey(其值为“collection”)和 groupValue(其值为链上合集 ID)。
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const { result } = await response.json();现在,如果服务器响应不成功,我们会抛出错误以便捕获。如果请求成功,则以 JSON 格式呈现响应。
如果 url 中没有设置有效的 API 密钥,你可能会遇到错误。
3. 将新资产追加到列表中
在上一部分中,我们最初让 getAssetsByGroup 在页面设置为 1 时运行。但它尚未配置为遍历所有可能的结果页面。接下来完成此配置:
assetList.push(...result.items);
if (result.total !== 1000) {
page = false;
} else {
page++;
}
}此代码会将响应中的项目添加到 assetList 数组。如果结果总数不等于 1,000 的上限,我们会将 page 设置为 false,以退出循环。
4. 将资产记录到文件中
要将检索到的资产信息保存到外部 JSON 文件,请添加以下代码:
const resultData = {
totalResults: assetList.length,
results: assetList,
};
await fs.writeFile('results.json', JSON.stringify(resultData, null, 2));
console.log('Results saved to results.json')
console.timeEnd('getAssetsByGroup');此代码会构建一个 resultData 对象,其中包含结果总数和 assetList 数组。我们使用 fs.writeFile 将数据写入名为 results.json 的 JSON 文件。最后,我们记录一条确认消息,并使用 console.timeEnd 结束计时。
5. 实现错误处理
现在,我们需要设计一个安全机制来处理潜在的服务器请求失败。可以通过以下设置实现。如果执行请求期间出现问题,此代码块会在控制台中记录错误消息。
} catch (error) {
console.error('Error occurred:', error);
}如果没有填入有效的链上合集 ID,发送请求时可能会遇到错误。
完整代码
你的 assetList.js 文件应类似于以下代码片段。
const { promises : fs } = require("fs");
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByGroup = async () => {
console.time('getAssetsByGroup'); // Start the timer
let page = 1;
let assetList = [];
try {
while (page) {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 'my-id',
method: 'getAssetsByGroup',
params: {
groupKey: 'collection',
groupValue: 'J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w',
page: page,
limit: 1000,
},
}),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const { result } = await response.json();
assetList.push(...result.items);
if (result.total !== 1000) {
page = false;
} else {
page++;
}
}
const resultData = {
totalResults: assetList.length,
results: assetList,
};
await fs.writeFile('results.json', JSON.stringify(resultData, null, 2));
console.log('Results saved to results.json')
console.timeEnd('getAssetsByGroup');
} catch (error) {
console.error('Error occurred:', error);
}
};
getAssetsByGroup();结果
文件内容与上面的代码一致后,你可以在终端中使用 node assetList.js 命令运行它并发起请求。这将生成一个 results.json 文件。
完成后,控制台会显示结果已保存到 results.json 文件,并记录获取资产所用的时间。在本例中,我们使用 Node.js 检索 Mad Lads 链上合集的资产信息,平均耗时为 9.27 秒。
打开 results.json 文件后,你会看到返回的结果总数和资产详细信息。这些资产分别代表你所查询合集中的 NFT。
要进一步自定义返回的数据,你可以提取图像、所有者以及其他有价值的元数据等特定信息。
由于需要计入已销毁和链下资产,合集总数可能显示为 9967,而不是 10,000。
results.json
{
"totalResults": 9967,
"results": [
{
"interface": "Custom",
"id": "GVPX9rXRXo9SVGktJCzA3Qb9v263kQzEyAWsgX3LL8P5",
"content": {
"$schema": "https://schema.metaplex.com/nft1.0.json",
"json_uri": "https://madlads.s3.us-west-2.amazonaws.com/json/859.json",
"files": [
{
"uri": "https://madlads.s3.us-west-2.amazonaws.com/images/859.png",
"cdn_uri": "https://cdn.helius.services/cdn-cgi/image//https://madlads.s3.us-west-2.amazonaws.com/images/859.png",
"mime": "image/png"
},
{
"uri": "https://arweave.net/qJ5B6fx5hEt4P7XbicbJQRyTcbyLaV-OQNA1KjzdqOQ/859.png",
"cdn_uri": "https://cdn.helius.services/cdn-cgi/image//https://arweave.net/qJ5B6fx5hEt4P7XbicbJQRyTcbyLaV-OQNA1KjzdqOQ/859.png",
"mime": "image/png"
}
],
"metadata": {
"attributes": [
{
"value": "Male",
"trait_type": "Gender"
},
{
"value": "Galaxy",
"trait_type": "Type"
},
{
"value": "Galaxy",
"trait_type": "Expression"
},
{
"value": "Gambler",
"trait_type": "Hat"
},
{
"value": "Galaxy",
"trait_type": "Eyes"
},
{
"value": "Dark Windsor",
"trait_type": "Clothing"
},
{
"value": "Grey",
"trait_type": "Background"
}
],
"description": "Fock it.",
"name": "Mad Lads #859",
"symbol": "MAD"
},
"links": {
"external_url": null
}
},
"authorities": [
{
"address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW",
"scopes": [
"full"
]
}
],
"compression": {
"eligible": false,
"compressed": false,
"data_hash": "",
"creator_hash": "",
"asset_hash": "",
"tree": "",
"seq": 0,
"leaf_id": 0
},
"grouping": [
{
"group_key": "collection",
"group_value": "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w"
}
],
"royalty": {
"royalty_model": "creators",
"target": null,
"percent": 0.042,
"basis_points": 420,
"primary_sale_happened": true,
"locked": false
},
"creators": [
{
"address": "5XvhfmRjwXkGp3jHGmaKpqeerNYjkuZZBYLVQYdeVcRv",
"share": 0,
"verified": true
},
{
"address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW",
"share": 100,
"verified": true
}
],
"ownership": {
"frozen": false,
"delegated": false,
"delegate": null,
"ownership_model": "single",
"owner": "GX6KFMFS6yZGJzuZ28Q5Cbk9RN8Wv8UmNP2abcC4kcM2"
},
"supply": null,
"mutable": true
}, ...
// Addtional Items
]这会显示返回的全部资产。现在,你可以进一步处理这些数据,仅返回代币地址、所有者和其他各种元数据信息。
你会发现合集显示为 9967,而不是 10,000。这是因为其中反映了已销毁且不再位于链上的资产数量。
总结
恭喜!你已使用新发布的数字资产标准 (DAS) API,成功检索了一个 10k 规模合集中的所有资产。总结如下:
- DAS API 为 Solana dApp 提供了更精简的资产获取方式。
- 此方法同时适用于常规合集和压缩合集。
- 使用 DAS API,你可以在 15 秒内访问有价值的元数据和所有权信息。
使用 DAS API,可以简化 Solana dApp 的资产获取流程。无需通过多次 API 调用来收集信息,只需使用一个端点即可。
在后续教程中,我们将介绍其他用于返回和处理资产的精简方案。
欢迎加入我们的 Discord,提出你的任何问题!
相关文章
订阅 Helius
及时了解 Solana 开发的最新动态,并在我们发布新内容时收到更新


