Skip to main content
Lorsque vous développez des applications qui doivent réagir à des changements sur la chaîne, interroger les points de terminaison RPC pour les mises à jour de compte est à la fois inefficace et lent. Les abonnements de compte résolvent ce problème en fournissant des mises à jour en temps réel sur les changements d’état de compte directement à votre application. Ce guide couvre tout ce que vous devez savoir sur les abonnements de compte : ce qu’ils sont, comment ils fonctionnent et comment les optimiser pour votre cas d’utilisation spécifique.

Le contexte du modèle de compte

Passez cette section si vous êtes familier avec les comptes Solana et leur structure.
Solana utilise un modèle basé sur les comptes où chaque donnée vit dans un compte - un conteneur qui contient à la fois des données et des métadonnées. Chaque compte a :
  • Données : Les octets réels stockant l’état du programme, les soldes des jetons ou d’autres informations
  • Propriétaire : Le programme qui contrôle ce compte et peut modifier ses données
  • Lamports : Le solde SOL du compte pour l’exonération de loyer
  • Exécutable : Si ce compte contient du code de programme
Les programmes sont sans état - ils ne stockent pas de données en interne. Au lieu de cela, ils créent et gèrent des comptes séparés pour stocker leur état. Lorsque vous interagissez avec un programme, vous transmettez les comptes qu’il doit lire ou écrire. Cette conception rend les abonnements de compte puissants : vous pouvez surveiller les changements de comptes spécifiques, tous les comptes appartenant à un programme ou des comptes correspondant à certains critères.

Abonnement de compte de base

Commençons par un exemple simple qui s’abonne aux changements dans les comptes de jetons. Ce script vous notifiera chaque fois que les soldes des jetons changent :
Lorsque vous exécutez cet abonnement de base, vous verrez des mises à jour de compte en temps réel diffusées sur votre console :
Que s’est-il passé ? Notre abonnement a parfaitement fonctionné ! Nous avons demandé à Laserstream de nous notifier des changements de compte de jetons, et il a fourni une mise à jour sur le compte BKMHWYLAX4un3HUbR7a3u9jPmzCiLNa4mSj1RiX11eWF. Ce compte a :
  • 2,039,280 lamports (~0.002 SOL de solde - c’est la somme exonérée de loyer pour ce compte de jeton)
  • Programme propriétaire TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA (c’est le programme SPL Token)
  • Signature de transaction 5C9Hr5nG2j8eQz6inxPmfyjbYdmXddzUDyR1iQgEnjYQ3RNvuP4Zzc8t1enLNy7Rk8KNCtQPEQztENYWxkt9GaVD montrant quelle transaction spécifique a provoqué le changement de ce compte
  • Slot 352366983 indiquant quand cette mise à jour s’est produite sur la blockchain
  • Champ de données contenant 165 octets de données de compte encodées en base58

Comprendre le filtrage des comptes avec datasize

Le champ de données est crucial - il contient la structure réelle du compte de jetons. Utilisons cette compréhension pour le filtrage intelligent des comptes.

Pourquoi utiliser le filtrage par datasize ?

Pour comprendre pourquoi nous avons besoin de filtrage, comprenons d’abord ce que sont réellement les comptes de jetons. Pour chaque jeton qu’un portefeuille détient, il y a un compte séparé sur la chaîne. Si votre portefeuille détient 3 jetons différents (USDC, BONK, et SOL), vous avez en fait 1 compte de portefeuille (votre compte principal SOL) plus 3 comptes de jetons (un pour chaque type de jeton). Chaque compte de jeton fait exactement 165 octets et stocke : quel jeton il détient (adresse de frappe), qui le possède (adresse de votre portefeuille), et combien de ce jeton il contient (montant). Le programme Token possède des millions de comptes sur Solana, mais tous ne sont pas ce que nous considérons comme des “comptes de jetons” détenant des soldes utilisateur. Voici ce qui se passe avec et sans filtrage : Sans filtrage - L’inondation :
Cela s’abonne à TOUS les comptes appartenant au programme Token, ce qui inclut :
  • Comptes de jetons (165 octets) - Soldes utilisateurs : millions de comptes
  • Comptes de frappe (82 octets) - Définitions des jetons : centaines de milliers de comptes
  • Comptes multisig (355 octets) - Contrôles de portefeuille partagés : dizaines de milliers de comptes
  • Comptes du programme de jetons associés (tailles variées) - millions de comptes
