关于Solana新DAS API的所有信息

  • Helius
  • 发布于 2023-06-11 17:39
  • 阅读 9

本文详尽介绍了Solana的数字资产标准(DAS)API,提供了关于如何简化NFT和代币检索的全方位指南。文章涵盖了资产类型、API方法及其用法示例,展示了一系列用例以帮助开发者高效使用该API。

15分钟阅读

2023年6月9日

概述

由于引入了数字资产标准(DAS)API,在 Solana 上检索 NFT 和代币变得更加简化。DAS API 是 Solana 开发者工具包的最新补充,提供了一个统一的界面来检索 Solana 上的数字资产。开发者现在可以利用一个单一的 API 来获取他们应用程序所需的数据,而不必处理与不同资产类型交互的多个端点。

本互动指南将涵盖:

  1. 理解 Solana 上可用的资产类型。
  2. 详细了解 DAS API 提供的方法。
  3. 各个端点的实际用例演示,易于自定义。

本指南将使你能够跟随每个用例,在结束时,你将能够熟练使用 DAS。

前提条件

  • 安装 Node.js (需要 v18.0 以使用内置的 fetch)
  • Helius RPC
  • JavaScript 的基本知识

环境设置

  1. 创建一个名为 functions 的项目文件夹。
  2. 对于每个示例,在该文件夹内创建一个新文件。

资产类型

在 Solana 生态系统中,"资产" 可以是任何有价值的数字项目,比如存在于区块链上的代币或非同质化代币(NFT)。Solana 支持各种各样的这些资产。了解 DAS API 在交互这些资产时返回的数据类型至关重要。

让我们更详细地查看每种资产类型。

非同质化

非同质化资产遵循标准 NFT 模型,存储在代币账户中的元数据。这些数据存储在程序派生地址(PDA)中,PDA 是由程序拥有而不是特定用户拥有的地址。它们在 Solana 区块链上具有元数据 PDA 和主版本 PDA。

同质化

同质化资产是具有有限元数据的 SPL 代币。它们可以代表像 USDC 或社区/项目代币这样的代币。如果在创建时其小数值大于 0,则一个代币将符合同质化标准。

同质化资产

同质化资产代表项目而不是单个单位。它们可以持有比标准同质化资产更多的元数据。如果在创建同质化标准项目时小数设置为 0,则会转变为同质化资产标准。

可编程非同质化

可编程非同质化资产镜像非同质化标准,但保持在一个冻结的代币账户中。这种状态防止用户在不与代币元数据程序交互的情况下销毁、锁定或转移可编程资产。该标准是对 Solana 上版税争论的回应。

可用方法

DAS API 提供了多种方法,针对不同的用例,包括:

  1. getAsset: 通过 ID 检索资产。
  2. searchAssets: 使用各种参数查找资产。
  3. getAssetProof: 通过 ID 获取压缩资产的 merkle 证明。
  4. getAssetsByGroup: 根据组键和值获取资产列表。
  5. getAssetsByOwner: 检索特定地址拥有的资产列表。
  6. getAssetsByCreator: 获取由特定地址创建的资产列表。
  7. getAssetsByAuthority: 查找具有特定权限的资产列表。

有关每种方法的详细信息,请参考我们的 文档

1. 获取资产

getAsset 端点允许你通过 ID 检索特定资产。这个 ID 可以代表链上的代币地址或针对压缩资产的 merkle 树中的 ID。

欲了解更多信息,请参考 getAsset 文档

示例

假设我们想获取 Rank 1 Claynosaurz 资产的元数据。在这种情况下,我们需要找到资产的 ID,设置我们的函数以向 DAS 发起调用,并安排我们的响应来解析我们需要的确切对象。

请在下面按照步骤操作:

  1. 首先,在名为“getAsset.js”的新文件中设置函数:

代码

const url = `https://rpc.helius.xyz/?api-key=`;

const getAsset = async () => {
// 代码在这里
};
getAsset();

     2. 接下来,设置你的 fetch 和 await 操作。在请求体中包含所需的 ID 参数:

代码

const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'my-id',
      method: 'getAsset',
      params: {
    // Rank 1 Claynosaurz #7392
        id: 'B1rzqj4cEM6pWsrm3rLPCu8QwcXMn6H6bd7xAnk941dU',
      },
    }),
  });

在这一步中,我们向 DAS API 发送一个 POST 请求,请求体中包含资产的独特 ID。

    3. 解析结果并显示元数据:

代码

const { result } = await response.json();
console.log("资产: ", result);

这段代码将 API 响应解析为 JSON 格式,并将结果记录到控制台。

然后,你可以使用命令 node getAsset.js 运行脚本。

注意

该方法用于检索单个资产的数据。如果你需要搜索一组资产,DAS API 提供了其他方法,我们稍后将讨论。

结果

执行此脚本将显示指定资产的元数据:

代码

