solana

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 23, 2021 License: Apache-2.0 Imports: 23 Imported by: 595

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.

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/solana-go@v1.0.2

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())

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.

Documentation

Index

Constants

View Source
const (
	/// Number of bytes in a pubkey.
	PublicKeyLength = 32
	// Maximum length of derived pubkey seed.
	MaxSeedLength = 32
	// Maximum number of seeds.
	MaxSeeds = 16
)
View Source
const (
	// There are 1-billion lamports in one SOL.
	LAMPORTS_PER_SOL uint64 = 1000000000
)
View Source
const PDA_MARKER = "ProgramDerivedAddress"

Variables

View Source
var (
	// Create new accounts, allocate account data, assign accounts to owning programs,
	// transfer lamports from System Program owned accounts and pay transacation fees.
	SystemProgramID = MustPublicKeyFromBase58("11111111111111111111111111111111")

	// Add configuration data to the chain and the list of public keys that are permitted to modify it.
	ConfigProgramID = MustPublicKeyFromBase58("Config1111111111111111111111111111111111111")

	// Create and manage accounts representing stake and rewards for delegations to validators.
	StakeProgramID = MustPublicKeyFromBase58("Stake11111111111111111111111111111111111111")

	// Create and manage accounts that track validator voting state and rewards.
	VoteProgramID = MustPublicKeyFromBase58("Vote111111111111111111111111111111111111111")

	BPFLoaderDeprecatedProgramID = MustPublicKeyFromBase58("BPFLoader1111111111111111111111111111111111")
	// Deploys, upgrades, and executes programs on the chain.
	BPFLoaderProgramID            = MustPublicKeyFromBase58("BPFLoader2111111111111111111111111111111111")
	BPFLoaderUpgradeableProgramID = MustPublicKeyFromBase58("BPFLoaderUpgradeab1e11111111111111111111111")

	// Verify secp256k1 public key recovery operations (ecrecover).
	Secp256k1ProgramID = MustPublicKeyFromBase58("KeccakSecp256k11111111111111111111111111111")

	FeatureProgramID = MustPublicKeyFromBase58("Feature111111111111111111111111111111111111")
)
View Source
var (
	// A Token program on the Solana blockchain.
	// This program defines a common implementation for Fungible and Non Fungible tokens.
	TokenProgramID = MustPublicKeyFromBase58("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")

	// A Uniswap-like exchange for the Token program on the Solana blockchain,
	// implementing multiple automated market maker (AMM) curves.
	TokenSwapProgramID = MustPublicKeyFromBase58("SwaPpA9LAaLfeLi3a68M4DjnLqgtticKg6CnyNwgAC8")
	TokenSwapFeeOwner  = MustPublicKeyFromBase58("HfoTxFR1Tm6kGmWgYWD6J7YHVy1UwqSULUGVLXkJqaKN")

	// A lending protocol for the Token program on the Solana blockchain inspired by Aave and Compound.
	TokenLendingProgramID = MustPublicKeyFromBase58("LendZqTs8gn5CTSJU1jWKhKuVpjJGom45nnwPb2AMTi")

	// This program defines the convention and provides the mechanism for mapping
	// the user's wallet address to the associated token accounts they hold.
	SPLAssociatedTokenAccountProgramID = MustPublicKeyFromBase58("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL")

	// 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.
	// The program also logs the memo, as well as any verified signer addresses,
	// to the transaction log, so that anyone can easily observe memos
	// and know they were approved by zero or more addresses
	// by inspecting the transaction log from a trusted provider.
	MemoProgramID = MustPublicKeyFromBase58("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr")
)

SPL:

