Go SDK library for the Solana Blockchain

Overview

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.

Clients for Solana native programs, Solana Program Library (SPL), and Serum DEX are in development.

More contracts to come.

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.0.2 which is an alpha release.

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

Requirements

  • Go 1.16 or later

Installation

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

Pretty-Print transactions/instructions

pretty-printed

Instructions can be pretty-printed with the EncodeTree 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:
tx.EncodeTree(text.NewTreeEncoder(os.Stdout, "Transfer SOL"))

SendAndConfirmTransaction

You can wait for a transaction confirmation using the github.com/gagliardetto/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.

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)

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

Examples

Create account (wallet)

package main

import (
  "context"
  "fmt"

  "github.com/gagliardetto/solana-go"
  "github.com/gagliardetto/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*5,
    rpc.CommitmentFinalized,
  )
  if err != nil {
    panic(err)
  }
  fmt.Println("airdrop transaction signature:", out)
}

Load/parse private and private 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/gagliardetto/solana-go"
  "github.com/gagliardetto/solana-go/programs/system"
  "github.com/gagliardetto/solana-go/rpc"
  confirm "github.com/gagliardetto/solana-go/rpc/sendAndConfirmTransaction"
  "github.com/gagliardetto/solana-go/rpc/jsonrpc"
  "github.com/gagliardetto/solana-go/rpc/ws"
  "github.com/gagliardetto/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*5,
      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/gagliardetto/solana-go"
  "github.com/gagliardetto/solana-go/programs/token"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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 > GetFirstAvailableBlock

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/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 > GetIdentity

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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"
  "github.com/gagliardetto/solana-go"
  "github.com/gagliardetto/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.MustPublicKeyFromBase58("So11111111111111111111111111111111111111112"),
    },
    nil,
  )
  if err != nil {
    panic(err)
  }
  spew.Dump(out)
}

index > RPC > GetTokenLargestAccounts

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/solana-go/rpc"
)