Résultat: Votre application reçoit des millions de mises à jour de compte constamment, dont la plupart ne vous intéressent pas.
Avec un filtrage intelligent - Précision chirurgicale :
Cela filtre uniquement les comptes de 165 octets, qui sont spécifiquement les comptes de solde de jetons utilisateur - exactement ce que vous voulez pour suivre les transferts de jetons, les changements de solde, et les mises à jour de portefeuille. La différence :
  • Sans filtrage : Millions de mises à jour de comptes (créations de frappe, changements multisig, etc.)
  • Avec filtrage par datasize : Uniquement les changements de solde de jetons
Cela représente une réduction significative du bruit, en se concentrant uniquement sur les comptes qui représentent réellement les avoirs en jetons des utilisateurs.

D’où viennent les 165 octets ?

Ce n’est pas de la magie - cela provient de la structure de compte du programme SPL Token. En regardant le code source, nous pouvons voir que la struct Account définit exactement 165 octets :
Cette taille fixe nous permet de filtrer précisément les comptes de jetons standard et d’exclure :
  • Comptes de frappe (82 octets)
  • Comptes multisig (355 octets)
  • Comptes de programme de compte de jeton associé
  • Autres comptes liés aux jetons de tailles différentes
Pour calculer les tailles de compte dans d’autres programmes, consultez la référence d’espace Anchor - elle vous montre combien d’espace prennent différents types de données (Pubkey = 32 octets, u64 = 8 octets, etc.).

Décoder la structure du compte

Maintenant que nous comprenons pourquoi nous avons filtré 165 octets, décodons ce qui se trouve dans notre compte d’exemple :
Les 165 octets se décomposent comme suit :
  • Octets 0-31 : Adresse de frappe (quel jeton ce compte détient)
  • Octets 32-63 : Adresse du propriétaire (qui possède ce compte de jeton)
  • Octets 64-71 : Montant du jeton (combien de jetons sont dans le compte)
  • Octets 72-164 : Métadonnées supplémentaires (délégué, état, autorité de fermeture, etc.)
Cette approche structurée nous donne une précision chirurgicale : nous ne recevons que des mises à jour pour les comptes de jetons standard, pas le bruit provenant d’autres types de comptes.

Combiner les filtres : datasize + memcmp pour une précision laser

Maintenant que nous savons que l’adresse de frappe se situe aux octets 0-31, nous pouvons être encore plus spécifiques. Supposons que nous voulons seulement surveiller les comptes de jetons USDC. Nous pouvons combiner notre filtre datasize avec un filtre memcmp pour cibler l’adresse de frappe exacte :
Stratégie de filtrage progressive :
  1. Filtre de propriétaire : “Donne-moi les comptes gérés par le programme Token” (millions de comptes)
  2. Filtre de datasize : “Mais seulement les comptes de jetons standard de 165 octets” (centaines de milliers)
  3. Filtre memcmp : “Et seulement ceux détenant de l’USDC” (milliers)
Cette progression du large au spécifique est la clé d’une surveillance efficace des comptes. Chaque filtre réduit le jeu de résultats, de sorte que vous ne recevez que les mises à jour exactes qui vous intéressent. Important : Tous les filtres utilisent la logique AND - chaque condition doit être remplie pour qu’une mise à jour de compte soit déclenchée.

Lire les mises à jour de comptes USDC : Qui, Combien, Où ?

Voyons maintenant ce que ces mises à jour filtrées contiennent réellement. Créons un moniteur spécifique à l’USDC qui répond aux questions clés lorsqu’un compte de jeton change :
  • Qui possède ce compte de jeton ?
  • Combien d’USDC contient-il maintenant ?
  • (quel compte spécifique) a changé ?
  • Quand ce changement s’est-il produit ?
  • Quelle transaction a causé le changement ?
