Categorygithub.com/RoboticAgile/solana-go
modulepackage
0.0.2
Repository: https://github.com/roboticagile/solana-go.git
Documentation: pkg.go.dev

# README

Solana SDK library for Go

GoDoc GitHub tag (latest SemVer pre-release) Build Status TODOs Go Report Card

Go library to interface with Solana JSON RPC and WebSocket interfaces.

More contracts to come.

If you're using/developing Solana programs written in Anchor Framework, you can use anchor-go to generate Golang clients

If you're looking for a SERUM library, you can check out gagliardetto/serum-go (./programs/serum is deprecated.)

Future Development

solana-go is exclusively supported by my own time (which is money).

If my work has been useful in building your for-profit services/infra/bots/etc., consider donating at DkP56dVfmTTN58oy6hDpRLtw4RMEFMmEWs8umN3Kg8vp

Thanks!

Contents

Features

  • Full JSON RPC API
  • Full WebSocket JSON streaming API
  • Wallet, account, and keys management
  • Clients for native programs
    • system
    • config
    • stake
    • vote
    • BPF Loader
    • Secp256k1
  • Clients for Solana Program Library (SPL)
  • Client for Serum
  • Metaplex:
    • auction
    • metaplex
    • token-metadata
    • token-vault
    • nft-candy-machine
  • More programs

Current development status

There is currently no stable release. The SDK is actively developed and latest is v1.5.0 which is an alpha release.

The RPC and WS client implementation is based on this RPC spec.

Note

  • solana-go is in active development, so all APIs are subject to change.
  • This code is unaudited. Use at your own risk.

Requirements

  • Go 1.16 or later

Installation

$ cd my-project
$ go get github.com/RoboticAgile/[email protected]

Pretty-Print transactions/instructions

pretty-printed

Instructions can be pretty-printed with the String() method on a Transaction:

tx, err := solana.NewTransaction(
  []solana.Instruction{
    system.NewTransferInstruction(
      amount,
      accountFrom.PublicKey(),
      accountTo,
    ).Build(),
  },
  recent.Value.Blockhash,
  solana.TransactionPayer(accountFrom.PublicKey()),
)

...

// Pretty print the transaction:
fmt.Println(tx.String())
// OR you can choose a destination and a title:
// tx.EncodeTree(text.NewTreeEncoder(os.Stdout, "Transfer SOL"))

SendAndConfirmTransaction

You can wait for a transaction confirmation using the github.com/RoboticAgile/solana-go/rpc/sendAndConfirmTransaction package tools (for a complete example: see here)

// Send transaction, and wait for confirmation:
sig, err := confirm.SendAndConfirmTransaction(
  context.TODO(),
  rpcClient,
  wsClient,
  tx,
)
if err != nil {
  panic(err)
}
spew.Dump(sig)

The above command will send the transaction, and wait for its confirmation.

Parse/decode an instruction from a transaction

package main

import (
  "context"
  "encoding/base64"
  "os"
  "reflect"

  "github.com/davecgh/go-spew/spew"
  bin "github.com/gagliardetto/binary"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/programs/system"
  "github.com/RoboticAgile/solana-go/rpc"
  "github.com/RoboticAgile/solana-go/text"
)

func main() {
  exampleFromGetTransaction()
}

func exampleFromBase64() {
  encoded := "AfjEs3XhTc3hrxEvlnMPkm/cocvAUbFNbCl00qKnrFue6J53AhEqIFmcJJlJW3EDP5RmcMz+cNTTcZHW/WJYwAcBAAEDO8hh4VddzfcO5jbCt95jryl6y8ff65UcgukHNLWH+UQGgxCGGpgyfQVQV02EQYqm4QwzUt2qf9f1gVLM7rI4hwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6ANIF55zOZWROWRkeh+lExxZBnKFqbvIxZDLE7EijjoBAgIAAQwCAAAAOTAAAAAAAAA="

  data, err := base64.StdEncoding.DecodeString(encoded)
  if err != nil {
    panic(err)
  }

  // parse transaction:
  tx, err := solana.TransactionFromDecoder(bin.NewBinDecoder(data))
  if err != nil {
    panic(err)
  }

  decodeSystemTransfer(tx)
}

func exampleFromGetTransaction() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  txSig := solana.MustSignatureFromBase58("3pByJJ2ff7EQANKd2bgetmnYQxknk3QUib1xLMnrg6aCvg5hS78peaGMoceC9AFckomqrsgo38DpzrG2LPW9zj3g")
  {
    out, err := client.GetTransaction(
      context.TODO(),
      txSig,
      &rpc.GetTransactionOpts{
        Encoding: solana.EncodingBase64,
      },
    )
    if err != nil {
      panic(err)
    }

    tx, err := solana.TransactionFromDecoder(bin.NewBinDecoder(out.Transaction.GetBinary()))
    if err != nil {
      panic(err)
    }

    decodeSystemTransfer(tx)
  }
}