View Source
var (
	// The Clock sysvar contains data on cluster time,
	// including the current slot, epoch, and estimated wall-clock Unix timestamp.
	// It is updated every slot.
	SysVarClockPubkey = MustPublicKeyFromBase58("SysvarC1ock11111111111111111111111111111111")

	// 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.
	// (Note: the epoch schedule is distinct from the leader schedule)
	SysVarEpochSchedulePubkey = MustPublicKeyFromBase58("SysvarEpochSchedu1e111111111111111111111111")

	// The Fees sysvar contains the fee calculator for the current slot.
	// It is updated every slot, based on the fee-rate governor.
	SysVarFeesPubkey = MustPublicKeyFromBase58("SysvarFees111111111111111111111111111111111")

	// The Instructions sysvar contains the serialized instructions in a Message while that Message is being processed.
	// This allows program instructions to reference other instructions in the same transaction.
	SysVarInstructionsPubkey = MustPublicKeyFromBase58("Sysvar1nstructions1111111111111111111111111")

	// The RecentBlockhashes sysvar contains the active recent blockhashes as well as their associated fee calculators.
	// It is updated every slot.
	// Entries are ordered by descending block height,
	// so the first entry holds the most recent block hash,
	// and the last entry holds an old block hash.
	SysVarRecentBlockHashesPubkey = MustPublicKeyFromBase58("SysvarRecentB1ockHashes11111111111111111111")

	// The Rent sysvar contains the rental rate.
	// Currently, the rate is static and set in genesis.
	// The Rent burn percentage is modified by manual feature activation.
	SysVarRentPubkey = MustPublicKeyFromBase58("SysvarRent111111111111111111111111111111111")

	//
	SysVarRewardsPubkey = MustPublicKeyFromBase58("SysvarRewards111111111111111111111111111111")

	// The SlotHashes sysvar contains the most recent hashes of the slot's parent banks.
	// It is updated every slot.
	SysVarSlotHashesPubkey = MustPublicKeyFromBase58("SysvarS1otHashes111111111111111111111111111")

	// The SlotHistory sysvar contains a bitvector of slots present over the last epoch. It is updated every slot.
	SysVarSlotHistoryPubkey = MustPublicKeyFromBase58("SysvarS1otHistory11111111111111111111111111")

	// The StakeHistory sysvar contains the history of cluster-wide stake activations and de-activations per epoch.
	// It is updated at the start of every epoch.
	SysVarStakeHistoryPubkey = MustPublicKeyFromBase58("SysvarStakeHistory1111111111111111111111111")
)

From https://github.com/solana-labs/solana/blob/94ab0eb49f1bce18d0a157dfe7a2bb1fb39dbe2c/docs/src/developing/runtime-facilities/sysvars.md

View Source
var InstructionDecoderRegistry = map[string]InstructionDecoder{}
View Source
var (
	// The Mint for native SOL Token accounts
	SolMint = MustPublicKeyFromBase58("So11111111111111111111111111111111111111112")
)
View Source
var (
	TokenMetadataProgramID = MustPublicKeyFromBase58("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s")
)

Functions

func DecimalsInBigInt

func DecimalsInBigInt(decimal uint32) *big.Int

func DecodeInstruction

func DecodeInstruction(programID PublicKey, accounts []*AccountMeta, data []byte) (interface{}, error)

func IsAnyOfEncodingType added in v0.3.5

func IsAnyOfEncodingType(candidate EncodingType, allowed ...EncodingType) bool

IsAnyOfEncodingType checks whether the provided `candidate` is any of the `allowed`.

func RegisterInstructionDecoder

func RegisterInstructionDecoder(programID PublicKey, decoder InstructionDecoder)

Types

type AccountMeta

type AccountMeta struct {
	PublicKey  PublicKey
	IsWritable bool
	IsSigner   bool
}

func Meta added in v0.4.0

func Meta(
	pubKey PublicKey,
) *AccountMeta

Meta intializes a new AccountMeta with the provided pubKey.

func NewAccountMeta added in v0.4.0

func NewAccountMeta(
	pubKey PublicKey,
	WRITE bool,
	SIGNER bool,
) *AccountMeta

func (*AccountMeta) SIGNER added in v0.4.0

func (meta *AccountMeta) SIGNER() *AccountMeta

SIGNER sets IsSigner to true.

func (*AccountMeta) WRITE added in v0.4.0

func (meta *AccountMeta) WRITE() *AccountMeta

WRITE sets IsWritable to true.

type AccountMetaSlice added in v0.4.0

type AccountMetaSlice []*AccountMeta

func (*AccountMetaSlice) Append added in v0.4.0

func (slice *AccountMetaSlice) Append(account *AccountMeta)

func (AccountMetaSlice) GetAccounts added in v0.4.0

func (slice AccountMetaSlice) GetAccounts() (out []*AccountMeta)

func (AccountMetaSlice) GetSigners added in v0.4.0

func (slice AccountMetaSlice) GetSigners() []*AccountMeta

GetSigners returns the accounts that are signers.

func (AccountMetaSlice) Len added in v0.4.4

func (slice AccountMetaSlice) Len() int

func (*AccountMetaSlice) SetAccounts added in v0.4.0

