本文详尽介绍了Solana的数字资产标准(DAS)API,提供了关于如何简化NFT和代币检索的全方位指南。文章涵盖了资产类型、API方法及其用法示例,展示了一系列用例以帮助开发者高效使用该API。
由于引入了数字资产标准(DAS)API,在 Solana 上检索 NFT 和代币变得更加简化。DAS API 是 Solana 开发者工具包的最新补充,提供了一个统一的界面来检索 Solana 上的数字资产。开发者现在可以利用一个单一的 API 来获取他们应用程序所需的数据,而不必处理与不同资产类型交互的多个端点。
本互动指南将涵盖:
本指南将使你能够跟随每个用例,在结束时,你将能够熟练使用 DAS。
在 Solana 生态系统中,"资产" 可以是任何有价值的数字项目,比如存在于区块链上的代币或非同质化代币(NFT)。Solana 支持各种各样的这些资产。了解 DAS API 在交互这些资产时返回的数据类型至关重要。
让我们更详细地查看每种资产类型。
非同质化资产遵循标准 NFT 模型,存储在代币账户中的元数据。这些数据存储在程序派生地址(PDA)中,PDA 是由程序拥有而不是特定用户拥有的地址。它们在 Solana 区块链上具有元数据 PDA 和主版本 PDA。
同质化资产是具有有限元数据的 SPL 代币。它们可以代表像 USDC 或社区/项目代币这样的代币。如果在创建时其小数值大于 0,则一个代币将符合同质化标准。
同质化资产代表项目而不是单个单位。它们可以持有比标准同质化资产更多的元数据。如果在创建同质化标准项目时小数设置为 0,则会转变为同质化资产标准。
可编程非同质化资产镜像非同质化标准,但保持在一个冻结的代币账户中。这种状态防止用户在不与代币元数据程序交互的情况下销毁、锁定或转移可编程资产。该标准是对 Solana 上版税争论的回应。
DAS API 提供了多种方法,针对不同的用例,包括:
getAsset
: 通过 ID 检索资产。searchAssets
: 使用各种参数查找资产。getAssetProof
: 通过 ID 获取压缩资产的 merkle 证明。getAssetsByGroup
: 根据组键和值获取资产列表。getAssetsByOwner
: 检索特定地址拥有的资产列表。getAssetsByCreator
: 获取由特定地址创建的资产列表。getAssetsByAuthority
: 查找具有特定权限的资产列表。有关每种方法的详细信息,请参考我们的 文档。
getAsset
端点允许你通过 ID 检索特定资产。这个 ID 可以代表链上的代币地址或针对压缩资产的 merkle 树中的 ID。
欲了解更多信息,请参考 getAsset 文档 。
假设我们想获取 Rank 1 Claynosaurz 资产的元数据。在这种情况下,我们需要找到资产的 ID,设置我们的函数以向 DAS 发起调用,并安排我们的响应来解析我们需要的确切对象。
请在下面按照步骤操作:
const url = `https://rpc.helius.xyz/?api-key=`;
const getAsset = async () => {
// 代码在这里
};
getAsset();
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。
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
函数以执行该过程。
getAssetProof
端点用于检索资产证明,这对于对压缩程序进行修改是必要的。这些修改包括转移、销毁、更新创造者、更新集合以及解压缩压缩资产等操作。
欲了解更多使用资产证明的修改详细信息,请参考 文档 。
要获取修改压缩资产所需的资产证明,请遵循以下步骤:
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();
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 { 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
函数以执行该过程。
searchAssets
方法根据指定的搜索参数检索数字资产,提供了一种灵活的方法来获取数据。它允许用户自定义搜索,从而更详细地控制返回的资产。
详细参数可在 searchAssets 文档 中找到。
让我们通过一个示例,让我们想要从用户的钱包中显示属于 Drip Haus 集合的资产图像和名称,并且仅显示其中的压缩项。为了简化本教程,我们将以 JSON 文件形式发布这个示例钱包中每个 Drip 资产的名称和图像。
const fs = require('fs');
const url = `https://rpc.helius.xyz/?api-key=`;
const searchAssets = async () => {
// 代码在这里
};
searchAssets();
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);
}
}
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
函数来启动这个过程。
getAssetsByOwner
端点提供了特定地址拥有的数字资产列表。这是使用 Helius 获取特定数字资产所有权信息的最快方法。
要获取某个地址拥有的资产,请按照以下步骤操作:
const fs = require('fs');
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByOwner = async () => {
// 代码放这里
};
getAssetsByOwner();
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
},
}),
});
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');
输出将包括指定地址拥有的数字资产:
{
"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
函数以执行该过程。
getAssetsByGroup 端点用于检索与特定集合 ID 相关的数字资产。当你需要获取特定于集合的项目或希望将 token-gated dApp 与特定链上的集合关联时,此端点至关重要。
在这个场景中,我们将为 SMB 设置集合快照。解析响应以提取所有者的资产从所拥有的对象中非常重要,详细信息请参阅我们的 文档。目标是筛选出拥有多个 SMB 的所有者,并仅在我们的 JSON 中显示一次,有效地创建了一个“快照”。
const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');
const uniqueOwners = new Set();
const getAssetsByGroup = async () => {
// 代码放这里
};
getAssetsByGroup();
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,
},
}),
});
const { result } = await response.json();
// 将每个所有者添加到 Set 中,自动丢弃重复项
result.items.forEach(item => uniqueOwners.add(item.ownership.owner));
page
参数来设置分页。如果少于 1000,则将 hasMoreResults
设置为 false 以停止分页:if (result.items.length < 1000) {
hasMoreResults = false;
} else {
page++;
}
}
const uniqueOwnersArray = Array.from(uniqueOwners);
const root = {
count: uniqueOwners.size,
owners: uniqueOwnersArray
};
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 的集合的当前持有者快照。
getAssetsByCreator
端点用于根据特定公钥地址检索创建的资产。当你想查找与特定艺术家或 Solana 上项目相关的资产时,这个端点非常有用。
在这个示例中,我们将返回由 Zen0 创建的资产。我们可以使用创建者地址,并将 onlyVerified
参数设置为 true 以仅检索由经过验证的钱包创建的资产。我们将解析结果以显示每个资产的 ID 和其所有者。
fs
模块将结果发布到 JSON 文件:const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');
const getAssetsByCreator = async () => {
// 代码放这里
};
getAssetsByCreator();
await
响应。在请求体中设置必要的参数,包括 creatorAddress
和 onlyVerified
: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>
为你希望检索其资产的创作者的实际地址。
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],
};
}
}
// 创建新数组以保存所需属性
const modifiedResults = totalResults.map(item => ({
id: item.id,
owner: item.ownership.owner
}));
// 创建根对象以保存计数和结果
const root = {
count: modifiedResults.length,
results: modifiedResults
};
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 区块链上移动感兴趣的人,尤其是那些与特定创作者或项目相关的资产。
函数 getAssetsByAuthority
获取与特定更新权威相关的资产。更新权威是一个拥有修改集合权限的地址。当你需要在集合 ID 不存在的情况下获取一组资产时,此功能尤其有价值。此外,它还提供了从一个权威地址检索更多资产的优势,扩展到一个集合 ID 之外的范围。
示例:
在以下示例中,我们将检索 Taiyo Robotics、Pilots 和 Infants 中的每个集合 NFT 及其各自的所有者。由于它们共享一个共同的更新权威,因此可以返回与该项目相关的所有结果。
这是对 getAssetsByGroup
函数的升级,因为你可以将资产分组与设定的权威 CDgbhX61QFADQAeeYKP5BQ7nnzDyMkkR3NEhYF2ETn1k
相关联。
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByAuthority = async () => {
// 代码在这里
};
getAssetsByAuthority();
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>
替换为你希望提取资产的实际权威地址。
如果结果数量较少,则标志将被设置为 false,从而终止分页,hasMoreResults
将返回 false。
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
};
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" 文件。
结果
getAssetsByAuthority
端点的输出包括资产的计数和一个对象数组,每个对象代表一个资产,包含其 ID 和所有者。下面是一个示例:
{
"count": 37330,
"results": [
{
"id": "HmwL6uy7gQcXv74Mi8xF5G9mymZNd9rnUCpUFwSx1DX1",
"owner": "5gt59Q14FEhT8LuETjLyiNHRkqCQf5hQsPP58ucBy5oC"
},
{
"id": "HmztH56n4GD3p3EdgMKdzj8x21LjFQk4Bcp2YAQD8Urx",
"owner": "H3AkHZHfcqGCcJpBn3FJWe52LcLxFMJQoZvZ6XyApFWf"
},
{
"id": "Hn1NZXCaAxcr1btsaDm3eZRtLNbamy9FyrcVGLbZ2k5w",
"owner": "AEqhqiQZBBa3dPTY1GwGsZJJnf5vzRKJpdXv6xzakfx8"
}, ...
}
完整代码
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 文件中。
你现在应该对如何使用数字资产标准 (DAS) API 以及每种方法的多个实际应用有了全面的理解。这标志着从之前需要多个端点来获取特定资产信息的做法重大转变。
这些方法适用于压缩和常规资产,提供了一种统一的接口,以多种方式发起这些请求。
如需更多信息,你始终可以参考我们的详细 文档 关于数字资产标准 (DAS) API,并探索我们的 开放 API 小部件 ,详细分解请求和响应参数。
- 原文链接: helius.dev/blog/all-you-...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!