Ga naar de hoofdinhoud

Solana monitoren met Solana gRPC TypeScript)

Bijgewerkt op
Sep 03, 2026

Leestijd: 20 min.

Updates: van Slot Instellingen voor het afspelen van historische gegevens en meer

Vanaf juli 2025 Quicknode de van Slot parameter waarmee klanten gegevens uit maximaal 3000 recente slots – ongeveer 20 minuten – kunnen terugspelen, wat meer flexibiliteit biedt voor klanten die te maken kunnen krijgen met netwerkinstabiliteit of die tijdens het herstel een aanvulling nodig hebben.

Deze handleiding is bijgewerkt om rekening te houden met deze nieuwe functie, en is tevens aangepast voor gebruik met Solana , de huidige versies van Node.js en andere nieuwere tools.

Overzicht

In deze handleiding gaan we bekijken hoe je Solana gRPC (Yellowstone Geyser gRPC) te gebruiken om realtime on-chain-activiteit te monitoren. We gaan met name een TypeScript-applicatie maken die nieuwe token-uitgiften van het Pump.fun-programma op mainnet Solana bijhoudt. Dit project laat zien hoe je de mogelijkhedengRPC Solana gRPC voor gegevenstoegang met lage latentie kunt benutten om responsieve en efficiënte monitoringtools te bouwen.

Liever een visuele uitleg? Bekijk dan de video omgRPC 9 minuten te leren hoe je Solana kunt monitoren met behulp van Solana gRPC .
Abonneer je op ons YouTube-kanaal voor meer video's!

Wat je gaat doen

  • Meer informatie over Geyser en Solana gRPC
  • Gebruik TypeScript en Solana gRPC nieuwe Pump.fun-mints op Solana te monitoren
  • Deze logica ook op andere programma’s kunnen toepassen

Zo zal het programma eruitzien:

Solana gRPC

Wat je nodig hebt

  • Basisbegrip van Solana
  • Node.js (versie 20 of hoger)
  • Een Quicknode met een Scale- of Business-abonnement (gRPC Solana gRPC ), of met een Build/Accelerate-abonnement met de Solana gRPC
  • Een code-editor naar keuze (bijvoorbeeld VS Code)

Wat is Geyser?

Geyser is een plug-insysteem voor Solana dat toegang met lage latentie tot blockchaingegevens biedt, zonder de validators te overbelasten met intensieve RPC-verzoeken (bijvoorbeeld, getProgramAccounts). In plaats van rechtstreeks bij de validator te vragen, sturen Geyser-plugins realtime informatie over accounts, transacties, slots en blokken door naar de door jou gekozen externe gegevensopslag, bijvoorbeeld een relationele database, een NoSQL-database of streamingplatforms zoals Kafka. Deze aanpak vermindert de belasting van de validators aanzienlijk en verbetert tegelijkertijd de efficiëntie van de gegevenstoegang.

Het belangrijkste voordeel van Geyser-plugins is dat ze kunnen meegroeien met Solana grote volumes Solana . Door gegevensverzoeken door te sturen naar externe opslagplaatsen kunnen ontwikkelaars geoptimaliseerde toegangspatronen implementeren, zoals caching en indexering. Dit is met name waardevol voor toepassingen die regelmatig toegang moeten hebben tot grote datasets of historische informatie. Dankzij deze scheiding kunnen validators zich concentreren op hun primaire taak, namelijk het verwerken van transacties, terwijl ontwikkelaars tegelijkertijd verzekerd zijn van de uitgebreide, realtime toegang tot gegevens die ze nodig hebben.

Wat is Solana gRPC?

Solana gRPC gRPC Yellowstone Geyser gRPC Quicknode — die samenwerkt met het open-source Yellowstone gRPC ecosysteem. Het maakt gebruik van gRPC, het krachtige framework van Google dat Protocol Buffers voor serialisatie combineert met HTTP/2 voor transport, waardoor snelle en typeveilige communicatie tussen gedistribueerde systemen mogelijk wordt.

Solana gRPC realtime streaming van:

  • Wijzigingen in het account
  • Transacties
  • Inzendingen
  • Meldingen blokkeren
  • Meldingen over slots