func (slice *AccountMetaSlice) SetAccounts(accounts []*AccountMeta) error

func (AccountMetaSlice) SplitFrom added in v0.4.4

func (slice AccountMetaSlice) SplitFrom(index int) (AccountMetaSlice, AccountMetaSlice)

type AccountsGettable added in v0.4.0

type AccountsGettable interface {
	GetAccounts() (accounts []*AccountMeta)
}

type AccountsSettable added in v0.4.0

type AccountsSettable interface {
	SetAccounts(accounts []*AccountMeta) error
}

type Base58

type Base58 []byte

func (Base58) MarshalJSON

func (t Base58) MarshalJSON() ([]byte, error)

func (Base58) String

func (t Base58) String() string

func (*Base58) UnmarshalJSON

func (t *Base58) UnmarshalJSON(data []byte) (err error)

type ByteWrapper

type ByteWrapper struct {
	io.Reader
}

func (*ByteWrapper) ReadByte

func (w *ByteWrapper) ReadByte() (byte, error)

type CompiledInstruction

type CompiledInstruction struct {
	// Index into the message.accountKeys array indicating the program account that executes this instruction.
	// NOTE: it is actually a uint8, but using a uint16 because uint8 is treated as a byte everywhere,
	// and that can be an issue.
	ProgramIDIndex uint16 `json:"programIdIndex"`

	AccountCount bin.Varuint16 `json:"-" bin:"sizeof=Accounts"`
	DataLength   bin.Varuint16 `json:"-" bin:"sizeof=Data"`

	// List of ordered indices into the message.accountKeys array indicating which accounts to pass to the program.
	// NOTE: it is actually a []uint8, but using a uint16 because []uint8 is treated as a []byte everywhere,
	// and that can be an issue.
	Accounts []uint16 `json:"accounts"`

	// The program input data encoded in a base-58 string.
	Data Base58 `json:"data"`
}

func (*CompiledInstruction) ResolveInstructionAccounts

func (ci *CompiledInstruction) ResolveInstructionAccounts(message *Message) (out []*AccountMeta)

type Data

type Data struct {
	Content  []byte
	Encoding EncodingType
}

func (Data) MarshalJSON

func (t Data) MarshalJSON() ([]byte, error)

func (Data) String

func (t Data) String() string

func (*Data) UnmarshalJSON

func (t *Data) UnmarshalJSON(data []byte) (err error)

type DurationSeconds added in v1.0.1

type DurationSeconds int64

func (DurationSeconds) Duration added in v1.0.1

func (res DurationSeconds) Duration() time.Duration

func (DurationSeconds) String added in v1.0.1

func (res DurationSeconds) String() string

type EncodingType

type EncodingType string
const (
	EncodingBase58     EncodingType = "base58"      // limited to Account data of less than 129 bytes
	EncodingBase64     EncodingType = "base64"      // will return base64 encoded data for Account data of any size
	EncodingBase64Zstd EncodingType = "base64+zstd" // compresses the Account data using Zstandard and base64-encodes the result

	// attempts to use program-specific state parsers to
	// return more human-readable and explicit account state data.
	// If "jsonParsed" is requested but a parser cannot be found,
	// the field falls back to "base64" encoding, detectable when the data field is type <string>.
	// Cannot be used if specifying dataSlice parameters (offset, length).
	EncodingJSONParsed EncodingType = "jsonParsed"

	EncodingJSON EncodingType = "json" // NOTE: you're probably looking for EncodingJSONParsed
)

type GenericInstruction added in v0.5.0

type GenericInstruction struct {
	AccountValues AccountMetaSlice
	ProgID        PublicKey
	DataBytes     []byte
}

func NewInstruction added in v0.5.0

func NewInstruction(
	programID PublicKey,
	accounts AccountMetaSlice,
	data []byte,
) *GenericInstruction

NewInstruction creates a generic instruction with the provided programID, accounts, and data bytes.

func (*GenericInstruction) Accounts added in v0.5.0

func (in *GenericInstruction) Accounts() []*AccountMeta

func (*GenericInstruction) Data added in v0.5.0

func (in *GenericInstruction) Data() ([]byte, error)

func (*GenericInstruction) ProgramID added in v0.5.0

func (in *GenericInstruction) ProgramID() PublicKey

type Hash

type Hash PublicKey

func HashFromBase58

func HashFromBase58(in string) (Hash, error)

func HashFromBytes added in v1.0.2

func HashFromBytes(in []byte) Hash