asset:  {
  interface: 'Custom',
  id: 'B1rzqj4cEM6pWsrm3rLPCu8QwcXMn6H6bd7xAnk941dU',
  content: {
    '$schema': 'https://schema.metaplex.com/nft1.0.json',
    json_uri: 'https://nftstorage.link/ipfs/bafybeig2dp7oyauxdkhwduh274ekbl3cixyvbnky444qfewz3vfcauos6m/7391.json',
    files: [],
    metadata: { name: 'Claynosaurz #7392', symbol: 'DINO' }
  },
  authorities: [\
    {\
      address: 'B7B2g3WbdZMDV3YcDGRGhEt5KyWqDJZFwRR8zpWVEkUF',\
      scopes: [Array]\
    }\
  ],
  compression: {
    eligible: false,
    compressed: false,
    data_hash: '',
    creator_hash: '',
    asset_hash: '',
    tree: '',
    seq: 0,
    leaf_id: 0
  },
  grouping: [\
    {\
      group_key: 'collection',\
      group_value: '6mszaj17KSfVqADrQj3o4W3zoLMTykgmV37W4QadCczK'\
    }\
  ],
  royalty: {
    royalty_model: 'creators',
    target: null,
    percent: 0.05,
    basis_points: 500,
    primary_sale_happened: true,
    locked: false
  },
  creators: [\
    {\
      address: 'AoebZtN5iKpVyUBc82aouWhugVknLzjUmEEUezxviYNo',\
      share: 0,\
      verified: true\
    },\
    {\
      address: '36tfiBtaDGjAMKd6smPacHQhe4MXycLL6f9ww9CD1naT',\
      share: 100,\
      verified: false\
    }\
  ],
  ownership: {
    frozen: false,
    delegated: false,
    delegate: null,
    ownership_model: 'single',
    owner: '4zdNGgAtFsW1cQgHqkiWyRsxaAgxrSRRynnuunxzjxue'
  },
  supply: null,
  mutable: true
}

该输出提供有关资产的详细信息,包括接口类型、ID、元数据、创造者、权限和所有权。

完整代码

以下是使用其 ID 获取资产的完整代码:

代码

const url = `https://rpc.helius.xyz/?api-key=`;

const getAsset = async () => {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'my-id',
      method: 'getAsset',
      params: {
        id: 'B1rzqj4cEM6pWsrm3rLPCu8QwcXMn6H6bd7xAnk941dU',
      },
    }),
  });

  const { result } = await response.json();
  console.log("资产: ", result);
};

getAsset();

确保将 <api-key> 替换为你的实际 API 密钥。

在此代码中,我们定义了一个异步函数 getAsset,它向 DAS API 发送一个 POST 请求。我们将资产的 ID 作为请求体的一部分传递。请求完成后,函数将响应解析为 JSON,并将资产数据打印到控制台。最后,我们调用 getAsset 函数以执行该过程。

2. 获取资产证明

getAssetProof 端点用于检索资产证明,这对于对压缩程序进行修改是必要的。这些修改包括转移、销毁、更新创造者、更新集合以及解压缩压缩资产等操作。

欲了解更多使用资产证明的修改详细信息,请参考 文档

示例

要获取修改压缩资产所需的资产证明,请遵循以下步骤:

  1. 首先,在名为“getAssetProof.js”的新文件中设置函数:

代码

const url = `https://rpc.helius.xyz/?api-key=`;

const getAsset = async () => {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'my-id',
      method: 'getAsset',
      params: {
        id: 'B1rzqj4cEM6pWsrm3rLPCu8QwcXMn6H6bd7xAnk941dU',
      },
    }),
  });

  const { result } = await response.json();
  console.log("资产: ", result);
};

getAsset();

      2. 继续设置你的 fetch 和 await。在请求体中包含所需的 ID 参数:

代码

const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
        body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'my-id',
      method: 'getAssetProof',
      params: {
        id: 'JDuAmJjiiNKCfK9SyW1aQCNvhL7krhVWZbeijVupAz4i'
      },
    }),
  });

     3. 解析结果并提取根:

代码

const { proof } = await response.json();
console.log("资产证明: ", result);
const root = decode(proof.root);
console.log(root)

‍在这里,我们从资产证明中提取根,随后可以用它对压缩资产进行其他修改。

在终端运行 node getAssetProof.js 以获取你在此处设置的资产的返回值。

结果

输出将包含资产证明信息:

代码

资产证明:  {
  root: 'FCdCNPGauQp1NqZbs1f4DDAWawHLbBqfD9LYjMy1fqH4',
  proof: [\
    'EmJXiXEAhEN3FfNQtBa5hwR8LC5kHvdLsaGCoERosZjK',\
    '7NEfhcNPAwbw3L87fjsPqTz2fQdd1CjoLE138SD58FDQ',\
    '6dM3VyeQoYkRFZ74G53EwvUPbQC6LsMZge6c7S1Ds4ks',\
    '34dQBtcjnCUoPVzZEmVPAMH7b3b8aD6GUB9aYS11AaWJ',\
    '2VG5cKeBZdqozwhHGGzs13b9tzy9TXt9kPfN8MzSJ1Sm',\
    'r1o8vR5KFHJeER7A1K7kBCjceDHnUbSwiFEqqmeAQSd',\
    '88sRtuz1QHWhYEKtx1VamwwrmtDkb8vyDyUuqWCJrxoa',\
    '9Y8Xa2qwARx7Mg6deJwP37UEX9BA2tM75N4f6vaGyBDU',\
    'CKWwHXAcqoTptkjZkuKqhQ9iuajC8dK6f8eGpknesqWS',\
    '4n9Z4eSKNZa1a4oA3sbFGowA7go9BV9WopLpA4KqnYdD',\
    '6MJKrpnK1GbYsnEzwMRWStNGkTjAZF23NhzTQSQVXsD3',\
    'HjnrJn5vBUUzpCxzjjM9ZnCPuXei2cXKJjX468B9yWD7',\
    '4YCF1CSyTXm1Yi9W9JeYevawupkomdgy2dLxEBHL9euq',\
    'E3oMtCuPEauftdZLX8EZ8YX7BbFzpBCVRYEiLxwPJLY2'\
  ],
  node_index: 16384,
  leaf: '6YdZXw49M97mfFTwgQb6kxM2c6eqZkHSaW9XhhoZXtzv',
  tree_id: '2kuTFCcjbV22wvUmtmgsFR7cas7eZUzAu96jzJUvUcb7'
}