Les mises à jour des comptes bruts contiennent des données binaires que nous devons décoder. Étant donné que Solana utilise le codage base58 pour les adresses et les signatures, nous utilisons la fonction bs58.encode() pour convertir les objets Buffer binaires en chaînes lisibles.
Lorsque vous exécutez ce moniteur USDC, vous verrez une sortie propre et structurée comme ceci :
Chaque bloc représente un compte USDC qui a changé d’état. Le premier compte détient maintenant 1 500 USDC, tandis que le deuxième compte a été vidé à 0 USDC. Vous obtenez le solde actuel immédiatement après chaque transaction, ainsi que le compte spécifique qui a changé et quand. Les abonnements aux comptes vous montrent le résultat final de ce qui est arrivé à chaque compte, pas les détails de la transaction. Si vous avez besoin de comprendre le contexte complet de la transaction (qui a envoyé à qui, les frais, etc.), vous devrez récupérer la transaction complète en utilisant la signature affichée.

Référence complète de filtrage

Au-delà des filtres de base owner, datasize, et memcmp que nous avons utilisés, les abonnements de compte prennent en charge des options de filtrage supplémentaires pour affiner encore vos résultats :

Filtrage de comptes spécifiques

Surveillez des comptes exacts par leurs clés publiques :
Cette approche fonctionne bien lorsque vous savez exactement quels comptes comptent pour votre application - comme surveiller les comptes de trésorerie de votre application ou des comptes utilisateur spécifiques. Pour des ensembles de comptes très larges, les listes de clés publiques explicites deviennent coûteuses — 32 octets par compte dans la demande d’abonnement. Au-delà de ~10 000 comptes, utilisez un filtre cuckoo compressé (~3–4 octets par compte) pour suivre des centaines de milliers de comptes dans un seul flux. Disponible dans les SDK Rust et JavaScript.

Stratégies de filtrage combinées

La puissance vient de la combinaison de plusieurs types de filtres. Voici le modèle mental :
  1. Lancer un large filet avec owner - “Donne-moi tous les comptes gérés par ce programme”
  2. Filtrer par structure avec datasize - “Mais seulement les comptes de ce type spécifique”
  3. Cibler des données spécifiques avec memcmp - “Et seulement ceux contenant ces informations spécifiques”
  4. Surveiller des comptes connus avec account - “Ou regardez simplement ces comptes exacts qui m’intéressent”
Par exemple, surveiller les comptes USDC à forte valeur :
L’idée clé est que chaque filtre réduit le volume de mises à jour que vous recevez. Sans filtrage, vous pourriez obtenir des quantités écrasantes de mises à jour de compte. Avec un filtrage intelligent, vous obtenez uniquement les mises à jour qui comptent pour votre cas d’utilisation spécifique.

Comprendre le tableau d’ensemble

Considérez les abonnements de compte comme la surveillance d’un flux en direct de changements de base de données. L’état de Solana est essentiellement un vaste magasin de valeurs clés où chaque compte est une entrée. Lorsque les programmes s’exécutent, ils modifient ces comptes. Votre abonnement vous permet de surveiller en temps réel les entrées spécifiques qui changent. Le système de filtrage fonctionne comme les index de base de données - vous ne regardez pas juste “tous les changements” mais plutôt “les changements des comptes qui correspondent à ces critères”. Cela rend possible la création d’applications réactives qui réagissent immédiatement aux événements pertinents sur la chaîne sans submerger votre système avec des données non pertinentes.

Appliquer ce modèle à d’autres programmes

L’approche que nous avons apprise fonctionne pour n’importe quel programme Solana. Voici le modèle général :
  1. Recherchez la structure du compte - Consultez le code source ou la documentation du programme
  2. Commencez par le filtrage de propriétaire - Ciblez le programme qui gère les comptes
  3. Appliquez des filtres structurels - Utilisez la taille du compte, les motifs de données ou d’autres caractéristiques pour réduire à des types de comptes spécifiques
  4. Ajoutez des filtres ciblés - Concentrez-vous sur des comptes spécifiques, des états ou des valeurs de données qui comptent pour votre application