func decodeSystemTransfer(tx *solana.Transaction) {
  spew.Dump(tx)

  // Get (for example) the first instruction of this transaction
  // which we know is a `system` program instruction:
  i0 := tx.Message.Instructions[0]

  // Find the program address of this instruction:
  progKey, err := tx.ResolveProgramIDIndex(i0.ProgramIDIndex)
  if if err != nil {
    panic(err)
  }

  // FInd the accounts of this instruction:
  accounts := i0.ResolveInstructionAccounts(&tx.Message)

  // Feed the accounts and data to the system program parser
  // OR see below for alternative parsing when you DON'T know
  // what program the instruction is for / you don't have a parser.
  inst, err := system.DecodeInstruction(accounts, i0.Data)
  if err != nil {
    panic(err)
  }

  // inst.Impl contains the specific instruction type (in this case, `inst.Impl` is a `*system.Transfer`)
  spew.Dump(inst)
  if _, ok := inst.Impl.(*system.Transfer); !ok {
    panic("the instruction is not a *system.Transfer")
  }

  // OR
  {
    // There is a more general instruction decoder: `solana.DecodeInstruction`.
    // But before you can use `solana.DecodeInstruction`,
    // you must register a decoder for each program ID beforehand
    // by using `solana.RegisterInstructionDecoder` (all solana-go program clients do it automatically with the default program IDs).
    decodedInstruction, err := solana.DecodeInstruction(
      progKey,
      accounts,
      i0.Data,
    )
    if err != nil {
      panic(err)
    }
    // The returned `decodedInstruction` is the decoded instruction.
    spew.Dump(decodedInstruction)

    // decodedInstruction == inst
    if !reflect.DeepEqual(inst, decodedInstruction) {
      panic("they are NOT equal (this would never happen)")
    }

    // To register other (not yet registered decoders), you can add them with
    // `solana.RegisterInstructionDecoder` function.
  }

  {
    // pretty-print whole transaction:
    _, err := tx.EncodeTree(text.NewTreeEncoder(os.Stdout, text.Bold("TEST TRANSACTION")))
    if err != nil {
      panic(err)
    }
  }
}

Borsh encoding/decoding

You can use the github.com/gagliardetto/binary package for encoding/decoding borsh-encoded data:

Decoder:

  resp, err := client.GetAccountInfo(
    context.TODO(),
    pubKey,
  )
  if err != nil {
    panic(err)
  }

  borshDec := bin.NewBorshDecoder(resp.Value.Data.GetBinary())
  var meta token_metadata.Metadata
  err = borshDec.Decode(&meta)
  if err != nil {
    panic(err)
  }

Encoder:

buf := new(bytes.Buffer)
borshEncoder := bin.NewBorshEncoder(buf)
err := borshEncoder.Encode(meta)
if err != nil {
  panic(err)
}
// fmt.Print(buf.Bytes())

ZSTD account data encoding

You can request account data to be encoded with base64+zstd in the Encoding parameter:

resp, err := client.GetAccountInfoWithOpts(
  context.TODO(),
  pubKey,
  &rpc.GetAccountInfoOpts{
    Encoding:   solana.EncodingBase64Zstd,
    Commitment: rpc.CommitmentFinalized,
  },
)
if err != nil {
  panic(err)
}
spew.Dump(resp)

var mint token.Mint
err = bin.NewDecoder(resp.Value.Data.GetBinary()).Decode(&mint)
if err != nil {
  panic(err)
}
spew.Dump(mint)

Working with rate-limited RPC providers

package main