完整代码

以下是使用其 ID 获取资产证明的完整代码:

代码

const url = `https://rpc.helius.xyz/?api-key=`;

const getAssetProof = async () => {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'my-id',
      method: 'getAssetProof',
      params: {
        id: 'JDuAmJjiiNKCfK9SyW1aQCNvhL7krhVWZbeijVupAz4i'
      },
    }),
  });
  const { result } = await response.json();
  console.log("资产证明: ", result);
    const root = proof.root;
    console.log(root)
};
getAssetProof();

确保将 <api-key> 替换为你的实际 API 密钥。

在此脚本中,我们定义了一个异步函数 getAssetProof,它向 Helius API 发送了 POST 请求。我们在请求体中传递资产的 ID。请求完成后,该函数将响应解析为 JSON,并将资产证明及其根打印到控制台。最后,我们调用 getAssetProof 函数以执行该过程。

3. 搜索资产

searchAssets 方法根据指定的搜索参数检索数字资产,提供了一种灵活的方法来获取数据。它允许用户自定义搜索,从而更详细地控制返回的资产。

详细参数可在 searchAssets 文档 中找到。

示例

让我们通过一个示例,让我们想要从用户的钱包中显示属于 Drip Haus 集合的资产图像和名称,并且仅显示其中的压缩项。为了简化本教程,我们将以 JSON 文件形式发布这个示例钱包中每个 Drip 资产的名称和图像。

  1. 首先,创建一个名为 searchAssets.js 的新文件,并在其中使用以下异步函数:

代码

const fs = require('fs');
const url = `https://rpc.helius.xyz/?api-key=`;

const searchAssets = async () => {
    // 代码在这里
};
searchAssets();

     2. 实现该函数以发送 POST 请求并指定搜索参数。在此案例中,我们使用压缩、所有者地址和集合分组参数以实现我们的预期结果:

代码

const response = await fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: "my-id",
      method: "searchAssets",
      params: {
        // 仅返回压缩项目。
        compressed: true,
        // 示例钱包
        ownerAddress: "2k5AXX4guW9XwRQ1AKCpAuUqgWDpQpwFfpVFh3hnm2Ha",
        // Drip Haus 集合 ID。
        grouping: [\
          "collection",\
          "DRiP2Pn2K6fuMLKQmt5rZWyHiUZ6WK3GChEySUpHSS4x"\
        ],
        page: 1,
      },
    }),
  });

    3. 解析响应,以其 ID 将资产分组,并处理潜在的重复项,通过详细说明我们需要的确切项目,从而实现处理:

代码

const { result } = await response.json();

  const groupedResults = [];

  for (let i = 0; i < result.items.length; i++) {
    const asset = {
      id: result.items[i].id,
      name: result.items[i].content.metadata.name,
      json_uri: result.items[i].content.json_uri,
    };

    4. 下一个函数是寻找任何重复的资产并将其从列表中移除,你可以选择不使用此功能以显示重复资产。当确定不是重复资产时,这也将添加到一个新的资产组中:

代码

const existingGroup = groupedResults.find(group => group.id === asset.id);
        if (existingGroup) {
      // 将资产添加到现有组
      existingGroup.assets.push(asset);
    } else {
      // 为资产创建新组
      const newGroup = {
        id: asset.id,
        assets: [asset],
      };
  // 将新组添加到分组结果中
      groupedResults.push(newGroup);
    }
  }

5. 将搜索结果保存到名为 searchResults.json 的 JSON 文件中:

代码

const json = JSON.stringify(groupedResults, null, 2);

// 将 JSON 写入文件
fs.writeFileSync('searchResults.json', json);

console.log('结果已保存到 results.json');

要执行脚本,请运行 node searchAssets.js。这将以搜索结果填充 searchResults.json 文件。

结果

代码

[
  {
    "id": "4XSuZ2JaCPYA76EomCd1mZCtrjkx4F4sdcepBgBF2LKE",
    "assets": [
      {
        "id": "4XSuZ2JaCPYA76EomCd1mZCtrjkx4F4sdcepBgBF2LKE",
        "name": "MOMENT",
        "json_uri": "https://arweave.net/3DniodKpcCTio-GlyB4GMjdA4c5epHzYQecdLZctt5s"
      }
    ]
  },
  {
    "id": "AJw2QNwWMLWTuUTiUWYpEyGjUQSPB5rYEcbn5uiBjQ2g",
    "assets": [
      {
        "id": "AJw2QNwWMLWTuUTiUWYpEyGjUQSPB5rYEcbn5uiBjQ2g",
        "name": "\"Kokoro\" (心)",
        "json_uri": "https://arweave.net/PyPo4Zr4iWH2iRROBDtZTFZv3qWw1dVcrYPq4A_6ttM"
      }
    ]
  }, ...
}

完整代码

代码

const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');