func MustHashFromBase58

func MustHashFromBase58(in string) Hash

func (Hash) Equals

func (ha Hash) Equals(pb Hash) bool

func (Hash) IsZero

func (ha Hash) IsZero() bool

func (Hash) MarshalJSON

func (ha Hash) MarshalJSON() ([]byte, error)

func (Hash) String

func (ha Hash) String() string

func (*Hash) UnmarshalJSON

func (ha *Hash) UnmarshalJSON(data []byte) (err error)

type Instruction

type Instruction interface {
	ProgramID() PublicKey     // the programID the instruction acts on
	Accounts() []*AccountMeta // returns the list of accounts the instructions requires
	Data() ([]byte, error)    // the binary encoded instructions
}

type InstructionDecoder

type InstructionDecoder func(instructionAccounts []*AccountMeta, data []byte) (interface{}, error)

InstructionDecoder receives the AccountMeta FOR THAT INSTRUCTION, and not the accounts of the *Message object. Resolve with CompiledInstruction.ResolveInstructionAccounts(message) beforehand.

type Message

type Message struct {
	// List of base-58 encoded public keys used by the transaction,
	// including by the instructions and for signatures.
	// The first `message.header.numRequiredSignatures` public keys must sign the transaction.
	AccountKeys []PublicKey `json:"accountKeys"`

	// Details the account types and signatures required by the transaction.
	Header MessageHeader `json:"header"`

	// A base-58 encoded hash of a recent block in the ledger used to
	// prevent transaction duplication and to give transactions lifetimes.
	RecentBlockhash Hash `json:"recentBlockhash"`

	// List of program instructions that will be executed in sequence
	// and committed in one atomic transaction if all succeed.
	Instructions []CompiledInstruction `json:"instructions"`
}

func (*Message) AccountMetaList

func (m *Message) AccountMetaList() (out []*AccountMeta)

func (*Message) EncodeToTree added in v0.4.0

func (mx *Message) EncodeToTree(txTree treeout.Branches)

func (*Message) IsSigner

func (m *Message) IsSigner(account PublicKey) bool

func (*Message) IsWritable

func (m *Message) IsWritable(account PublicKey) bool

func (*Message) MarshalBinary added in v0.3.5

func (mx *Message) MarshalBinary() ([]byte, error)

func (*Message) MarshalWithEncoder added in v0.4.0

func (mx *Message) MarshalWithEncoder(encoder *bin.Encoder) error

func (*Message) ResolveProgramIDIndex

func (m *Message) ResolveProgramIDIndex(programIDIndex uint16) (PublicKey, error)

func (*Message) TouchAccount

func (m *Message) TouchAccount(account PublicKey) bool

func (*Message) UnmarshalWithDecoder added in v0.4.0

func (mx *Message) UnmarshalWithDecoder(decoder *bin.Decoder) (err error)

type MessageHeader

type MessageHeader struct {
	// The total number of signatures required to make the transaction valid.
	// The signatures must match the first `numRequiredSignatures` of `message.account_keys`.
	NumRequiredSignatures uint8 `json:"numRequiredSignatures"`

	// The last numReadonlySignedAccounts of the signed keys are read-only accounts.
	// Programs may process multiple transactions that load read-only accounts within
	// a single PoH entry, but are not permitted to credit or debit lamports or modify
	// account data.
	// Transactions targeting the same read-write account are evaluated sequentially.
	NumReadonlySignedAccounts uint8 `json:"numReadonlySignedAccounts"`

	// The last `numReadonlyUnsignedAccounts` of the unsigned keys are read-only accounts.
	NumReadonlyUnsignedAccounts uint8 `json:"numReadonlyUnsignedAccounts"`
}

func (*MessageHeader) EncodeToTree added in v0.4.0

func (header *MessageHeader) EncodeToTree(mxBranch treeout.Branches)

type Padding

type Padding []byte

type PrivateKey

type PrivateKey []byte

func MustPrivateKeyFromBase58

func MustPrivateKeyFromBase58(in string) PrivateKey

func NewRandomPrivateKey

func NewRandomPrivateKey() (PrivateKey, error)

func PrivateKeyFromBase58

func PrivateKeyFromBase58(privkey string) (PrivateKey, error)

func PrivateKeyFromSolanaKeygenFile

func PrivateKeyFromSolanaKeygenFile(file string) (PrivateKey, error)

func (PrivateKey) PublicKey