In vergelijking met traditionele WebSocket-implementatiesgRPC Solana gRPC een lagere latentie en een hogere stabiliteit. Het bevat bovendien unaire bewerkingen voor het snel en eenmalig ophalen van gegevens. Door de combinatie van de efficiëntie en de typveiligheid gRPC is Solana gRPC geschikt voor cloudgebaseerde diensten en database-updates. Solana gRPC inbegrepen bij de Scale- en Business-abonnementen. Bij de Build- en Accelerate-abonnementen blijft het beschikbaar via de Solana gRPC .

Laten we eens kijken hoe Solana gRPC de praktijk werkt door een script te schrijven waarmee we nieuwe Pump.fun-mints op Solana kunnen volgen.


Overwegingen met betrekking tot de prestaties bij Streams met een hoog volume

Als je Solana gRPC Node.js gebruikt voor zeer grote hoeveelheden gegevens, kan dit een enkele CPU overbelasten. Als je systemen bouwt die alle transacties van drukke programma’s moeten verwerken of meerdere programma’s tegelijkertijd moeten volgen, kun je de volgende alternatieven met hoge prestaties overwegen:

  • Meerdere threads gebruiken. Node.js beschikt over twee modules: cluster (meerdere processen, één thread per proces) en werknemer (één proces, meerdere threads). Beide oplossingen lossen het probleem op dat een node één kern overbelast, maar cluster is eenvoudiger omdat elk proces in een afzonderlijk geheugengebied draait. Verdeel de Solana gRPC over meerdere instanties van cluster of werknemer om de belasting te verdelen.

  • Solana gRPC gebruiken gRPC Rust (zie ook de handleidingSolana gRPC Rust’)

  • Solana gRPC gebruiken gRPC Go (zie ook de handleidingSolana gRPC Go’).

Een nieuw project aanmaken

Laten we beginnen met het opzetten van een nieuw TypeScript-project:

  1. Maak een nieuwe map voor je project aan en ga daarheen:

    mkdir pump-fun-monitor && cd pump-fun-monitor
  2. Een nieuw Node.js-project opzetten:

    npm init -y

Schakel vervolgens ES6-modules in je package.json bestand door het volgende toe te voegen:

{
...existing package.json content...
"type": "module"
}
  1. Installeer de benodigde afhankelijkheden:

    npm install tsx @triton-one/yellowstone-grpc @types/node @solana/kit
  2. Sla de IDL op voor het programma dat je wilt monitoren. In dit geval halen we de IDL op voor het programma Pump.fun.

    curl -o program.json https://raw.githubusercontent.com/rckprtr/pumpdotfun-sdk/refs/heads/main/src/IDL/pump-fun.json

Nu ben je klaar om te beginnen met het schrijven van je programma!

Schrijf het script

Laten we ons programma maken om Pump.fun-mints te volgen met behulp van Solana gRPC. We zullen dit in verschillende stappen opsplitsen:

Stap 1: Interfaces definiëren

We zullen voornamelijk gebruikmaken van de interfaces uit de grpc pakket, dus we hoeven hier veel daarvan niet te definiëren. Maak een nieuw bestand aan met de naam lib/interfaces.ts en voeg de volgende code toe:

export interface CompiledInstruction {
programIdIndex: number;
accounts: Uint8Array;
data: Uint8Array;
}

export interface MintInformation {
mint: string;
transaction: string;
slot: number;
}

Stap 2: Maak een functie aan om je Solana endpoint op te halen

Solana gRPC een andere poort dan het gebruikelijke endpoint. Deze functie zet je Quicknode endpoint eengRPC endpoint -token. Maak een nieuw bestand aan met de naam quicknode.ts en voeg de volgende code toe:

// Convert the RPC endpoint to a Solana gRPC endpoint and token
export const getYellowstoneEndpointAndToken = (rpcEndpoint: string) => {
// Convert endpoint to URL object
const url = new URL(rpcEndpoint);
const YELLOWSTONE_PORT = 443;

// Solana gRPC endpoint is the same as the RPC endpoint, but with port 443 and no pathname
const yellowstoneEndpoint = `${url.protocol}//${url.hostname}:${YELLOWSTONE_PORT}`;

// The token is the pathname of the RPC endpoint, but without the leading slash
const yellowstoneToken = url.pathname.replace(/\//g, "");

return { yellowstoneEndpoint, yellowstoneToken };
};

Stap 3: Hulpfuncties maken

Solana gRPC transactiehandtekeningen en tokenadressengRPC als Uint8Array. We moeten deze omzetten naar base58 om ze leesbaar te maken. Maak een nieuw bestand aan met de naam lib/helpers.ts en voeg de volgende code toe:

import { getBase58Decoder } from "@solana/kit";

export const bufferToBase58 = (buffer: Uint8Array): string => {
return getBase58Decoder().decode(buffer);
};

Vervolgens voegen we een functie toe om de Explorer-URL voor een adres of transactie op te halen. Moderne terminal-apps ondersteunen het klikken op links, waardoor we elke mint kunnen bekijken zodra deze wordt aangemaakt:

export const getExplorerUrl = (address: string, type: "address" | "tx") => {
return `https://explorer.solana.com/${type}/${address}`;
};

Vervolgens voegen we een functie toe om de discriminator voor een instructiehandler uit de IDL van een programma op te halen. Deze kunnen we later gebruiken om instructies te vinden die deze instructiehandler hebben aangeroepen.

export const getInstructionHandlerDiscriminator = (
programIdl: any,
instructionName: string
) => {
const instruction = programIdl.instructions.find(
(instruction: any) => instruction.name === instructionName
);
const discriminatorBytes = instruction.discriminator;
return Buffer.from(discriminatorBytes);
};

Vervolgens voegen we een functie toe om de rekeningnamen en indices op te halen van de rekeningen die in een opdrachtverwerker worden gebruikt. Deze kunnen we later gebruiken om transacties te filteren, zodat alleen opdrachten voor een bepaalde opdrachtverwerker worden meegenomen.

export const getAccountsFromIdl = (
programIdl: any,
instructionName: string
): Array<{ name: string; index: number }> => {
const instruction = programIdl.instructions.find(
(instruction: any) => instruction.name === instructionName
);

if (!instruction) {
throw new Error(`Instruction '${instructionName}' not found in IDL`);
}

return instruction.accounts.map((account: any, index: number) => ({
name: account.name,
index: index,
}));
};

Stap 4: Constanten aanmaken

Sommige dingen veranderen niet zo vaak, dus laten we ze even vastleggen. Maak een nieuw bestand aan met de naam lib/constants.ts en voeg de volgende code toe:

// Set by Solana
export const SOLANA_SLOT_TIME_MS = 400;

// Set by Quicknode
export const MAX_SLOTS_TO_REPLAY = 3000;

// Set by the late 18th century French scientists
export const SECONDS = 1000;

// Set by ancient Babylonians
export const MINUTES = SECONDS * 60;

export const MAX_TIME_TO_REPLAY_MS = MAX_SLOTS_TO_REPLAY * SOLANA_SLOT_TIME_MS;
export const MAX_TIME_TO_REPLAY_MINUTES = MAX_TIME_TO_REPLAY_MS / 1000 / 60;

Stap 5: Maak onze Solana gRPC aan

Maak een nieuw bestand aan met de naam yellowstone.ts. We zullen dit zo algemeen mogelijk houden, zodat je het in meerdere projecten kunt hergebruiken. Begin met het importeren van de relevante afhankelijkheden — de grpc client, gRPC en onze helpers, interfaces en constanten.

import Client, {
CommitmentLevel,
SubscribeRequest,
SubscribeUpdate,
SubscribeUpdateTransaction,
} from "@triton-one/yellowstone-grpc";
import { ClientDuplexStream } from "@grpc/grpc-js";
import { bufferToBase58, getExplorerUrl } from "./helpers";
import { CompiledInstruction, MintInformation } from "./interfaces";
import {
MAX_SLOTS_TO_REPLAY,
MAX_TIME_TO_REPLAY_MINUTES,
SOLANA_SLOT_TIME_MS,
} from "./constants";

Laten we een paar handige hulpfuncties maken. Solana gRPC geeft de slotgRPC als een string terug, dus laten we dat even aanpassen:

export const getCurrentSlot = async (
yellowstoneClient: Client
): Promise<number> => {
const currentSlotString = await yellowstoneClient.getSlot();
return Number(currentSlotString);
};

Een abonnementsaanvraag indienen

Deze functie maakt een AbonnerenAanvraag die de opgegeven programma-ID’s en de vereiste accounts in de gaten houdt.

We willen onze filters zo specifiek mogelijk instellen, zodat we de hoeveelheid gegevens die we van de server ontvangen kunnen beperken:

  • accountInclude: omvatten transacties waarbij gebruik wordt gemaakt van welke dan ook account uit de array.
  • accountExclude: uitsluiten transacties waarbij gebruik wordt gemaakt van welke dan ook account uit de array.
  • accountVereist: neem alleen transacties op waarbij gebruik wordt gemaakt van alle records uit de array.

Wij geven de voorkeur aan accountVereist aangezien het specifieker is dan accountInclude en accountExclude.

export const createSubscribeRequest = (
includedAccounts: Array<string>,
excludedAccounts: Array<string>,
requiredAccounts: Array<string>,
fromSlot: number | null = null
): SubscribeRequest => {
// See https://github.com/rpcpool/yellowstone-grpc?tab=readme-ov-file#filters-for-streamed-data for full list of filters.
const request: SubscribeRequest = {
commitment: CommitmentLevel.CONFIRMED,
accounts: {},
slots: {},
transactions: {
// We can have multiple filters here, but for this demo, we'll only have one.
// When we get events, we can check which filter was matched.
// https://github.com/rpcpool/yellowstone-grpc?tab=readme-ov-file#transactions
pumpFun: {
vote: false,
failed: false,
accountInclude: includedAccounts,
accountExclude: excludedAccounts,
accountRequired: requiredAccounts,
},
},
transactionsStatus: {},
entry: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
ping: undefined,
};

if (fromSlot) {
// Solana gRPC expects the slot as a string, so let's fix that.
request.fromSlot = String(fromSlot);
}

return request;
};

Laten we ook een functie maken om het abonnementsverzoek naar de Solana gRPC te sturen – we maken die stream zo meteen aan.

export const sendSubscribeRequest = (
stream: ClientDuplexStream<SubscribeRequest, SubscribeUpdate>,
request: SubscribeRequest
): Promise<void> => {
return new Promise<void>((resolve, reject) => {
stream.write(request, (error: Error | null) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
};

Voeg enkele filters aan de clientzijde toe

Het grootste deel van onze filtering gebeurt via Solana gRPC, maar daar worden transacties niet rechtstreeks op instructiehandler gefilterd, dus voegen we een extra controle aan de clientzijde toe:

// Solana gRPC doesn't directly filter by instruction handler so we have to
// do it client-side.
export const checkInstructionMatchesInstructionHandlers = (
instruction: CompiledInstruction,
instructionHandlerDiscriminators: Array<Uint8Array>
): boolean => {
return (
instruction?.data &&
instructionHandlerDiscriminators.some((instructionHandlerDiscriminator) =>
Buffer.from(instructionHandlerDiscriminator).equals(
instruction.data.slice(0, 8)
)
)
);
};

We gaan ook een functie maken om een mooi object met naam-adresparen samen te stellen, zodat we de adressen kunnen ophalen die deze instructie voor specifieke accountnamen heeft gebruikt (zoals de munt (een overzicht van elk nieuw token op Pump.fun) en deze in een overzichtelijke tabel weergeven.

export const getAccountsByName = (
accountsToInclude: Array<{ name: string; index: number }>,
instruction: CompiledInstruction,
accountKeys: Array<Uint8Array>
): Record<string, string> => {
return accountsToInclude.reduce<Record<string, string>>(
(accumulator, account) => {
const accountIndex = instruction.accounts[account.index];
const address = bufferToBase58(accountKeys[accountIndex]);
accumulator[account.name] = address;
return accumulator;
},
{}
);
};

Klaar! Laten we nu aan de slag gaan met het verwerken van de updates die we van Solana gRPC ontvangen, met behulp van de functies die we zojuist hebben gemaakt.

Maak een functie om SubscribeUpdate om te zetten in mooi opgemaakte mint-informatie

We gaan een functie maken die een Abonneren | Bijwerken van Solana gRPC een MintInformatie — een eenvoudig object met het adres van de munt, de transactiehandtekening en het slotnummer.

export const getMintInfoFromUpdate = (
update: SubscribeUpdate,
instructionHandlerDiscriminators: Array<Uint8Array>,
accountsToInclude: Array<{ name: string; index: number }>
): null | MintInformation => {
// Check the filter name that was matched
// (Solana gRPC also sends other things like 'ping' updates, but we don't care about those)
if (!update.filters.includes("pumpFun")) {
return null;
}

// These should never happen in this demo,
// since our filter's matches will include the right properties.
// but let's satisfy the type checker.
const transaction = update.transaction?.transaction;
const message = transaction?.transaction?.message;
const slot = update.transaction?.slot;
if (!transaction || !message || !slot) {
return null;
}

// Find the instruction that matches our target instruction handler
const instruction =
message.instructions.find((instruction) =>
checkInstructionMatchesInstructionHandlers(
instruction,
instructionHandlerDiscriminators
)
) || null;
if (!instruction) {
return null;
}

// Make a nice Object of account value/address pairs, so we can get the address
// values this instruction used for each account name.
const accountsByName = getAccountsByName(
accountsToInclude,
instruction,
message.accountKeys
);

const base58TransactionSignature = bufferToBase58(transaction.signature);

return {
mint: getExplorerUrl(accountsByName.mint, "address"),
transaction: getExplorerUrl(base58TransactionSignature, "tx"),
slot: Number(slot),
};
};

Koppel de stream aan onze functies

Nu zijn we klaar om de stream aan onze functies te koppelen. Telkens wanneer de stream een update verstuurt, roepen we getMintInfoFromUpdate om de mint-informatie op te halen en deze naar de console af te drukken. Open yellowstone.ts en voeg de volgende code toe:


export const handleStreamEvents = (
stream: ClientDuplexStream<SubscribeRequest, SubscribeUpdate>,
instructionDiscriminators: Array<Uint8Array>,
accountsToInclude: Array<{ name: string; index: number }>
): Promise<void> => {
return new Promise<void>((resolve, reject) => {
stream.on("data", (update: SubscribeUpdate) => {
const mintInfo = getMintInfoFromUpdate(
update,
instructionDiscriminators,
accountsToInclude
);

if (mintInfo) {
console.log("💊 New Pump.fun Mint Detected!");
console.table(mintInfo);
console.log("\n");
}
});
stream.on("error", (error: Error) => {
console.error("Stream error:", error);
reject(error);
stream.end();
});
stream.on("end", () => {
console.log("Stream ended");
resolve();
});
stream.on("close", () => {
console.log("Stream closed");
resolve();
});
});
};

Dat is alles yellowstone.ts!

Stap 6: Onze filters kiezen en alles samenvoegen

Nu zijn we klaar om het hoofdscript te maken. Hier gaan we een aantal waarden instellen voor de transacties die we willen monitoren, maken we verbinding met Solana gRPC en roepen we vervolgens de functies aan die we zojuist hebben gemaakt om de transactie te monitoren.

We willen onze filters zo specifiek mogelijk maken, zodat we de hoeveelheid gegevens die we van de server ontvangen kunnen beperken, minder API-credits verbruiken en ons script efficiënter maken. We zouden gewoon het volgende kunnen opnemen: PROGRAMMA_ID om alle transacties te verkrijgen waarbij het programma betrokken is, maar aangezien we alleen op zoek zijn naar een deelverzameling van instructies (in dit geval, maken (instructies), zouden we de IDL kunnen bekijken en eventuele extra accounts kunnen identificeren die mogelijk alleen worden doorgegeven aan de maken instructieverwerker. Aangezien de Pump.fun-tokenuitgifte-instantie wordt in elke maken instructieverwerker; door beide accounts verplicht te stellen, kunnen we de hoeveelheid gegevens die we ontvangen verminderen en ons script efficiënter maken.

We willen ook het specifieke adres weergeven dat voor ‘mint’ wordt gebruikt. Solana wordt gebruikgemaakt van arrays, niet van benoemde accounts, dus moeten we de index van het account dat we willen volgen uit de IDL van het programma halen, net zoals we eerder hebben gedaan. Voeg gerust extra accounts toe die je wilt volgen (je kunt hun index uit de IDL van je programma halen).

Maak een nieuw bestand aan met de naam monitor-program.ts en voeg de volgende code toe:

import {
createSubscribeRequest,
handleStreamEvents,
sendSubscribeRequest,
getSlotFromTimeAgo,
} from "./lib/yellowstone";
import { getYellowstoneEndpointAndToken } from "./lib/quicknode";
import { env } from "node:process";
import { MINUTES } from "./lib/constants";
import Client from "@triton-one/yellowstone-grpc";
import {
getInstructionHandlerDiscriminator,
getAccountsFromIdl,
} from "./lib/helpers";
import programIdl from "./program.json";

// We're watching the pump.fun program
const PROGRAM_ID = programIdl.address;

// We're watching the create() instruction handler
const PUMP_FUN_CREATE_INSTRUCTION_HANDLER_DISCRIMINATOR =
getInstructionHandlerDiscriminator(programIdl, "create");

const PUMP_FUN_MINT_AUTHORITY = "TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM";

// The program and required accounts to watch via Solana gRPC
// See https://github.com/rpcpool/yellowstone-grpc?tab=readme-ov-file#filters-for-streamed-data for full list of filters.
const requiredAccounts: Array<string> = [PROGRAM_ID, PUMP_FUN_MINT_AUTHORITY];

// After we get the events from Solana gRPC, we'll filter them by the instruction handler (onchain function) being invoked
const instructionDiscriminators: Array<Uint8Array> = [
PUMP_FUN_CREATE_INSTRUCTION_HANDLER_DISCRIMINATOR,
];

// Get account information from the IDL for the create instruction
// This will include all accounts used in the create instruction with their names and indices
const ACCOUNTS_TO_INCLUDE = getAccountsFromIdl(programIdl, "create");

const rpcEndpoint = env["QUICKNODE_SOLANA_MAINNET_ENDPOINT"];
if (!rpcEndpoint) {
throw new Error(
"QUICKNODE_SOLANA_MAINNET_ENDPOINT environment variable is required"
);
}

const { yellowstoneEndpoint, yellowstoneToken } =
getYellowstoneEndpointAndToken(rpcEndpoint);

const yellowstoneClient = new Client(yellowstoneEndpoint, yellowstoneToken, {
grpcDefaultCompressionAlgorithm: 0, // 0 = gzip, 1 = zstd
});
await yellowstoneClient.connect();
// Somewhat confusingly, we need to call `subscribe` on the client to get a stream
// and then make a subscribe request to the stream.
const stream = await yellowstoneClient.subscribe();

// We'll use this later in the guide
const fromSlot = null;

// Create subscribe request with fromSlot parameter
const request = createSubscribeRequest([], [], requiredAccounts, fromSlot);

await sendSubscribeRequest(stream, request);
console.log(
"🔌 Geyser connection established - watching new Pump.fun token mints...\n"
);
await handleStreamEvents(
stream,
instructionDiscriminators,
ACCOUNTS_TO_INCLUDE
);

Voeg jeendpoint toeendpoint een .env bestand

Voordat je het script uitvoert, je endpoint ophalen endpoint het Quicknode en voeg het toe aan een nieuw bestand met de naam .env, waarbij je het endpoint vervangt endpoint je eigen eindpunt:

QUICKNODE_SOLANA_MAINNET_ENDPOINT="https://three-custom-words.solana-mainnet.quiknode.pro/1234567890abcdefghijklmnopqrstuvwxyz1234/"

Leg je .env Voeg het bestand toe aan je repository!

Leg je .env bestand naar je repository, aangezien het jeendpoint bevat. Dit vormt een veiligheidsrisico, omdat iedereen hierdoor zonder jouw toestemming toegang krijgt tot je endpoint het kan gebruiken. Voeg het toe aan je .gitignore bestand om dit te voorkomen.

Voer het script uit

Nu zijn we klaar om het script uit te voeren. Voer in je terminal de volgende opdracht uit:

npx tsx --env-file=.env monitor-program.ts

Je zou de volgende uitvoer moeten zien:

npx tsx --env-file=.env monitor-program.ts
🔌 Geyser connection established - watching new Pump.fun token mints...

💊 New Pump.fun Mint Detected!
┌─────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ (index) │ Values │
├─────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ mint │ 'https://explorer.solana.com/address/G8XYfdnujEiwivG8LZuj5NKppUkx6nn6Wo72A1Ckpump' │
│ transaction │ 'https://explorer.solana.com/tx/2sSHoWvNNuHVMJMPLeramPNKj8VJvtjhG6hLrci4FmnYG6xmPEqRiKHAWY15wcTGMxqhgnLi8DRBPWEM3r5bSAut' │
│ slot │ 358713246 │
└─────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘


💊 New Pump.fun Mint Detected!
┌─────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ (index) │ Values │
├─────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ mint │ 'https://explorer.solana.com/address/EjrHSwxfZ3mCbLnnuXg4xYuHuzvMCbB5S4ptVzxAfonq' │
│ transaction │ 'https://explorer.solana.com/tx/2rR47UGUcv5EY5hTij8eVshZPHqLV2mUVJdZYr4kxm25EQwLdumqt3v9RfLMfGBM7ENVpRGbdD1b3Q7L4mo3W9TX' │
│ slot │ 358713253 │
└─────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘


💊 New Pump.fun Mint Detected!
┌─────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ (index) │ Values │
├─────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ mint │ 'https://explorer.solana.com/address/8prBRtMZvYpppiUfcKbmteQx8gHqn8XicDZAPfPRpump' │
│ transaction │ 'https://explorer.solana.com/tx/5cS6buykKeFaE9bNDzoo8PvKixew4cV14hJMMLYSwuvQm5xWrxr2uRf2Hf3ZRrwizKbc8GsytmbxbpaXhHgYaZYJ' │
│ slot │ 358713276 │
└─────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Je kunt op het mint-adres klikken om de mint-informatie op Solana te bekijken:

Informatie over Mint in Solana

Heb je problemen? De volledige code is beschikbaar in de GitHub-repository van pump.fun monitor.

Historische herhaling met fromSlot

Soms willen we het proces hervatten vanaf een bepaald tijdstip in het verleden – bijvoorbeeld voor klanten die mogelijk berichten hebben gemist of die tijdens het herstelproces gegevens moeten aanvullen. We kunnen het proces ook hervatten vanaf elk willekeurig tijdstip binnen de laatste 3000 slots (20 minuten).

Normaal gesproken zouden we het meest recente slotnummer opslaan zodra er nieuwe slots binnenkomen, en vervolgens van Slot bij het herstellen dat nummer in de abonnementsaanvraag.

Voor deze demo kiezen we gewoon een slot uit een bepaald moment in het verleden – open yellowstone.ts en voeg de volgende functie toe:

// Allow us to get the slot from a given time in the past
export const getSlotFromTimeAgo = async (
yellowstoneClient: Client,
timeAgo: number
) => {
const now = Date.now();
const fromTime = now - timeAgo;

const slotsAgo = Math.ceil(timeAgo / SOLANA_SLOT_TIME_MS);
if (slotsAgo > MAX_SLOTS_TO_REPLAY) {
throw new Error(
`From time ${new Date(
fromTime
).toISOString()} is too far in the past. Maximum time to replay is ${MAX_TIME_TO_REPLAY_MINUTES} minutes.`
);
}

const currentSlot = await getCurrentSlot(yellowstoneClient);
const fromSlot = currentSlot - slotsAgo;

return fromSlot;
};

Vervolgens in monitor-program.ts, dan kunnen we instellen van Slot in de sleuf, 5 minuten geleden:

// Typically, we would record the most recent slot when each event is recieved,
// and then replay from that slot if we need to recover.
// For this demo, let's get the last 5 minutes of transactions
const fromSlot = await getSlotFromTimeAgo(yellowstoneClient, 5 * MINUTES);

Voer het script opnieuw uit; je zou dan eerst een reeks historische gegevens moeten zien voordat het script weer synchroon loopt met de realtime gegevens. Je kunt op een willekeurige munt of transactie klikken om de details op Solana te bekijken, inclusief het tijdstip waarop deze plaatsvond.

Samenvatting

In deze handleiding hebben we bekeken hoe je Solana gRPC kunt gebruikengRPC Solana in realtimegRPC monitoren. We hebben ons gericht op het volgen van nieuwe token-uitgiften vanuit het Pump.fun-programma, maar de principes die we hebben besproken, kunnen worden gebruikt om elk Solana of -account te monitoren.

Als je verder bouwt op Solana, kun je overwegen hoe je Solana gRPC kunt inzettengRPC responsievere en efficiëntere applicaties te ontwikkelen. Of je nu een tradingbot, een analysedashboard of een complexe DeFi-applicatie bouwt: realtime toegang tot gegevens met een lage latentie kan je een aanzienlijk voordeel opleveren.

Bronnen

Laten we contact houden!

We horen graag hoe jij Solana gRPC gebruikt. Deel je ervaringen, vragen of feedback met ons via Twitter of Discord.