const searchAssets = async () => {
  const response = await fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: "my-id",
      method: "searchAssets",
      params: {
        // 仅返回压缩项目。
        compressed: true,
        // 示例钱包
        ownerAddress: "2k5AXX4guW9XwRQ1AKCpAuUqgWDpQpwFfpVFh3hnm2Ha",
        // Drip Haus 集合 ID。
        grouping: [
          "collection",
          "DRiP2Pn2K6fuMLKQmt5rZWyHiUZ6WK3GChEySUpHSS4x"
        ],
        page: 1,
      },
    }),
  });
  const { result } = await response.json();

  const groupedResults = [];

  for (let i = 0; i < result.items.length; i++) {
    const asset = {
      id: result.items[i].id,
      name: result.items[i].content.metadata.name,
      json_uri: result.items[i].content.json_uri,
    };

    // 查找资产的现有组,如果存在
    const existingGroup = groupedResults.find(group => group.id === asset.id);

    if (existingGroup) {
      // 添加资产到现有组
      existingGroup.assets.push(asset);
    } else {
      // 为资产创建新组
      const newGroup = {
        id: asset.id,
        assets: [asset],
      };

      // 将新组加入分组结果
      groupedResults.push(newGroup);
    }
  }

  // 将分组结果转换为 JSON
  const json = JSON.stringify(groupedResults, null, 2);

  // 将 JSON 写入文件
  fs.writeFileSync('searchResults.json', json);

  console.log('结果已保存至 results.json');
};

searchAssets();

确保用你的实际 API 密钥替换 <api-key>

在这个脚本中,我们定义了一个异步函数 searchAssets,该函数发送一个 POST 请求。它在请求体中使用了各种搜索参数,如压缩、所有者地址和集合 ID。一旦请求完成,函数将解析响应为 JSON 并提取相关资产信息(ID、名称、JSON URI)。它根据 ID 对这些资产进行分组,并将这个组织好的数据保存到文件名为 searchResults.json 的 JSON 文件中。最后,我们调用 searchAssets 函数来启动这个过程。

4. 根据所有者获取资产

getAssetsByOwner 端点提供了特定地址拥有的数字资产列表。这是使用 Helius 获取特定数字资产所有权信息的最快方法。

示例

要获取某个地址拥有的资产,请按照以下步骤操作:

  1. 首先在新的文件中设置函数,命名为“getAssetsByOwner.js”:

代码

const fs = require('fs');
const url = `https://rpc.helius.xyz/?api-key=`;

const getAssetsByOwner = async () => {
  // 代码放这里
};
getAssetsByOwner();
  1. 设置你的 fetch 和 await,并在请求体中包含参数,对于此端点我们使用 ownerAddress

代码

const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'hunter-test',
      method: 'getAssetsByOwner',
      params: {
        // 示例钱包
        ownerAddress: '2k5AXX4guW9XwRQ1AKCpAuUqgWDpQpwFfpVFh3hnm2Ha',
        page: 1
      },
    }),
  });
  1. 然后,解析你的响应并提取必要的资产信息以发布到 JSON。我们将使用资产 ID、名称和 json URI 进行分组到我们正在搜索的钱包:

代码

const { result } = await response.json();
const groupedResults = {};

for (let i = 0; i < result.items.length; i++) {
  const ownerAddress = result.items[i].owner.address;
  const asset = {
    id: result.items[i].id,
    name: result.items[i].content.metadata.name,
    json_uri: result.items[i].content.json_uri,
  };

  if (groupedResults.hasOwnProperty(ownerAddress)) {
    // 添加资产到现有组
    groupedResults[ownerAddress].assets.push(asset);
  } else {
    // 为所有者创建新组
    groupedResults[ownerAddress] = {
      assets: [asset],
    };
  }
}
  1. 现在我们可以设置对象,以便发布到 JSON:

代码

// 将分组结果转换为 JSON
const json = JSON.stringify(groupedResults, null, 2);

// 将 JSON 写入文件
fs.writeFileSync('results.json', json);

console.log('结果已保存至 results.json');

结果

输出将包括指定地址拥有的数字资产:

代码

{
  "2k5AXX4guW9XwRQ1AKCpAuUqgWDpQpwFfpVFh3hnm2Ha": {
    "assets": [
      {
        "id": "7Qj3QGCqRChr3uBR4R756usz2eoPSisoWcPfeozY7Bo",
        "name": "",
        "json_uri": "https://nftstorage.link/ipfs/bafybeiewlaxjeredwgsboqqha2ww25g46dgrqs6lwn5cooq3evsvye33iy/3071.json"
      },
      {
        "id": "8W1Dx9vhyQ8fNyi6oVu2EFbZHo2kKpcRxMVbQ3em3ne",
        "name": "Compass Rose #2745",
        "json_uri": "https://shdw-drive.genesysgo.net/HqhFDmVhqqN23g4soMd8UzrfLEXT8GsjWtWaqxfm9A2x/2745.json"
      },
      {
        "id": "Ba5qsjq5LryLPZ1e6AVqwPzB5LBBBzGWvvRQww4KCiG",
        "name": "Foxy Pixel Demon #423",
        "json_uri": "https://cdn.secretsphinx.io/ml/1c22a51697c644a8e45f603ed884ade7.json"
      },
      {
        "id": "Hmid2Dhi3zLV7AxCAibQ8n4nviWdPv2ZvUeZq4N33oe",
        "name": "",
        "json_uri": "https://nftstorage.link/ipfs/bafybeiewlaxjeredwgsboqqha2ww25g46dgrqs6lwn5cooq3evsvye33iy/140.json"
      }, ...
    ]
  }
}

完整代码

以下是获取特定地址拥有的资产的完整代码:

代码

const url = `https://rpc.helius.xyz/?api-key=`;

