gill

Create a Solana client

Create a client connection to the Solana blockchain to perform Solana RPC requests.

Setting up a client connection to the Solana blockchain is a very important part of your application. This client connection is how your application will be sending and receiving data from the Solana JSON RPC layer, including fetching accounts and sending transactions.

Gill considers the "Solana client" to be (at a minimum) the following pieces:

  • rpc - used to interact with the your Solana JSON RPC provider (typically via HTTP)
  • rpcSubscriptions - used to interact with the Solana RPC over websockets
  • sendAndConfirmTransaction - used to send and confirm a Solana transaction over the RPC connections

If you are familiar with the Connection class from the older @solana/web3.js library, gill's createSolanaClient is similar. But more bare-bones and lightweight.

Most client applications will need to initialize the above functionality in their codebase. Within gill, there are two primary ways to create a Solana client:

  1. using the createSolanaClient() function (recommended in order to reduce application boilerplate)
  2. manually initialize them all individually

Create a Solana RPC connection

Create the Solana client connections (i.e. rpc and rpcSubscriptions) from any RPC URL or standard Solana network moniker (i.e. devnet, localnet, mainnet etc) using the createSolanaClient() function.

import {  } from "gill";
 
const { , ,  } = ({
  : "mainnet",
});

Using the Solana moniker will connect to the public RPC endpoints. These are subject to rate limits and should not be used in production applications. Applications should find their own RPC provider and use the URL provided by them.

Solana client for localnet

Developers can also connect to a local test validator (like solana-test-validator) running on your computer.

To create a Solana client for your local test validator:

import {  } from "gill";
 
const { , ,  } = ({
  : "localnet",
});

The urlOrMoniker value of localnet will utilize the default test validator address and port of http://127.0.0.1:8899. If you need to connect to a different address/port, then simply pass in its entire URL. See custom RPC URL below.

Solana client for a custom RPC URL

To create an RPC client for an custom RPC provider or service:

import {  } from "gill";
 
const { , ,  } = ({
  : "https://private-solana-rpc-provider.com",
});

Making Solana RPC calls

After you have a Solana rpc connection, you can make all the JSON RPC method calls directly off of it. Most commonly to get the latest blockhash or fetching a specific account.

import {  } from "gill";
 
const {  } = ({ : "devnet" });
 
// get slot
const  = await .().();
 
// get the latest blockhash
const { :  } = await .().();

The rpc client requires you to call .send() on the RPC method in order to actually send the request to your RPC provider and get a response.

Destructure and renaming response values

Many of the Solana RPC responses will return a generic value attribute containing the typed response payload. It is a common practice to destructure this generic value into a more aptly named variable, such as latestBlockhash (as demonstrated in the example below).

Get the latest blockhash

On Solana, the latest blockhash is uses as a sort of "recent timestamp" check within the transaction.

To get the latest blockhash from your RPC:

import {  } from "gill";
 
const {  } = ({ : "devnet" });
 
// get the latest blockhash
const { :  } = await .().();

Pro tip

Only request this value just before you are going to use it your code. Since latest blockhashes are only valid for approximately 1-2 minutes, requesting it at the latest possible time in your codebase can help improve transaction landing rates.

Fetch an account

All the data stored on the Solana blockchain is stored in accounts, including native SOL balance, tokens, and programs. The structure of an account's data and associated metadata information is called an AccountInfo.

To get an account's AccountInfo from your RPC:

import { ,  } from "gill";
 
const {  } = ({ : "devnet" });
 
const  = ("nick6zJc6HpW3kfBm4xS2dmbuVRyb5F3AnUvj5ymzR5");
 
// get the `AccountInfo` with (default) `base58` encoding for the data
const { :  } = await .().();

By default, the getAccountInfo RPC method will utilize the base58 encoding for the data within the account itself. This is fine for accounts with small amounts of data stored in them, but fetching accounts with larger amounts of data will result in an error with the base58 encoding.

It is strongly recommended to utilize base64 encoding when fetching accounts from the blockchain to avoid the common errors when fetching with the default base58 encoding.

import { ,  } from "gill";
 
const {  } = ({ : "devnet" });
 
const  = ("nick6zJc6HpW3kfBm4xS2dmbuVRyb5F3AnUvj5ymzR5");
 
// get the `AccountInfo` with `base64` encoding for the data
const { :  } = await 
  .(, { : "base64" })
  .();

An even better solution is to utilize the fetchEncodedAccount() function to fetch accounts, which always utilizes the base64 encoding.

import { , ,  } from "gill";
 
const {  } = ({ : "devnet" });
 
const  = ("nick6zJc6HpW3kfBm4xS2dmbuVRyb5F3AnUvj5ymzR5");
 
const  = await (, );

These encoded accounts can then easily be decoded by the correct Decoder for the structure of the account's data.

Using AbortControllers

You can also include custom configuration settings on your RPC calls, like using a JavaScript AbortController, by passing them into send():

import {  } from "gill";
 
const {  } = ({ : "devnet" });
 
// Create a new AbortController.
const  = new ();
 
// Abort the request when the user navigates away from the current page.
function () {
  .();
}
 
// The request will be aborted if and only if the user navigates away from the page.
const  = await .().({ : . });

On this page