Solana Geyser gRPC - Filtres

Le Solana Stream SDK 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 uniquement les données qui vous intéressent, comme des comptes, des programmes, des transactions, des slots et des blocs spécifiques.
Ci-dessous, nous fournissons des exemples TypeScript utilisant le Solana Stream SDK, qui expliquent clairement le rôle précis de chaque filtre. La structure et la signification des filtres sont identiques lorsque vous utilisez Rust.
Rôles et exemples de chaque filtre
S'abonner à un compte
Abonnez-vous aux mises à jour en temps réel d'un compte spécifique. L'exemple suivant s'abonne au compte OpenBook SOL-USDC au niveau de commitment Confirmed:
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,
}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, les programmes, les blocs et les slots peuvent être combinés dans une seule requête JSON.
S'abonner à un compte avec account_data_slice
Cet exemple montre comment récupérer uniquement une partie spécifique des données d'un compte. Au lieu de récupérer l'intégralité des données (165 octets) d'un compte de token USDC, il récupère 40 octets à partir de l'offset 32. Cette plage comprend des informations telles que le propriétaire et le solde en lamports.
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 }],
}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 }],
}S'abonner à un programme
Cet exemple montre comment s'abonner aux mises à jour de comptes associées à un programme spécifique.
Ci-dessous, nous nous abonnons aux mises à jour des comptes détenus par le programme Solend, au niveau de commitment
Processed.typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {
solend: {
owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}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 que le client peut définir librement.- 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 en une seule fois aux mises à jour de comptes associées à plusieurs programmes.
L'exemple ci-dessous s'abonne aux mises à jour des comptes détenus par les programmes 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,
}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 une étiquette distincte à 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,
}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 transactions finalisées, hors transactions de vote et transactions échouées
Cet exemple montre comment s'abonner à toutes les transactions au niveau de commitment
Finalized, en excluant les transactions de vote et les transactions é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,
}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: falseexclut les transactions de vote.failed: falseexclut les transactions échouées.- Si les champs sont laissés vides, toutes les transactions sont récupérées.
- Lorsque plusieurs champs sont spécifiés, ils sont combinés avec une condition AND.
S'abonner aux transactions hors vote qui mentionnent un compte
Cet exemple montre comment s'abonner aux transactions impliquant un compte spécifique, en excluant les transactions de vote.
L'exemple ci-dessous s'abonne aux transactions hors vote qui mentionnent 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,
}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 aux transactions en excluant des comptes
Cet exemple montre comment s'abonner aux transactions en excluant celles qui impliquent des comptes spécifiques.
L'exemple ci-dessous récupère les transactions en excluant tout compte détenu par les 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,
}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 aux transactions qui mentionnent des comptes, en excluant certains comptes
Cet exemple montre comment s'abonner aux transactions impliquant certains comptes, tout en excluant explicitement d'autres comptes spécifiés.
L'exemple ci-dessous s'abonne aux transactions qui mentionnent 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,
}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,
}S'abonner à une signature de transaction
Cet exemple montre comment s'abonner aux mises à jour en temps réel d'une signature de transaction spécifique, jusqu'à ce qu'elle atteigne l'état
Confirmed ou Finalized.typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {
sign: {
signature:
'5rp2hL9b6kexex11Mugfs3vfU9GhieKruj4CkFFSnu52WLxiGn4VcLLwsB62XURhMmT1j4CZiXT6FFtYbXsLq2Zs',
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {
sign: {
signature:
'5rp2hL9b6kexex11Mugfs3vfU9GhieKruj4CkFFSnu52WLxiGn4VcLLwsB62XURhMmT1j4CZiXT6FFtYbXsLq2Zs',
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}S'abonner aux slots
Cet exemple montre comment s'abonner aux notifications des slots entrants. Aucun détail supplémentaire n'est requis, à part 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,
}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 d'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,
}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 de compte mises à jour:
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,
}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/comptes 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,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {
blocks: {
accountInclude: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
},
},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}S'abonner aux métadonnées de bloc
Abonnez-vous uniquement aux notifications de métadonnées de bloc lorsque des blocs sont traités. Les données détaillées des 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,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {},
blocksMeta: {
blockmetadata: {},
},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}Gérer les niveaux de commitment
Le flux Solana Geyser gRPC utilise par défaut le niveau de commitment
Processed.Vous pouvez spécifier des niveaux de commitment plus élevés, comme
Confirmed ou Finalized. Dans ces cas, Geyser met les données en mémoire tampon et envoie les notifications une fois le niveau de commitment spécifié atteint.Pour des performances maximales, il est recommandé de gérer le niveau de commitment côté client.
Voici comment spécifier les niveaux de commitment:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
enum CommitmentLevel {
PROCESSED = 0,
CONFIRMED = 1,
FINALIZED = 2,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
enum CommitmentLevel {
PROCESSED = 0,
CONFIRMED = 1,
FINALIZED = 2,
}PROCESSED: Données disponibles immédiatement après le traitement. Récupération rapide, mais données pas encore confirmées.CONFIRMED: Données confirmées par le cluster, offrant une certitude accrue.FINALIZED: Données entièrement finalisées, sans risque de réorganisation.
Avantages de travailler au niveau Processed
Le principal avantage du niveau de commitment
Processed 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, ce qui offre une grande réactivité.Comment gérer Confirmed et Finalized
Lorsque vous utilisez les niveaux
Confirmed ou Finalized, les événements (transactions ou mises à jour de compte) devraient être mis en mémoire tampon par slot.Mettez les événements en mémoire tampon slot par slot, abonnez-vous aux notifications de slots, puis libérez les événements de la mémoire tampon une fois qu'un slot donné atteint le niveau de commitment souhaité (
Confirmed ou Finalized).Les événements seront d'abord reçus avant qu'un slot n'atteigne
Confirmed ou Finalized.La particularité de Finalized
En raison des spécifications de Solana Geyser, tous les slots ne reçoivent pas de notification explicite de finalisation. Par conséquent, lorsque vous recevez une notification de finalisation pour un slot, vous devez traiter tous les slots ancêtres comme finalisés, même si aucune notification n'a été reçue explicitement.
Plus précisément, à la réception d'une notification de finalisation, traitez rétroactivement tous les slots ancêtres comme finalisés.