const getAssetsByOwner = async () => {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'hunter-test',
      method: 'getAssetsByOwner',
      params: {
        // 示例钱包
        ownerAddress: '2k5AXX4guW9XwRQ1AKCpAuUqgWDpQpwFfpVFh3hnm2Ha',
        page: 1,
      },
    }),
  });
  const { result } = await response.json();
  const groupedResults = {};

  for (let i = 0; i < result.items.length; i++) {
    const ownerAddress = result.items[i].owner.address;
    const asset = {
      id: result.items[i].id,
      name: result.items[i].content.metadata.name,
      json_uri: result.items[i].content.json_uri,
    };

    if (groupedResults.hasOwnProperty(ownerAddress)) {
      // 添加资产到现有组
      groupedResults[ownerAddress].assets.push(asset);
    } else {
      // 为所有者创建新组
      groupedResults[ownerAddress] = {
        assets: [asset],
      };
    }
  }

  // 将分组结果转换为 JSON
  const json = JSON.stringify(groupedResults, null, 2);

  // 将 JSON 写入文件
  fs.writeFileSync('results.json', json);

  console.log('结果已保存至 results.json');
};

getAssetsByOwner();

确保用你的实际 API 密钥替换 <api-key>

在这个脚本中,我们定义了一个异步函数 getAssetsByOwner,该函数向 Helius API 发送一个 POST 请求。我们将所有者的地址传递在请求体中。请求完成后,函数解析响应为 JSON 并将拥有指定地址的资产打印到控制台。最后,我们调用 getAssetsByOwner 函数以执行该过程。

5. 根据组获取资产

getAssetsByGroup 端点用于检索与特定集合 ID 相关的数字资产。当你需要获取特定于集合的项目或希望将 token-gated dApp 与特定链上的集合关联时,此端点至关重要。

示例

在这个场景中,我们将为 SMB 设置集合快照。解析响应以提取所有者的资产从所拥有的对象中非常重要,详细信息请参阅我们的 文档。目标是筛选出拥有多个 SMB 的所有者,并仅在我们的 JSON 中显示一次,有效地创建了一个“快照”。

  1. 首先在新文件中设置函数,命名为“getAssetsByGroup.js”。使用 Set 确保我们只存储唯一的所有者:

代码

const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');
const uniqueOwners = new Set();

const getAssetsByGroup = async () => {
  // 代码放这里
};
getAssetsByGroup();
  1. 继续设置你的 fetch 和 await。在请求体中列出上述参数。设置 groupKey 和 groupValue。初始化 page 为 1,将 hasMoreResults 设置为 true,以准备分页。这将在后面设置一个分页功能,如果页面的结果少于 1000(每个请求的最大限制),则返回 false:

代码

let page = 1;
let hasMoreResults = true;

while (hasMoreResults) {
  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: 'SMBtHCCC6RYRutFEPb4gZqeBLUZbMNhRKaMKZZLHi7W',
        page,
        limit: 1000,
      },
    }),
  });
  1. 解析结果以提取创建当前所有者快照所需的所有者字符串:

代码

const { result } = await response.json();
// 将每个所有者添加到 Set 中,自动丢弃重复项
result.items.forEach(item => uniqueOwners.add(item.ownership.owner));
  1. 通过在 1000 个结果的情况下增加 page 参数来设置分页。如果少于 1000,则将 hasMoreResults 设置为 false 以停止分页:

代码

if (result.items.length < 1000) {
    hasMoreResults = false;
  } else {
    page++;
  }
}
  1. 现在我们可以将所有者设置为数组,并设置根值以发布到 JSON,包含持有者的数量以及每个唯一的所有者钱包:

代码

const uniqueOwnersArray = Array.from(uniqueOwners);

const root = {
  count: uniqueOwners.size,
  owners: uniqueOwnersArray
};
  1. 将唯一所有者的 Set 转换为数组。设置根值以发布到 JSON,包括持有者的数量和每个唯一的所有者钱包:

代码

fs.writeFile('./ownerResults.json', jsonResult, 'utf8', (err) => {
    if (err) {
      console.error("写入 JSON 文件时出错:", err);
    } else {
      console.log("JSON 文件保存成功。");
    }
  });
console.log("唯一所有者的总数量:", uniqueOwners.size);
};

然后可以运行命令 node getAssetsByGroup.js 以填充“ownerResults.json”文件。

结果

你的结果将是一个持有快照的 JSON 等价物,包括唯一所有者的数量和所有唯一所有者的列表:

代码

{
  "count": 2785,
  "owners": [
    "6VqzFgtrJb33nhvbug4KZoUx8p65dD2iT1QuAeAQgYiw",
    "5Xeb43ASEa64b9i9owcLB4yrNbUw1oMiTpcWsAdXN8qG",
    "Cb355XH2WGPeQUGTTXWiQZT4nhnyHCPkhScDezUGhXQF",
    "Fuu7xpK3mWqpqPLTHaxF7pU2czkBESKyg3r2Lm2F3AWz",
    "1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix",
    "86tCSKzryE5KvbTmMXN9tkxyn8GNr4z54DnNqrcZwYuy",
    "D2DYL5sdxBCpauvKs1oyQkkSm2B9rFzzGowMacv3Q58z",
    // 更多结果 ...
  ]
}

完整代码

代码

const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');
const uniqueOwners = new Set();

