本文介绍了如何使用数字资产标准(DAS)API从Solana的NFT集合中获取所有资产信息,提供了操作步骤和代码示例,包括环境设置、API请求和错误处理等关键要素。最终用户可以将获取的数据保存为JSON格式,方便进一步的分析和使用。
数字资产标准(DAS) API 是一个新发布的接口,统一了 Solana 上的常规资产和压缩资产(代币、NFT 等)。随着压缩资产的引入,Solana 开发者现在可以更高效地检索与钱包、集合或授权相关的所有资产,消除了使用多个端点的需求。DAS API 也在后台进行索引,为作为开发者的你提供了最优性能的调用。利用 DAS,你可以通过消除冗长的 gPA 调用,简化检索信息的过程。在 getAssetsByOwner 端点中,你可以使用其链上集合 ID 访问属于特定集合的所有资产的元数据和离线信息。
在本教程中,我们将演示如何利用 DAS API 从 Mad Lads 集合中检索资产信息。要跟随我们当前的代码库,你可以查看 GitHub 仓库 这里。你也可以在我们扩展的 DAS API 文档中查看更多内容 这里。
J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w。你可以在 Magic Eden 等市场上查看特定 NFT 时找到链上的集合地址。
如果没有链上集合 ID,你需要使用替代的 DAS 方法来检索结果。
以下是如何使用 DAS API 从 NFT 集合中检索资产信息的步骤。
首先,让我们创建一个函数来检索与集合相关的所有资产。我们将在此函数中嵌套对 DAS API 的 POST 请求。
首先建立一个异步函数:
const { promises : fs } = require("fs");
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByGroup = async () => {
// 代码写在这里。
};
getAssetsByGroup();在这一部分中,我们导入了 fs 模块来处理文件系统操作,确定了 RPC URL,并声明了 getAssetsByGroup 函数。
确保将 <api-key> 替换为你在 开发者门户 中的 API 密钥。
让我们定义 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 密钥,可能会遇到错误。
在上一个部分中,我们最初指示 getAssetsByGroup 在页面设置为 1 时操作。然而,它尚未配置为遍历所有可能的结果页面。让我们接下来建立这一点:
assetList.push(...result.items);
    if (result.total !== 1000) {
      page = false;
    } else {
      page++;
    }
  }这段代码将响应中的项目添加到 assetList 数组中。如果结果的总数不等于 1,000 的限制,我们将 page 设置为 false,以退出循环。
要将检索到的资产信息保存到外部 JSON 文件中,请添加以下代码:
const resultData = {
    totalResults: assetList.length,
    results: assetList,
  };
  await fs.writeFile('results.json', JSON.stringify(resultData, null, 2));
    console.log('结果已保存到 results.json')
  console.timeEnd('getAssetsByGroup');这段代码构建了一个 resultData 对象,包含总结果数和 assetList 数组。我们应用 fs.writeFile 将数据写入名为 results.json 的 JSON 文件。最后,我们记录一条确认消息并使用 console.timeEnd 结束计时。
现在,我们需要建立一个安全网来处理可能的服务器请求失败。这可以通过以下设置实现。如果在请求执行过程中出现问题,这段代码块将记录一条错误消息到我们的控制台。
} catch (error) {
    console.error('发生错误:', error);
}如果你没有插入有效的链上集合 ID,你可能会在请求时遇到错误。
你的 assetList.js 文件应类似于以下代码片段。
const { promises : fs } = require("fs");
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByGroup = async () => {
  console.time('getAssetsByGroup'); // 开始计时
  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.json')
  console.timeEnd('getAssetsByGroup');
    } catch (error) {
    console.error('发生错误:', error);
  }
};
getAssetsByGroup();一旦你的文件类似于上述代码,你可以使用 node assetList.js 命令在终端中运行它以启动请求。这将生成一个 results.json 文件。
完成后,控制台将指示结果已保存到 results.json 文件中,并记录获取资产所需的时间。在我们的案例中,使用 Node.js 检索 Mad Lads 的链上集合资产信息的过程平均耗时 9.27 秒。

当你打开 results.json 文件时,你将看到返回的结果总数以及资产的详细信息。这些将表示属于你查询的集合的单个 NFT。
为了进一步自定义返回的数据,你可以提取特定信息,例如图像、所有者和其他被认为有价值的元数据。
该集合可能显示 9967 的总数而不是 10,000,这是由于计算被烧掉和链外资产的数量。
{
  "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
    }, ...
    // 其他项目
]这将显示返回的所有资产。现在,你可以进一步拆分,只返回代币地址、所有者和各种其他元数据信息。
注意:
你会注意到该集合显示 9967 而不是 10,000。那是因为反映了被烧掉的金额和不再在链上的量。
恭喜你!你已成功使用新发布的数字资产标准 (DAS) API 检索了一个 10k 大小的集合的所有资产。总的来说:
通过使用 DAS API,我们可以简化 Solana 上 dApp 的资产提取。我们只需要使用一个端点,而不必进行多个 API 调用来收集信息。
在未来的教程中,我们将讨论一些其他简化的选项,以返回参与的资产。
- 原文链接: helius.dev/blog/solana-d...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
 
                如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!