import (
  "context"

  "golang.org/x/time/rate"
  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  cluster := rpc.MainNetBeta
  client := rpc.NewWithLimiter(
    cluster.RPC,
    rate.Every(time.Second), // time frame
    5, // limit of requests per time frame
  )

  out, err := client.GetVersion(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

Custom Headers for authenticating with RPC providers

package main

import (
  "context"

  "golang.org/x/time/rate"
  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  cluster := rpc.MainNetBeta
  client := rpc.NewWithHeaders(
    cluster.RPC,
    map[string]string{
      "x-api-key": "...",
    },
  )

  out, err := client.GetVersion(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

The data will AUTOMATICALLY get decoded and returned (the right decoder will be used) when you call the resp.Value.Data.GetBinary() method.

Timeouts and Custom HTTP Clients

You can use a timeout context:

ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
acc, err := rpcClient.GetAccountInfoWithOpts(
  ctx,
  accountID,
  &rpc.GetAccountInfoOpts{
    Commitment: rpc.CommitmentProcessed,
  },
)

Or you can initialize the RPC client using a custom HTTP client using rpc.NewWithCustomRPCClient:

import (
  "net"
  "net/http"
  "time"

  "github.com/RoboticAgile/solana-go/rpc"
  "github.com/RoboticAgile/solana-go/rpc/jsonrpc"
)

func NewHTTPTransport(
  timeout time.Duration,
  maxIdleConnsPerHost int,
  keepAlive time.Duration,
) *http.Transport {
  return &http.Transport{
    IdleConnTimeout:     timeout,
    MaxIdleConnsPerHost: maxIdleConnsPerHost,
    Proxy:               http.ProxyFromEnvironment,
    Dial: (&net.Dialer{
      Timeout:   timeout,
      KeepAlive: keepAlive,
    }).Dial,
  }
}

// NewHTTP returns a new Client from the provided config.
func NewHTTP(
  timeout time.Duration,
  maxIdleConnsPerHost int,
  keepAlive time.Duration,
) *http.Client {
  tr := NewHTTPTransport(
    timeout,
    maxIdleConnsPerHost,
    keepAlive,
  )

  return &http.Client{
    Timeout:   timeout,
    Transport: tr,
  }
}

// NewRPC creates a new Solana JSON RPC client.
func NewRPC(rpcEndpoint string) *rpc.Client {
  var (
    defaultMaxIdleConnsPerHost = 10
    defaultTimeout             = 25 * time.Second
    defaultKeepAlive           = 180 * time.Second
  )
  opts := &jsonrpc.RPCClientOpts{
    HTTPClient: NewHTTP(
      defaultTimeout,
      defaultMaxIdleConnsPerHost,
      defaultKeepAlive,
    ),
  }
  rpcClient := jsonrpc.NewClientWithOpts(rpcEndpoint, opts)
  return rpc.NewWithCustomRPCClient(rpcClient)
}

Examples

Create account (wallet)

package main

import (
  "context"
  "fmt"

  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  // Create a new account:
  account := solana.NewWallet()
  fmt.Println("account private key:", account.PrivateKey)
  fmt.Println("account public key:", account.PublicKey())

  // Create a new RPC client:
  client := rpc.New(rpc.TestNet_RPC)

  // Airdrop 5 SOL to the new account:
  out, err := client.RequestAirdrop(
    context.TODO(),
    account.PublicKey(),
    solana.LAMPORTS_PER_SOL*1,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  fmt.Println("airdrop transaction signature:", out)
}

Load/parse private and public keys

{
  // Load private key from a json file generated with
  // $ solana-keygen new --outfile=standard.solana-keygen.json
  privateKey, err := solana.PrivateKeyFromSolanaKeygenFile("/path/to/standard.solana-keygen.json")
  if err != nil {
    panic(err)
  }
  fmt.Println("private key:", privateKey.String())
  // To get the public key, you need to call the `PublicKey()` method:
  publicKey := privateKey.PublicKey()
  // To get the base58 string of a public key, you can call the `String()` method:
  fmt.Println("public key:", publicKey.String())
}

{
  // Load private key from base58:
  {
    privateKey, err := solana.PrivateKeyFromBase58("66cDvko73yAf8LYvFMM3r8vF5vJtkk7JKMgEKwkmBC86oHdq41C7i1a2vS3zE1yCcdLLk6VUatUb32ZzVjSBXtRs")
    if err != nil {
      panic(err)
    }
    fmt.Println("private key:", privateKey.String())
    fmt.Println("public key:", privateKey.PublicKey().String())
  }
  // OR:
  {
    privateKey := solana.MustPrivateKeyFromBase58("66cDvko73yAf8LYvFMM3r8vF5vJtkk7JKMgEKwkmBC86oHdq41C7i1a2vS3zE1yCcdLLk6VUatUb32ZzVjSBXtRs")
    _ = privateKey
  }
}

{
  // Generate a new key pair:
  {
    privateKey, err := solana.NewRandomPrivateKey()
    if err != nil {
      panic(err)
    }
    _ = privateKey
  }
  {
    { // Generate a new private key (a Wallet struct is just a wrapper around a private key)
      account := solana.NewWallet()
      _ = account
    }
  }
}

{
  // Parse a public key from a base58 string:
  {
    publicKey, err := solana.PublicKeyFromBase58("F8UvVsKnzWyp2nF8aDcqvQ2GVcRpqT91WDsAtvBKCMt9")
    if err != nil {
      panic(err)
    }
    _ = publicKey
  }
  // OR:
  {
    publicKey := solana.MustPublicKeyFromBase58("F8UvVsKnzWyp2nF8aDcqvQ2GVcRpqT91WDsAtvBKCMt9")
    _ = publicKey
  }
}

Transfer Sol from one wallet to another wallet

package main

import (
  "context"
  "fmt"
  "os"
  "time"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/programs/system"
  "github.com/RoboticAgile/solana-go/rpc"
  confirm "github.com/RoboticAgile/solana-go/rpc/sendAndConfirmTransaction"
  "github.com/RoboticAgile/solana-go/rpc/jsonrpc"
  "github.com/RoboticAgile/solana-go/rpc/ws"
  "github.com/RoboticAgile/solana-go/text"
)

func main() {
  // Create a new RPC client:
  rpcClient := rpc.New(rpc.DevNet_RPC)

  // Create a new WS client (used for confirming transactions)
  wsClient, err := ws.Connect(context.Background(), rpc.DevNet_WS)
  if err != nil {
    panic(err)
  }

  // Load the account that you will send funds FROM:
  accountFrom, err := solana.PrivateKeyFromSolanaKeygenFile("/path/to/.config/solana/id.json")
  if err != nil {
    panic(err)
  }
  fmt.Println("accountFrom private key:", accountFrom)
  fmt.Println("accountFrom public key:", accountFrom.PublicKey())

  // The public key of the account that you will send sol TO:
  accountTo := solana.MustPublicKeyFromBase58("TODO")
  // The amount to send (in lamports);
  // 1 sol = 1000000000 lamports
  amount := uint64(3333)

  if true {
    // Airdrop 5 sol to the account so it will have something to transfer:
    out, err := rpcClient.RequestAirdrop(
      context.TODO(),
      accountFrom.PublicKey(),
      solana.LAMPORTS_PER_SOL*1,
      rpc.CommitmentFinalized,
    )
    if err != nil {
      panic(err)
    }
    fmt.Println("airdrop transaction signature:", out)
    time.Sleep(time.Second * 5)
  }
  //---------------

  recent, err := rpcClient.GetRecentBlockhash(context.TODO(), rpc.CommitmentFinalized)
  if err != nil {
    panic(err)
  }

  tx, err := solana.NewTransaction(
    []solana.Instruction{
      system.NewTransferInstruction(
        amount,
        accountFrom.PublicKey(),
        accountTo,
      ).Build(),
    },
    recent.Value.Blockhash,
    solana.TransactionPayer(accountFrom.PublicKey()),
  )
  if err != nil {
    panic(err)
  }

  _, err = tx.Sign(
    func(key solana.PublicKey) *solana.PrivateKey {
      if accountFrom.PublicKey().Equals(key) {
        return &accountFrom
      }
      return nil
    },
  )
  if err != nil {
    panic(fmt.Errorf("unable to sign transaction: %w", err))
  }
  spew.Dump(tx)
  // Pretty print the transaction:
  tx.EncodeTree(text.NewTreeEncoder(os.Stdout, "Transfer SOL"))

  // Send transaction, and wait for confirmation:
  sig, err := confirm.SendAndConfirmTransaction(
    context.TODO(),
    rpcClient,
    wsClient,
    tx,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(sig)

  // Or just send the transaction WITHOUT waiting for confirmation:
  // sig, err := rpcClient.SendTransactionWithOpts(
  //   context.TODO(),
  //   tx,
  //   false,
  //   rpc.CommitmentFinalized,
  // )
  // if err != nil {
  //   panic(err)
  // }
  // spew.Dump(sig)
}

RPC usage examples

RPC Methods

index > RPC > GetAccountInfo

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  bin "github.com/gagliardetto/binary"
  solana "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/programs/token"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.MainNetBeta_RPC
  client, _ := rpc.new(endpoint)

  {
    pubKey := solana.MustPublicKeyFromBase58("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt") // serum token
    // basic usage
    resp, err := client.GetAccountInfo(
      context.TODO(),
      pubKey,
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(resp)

    var mint token.Mint
    // Account{}.Data.GetBinary() returns the *decoded* binary data
    // regardless the original encoding (it can handle them all).
    err = bin.NewDecoder(resp.Value.Data.GetBinary()).Decode(&mint)
    if err != nil {
      panic(err)
    }
    spew.Dump(mint)
    // NOTE: The supply is mint.Supply, with the mint.Decimals:
    // mint.Supply = 9998022451607088
    // mint.Decimals = 6
    // ... which means that the supply is 9998022451.607088
  }
  {
    // Or you can use `GetAccountDataInto` which does all of the above in one call:
    pubKey := solana.MustPublicKeyFromBase58("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt") // serum token
    var mint token.Mint
    // Get the account, and decode its data into the provided mint object:
    err := client.GetAccountDataInto(
      context.TODO(),
      pubKey,
      &mint,
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(mint)
  }
  {
    // // Or you can use `GetAccountDataBorshInto` which does all of the above in one call but for borsh-encoded data:
    // var metadata token_metadata.Metadata
    // // Get the account, and decode its data into the provided metadata object:
    // err := client.GetAccountDataBorshInto(
    //   context.TODO(),
    //   pubKey,
    //   &metadata,
    // )
    // if err != nil {
    //   panic(err)
    // }
    // spew.Dump(metadata)
  }
  {
    pubKey := solana.MustPublicKeyFromBase58("4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R") // raydium token
    // advanced usage
    resp, err := client.GetAccountInfoWithOpts(
      context.TODO(),
      pubKey,
      // You can specify more options here:
      &rpc.GetAccountInfoOpts{
        Encoding:   solana.EncodingBase64Zstd,
        Commitment: rpc.CommitmentFinalized,
        // You can get just a part of the account data by specify a DataSlice:
        // DataSlice: &rpc.DataSlice{
        //  Offset: pointer.ToUint64(0),
        //  Length: pointer.ToUint64(1024),
        // },
      },
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(resp)

    var mint token.Mint
    err = bin.NewDecoder(resp.Value.Data.GetBinary()).Decode(&mint)
    if err != nil {
      panic(err)
    }
    spew.Dump(mint)
  }
}

index > RPC > GetBalance

package main

import (
  "context"
  "fmt"
  "math/big"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.MainNetBeta_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("7xLk17EQQ5KLDLDe44wCmupJKJjTGd8hs3eSVVhCx932")
  out, err := client.GetBalance(
    context.TODO(),
    pubKey,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
  spew.Dump(out.Value) // total lamports on the account; 1 sol = 1000000000 lamports

  var lamportsOnAccount = new(big.Float).SetUint64(uint64(out.Value))
  // Convert lamports to sol:
  var solBalance = new(big.Float).Quo(lamportsOnAccount, new(big.Float).SetUint64(solana.LAMPORTS_PER_SOL))

  // WARNING: this is not a precise conversion.
  fmt.Println("◎", solBalance.Text('f', 10))
}

index > RPC > GetBlock

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetRecentBlockhash(context.TODO(), rpc.CommitmentFinalized)
  if err != nil {
    panic(err)
  }

  {
    out, err := client.GetBlock(context.TODO(), uint64(example.Context.Slot))
    if err != nil {
      panic(err)
    }
    // spew.Dump(out) // NOTE: This generates a lot of output.
    spew.Dump(len(out.Transactions))
  }

  {
    includeRewards := false
    out, err := client.GetBlockWithOpts(
      context.TODO(),
      uint64(example.Context.Slot),
      // You can specify more options here:
      &rpc.GetBlockOpts{
        Encoding:   solana.EncodingBase64,
        Commitment: rpc.CommitmentFinalized,
        // Get only signatures:
        TransactionDetails: rpc.TransactionDetailsSignatures,
        // Exclude rewards:
        Rewards: &includeRewards,
      },
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
}

index > RPC > GetBlockCommitment

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetRecentBlockhash(context.TODO(), rpc.CommitmentFinalized)
  if err != nil {
    panic(err)
  }

  out, err := client.GetBlockCommitment(
    context.TODO(),
    uint64(example.Context.Slot),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetBlockHeight

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetBlockHeight(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetBlockProduction

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  {
    out, err := client.GetBlockProduction(context.TODO())
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
  {
    out, err := client.GetBlockProductionWithOpts(
      context.TODO(),
      &rpc.GetBlockProductionOpts{
        Commitment: rpc.CommitmentFinalized,
        // Range: &rpc.SlotRangeRequest{
        //  FirstSlot: XXXXXX,
        //  Identity:  solana.MustPublicKeyFromBase58("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),
        // },
      },
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
}

index > RPC > GetBlockTime

package main

import (
  "context"
  "time"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetRecentBlockhash(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }

  out, err := client.GetBlockTime(
    context.TODO(),
    uint64(example.Context.Slot),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
  spew.Dump(out.Time().Format(time.RFC1123))
}

index > RPC > GetBlocks

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetRecentBlockhash(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }

  endSlot := uint64(example.Context.Slot)
  out, err := client.GetBlocks(
    context.TODO(),
    uint64(example.Context.Slot-3),
    &endSlot,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetBlocksWithLimit

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetRecentBlockhash(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }

  limit := uint64(4)
  out, err := client.GetBlocksWithLimit(
    context.TODO(),
    uint64(example.Context.Slot-10),
    limit,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetClusterNodes

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetClusterNodes(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetConfirmedBlock

package main

import (
  "context"

  "github.com/AlekSi/pointer"
  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetRecentBlockhash(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }

  { // deprecated and is going to be removed in solana-core v1.8
    out, err := client.GetConfirmedBlock(
      context.TODO(),
      uint64(example.Context.Slot),
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
  {
    slot := uint64(example.Context.Slot)
    out, err := client.GetConfirmedBlockWithOpts(
      context.TODO(),
      slot,
      // You can specify more options here:
      &rpc.GetConfirmedBlockOpts{
        Encoding:   solana.EncodingBase64,
        Commitment: rpc.CommitmentFinalized,
        // Get only signatures:
        TransactionDetails: rpc.TransactionDetailsSignatures,
        // Exclude rewards:
        Rewards: pointer.ToBool(false),
      },
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
}

index > RPC > GetConfirmedBlocks

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetRecentBlockhash(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }

  {
    endSlot := uint64(example.Context.Slot)
    // deprecated and is going to be removed in solana-core v1.8
    out, err := client.GetConfirmedBlocks(
      context.TODO(),
      uint64(example.Context.Slot-3),
      &endSlot,
      rpc.CommitmentFinalized,
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
}

index > RPC > GetConfirmedBlocksWithLimit

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetRecentBlockhash(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }

  limit := uint64(3)
  { // deprecated and is going to be removed in solana-core v1.8
    out, err := client.GetConfirmedBlocksWithLimit(
      context.TODO(),
      uint64(example.Context.Slot-10),
      limit,
      rpc.CommitmentFinalized,
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
}

index > RPC > GetConfirmedSignaturesForAddress2

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt") // serum token
  {
    // deprecated and is going to be removed in solana-core v1.8
    out, err := client.GetConfirmedSignaturesForAddress2(
      context.TODO(),
      pubKey,
      // TODO:
      nil,
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
}

index > RPC > GetConfirmedTransaction

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt") // serum token
  // Let's get a valid transaction to use in the example:
  example, err := client.GetConfirmedSignaturesForAddress2(
    context.TODO(),
    pubKey,
    nil,
  )
  if err != nil {
    panic(err)
  }

  out, err := client.GetConfirmedTransaction(
    context.TODO(),
    example[0].Signature,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetEpochInfo

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetEpochInfo(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetEpochSchedule

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetEpochSchedule(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetFeeCalculatorForBlockhash

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetRecentBlockhash(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }

  out, err := client.GetFeeCalculatorForBlockhash(
    context.TODO(),
    example.Value.Blockhash,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetFeeRateGovernor

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetFeeRateGovernor(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetFees

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetFees(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetFeeForMessage

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetFeeForMessage(
    context.Background(),
    "AQABAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAA",
    rpc.CommitmentProcessed,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(example)
}

index > RPC > GetFirstAvailableBlock

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetFirstAvailableBlock(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetGenesisHash

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetGenesisHash(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetHealth

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetHealth(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
  spew.Dump(out == rpc.HealthOk)
}

index > RPC > GetHighestSnapshotSlot

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetHighestSnapshotSlot(
    context.Background(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(example)
}

index > RPC > GetLatestBlockhash

NEW: This method is only available in solana-core v1.9 or newer. Please use getRecentBlockhash for solana-core v1.8

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  example, err := client.GetLatestBlockhash(
    context.Background(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(example)
}

index > RPC > GetIdentity

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetIdentity(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetInflationGovernor

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetInflationGovernor(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetInflationRate

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetInflationRate(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetInflationReward

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("6dmNQ5jwLeLk5REvio1JcMshcbvkYMwy26sJ8pbkvStu")

  out, err := client.GetInflationReward(
    context.TODO(),
    []solana.PublicKey{
      pubKey,
    },
    &rpc.GetInflationRewardOpts{
      Commitment: rpc.CommitmentFinalized,
    },
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetLargestAccounts

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetLargestAccounts(
    context.TODO(),
    rpc.CommitmentFinalized,
    rpc.LargestAccountsFilterCirculating,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetLeaderSchedule

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetLeaderSchedule(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out) // NOTE: this creates a lot of output
}

index > RPC > GetMaxRetransmitSlot

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetMaxRetransmitSlot(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetMaxShredInsertSlot

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetMaxShredInsertSlot(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetMinimumBalanceForRentExemption

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  dataSize := uint64(1024 * 9)
  out, err := client.GetMinimumBalanceForRentExemption(
    context.TODO(),
    dataSize,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetMultipleAccounts

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.MainNetBeta_RPC
  client, _ := rpc.new(endpoint)

  {
    out, err := client.GetMultipleAccounts(
      context.TODO(),
      solana.MustPublicKeyFromBase58("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt"),  // serum token
      solana.MustPublicKeyFromBase58("4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R"), // raydium token
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
  {
    out, err := client.GetMultipleAccountsWithOpts(
      context.TODO(),
      []solana.PublicKey{solana.MustPublicKeyFromBase58("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt"), // serum token
        solana.MustPublicKeyFromBase58("4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R"), // raydium token
      },
      &rpc.GetMultipleAccountsOpts{
        Encoding:   solana.EncodingBase64Zstd,
        Commitment: rpc.CommitmentFinalized,
        // You can get just a part of the account data by specify a DataSlice:
        // DataSlice: &rpc.DataSlice{
        //  Offset: pointer.ToUint64(0),
        //  Length: pointer.ToUint64(1024),
        // },
      },
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
  }
}

index > RPC > GetProgramAccounts

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetProgramAccounts(
    context.TODO(),
    solana.MustPublicKeyFromBase58("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(len(out))
  spew.Dump(out) // NOTE: this can generate a lot of output
}

index > RPC > GetRecentBlockhash

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  recent, err := client.GetRecentBlockhash(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(recent)
}

index > RPC > GetRecentPerformanceSamples

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  limit := uint(3)
  out, err := client.GetRecentPerformanceSamples(
    context.TODO(),
    &limit,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetSignatureStatuses

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetSignatureStatuses(
    context.TODO(),
    true,
    // All the transactions you want the get the status for:
    solana.MustSignatureFromBase58("2CwH8SqVZWFa1EvsH7vJXGFors1NdCuWJ7Z85F8YqjCLQ2RuSHQyeGKkfo1Tj9HitSTeLoMWnxpjxF2WsCH8nGWh"),
    solana.MustSignatureFromBase58("5YJHZPeHZuZjhunBc1CCB1NDRNf2tTJNpdb3azGsR7PfyEncCDhr95wG8EWrvjNXBc4wCKixkheSbCxoC2NCG3X7"),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetSignaturesForAddress

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetSignaturesForAddress(
    context.TODO(),
    solana.MustPublicKeyFromBase58("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetSlot

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetSlot(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetSlotLeader

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetSlotLeader(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetSlotLeaders

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  recent, err := client.GetRecentBlockhash(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }

  out, err := client.GetSlotLeaders(
    context.TODO(),
    uint64(recent.Context.Slot),
    10,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetSnapshotSlot

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetSnapshotSlot(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetStakeActivation

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("EW2p7QCJNHMVj5nQCcW7Q2BDETtNBXn68FyucU4RCjvb")
  out, err := client.GetStakeActivation(
    context.TODO(),
    pubKey,
    rpc.CommitmentFinalized,
    nil,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetSupply

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetSupply(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetTokenAccountBalance

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("EzK5qLWhftu8Z2znVa5fozVtobbjhd8Gdu9hQHpC8bec")
  out, err := client.GetTokenAccountBalance(
    context.TODO(),
    pubKey,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetTokenAccountsByDelegate

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("AfkALUPjQp8R1rUwE6KhT38NuTYWCncwwHwcJu7UtAfV")
  out, err := client.GetTokenAccountsByDelegate(
    context.TODO(),
    pubKey,
    &rpc.GetTokenAccountsConfig{
      Mint: solana.MustPublicKeyFromBase58("So11111111111111111111111111111111111111112"),
    },
    nil,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetTokenAccountsByOwner

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  bin "github.com/gagliardetto/binary"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/programs/token"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("7HZaCWazgTuuFuajxaaxGYbGnyVKwxvsJKue1W4Nvyro")
  out, err := client.GetTokenAccountsByOwner(
    context.TODO(),
    pubKey,
    &rpc.GetTokenAccountsConfig{
      Mint: solana.WrappedSol.ToPointer(),
    },
    &rpc.GetTokenAccountsOpts{
      Encoding: solana.EncodingBase64Zstd,
    },
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)

  {
    tokenAccounts := make([]token.Account, 0)
    for _, rawAccount := range out.Value {
      var tokAcc token.Account

      data := rawAccount.Account.Data.GetBinary()
      dec := bin.NewBinDecoder(data)
      err := dec.Decode(&tokAcc)
      if err != nil {
        panic(err)
      }
      tokenAccounts = append(tokenAccounts, tokAcc)
    }
    spew.Dump(tokenAccounts)
  }
}

index > RPC > GetTokenLargestAccounts

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.MainNetBeta_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt") // serum token
  out, err := client.GetTokenLargestAccounts(
    context.TODO(),
    pubKey,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetTokenSupply

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.MainNetBeta_RPC
  client, _ := rpc.new(endpoint)

  pubKey := solana.MustPublicKeyFromBase58("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt") // serum token
  out, err := client.GetTokenSupply(
    context.TODO(),
    pubKey,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetTransaction

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  txSig := solana.MustSignatureFromBase58("4bjVLV1g9SAfv7BSAdNnuSPRbSscADHFe4HegL6YVcuEBMY83edLEvtfjE4jfr6rwdLwKBQbaFiGgoLGtVicDzHq")
  {
    out, err := client.GetTransaction(
      context.TODO(),
      txSig,
      &rpc.GetTransactionOpts{
        Encoding: solana.EncodingBase64,
      },
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
    spew.Dump(out.Transaction.GetBinary())

    decodedTx, err := solana.TransactionFromDecoder(bin.NewBinDecoder(out.Transaction.GetBinary()))
    if err != nil {
      panic(err)
    }
    spew.Dump(decodedTx)
  }
  {
    out, err := client.GetTransaction(
      context.TODO(),
      txSig,
      nil,
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
    spew.Dump(out.Transaction.GetParsedTransaction())
  }
}

index > RPC > GetTransactionCount

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetTransactionCount(
    context.TODO(),
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetVersion

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetVersion(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetVoteAccounts

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.GetVoteAccounts(
    context.TODO(),
    &rpc.GetVoteAccountsOpts{
      VotePubkey: solana.MustPublicKeyFromBase58("vot33MHDqT6nSwubGzqtc6m16ChcUywxV7tNULF19Vu"),
    },
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > IsBlockhashValid

package main

import (
  "context"
  "fmt"
  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.MainNetBeta_RPC
  client, _ := rpc.new(endpoint)

  blockHash := solana.MustHashFromBase58("J7rBdM6AecPDEZp8aPq5iPSNKVkU5Q76F3oAV4eW5wsW")
  out, err := client.IsBlockhashValid(
    context.TODO(),
    blockHash,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
  spew.Dump(out.Value) // true or false

  fmt.Println("is blockhash valid:", out.Value)
}

index > RPC > MinimumLedgerSlot

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  out, err := client.MinimumLedgerSlot(
    context.TODO(),
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > RequestAirdrop

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client, _ := rpc.new(endpoint)

  amount := solana.LAMPORTS_PER_SOL // 1 sol
  pubKey := solana.MustPublicKeyFromBase58("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
  out, err := client.RequestAirdrop(
    context.TODO(),
    pubKey,
    amount,
    "",
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > SendTransaction

package main

func main() {

}

index > RPC > SimulateTransaction

package main

func main() {

}

Websocket Subscriptions

index > WS Subscriptions > AccountSubscribe

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
  "github.com/RoboticAgile/solana-go/rpc/ws"
)

func main() {
  client, err := ws.Connect(context.Background(), rpc.MainNetBeta_WS)
  if err != nil {
    panic(err)
  }
  program := solana.MustPublicKeyFromBase58("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin") // serum

  {
    sub, err := client.AccountSubscribe(
      program,
      "",
    )
    if err != nil {
      panic(err)
    }
    defer sub.Unsubscribe()

    for {
      got, err := sub.Recv()
      if err != nil {
        panic(err)
      }
      spew.Dump(got)
    }
  }
  if false {
    sub, err := client.AccountSubscribeWithOpts(
      program,
      "",
      // You can specify the data encoding of the returned accounts:
      solana.EncodingBase64,
    )
    if err != nil {
      panic(err)
    }
    defer sub.Unsubscribe()

    for {
      got, err := sub.Recv()
      if err != nil {
        panic(err)
      }
      spew.Dump(got)
    }
  }
}

index > WS Subscriptions > LogsSubscribe

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
  "github.com/RoboticAgile/solana-go/rpc/ws"
)

func main() {
  client, err := ws.Connect(context.Background(), rpc.MainNetBeta_WS)
  if err != nil {
    panic(err)
  }
  program := solana.MustPublicKeyFromBase58("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin") // serum

  {
    // Subscribe to log events that mention the provided pubkey:
    sub, err := client.LogsSubscribeMentions(
      program,
      rpc.CommitmentRecent,
    )
    if err != nil {
      panic(err)
    }
    defer sub.Unsubscribe()

    for {
      got, err := sub.Recv()
      if err != nil {
        panic(err)
      }
      spew.Dump(got)
    }
  }
  if false {
    // Subscribe to all log events:
    sub, err := client.LogsSubscribe(
      ws.LogsSubscribeFilterAll,
      rpc.CommitmentRecent,
    )
    if err != nil {
      panic(err)
    }
    defer sub.Unsubscribe()

    for {
      got, err := sub.Recv()
      if err != nil {
        panic(err)
      }
      spew.Dump(got)
    }
  }
}

index > WS Subscriptions > ProgramSubscribe

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
  "github.com/RoboticAgile/solana-go/rpc/ws"
)

func main() {
  client, err := ws.Connect(context.Background(), rpc.MainNetBeta_WS)
  if err != nil {
    panic(err)
  }
  program := solana.MustPublicKeyFromBase58("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") // token

  sub, err := client.ProgramSubscribeWithOpts(
    program,
    rpc.CommitmentRecent,
    solana.EncodingBase64Zstd,
    nil,
  )
  if err != nil {
    panic(err)
  }
  defer sub.Unsubscribe()

  for {
    got, err := sub.Recv()
    if err != nil {
      panic(err)
    }
    spew.Dump(got)

    decodedBinary := got.Value.Account.Data.GetBinary()
    if decodedBinary != nil {
      // spew.Dump(decodedBinary)
    }

    // or if you requested solana.EncodingJSONParsed and it is supported:
    rawJSON := got.Value.Account.Data.GetRawJSON()
    if rawJSON != nil {
      // spew.Dump(rawJSON)
    }
  }
}

index > WS Subscriptions > RootSubscribe

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
  "github.com/RoboticAgile/solana-go/rpc/ws"
)

func main() {
  client, err := ws.Connect(context.Background(), rpc.TestNet_WS)
  if err != nil {
    panic(err)
  }

  sub, err := client.RootSubscribe()
  if err != nil {
    panic(err)
  }

  for {
    got, err := sub.Recv()
    if err != nil {
      panic(err)
    }
    spew.Dump(got)
  }
}

index > WS Subscriptions > SignatureSubscribe

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go"
  "github.com/RoboticAgile/solana-go/rpc"
  "github.com/RoboticAgile/solana-go/rpc/ws"
)

func main() {
  client, err := ws.Connect(context.Background(), rpc.TestNet_WS)
  if err != nil {
    panic(err)
  }

  txSig := solana.MustSignatureFromBase58("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")

  sub, err := client.SignatureSubscribe(
    txSig,
    "",
  )
  if err != nil {
    panic(err)
  }
  defer sub.Unsubscribe()

  for {
    got, err := sub.Recv()
    if err != nil {
      panic(err)
    }
    spew.Dump(got)
  }
}

index > WS Subscriptions > SlotSubscribe

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
  "github.com/RoboticAgile/solana-go/rpc/ws"
)

func main() {
  client, err := ws.Connect(context.Background(), rpc.TestNet_WS)
  if err != nil {
    panic(err)
  }

  sub, err := client.SlotSubscribe()
  if err != nil {
    panic(err)
  }
  defer sub.Unsubscribe()

  for {
    got, err := sub.Recv()
    if err != nil {
      panic(err)
    }
    spew.Dump(got)
  }
}

index > WS Subscriptions > VoteSubscribe

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/RoboticAgile/solana-go/rpc"
  "github.com/RoboticAgile/solana-go/rpc/ws"
)

func main() {
  client, err := ws.Connect(context.Background(), rpc.MainNetBeta_WS)
  if err != nil {
    panic(err)
  }

  // NOTE: this subscription must be enabled by the node you're connecting to.
  // This subscription is disabled by default.
  sub, err := client.VoteSubscribe()
  if err != nil {
    panic(err)
  }
  defer sub.Unsubscribe()

  for {
    got, err := sub.Recv()
    if err != nil {
      panic(err)
    }
    spew.Dump(got)
  }
}

Contributing

We encourage everyone to contribute, submit issues, PRs, discuss. Every kind of help is welcome.

License

Apache 2.0

Credits

  • Gopher logo was originally created by Takuya Ueda (https://twitter.com/tenntenn). Licensed under the Creative Commons 3.0 Attributions license.

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Copyright 2021 github.com/gagliardetto This file has been modified by github.com/gagliardetto Copyright 2020 dfuse Platform Inc.
No description provided by the author
No description provided by the author
No description provided by the author

# Functions

Create a program address.
Ported from https://github.com/solana-labs/solana/blob/216983c50e0a618facc39aa07472ba6d23f1b33a/sdk/program/src/pubkey.rs#L159.
No description provided by the author
No description provided by the author
No description provided by the author
Find a valid program address and its corresponding bump seed.
FindTokenMetadataAddress returns the token metadata program-derived address given a SPL token mint address.
GetAddedRemovedPubkeys accepts two slices of pubkeys (`previous` and `next`), and returns two slices: - `added` is the slice of pubkeys that are present in `next` but NOT present in `previous`.
HashFromBase58 decodes a base58 string into a Hash.
HashFromBytes decodes a byte slice into a Hash.
IsAnyOfEncodingType checks whether the provided `candidate` is any of the `allowed`.
Check if the provided `b` is on the ed25519 curve.
Meta intializes a new AccountMeta with the provided pubKey.
MPK is a convenience alias for MustPublicKeyFromBase58.
MustHashFromBase58 decodes a base58 string into a Hash.
No description provided by the author
No description provided by the author
MustSignatureFromBase58 decodes a base58 string into a Signature.
MustTransactionFromDecoder decodes a transaction from a decoder.
No description provided by the author
NewInstruction creates a generic instruction with the provided programID, accounts, and data bytes.
No description provided by the author
No description provided by the author
NewTransactionBuilder creates a new instruction builder.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
SignatureFromBase58 decodes a base58 string into a Signature.
SignatureFromBytes decodes a byte slice into a Signature.
No description provided by the author
TransactionFromDecoder decodes a transaction from a decoder.
No description provided by the author
No description provided by the author

# Constants

limited to Account data of less than 129 bytes.
will return base64 encoded data for Account data of any size.
compresses the Account data using Zstandard and base64-encodes the result.
NOTE: you're probably looking for EncodingJSONParsed.
attempts to use program-specific state parsers to return more human-readable and explicit account state data.
There are 1-billion lamports in one SOL.
Maximum length of derived pubkey seed.
Maximum number of seeds.
default.
v0.
No description provided by the author
Number of bytes in a pubkey.
Number of bytes in a signature.

# Variables

No description provided by the author
Deploys, upgrades, and executes programs on the chain.
No description provided by the author
No description provided by the author
Add configuration data to the chain and the list of public keys that are permitted to modify it.
No description provided by the author
No description provided by the author
No description provided by the author
The Memo program is a simple program that validates a string of UTF-8 encoded characters and verifies that any accounts provided are signers of the transaction.
Verify secp256k1 public key recovery operations (ecrecover).
The Mint for native SOL Token accounts.
This program defines the convention and provides the mechanism for mapping the user's wallet address to the associated token accounts they hold.
Create and manage accounts representing stake and rewards for delegations to validators.
Create new accounts, allocate account data, assign accounts to owning programs, transfer lamports from System Program owned accounts and pay transacation fees.
The Clock sysvar contains data on cluster time, including the current slot, epoch, and estimated wall-clock Unix timestamp.
The EpochSchedule sysvar contains epoch scheduling constants that are set in genesis, and enables calculating the number of slots in a given epoch, the epoch for a given slot, etc.
The Fees sysvar contains the fee calculator for the current slot.
The Instructions sysvar contains the serialized instructions in a Message while that Message is being processed.
The RecentBlockhashes sysvar contains the active recent blockhashes as well as their associated fee calculators.
The Rent sysvar contains the rental rate.
.
The SlotHashes sysvar contains the most recent hashes of the slot's parent banks.
The SlotHistory sysvar contains a bitvector of slots present over the last epoch.
The StakeHistory sysvar contains the history of cluster-wide stake activations and de-activations per epoch.
A lending protocol for the Token program on the Solana blockchain inspired by Aave and Compound.
No description provided by the author
A Token program on the Solana blockchain.
SPL:.
A Uniswap-like exchange for the Token program on the Solana blockchain, implementing multiple automated market maker (AMM) curves.
Create and manage accounts that track validator voting state and rewards.
No description provided by the author

# Structs

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Wallet is a wrapper around a PrivateKey.

# Interfaces

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Type aliases

No description provided by the author
No description provided by the author
DurationMilliseconds represents a duration in milliseconds.
DurationSeconds represents a duration in seconds.
No description provided by the author
No description provided by the author
InstructionDecoder receives the AccountMeta FOR THAT INSTRUCTION, and not the accounts of the *Message object.
No description provided by the author
No description provided by the author
No description provided by the author
PK is a convenience alias for PublicKey.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
UnixTimeMilliseconds represents a UNIX millisecond-resolution timestamp.
UnixTimeSeconds represents a UNIX second-resolution timestamp.