const getAssetsByGroup = async () => {
  let page = 1;
  let hasMoreResults = true;

  while (hasMoreResults) {
    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: 'SMBtHCCC6RYRutFEPb4gZqeBLUZbMNhRKaMKZZLHi7W',
          page,
          limit: 1000,
        },
      }),
    });

    const { result } = await response.json();
    // 将每个所有者添加到 Set 中,自动丢弃重复项
    result.items.forEach(item => uniqueOwners.add(item.ownership.owner));

    if (result.items.length < 1000) {
      hasMoreResults = false;
    } else {
      page++;
    }
  }

  // 将 Set 转换为 Array 以便转换为字符串
  const uniqueOwnersArray = Array.from(uniqueOwners);

  const root = {
    count: uniqueOwners.size,
    owners: uniqueOwnersArray
  };

  const jsonResult = JSON.stringify(root, null, 2);

  fs.writeFile('./ownerResults.json', jsonResult, 'utf8', (err) => {
    if (err) {
      console.error("写入 JSON 文件时出错:", err);
    } else {
      console.log("JSON 文件保存成功。");
    }
  });
};
console.log("唯一所有者的总数量:", uniqueOwners.size);

getAssetsByGroup();

确保用你的实际 API 密钥替换 <api-key>

你现在已学习如何使用 getAssetsByGroup 端点检索与特定集合 ID 相关的数字资产。通过有效利用分页和 Set 数据结构以确保唯一所有者条目,你可以创建任何带有链上 ID 的集合的当前持有者快照。

6. 根据创建者获取资产

getAssetsByCreator 端点用于根据特定公钥地址检索创建的资产。当你想查找与特定艺术家或 Solana 上项目相关的资产时,这个端点非常有用。

示例

在这个示例中,我们将返回由 Zen0 创建的资产。我们可以使用创建者地址,并将 onlyVerified 参数设置为 true 以仅检索由经过验证的钱包创建的资产。我们将解析结果以显示每个资产的 ID 和其所有者。

  1. 首先在新文件中设置名为 "getAssetsByCreator.js" 的函数。我们将使用 fs 模块将结果发布到 JSON 文件:

代码

const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');

const getAssetsByCreator = async () => {
  // 代码放这里
};
getAssetsByCreator();
  1. 现在我们可以设置 fetch 请求并 await 响应。在请求体中设置必要的参数,包括 creatorAddressonlyVerified

代码

let page = 1;
let allResults = [];
let hasMoreResults = true;

while (hasMoreResults) {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'my-id',
      method: 'getAssetsByCreator',
      params: {
        creatorAddress: 'zvrsoq2LbNxekPqLK1v8DsLgeC4LHxMQL52beX8Ktn8',
        onlyVerified: true,
        page,
        limit: 1000,
      },
    }),
  });

别忘了替换 <creator-address> 为你希望检索其资产的创作者的实际地址。

  1. 解析响应以提取结果并将其存储在数组中:

代码

const { result } = await response.json();
allResults = allResults.concat(result.items);

if (result.items.length < 1000) {
    hasMoreResults = false;
  } else {
    page++;
  }
}
  1. 根据所有权 ID 对资产进行分组(因为一个人可以拥有多个资产),并显示每个 ID 拥有的资产。如果检测到新所有者,将在 JSON 文件中创建新组:

代码

const groupedResults = {};

for (let i = 0; i < allResults.length; i++) {
  const ownershipId = allResults[i].ownership.owner;
  const asset = {
    id: allResults[i].id,
    ownershipId: ownershipId,
  };

  if (groupedResults.hasOwnProperty(ownershipId)) {
    // 将资产添加到现有组
    groupedResults[ownershipId].assets.push(asset);
  } else {
    // 为所有权 ID 创建新组
    groupedResults[ownershipId] = {
      assets: [asset],
    };
  }
}
  1. 下一步是构造结果。在这种情况下,我们对 NFT 的地址和返回的每个资产的所有者感兴趣。我们使用根对象来指定返回的长度,并存储修改后的结果以进行输出:

代码

// 创建新数组以保存所需属性
const modifiedResults = totalResults.map(item => ({
    id: item.id,
    owner: item.ownership.owner
  }));
  // 创建根对象以保存计数和结果
  const root = {
    count: modifiedResults.length,
    results: modifiedResults
  };
  1. 最后,使用 fs 模块将结果保存到名为 "creatorResults.json" 的文件:

代码

// 将分组结果转换为 JSON
const json = JSON.stringify(groupedResults, null, 2);

// 将 JSON 写入文件
fs.writeFileSync('creatorResults.json', json);

console.log('结果已保存至 results.json');

最后,运行命令 node getAssetsByCreator.js 来执行脚本并填充 "creatorResults.json" 文件中的检索结果。

结果

生成的 JSON 文件包含每个所有者的公钥地址及其拥有的资产。每个资产由其 ID 代表,为由特定创作者创建的资产的所有权状态提供清晰快照。

代码