func main() {
  endpoint := rpc.TestNet_RPC
  client := rpc.New(endpoint)

  txSig := solana.MustSignatureFromBase58("4bjVLV1g9SAfv7BSAdNnuSPRbSscADHFe4HegL6YVcuEBMY83edLEvtfjE4jfr6rwdLwKBQbaFiGgoLGtVicDzHq")
  {
    out, err := client.GetTransaction(
      context.TODO(),
      txSig,
      nil,
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
    spew.Dump(out.Transaction.GetParsedTransaction())
  }
  {
    out, err := client.GetTransaction(
      context.TODO(),
      txSig,
      &rpc.GetTransactionOpts{
        Encoding: solana.EncodingJSON,
      },
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
    spew.Dump(out.Transaction.GetParsedTransaction())
  }
  {
    out, err := client.GetTransaction(
      context.TODO(),
      txSig,
      &rpc.GetTransactionOpts{
        Encoding: solana.EncodingBase58,
      },
    )
    if err != nil {
      panic(err)
    }
    spew.Dump(out)
    spew.Dump(out.Transaction.GetBinary())
  }
  {
    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())
  }
}

index > RPC > GetTransactionCount

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/gagliardetto/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/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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 > MinimumLedgerSlot

package main

import (
  "context"

  "github.com/davecgh/go-spew/spew"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/solana-go/rpc"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/solana-go/rpc"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/solana-go/rpc"
  "github.com/gagliardetto/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/gagliardetto/solana-go/rpc"
  "github.com/gagliardetto/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/gagliardetto/solana-go"
  "github.com/gagliardetto/solana-go/rpc"
  "github.com/gagliardetto/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/gagliardetto/solana-go/rpc"
  "github.com/gagliardetto/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/gagliardetto/solana-go/rpc"
  "github.com/gagliardetto/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.
Issues
  • How to decode a raw transaction into a transaction object?

    How to decode a raw transaction into a transaction object?

    Hello,

    I don't understand if it's possible to decode a raw transaction string to a solana.Transaction object in the SDK. I'd like to do this to support the feature of getting a raw transaction from a user and only submitting that to the network via the sendTransaction rpc method, which takes a transaction.

    Maybe doing some borsh decoder like here could help, but don't really know. Any tips?

    Also, if there's the interest, there could exist a function in the rpc package to submit raw transaction strings directly, without the need to convert to a transaction, or provide a function that easily converts that, maybe in the transaction package (in the case that there doesn't exist one)

    opened by GCrispino 12
  • rpc.Client struct needs to implement a close method for its own socket

    rpc.Client struct needs to implement a close method for its own socket

    gm,

    may be this is an edge case - whenever you instance many rpc.New calls, macOS would throw tcp lookup not found errors even after ulimit -n 69420710 or ulimit > unlimited. so in my programs, i have to instance a global rpc.Client via rpc.New and then pass down to functions that require rpc interactions. this implies that many instances of rpc.New will exceed the OS max open sockets and fail due to not being closed after usage.

    so i would like to know where to start on making the pr that implements this if you dont have time to. or i would be eternally grateful if this gets implemented in a future release.

    much love <3, D

    opened by whymidnight 10
  • How to use serum place order instruction

    How to use serum place order instruction

    hi,i want use the serum package to place a order,but when i create serum.instruction,have a problem。the ide tell me the serum.instruction have not implement solana.instruction(three method ProgramID, Accounts, Data).

    i want to know how to use serum.instruction to send transaction?

    what is my mistake?

    thank you!

    opened by first-giver 6
  • Transaction decoding with Meta property

    Transaction decoding with Meta property

    Hey there,

    I have asked this in another person's issue but wanted to open an official one.

    When calling the TransactionFromDecoder method the returned struct is solana.Transaction which doesn't contain the Meta property which when calling RPC GetTransaction you do get.

    Is there a reason for doing so and is it possible to have the Meta property from a decoded transaction?

    Thanks

    opened by Lazar955 6
  • how to parse transactions

    how to parse transactions

    I'm currently working on a sol back-end wallet project. I'm familiar with eth series. I know that a TX contains from, to and amount. However, I found that there is no explicit amount field in Sol's API. Instead, it is divided into postBalances and preBalances.

    so,do I need to build postbalances, prebalances and accountkeys into a data struct and calculate the amount? I count found how to parse instructions.data. Can you give me some advice?

    opened by yifanes 5
  • Fixed GetTokenAccountsResult unmarshalling

    Fixed GetTokenAccountsResult unmarshalling

    Current implementation of the library incorrectly unmarshalls result obtained from the network.

    The network response:

    {
        "context": {
            "slot": 88881251
        },
        "value": [
            {
                "account": {
                    "data": {
                        "parsed": {
                            "info": {
                                "isNative": false,
                                "mint": "7duMWSNdYMof6WKZHs5X1wdmmxUa6cDGqqKShhMSGkgg",
                                "owner": "5VpgCCusY5wqQdsW4auwBKLrAcPatvhJqP3RsdWCVhGc",
                                "state": "initialized",
                                "tokenAmount": {
                                    "amount": "160000000000",
                                    "decimals": 9,
                                    "uiAmount": 160.0,
                                    "uiAmountString": "160"
                                }
                            },
                            "type": "account"
                        },
                        "program": "spl-token",
                        "space": 165
                    },
                    "executable": false,
                    "lamports": 2039280,
                    "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                    "rentEpoch": 204
                },
                "pubkey": "FogtU272rSRCbVhcga2UGDCXnvdvcPHXtEBrd6PTwAeK"
            },
            {
                "account": {
                    "data": {
                        "parsed": {
                            "info": {
                                "isNative": false,
                                "mint": "6E8tJq85M64wqerfwBN6iYQGJPVcUFzgc8wKqc3tcKeD",
                                "owner": "5VpgCCusY5wqQdsW4auwBKLrAcPatvhJqP3RsdWCVhGc",
                                "state": "initialized",
                                "tokenAmount": {
                                    "amount": "25000000000",
                                    "decimals": 9,
                                    "uiAmount": 25.0,
                                    "uiAmountString": "25"
                                }
                            },
                            "type": "account"
                        },
                        "program": "spl-token",
                        "space": 165
                    },
                    "executable": false,
                    "lamports": 2039280,
                    "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                    "rentEpoch": 205
                },
                "pubkey": "sRstQnQayXAK5HYW9VjZZdWjczDzsacP1mN6Ya5WUnE"
            },
            {
                "account": {
                    "data": {
                        "parsed": {
                            "info": {
                                "isNative": false,
                                "mint": "GAB8JrLm2CbLG9e3j769qt69bAuJzErRh3XVbazYCHyH",
                                "owner": "5VpgCCusY5wqQdsW4auwBKLrAcPatvhJqP3RsdWCVhGc",
                                "state": "initialized",
                                "tokenAmount": {
                                    "amount": "1",
                                    "decimals": 0,
                                    "uiAmount": 1.0,
                                    "uiAmountString": "1"
                                }
                            },
                            "type": "account"
                        },
                        "program": "spl-token",
                        "space": 165
                    },
                    "executable": false,
                    "lamports": 2039280,
                    "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                    "rentEpoch": 205
                },
                "pubkey": "1Cn2825y8DZgmJW34iD1T5GMNRXhzQ16yXnbzz64WLc"
            }
        ]
    }
    

    The current go struct:

    type GetTokenAccountsResult struct {
    	RPCContext
    	Value []*Account `json:"value"`
    }
    

    So the slice of accounts can't be unmarshalled correctly because the network response contains additional "account" key in every slice element. This PR fixes the problem without breaking the API of the package.

    opened by hexdigest 5
  • compilation error on v0.4.2

    compilation error on v0.4.2

    # github.com/gagliardetto/solana-go
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/transaction.go:260:2: undefined: bin.EncodeCompactU16Length
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/transaction.go:276:16: encoder.WriteBytes undefined (type *bin.Encoder has no field or method WriteBytes)
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/transaction.go:281:25: undefined: bin.DecodeCompactU16LengthFromByteReader
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/transaction.go:287:28: decoder.ReadNBytes undefined (type *bin.Decoder has no field or method ReadNBytes)
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/types.go:36:7: undefined: bin.EncoderDecoder
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/types.go:64:7: undefined: bin.EncoderDecoder
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/types.go:93:2: undefined: bin.EncodeCompactU16Length
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/types.go:100:2: undefined: bin.EncodeCompactU16Length
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/types.go:103:3: undefined: bin.EncodeCompactU16Length
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/types.go:108:3: undefined: bin.EncodeCompactU16Length
    ../../go/pkg/mod/github.com/gagliardetto/[email protected]/types.go:108:3: too many errors
    
    opened by defactojob 5
  • Error when decoding AccountInfo

    Error when decoding AccountInfo

    Hello,

    I am getting the following error byte array: varlen=3069866594, missing 3069866581 bytes when trying to read the AccountInfo of an account address. This is the account information in the dev net

    Ultimately I am trying to read the account data so I can read the attributes of the NFT.

    This is my code

    
    import (
    	"context"
    	"fmt"
    	"github.com/gagliardetto/binary"
    	tokenmetadata "github.com/gagliardetto/metaplex-go/clients/token-metadata"
    	"github.com/gagliardetto/solana-go"
    	"github.com/gagliardetto/solana-go/rpc"
    )
    	c := rpc.New(rpc.DevNet_RPC)
    	a := solana.MustPublicKeyFromBase58("Gv1VNiC7YTXb7FerKoWiB99RTXzs2Qrq6p5JpYnQ63aZ")
    	resp, err := c.GetAccountInfo(context.TODO(), a)
    	if err != nil {
    		panic(err)
    	}
    	d := bin.NewBorshDecoder(resp.Value.Data.GetBinary())
    	var meta tokenmetadata.Metadata
    	err = d.Decode(&meta)
    	if err != nil {
    		panic(err)
    	}
    

    Any ideas what I could be doing wrong?

    opened by martymcflyDMC 4
  • Issues running with go 1.18

    Issues running with go 1.18

    Here is the stack:

    runtime.throw({0x175c318?, 0xc02ad833c0?})
    /usr/lib/go-1.18/src/runtime/panic.go:992 +0x71 fp=0xc02ad83380 sp=0xc02ad83350 pc=0x449931
    runtime.sigpanic()
    /usr/lib/go-1.18/src/runtime/signal_unix.go:825 +0x305 fp=0xc02ad833d0 sp=0xc02ad83380 pc=0x45fbe5
    aeshashbody()
    /usr/lib/go-1.18/src/runtime/asm_amd64.s:1343 +0x39f fp=0xc02ad833d8 sp=0xc02ad833d0 pc=0x479cbf
    runtime.mapiternext(0xc02f1e8e80)
    /usr/lib/go-1.18/src/runtime/map.go:934 +0x2cb fp=0xc02ad83448 sp=0xc02ad833d8 pc=0x4233cb
    runtime.mapiterinit(0xc02ad834e0?, 0x420be5?, 0xc02f1c9ea8?)
    /usr/lib/go-1.18/src/runtime/map.go:861 +0x228 fp=0xc02ad83468 sp=0xc02ad83448 pc=0x4230a8
    reflect.mapiterinit(0x4229bd?, 0x1536ba0?, 0xc02f1af3a8?)
    /usr/lib/go-1.18/src/runtime/map.go:1373 +0x19 fp=0xc02ad83490 sp=0xc02ad83468 pc=0x476319
    github.com/modern-go/reflect2.(*UnsafeMapType).UnsafeIterate(...)
    /home/user/go/pkg/mod/github.com/modern-go/[email protected]/unsafe_map.go:112
    github.com/json-iterator/go.(*sortKeysMapEncoder).Encode(0xc02f319020, 0xc02e443198, 0xc02f305140)
    /home/user/go/pkg/mod/github.com/json-iterator/[email protected]/reflect_map.go:291 +0x225 fp=0xc02ad83600 sp=0xc02ad83490 pc=0x726cc5
    github.com/json-iterator/go.(*onePtrEncoder).Encode(0xc02f301360, 0xc02f318810, 0xc02f1e8e80?)
    /home/user/go/pkg/mod/github.com/json-iterator/[email protected]/reflect.go:219 +0x82 fp=0xc02ad83638 sp=0xc02ad83600 pc=0x71efc2
    github.com/json-iterator/go.(*Stream).WriteVal(0xc02f305140, {0x158e020, 0xc02f318810})
    /home/user/go/pkg/mod/github.com/json-iterator/[email protected]/reflect.go:98 +0x158 fp=0xc02ad836a8 sp=0xc02ad83638 pc=0x71e2d8
    
    opened by Lazar955 4
  • How to use system.NewCreateAccountWithSeedInstruction properly?

    How to use system.NewCreateAccountWithSeedInstruction properly?

    I am trying to replicate this solana example hello world program in .ts using go. But I am stuck on using system.NewCreateAccountWithSeedInstruction. I got this error Transaction simulation failed: Error processing Instruction 0: invalid instruction data when executing confirm.SendAndConfirmTransaction using system.NewCreateAccountWithSeedInstruction instruction:

    
    2021/12/24 11:57:11 (*jsonrpc.RPCError)(0xc0001f5890)({
     Code: (int) -32002,
     Message: (string) (len=87) "Transaction simulation failed: Error processing Instruction 0: invalid instruction data",
     Data: (map[string]interface {}) (len=3) {
      (string) (len=8) "accounts": (interface {}) <nil>,
      (string) (len=3) "err": (map[string]interface {}) (len=1) {
       (string) (len=16) "InstructionError": ([]interface {}) (len=2 cap=2) {
        (json.Number) (len=1) "0",
        (string) (len=22) "InvalidInstructionData"
       }
      },
      (string) (len=4) "logs": ([]interface {}) (len=2 cap=2) {
       (string) (len=51) "Program 11111111111111111111111111111111 invoke [1]",
       (string) (len=73) "Program 11111111111111111111111111111111 failed: invalid instruction data"
      }
     }
    })
    

    And here is my code in go:

    func main() {
    	// var
    	ctx := context.Background()
    	rpcCli := rpc.New(rpc.LocalNet_RPC)
    	wsCli, _ := ws.Connect(ctx, rpc.LocalNet_WS)
    	payerPrivateKey, _ := solana.PrivateKeyFromBase58("5LRLfrUP22VtiNaPGAEgHPucoJmG8ejmomMVmpn4fkXjexYsT7RQGfGuMePG5PKvecZxMGrqa6EP2RmYcm7TYQvX") // don't worry, I only use this private key in my local computer
    	payerAccount, _ := solana.WalletFromPrivateKeyBase58(payerPrivateKey.String())
    	programID := "4sCcZNQR8vfWckyi5L9KdptdaiLxdiMjVgKQay7HxzmK"
    	programPubKey, _ := solana.PublicKeyFromBase58(programID)
    
    	// create new subaccount (seed account)
    	newSubAccount, err := solana.CreateWithSeed(
    		payerAccount.PublicKey(),
    		"hello",
    		programPubKey,
    	)
    	if err != nil {
    		log.Fatalln("Failed to CreateWithSeed")
    	}
    
    	instruction, err := system.NewCreateAccountWithSeedInstruction(
    		payerAccount.PublicKey(),
    		"hello",
    		918720,
    		4,
    		programPubKey,
    		payerAccount.PublicKey(),
    		newSubAccount,
    		payerAccount.PublicKey(),
    	).ValidateAndBuild()
    	if err != nil {
    		log.Fatalln("Failed building NewCreateAccountInstruction instruction", err)
    	}
    
    	instructionData, _ := instruction.Data()
    	fmt.Printf("------> instructionData length: %d bytes, data: %v\n", len(instructionData), instructionData)
    
    	instructions := []solana.Instruction{instruction}
    	signers := []solana.PrivateKey{payerAccount.PrivateKey}
    	opts := []solana.TransactionOption{solana.TransactionPayer(payerAccount.PublicKey())}
    
    	// create recent blockhash
    	recent, err := rpcCli.GetRecentBlockhash(ctx, rpc.CommitmentFinalized)
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	// create transaction
    	tx, err := solana.NewTransaction(
    		instructions,
    		recent.Value.Blockhash,
    		opts...,
    	)
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	// sign transaction
    	_, err = tx.Sign(
    		func(key solana.PublicKey) *solana.PrivateKey {
    			for _, signer := range signers {
    				if signer.PublicKey().Equals(key) {
    					return &signer
    				}
    			}
    
    			return nil
    		},
    	)
    	if err != nil {
    		log.Fatalln(err)
    	}
    	tx.EncodeTree(text.NewTreeEncoder(os.Stdout, "Transfer SOL"))
    
    	// send and confirm transaction
    	_, err = confirm.SendAndConfirmTransaction(
    		ctx,
    		rpcCli,
    		wsCli,
    		tx,
    	)
    	if err != nil {
    		log.Fatalln(err)
    	}
    }
    

    I tried to print the instruction.Data() in go and got this

    ------> instructionData length: 90 bytes, data: [3 0 0 0 204 95 77 127 148 25 135 127 89 146 22 90 233 80 113 3 70 176 165 222 81 200 100 223 117 165 155 44 53 225 124 20 5 104 101 108 108 111 192 4 14 0 0 0 0 0 4 0 0 0 0 0 0 0 57 111 59 111 183 248 249 251 128 174 206 0 81 22 3 173 244 104 15 249 239 112 33 255 66 169 29 66 7 106 231 230]
    

    And here is the instruction data on the .ts from the solana helloworld example for comparison console.log(instruction.data.buffer)

    ArrayBuffer {
      [Uint8Contents]: <03 00 00 00 cc 5f 4d 7f 94 19 87 7f 59 92 16 5a e9 50 71 03 46 b0 a5 de 51 c8 64 df 75 a5 9b 2c 35 e1 7c 14 05 00 00 00 00 00 00 00 68 65 6c 6c 6f c0 04 0e 00 00 00 00 00 04 00 00 00 00 00 00 00 39 6f 3b 6f b7 f8 f9 fb 80 ae ce 00 51 16 03 ad f4 68 0f f9 ef 70 21 ff 42 a9 1d 42 07 6a e7 e6>,
      byteLength: 97
    }
    

    And here is the conversion from hex to 0-255

    3 0 0 0 204 95 77 127 148 25 135 127 89 146 22 90 233 80 113 3 70 176 165 222 81 200 100 223 117 165 155 44 53 225 124 20 5 **0 0 0 0 0 0 0** 104 101 108 108 111 192 4 14 0 0 0 0 0 4 0 0 0 0 0 0 0 57 111 59 111 183 248 249 251 128 174 206 0 81 22 3 173 244 104 15 249 239 112 33 255 66 169 29 66 7 106 231 230
    

    I see that there are 7 bytes difference (the one that I bold) in 0 0 0 0 0 0 0. What do I do wrong? Am I missing something? Is there any example on how to use this instruction? Thanks!

    opened by pikomonde 4
  • Send raw transaction

    Send raw transaction

    As discussed in https://github.com/gagliardetto/solana-go/issues/15, this PR implements two new functions for the rpc.Client struct:

    • SendRawTransaction, that sends a transaction encoded in wire format as a bytes array, and
    • SendEncodedTransaction, that sends a transaction encoded in wire format as a base64 string

    Examples and tests were added to these functions as well

    opened by GCrispino 4
  • dfuse-io logging module update to new URL

    dfuse-io logging module update to new URL

    Since the module github.com/dfuse-io/logging now redirects to github.com/streamingfast/logging , when I do go get -u this error comes up:

    go get: github.com/dfuse-io/[email protected] updating to
            github.com/dfuse-io/[email protected]: parsing go.mod:
            module declares its path as: github.com/streamingfast/logging
                    but was required as: github.com/dfuse-io/logging
    

    Any reason why this hasn't been fixed? Is the old logging module different from the new one at streamingfast?

    opened by johnbailon 1
  • Add ws connect method with http header parameter

    Add ws connect method with http header parameter

    Hello,

    A new connect method is needed that accepts a requestHeader http.Header parameter that passes that to the DialContext method. The existing is missing it. https://github.com/gagliardetto/solana-go/blob/2acfcf2684c6dca9a9ae67126d09abc910c3a3fd/rpc/ws/client.go#L56 Reason: if you plan to pass in a user password for authentication, this is the prescribed way. gorilla WebSocket basic authentication

    Thanks for enriching the Solana ecosystem with a Go SDK!

    opened by blewater 0
  • Get Anchor Data with GetAccountInfoWithOpts

    Get Anchor Data with GetAccountInfoWithOpts

    I want to fetch this data from https://explorer.solana.com/address/61CCEcc5LZCp9RJ2yPhmABHno3fPLKK6Lbxrpvqdj5Bu/anchor-account?cluster=devnet image

    The only way I have found to make this request: image

    This returns me that output: ["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","base64"]

    But after trying to decode this with all possible ways I understood that nothing helps, could you explain me how to solve this problem, please?

    opened by genshawty 0
  • How to use filters with rpc.GetProgramAccountsOpts

    How to use filters with rpc.GetProgramAccountsOpts

    Ask - Do you have an example of using GetProgramAccountsWithOpts that includes the dataslice and memcmp filters?

    I am trying to use DataSlice and Filters with GetProgramAccountsWithOpts and I'm sure I'm making some rookie mistake here with the format but I can't figure out the proper format to include the memcmp filter. Thank you.

    out, err := client.GetProgramAccountsWithOpts(
    		context.TODO(),
    		solana.MustPublicKeyFromBase58("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"),
    		&rpc.GetProgramAccountsOpts{
    			Encoding:   solana.EncodingBase64Zstd,
    			Commitment: rpc.CommitmentFinalized,
    			DataSlice: &rpc.DataSlice{
    				Offset: pointer.ToUint64(0),
    				Length: pointer.ToUint64(1024),
    			},
    			//TODO: what is the correct format for filters
    			Filters: ,
    		},
    	)
    
    opened by m4thfr34k 0
Releases(v1.4.0)
  • v1.4.0(Mar 16, 2022)

    What's Changed

    • allow PublicKey to be used as flag by @terorie in https://github.com/gagliardetto/solana-go/pull/42
    • update json-iterator for go1.18 support by @defactojob in https://github.com/gagliardetto/solana-go/pull/48

    New Contributors

    • @defactojob made their first contribution in https://github.com/gagliardetto/solana-go/pull/48

    Full Changelog: https://github.com/gagliardetto/solana-go/compare/v1.3.0...v1.4.0

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Feb 16, 2022)

  • v1.2.1(Feb 15, 2022)

  • v1.2.0(Feb 13, 2022)

  • v1.1.0(Feb 1, 2022)

    What's Changed

    • Bump up fatih/color to fix wasm error by @pikomonde in https://github.com/gagliardetto/solana-go/pull/34

    New Contributors

    • @pikomonde made their first contribution in https://github.com/gagliardetto/solana-go/pull/34

    Full Changelog: https://github.com/gagliardetto/solana-go/compare/v1.0.4...v1.1.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.4(Jan 6, 2022)

  • v1.0.3(Jan 5, 2022)

    What's Changed

    • Send raw transaction by @GCrispino in https://github.com/gagliardetto/solana-go/pull/16
    • fix: Handle client.newRequest returning nil request by @archseer in https://github.com/gagliardetto/solana-go/pull/29
    • Feature/is blockhash valid by @Lazar955 in https://github.com/gagliardetto/solana-go/pull/26
    • Implemented GetSupplyWithOpts method to be able to exclude non circulating accounts list from getSupply response. by @martelev in https://github.com/gagliardetto/solana-go/pull/27
    • Implement BPF Loader by @lebdron in https://github.com/gagliardetto/solana-go/pull/10

    New Contributors

    • @GCrispino made their first contribution in https://github.com/gagliardetto/solana-go/pull/16
    • @archseer made their first contribution in https://github.com/gagliardetto/solana-go/pull/29
    • @Lazar955 made their first contribution in https://github.com/gagliardetto/solana-go/pull/26
    • @martelev made their first contribution in https://github.com/gagliardetto/solana-go/pull/27

    Full Changelog: https://github.com/gagliardetto/solana-go/compare/v1.0.2...v1.0.3

    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Oct 23, 2021)

    What's Changed

    • Add FindTokenMetadataAddress() by @terorie in https://github.com/gagliardetto/solana-go/pull/7
    • WebSocket Client: remove configuration from unsubscribe call, add missing SetWriteDeadline calls by @lebdron in https://github.com/gagliardetto/solana-go/pull/9
    • Fix getBlockProduction opts by @terorie in https://github.com/gagliardetto/solana-go/pull/11
    • Fixed GetTokenAccountsResult unmarshalling by @hexdigest in https://github.com/gagliardetto/solana-go/pull/12

    New Contributors

    • @terorie made their first contribution in https://github.com/gagliardetto/solana-go/pull/7
    • @lebdron made their first contribution in https://github.com/gagliardetto/solana-go/pull/9
    • @hexdigest made their first contribution in https://github.com/gagliardetto/solana-go/pull/12

    Full Changelog: https://github.com/gagliardetto/solana-go/compare/v1.0.1...v1.0.2

    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Oct 10, 2021)

    • Add DurationSeconds
    • JSON RPC performance improvements
    • Use better zstd encoder/decoder pools
    • Improve README
    • Rename GetAccountDataIn to GetAccountDataInto
    • Add GetAccountDataBorshInto
    • Add/update license/copyright headers inside files.
    • Add changes notice
    Source code(tar.gz)
    Source code(zip)
  • v0.5.1(Sep 21, 2021)

    • Improve README.
    • Improve transaction serialization logic.
    • Upgrade github.com/gagliardetto/binary to v0.4.4.
    • Add String() method to UnixTimeSeconds type.
    • Add example with SendAndConfirmTransaction.
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Sep 13, 2021)

    • Add associated-token-account program client.
    • Move UnixTimeSeconds to solana package.
    • (AccountMetaSlice) GetAccounts() : Skip nil accounts.
    • Add generic instruction with creator.
    Source code(tar.gz)
    Source code(zip)
  • v0.4.5(Sep 8, 2021)

  • v0.4.4(Sep 6, 2021)

  • v0.4.3(Sep 4, 2021)

  • v0.4.2(Sep 1, 2021)

  • v0.4.1(Sep 1, 2021)

  • v0.4.0(Aug 31, 2021)

    • Refactor transaction handling and displaying
    • Refactor system program
    • Get ready for anchor-go
    • Add functions to derive addresses
    • Refactor AccountMeta tools
    • Add more native program IDs
    Source code(tar.gz)
    Source code(zip)
  • v0.3.5(Jul 28, 2021)

  • v0.3.2(Jul 19, 2021)

  • v0.3.1(Jul 14, 2021)

