Solana Geyser gRPC - Filtres

Solana Stream SDK
Le SDK Solana Stream est fourni sous forme de logiciel open source. Pour plus de détails, veuillez consulter le dépôt GitHub ci-dessous.

Aperçu des filtres gRPC

Solana Geyser gRPC utilise des filtres pour récupérer efficacement seulement les données qui vous intéressent, comme des comptes spécifiques, des programmes, des transactions, des créneaux horaires et des blocs.
Ci-dessous, nous fournissons des exemples de TypeScript utilisant le SDK Solana Stream, expliquant clairement les rôles spécifiques de chaque filtre. La structure et la signification des filtres sont identiques lors de l'utilisation de Rust.

Rôles et exemples de chaque filtre

S'abonner à un compte

Abonnez-vous aux mises à jour en temps réel pour un compte spécifique. L'exemple suivant s'inscrit au compte SOL-USDC OpenBook au niveau d'engagement confirmé:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: { slots: {} },
  accounts: {
    'wsol/usdc': {
      account: ['8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6'],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.CONFIRMED,
}
  • "wsol/usdc" est une étiquette définie par le client.
  • Plusieurs filtres pour les comptes, programmes, blocs et slots peuvent être combinés en une seule requête JSON.

Inscrivez-vous à un compte avec account_data_slice

Cet exemple démontre qu'il n'y a qu'une partie spécifique des données du compte. Au lieu de récupérer l'ensemble des données (165 octets) d'un compte jeton USDC, il récupère 40 octets à partir du décalage 32. Cette gamme comprend des informations telles que le propriétaire et la balance des lampes.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {
    usdc: {
      owner: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
      filters: [
        {
          tokenAccountState: true,
        },
        {
          memcmp: {
            offset: 0,
            data: {
              base58: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
            },
          },
        },
      ],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  commitment: CommitmentLevel.CONFIRMED,
  accountsDataSlice: [{ offset: 32, length: 40 }],
}

Abonnez-vous à un programme

Cet exemple démontre que vous vous abonner à des mises à jour de compte associées à un programme spécifique.
Ci-dessous, nous nous abonneons aux mises à jour de comptes pour les comptes détenus par le programme Solend au Processed niveau d'engagement.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {
    solend: {
      owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}
  • "solend" est une étiquette personnalisée qui peut être librement définie par le client.
  • Pour vous abonner à plusieurs programmes, veuillez consulter la section suivante intitulée « S'abonner à plusieurs programmes ».

S'abonner à plusieurs programmes

Cet exemple montre comment s'abonner aux mises à jour de comptes associées à plusieurs programmes à la fois.
L'exemple ci-dessous s'inscrit aux mises à jour pour les comptes appartenant à Solend et à Serum.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {
    programs: {
      owner: [
        'So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo',
        '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
      ],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}
Si vous préférez attribuer des étiquettes individuelles à chaque programme, utilisez l'approche suivante:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {
    solend: {
      owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
    },
    serum: {
      owner: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

S'abonner à toutes les opérations non réglées par vote ou non

Cet exemple démontre l'adhésion à toutes les opérations de la Finalized le niveau d'engagement, à l'exclusion des opérations de crédit et des opérations échouées.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    alltxs: {
      vote: false,
      failed: false,
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.FINALIZED,
}
  • vote: false exclut les opérations de vote.
  • failed: false exclut les opérations en échec.
  • Si les champs sont laissés vides, toutes les transactions sont récupérées.
  • Lorsque plusieurs champs sont spécifiés, ils fonctionnent avec une condition ET.

S'abonner à des transactions non-votes mentionnant un compte

Cet exemple démontre l'adhésion à des opérations impliquant un compte spécifique, mais excluant les opérations de vote.
L'exemple ci-dessous s'inscrit à des transactions non-votes mentionnant des comptes associés au programme Serum.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    serum: {
      vote: false,
      accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

S'abonner à des opérations hors comptes

Cet exemple démontre qu'il s'agit d'abonnements à des opérations excluant celles qui concernent des comptes spécifiques.
L'exemple ci-dessous récupère les transactions à l'exclusion des comptes appartenant aux programmes Serum et Tokenkeg.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    serum: {
      accountExclude: [
        '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
        'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
      ],
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

S'abonner à des transactions mentionnant des comptes et excluant certains comptes

Cet exemple démontre l'adhésion à des opérations impliquant certains comptes, tout en excluant explicitement d'autres comptes spécifiés.
L'exemple ci-dessous s'inscrit à des transactions mentionnant le compte de Serum, mais exclut un compte spécifié:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    serum: {
      accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
      accountExclude: ['9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT'],
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Inscrivez-vous à une signature de transaction

Cet exemple montre qu'il s'inscrit à des mises à jour en temps réel pour une signature de transaction spécifique, jusqu'à ce qu'il atteigne le Confirmed ou Finalized État.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {
    sign: {
      signature:
        '5rp2hL9b6kexex11Mugfs3vfU9GhieKruj4CkFFSnu52WLxiGn4VcLLwsB62XURhMmT1j4CZiXT6FFtYbXsLq2Zs',
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Abonnez-vous aux machines à sous

Cet exemple démontre l'abonnement aux notifications des créneaux entrants. Aucun détail supplémentaire n'est requis au-delà de l'attribution d'un nom d'étiquette personnalisé:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    incoming_slots: {},
  },
  accounts: {},
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

S'abonner aux blocs

Abonnez-vous aux mises à jour en temps réel de tous les blocs générés. Par défaut, toutes les transactions dans un bloc seront récupérées:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {
    blocks: {},
  },
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Pour exclure les transactions et récupérer uniquement les informations mises à jour du compte:

typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {
    blocks: {
      includeTransactions: false,
      includeAccounts: true,
    },
  },
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Pour récupérer uniquement les transactions/accounts impliquant des comptes spécifiques:

typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {
    blocks: {
      accountInclude: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
    },
  },
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

S'abonner pour bloquer les métadonnées

Inscrivez-vous uniquement pour bloquer les notifications de métadonnées lorsque les blocs sont traités. Les données détaillées sur les transactions ne sont pas incluses.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {},
  blocksMeta: {
    blockmetadata: {},
  },
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Gestion des niveaux d'engagement

Le flux de Solana Geyser gRPC par défaut Processed niveau d'engagement.
Vous pouvez spécifier des niveaux d'engagement plus élevés tels que Confirmed ou Finalized. Dans ces cas, Geyser tamponne les données et envoie des notifications une fois le niveau d'engagement spécifié atteint.
Pour une performance maximale, il est recommandé de gérer la gestion du niveau d'engagement du côté client.
Voici comment spécifier les niveaux d'engagement:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

enum CommitmentLevel {
  PROCESSED = 0,
  CONFIRMED = 1,
  FINALIZED = 2,
}
  • PROCESSED: Données immédiates après traitement. Récupération rapide, mais pas encore confirmée.
  • CONFIRMED: Données confirmées par le groupe, offrant une certitude accrue.
  • FINALIZED: Données complètes sans risque de réorganisation.

Avantages du travail Processed

L'avantage principal de Processed Le niveau d'engagement est la récupération immédiate des transactions, ce qui permet un traitement rapide côté client. Les clients peuvent ensuite détecter les transitions vers Confirmed ou Finalized, offrant une réactivité rapide.

Comment gérer Confirmed et Finalized

Lors de l' utilisation Confirmed ou Finalized niveaux, événements (transactions ou mises à jour de compte) doivent être tamponnés par emplacement.
Met les événements en tampon par slot, s'abonne aux notifications de slot, puis émet les événements mis en tampon une fois qu'un slot spécifique atteint l'engagement souhaité (Confirmed ou Finalized).
Les événements seront initialement reçus avant qu'un créneau atteigne Confirmed ou Finalized.

La chose spéciale à propos de Finalized

En raison des spécifications de Solana Geyser, tous les créneaux ne reçoivent pas des notifications définitives explicites. Par conséquent, lorsque vous recevez une notification définitive pour un créneau, vous devez traiter tous les créneaux de l'ancêtre comme finalisés, même si aucune notification n'a été reçue explicitement.
Plus précisément, après avoir reçu une notification définitive, traiter rétroactivement tous les créneaux de l'ancêtre comme terminés.