{
  "ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22": {
    "assets": [
      {
        "id": "KvbtDebCi6BGSFuafJWZpwV5mt1XYng13Pt2vh4G2Qa",
        "ownershipId": "ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22"
      },
      {
        "id": "28bXCZaETv6ihBGbtavDkedzRcWZPbmDG5VYXxSdmZBc",
        "ownershipId": "ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22"
      },
      {
        "id": "2H4txSfZwV3nX4fJ1D8dPNHiafn247iQ8vtq3y3UYdpe",
        "ownershipId": "ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22"
      },
      {
        "id": "5oauJRPWbboJVUBms2mqBF2wMQGMSCFScgX18SawyKV3",
        "ownershipId": "ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22"
      },
      ...
  }
}

'ownershipId' 代表 Solana 区块链上所有者的公钥地址,资产是与该地址关联的 NFT。

完整代码

代码

const fs = require('fs');

const url = `https://rpc.helius.xyz/?api-key=`;

const getAssetsByCreator = async () => {
  let page = 1;
  let allResults = [];
  let hasMoreResults = true;

  while (hasMoreResults) {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: 'my-id',
        method: 'getAssetsByCreator',
        params: {
          creatorAddress: 'zvrsoq2LbNxekPqLK1v8DsLgeC4LHxMQL52beX8Ktn8',
          onlyVerified: true,
          page,
          limit: 1000,
        },
      }),
    });

    const { result } = await response.json();
    allResults = allResults.concat(result.items);

    if (result.items.length < 1000) {
      hasMoreResults = false;
    } else {
      page++;
    }
  }

  // 创建一个对象来存储分组结果
  const groupedResults = {};

  for (let i = 0; i < allResults.length; i++) {
    const ownershipId = allResults[i].ownership.owner;
    const asset = {
      id: allResults[i].id,
      ownershipId: ownershipId,
    };

    if (groupedResults.hasOwnProperty(ownershipId)) {
      // 添加资产到现有组
      groupedResults[ownershipId].assets.push(asset);
    } else {
      // 为所有权 ID 创建新组
      groupedResults[ownershipId] = {
        assets: [asset],
      };
    }
  }

  // 将分组结果转换为 JSON
  const json = JSON.stringify(groupedResults, null, 2);

  // 将 JSON 写入文件
  fs.writeFileSync('creatorResults.json', json);
};

console.log('结果已保存到 results.json');\ };\ \ getAssetsByCreator();\


\
确保将 `<api-key>` 替换为你的实际 API 密钥。\
\
在这个例子中,我们向 DAS API 的 “getAssetsByCreator” 端点发起异步请求。然后,我们传入我们的创作者地址并表示他们是经过验证的创作者。最后,我们设置响应,以解析每个在创作者地址下的资产的所有者,并发布到外部 JSON 文件。\
\
总的来说,这是一个有价值的工具,适合任何对跟踪或分析资产在 Solana 区块链上移动感兴趣的人,尤其是那些与特定创作者或项目相关的资产。\
\
### [7\. 按权威获取资产](https://www.helius.dev/blog/all-you-need-to-know-about-solanas-new-das-api\#7-get-assets-by-authority)\
\
函数 `getAssetsByAuthority` 获取与特定更新权威相关的资产。更新权威是一个拥有修改集合权限的地址。当你需要在集合 ID 不存在的情况下获取一组资产时,此功能尤其有价值。此外,它还提供了从一个权威地址检索更多资产的优势,扩展到一个集合 ID 之外的范围。\
\
#### [示例](https://www.helius.dev/blog/all-you-need-to-know-about-solanas-new-das-api\#example)\
\
在以下示例中,我们将检索 Taiyo Robotics、Pilots 和 Infants 中的每个集合 NFT 及其各自的所有者。由于它们共享一个共同的更新权威,因此可以返回与该项目相关的所有结果。\
\
这是对 `getAssetsByGroup` 函数的升级,因为你可以将资产分组与设定的权威 `CDgbhX61QFADQAeeYKP5BQ7nnzDyMkkR3NEhYF2ETn1k` 相关联。\
\
1. 首先,在新创建的名为 "getAssetsByAuthority.js" 的文件中设置函数:\
\
代码\
\
```\
const url = `https://rpc.helius.xyz/?api-key=`;\
\
const getAssetsByAuthority = async () => {\
  // 代码在这里\
};\
getAssetsByAuthority();\
```\
\
1. 配置获取请求并在请求体中整合必要的参数,例如 `authorityAddress`、`page` 和 `limit`:\
\
代码\
\
```\
let page = 1;\
let hasMoreResults = true;\
\
while (hasMoreResults) {\
    const response = await fetch(url, {\
      method: 'POST',\
      headers: {\
        'Content-Type': 'application/json',\
      },\
      body: JSON.stringify({\
        jsonrpc: '2.0',\
        id: 'my-id',\
        method: 'getAssetsByAuthority',\
        params: {\
          authorityAddress: 'CDgbhX61QFADQAeeYKP5BQ7nnzDyMkkR3NEhYF2ETn1k',\
          page,\
          limit: 1000,\
        },\
      }),\
    });\
```\
\
确保将 `<authority-address>` 替换为你希望提取资产的实际权威地址。\
\
     3\. 现在可以安排我们的返回,循环遍历结果,如果结果有1000个。\
\
     如果结果数量较少,则标志将被设置为 false,从而终止分页,`hasMoreResults` 将返回 false。\
\
代码\
\
```\
const { result } = await response.json();\
    totalResults.push(...result.items);\
\
    if (result.items.length < 1000) {\
      hasMoreResults = false;\
    } else {\
      page++;\
    }\
  }\
```\
\
1. 处理资产以获取所需的信息。在这里,我们旨在显示资产的 ID 和所有者。我们还将创建一个根对象,以包含资产的计数和处理过的资产数组:\
\
代码\
\
```\
 // 创建新数组以保存所需属性\
 const modifiedResults = totalResults.map(item => ({\
    id: item.id,\
    owner: item.ownership.owner\
  }));\
  // 创建根对象以保存计数和结果\
  const root = {\
    count: modifiedResults.length,\
    results: modifiedResults\
  };\