Owner
Slavomir
gopher
Slavomir
Go clients for the Metaplex Solana programs

metaplex-go A suite of Go clients for the 5 metaplex contracts. This is an alpha version. For usage examples, you can get inspired by their Rust/Types

Slavomir 23 Jun 22, 2022
Token-list - The community maintained Solana token registry

Please note: This repository is being rebuilt to accept the new volume of token

null 0 Feb 2, 2022
planet is a blockchain built using Cosmos SDK and Tendermint and created with Starport.

planet planet is a blockchain built using Cosmos SDK and Tendermint and created with Starport. Get started starport chain serve serve command install

Andrei Ivasko 0 Oct 31, 2021
A go sdk for baidu netdisk open platform 百度网盘开放平台 Go SDK

Pan Go Sdk 该代码库为百度网盘开放平台Go语言的SDK

Jsyz Chen 71 Jun 15, 2022
Nextengine-sdk-go: the NextEngine SDK for the Go programming language

NextEngine SDK for Go nextengine-sdk-go is the NextEngine SDK for the Go programming language. Getting Started Install go get github.com/takaaki-s/nex

null 0 Dec 7, 2021
Commercetools-go-sdk is fork of original commercetools-go-sdk

commercetools-go-sdk The Commercetools Go SDK is automatically generated based on the official API specifications of Commercetools. It should therefor

