
Tudo o que você precisa saber sobre a nova DAS API da Solana
Visão geral
A introdução da API Digital Asset Standard (DAS) simplificou a recuperação de NFTs e tokens na Solana. A DAS API, uma adição recente ao conjunto de ferramentas dos desenvolvedores da Solana, oferece uma interface unificada para recuperar ativos digitais na Solana. Em vez de lidar com vários endpoints para interagir com diferentes tipos de ativos, agora os desenvolvedores podem usar uma única API para obter os dados necessários para suas aplicações.
Este guia interativo abordará:
- Uma compreensão dos tipos de ativos disponíveis na Solana.
- Uma visão abrangente dos métodos fornecidos pela DAS API.
- Demonstrações de casos de uso reais para cada endpoint, que podem ser facilmente personalizados.
Este guia permitirá que você acompanhe cada caso de uso e, ao final, estará preparado para usar a DAS com maestria.
Pré-requisitos
- Node.js instalado (v18.0 necessária para usar o fetch integrado)
- RPC da Helius
- Conhecimento básico de JavaScript
Configuração do ambiente
- Crie uma pasta de projeto chamada functions.
- Para cada exemplo, crie um novo arquivo nessa pasta.
Tipos de ativos
No ecossistema da Solana, um "ativo" pode ser qualquer item digital de valor existente na blockchain, como tokens ou tokens não fungíveis (NFTs). A Solana aceita uma ampla variedade desses ativos. É essencial compreender o tipo de dado que a DAS API retorna ao interagir com eles.
Vamos analisar cada tipo de ativo mais detalhadamente.
Não fungível
Ativos não fungíveis seguem o modelo padrão de NFT e armazenam metadados em uma conta de token. Esses dados ficam em um Program Derived Address (PDA), um endereço pertencente a um programa, não a um usuário específico. Eles contam com um Metadata PDA e um Master Edition PDA na blockchain da Solana.
Fungível
Ativos fungíveis são tokens SPL com metadados limitados. Eles podem representar tokens como USDC ou tokens de comunidades/projetos. Um token seguirá o padrão Fungible se seu valor decimal for maior que 0 durante a criação.
Ativo fungível
Ativos fungíveis representam itens, em vez de unidades individuais. Eles podem conter mais metadados do que um ativo Fungible padrão. Se o valor decimal for definido como 0 durante a criação de um item no padrão Fungible, ele se transforma no padrão Fungible Asset.
Não fungível programável
Ativos não fungíveis programáveis seguem o padrão Non-Fungible, mas permanecem em uma conta de token congelada. Esse estado impede que os usuários queimem, bloqueiem ou transfiram ativos programáveis sem interagir com o programa Token Metadata. Esse padrão surgiu como resposta ao debate sobre royalties na Solana.
Métodos disponíveis
A DAS API oferece vários métodos adaptados a diferentes casos de uso, incluindo:
getAsset: recupera um ativo por seu ID.searchAssets: localiza ativos usando vários parâmetros.getAssetProof: obtém uma prova de Merkle de um ativo compactado por seu ID.getAssetsByGroup: obtém uma lista de ativos por chave e valor de grupo.getAssetsByOwner: recupera uma lista de ativos pertencentes a um endereço.getAssetsByCreator: obtém uma lista de ativos criados por um endereço.getAssetsByAuthority: encontra uma lista de ativos com uma autoridade específica.
Para obter informações detalhadas sobre cada método, consulte nossa documentação.
1. Obter ativo
O endpoint getAsset permite recuperar um ativo específico por seu ID. Esse ID pode representar o endereço on-chain de um token ou o ID na árvore de Merkle para ativos compactados.
Para obter mais informações, consulte a documentação de getAsset.
Exemplo
Suponha que queremos buscar os metadados do ativo Claynosaurz de classificação 1. Nesse caso, precisamos localizar o ID do ativo, configurar nossa função para fazer a chamada à DAS e organizar a resposta para extrair dos resultados exatamente o objeto necessário.
Siga as etapas abaixo:
- Comece configurando a função em um novo arquivo chamado “getAsset.js”:
const url = `https://rpc.helius.xyz/?api-key=`;
const getAsset = async () => {
// Code goes here
};
getAsset();2. Em seguida, configure as operações de fetch e await. Inclua o parâmetro de ID obrigatório no corpo da solicitação:
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',
},
}),
});Nesta etapa, enviamos uma solicitação POST à DAS API com o ID exclusivo do ativo no corpo da solicitação.
3. Analise os resultados e exiba as informações dos metadados:
const { result } = await response.json();
console.log("asset: ", result);Esse trecho de código analisa a resposta da API no formato JSON e registra o resultado no console.
Depois, você pode executar o script usando o comando node getAsset.js.
Este método recupera os dados de um único ativo. Se você precisar pesquisar um grupo de ativos, a DAS API oferece outros métodos, que veremos mais adiante.
Resultado
A execução desse script exibirá os metadados do ativo especificado:
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
}Essa saída fornece informações detalhadas sobre o ativo, incluindo o tipo de interface, ID, metadados, criadores, autoridades e propriedade.
Código completo
Veja abaixo o código completo para buscar um ativo usando seu 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("asset: ", result);
};
getAsset();Substitua <api-key> por sua chave de API real.
Nesse código, definimos uma função assíncrona, getAsset, que envia uma solicitação POST à DAS API. Passamos o ID do ativo no corpo da solicitação. Após a conclusão da solicitação, a função analisa a resposta como JSON e exibe os dados do ativo no console. Por fim, invocamos a função getAsset para executar esse processo.
2. Obter prova do ativo
O endpoint getAssetProof é usado para recuperar uma prova de ativo necessária para fazer alterações no programa de compactação. Essas alterações incluem ações como transferir, queimar, atualizar o criador, atualizar a coleção e descompactar ativos compactados.
Para ver uma lista detalhada das alterações que usam a prova do ativo, consulte a documentação.
Exemplo
Para buscar a prova de ativo necessária para modificar um ativo compactado, siga estas etapas:
- Comece configurando a função em um novo arquivo chamado “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("asset: ", result);
};
getAsset();2. Prossiga configurando o fetch e o await. Inclua o parâmetro de ID obrigatório no corpo da solicitação:
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. Analise o resultado e extraia a raiz:
const { proof } = await response.json();
console.log("Asset Proof: ", result);
const root = decode(proof.root);
console.log(root)Aqui, extraímos a raiz da prova do ativo, que pode então ser usada para fazer outras alterações no ativo compactado.
Execute node getAssetProof.js no terminal para obter um retorno sobre o ativo definido aqui.
Resultado
A saída incluirá as informações da prova do ativo:
Assets Proof: {
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'
}Código completo
Este é o código completo para buscar uma prova de ativo usando seu 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("Asset Proof: ", result);
const root = proof.root;
console.log(root)
};
getAssetProof();Substitua <api-key> por sua chave de API real.
Nesse script, definimos uma função assíncrona, getAssetProof, que envia uma solicitação POST à API da Helius. Passamos o ID do ativo no corpo da solicitação. Após a conclusão da solicitação, a função analisa a resposta como JSON e exibe no console a prova do ativo e sua raiz. Por fim, chamamos a função getAssetProof para executar esse processo.
3. Pesquisar ativos
O método searchAssets recupera ativos digitais com base nos parâmetros de pesquisa especificados, oferecendo uma abordagem flexível para buscar dados. Ele permite personalizar a pesquisa, proporcionando um controle mais detalhado sobre os ativos retornados.
Os parâmetros detalhados estão disponíveis na documentação de searchAssets.
Exemplo
Vamos analisar um exemplo em que queremos exibir a imagem e o nome dos ativos de uma carteira de usuário que pertencem à coleção Drip Haus, mostrando apenas os itens compactados. Para manter este tutorial conciso, publicaremos os dados em um arquivo JSON com o nome e a imagem de cada ativo Drip na carteira de exemplo.
- Comece criando um novo arquivo chamado searchAssets.js com a seguinte função assíncrona:
const fs = require('fs');
const url = `https://rpc.helius.xyz/?api-key=`;
const searchAssets = async () => {
// Code goes here
};
searchAssets();2. Implemente a função para enviar uma solicitação POST com os parâmetros de pesquisa especificados. Nesse caso, usamos os parâmetros de compactação, endereço do proprietário e agrupamento por coleção para obter o resultado desejado:
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: "my-id",
method: "searchAssets",
params: {
// Returning only compressed items.
compressed: true,
// Example wallet
ownerAddress: "2k5AXX4guW9XwRQ1AKCpAuUqgWDpQpwFfpVFh3hnm2Ha",
// Drip Haus collection ID.
grouping: [
"collection",
"DRiP2Pn2K6fuMLKQmt5rZWyHiUZ6WK3GChEySUpHSS4x"
],
page: 1,
},
}),
});3. Analise a resposta, agrupe os ativos por ID e trate possíveis duplicatas, detalhando exatamente os itens necessários da resposta de cada item:
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. A próxima função encontra repetições e as remove da lista. Você pode optar por não usar essa função se quiser mostrar ativos repetidos. Ela também adicionará o ativo a um novo grupo quando determinar que não se trata de uma repetição:
const existingGroup = groupedResults.find(group => group.id === asset.id);
if (existingGroup) {
// Add the asset to the existing group
existingGroup.assets.push(asset);
} else {
// Create a new group for the asset
const newGroup = {
id: asset.id,
assets: [asset],
};
// Add the new group to the grouped results
groupedResults.push(newGroup);
}
}5. Salve os resultados da pesquisa em um arquivo JSON chamado searchResults.json:
const json = JSON.stringify(groupedResults, null, 2);
// Write the JSON to a file
fs.writeFileSync('searchResults.json', json);
console.log('Results saved to results.json');Para executar o script, rode node searchAssets.js. Isso preencherá o arquivo searchResults.json com os resultados da pesquisa.
Resultado
[
{
"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"
}
]
}, ...
}Código completo
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: {
// Returning only compressed items.
compressed: true,
// Example wallet
ownerAddress: "2k5AXX4guW9XwRQ1AKCpAuUqgWDpQpwFfpVFh3hnm2Ha",
// Drip Haus collection 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,
};
// Find an existing group for the asset if it exists
const existingGroup = groupedResults.find(group => group.id === asset.id);
if (existingGroup) {
// Add the asset to the existing group
existingGroup.assets.push(asset);
} else {
// Create a new group for the asset
const newGroup = {
id: asset.id,
assets: [asset],
};
// Add the new group to the grouped results
groupedResults.push(newGroup);
}
}
// Convert the grouped results to JSON
const json = JSON.stringify(groupedResults, null, 2);
// Write the JSON to a file
fs.writeFileSync('searchResults.json', json);
console.log('Results saved to results.json');
};
searchAssets();Substitua <api-key> por sua chave de API real.
Nesse script, definimos uma função assíncrona, searchAssets, que envia uma solicitação POST. Ela usa vários parâmetros de pesquisa no corpo da solicitação, como compactação, endereço do proprietário e ID da coleção. Após a conclusão da solicitação, a função analisa a resposta como JSON e extrai as informações relevantes dos ativos (ID, nome e URI do JSON). Ela agrupa esses ativos por ID e salva os dados organizados em um arquivo JSON chamado searchResults.json. Por fim, chamamos a função searchAssets para iniciar esse processo.
4. Obter ativos por proprietário
O endpoint getAssetsByOwner fornece uma lista dos ativos digitais pertencentes a um endereço específico. Atualmente, essa é a forma mais rápida de recuperar informações específicas sobre a propriedade de ativos digitais usando a Helius.
Exemplo
Para buscar os ativos pertencentes a determinado endereço, siga estas etapas:
- Comece configurando a função em um novo arquivo chamado “getAssetsByOwner.js”:
const fs = require('fs');
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByOwner = async () => {
// Code goes here
};
getAssetsByOwner();- Configure o fetch e o await e inclua os parâmetros no corpo da solicitação. Para este endpoint, usamos
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: {
// Example wallet
ownerAddress: '2k5AXX4guW9XwRQ1AKCpAuUqgWDpQpwFfpVFh3hnm2Ha',
page: 1
},
}),
});- Em seguida, analise a resposta e extraia as informações necessárias dos ativos para publicá-las no JSON. Usaremos o ID, o nome e a URI do JSON do ativo para agrupá-lo na carteira pesquisada:
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)) {
// Add the asset to the existing group
groupedResults[ownerAddress].assets.push(asset);
} else {
// Create a new group for the owner
groupedResults[ownerAddress] = {
assets: [asset],
};
}
}- Agora podemos configurar nossa função para publicar os dados em um JSON:
// Convert the grouped results to JSON
const json = JSON.stringify(groupedResults, null, 2);
// Write the JSON to a file
fs.writeFileSync('results.json', json);
console.log('Results saved to results.json');Resultado
A saída incluirá os ativos digitais pertencentes ao endereço especificado:
{
"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"
}, ...
}Código completo
Este é o código completo para buscar os ativos pertencentes a um endereço específico:
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: {
// Example wallet
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)) {
// Add the asset to the existing group
groupedResults[ownerAddress].assets.push(asset);
} else {
// Create a new group for the owner
groupedResults[ownerAddress] = {
assets: [asset],
};
}
}
// Convert the grouped results to JSON
const json = JSON.stringify(groupedResults, null, 2);
// Write the JSON to a file
fs.writeFileSync('results.json', json);
console.log('Results saved to results.json');
};
getAssetsByOwner();Substitua <api-key> por sua chave de API real.
Nesse script, definimos uma função assíncrona, getAssetsByOwner, que envia uma solicitação POST à API da Helius. Passamos o endereço do proprietário no corpo da solicitação. Após a conclusão da solicitação, a função analisa a resposta como JSON e exibe no console os ativos pertencentes ao endereço especificado. Por fim, chamamos a função getAssetsByOwner para executar esse processo.
5. Obter ativos por grupo
O endpoint getAssetsByGroup é usado para recuperar ativos digitais associados a um ID de coleção específico. Esse endpoint é essencial quando você precisa buscar itens específicos de uma coleção ou vincular uma dApp com acesso restrito por token a determinada coleção on-chain.
Exemplo
Neste cenário, configuraremos um snapshot de coleção para SMBs. É importante analisar a resposta para extrair o proprietário do ativo do objeto de propriedade, conforme detalhado em nossa documentação. O objetivo é filtrar os proprietários de vários SMBs e mostrá-los apenas uma vez no JSON, criando efetivamente um “snapshot”.
- Comece configurando a função em um novo arquivo chamado “getAssetsByGroup.js”. Use um Set para garantir que armazenaremos apenas proprietários únicos:
const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');
const uniqueOwners = new Set();
const getAssetsByGroup = async () => {
// Code goes here
};
getAssetsByGroup();- Prossiga configurando o fetch e o await. Defina no corpo da solicitação os parâmetros listados acima. Defina groupKey e groupValue na solicitação. Inicialize
pagecomo 1 ehasMoreResultscomo true para preparar a paginação. Depois, isso configurará uma função de paginação que retornará false se os resultados da página forem inferiores a 1.000 (o limite máximo por solicitação):
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,
},
}),
});- Analise os resultados para extrair a string do proprietário necessária para criar o snapshot dos proprietários atuais:
const { result } = await response.json();
// Add each owner to the Set, automatically discarding duplicates
result.items.forEach(item => uniqueOwners.add(item.ownership.owner));- Configure a paginação aumentando o parâmetro
pagese houver 1.000 resultados. Se houver menos, definahasMoreResultscomo false para interromper a paginação:
if (result.items.length < 1000) {
hasMoreResults = false;
} else {
page++;
}
}- Agora podemos transformar nossos proprietários em um array e configurar o valor raiz para publicar em um JSON o número de detentores e cada carteira de proprietário única:
const uniqueOwnersArray = Array.from(uniqueOwners);
const root = {
count: uniqueOwners.size,
owners: uniqueOwnersArray
};- Converta o
Setde proprietários únicos em um array. Configure o valorrootpara publicar em um JSON o número de detentores e cada carteira de proprietário única:
fs.writeFile('./ownerResults.json', jsonResult, 'utf8', (err) => {
if (err) {
console.error("Error writing JSON file:", err);
} else {
console.log("JSON file saved successfully.");
}
});
console.log("Total number of unique owners:", uniqueOwners.size);
};Depois, você pode executar o comando node getAssetsByGroup.js para preencher o arquivo "ownerResults.json" com seus resultados.
Resultado
O resultado será um JSON equivalente a um snapshot de detentores, com a contagem de proprietários únicos e uma lista de todos eles:
{
"count": 2785,
"owners": [
"6VqzFgtrJb33nhvbug4KZoUx8p65dD2iT1QuAeAQgYiw",
"5Xeb43ASEa64b9i9owcLB4yrNbUw1oMiTpcWsAdXN8qG",
"Cb355XH2WGPeQUGTTXWiQZT4nhnyHCPkhScDezUGhXQF",
"Fuu7xpK3mWqpqPLTHaxF7pU2czkBESKyg3r2Lm2F3AWz",
"1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix",
"86tCSKzryE5KvbTmMXN9tkxyn8GNr4z54DnNqrcZwYuy",
"D2DYL5sdxBCpauvKs1oyQkkSm2B9rFzzGowMacv3Q58z",
// Additional results ...
]
}Código completo
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();
// Add each owner to the Set, automatically discarding duplicates
result.items.forEach(item => uniqueOwners.add(item.ownership.owner));
if (result.items.length < 1000) {
hasMoreResults = false;
} else {
page++;
}
}
// Convert Set to Array for stringification
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("Error writing JSON file:", err);
} else {
console.log("JSON file saved successfully.");
}
});
};
console.log("Total number of unique owners:", uniqueOwners.size);
getAssetsByGroup();Substitua <api-key> por sua chave de API real.
Agora você aprendeu a recuperar ativos digitais associados a um ID de coleção específico usando o endpoint getAssetsByGroup. Ao usar de forma eficiente a paginação e a estrutura de dados Set para garantir entradas únicas de proprietários, você pode criar um snapshot dos detentores atuais de qualquer coleção com um ID on-chain.
6. Obter ativos por criador
O endpoint getAssetsByCreator é usado para recuperar ativos criados por um endereço de chave pública específico. Esse endpoint é útil quando você quer encontrar ativos relacionados a determinado artista ou projeto na Solana.
Exemplo
Neste exemplo, retornaremos os ativos criados por Zen0. Podemos usar o endereço do criador e definir o parâmetro onlyVerified como true para recuperar apenas os ativos criados por uma carteira verificada. Analisaremos os resultados para exibir o ID e o proprietário de cada ativo.
- Comece configurando a função em um novo arquivo chamado "getAssetsByCreator.js". Usaremos o módulo
fspara publicar os resultados em um arquivo JSON:
const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');
const getAssetsByCreator = async () => {
// Code goes here
};
getAssetsByCreator();- Agora podemos configurar a solicitação fetch e
awaita resposta. Defina os parâmetros necessários no corpo da solicitação, incluindocreatorAddresseonlyVerified:
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,
},
}),
});Não se esqueça de substituir <creator-address> pelo endereço real do criador cujos ativos você deseja recuperar.
- Analise a resposta para extrair o resultado e armazená-lo em um array:
const { result } = await response.json();
allResults = allResults.concat(result.items);
if (result.items.length < 1000) {
hasMoreResults = false;
} else {
page++;
}
}- Agrupe os ativos com base no ID de propriedade, já que uma única pessoa pode possuir vários ativos, e exiba os ativos pertencentes a cada ID. Se um novo proprietário for detectado, um novo grupo será criado no arquivo 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)) {
// Add the asset to the existing group
groupedResults[ownershipId].assets.push(asset);
} else {
// Create a new group for the ownership ID
groupedResults[ownershipId] = {
assets: [asset],
};
}
}- A próxima etapa é estruturar os resultados. Nesse caso, queremos o endereço do NFT e o proprietário de cada ativo retornado. Usamos root para especificar o tamanho do retorno e armazenar nossos resultados modificados para a saída:
// Create new array to hold the desired properties
const modifiedResults = totalResults.map(item => ({
id: item.id,
owner: item.ownership.owner
}));
// Create a root object to hold the count and the results
const root = {
count: modifiedResults.length,
results: modifiedResults
};- Por fim, salvamos os resultados em um arquivo chamado "creatorResults.json" usando o módulo
fs:
// Convert the grouped results to JSON
const json = JSON.stringify(groupedResults, null, 2);
// Write the JSON to a file
fs.writeFileSync('creatorResults.json', json);
console.log('Results saved to results.json');Por fim, execute o comando node getAssetsByCreator.js para rodar o script e preencher o arquivo "creatorResults.json" com os resultados recuperados.
Resultado
O arquivo JSON resultante contém o endereço de chave pública de cada proprietário e os respectivos ativos que ele possui. Cada ativo é representado por seu ID, proporcionando um snapshot claro do status de propriedade dos ativos criados pelo criador específico.
{
"ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22": {
"assets": [
{
"id": "KvbtDebCi6BGSFuafJWZpwV5mt1XYng13Pt2vh4G2Qa",
"ownershipId": "ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22"
},
{
"id": "28bXCZaETv6ihBGbtavDkedzRcWZPbmDG5VYXxSdmZBc",
"ownershipId": "ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22"
},
{
"id": "2H4txSfZwV3nX4fJ1D8dPNHiafn247iQ8vtq3y3UYdpe",
"ownershipId": "ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22"
},
{
"id": "5oauJRPWbboJVUBms2mqBF2wMQGMSCFScgX18SawyKV3",
"ownershipId": "ZVcBfkk3Be8QMn4rmQL2VtP2WJQp9wpU8udFwrTGA22"
},
"Fb7pzfL6SLDNi79WSWkZm6zKA94LYNsYKDJC7GNvkZaC": {
"assets": [
{
"id": "2jLjf8Vmbisu5eac1NgSiDcqkcJfR8R9LSGjD6SExC99",
"ownershipId": "Fb7pzfL6SLDNi79WSWkZm6zKA94LYNsYKDJC7GNvkZaC"
},
{
"id": "2rVtLCHWp1hpUc7YVoAkFrSL3iwGQDcCzAvboCvrq5kT",
"ownershipId": "Fb7pzfL6SLDNi79WSWkZm6zKA94LYNsYKDJC7GNvkZaC"
},
{
"id": "6QXfTMwuaKTMZyFYoUwNWpaT692Z9Zqg94WE9MTi4J2p",
"ownershipId": "Fb7pzfL6SLDNi79WSWkZm6zKA94LYNsYKDJC7GNvkZaC"
}
]
}, ...
}'ownershipId' representa o endereço da chave pública do proprietário na blockchain da Solana, e os ativos são os NFTs vinculados ao endereço.
Código completo
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++;
}
}
// Create an object to store the grouped results
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)) {
// Add the asset to the existing group
groupedResults[ownershipId].assets.push(asset);
} else {
// Create a new group for the ownership ID
groupedResults[ownershipId] = {
assets: [asset],
};
}
}
// Convert the grouped results to JSON
const json = JSON.stringify(groupedResults, null, 2);
// Write the JSON to a file
fs.writeFileSync('creatorResults.json', json);
console.log('Results saved to results.json');
};
getAssetsByCreator();Substitua <api-key> por sua chave de API real.
Neste exemplo, fazemos uma solicitação assíncrona à DAS API para o endpoint “getAssetsByCreator”. Em seguida, passamos o endereço do criador e indicamos que ele é um criador verificado. Por fim, configuramos a resposta para extrair o proprietário de cada ativo associado ao endereço do criador e publicamos os dados em um arquivo JSON externo.
De modo geral, essa é uma ferramenta valiosa para quem deseja monitorar ou analisar a movimentação de ativos na blockchain da Solana, especialmente aqueles vinculados a um criador ou projeto específico.
7. Obter ativos por autoridade
A função getAssetsByAuthority busca ativos associados a uma autoridade de atualização específica. Uma autoridade de atualização é um endereço que possui os direitos para modificar uma coleção. Esse recurso é especialmente útil quando você precisa buscar um conjunto de ativos em casos nos quais não existe um ID de coleção. Além disso, ele permite recuperar um conjunto maior de ativos associados ao endereço de uma autoridade, indo além dos limites de um único ID de coleção.
Exemplo
No exemplo a seguir, recuperaremos cada NFT das coleções Taiyo Robotics, Pilots e Infants, além de seus respectivos proprietários. Como todos compartilham uma autoridade de atualização, é possível retornar todos os resultados relevantes para o projeto.
Isso representa uma evolução em relação à função getAssetsByGroup, pois você pode agrupar ativos vinculados a uma autoridade definida CDgbhX61QFADQAeeYKP5BQ7nnzDyMkkR3NEhYF2ETn1k.
- Comece configurando a função em um novo arquivo chamado "getAssetsByAuthority.js":
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByAuthority = async () => {
// Code goes here
};
getAssetsByAuthority();- Configure a solicitação fetch e inclua os parâmetros necessários no corpo, como
authorityAddress,pageelimit:
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,
},
}),
});Substitua <authority-address> pelo endereço real da autoridade cujos ativos você deseja extrair.
3. Agora é possível organizar o retorno para percorrer os resultados caso haja 1.000 resultados.
Se houver menos resultados, o indicador será definido como false, encerrando a paginação, e hasMoreResults retornará false.
const { result } = await response.json();
totalResults.push(...result.items);
if (result.items.length < 1000) {
hasMoreResults = false;
} else {
page++;
}
}- Processe os ativos para obter as informações necessárias. Aqui, queremos exibir o ID do ativo e seu proprietário. Também criaremos um objeto raiz para conter a contagem de ativos e o array de ativos processados:
// Create new array to hold the desired properties
const modifiedResults = totalResults.map(item => ({
id: item.id,
owner: item.ownership.owner
}));
// Create a root object to hold the count and the results
const root = {
count: modifiedResults.length,
results: modifiedResults
};- Agora podemos definir os itens retornados para publicação em um JSON chamado authorityResults.json e registrar uma mensagem quando o processo for concluído.
const jsonResult = JSON.stringify(root, null, 2);
fs.writeFile('./authorityResults.json', jsonResult, 'utf8', (err) => {
if (err) {
console.error("Error writing JSON file:", err);
} else {
console.log("JSON file saved successfully.");
}
});
console.log("Process completed.");
console.timeEnd("getAssetsByAuthority");Por fim, execute o comando node getAssetsByAuthority.js para rodar o script e preencher o arquivo "authorityResults.json" com os resultados buscados.
Resultado
A saída do endpoint getAssetsByAuthority inclui uma contagem de ativos e um array de objetos, cada um representando um ativo e contendo seu ID e proprietário. Veja um exemplo:
{
"count": 37330,
"results": [
{
"id": "HmwL6uy7gQcXv74Mi8xF5G9mymZNd9rnUCpUFwSx1DX1",
"owner": "5gt59Q14FEhT8LuETjLyiNHRkqCQf5hQsPP58ucBy5oC"
},
{
"id": "HmztH56n4GD3p3EdgMKdzj8x21LjFQk4Bcp2YAQD8Urx",
"owner": "H3AkHZHfcqGCcJpBn3FJWe52LcLxFMJQoZvZ6XyApFWf"
},
{
"id": "Hn1NZXCaAxcr1btsaDm3eZRtLNbamy9FyrcVGLbZ2k5w",
"owner": "AEqhqiQZBBa3dPTY1GwGsZJJnf5vzRKJpdXv6xzakfx8"
}, ...
}Código completo
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++;
}
}
// Create new array to hold the desired properties
const modifiedResults = totalResults.map(item => ({
id: item.id,
owner: item.ownership.owner
}));
// Create a root object to hold the count and the results
const root = {
count: modifiedResults.length,
results: modifiedResults
};
// Stringify with 2 spaces indentation for readability
const jsonResult = JSON.stringify(root, null, 2);
fs.writeFile('./authorityResults.json', jsonResult, 'utf8', (err) => {
if (err) {
console.error("Error writing JSON file:", err);
} else {
console.log("JSON file saved successfully.");
}
});
console.log("Process completed.");
console.timeEnd("getAssetsByAuthority");
};
getAssetsByAuthority()Substitua <api-key> por sua chave de API real.
Neste exemplo, usamos o método "getAssetsByAuthority" para retornar todos os ativos vinculados ao endereço de uma autoridade em três coleções. Usamos apenas page e limit como parâmetros adicionais da solicitação. Em seguida, analisamos os resultados para extrair os ativos sob a autoridade e os armazenamos em um arquivo JSON externo.
Conclusão
Agora você deve ter uma compreensão abrangente de como usar a API Digital Asset Standard (DAS), além de conhecer várias aplicações práticas para cada método. Isso representa uma mudança significativa em relação à prática anterior de usar vários endpoints para buscar informações específicas sobre ativos.
Esses métodos atendem tanto a ativos compactados quanto a ativos comuns, oferecendo uma interface unificada para fazer essas solicitações de várias maneiras.
Para obter mais informações, você pode consultar nossa ampla documentação sobre a API Digital Asset Standard (DAS) e explorar nosso widget Open API, que fornece uma análise detalhada dos parâmetros de solicitação e resposta.
Como sempre, convidamos você a participar da nossa comunidade no Discord. Se tiver alguma dúvida, não hesite em me chamar por lá!
Artigos relacionados
Assine a Helius
Acompanhe as novidades mais recentes do desenvolvimento Solana e receba atualizações quando publicarmos