```\
\
1. 我们现在准备将返回的项目发布到名为 authorityResults.json 的 JSON 文件,并在处理完成后记录日志。\
\
代码\
\
```\
const jsonResult = JSON.stringify(root, null, 2);\
\
  fs.writeFile('./authorityResults.json', jsonResult, 'utf8', (err) => {\
    if (err) {\
      console.error("写入 JSON 文件时出错:", err);\
    } else {\
      console.log("JSON 文件成功保存.");\
    }\
  });\
console.log("处理完成.");\
console.timeEnd("getAssetsByAuthority");\
```\
\
最后,执行命令 `node getAssetsByAuthority.js` 以运行脚本并用获取的结果填充 "authorityResults.json" 文件。\
\
#### [**结果**](https://www.helius.dev/blog/all-you-need-to-know-about-solanas-new-das-api\#result)\
\
`getAssetsByAuthority` 端点的输出包括资产的计数和一个对象数组,每个对象代表一个资产,包含其 ID 和所有者。下面是一个示例:\
\
代码\
\
```\
{\
  "count": 37330,\
  "results": [\
    {\
      "id": "HmwL6uy7gQcXv74Mi8xF5G9mymZNd9rnUCpUFwSx1DX1",\
      "owner": "5gt59Q14FEhT8LuETjLyiNHRkqCQf5hQsPP58ucBy5oC"\
    },\
    {\
      "id": "HmztH56n4GD3p3EdgMKdzj8x21LjFQk4Bcp2YAQD8Urx",\
      "owner": "H3AkHZHfcqGCcJpBn3FJWe52LcLxFMJQoZvZ6XyApFWf"\
    },\
    {\
      "id": "Hn1NZXCaAxcr1btsaDm3eZRtLNbamy9FyrcVGLbZ2k5w",\
      "owner": "AEqhqiQZBBa3dPTY1GwGsZJJnf5vzRKJpdXv6xzakfx8"\
    }, ...\
}\
```\
\
#### [完整代码](https://www.helius.dev/blog/all-you-need-to-know-about-solanas-new-das-api\#full-code)\
\
代码\
\
```\
const fs = require('fs');\
const url = `https://rpc.helius.xyz/?api-key=`;\
\
const totalResults = [];\
\
const getAssetsByAuthority = async () => {\
  let page = 1;\
  let hasMoreResults = true;\
\
  while (hasMoreResults) {\
    const response = await fetch(url, {\
      method: 'POST',\
      headers: {\
        'Content-Type': 'application/json',\
      },\
      body: JSON.stringify({\
        jsonrpc: '2.0',\
        id: 'my-id',\
        method: 'getAssetsByAuthority',\
        params: {\
          authorityAddress: 'CDgbhX61QFADQAeeYKP5BQ7nnzDyMkkR3NEhYF2ETn1k',\
          page,\
          limit: 1000,\
        },\
      }),\
    });\
\
    const { result } = await response.json();\
    totalResults.push(...result.items);\
\
    if (result.items.length < 1000) {\
      hasMoreResults = false;\
    } else {\
      page++;\
    }\
  }\
  // 创建新数组以保存所需属性\
  const modifiedResults = totalResults.map(item => ({\
    id: item.id,\
    owner: item.ownership.owner\
  }));\
\
  // 创建根对象以保存计数和结果\
  const root = {\
    count: modifiedResults.length,\
    results: modifiedResults\
  };\
\
  // 以2个空格的缩进格式化为可读的 JSON 字符串\
  const jsonResult = JSON.stringify(root, null, 2);\
\
  fs.writeFile('./authorityResults.json', jsonResult, 'utf8', (err) => {\
    if (err) {\
      console.error("写入 JSON 文件时出错:", err);\
    } else {\
      console.log("JSON 文件成功保存.");\
    }\
  });\
console.log("处理完成.");\
console.timeEnd("getAssetsByAuthority");\
};\
getAssetsByAuthority()\
```\
\
确保将 `<api-key>` 替换为你的实际 API 密钥。\
\
在这个例子中,我们采用 "getAssetsByAuthority" 方法来返回与一个权威地址相关的所有资产,涵盖 3 个集合。我们只使用 `page` 和 `limit` 作为请求的附加参数。随后,我们解析结果以提取权威下的资产,并将它们存储在外部 JSON 文件中。\
\
## [结论](https://www.helius.dev/blog/all-you-need-to-know-about-solanas-new-das-api\#conclusion)\
\
你现在应该对如何使用数字资产标准 (DAS) API 以及每种方法的多个实际应用有了全面的理解。这标志着从之前需要多个端点来获取特定资产信息的做法重大转变。\
\
这些方法适用于压缩和常规资产,提供了一种统一的接口,以多种方式发起这些请求。\
\
如需更多信息,你始终可以参考我们的详细 [文档](https://docs.helius.dev/compression-and-das-api/digital-asset-standard-das-api) 关于数字资产标准 (DAS) API,并探索我们的 [开放 API 小部件](https://docs.helius.dev/compression-and-das-api/digital-asset-standard-das-api) ,详细分解请求和响应参数。\
\
我们始终欢迎你加入我们的 [**Discord**](https://discord.gg/VbxaGJwmEr) 社区。如有任何疑问,请随时与我联系!\

>- 原文链接: [helius.dev/blog/all-you-...](https://www.helius.dev/blog/all-you-need-to-know-about-solanas-new-das-api)
>- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Helius
Helius
https://www.helius.dev/