Flink 0 Dec 13, 2021
Sdk-go - Go version of the Synapse SDK

synapsesdk-go Synapse Protocol's Go SDK. Currently in super duper alpha, do not

null 0 Jan 7, 2022
Redash-go-sdk - An SDK for the programmatic management of Redash, in Go

Redash Go SDK An SDK for the programmatic management of Redash. The main compone

RecoLabs 24 Mar 3, 2022
Simple no frills AWS S3 Golang Library using REST with V4 Signing (without AWS Go SDK)

simples3 : Simple no frills AWS S3 Library using REST with V4 Signing Overview SimpleS3 is a golang library for uploading and deleting objects on S3 b

Rohan Verma 87 Jun 10, 2022
Microsoft Graph SDK for Go - Core Library

Microsoft Graph Core SDK for Go Get started with the Microsoft Graph Core SDK for Go by integrating the Microsoft Graph API into your Go application!

Microsoft Graph 8 Jun 9, 2022
A Golang Client Library for building Cosmos SDK chain clients

Cosmos Client Lib in Go This is the start of ideas around how to implement the cosmos client libraries in a seperate repo How to instantiate and use t

Jack Zampolin 113 Jun 18, 2022
AWS SDK for the Go programming language.

AWS SDK for Go aws-sdk-go is the official AWS SDK for the Go programming language. Checkout our release notes for information about the latest bug fix

