WEB3DEV

Cover image for Como criar Subscrições de Websocket para a Blockchain Solana usando o Typescript
Paulo Gio
Paulo Gio

Posted on

Como criar Subscrições de Websocket para a Blockchain Solana usando o Typescript

Visão Geral

Criar ouvintes de eventos é uma forma efetiva de alertar seu aplicativo ou seus usuários de que algo que você está monitorando mudou. A Solana possui vários ouvintes de eventos úteis integrados, também conhecidos como subscrições, que facilitam a escuta de mudanças na Blockchain Solana. Não sabe como você usaria isso? Aqui estão alguns exemplos onde isso pode ser útil: um bot do Discord que procura interações com um Programa na cadeia (por exemplo, um bot de vendas), um dApp que verifica erros em uma transação de um usuário ou uma notificação de telefone quando o saldo da carteira de um usuário mudar.

O que você irá fazer

Neste guia, você aprenderá a usar vários métodos de ouvintes de eventos da Solana e pontos de extremidade (endpoints) de Websocket do QuickNode (WSS://) para ouvir mudanças na cadeia. Especificamente, você criará um aplicativo simples em TypeScript para rastrear mudanças em uma conta (ou carteira). Em seguida, você aprenderá como utilizar os métodos de cancelamento de subscrição da Solana para remover um ouvinte de seu aplicativo. Também abordaremos conceitos básicos sobre alguns dos outros métodos de ouvintes da Solana.

​​O que você vai precisar

  • Nodejs instalado (versão 16.15 ou superior)
  • npm ou yarn instalado (vamos usar o yarn para inicializar nosso projeto e instalar os pacotes necessários. Sinta-se à vontade para usar o npm se esse for o seu gerenciador de pacotes preferido)
  • Experiência em Typescript e ts-node instalado
  • Solana Web3

Configure seu ambiente

Crie um novo diretório de projeto em seu terminal com:

mkdir solana-subscriptions
cd solana-subscriptions
Enter fullscreen mode Exit fullscreen mode

Crie um arquivo app.ts:

echo > app.ts
Enter fullscreen mode Exit fullscreen mode

Inicialize seu projeto com o sinalizador (flag) "yes" para usar valores-padrão para seu novo pacote:

yarn init --yes
#ou
npm init --yes
Enter fullscreen mode Exit fullscreen mode

Instale as dependências Web3 da Solana:

yarn add @solana/web3.js
#ou
npm install @solana/web3.js
Enter fullscreen mode Exit fullscreen mode

Abra app.ts em seu editor de código preferido e na linha 1, importe Connection, PublicKey e LAMPORTS_PER_SOL da biblioteca Web3 da Solana:

import { Connection, PublicKey, LAMPORTS_PER_SOL, } from "@solana/web3.js";
Enter fullscreen mode Exit fullscreen mode

Ótimo! Estamos prontos para seguir adiante.

Configure seu Ponto de Extremidade Quicknode

Para construir na Solana, você precisará de um ponto de extremidade de API para se conectar à rede. Você pode usar nós públicos ou implantar e gerenciar sua própria infraestrutura; no entanto, se você quiser tempos de resposta 8x mais rápidos, pode deixar o trabalho pesado conosco. Veja por que mais de 50% dos projetos na Solana escolhem o QuickNode e se inscreva para uma conta gratuita aqui.

Vamos usar um nó Solana da rede de desenvolvimento (Devnet). Copie os links do provedor HTTP e do provedor WSS:

https://www.quicknode.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBdjhEIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--fa80e5df2cdfd7508925a39d8abdbf790670c24d/newNode.png

Crie duas novas variáveis nas linhas 3 e 4 do arquivo app.js para armazenar esses URLs:

const WSS_ENDPOINT = 'wss://example.solana-devnet.quiknode.pro/000/'; // substitua pelo seu URL
const HTTP_ENDPOINT = 'https://example.solana-devnet.quiknode.pro/000/'; // substitua pelo seu URL
Enter fullscreen mode Exit fullscreen mode

Estabeleça uma conexão com a Solana

Na linha 5, crie uma nova conexão com a Solana:

const solanaConnection = new Connection(HTTP_ENDPOINT,{wsEndpoint:WSS_ENDPOINT});
Enter fullscreen mode Exit fullscreen mode

Se você criou instâncias de conexão com a Solana no passado, você pode notar algo diferente sobre nossos parâmetros, particularmente a inclusão de {wsEndpoint:WSS_ENDPOINT}. Vamos nos aprofundar um pouco mais nisso.

O constructor (construtor) da classe Connection nos permite passar um commitmentOrConfig opcional. Existem algumas opções interessantes que podemos incluir com o ConnectionConfig, mas hoje vamos nos concentrar no parâmetro opcional, wsEndpoint. Esta é uma opção para você fornecer um URL de ponto de extremidade para o ponto de extremidade de Websocket JSON RPC PubSub do nó completo. No nosso caso, esse é o Ponto de Extremidade WSS que definimos anteriormente, WSS_ENDPOINT.

O que acontece se você não passar um wsEndpoint? Bem, a Solana conta com uma função, makeWebsocketUrl, que substitui o https do URL do ponto de extremidade por wss ou http por ws (fonte). Como todos os pontos de extremidade HTTP do QuickNode possuem um ponto de extremidade WSS correspondente com o mesmo token de autenticação, não há problema em omitir esse parâmetro, a menos que você queira usar um ponto de extremidade separado para suas consultas de Websocket.

Vamos então criar algumas subscrições!

Crie uma Subscrição de Conta

Para rastrear uma carteira na Solana, precisaremos chamar o método onAccountChange em nossa solanaConnection. Passaremos ACCOUNT_TO_WATCH, a chave pública da carteira que desejamos pesquisar, e uma função de retorno de chamada (callback). Criamos um log simples que nos alerta que um evento foi detectado e registra o novo saldo da conta. Adicione este trecho ao seu código após sua declaração solanaConnection na linha 7:

(async()=>{
    const ACCOUNT_TO_WATCH = new PublicKey('vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg'); // Substitua por seu próprio endereço de carteira
    const subscriptionId = await solanaConnection.onAccountChange(
        ACCOUNT_TO_WATCH,
        (updatedAccountInfo) =>
            console.log(`---Event Notification for ${ACCOUNT_TO_WATCH.toString()}--- \nNew Account Balance:`, updatedAccountInfo.lamports / LAMPORTS_PER_SOL, ' SOL'),
        "confirmed"
    );
    console.log('Starting web socket, subscription ID: ', subscriptionId);
})()
Enter fullscreen mode Exit fullscreen mode

Crie um Teste Simples

Este código está pronto para ser executado como está, mas adicionaremos mais uma funcionalidade para nos ajudar a testar se está funcionando corretamente. Faremos isso adicionando uma função sleep (para adicionar um atraso de tempo) e uma solicitação de airdrop. Na linha 6, antes do bloco de código Async, adicione:

const sleep = (ms:number) => {
    return new Promise(resolve => setTimeout(resolve, ms));
}
Enter fullscreen mode Exit fullscreen mode

E então, dentro do seu bloco de código Async após o log "Starting web socket", adicione esta chamada do airdrop:

    await sleep(10000); //Aguarde 10 segundos para o teste de soquete
    await solanaConnection.requestAirdrop(ACCOUNT_TO_WATCH, LAMPORTS_PER_SOL);
Enter fullscreen mode Exit fullscreen mode

Seu código irá esperar efetivamente 10 segundos após a inicialização do soquete (socket) para solicitar um airdrop para a carteira (observação: isso funcionará apenas na rede de desenvolvimento e na rede de teste (testnet)).

Nosso código agora se parece com isso:

import { Connection, PublicKey, LAMPORTS_PER_SOL, } from "@solana/web3.js";

const WSS_ENDPOINT = 'wss://example.solana-devnet.quiknode.pro/000/'; // substitua pelo seu URL
const HTTP_ENDPOINT = 'https://example.solana-devnet.quiknode.pro/000/'; // substitua pelo seu URL
const solanaConnection = new Connection(HTTP_ENDPOINT, { wsEndpoint: WSS_ENDPOINT });
const sleep = (ms:number) => {
    return new Promise(resolve => setTimeout(resolve, ms));
}

(async () => {
    const ACCOUNT_TO_WATCH = new PublicKey('vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg');
    const subscriptionId = await solanaConnection.onAccountChange(
        ACCOUNT_TO_WATCH,
        (updatedAccountInfo) =>
            console.log(`---Event Notification for ${ACCOUNT_TO_WATCH.toString()}--- \nNew Account Balance:`, updatedAccountInfo.lamports / LAMPORTS_PER_SOL, ' SOL'),
        "confirmed"
    );
    console.log('Starting web socket, subscription ID: ', subscriptionId);
    await sleep(10000); //Aguarde 10 segundos para o teste de soquete
    await solanaConnection.requestAirdrop(ACCOUNT_TO_WATCH, LAMPORTS_PER_SOL);
})()
Enter fullscreen mode Exit fullscreen mode

Inicialize seu soquete!

Vamos aos testes. Em seu terminal, você pode inserir ts-node app.ts para iniciar seu web socket! Após cerca de 10 segundos, você deverá ver um log de retorno de chamada do terminal como este:

​​solana-subscriptions % ts-node app.ts
Starting web socket, subscription ID:  0
---Event Notification for vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg---
New Account Balance: 88790.51694709  SOL
Enter fullscreen mode Exit fullscreen mode

Excelente! Você deve observar que seu aplicativo permanece aberto mesmo após a notificação do evento. Isso ocorre porque nossa subscrição ainda está ouvindo alterações em nossa conta. Precisamos de uma maneira de cancelar a subscrição do ouvinte. Pressione Ctrl^C para interromper o processo.

Cancelar Subscrição do Ouvinte de Alteração de Conta

A Solana criou um método interno que podemos usar para cancelar a subscrição do nosso ouvinte de mudança de conta, removeAccountChangeListener. O método aceita um subscriptionId (número) válido como seu único parâmetro. Dentro do bloco Async, adicione outra função sleep após o airdrop para dar tempo para a transação processar e, em seguida, chame removeAccountChangeListener:

await sleep(10000); //Aguarde 10 segundos para o teste de soquete
    await solanaConnection.removeAccountChangeListener(subscriptionId);
    console.log(`Websocket ID: ${subscriptionId} closed.`);
Enter fullscreen mode Exit fullscreen mode

Agora execute seu código novamente e você verá a mesma sequência seguida pelo fechamento do Websocket:

solana-subscriptions % ts-node app.ts
Starting web socket, subscription ID:  0
---Event Notification for vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg---
New Account Balance: 88791.51694709  SOL
Websocket ID: 0 closed.
Enter fullscreen mode Exit fullscreen mode

Ótimo trabalho! Como você pode ver, isso pode ser útil se você quiser desabilitar um ouvinte depois que algo acontecer (por exemplo, tempo decorrido, certo limite alcançado, número de notificações, etc.).

Publicamos o código final deste script em nosso repositório do Github para sua referência.

Outras Subscrições de Websocket da Solana

A Solana tem vários outros métodos semelhantes de subscrição/cancelamento de Websocket que também são úteis. Vamos descrevê-los brevemente nesta seção.

  • onProgramAccountChange: Registre um retorno de chamada para ser chamado sempre que as contas pertencentes ao programa especificado forem alteradas. Passe a PublicKey (chave pública) de um Programa e um array opcional de filtros de conta. Entre outras coisas, isso pode ser útil para rastrear alterações na conta de tokens de um usuário. Cancele a subscrição com removeProgramAccountChangeListener.
  • onLogs: Registre um retorno de chamada a ser invocado sempre que os logs são emitidos – pode ser usado de forma semelhante a onAccountChange passando uma PublicKey válida. O retorno de chamada retornará o ID da transação recente. Cancele a subscrição com removeOnLogsListener.
  • onSlotChange: Registre um retorno de chamada a ser invocado nas alterações de slot. Somente uma função de retorno de chamada é passada para esse método. Cancele a subscrição com removeSlotChangeListener.
  • onSignature: Registre um retorno de chamada a ser invocado nas atualizações de assinatura ao passar uma Assinatura de Transação válida. O retorno de chamada retornará independentemente de a transação ter sofrido um erro ou não. Cancele a subscrição com removeSignatureListener.
  • onRootChange: Registre um retorno de chamada para ser invocado após alterações na raiz. Somente uma função de retorno de chamada é passada para esse método. Cancele a subscrição com removeRootChangeListener.

Observação: todos os métodos de cancelamento de subscrição exigem um parâmetro subscriptionId (número). Você pode encontrar mais informações sobre esses métodos em nossa documentação, em quicknode.com/docs/solana. Sinta-se à vontade para experimentar cada uma delas, fazendo pequenas modificações em app.js para experimentar algumas dessas outras subscrições.

Conclusão

Bom trabalho! Agora você deve saber como usar as subscrições de Websocket na Solana. Como você está usando os Websockets da Solana? Adoraríamos ver o que você está criando! Compartilhe seu aplicativo conosco no Discord ou no Twitter. Se você tiver algum comentário ou pergunta sobre este guia, adoraríamos ouvi-lo!

Para saber mais, confira alguns de nossos outros tutoriais sobre a Solana aqui e, se você se divertiu com as subscrições de Websocket, considere subscrever a nossa newsletter.

Artigo original publicado por Quicknode. Traduzido por Paulinho Giovannini.

Latest comments (0)