diff --git a/README.md b/README.md index 79526fe91..65d39045d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Solana SDK library for Go -[![GoDoc](https://pkg.go.dev/badge/github.com/gagliardetto/solana-go?status.svg)](https://pkg.go.dev/github.com/gagliardetto/solana-go@v1.12.0?tab=doc) +[![GoDoc](https://pkg.go.dev/badge/github.com/gagliardetto/solana-go?status.svg)](https://pkg.go.dev/github.com/gagliardetto/solana-go@v1.16.0?tab=doc) [![GitHub tag (latest SemVer pre-release)](https://img.shields.io/github/v/tag/gagliardetto/solana-go?include_prereleases&label=release-tag)](https://github.com/gagliardetto/solana-go/releases) [![Build Status](https://github.com/gagliardetto/solana-go/workflows/tests/badge.svg?branch=main)](https://github.com/gagliardetto/solana-go/actions?query=branch%3Amain) [![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/gagliardetto/solana-go/main)](https://www.tickgit.com/browse?repo=github.com/gagliardetto/solana-go&branch=main) @@ -19,27 +19,27 @@ More contracts to come. ## Contents - [Solana SDK library for Go](#solana-sdk-library-for-go) - - [Contents' Index](#contents) + - [Contents](#contents) - [Features](#features) - [Current development status](#current-development-status) + - [Note](#note) - [Requirements](#requirements) - [Installation](#installation) - [Pretty-Print transactions/instructions](#pretty-print-transactionsinstructions) - [SendAndConfirmTransaction](#sendandconfirmtransaction) - [Address Lookup Tables](#address-lookup-tables) - - [Decode an instruction data](#parsedecode-an-instruction-from-a-transaction) + - [Parse/decode an instruction from a transaction](#parsedecode-an-instruction-from-a-transaction) - [Borsh encoding/decoding](#borsh-encodingdecoding) - [ZSTD account data encoding](#zstd-account-data-encoding) - - [Custom Headers for authenticating with RPC providers](#custom-headers-for-authenticating-with-rpc-providers) - [Working with rate-limited RPC providers](#working-with-rate-limited-rpc-providers) + - [Custom Headers for authenticating with RPC providers](#custom-headers-for-authenticating-with-rpc-providers) - [Timeouts and Custom HTTP Clients](#timeouts-and-custom-http-clients) - [Examples](#examples) - - [Create Account/Wallet](#create-account-wallet) - - [Load/parse keys](#loadparse-private-and-public-keys) - - [Transfer SOL from a wallet to another](#transfer-sol-from-one-wallet-to-another-wallet) - - [RPC (index)](#rpc-usage-examples) - - [RPC examples](#rpc-methods) - - [Websocket Subscription examples](#websocket-subscriptions) + - [Create account (wallet)](#create-account-wallet) + - [Load/parse private and public keys](#loadparse-private-and-public-keys) + - [Transfer Sol from one wallet to another wallet](#transfer-sol-from-one-wallet-to-another-wallet) + - [RPC Methods](#rpc-methods) + - [WebSocket Subscriptions](#websocket-subscriptions) - [Contributing](#contributing) - [License](#license) - [Credits](#credits) @@ -72,7 +72,7 @@ More contracts to come. ## Current development status -There is currently **no stable release**. The SDK is actively developed and latest is `v1.12.0` which is an `alpha` release. +There is currently **no stable release**. The SDK is actively developed and latest is `v1.16.0` which is an `alpha` release. The RPC and WS client implementation is based on the [Solana RPC API documentation](https://solana.com/docs/rpc). @@ -89,7 +89,7 @@ The RPC and WS client implementation is based on the [Solana RPC API documentati ```bash $ cd my-project -$ go get github.com/gagliardetto/solana-go@v1.12.0 +$ go get github.com/gagliardetto/solana-go@v1.16.0 ``` ## Pretty-Print transactions/instructions @@ -813,2045 +813,19 @@ func main() { ``` -## RPC usage examples - -- [RPC Methods](#rpc-methods) - - [GetAccountInfo](#index--rpc--getaccountinfo) - - [GetBalance](#index--rpc--getbalance) - - [GetBlock](#index--rpc--getblock) - - [GetBlockCommitment](#index--rpc--getblockcommitment) - - [GetBlockHeight](#index--rpc--getblockheight) - - [GetBlockProduction](#index--rpc--getblockproduction) - - [GetBlockTime](#index--rpc--getblocktime) - - [GetBlocks](#index--rpc--getblocks) - - [GetBlocksWithLimit](#index--rpc--getblockswithlimit) - - [GetClusterNodes](#index--rpc--getclusternodes) - - [GetEpochInfo](#index--rpc--getepochinfo) - - [GetEpochSchedule](#index--rpc--getepochschedule) - - [GetFeeForMessage](#index--rpc--getfeeformessage) - - [GetFirstAvailableBlock](#index--rpc--getfirstavailableblock) - - [GetGenesisHash](#index--rpc--getgenesishash) - - [GetHealth](#index--rpc--gethealth) - - [GetHighestSnapshotSlot](#index--rpc--gethighestsnapshotslot) - - [GetLatestBlockhash](#index--rpc--getlatestblockhash) - - [GetIdentity](#index--rpc--getidentity) - - [GetInflationGovernor](#index--rpc--getinflationgovernor) - - [GetInflationRate](#index--rpc--getinflationrate) - - [GetInflationReward](#index--rpc--getinflationreward) - - [GetLargestAccounts](#index--rpc--getlargestaccounts) - - [GetLeaderSchedule](#index--rpc--getleaderschedule) - - [GetMaxRetransmitSlot](#index--rpc--getmaxretransmitslot) - - [GetMaxShredInsertSlot](#index--rpc--getmaxshredinsertslot) - - [GetMinimumBalanceForRentExemption](#index--rpc--getminimumbalanceforrentexemption) - - [GetMultipleAccounts](#index--rpc--getmultipleaccounts) - - [GetProgramAccounts](#index--rpc--getprogramaccounts) - - [GetRecentPerformanceSamples](#index--rpc--getrecentperformancesamples) - - [GetRecentPrioritizationFees](#index--rpc--getrecentprioritizationfees) - - [GetSignatureStatuses](#index--rpc--getsignaturestatuses) - - [GetSignaturesForAddress](#index--rpc--getsignaturesforaddress) - - [GetSlot](#index--rpc--getslot) - - [GetSlotLeader](#index--rpc--getslotleader) - - [GetSlotLeaders](#index--rpc--getslotleaders) - - [GetSupply](#index--rpc--getsupply) - - [GetTokenAccountBalance](#index--rpc--gettokenaccountbalance) - - [GetTokenAccountsByDelegate](#index--rpc--gettokenaccountsbydelegate) - - [GetTokenAccountsByOwner](#index--rpc--gettokenaccountsbyowner) - - [GetTokenLargestAccounts](#index--rpc--gettokenlargestaccounts) - - [GetTokenSupply](#index--rpc--gettokensupply) - - [GetTransaction](#index--rpc--gettransaction) - - [GetTransactionCount](#index--rpc--gettransactioncount) - - [GetVersion](#index--rpc--getversion) - - [GetVoteAccounts](#index--rpc--getvoteaccounts) - - [IsBlockhashValid](#index--rpc--isblockhashvalid) - - [MinimumLedgerSlot](#index--rpc--minimumledgerslot) - - [RequestAirdrop](#index--rpc--requestairdrop) - - [SendTransaction](#index--rpc--sendtransaction) - - [SimulateTransaction](#index--rpc--simulatetransaction) -- [Websocket Subscriptions](#websocket-subscriptions) - - [AccountSubscribe](#index--ws-subscriptions--accountsubscribe) - - [LogsSubscribe](#index--ws-subscriptions--logssubscribe) - - [ProgramSubscribe](#index--ws-subscriptions--programsubscribe) - - [RootSubscribe](#index--ws-subscriptions--rootsubscribe) - - [SignatureSubscribe](#index--ws-subscriptions--signaturesubscribe) - - [SlotSubscribe](#index--ws-subscriptions--slotsubscribe) - - [VoteSubscribe](#index--ws-subscriptions--votesubscribe) - -### RPC Methods - -#### [index](#contents) > [RPC](#rpc-methods) > GetAccountInfo - -```go -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.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.GetBinary()).Decode(&mint) - if err != nil { - panic(err) - } - spew.Dump(mint) - } -} -``` - -#### [index](#contents) > [RPC](#rpc-methods) > GetBalance - -```go -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](#contents) > [RPC](#rpc-methods) > GetBlock - -```go -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.GetLatestBlockhash(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](#contents) > [RPC](#rpc-methods) > GetBlockCommitment - -```go -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.GetLatestBlockhash(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](#contents) > [RPC](#rpc-methods) > GetBlockHeight - -```go -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](#contents) > [RPC](#rpc-methods) > GetBlockProduction - -```go -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](#contents) > [RPC](#rpc-methods) > GetBlockTime - -```go -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.GetLatestBlockhash( - 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](#contents) > [RPC](#rpc-methods) > GetBlocks - -```go -package main +## RPC Methods -import ( - "context" +All RPC methods from the [Solana JSON RPC API](https://solana.com/docs/rpc) are supported. +Each method has a testable example in [`rpc/example_test.go`](rpc/example_test.go) that is rendered on +[pkg.go.dev](https://pkg.go.dev/github.com/gagliardetto/solana-go@v1.16.0/rpc#pkg-examples). - "github.com/davecgh/go-spew/spew" - "github.com/gagliardetto/solana-go/rpc" -) -func main() { - endpoint := rpc.TestNet_RPC - client := rpc.New(endpoint) +## WebSocket Subscriptions - example, err := client.GetLatestBlockhash( - context.TODO(), - rpc.CommitmentFinalized, - ) - if err != nil { - panic(err) - } +All WebSocket subscriptions from the [Solana WebSocket API](https://solana.com/docs/rpc/websocket) are supported. +Each subscription has a testable example in [`rpc/ws/example_test.go`](rpc/ws/example_test.go) that is rendered on +[pkg.go.dev](https://pkg.go.dev/github.com/gagliardetto/solana-go@v1.16.0/rpc/ws#pkg-examples). - 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](#contents) > [RPC](#rpc-methods) > GetBlocksWithLimit - -```go -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.GetLatestBlockhash( - 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](#contents) > [RPC](#rpc-methods) > GetClusterNodes - -```go -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](#contents) > [RPC](#rpc-methods) > GetEpochInfo - -```go -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](#contents) > [RPC](#rpc-methods) > GetEpochSchedule - -```go -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](#contents) > [RPC](#rpc-methods) > GetFeeForMessage - -```go -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.GetFeeForMessage( - context.Background(), - "AQABAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAA", - rpc.CommitmentProcessed, - ) - if err != nil { - panic(err) - } - spew.Dump(example) -} -``` - -#### [index](#contents) > [RPC](#rpc-methods) > GetFirstAvailableBlock - -```go -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](#contents) > [RPC](#rpc-methods) > GetGenesisHash - -```go -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](#contents) > [RPC](#rpc-methods) > GetHealth - -```go -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](#contents) > [RPC](#rpc-methods) > GetHighestSnapshotSlot - -```go -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.GetHighestSnapshotSlot( - context.Background(), - ) - if err != nil { - panic(err) - } - spew.Dump(example) -} -``` - -#### [index](#contents) > [RPC](#rpc-methods) > GetLatestBlockhash - -NEW: This method is only available in solana-core v1.9 or newer. Please use getRecentBlockhash for solana-core v1.8 - -```go -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.GetLatestBlockhash( - context.Background(), - rpc.CommitmentFinalized, - ) - if err != nil { - panic(err) - } - spew.Dump(example) -} -``` - -#### [index](#contents) > [RPC](#rpc-methods) > GetIdentity - -```go -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](#contents) > [RPC](#rpc-methods) > GetInflationGovernor - -```go -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](#contents) > [RPC](#rpc-methods) > GetInflationRate - -```go -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](#contents) > [RPC](#rpc-methods) > GetInflationReward - -```go -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](#contents) > [RPC](#rpc-methods) > GetLargestAccounts - -```go -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](#contents) > [RPC](#rpc-methods) > GetLeaderSchedule - -```go -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](#contents) > [RPC](#rpc-methods) > GetMaxRetransmitSlot - -```go -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](#contents) > [RPC](#rpc-methods) > GetMaxShredInsertSlot - -```go -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](#contents) > [RPC](#rpc-methods) > GetMinimumBalanceForRentExemption - -```go -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](#contents) > [RPC](#rpc-methods) > GetMultipleAccounts - -```go -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](#contents) > [RPC](#rpc-methods) > GetProgramAccounts - -```go -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](#contents) > [RPC](#rpc-methods) > GetRecentPerformanceSamples - -```go -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](#contents) > [RPC](#rpc-methods) > GetRecentPrioritizationFees - -```go -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.GetRecentPrioritizationFees( - context.TODO(), - []solana.PublicKey{ - solana.MustPublicKeyFromBase58("q5BgreVhTyBH1QCeriVb7kQYEPneanFXPLjvyjdf8M3"), - }, - ) - if err != nil { - panic(err) - } - spew.Dump(out) -} -``` - -#### [index](#contents) > [RPC](#rpc-methods) > GetSignatureStatuses - -```go -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](#contents) > [RPC](#rpc-methods) > GetSignaturesForAddress - -```go -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](#contents) > [RPC](#rpc-methods) > GetSlot - -```go -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](#contents) > [RPC](#rpc-methods) > GetSlotLeader - -```go -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](#contents) > [RPC](#rpc-methods) > GetSlotLeaders - -```go -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.GetLatestBlockhash( - 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](#contents) > [RPC](#rpc-methods) > GetSupply - -```go -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](#contents) > [RPC](#rpc-methods) > GetTokenAccountBalance - -```go -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](#contents) > [RPC](#rpc-methods) > GetTokenAccountsByDelegate - -```go -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.WrappedSol, - }, - nil, - ) - if err != nil { - panic(err) - } - spew.Dump(out) -} -``` - -#### [index](#contents) > [RPC](#rpc-methods) > GetTokenAccountsByOwner - -```go -package main - -import ( - "context" - - "github.com/davecgh/go-spew/spew" - bin "github.com/gagliardetto/binary" - "github.com/gagliardetto/solana-go" - "github.com/gagliardetto/solana-go/programs/token" - "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.WrappedSol.ToPointer(), - }, - &rpc.GetTokenAccountsOpts{ - Encoding: solana.EncodingBase64Zstd, - }, - ) - if err != nil { - panic(err) - } - spew.Dump(out) - - { - tokenAccounts := make([]token.Account, 0) - for _, rawAccount := range out.Value { - var tokAcc token.Account - - data := rawAccount.Account.Data.GetBinary() - dec := bin.NewBinDecoder(data) - err := dec.Decode(&tokAcc) - if err != nil { - panic(err) - } - tokenAccounts = append(tokenAccounts, tokAcc) - } - spew.Dump(tokenAccounts) - } -} - -``` - -#### [index](#contents) > [RPC](#rpc-methods) > GetTokenLargestAccounts - -```go -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](#contents) > [RPC](#rpc-methods) > GetTokenSupply - -```go -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](#contents) > [RPC](#rpc-methods) > GetTransaction - -```go -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, - &rpc.GetTransactionOpts{ - Encoding: solana.EncodingBase64, - }, - ) - if err != nil { - panic(err) - } - spew.Dump(out) - spew.Dump(out.Transaction.GetBinary()) - - decodedTx, err := solana.TransactionFromDecoder(bin.NewBinDecoder(out.Transaction.GetBinary())) - if err != nil { - panic(err) - } - spew.Dump(decodedTx) - } - { - out, err := client.GetTransaction( - context.TODO(), - txSig, - nil, - ) - if err != nil { - panic(err) - } - spew.Dump(out) - spew.Dump(out.Transaction.GetParsedTransaction()) - } -} -``` - -#### [index](#contents) > [RPC](#rpc-methods) > GetTransactionCount - -```go -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](#contents) > [RPC](#rpc-methods) > GetVersion - -```go -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](#contents) > [RPC](#rpc-methods) > GetVoteAccounts - -```go -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](#contents) > [RPC](#rpc-methods) > IsBlockhashValid - -```go -package main - -import ( - "context" - "fmt" - "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) - - blockHash := solana.MustHashFromBase58("J7rBdM6AecPDEZp8aPq5iPSNKVkU5Q76F3oAV4eW5wsW") - out, err := client.IsBlockhashValid( - context.TODO(), - blockHash, - rpc.CommitmentFinalized, - ) - if err != nil { - panic(err) - } - spew.Dump(out) - spew.Dump(out.Value) // true or false - - fmt.Println("is blockhash valid:", out.Value) -} -``` - -#### [index](#contents) > [RPC](#rpc-methods) > MinimumLedgerSlot - -```go -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](#contents) > [RPC](#rpc-methods) > RequestAirdrop - -```go -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](#contents) > [RPC](#rpc-methods) > SendTransaction - -```go -package main - -func main() { - -} -``` - -#### [index](#contents) > [RPC](#rpc-methods) > SimulateTransaction - -```go -package main - -func main() { - -} -``` - -### Websocket Subscriptions - -#### [index](#contents) > [WS Subscriptions](#websocket-subscriptions) > AccountSubscribe - -```go -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() { - ctx := context.Background() - 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(ctx) - 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(ctx) - if err != nil { - panic(err) - } - spew.Dump(got) - } - } -} -``` - -#### [index](#contents) > [WS Subscriptions](#websocket-subscriptions) > LogsSubscribe - -```go -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() { - ctx := context.Background() - 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(ctx) - 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(ctx) - if err != nil { - panic(err) - } - spew.Dump(got) - } - } -} -``` - -#### [index](#contents) > [WS Subscriptions](#websocket-subscriptions) > ProgramSubscribe - -```go -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() { - ctx := context.Background() - 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(ctx) - 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](#contents) > [WS Subscriptions](#websocket-subscriptions) > RootSubscribe - -```go -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() { - ctx := context.Background() - 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(ctx) - if err != nil { - panic(err) - } - spew.Dump(got) - } -} -``` - -#### [index](#contents) > [WS Subscriptions](#websocket-subscriptions) > SignatureSubscribe - -```go -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() { - ctx := context.Background() - 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(ctx) - if err != nil { - panic(err) - } - spew.Dump(got) - } -} -``` - -#### [index](#contents) > [WS Subscriptions](#websocket-subscriptions) > SlotSubscribe - -```go -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() { - ctx := context.Background() - 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(ctx) - if err != nil { - panic(err) - } - spew.Dump(got) - } -} -``` - -#### [index](#contents) > [WS Subscriptions](#websocket-subscriptions) > VoteSubscribe - -```go -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() { - ctx := context.Background() - 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(ctx) - if err != nil { - panic(err) - } - spew.Dump(got) - } -} -``` ## Contributing diff --git a/rpc/example_test.go b/rpc/example_test.go new file mode 100644 index 000000000..b7a089abc --- /dev/null +++ b/rpc/example_test.go @@ -0,0 +1,967 @@ +package rpc_test + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/davecgh/go-spew/spew" + bin "github.com/gagliardetto/binary" + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/programs/token" + "github.com/gagliardetto/solana-go/rpc" +) + +func ExampleClient_GetAccountInfo() { + 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.NewBinDecoder(resp.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) + } + { + 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.NewBinDecoder(resp.GetBinary()).Decode(&mint) + if err != nil { + panic(err) + } + spew.Dump(mint) + } +} + +func ExampleClient_GetBalance() { + 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)) +} + +func ExampleClient_GetBlock() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + example, err := client.GetLatestBlockhash(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) + } +} + +func ExampleClient_GetBlockCommitment() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + example, err := client.GetLatestBlockhash(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) +} + +func ExampleClient_GetBlockHeight() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetBlockHeight( + context.TODO(), + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetBlockProduction() { + 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, + }, + ) + if err != nil { + panic(err) + } + spew.Dump(out) + } +} + +func ExampleClient_GetBlockTime() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + example, err := client.GetLatestBlockhash( + 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)) +} + +func ExampleClient_GetBlocks() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + example, err := client.GetLatestBlockhash( + 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) +} + +func ExampleClient_GetBlocksWithLimit() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + example, err := client.GetLatestBlockhash( + 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) +} + +func ExampleClient_GetClusterNodes() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetClusterNodes( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetEpochInfo() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetEpochInfo( + context.TODO(), + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetEpochSchedule() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetEpochSchedule( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetFeeForMessage() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + example, err := client.GetFeeForMessage( + context.Background(), + "AQABAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAA", + rpc.CommitmentProcessed, + ) + if err != nil { + panic(err) + } + spew.Dump(example) +} + +func ExampleClient_GetFirstAvailableBlock() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetFirstAvailableBlock( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetGenesisHash() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetGenesisHash( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetHealth() { + 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) +} + +func ExampleClient_GetHighestSnapshotSlot() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + example, err := client.GetHighestSnapshotSlot( + context.Background(), + ) + if err != nil { + panic(err) + } + spew.Dump(example) +} + +func ExampleClient_GetLatestBlockhash() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + example, err := client.GetLatestBlockhash( + context.Background(), + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(example) +} + +func ExampleClient_GetIdentity() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetIdentity( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetInflationGovernor() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetInflationGovernor( + context.TODO(), + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetInflationRate() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetInflationRate( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetInflationReward() { + 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) +} + +func ExampleClient_GetLargestAccounts() { + 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) +} + +func ExampleClient_GetLeaderSchedule() { + 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 +} + +func ExampleClient_GetMaxRetransmitSlot() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetMaxRetransmitSlot( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetMaxShredInsertSlot() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetMaxShredInsertSlot( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetMinimumBalanceForRentExemption() { + 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) +} + +func ExampleClient_GetMultipleAccounts() { + 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, + }, + ) + if err != nil { + panic(err) + } + spew.Dump(out) + } +} + +func ExampleClient_GetProgramAccounts() { + 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)) +} + +func ExampleClient_GetRecentPerformanceSamples() { + 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) +} + +func ExampleClient_GetRecentPrioritizationFees() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetRecentPrioritizationFees( + context.TODO(), + []solana.PublicKey{ + solana.MustPublicKeyFromBase58("q5BgreVhTyBH1QCeriVb7kQYEPneanFXPLjvyjdf8M3"), + }, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetSignatureStatuses() { + 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) +} + +func ExampleClient_GetSignaturesForAddress() { + 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) +} + +func ExampleClient_GetSlot() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetSlot( + context.TODO(), + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetSlotLeader() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetSlotLeader( + context.TODO(), + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetSlotLeaders() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + recent, err := client.GetLatestBlockhash( + 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) +} + +func ExampleClient_GetStakeMinimumDelegation() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetStakeMinimumDelegation( + context.TODO(), + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetSupply() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetSupply( + context.TODO(), + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetTokenAccountBalance() { + 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) +} + +func ExampleClient_GetTokenAccountsByDelegate() { + 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").ToPointer(), + }, + nil, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetTokenAccountsByOwner() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + pubKey := solana.MustPublicKeyFromBase58("7HZaCWazgTuuFuajxaaxGYbGnyVKwxvsJKue1W4Nvyro") + out, err := client.GetTokenAccountsByOwner( + context.TODO(), + pubKey, + &rpc.GetTokenAccountsConfig{ + Mint: solana.WrappedSol.ToPointer(), + }, + &rpc.GetTokenAccountsOpts{ + Encoding: solana.EncodingBase64Zstd, + }, + ) + if err != nil { + panic(err) + } + spew.Dump(out) + + { + tokenAccounts := make([]token.Account, 0) + for _, rawAccount := range out.Value { + var tokAcc token.Account + + data := rawAccount.Account.Data.GetBinary() + dec := bin.NewBinDecoder(data) + err := dec.Decode(&tokAcc) + if err != nil { + panic(err) + } + tokenAccounts = append(tokenAccounts, tokAcc) + } + spew.Dump(tokenAccounts) + } +} + +func ExampleClient_GetTokenLargestAccounts() { + 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) +} + +func ExampleClient_GetTokenSupply() { + 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) +} + +func ExampleClient_GetTransaction() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + txSig := solana.MustSignatureFromBase58("4bjVLV1g9SAfv7BSAdNnuSPRbSscADHFe4HegL6YVcuEBMY83edLEvtfjE4jfr6rwdLwKBQbaFiGgoLGtVicDzHq") + { + out, err := client.GetTransaction( + context.TODO(), + txSig, + &rpc.GetTransactionOpts{ + Encoding: solana.EncodingBase64, + }, + ) + if err != nil { + panic(err) + } + spew.Dump(out) + spew.Dump(out.Transaction.GetBinary()) + + decodedTx, err := solana.TransactionFromDecoder(bin.NewBinDecoder(out.Transaction.GetBinary())) + if err != nil { + panic(err) + } + spew.Dump(decodedTx) + } + { + out, err := client.GetTransaction( + context.TODO(), + txSig, + nil, + ) + if err != nil { + panic(err) + } + spew.Dump(out) + + decodedTx, err := out.Transaction.GetTransaction() + if err != nil { + panic(err) + } + spew.Dump(decodedTx) + } +} + +func ExampleClient_GetTransactionCount() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetTransactionCount( + context.TODO(), + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetVersion() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetVersion( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_GetVoteAccounts() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.GetVoteAccounts( + context.TODO(), + &rpc.GetVoteAccountsOpts{ + VotePubkey: solana.MustPublicKeyFromBase58("vot33MHDqT6nSwubGzqtc6m16ChcUywxV7tNULF19Vu").ToPointer(), + }, + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_IsBlockhashValid() { + endpoint := rpc.MainNetBeta_RPC + client := rpc.New(endpoint) + + blockHash := solana.MustHashFromBase58("J7rBdM6AecPDEZp8aPq5iPSNKVkU5Q76F3oAV4eW5wsW") + out, err := client.IsBlockhashValid( + context.TODO(), + blockHash, + rpc.CommitmentFinalized, + ) + if err != nil { + panic(err) + } + spew.Dump(out) + spew.Dump(out.Value) // true or false + + fmt.Println("is blockhash valid:", out.Value) +} + +func ExampleClient_MinimumLedgerSlot() { + endpoint := rpc.TestNet_RPC + client := rpc.New(endpoint) + + out, err := client.MinimumLedgerSlot( + context.TODO(), + ) + if err != nil { + panic(err) + } + spew.Dump(out) +} + +func ExampleClient_RequestAirdrop() { + 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) +} diff --git a/rpc/getStakeMinimumDelegation.go b/rpc/getStakeMinimumDelegation.go new file mode 100644 index 000000000..a70ed2dd8 --- /dev/null +++ b/rpc/getStakeMinimumDelegation.go @@ -0,0 +1,32 @@ +// Copyright 2021 github.com/gagliardetto +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package rpc + +import ( + "context" +) + +// GetStakeMinimumDelegation returns the stake minimum delegation, in lamports. +func (cl *Client) GetStakeMinimumDelegation( + ctx context.Context, + commitment CommitmentType, // optional +) (out *GetStakeMinimumDelegationResult, err error) { + params := []interface{}{} + if commitment != "" { + params = append(params, M{"commitment": string(commitment)}) + } + err = cl.rpcClient.CallForInto(ctx, &out, "getStakeMinimumDelegation", params) + return +} diff --git a/rpc/types.go b/rpc/types.go index f24b2860d..d1c396477 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -41,6 +41,11 @@ type GetBalanceResult struct { Value uint64 `json:"value"` } +type GetStakeMinimumDelegationResult struct { + RPCContext + Value uint64 `json:"value"` +} + type FeeCalculator struct { LamportsPerSignature uint64 `json:"lamportsPerSignature"` } diff --git a/rpc/ws/example_test.go b/rpc/ws/example_test.go new file mode 100644 index 000000000..e1f42137b --- /dev/null +++ b/rpc/ws/example_test.go @@ -0,0 +1,292 @@ +package ws_test + +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 ExampleClient_AccountSubscribe() { + 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(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +} + +func ExampleClient_AccountSubscribeWithOpts() { + client, err := ws.Connect(context.Background(), rpc.MainNetBeta_WS) + if err != nil { + panic(err) + } + program := solana.MustPublicKeyFromBase58("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin") // serum + + // You can specify the data encoding of the returned accounts: + sub, err := client.AccountSubscribeWithOpts( + program, + "", + solana.EncodingBase64, + ) + if err != nil { + panic(err) + } + defer sub.Unsubscribe() + + for { + got, err := sub.Recv(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +} + +func ExampleClient_BlockSubscribe() { + client, err := ws.Connect(context.Background(), rpc.TestNet_WS) + if err != nil { + panic(err) + } + + // NOTE: This subscription is unstable and only available if the validator + // was started with the --rpc-pubsub-enable-block-subscription flag. + sub, err := client.BlockSubscribe( + ws.NewBlockSubscribeFilterAll(), + &ws.BlockSubscribeOpts{ + Commitment: rpc.CommitmentFinalized, + }, + ) + if err != nil { + panic(err) + } + defer sub.Unsubscribe() + + for { + got, err := sub.Recv(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +} + +func ExampleClient_LogsSubscribeMentions() { + 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.CommitmentProcessed, + ) + if err != nil { + panic(err) + } + defer sub.Unsubscribe() + + for { + got, err := sub.Recv(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +} + +func ExampleClient_LogsSubscribe() { + client, err := ws.Connect(context.Background(), rpc.MainNetBeta_WS) + if err != nil { + panic(err) + } + + // Subscribe to all log events: + sub, err := client.LogsSubscribe( + ws.LogsSubscribeFilterAll, + rpc.CommitmentProcessed, + ) + if err != nil { + panic(err) + } + defer sub.Unsubscribe() + + for { + got, err := sub.Recv(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +} + +func ExampleClient_ProgramSubscribeWithOpts() { + 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.CommitmentProcessed, + solana.EncodingBase64Zstd, + nil, + ) + if err != nil { + panic(err) + } + defer sub.Unsubscribe() + + for { + got, err := sub.Recv(context.Background()) + 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) + } + } +} + +func ExampleClient_RootSubscribe() { + 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(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +} + +func ExampleClient_SignatureSubscribe() { + 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(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +} + +func ExampleClient_SlotSubscribe() { + 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(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +} + +func ExampleClient_SlotsUpdatesSubscribe() { + client, err := ws.Connect(context.Background(), rpc.TestNet_WS) + if err != nil { + panic(err) + } + + // NOTE: This subscription is unstable; the format of this subscription + // may change in the future and it may not always be supported. + sub, err := client.SlotsUpdatesSubscribe() + if err != nil { + panic(err) + } + defer sub.Unsubscribe() + + for { + got, err := sub.Recv(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +} + +func ExampleClient_VoteSubscribe() { + 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(context.Background()) + if err != nil { + panic(err) + } + spew.Dump(got) + } +}