func (k PrivateKey) PublicKey() PublicKey

func (PrivateKey) Sign

func (k PrivateKey) Sign(payload []byte) (Signature, error)

func (PrivateKey) String

func (k PrivateKey) String() string

type PublicKey

type PublicKey [PublicKeyLength]byte

func CreateProgramAddress added in v0.4.0

func CreateProgramAddress(seeds [][]byte, programID PublicKey) (PublicKey, error)

Create a program address. Ported from https://github.com/solana-labs/solana/blob/216983c50e0a618facc39aa07472ba6d23f1b33a/sdk/program/src/pubkey.rs#L204

func FindAssociatedTokenAddress added in v0.4.0

func FindAssociatedTokenAddress(
	wallet PublicKey,
	mint PublicKey,
) (PublicKey, uint8, error)

func FindProgramAddress added in v0.4.0

func FindProgramAddress(seed [][]byte, programID PublicKey) (PublicKey, uint8, error)

Find a valid program address and its corresponding bump seed.

func FindTokenMetadataAddress added in v1.0.2

func FindTokenMetadataAddress(mint PublicKey) (PublicKey, uint8, error)

FindTokenMetadataAddress returns the token metadata program-derived address given a SPL token mint address.

func MustPublicKeyFromBase58

func MustPublicKeyFromBase58(in string) PublicKey

func PublicKeyFromBase58

func PublicKeyFromBase58(in string) (out PublicKey, err error)

func PublicKeyFromBytes

func PublicKeyFromBytes(in []byte) (out PublicKey)

func (PublicKey) Bytes added in v0.4.0

func (p PublicKey) Bytes() []byte

func (PublicKey) Equals

func (p PublicKey) Equals(pb PublicKey) bool

func (PublicKey) IsZero

func (p PublicKey) IsZero() bool

IsZero returns whether the public key is zero. NOTE: the System Program public key is also zero.

func (PublicKey) MarshalJSON

func (p PublicKey) MarshalJSON() ([]byte, error)

func (PublicKey) MarshalText added in v0.3.4

func (p PublicKey) MarshalText() ([]byte, error)

func (PublicKey) String

func (p PublicKey) String() string

func (PublicKey) ToPointer added in v0.4.0

func (p PublicKey) ToPointer() *PublicKey

ToPointer returns a pointer to the pubkey.

func (*PublicKey) UnmarshalJSON

func (p *PublicKey) UnmarshalJSON(data []byte) (err error)

func (*PublicKey) UnmarshalText added in v0.3.4

func (p *PublicKey) UnmarshalText(data []byte) (err error)

type PublicKeySlice added in v0.4.0

type PublicKeySlice []PublicKey

func (*PublicKeySlice) Append added in v0.4.0

func (slice *PublicKeySlice) Append(pubkey PublicKey)

func (PublicKeySlice) Has added in v0.4.0

func (slice PublicKeySlice) Has(pubkey PublicKey) bool

func (*PublicKeySlice) UniqueAppend added in v0.4.0

func (slice *PublicKeySlice) UniqueAppend(pubkey PublicKey) bool

UniqueAppend appends the provided pubkey only if it is not already present in the slice. Returns true when the provided pubkey wasn't already present.

type Signature

type Signature [64]byte

func MustSignatureFromBase58

func MustSignatureFromBase58(in string) Signature

func SignatureFromBase58

func SignatureFromBase58(in string) (out Signature, err error)

func (Signature) Equals

func (sig Signature) Equals(pb Signature) bool

func (Signature) IsZero

func (sig Signature) IsZero() bool

func (Signature) MarshalJSON

func (p Signature) MarshalJSON() ([]byte, error)

func (Signature) String

func (p Signature) String() string

func (*Signature) UnmarshalJSON

func (p *Signature) UnmarshalJSON(data []byte) (err error)

type Transaction

type Transaction struct {
	// A list of base-58 encoded signatures applied to the transaction.
	// The list is always of length `message.header.numRequiredSignatures` and not empty.
	// The signature at index `i` corresponds to the public key at index
	// `i` in `message.account_keys`. The first one is used as the transaction id.
	Signatures []Signature `json:"signatures"`

	// Defines the content of the transaction.
	Message Message `json:"message"`
}

func MustTransactionFromDecoder added in v0.4.1

func MustTransactionFromDecoder(decoder *bin.Decoder) *Transaction

func NewTransaction

