
Tout savoir sur la nouvelle API DAS de Solana
Présentation
La récupération de NFT et de tokens sur Solana est désormais simplifiée grâce à l’introduction de l’API Digital Asset Standard (DAS). Récemment ajoutée à la boîte à outils des développeurs Solana, l’API DAS offre une interface unifiée pour récupérer des actifs numériques sur Solana. Au lieu d’utiliser plusieurs endpoints pour interagir avec différents types d’actifs, les développeurs peuvent désormais s’appuyer sur une seule API pour obtenir les données nécessaires à leurs applications.
Ce guide interactif couvrira les points suivants :
- Comprendre les types d’actifs disponibles sur Solana.
- Examiner en détail les méthodes fournies par l’API DAS.
- Découvrir des cas d’usage réels et facilement personnalisables pour chaque endpoint.
Ce guide vous permettra de suivre chaque cas d’usage pas à pas. À la fin, vous saurez utiliser DAS avec maîtrise.
Prérequis
- Node.js installé (v18.0 requise pour utiliser la fonction fetch intégrée)
- RPC Helius
- Connaissances de base en JavaScript
Configuration de l’environnement
- Créez un dossier de projet nommé functions.
- Pour chaque exemple, créez un nouveau fichier dans ce dossier.
Types d’actifs
Dans l’écosystème Solana, un « actif » peut être tout élément numérique ayant une valeur, comme un token ou un token non fongible (NFT), présent sur la blockchain. Solana prend en charge un large éventail de ces actifs. Il est essentiel de comprendre le type de données renvoyé par l’API DAS lors des interactions avec ces actifs.
Examinons chaque type d’actif plus en détail.
Non fongible
Les actifs non fongibles suivent le modèle NFT standard et stockent leurs métadonnées dans un compte de token. Ces données résident dans une adresse dérivée d’un programme (Program Derived Address, ou PDA), c’est-à-dire une adresse détenue par un programme et non par un utilisateur spécifique. Sur la blockchain Solana, ils disposent d’une Metadata PDA et d’une Master Edition PDA.
Fongible
Les actifs fongibles sont des tokens SPL dotés de métadonnées limitées. Ils peuvent représenter des tokens comme USDC ou les tokens d’une communauté ou d’un projet. Un token respecte le standard Fungible si sa valeur décimale est supérieure à 0 lors de sa création.
Actif fongible
Les actifs fongibles représentent des éléments plutôt que des unités individuelles. Ils peuvent contenir davantage de métadonnées qu’un actif Fungible standard. Si le nombre de décimales est défini sur 0 lors de la création d’un élément au standard Fungible, celui-ci devient conforme au standard Fungible Asset.
Non fongible programmable
Les actifs non fongibles programmables reprennent le standard Non-Fungible, mais restent dans un compte de token gelé. Cet état empêche les utilisateurs de détruire, verrouiller ou transférer des actifs programmables sans interagir avec le programme Token Metadata. Ce standard a été créé en réponse au débat sur les royalties au sein de Solana.
Méthodes disponibles
L’API DAS propose plusieurs méthodes adaptées à différents cas d’usage, notamment :
getAsset: récupérer un actif à partir de son ID.searchAssets: rechercher des actifs à l’aide de différents paramètres.getAssetProof: obtenir une preuve de Merkle pour un actif compressé à partir de son ID.getAssetsByGroup: obtenir une liste d’actifs à partir d’une clé et d’une valeur de groupe.getAssetsByOwner: récupérer la liste des actifs détenus par une adresse.getAssetsByCreator: obtenir la liste des actifs créés par une adresse.getAssetsByAuthority: rechercher une liste d’actifs associés à une autorité spécifique.
Pour en savoir plus sur chaque méthode, consultez notre documentation.
1. Obtenir un actif
L’endpoint getAsset vous permet de récupérer un actif spécifique à partir de son ID. Cet ID peut représenter l’adresse on-chain d’un token ou l’ID figurant dans l’arbre de Merkle pour les actifs compressés.
Pour plus d’informations, consultez la documentation de getAsset.
Exemple
Supposons que nous souhaitions récupérer les métadonnées de l’actif Claynosaurz classé numéro 1. Dans ce cas, nous devons trouver l’ID de l’actif, configurer notre fonction pour appeler DAS et organiser notre réponse afin d’extraire des résultats l’objet exact dont nous avons besoin.
Suivez les étapes ci-dessous :
- Commencez par configurer la fonction dans un nouveau fichier nommé « getAsset.js » :
const url = `https://rpc.helius.xyz/?api-key=`;
const getAsset = async () => {
// Code goes here
};
getAsset();2. Configurez ensuite vos opérations fetch et await. Incluez le paramètre ID requis dans le corps de votre requête :
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',
},
}),
});À cette étape, nous envoyons une requête POST à l’API DAS avec l’ID unique de l’actif dans le corps de la requête.
3. Analysez les résultats et affichez les métadonnées :
const { result } = await response.json();
console.log("asset: ", result);Cet extrait de code analyse la réponse de l’API au format JSON et affiche le résultat dans la console.
Vous pouvez ensuite exécuter le script avec la commande node getAsset.js.
Cette méthode récupère les données d’un seul actif. Si vous devez rechercher un groupe d’actifs, l’API DAS propose d’autres méthodes que nous aborderons plus loin.
Résultat
L’exécution de ce script affichera les métadonnées de l’actif indiqué :
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
}Cette sortie fournit des informations détaillées sur l’actif, notamment son type d’interface, son ID, ses métadonnées, ses créateurs, ses autorités et son propriétaire.
Code complet
Voici le code complet permettant de récupérer un actif à partir de son 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();Veillez à remplacer <api-key> par votre véritable clé API.
Dans ce code, nous définissons une fonction asynchrone, getAsset, qui envoie une requête POST à l’API DAS. Nous transmettons l’ID de l’actif dans le corps de la requête. Une fois la requête terminée, la fonction analyse la réponse au format JSON et affiche les données de l’actif dans la console. Enfin, nous appelons la fonction getAsset pour exécuter ce processus.
2. Obtenir une preuve d’actif
L’endpoint getAssetProof permet de récupérer la preuve d’un actif nécessaire pour modifier le programme de compression. Ces modifications incluent notamment le transfert, la destruction, la mise à jour du créateur, la mise à jour de la collection et la décompression des actifs compressés.
Pour obtenir la liste détaillée des modifications utilisant la preuve d’actif, consultez la documentation.
Exemple
Pour récupérer la preuve d’actif nécessaire à la modification d’un actif compressé, procédez comme suit :
- Commencez par configurer la fonction dans un nouveau fichier nommé « 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. Configurez ensuite vos opérations fetch et await. Incluez le paramètre ID requis dans le corps de votre requête :
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. Analysez le résultat et extrayez la racine :
const { proof } = await response.json();
console.log("Asset Proof: ", result);
const root = decode(proof.root);
console.log(root)Ici, nous extrayons la racine de la preuve d’actif. Elle peut ensuite servir à apporter d’autres modifications à l’actif compressé.
Exécutez node getAssetProof.js dans votre terminal pour obtenir les données de l’actif défini ici.
Résultat
La sortie contiendra les informations de la preuve d’actif :
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'
}Code complet
Voici le code complet permettant de récupérer la preuve d’un actif à partir de son 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();Veillez à remplacer <api-key> par votre véritable clé API.
Dans ce script, nous définissons une fonction asynchrone, getAssetProof, qui envoie une requête POST à l’API Helius. Nous transmettons l’ID de l’actif dans le corps de la requête. Une fois la requête terminée, la fonction analyse la réponse au format JSON et affiche la preuve de l’actif et sa racine dans la console. Enfin, nous appelons la fonction getAssetProof pour exécuter ce processus.
3. Rechercher des actifs
La méthode searchAssets récupère des actifs numériques selon les paramètres de recherche indiqués, offrant ainsi une approche flexible de la récupération des données. Elle permet aux utilisateurs de personnaliser la recherche et donc de contrôler plus précisément les actifs renvoyés.
Les paramètres détaillés sont disponibles dans la documentation de searchAssets.
Exemple
Prenons un exemple dans lequel nous voulons afficher l’image et le nom d’actifs issus du portefeuille d’un utilisateur, appartenant à la collection Drip Haus, en ne présentant que les éléments compressés qu’elle contient. Pour préserver la concision de ce tutoriel, nous enregistrerons dans un fichier JSON le nom et l’image de chaque actif Drip figurant dans le portefeuille d’exemple.
- Commencez par créer un fichier nommé searchAssets.js contenant la fonction asynchrone suivante :
const fs = require('fs');
const url = `https://rpc.helius.xyz/?api-key=`;
const searchAssets = async () => {
// Code goes here
};
searchAssets();2. Implémentez la fonction afin d’envoyer une requête POST avec les paramètres de recherche indiqués. Ici, nous utilisons les paramètres de compression, d’adresse du propriétaire et de regroupement par collection pour obtenir le résultat souhaité :
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. Analysez la réponse, regroupez les actifs par ID et gérez les éventuels doublons en précisant les éléments exacts dont nous avons besoin dans la réponse de chaque actif :
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. La fonction suivante détecte les doublons et les supprime de notre liste. Vous pouvez choisir de ne pas l’utiliser si vous souhaitez afficher plusieurs fois les mêmes actifs. Elle ajoutera également l’actif à un nouveau groupe lorsqu’elle déterminera qu’il ne s’agit pas d’un doublon :
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. Enregistrez les résultats de la recherche dans un fichier JSON nommé 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');Pour exécuter le script, lancez node searchAssets.js. Le fichier searchResults.json sera alors rempli avec les résultats de la recherche.
Résultat
[
{
"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"
}
]
}, ...
}Code complet
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();Veillez à remplacer <api-key> par votre véritable clé API.
Dans ce script, nous définissons une fonction asynchrone, searchAssets, qui envoie une requête POST. Le corps de la requête utilise différents paramètres de recherche, comme la compression, l’adresse du propriétaire et l’ID de la collection. Une fois la requête terminée, la fonction analyse la réponse au format JSON et extrait les informations pertinentes sur les actifs (ID, nom et URI JSON). Elle regroupe ces actifs par ID et enregistre ces données structurées dans un fichier JSON nommé searchResults.json. Enfin, nous appelons la fonction searchAssets pour lancer ce processus.
4. Obtenir les actifs par propriétaire
L’endpoint getAssetsByOwner fournit la liste des actifs numériques détenus par une adresse donnée. Il s’agit actuellement du moyen le plus rapide de récupérer avec Helius des informations précises sur la propriété d’actifs numériques.
Exemple
Pour récupérer les actifs détenus par une adresse donnée, procédez comme suit :
- Commencez par configurer la fonction dans un nouveau fichier nommé « getAssetsByOwner.js » :
const fs = require('fs');
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByOwner = async () => {
// Code goes here
};
getAssetsByOwner();- Configurez vos opérations fetch et await, puis incluez vos paramètres dans le corps de la requête. Pour cet endpoint, nous utilisons
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
},
}),
});- Analysez ensuite la réponse et extrayez les informations nécessaires sur les actifs pour les enregistrer dans le fichier JSON. Nous utiliserons l’ID, le nom et l’URI JSON de l’actif afin de les regrouper avec le portefeuille recherché :
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],
};
}
}- Nous pouvons maintenant configurer notre fonction pour enregistrer les données dans un fichier 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');Résultat
La sortie contiendra les actifs numériques détenus par l’adresse indiquée :
{
"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"
}, ...
}Code complet
Voici le code complet permettant de récupérer les actifs détenus par une adresse donnée :
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();Veillez à remplacer <api-key> par votre véritable clé API.
Dans ce script, nous définissons une fonction asynchrone, getAssetsByOwner, qui envoie une requête POST à l’API Helius. Nous transmettons l’adresse du propriétaire dans le corps de la requête. Une fois la requête terminée, la fonction analyse la réponse au format JSON et affiche dans la console les actifs détenus par l’adresse indiquée. Enfin, nous appelons la fonction getAssetsByOwner pour exécuter ce processus.
5. Obtenir les actifs par groupe
L’endpoint getAssetsByGroup permet de récupérer les actifs numériques associés à un ID de collection donné. Cet endpoint est essentiel lorsque vous devez récupérer les éléments propres à une collection ou associer une dApp à accès contrôlé par token à une collection on-chain donnée.
Exemple
Dans ce scénario, nous allons créer un snapshot de collection pour les SMB. Il est important d’analyser la réponse afin d’extraire le propriétaire de l’actif depuis l’objet de propriété, comme l’explique notre documentation. L’objectif est de filtrer les propriétaires de plusieurs SMB et de ne les afficher qu’une seule fois dans notre fichier JSON afin de créer un « snapshot ».
- Commencez par configurer la fonction dans un nouveau fichier nommé « getAssetsByGroup.js ». Utilisez un Set pour ne stocker que des propriétaires uniques :
const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');
const uniqueOwners = new Set();
const getAssetsByGroup = async () => {
// Code goes here
};
getAssetsByGroup();- Configurez ensuite vos opérations fetch et await. Ajoutez les paramètres indiqués ci-dessus au corps de votre requête. Définissez groupKey et groupValue dans la requête. Initialisez
pageà 1 ethasMoreResultsà true afin de préparer la pagination. Une fonction de pagination sera ensuite configurée pour renvoyer false si la page contient moins de 1 000 résultats, soit la limite maximale par requête :
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,
},
}),
});- Analysez les résultats afin d’extraire la chaîne du propriétaire nécessaire à la création du snapshot des propriétaires actuels :
const { result } = await response.json();
// Add each owner to the Set, automatically discarding duplicates
result.items.forEach(item => uniqueOwners.add(item.ownership.owner));- Configurez la pagination en augmentant le paramètre
pages’il y a 1 000 résultats. S’il y en a moins, définissezhasMoreResultssur false pour arrêter la pagination :
if (result.items.length < 1000) {
hasMoreResults = false;
} else {
page++;
}
}- Nous pouvons maintenant transformer nos propriétaires en tableau et configurer notre valeur racine afin d’enregistrer dans un fichier JSON le nombre de détenteurs ainsi que chaque portefeuille de propriétaire unique :
const uniqueOwnersArray = Array.from(uniqueOwners);
const root = {
count: uniqueOwners.size,
owners: uniqueOwnersArray
};- Convertissez le
Setdes propriétaires uniques en tableau. Configurez la valeurrootafin d’enregistrer dans un fichier JSON le nombre de détenteurs et le portefeuille de chaque propriétaire unique :
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);
};Vous pouvez ensuite exécuter la commande node getAssetsByGroup.js pour remplir le fichier « ownerResults.json » avec vos résultats.
Résultat
Votre résultat sera l’équivalent JSON d’un snapshot des détenteurs, avec le nombre de propriétaires uniques et la liste de tous ces propriétaires :
{
"count": 2785,
"owners": [
"6VqzFgtrJb33nhvbug4KZoUx8p65dD2iT1QuAeAQgYiw",
"5Xeb43ASEa64b9i9owcLB4yrNbUw1oMiTpcWsAdXN8qG",
"Cb355XH2WGPeQUGTTXWiQZT4nhnyHCPkhScDezUGhXQF",
"Fuu7xpK3mWqpqPLTHaxF7pU2czkBESKyg3r2Lm2F3AWz",
"1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix",
"86tCSKzryE5KvbTmMXN9tkxyn8GNr4z54DnNqrcZwYuy",
"D2DYL5sdxBCpauvKs1oyQkkSm2B9rFzzGowMacv3Q58z",
// Additional results ...
]
}Code complet
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();Veillez à remplacer <api-key> par votre véritable clé API.
Vous savez désormais comment récupérer les actifs numériques associés à un ID de collection donné avec l’endpoint getAssetsByGroup. En utilisant efficacement la pagination et la structure de données Set pour garantir l’unicité des propriétaires, vous pouvez créer un snapshot des détenteurs actuels de toute collection possédant un ID on-chain.
6. Obtenir les actifs par créateur
L’endpoint getAssetsByCreator permet de récupérer les actifs créés par une adresse de clé publique donnée. Cet endpoint est utile lorsque vous souhaitez rechercher des actifs associés à un artiste ou à un projet spécifique sur Solana.
Exemple
Dans cet exemple, nous allons renvoyer les actifs créés par Zen0. Nous pouvons utiliser l’adresse du créateur et définir le paramètre onlyVerified sur true afin de ne récupérer que les actifs créés par un portefeuille vérifié. Nous analyserons les résultats pour afficher l’ID de chaque actif et son propriétaire.
- Commencez par configurer la fonction dans un nouveau fichier nommé « getAssetsByCreator.js ». Nous utiliserons le module
fspour enregistrer nos résultats dans un fichier JSON :
const url = `https://rpc.helius.xyz/?api-key=`;
const fs = require('fs');
const getAssetsByCreator = async () => {
// Code goes here
};
getAssetsByCreator();- Nous pouvons maintenant configurer la requête fetch et
awaitla réponse. Définissez les paramètres nécessaires dans le corps de la requête, notammentcreatorAddressetonlyVerified:
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’oubliez pas de remplacer <creator-address> par l’adresse réelle du créateur dont vous souhaitez récupérer les actifs.
- Analysez la réponse pour en extraire le résultat et le stocker dans un tableau :
const { result } = await response.json();
allResults = allResults.concat(result.items);
if (result.items.length < 1000) {
hasMoreResults = false;
} else {
page++;
}
}- Regroupez les actifs selon l’ID de propriété, puisqu’une même personne peut détenir plusieurs actifs, puis affichez les actifs détenus par chaque ID. Si un nouveau propriétaire est détecté, un nouveau groupe sera créé dans le fichier 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],
};
}
}- L’étape suivante consiste à structurer les résultats. Ici, nous nous intéressons à l’adresse du NFT et au propriétaire de chaque actif renvoyé. Nous utilisons root pour indiquer la longueur du résultat et stocker nos résultats modifiés en vue de leur exportation :
// 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
};- Enfin, nous enregistrons les résultats dans un fichier nommé « creatorResults.json » à l’aide du module
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');Enfin, exécutez la commande node getAssetsByCreator.js pour lancer le script et remplir le fichier « creatorResults.json » avec les résultats récupérés.
Résultat
Le fichier JSON obtenu contient l’adresse de clé publique de chaque propriétaire et les actifs qu’il détient. Chaque actif est représenté par son ID, ce qui fournit un snapshot clair de l’état de propriété des actifs créés par le créateur indiqué.
{
"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"
}
]
}, ...
}La valeur 'ownershipId' représente l’adresse de clé publique du propriétaire sur la blockchain Solana, et les actifs correspondent aux NFT associés à cette adresse.
Code complet
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();Veillez à remplacer <api-key> par votre véritable clé API.
Dans cet exemple, nous envoyons une requête asynchrone à l’API DAS pour l’endpoint « getAssetsByCreator ». Nous transmettons ensuite l’adresse de notre créateur en indiquant qu’il s’agit d’un créateur vérifié. Enfin, nous configurons notre réponse afin d’analyser le propriétaire de chaque actif associé à l’adresse du créateur, puis nous enregistrons les données dans un fichier JSON externe.
Dans l’ensemble, il s’agit d’un outil précieux pour toute personne souhaitant suivre ou analyser les mouvements d’actifs sur la blockchain Solana, en particulier ceux associés à un créateur ou à un projet spécifique.
7. Obtenir les actifs par autorité
La fonction getAssetsByAuthority récupère les actifs associés à une autorité de mise à jour donnée. Une autorité de mise à jour est une adresse disposant des droits nécessaires pour modifier une collection. Cette fonctionnalité est particulièrement utile lorsque vous devez récupérer un ensemble d’actifs sans disposer d’un ID de collection. Elle permet également de récupérer un ensemble plus vaste d’actifs associés à l’adresse d’une autorité, au-delà des limites d’un seul ID de collection.
Exemple
Dans l’exemple suivant, nous récupérerons chaque NFT de collection et son propriétaire respectif pour Taiyo Robotics, Pilots et Infants. Comme ils partagent tous la même autorité de mise à jour, il est possible de renvoyer tous les résultats pertinents pour le projet.
Cette fonction améliore getAssetsByGroup, car vous pouvez regrouper les actifs associés à une autorité définie CDgbhX61QFADQAeeYKP5BQ7nnzDyMkkR3NEhYF2ETn1k.
- Commencez par configurer la fonction dans un nouveau fichier nommé « getAssetsByAuthority.js » :
const url = `https://rpc.helius.xyz/?api-key=`;
const getAssetsByAuthority = async () => {
// Code goes here
};
getAssetsByAuthority();- Configurez la requête fetch et ajoutez les paramètres nécessaires au corps, tels que
authorityAddress,pageetlimit:
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,
},
}),
});Veillez à remplacer <authority-address> par l’adresse réelle de l’autorité dont vous souhaitez extraire les actifs.
3. Nous pouvons maintenant organiser la réponse afin de parcourir les pages de résultats lorsqu’il y en a 1 000.
S’il y a moins de résultats, l’indicateur sera défini sur false et la pagination prendra fin, hasMoreResults renvoyant alors false.
const { result } = await response.json();
totalResults.push(...result.items);
if (result.items.length < 1000) {
hasMoreResults = false;
} else {
page++;
}
}- Traitez les actifs afin d’obtenir les informations requises. Ici, nous voulons afficher l’ID de l’actif et son propriétaire. Nous allons également créer un objet racine contenant le nombre d’actifs et le tableau des actifs traités :
// 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
};- Nous sommes maintenant prêts à enregistrer les éléments renvoyés dans un fichier JSON nommé authorityResults.json. Nous consignerons également la fin du processus dans le journal.
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");Enfin, exécutez la commande node getAssetsByAuthority.js pour lancer le script et remplir le fichier « authorityResults.json » avec les résultats récupérés.
Résultat
La sortie de l’endpoint getAssetsByAuthority comprend un nombre d’actifs et un tableau d’objets, chacun représentant un actif et contenant son ID et son propriétaire. Voici un exemple :
{
"count": 37330,
"results": [
{
"id": "HmwL6uy7gQcXv74Mi8xF5G9mymZNd9rnUCpUFwSx1DX1",
"owner": "5gt59Q14FEhT8LuETjLyiNHRkqCQf5hQsPP58ucBy5oC"
},
{
"id": "HmztH56n4GD3p3EdgMKdzj8x21LjFQk4Bcp2YAQD8Urx",
"owner": "H3AkHZHfcqGCcJpBn3FJWe52LcLxFMJQoZvZ6XyApFWf"
},
{
"id": "Hn1NZXCaAxcr1btsaDm3eZRtLNbamy9FyrcVGLbZ2k5w",
"owner": "AEqhqiQZBBa3dPTY1GwGsZJJnf5vzRKJpdXv6xzakfx8"
}, ...
}Code complet
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()Veillez à remplacer <api-key> par votre véritable clé API.
Dans cet exemple, nous utilisons la méthode « getAssetsByAuthority » pour renvoyer tous les actifs associés à l’adresse d’une autorité dans trois collections. Nous utilisons uniquement page et limit comme paramètres supplémentaires de la requête. Nous analysons ensuite les résultats afin d’extraire les actifs associés à l’autorité et de les stocker dans un fichier JSON externe.
Conclusion
Vous devriez maintenant bien comprendre comment utiliser l’API Digital Asset Standard (DAS), ainsi que plusieurs applications pratiques de chacune de ses méthodes. Cette approche marque une rupture importante avec les pratiques antérieures, qui nécessitaient plusieurs endpoints pour récupérer des informations précises sur un actif.
Ces méthodes prennent en charge les actifs compressés comme les actifs classiques et offrent une interface unifiée pour effectuer ces requêtes de différentes manières.
Pour en savoir plus, vous pouvez consulter à tout moment notre documentation complète sur l’API Digital Asset Standard (DAS) et explorer notre widget Open API, qui présente en détail les paramètres des requêtes et des réponses.
Comme toujours, nous vous invitons à rejoindre notre communauté Discord. N’hésitez pas à m’y contacter si vous avez des questions !
Articles associés
Abonnez-vous à Helius
Suivez les dernières actualités du développement sur Solana et recevez une notification à chaque publication