Amazon Web Services 7.7k Jun 22, 2022
A Facebook Graph API SDK For Go.

A Facebook Graph API SDK In Golang This is a Go package that fully supports the Facebook Graph API with file upload, batch request and marketing API.

Huan Du 1.1k Jun 27, 2022
A Golang SDK for Medium's OAuth2 API

Medium SDK for Go This repository contains the open source SDK for integrating Medium's OAuth2 API into your Go app. Install go get github.com/Medium/

Medium 131 May 18, 2022
MinIO Client SDK for Go

MinIO Go Client SDK for Amazon S3 Compatible Cloud Storage The MinIO Go Client SDK provides simple APIs to access any Amazon S3 compatible object stor

High Performance, Kubernetes Native Object Storage 1.6k Jun 30, 2022
Twilight is an unofficial Golang SDK for Twilio APIs

Twilight is an unofficial Golang SDK for Twilio APIs. Twilight was born as a result of my inability to spell Twilio correctly. I searched for a Twillio Golang client library and couldn’t find any, I decided to build one. Halfway through building this, I realized I had spelled Twilio as Twillio when searching for a client library on Github.

Ghvst Code 18 Jul 2, 2021
Wechat Pay SDK(V3) Write by Go.

WechatPay GO(v3) Introduction Wechat Pay SDK(V3) Write by Go. API V3 of Office document is here. Features Signature/Verify messages Encrypt/Decrypt ce

luoji 23 May 23, 2022
Go Wechaty is a Conversational SDK for Chatbot Makers Written in Go

go-wechaty Connecting Chatbots Wechaty is a RPA SDK for Wechat Individual Account that can help you create a chatbot in 6 lines of Go. Voice of the De

Wechaty 238 Jun 20, 2022
An easy-to-use unofficial SDK for Feishu and Lark Open Platform

go-lark go-lark is an easy-to-use unofficial SDK for Feishu and Lark Open Platform. go-lark implements messaging APIs, with full-fledged supports on b

go-lark-sdk 98 Jun 21, 2022