func NewTransaction(instructions []Instruction, recentBlockHash Hash, opts ...TransactionOption) (*Transaction, error)

func TransactionFromDecoder added in v0.4.0

func TransactionFromDecoder(decoder *bin.Decoder) (*Transaction, error)

func (*Transaction) AccountMetaList

func (t *Transaction) AccountMetaList() (out []*AccountMeta)

func (*Transaction) EncodeToTree added in v0.4.0

func (tx *Transaction) EncodeToTree(parent treeout.Branches)

func (*Transaction) EncodeTree added in v0.4.0

func (tx *Transaction) EncodeTree(encoder *text.TreeEncoder) (int, error)

func (*Transaction) IsSigner

func (t *Transaction) IsSigner(account PublicKey) bool

func (*Transaction) IsWritable

func (t *Transaction) IsWritable(account PublicKey) bool

func (*Transaction) MarshalBinary added in v0.3.5

func (tx *Transaction) MarshalBinary() ([]byte, error)

func (*Transaction) MarshalWithEncoder added in v0.4.0

func (tx *Transaction) MarshalWithEncoder(encoder *bin.Encoder) error

func (*Transaction) ResolveProgramIDIndex

func (t *Transaction) ResolveProgramIDIndex(programIDIndex uint16) (PublicKey, error)

func (*Transaction) Sign

func (tx *Transaction) Sign(getter privateKeyGetter) (out []Signature, err error)

func (*Transaction) TouchAccount

func (t *Transaction) TouchAccount(account PublicKey) bool

func (*Transaction) UnmarshalWithDecoder added in v0.4.0

func (tx *Transaction) UnmarshalWithDecoder(decoder *bin.Decoder) (err error)

type TransactionBuilder added in v0.4.0

type TransactionBuilder struct {
	// contains filtered or unexported fields
}

func NewTransactionBuilder added in v0.4.0

func NewTransactionBuilder() *TransactionBuilder

NewTransactionBuilder creates a new instruction builder.

func (*TransactionBuilder) AddInstruction added in v0.4.0

func (builder *TransactionBuilder) AddInstruction(instruction Instruction) *TransactionBuilder

AddInstruction adds the provided instruction to the builder.

func (*TransactionBuilder) Build added in v0.4.0

func (builder *TransactionBuilder) Build() (*Transaction, error)

Build builds and returns a *Transaction.

func (*TransactionBuilder) SetFeePayer added in v0.4.0

func (builder *TransactionBuilder) SetFeePayer(feePayer PublicKey) *TransactionBuilder

Set transaction fee payer. If not set, defaults to first signer account of the first instruction.

func (*TransactionBuilder) SetRecentBlockHash added in v0.4.0

func (builder *TransactionBuilder) SetRecentBlockHash(recentBlockHash Hash) *TransactionBuilder

SetRecentBlockHash sets the recent blockhash for the instruction builder.

func (*TransactionBuilder) WithOpt added in v0.4.0

WithOpt adds a TransactionOption.

type TransactionOption

type TransactionOption interface {
	// contains filtered or unexported methods
}

func TransactionPayer

func TransactionPayer(payer PublicKey) TransactionOption

type UnixTimeSeconds added in v0.5.0

type UnixTimeSeconds int64

Unix timestamp (seconds since the Unix epoch)

func (UnixTimeSeconds) String added in v0.5.1

func (res UnixTimeSeconds) String() string

func (UnixTimeSeconds) Time added in v0.5.0

func (res UnixTimeSeconds) Time() time.Time

type Wallet added in v0.4.2

type Wallet struct {
	PrivateKey PrivateKey
}

Wallet is a wrapper around a PrivateKey

func NewWallet added in v0.4.2

func NewWallet() *Wallet

func WalletFromPrivateKeyBase58 added in v0.4.2

func WalletFromPrivateKeyBase58(privateKey string) (*Wallet, error)

func (*Wallet) PublicKey added in v0.4.2

func (a *Wallet) PublicKey() PublicKey

Directories

Path Synopsis
cmd
programs
serum
Code generated by rice embed-go; DO NOT EDIT.
Code generated by rice embed-go; DO NOT EDIT.
rpc
jsonrpc
Package jsonrpc provides a JSON-RPC 2.0 client that sends JSON-RPC requests and receives JSON-RPC responses using HTTP.
Package jsonrpc provides a JSON-RPC 2.0 client that sends JSON-RPC requests and receives JSON-RPC responses using HTTP.
ws

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL