solana

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 3, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

README

solana-go

A high-performance Go SDK for the Solana blockchain.

Install

go get github.com/MevYu/solana-go

Minimum Go version: 1.24.


Packages at a glance

Package Purpose
github.com/MevYu/solana-go Core types: PublicKey, Hash, Signature, Transaction, Message, Keypair
…/jsonrpc JSON-RPC 2.0 transport: Client.CallContext, retry, codec, Config, *ErrRPC, classifiers
…/rpc Typed wrappers for every stable RPC method: *rpc.Client with one Go method per RPC
…/ws WebSocket subscriptions: ws.Client, AccountSubscribe, LogsSubscribe, …
…/encoding Solana wire format: shortvec, bincode, Borsh, chained Encoder/Reader
…/helpers Pure-logic helpers: PriorityFeeStatsFromFees
…/tx Fluent transaction builder
…/programs/system System Program instructions (transfer, create-account, nonces, …)
…/programs/token SPL Token instructions + state decoding
…/programs/token2022 Token-2022 instructions (incl. extension builders) + state decoding
…/programs/associated-token-account ATA derivation + create-instruction builders
…/programs/compute-budget Compute-budget instructions (priority fees)
…/programs/memo Memo Program instruction builder
…/programs/address-lookup-table ALT instruction builders + state decoder
…/programs/stake Stake Program instructions
…/programs/vote Vote Program instructions
…/programs/secp256k1 secp256k1 precompile (Ethereum-style sig verify)

Quickstart

Parse a public key
import "github.com/MevYu/solana-go"

pk, err := solana.PublicKeyFromBase58("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
if err != nil {
    log.Fatal(err)
}
fmt.Println(pk) // TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Generate a keypair
kp, err := solana.NewEd25519Keypair()
if err != nil {
    log.Fatal(err)
}
fmt.Println("public key:", kp.PublicKey())
Typed RPC client
import (
    "context"
    "github.com/MevYu/solana-go/jsonrpc"
    "github.com/MevYu/solana-go/rpc"
)

c := rpc.NewClient("https://api.mainnet-beta.solana.com", jsonrpc.Config{})

// Get balance
res, err := c.GetBalance(ctx, pk)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("balance: %d lamports at slot %d\n", res.Value, res.Slot)

// Get account info — typed config struct, no functional options
info, err := c.GetAccountInfo(ctx, pk, rpc.AccountInfoCfg{
    Commitment: rpc.CommitmentConfirmed,
    Encoding:   solana.EncodingBase64,
})

// Get latest blockhash
bh, err := c.GetLatestBlockhash(ctx)

// Send a transaction (returns the signature once the node accepts it)
sig, err := c.SendTransaction(ctx, tx)

All ~50 stable Solana RPC methods are available as typed methods on *rpc.Client. Method options are typed rpc.XxxCfg structs (see jsonrpc/options.go); each method documents the exact Cfg type it accepts so unhonoured fields are a compile error rather than a silent no-op.

Build a transaction with the fluent builder
import (
    "github.com/MevYu/solana-go/tx"
    "github.com/MevYu/solana-go/programs/system"
)

t, err := tx.NewBuilder().
    SetFeePayer(payer.PublicKey()).
    SetRecentBlockhash(blockhash).
    AddInstruction(system.NewTransfer(payer.PublicKey(), recipient, lamports)).
    Sign(payer).
    Build(ctx)
if err != nil {
    log.Fatal(err)
}
Send and confirm a transaction
sig, err := c.SendAndConfirmTransaction(ctx,
    func(ctx context.Context, blockhash solana.Hash) (*solana.Transaction, error) {
        msg, _ := solana.NewMessage(payer.PublicKey(),
            []solana.Instruction{
                system.NewTransfer(payer.PublicKey(), recipient, lamports),
            },
            blockhash,
        )
        t := solana.NewTransaction(*msg)
        if err := t.Sign(ctx, payer); err != nil {
            return nil, err
        }
        return t, nil
    },
    rpc.WithSendCommitment(rpc.CommitmentConfirmed),
)

*rpc.Client.SendAndConfirmTransaction handles blockhash refresh on expiry and polls getSignatureStatuses until the requested commitment is reached.

Simulate a transaction
import "errors"

sim, err := c.SimulateTransaction(ctx, tx)
if err != nil {
    log.Fatal(err) // transport error
}
if sim.Err != nil {
    decoded := rpc.DecodeTransactionError(sim.Err)
    var ie *rpc.InstructionError
    if errors.As(decoded, &ie) {
        fmt.Printf("instruction %d failed: %s\n", ie.Index, ie.Kind)
    }
}
if sim.UnitsConsumed != nil {
    fmt.Println("units consumed:", *sim.UnitsConsumed)
}
Estimate priority fee
import "github.com/MevYu/solana-go/helpers"

fees, err := c.GetRecentPrioritizationFees(ctx,
    []solana.PublicKey{writableAccount},
)
if err != nil {
    log.Fatal(err)
}
stats := helpers.PriorityFeeStatsFromFees(fees)
fmt.Printf("p50: %d  p75: %d  p95: %d  micro-lamports/CU\n",
    stats.P50, stats.P75, stats.P95)
WebSocket subscriptions
import (
    "github.com/MevYu/solana-go/rpc"
    "github.com/MevYu/solana-go/ws"
)

wsc, err := ws.DialWebSocket(ctx, "wss://api.mainnet-beta.solana.com")
if err != nil {
    log.Fatal(err)
}
defer wsc.Close()

sub, err := wsc.AccountSubscribe(ctx, pk, rpc.CommitmentWithEncodingCfg{
    Commitment: rpc.CommitmentConfirmed,
})
if err != nil {
    log.Fatal(err)
}
defer sub.Unsubscribe(ctx)

for n := range sub.Recv() {
    fmt.Println("account updated at slot", n.Slot)
}

Available subscriptions: AccountSubscribe, LogsSubscribe, ProgramSubscribe, SignatureSubscribe, SlotSubscribe, SlotsUpdatesSubscribe, RootSubscribe, BlockSubscribe.

Sign with a remote signer

For hardware wallets, cloud HSMs, or any networked signing service:

remote := solana.NewRemoteSigner(
    walletPublicKey,
    func(ctx context.Context, message []byte) (solana.Signature, error) {
        return callMyHSM(ctx, message)
    },
)

tx.Sign(ctx, localPayer, remote)
Raw JSON-RPC escape hatch
import (
    "github.com/MevYu/solana-go/jsonrpc"
    "github.com/MevYu/solana-go/rpc"
)

c := rpc.NewClient("https://api.mainnet-beta.solana.com", jsonrpc.Config{})

// CallContext is promoted through the embedded *jsonrpc.Client.
var balance uint64
err := c.CallContext(ctx, &balance, "getBalance",
    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
)

// For {context, value} envelopes, use jsonrpc.CallContextValue[T]:
slot, lamports, err := jsonrpc.CallContextValue[uint64](
    ctx, c.Client, "getBalance",
    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
)

What's included

Area Status
Core types (PublicKey, Hash, Signature, Account) — base58 / JSON / text / SQL
Message encoding: legacy and v0 with Address Lookup Tables
Transaction: O(1) signer lookup, incremental multi-party signing
Signer: local Ed25519Keypair, BIP-39 mnemonic, function-adapted RemoteSigner
Zero-copy binary codec with Solana shortvec / Borsh support
jsonrpc.Client: JSON-RPC 2.0, pluggable codec, exponential-backoff retry, classifiers
~50 typed RPC methods on *rpc.Client
WebSocket subscriptions (8 subscription types) on *ws.Client
Fluent transaction builder (tx.Builder)
SendAndConfirmTransaction with blockhash refresh
DecodeTransactionError typed error decoding for SimulateTransaction / GetTransaction
PriorityFeeStatsFromFees percentile statistics
Program bindings: System, SPL Token, Token-2022 (incl. extensions), ATA, Compute Budget, Memo, ALT, Stake, Vote, Secp256k1

Performance design

  • Single-pass JSON decode for all {context, value} responses via jsonrpc.CallContextValue[T] — halves codec work on the hot path.
  • Tagged public types (SimulateResult, LatestBlockhash, SupplyResult, GetTransactionResult, WS notifications, …) decode straight from the wire — no internal wire-shape struct middleman.
  • Precise encoder pre-allocation in Message.Marshal and Transaction.Marshal — eliminates buffer growth and copy-out.
  • Lazy *time.Timer + defer Stop() in all retry and poll loops — no goroutine leaks on context cancellation.
  • Hoisted seed-augment slice in FindProgramAddress — up to 256 redundant allocations per call collapse to zero.

Architectural principles

  1. Typed config structs over functional options for RPC methods. Every method takes cfg ...rpc.XxxCfg so unhonoured fields are a compile error, not a silent no-op. Functional options remain only for constructor configuration (jsonrpc.WithMaxIdleConnsPerHost) and the send-and-confirm helper (rpc.WithSendCommitment).
  2. No panic in library code. All "impossible" states return errors. MustPublicKey / MustHash / MustSignature exist specifically for package-level program-id constants and explicitly panic — never use them on user input.
  3. No silent argument-dropping. Errors name the offending value.
  4. Errors are wrapped with method context. A typical error reads solana rpc getBalance: …, not a bare Forbidden.
  5. context.Context is the first argument of every public method that does I/O.
  6. Public map and slice returns are defensive copies. Callers cannot mutate internal state through a returned value.
  7. No *big.Int in hot paths. Lamports are uint64.
  8. encoding/json is not on the RPC hot path. Default codec is goccy/go-json; swap with jsonrpc.WithCodec(jsonrpc.StdCodec()) if you can't take the dependency.
  9. Every exported type has a doc comment naming the RPC method or protocol concept it represents.
  10. Hard caller-input limits up front. Methods enforce server caps locally (MaxGetMultipleAccountsAddresses, MaxGetSignatureStatusesSignatures, MaxGetRecentPrioritizationFeesAddresses) so callers see a precise error instead of a vague "Invalid params" from the server.

Dependencies

Dependency Purpose
filippo.io/edwards25519 PDA off-curve check
github.com/goccy/go-json Fast JSON codec (default)
github.com/gorilla/websocket WebSocket transport
github.com/mr-tron/base58 Base58 encoding
github.com/tyler-smith/go-bip39 BIP-39 mnemonic seeds
github.com/klauspost/compress base64+zstd account-data decoding (transitive)

All MIT or BSD licensed.


API documentation

Full API documentation: https://pkg.go.dev/github.com/MevYu/solana-go


Contributing

  • go build ./... must be green
  • go vet ./... must be green
  • go test -race ./... must be green
  • Every new exported identifier needs a doc comment
  • Performance-sensitive changes should ship with a benchmark

License

Apache-2.0. See LICENSE.

Documentation

Index

Constants

View Source
const (
	RpcCommitmentProcessed = CommitmentProcessed
	RpcCommitmentConfirmed = CommitmentConfirmed
	RpcCommitmentFinalized = CommitmentFinalized
)

go-solana-compatible commitment constants.

View Source
const (
	// PublicKeySize is the byte length of an Ed25519 public key used to
	// identify accounts, programs, and program-derived addresses on
	// Solana.
	PublicKeySize = ed25519.PublicKeySize
	// HashSize is the byte length of a Solana blockhash or transaction
	// hash.
	HashSize = 32
	// SignatureSize is the byte length of an Ed25519 signature produced
	// by a Solana keypair.
	SignatureSize = ed25519.SignatureSize
)

Size constants for the core Solana primitives, in bytes.

View Source
const DefaultDerivationPath = "m/44'/501'/0'/0'"

DefaultDerivationPath is the standard Solana BIP44 HD wallet path. All components are hardened as required by SLIP-0010 / Ed25519.

View Source
const LAMPORTS_PER_SOL = uint64(1_000_000_000)

LAMPORTS_PER_SOL is the number of lamports in one SOL. Use this to convert between human-readable SOL amounts and the on-chain lamport denomination: 1 SOL = 1,000,000,000 lamports.

View Source
const MaxPDASeedLength = 32

MaxPDASeedLength is the maximum length in bytes of a single seed passed to CreateProgramAddress or FindProgramAddress.

View Source
const MaxPDASeeds = 16

MaxPDASeeds is the maximum number of seeds a program-derived address may be derived from, per the Solana runtime rules.

Variables

View Source
var (
	// SystemProgramID is the System Program, which handles SOL transfers,
	// account creation, and program deployments.
	SystemProgramID = MustPublicKey("11111111111111111111111111111111")

	// TokenProgramID is the SPL Token program for the classic token standard.
	TokenProgramID = MustPublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")

	// Token2022ProgramID is the SPL Token-2022 program (extensions).
	Token2022ProgramID = MustPublicKey("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb")

	// AssociatedTokenProgramID is the Associated Token Account program.
	AssociatedTokenProgramID = MustPublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJe1bRS")

	// ComputeBudgetProgramID is the Compute Budget program for priority fees.
	ComputeBudgetProgramID = MustPublicKey("ComputeBudget111111111111111111111111111111")

	// SysvarRentPubkey is the address of the Rent sysvar account.
	SysvarRentPubkey = MustPublicKey("SysvarRent111111111111111111111111111111111")

	// SysvarClockPubkey is the address of the Clock sysvar account.
	SysvarClockPubkey = MustPublicKey("SysvarC1ock11111111111111111111111111111111")

	// SysvarRecentBlockhashesPubkey is the address of the RecentBlockhashes sysvar.
	SysvarRecentBlockhashesPubkey = MustPublicKey("SysvarRecentB1ockHashes11111111111111111111")

	// SysvarSlotHashesPubkey is the address of the SlotHashes sysvar.
	SysvarSlotHashesPubkey = MustPublicKey("SysvarS1otHashes111111111111111111111111111")

	// SysvarSlotHistoryPubkey is the address of the SlotHistory sysvar.
	SysvarSlotHistoryPubkey = MustPublicKey("SysvarS1otHistory11111111111111111111111111")

	// SysvarStakeHistoryPubkey is the address of the StakeHistory sysvar.
	SysvarStakeHistoryPubkey = MustPublicKey("SysvarStakeHistory1111111111111111111111111")

	// SysvarEpochSchedulePubkey is the address of the EpochSchedule sysvar.
	SysvarEpochSchedulePubkey = MustPublicKey("SysvarEpochSchedu1e111111111111111111111111")

	// SysvarInstructionsPubkey is the address of the Instructions sysvar,
	// used to inspect other instructions in the same transaction.
	SysvarInstructionsPubkey = MustPublicKey("Sysvar1nstructions1111111111111111111111111")

	// SysvarEpochRewardsPubkey is the address of the EpochRewards sysvar.
	SysvarEpochRewardsPubkey = MustPublicKey("SysvarEpochRewards1111111111111111111111111")
)

Well-known program addresses as PublicKey values. These are the canonical addresses for Solana's native and core programs.

View Source
var ErrInvalidBase58 = errors.New("solana: invalid base58")

ErrInvalidBase58 is returned when a string cannot be decoded as base58 because it is empty or contains characters outside the base58 alphabet.

View Source
var ErrInvalidLength = errors.New("solana: invalid length")

ErrInvalidLength is returned when a byte slice or a base58-decoded value has the wrong size for the target Solana primitive (public key, hash, signature, ...). Callers can detect it with errors.Is instead of string matching.

Functions

func GenerateMnemonic

func GenerateMnemonic(bitSize int) (string, error)

GenerateMnemonic generates a new random BIP39 mnemonic with the given bit size (128 for 12 words, 256 for 24 words).

Types

type Account

type Account struct {
	// Lamports is the account balance, denominated in lamports
	// (10^-9 SOL).
	Lamports uint64
	// Owner is the program that controls the account. Only the owner
	// program may debit lamports or modify Data.
	Owner PublicKey
	// Data is the raw account data bytes. A zero-length slice means
	// the account exists but holds no program-specific data.
	Data []byte
	// Executable reports whether the account stores a loadable
	// program. Executable accounts are immutable after finalisation.
	Executable bool
	// RentEpoch is the epoch at which the account next owes rent.
	// It is 0 on rent-exempt accounts, the modern default.
	RentEpoch uint64
}

Account describes the state of an on-chain Solana account as returned by JSON-RPC methods such as getAccountInfo.

type AccountData

type AccountData [2]string

AccountData is the raw data field of an AccountInfo. On the wire Solana RPC returns it as a two-element JSON array:

["<encoded_value>", "<encoding_name>"]

It is modelled as a fixed-size [2]string so both stdlib encoding/json and goccy/go-json decode it directly without a custom UnmarshalJSON. Use Value, Encoding, and Bytes to access it.

func (AccountData) Bytes

func (d AccountData) Bytes() ([]byte, error)

Bytes decodes Value according to Encoding and returns the raw bytes. An empty Value returns a nil slice and no error. An unsupported encoding (jsonParsed, json, base64+zstd) returns an error describing the shortfall so the caller can decide how to handle it.

func (AccountData) Encoding

func (d AccountData) Encoding() Encoding

Encoding returns the wire encoding name.

func (AccountData) Value

func (d AccountData) Value() string

Value returns the raw encoded value string.

type AccountInfo

type AccountInfo struct {
	Lamports   uint64      `json:"lamports"`
	Owner      PublicKey   `json:"owner"`
	Data       AccountData `json:"data"`
	Executable bool        `json:"executable"`
	RentEpoch  uint64      `json:"rentEpoch"`
	Space      uint64      `json:"space"`
}

AccountInfo is the JSON representation of an account as returned by the getAccountInfo and getMultipleAccounts RPC methods.

It differs from the wire-level Account type in that it preserves the RPC protocol's two-element [value, encoding] data form, plus the server-reported Space field which is absent from the binary wire format.

func (*AccountInfo) ToAccount

func (a *AccountInfo) ToAccount() (*Account, error)

ToAccount converts an AccountInfo into the binary-compatible Account type. It decodes the data field via Bytes so errors there propagate. Use this when you want to store account state in the same shape the binary wire format uses, or when you plan to feed the account into program-specific binary decoders.

type AccountMeta

type AccountMeta struct {
	PublicKey  PublicKey
	IsSigner   bool
	IsWritable bool
}

AccountMeta describes an account's role in an instruction: which account is referenced, whether it must sign the transaction, and whether the instruction may write to it.

Order matters: programs read their inputs positionally, so the slices returned by Instruction.Accounts are ordered exactly as the target program expects them.

func Meta

func Meta(pubKey PublicKey) *AccountMeta

Meta creates a new AccountMeta for pubKey with IsSigner and IsWritable both false. Chain WRITE() and SIGNER() to promote the account:

solana.Meta(pk).WRITE().SIGNER()

func NewAccountMeta

func NewAccountMeta(pk PublicKey, isSigner, isWritable bool) *AccountMeta

NewAccountMeta constructs an AccountMeta.

func (*AccountMeta) Less

func (m *AccountMeta) Less(other *AccountMeta) bool

Less reports whether m should sort before other in account-meta lists: signers before non-signers, then writable before read-only.

func (*AccountMeta) SIGNER

func (m *AccountMeta) SIGNER() *AccountMeta

SIGNER sets IsSigner to true and returns the receiver for chaining.

func (*AccountMeta) WRITE

func (m *AccountMeta) WRITE() *AccountMeta

WRITE sets IsWritable to true and returns the receiver for chaining.

type AccountMetaSlice

type AccountMetaSlice []*AccountMeta

AccountMetaSlice is a convenience wrapper around a slice of AccountMeta pointers. It provides helpers for common operations like appending, filtering, and extracting keys.

func (*AccountMetaSlice) Append

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

Append adds an account to the slice.

func (AccountMetaSlice) Get

func (s AccountMetaSlice) Get(index int) *AccountMeta

Get returns the AccountMeta at the given index, or nil if the index is out of range.

func (AccountMetaSlice) GetAccounts

func (s AccountMetaSlice) GetAccounts() []*AccountMeta

GetAccounts returns all non-nil entries in the slice.

func (AccountMetaSlice) GetKeys

func (s AccountMetaSlice) GetKeys() []PublicKey

GetKeys returns the public keys of all entries.

func (AccountMetaSlice) GetSigners

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

GetSigners returns only the entries that have IsSigner set.

func (AccountMetaSlice) Len

func (s AccountMetaSlice) Len() int

Len returns the length of the slice.

func (*AccountMetaSlice) SetAccounts

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

SetAccounts replaces the slice contents with accounts.

type AccountsGettable

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

AccountsGettable is implemented by types that can return their current list of account metas.

type AccountsSettable

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

AccountsSettable is implemented by types that accept a full replacement of their account meta list.

type Base58Data

type Base58Data []byte

Base58Data is a byte slice that JSON-marshals to/from a base58 string. It mirrors the go-solana type of the same name and is useful for instruction data fields on the wire.

func (Base58Data) Base58

func (t Base58Data) Base58() string

Base58 returns the base58 encoding.

func (Base58Data) Hex

func (t Base58Data) Hex() string

Hex returns the hex encoding.

func (Base58Data) MarshalJSON

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

MarshalJSON implements json.Marshaler.

func (Base58Data) String

func (t Base58Data) String() string

String returns the base58 encoding.

func (*Base58Data) UnmarshalJSON

func (t *Base58Data) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

type CommitmentLevel

type CommitmentLevel string

CommitmentLevel describes the level of confirmation required for a query. Solana defines three tiers, from fastest-but-reversible to slowest-but-permanent.

const (
	// CommitmentProcessed queries the most recent block. It has the
	// lowest latency but may be rolled back.
	CommitmentProcessed CommitmentLevel = "processed"

	// CommitmentConfirmed queries the most recent block that has
	// been voted on by a supermajority of the cluster.
	CommitmentConfirmed CommitmentLevel = "confirmed"

	// CommitmentFinalized queries the most recent block that a
	// supermajority of the cluster has rooted, so it will never be
	// rolled back. This is the safest default for money movement.
	CommitmentFinalized CommitmentLevel = "finalized"
)

type CompiledInstruction

type CompiledInstruction struct {
	// ProgramIDIndex is the position of the program account in the
	// message's AccountKeys.
	ProgramIDIndex uint8

	// Accounts holds the indices of the instruction's input accounts
	// within the message's AccountKeys; for v0 messages indices may
	// point past the static keys into addresses resolved through
	// AddressTableLookups.
	//
	// Typed as Uint8Slice (not []uint8) so encoding/json renders it as
	// a JSON array of numbers, matching the Solana JSON-RPC shape,
	// instead of as a base64 string.
	Accounts Uint8Slice

	// Data is the serialized instruction payload.
	Data []byte
}

CompiledInstruction is an Instruction whose program and accounts have been resolved to indices into the enclosing Message's account key array.

type Ed25519Keypair

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

Ed25519Keypair is a local, in-memory Signer backed by an Ed25519 private key from the standard library's crypto/ed25519.

This is the fastest path for signing when the private key material is already in process memory. For hardware wallets or remote HSMs, use RemoteSigner instead.

func Ed25519KeypairFromKeygenFile

func Ed25519KeypairFromKeygenFile(path string) (*Ed25519Keypair, error)

Ed25519KeypairFromKeygenFile loads an Ed25519Keypair from a Solana CLI keygen JSON file. The file contains a JSON array of uint8 values representing the 64-byte expanded private key.

Example file: [1,2,3,...,64]

func Ed25519KeypairFromMnemonic

func Ed25519KeypairFromMnemonic(mnemonic, password, path string) (*Ed25519Keypair, error)

Ed25519KeypairFromMnemonic derives an Ed25519Keypair from a BIP39 mnemonic phrase.

password is the optional BIP39 passphrase (empty string for none). path is the HD derivation path; pass "" to use DefaultDerivationPath. Valid path format: m/44'/501'/0'/0' (all components must be hardened).

Example:

kp, err := solana.Ed25519KeypairFromMnemonic(phrase, "", "")
kp, err := solana.Ed25519KeypairFromMnemonic(phrase, "", "m/44'/501'/1'/0'")

func Ed25519KeypairFromPrivateKey

func Ed25519KeypairFromPrivateKey(priv []byte) (*Ed25519Keypair, error)

Ed25519KeypairFromPrivateKey constructs a keypair from an already expanded 64-byte Ed25519 private key. The input bytes are copied; the caller may zero the input after the call returns.

func Ed25519KeypairFromSeed

func Ed25519KeypairFromSeed(seed []byte) (*Ed25519Keypair, error)

Ed25519KeypairFromSeed constructs a keypair deterministically from a 32-byte Ed25519 seed (the unexpanded form, as distinct from the 64-byte expanded private key).

func NewEd25519Keypair

func NewEd25519Keypair() (*Ed25519Keypair, error)

NewEd25519Keypair returns a fresh keypair generated from the system's cryptographically secure random source.

func (*Ed25519Keypair) PrivateKey

func (k *Ed25519Keypair) PrivateKey() []byte

PrivateKey returns a defensive copy of the signer's Ed25519 private key bytes in the 64-byte expanded form. The caller should zero the returned slice when it is no longer needed.

func (*Ed25519Keypair) PublicKey

func (k *Ed25519Keypair) PublicKey() PublicKey

PublicKey implements Signer.

func (*Ed25519Keypair) Sign

func (k *Ed25519Keypair) Sign(_ context.Context, message []byte) (Signature, error)

Sign implements Signer. The context is intentionally ignored: local Ed25519 signing is a pure computation with no I/O, and attempting to cancel it would only throw away work.

type Encoding

type Encoding string

Encoding is the on-wire encoding for binary payloads in RPC responses that carry account data or transaction data.

const (
	// EncodingJSONParsed asks the server to parse the data into a
	// program-specific JSON object (for example SPL Token account
	// state). Only programs the server recognises support this.
	EncodingJSONParsed Encoding = "jsonParsed"

	// EncodingJSON asks the server to return the data as a structured
	// JSON object. Very few programs support this form.
	EncodingJSON Encoding = "json"

	// EncodingBase58 asks the server to return the data as a
	// base58-encoded string. Slow for large payloads; avoid.
	EncodingBase58 Encoding = "base58"

	// EncodingBase64 asks the server to return the data as a
	// base64-encoded string. The most common choice.
	EncodingBase64 Encoding = "base64"

	// EncodingBase64ZSTD asks the server to return the data as
	// zstd-compressed base64. Saves bandwidth on large accounts but
	// requires a zstd decoder on the client side.
	EncodingBase64ZSTD Encoding = "base64+zstd"
)
const (
	EncodingBase64Zstd Encoding = EncodingBase64ZSTD
	EncodingJsonParsed Encoding = EncodingJSONParsed
	EncodingJson       Encoding = EncodingJSON
)

go-solana-compatible encoding constants.

type EncodingEnum

type EncodingEnum = Encoding

EncodingEnum is an alias for Encoding, matching the go-solana naming convention.

type Entry

type Entry struct {
	NumHashes    uint64
	Hash         Hash
	Transactions []Transaction
}

Entry is a Solana Proof-of-History entry as emitted on the wire by Jito ShredStream (and by solana-core internally). An entry carries a chain link (NumHashes, Hash) and a batch of transactions that were sequenced at this point in the PoH stream.

The bincode wire layout is:

num_hashes:   u64 little-endian
hash:         [32]byte
transactions: Vec<Transaction>   // u64 length prefix, then N wire-format txs

func DecodeEntries

func DecodeEntries(data []byte) ([]Entry, error)

DecodeEntries parses a bincode Vec<Entry> buffer, as delivered by Jito ShredStream's Entry.Entries field. The outer Vec length is a little-endian u64 (bincode default), each entry has a u64 num_hashes and a 32-byte hash, followed by a u64-prefixed Vec<Transaction> in Solana wire format.

The returned slice does not alias data: transaction signatures and message fields are copied out of the buffer.

func DecodeEntry

func DecodeEntry(d *encoding.Decoder) (*Entry, error)

DecodeEntry reads one Entry from d's current position.

func (*Entry) UnmarshalFromDecoder

func (e *Entry) UnmarshalFromDecoder(d *encoding.Decoder) error

UnmarshalFromDecoder implements encoding.Unmarshaler so that Entry can be decoded generically via d.DecodeTo(&entry).

type EnumCirculateFilter

type EnumCirculateFilter string

EnumCirculateFilter filters accounts by circulation status.

const (
	FilterCirculating    EnumCirculateFilter = "circulating"
	FilterNonCirculating EnumCirculateFilter = "nonCirculating"
)

type EnumRpcCommitment

type EnumRpcCommitment = CommitmentLevel

EnumRpcCommitment is an alias for CommitmentLevel, matching the go-solana naming convention.

type EnumTxDetailLevel

type EnumTxDetailLevel string

EnumTxDetailLevel is the transaction detail level for getBlock-style calls.

const (
	TxDetailLevelNone       EnumTxDetailLevel = "none"
	TxDetailLevelFull       EnumTxDetailLevel = "full"
	TxDetailLevelAccounts   EnumTxDetailLevel = "accounts"
	TxDetailLevelSignatures EnumTxDetailLevel = "signatures"
)

type Hash

type Hash [HashSize]byte

Hash is a 32-byte Solana blockhash or transaction hash. It uses the same base58 textual form as PublicKey.

func HashFromBase58

func HashFromBase58(s string) (Hash, error)

HashFromBase58 decodes a Solana blockhash or transaction hash from its base58 form.

func HashFromBytes

func HashFromBytes(b []byte) (Hash, error)

HashFromBytes constructs a Hash from a 32-byte slice. See PublicKeyFromBytes for the error contract.

func MustHash

func MustHash(s string) Hash

MustHash is like HashFromBase58 but panics on invalid input. Same contract as MustPublicKey.

func (Hash) Bytes

func (h Hash) Bytes() []byte

Bytes returns a defensive copy of the hash's raw bytes.

func (Hash) Equal

func (h Hash) Equal(other Hash) bool

Equal reports whether h and other represent the same hash.

func (Hash) IsZero

func (h Hash) IsZero() bool

IsZero reports whether the hash equals the all-zero Hash.

func (Hash) MarshalJSON

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

MarshalJSON implements json.Marshaler.

func (Hash) MarshalText

func (h Hash) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (*Hash) Scan

func (h *Hash) Scan(src any) error

Scan implements sql.Scanner. See PublicKey.Scan for the contract.

func (Hash) String

func (h Hash) String() string

String returns the base58 representation of the hash.

func (*Hash) UnmarshalJSON

func (h *Hash) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*Hash) UnmarshalText

func (h *Hash) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

func (Hash) Value

func (h Hash) Value() (driver.Value, error)

Value implements driver.Valuer.

type Instruction

type Instruction interface {
	// ProgramID returns the public key of the program that will run
	// this instruction.
	ProgramID() PublicKey

	// Accounts returns the account metas in positional order. The
	// returned slice is read-only; callers must not mutate it.
	Accounts() []*AccountMeta

	// Data returns the serialized instruction data or an error
	// describing why the instruction cannot be built.
	Data() ([]byte, error)
}

Instruction is the common interface implemented by every program instruction builder. An Instruction names its program, lists the accounts it consumes in positional order, and returns its serialized data bytes.

Implementations must not panic on invalid configuration; they return a descriptive error from Data() instead.

type Int128

type Int128 struct {
	Lo uint64
	Hi int64
}

Int128 is a little-endian signed 128-bit integer.

func (Int128) BigInt

func (i Int128) BigInt() *big.Int

func (Int128) IsZero

func (i Int128) IsZero() bool

func (Int128) MarshalToEncoder

func (i Int128) MarshalToEncoder(e *encoding.Encoder)

func (Int128) String

func (i Int128) String() string

func (*Int128) UnmarshalFromDecoder

func (i *Int128) UnmarshalFromDecoder(d *encoding.Decoder) error

type Int256

type Int256 struct {
	Lo Uint128
	Hi Int128
}

Int256 is a little-endian signed 256-bit integer.

func (Int256) String

func (i Int256) String() string

func (*Int256) UnmarshalFromDecoder

func (i *Int256) UnmarshalFromDecoder(d *encoding.Decoder) error

type LoadedAddressLookupTable

type LoadedAddressLookupTable struct {
	AccountKey PublicKey   // On-chain ALT address
	Addresses  []PublicKey // All addresses in the table, ordered by slot index
}

LoadedAddressLookupTable holds a resolved Address Lookup Table: its on-chain key and the full ordered list of addresses stored in the table (slot 0, 1, 2, …). Obtain this data by calling the RPC method getAddressLookupTable (or getAccountInfo on the ALT account and parsing the state). Pass a slice of LoadedAddressLookupTable to NewMessageV0 or Builder.BuildV0 so the builder can map instruction accounts to their table slot indices.

type Message

type Message struct {
	// Version is the wire-format version. Only MessageVersionLegacy
	// and MessageVersion0 are currently supported.
	Version MessageVersion

	// Header counts the signing and read-only static accounts.
	Header MessageHeader

	// AccountKeys is the static account array. Legacy messages use
	// only this list; v0 messages extend it with accounts resolved
	// through AddressTableLookups.
	AccountKeys []PublicKey

	// RecentBlockhash is the blockhash the transaction commits to.
	RecentBlockhash Hash

	// Instructions is the ordered list of compiled instructions.
	Instructions []CompiledInstruction

	// AddressTableLookups is empty for legacy messages and may be
	// non-empty for v0 messages.
	AddressTableLookups []MessageAddressTableLookup
}

Message is the serialized body of a Solana transaction. It supports both the legacy format (Version == MessageVersionLegacy) and the versioned format (Version == MessageVersion0).

func DecodeMessage

func DecodeMessage(d *encoding.Decoder) (*Message, error)

DecodeMessage reads a Solana Message from d's current position and advances the cursor past the last field. Unlike UnmarshalMessage it does NOT enforce end-of-buffer, so callers can decode a message out of a larger byte stream (e.g. Jito ShredStream entries).

The returned Message does not alias d's buffer: all variable-length fields are copied out before returning.

func NewMessage

func NewMessage(payer PublicKey, instructions []Instruction, recentBlockhash Hash) (*Message, error)

NewMessage compiles a slice of typed Instructions into a legacy Message ready to be signed by Transaction.Sign.

It deduplicates account keys across all instructions, orders them by role according to the Solana protocol, computes the header counters, and resolves each instruction's account list to positional indices into the deduplicated key array.

Account ordering within the resulting Message follows the Solana convention:

  1. payer (always first, signer + writable)
  2. other signer-writable accounts
  3. signer-readonly accounts
  4. non-signer-writable accounts
  5. non-signer-readonly accounts (including program ids)

Within each bucket, accounts are ordered by the order they first appear in the instructions slice, which matches solana-web3.js and produces stable, review-friendly output.

The payer is always placed first in the AccountKeys slice and is guaranteed to be signer + writable regardless of how individual instructions reference it. Roles elsewhere are cumulative: if the same account appears as signer in one instruction and non-signer in another, it ends up in the signer bucket.

func NewMessageV0

func NewMessageV0(payer PublicKey, instructions []Instruction, recentBlockhash Hash, tables []LoadedAddressLookupTable) (*Message, error)

NewMessageV0 compiles a v0 versioned Message that uses Address Lookup Tables to extend the account limit beyond the legacy 35-account cap.

tables contains resolved ALTs: each entry holds the table's on-chain address and the full ordered list of addresses stored in it. The builder inspects every instruction account and, when the account appears in a table AND is not required to sign (signer accounts must always be static), routes it through that table rather than the static account list.

Account index layout in the compiled message:

[0 .. staticLen-1]             — static accounts (same role ordering as NewMessage)
[staticLen .. +Σwritable]      — writable table accounts, table by table
[above .. +Σreadonly]          — readonly table accounts, table by table

If an account appears in multiple tables the first matching table wins.

func UnmarshalMessage

func UnmarshalMessage(data []byte) (*Message, error)

UnmarshalMessage parses data as a Solana Message and returns a new Message structure. The returned Message does not share memory with the input slice: all variable-length fields are copied out of the decoder before returning, so callers may mutate or free data afterwards.

Trailing bytes after the message body are rejected. To decode a message out of a larger stream, use DecodeMessage with a caller-owned *encoding.Decoder.

func (*Message) Marshal

func (m *Message) Marshal() ([]byte, error)

Marshal returns the wire-format encoding of the message. The returned slice is newly allocated and owned by the caller.

func (*Message) MarshalBinary

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

MarshalBinary is an alias for Marshal, matching the go-solana naming convention.

func (*Message) SerializedSize

func (m *Message) SerializedSize() int

SerializedSize returns the exact wire-format byte count for this message without allocating the encoded buffer. The result equals len(m.Marshal()) for any valid message.

type MessageAddressTableLookup

type MessageAddressTableLookup struct {
	// AccountKey is the address of the Address Lookup Table account.
	AccountKey PublicKey

	// WritableIndexes are the indices within the lookup table of
	// accounts that instructions in this message may write to. Typed
	// as Uint8Slice so JSON rendering is a number array.
	WritableIndexes Uint8Slice

	// ReadonlyIndexes are the indices within the lookup table of
	// accounts that are strictly read-only in this message. Typed as
	// Uint8Slice so JSON rendering is a number array.
	ReadonlyIndexes Uint8Slice
}

MessageAddressTableLookup is a v0-only reference to an Address Lookup Table that supplies additional accounts beyond the static keys in a Message.

type MessageHeader

type MessageHeader struct {
	// NumRequiredSignatures is the total number of accounts that must
	// sign the transaction.
	NumRequiredSignatures uint8

	// NumReadonlySignedAccounts is how many of the first
	// NumRequiredSignatures accounts are read-only.
	NumReadonlySignedAccounts uint8

	// NumReadonlyUnsignedAccounts is how many of the remaining
	// unsigned accounts are read-only.
	NumReadonlyUnsignedAccounts uint8
}

MessageHeader describes the signing and writability layout of a Message's static account keys.

type MessageVersion

type MessageVersion uint8

MessageVersion identifies the wire-format version of a Message.

const (
	// MessageVersionLegacy is the pre-v0 Solana message format. A
	// legacy message has no version prefix byte on the wire: its
	// serialized form begins directly with MessageHeader. This value
	// is a Go-level sentinel only; it is never written to the wire.
	MessageVersionLegacy MessageVersion = 0xFF

	// MessageVersion0 is the first versioned message format, which
	// introduces Address Lookup Table support. On the wire, a v0
	// message begins with the byte versionPrefixMask | 0 == 0x80.
	MessageVersion0 MessageVersion = 0
)

type PublicKey

type PublicKey [PublicKeySize]byte

PublicKey is a 32-byte Solana account or program address. Its canonical textual form is base58; JSON, text and SQL marshalling all use that form.

func CreateProgramAddress

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

CreateProgramAddress derives a program address from a sequence of seeds and a program id. It is the direct counterpart of the Solana runtime's create_program_address.

The derivation is:

sha256(seed1 || seed2 || ... || programID || "ProgramDerivedAddress")

The result is a 32-byte public key that must NOT lie on the ed25519 curve; if the hash happens to land on a curve point, CreateProgramAddress returns an error and the caller is expected to vary the seeds (typically by appending a "bump" byte via FindProgramAddress).

Constraints:

  • at most MaxPDASeeds seeds
  • each seed at most MaxPDASeedLength bytes

func FindProgramAddress

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

FindProgramAddress iterates over bump seeds from 255 down to 0 until it finds one that produces an off-curve program address. It is the direct counterpart of the Solana runtime's find_program_address.

The returned bump is the byte that was appended to seeds to produce the valid PDA; store it alongside the address if you plan to re-derive the same PDA later via CreateProgramAddress (re-deriving without the bump is possible but wastes CPU).

Returns an error only in the astronomically unlikely event that every bump from 255 to 0 produces an on-curve point.

func MustPublicKey

func MustPublicKey(s string) PublicKey

MustPublicKey is like PublicKeyFromBase58 but panics on invalid input. It is intended for package-level variable initializers that hardcode well-known program IDs, where a parse failure is a programmer error caught at startup rather than a runtime condition.

Library code that receives user input must NOT use this function; use PublicKeyFromBase58 and propagate the error.

func PublicKeyFromBase58

func PublicKeyFromBase58(s string) (PublicKey, error)

PublicKeyFromBase58 decodes a Solana address from its base58 form.

func PublicKeyFromBytes

func PublicKeyFromBytes(b []byte) (PublicKey, error)

PublicKeyFromBytes constructs a PublicKey from a 32-byte slice. It returns an error wrapping ErrInvalidLength when the input does not match PublicKeySize; it never silently truncates or pads.

func ReadOptionalPubkey

func ReadOptionalPubkey(r *encoding.Reader) *PublicKey

ReadOptionalPubkey reads a Solana COption<Pubkey>-shaped field from r: a u32 tag (0=None, 1=Some) followed by an unconditional 32-byte slot (the slot is always physically present in the wire layout — only the tag determines logical presence). Returns a non-nil *PublicKey when the tag is 1, nil when it is 0.

This is the common shape used throughout SPL Token state for MintAuthority, FreezeAuthority, Delegate, and CloseAuthority. It is not the same as Rust's bincode Option<Pubkey> (which uses a 1-byte tag and a payload that is only present when Some); for that, read a Bool and a Bytes32 separately.

func (PublicKey) Bytes

func (p PublicKey) Bytes() []byte

Bytes returns a defensive copy of the key's raw bytes. Mutating the returned slice does not affect the receiver.

func (PublicKey) Equal

func (p PublicKey) Equal(other PublicKey) bool

Equal reports whether p and other represent the same public key.

func (PublicKey) IsZero

func (p PublicKey) IsZero() bool

IsZero reports whether the key equals the all-zero PublicKey.

func (PublicKey) MarshalJSON

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

MarshalJSON implements json.Marshaler. The key is rendered as a JSON string holding its base58 form.

func (PublicKey) MarshalText

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

MarshalText implements encoding.TextMarshaler by returning the base58 form.

func (*PublicKey) Scan

func (p *PublicKey) Scan(src any) error

Scan implements sql.Scanner. It accepts a string or a []byte holding the base58 form. A nil src leaves the receiver unchanged. Raw-byte columns must be converted by the caller via PublicKeyFromBytes.

func (PublicKey) String

func (p PublicKey) String() string

String returns the base58 representation of the public key, matching the canonical Solana address form.

func (*PublicKey) UnmarshalJSON

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

UnmarshalJSON implements json.Unmarshaler. The value must be a JSON string holding a base58-encoded 32-byte public key. The JSON token "null" is accepted and leaves the receiver unchanged.

func (*PublicKey) UnmarshalText

func (p *PublicKey) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

func (PublicKey) Value

func (p PublicKey) Value() (driver.Value, error)

Value implements driver.Valuer by returning the base58 string form, which pairs with the string returned by String().

type RemoteSignFunc

type RemoteSignFunc func(ctx context.Context, message []byte) (Signature, error)

RemoteSignFunc is a caller-supplied function that produces an Ed25519 signature for message. Implementations perform whatever network or device I/O is needed to reach the key material (hardware wallet, cloud HSM, networked signing service).

type RemoteSigner

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

RemoteSigner adapts an arbitrary RemoteSignFunc into a Signer. It decouples transaction signing from the transport used to reach the signing key, so callers can integrate with Ledger, YubiHSM, AWS KMS, GCP KMS, or any in-house signing service without this library taking an opinion on the wire protocol.

A zero RemoteSigner is not usable; always construct one with NewRemoteSigner. The wrapped function receives the context passed to Transaction.Sign, so callers can enforce per-signature deadlines.

func NewRemoteSigner

func NewRemoteSigner(pk PublicKey, fn RemoteSignFunc) (*RemoteSigner, error)

NewRemoteSigner binds a public key to a signing function. The function must not be nil.

func (*RemoteSigner) PublicKey

func (r *RemoteSigner) PublicKey() PublicKey

PublicKey implements Signer.

func (*RemoteSigner) Sign

func (r *RemoteSigner) Sign(ctx context.Context, message []byte) (Signature, error)

Sign implements Signer by delegating to the wrapped RemoteSignFunc.

type Signature

type Signature [SignatureSize]byte

Signature is a 64-byte Ed25519 signature produced by a Solana keypair. It uses the same base58 textual form as PublicKey.

func MustSignature

func MustSignature(s string) Signature

MustSignature is like SignatureFromBase58 but panics on invalid input. Same contract as MustPublicKey.

func SignatureFromBase58

func SignatureFromBase58(s string) (Signature, error)

SignatureFromBase58 decodes an Ed25519 signature from its base58 form.

func SignatureFromBytes

func SignatureFromBytes(b []byte) (Signature, error)

SignatureFromBytes constructs a Signature from a 64-byte slice. See PublicKeyFromBytes for the error contract.

func (Signature) Bytes

func (s Signature) Bytes() []byte

Bytes returns a defensive copy of the signature's raw bytes.

func (Signature) Equal

func (s Signature) Equal(other Signature) bool

Equal reports whether s and other represent the same signature.

func (Signature) IsZero

func (s Signature) IsZero() bool

IsZero reports whether the signature equals the all-zero Signature.

func (Signature) MarshalJSON

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

MarshalJSON implements json.Marshaler.

func (Signature) MarshalText

func (s Signature) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (*Signature) Scan

func (s *Signature) Scan(src any) error

Scan implements sql.Scanner. See PublicKey.Scan for the contract.

func (Signature) String

func (s Signature) String() string

String returns the base58 representation of the signature.

func (*Signature) UnmarshalJSON

func (s *Signature) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*Signature) UnmarshalText

func (s *Signature) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

func (Signature) Value

func (s Signature) Value() (driver.Value, error)

Value implements driver.Valuer.

type Signer

type Signer interface {
	// PublicKey returns the Solana public key that this signer holds
	// the corresponding Ed25519 private key for.
	PublicKey() PublicKey

	// Sign produces an Ed25519 signature over message. The returned
	// Signature is consumed directly by Transaction.Sign; callers
	// should treat the exact bytes as opaque.
	Sign(ctx context.Context, message []byte) (Signature, error)
}

Signer is the interface implemented by anything that can produce Ed25519 signatures for a known Solana public key. It is the contract Transaction.Sign consumes to fill in a transaction's signature slots.

The context is threaded through so that remote signers (hardware wallets, cloud HSMs, networked signing services) can enforce deadlines and cancellations. Local in-memory signers may ignore it, but the signature of the interface is fixed either way so Transaction.Sign does not have to branch on the signer kind.

type Transaction

type Transaction struct {
	// Signatures holds one entry per required signer, ordered to
	// match the first Message.Header.NumRequiredSignatures entries
	// of Message.AccountKeys. Unfilled slots contain the all-zero
	// Signature.
	Signatures []Signature

	// Message is the transaction body.
	Message Message
}

Transaction is a Solana transaction: a message together with one signature per required signer. The wire encoding is a shortvec length prefix, then each signature as 64 raw bytes, then the serialized message body.

A freshly constructed Transaction has zero-filled signature slots for each required signer. Calling Sign fills in the slots for the signers that were passed, leaving all others untouched. This supports incremental signing: a caller may collect signatures from multiple parties by calling Sign more than once with different signer subsets.

func DecodeTransaction

func DecodeTransaction(d *encoding.Decoder) (*Transaction, error)

DecodeTransaction reads one Solana Transaction from d's current position and advances the cursor past the message body. Unlike UnmarshalTransaction it does NOT enforce end-of-buffer, so callers can decode a sequence of transactions from a larger stream (e.g. Jito ShredStream entries).

The returned Transaction does not alias d's buffer.

func NewTransaction

func NewTransaction(message Message) *Transaction

NewTransaction constructs an unsigned transaction for message. The Signatures slice is pre-allocated with zero-filled placeholder entries for each required signer, matching the header count.

func NewTransactionFromInstructions

func NewTransactionFromInstructions(instructions []Instruction, recentBlockhash Hash, payer PublicKey) (*Transaction, error)

NewTransactionFromInstructions is a go-solana-compatible convenience that builds a Message from instructions, recent blockhash, and payer, then wraps it into an unsigned Transaction. It mirrors the go-solana NewTransaction(instructions, recentBlockHash, payer) signature.

func UnmarshalTransaction

func UnmarshalTransaction(data []byte) (*Transaction, error)

UnmarshalTransaction parses a wire-format Solana transaction. The returned Transaction does not alias the input buffer: signatures are copied out, and the embedded Message is fully materialised by DecodeMessage, which itself copies its variable-length fields.

Trailing bytes after the transaction are rejected. To decode a transaction out of a larger stream, use DecodeTransaction with a caller-owned *encoding.Decoder.

func (*Transaction) Marshal

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

Marshal returns the wire-format encoding of the transaction. The returned slice is newly allocated and owned by the caller.

func (*Transaction) MarshalBinary

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

MarshalBinary is an alias for Marshal, matching the go-solana naming convention.

func (*Transaction) MessageBytes

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

MessageBytes returns the serialized message body that signers must sign over. It is equivalent to Message.Marshal and is exposed as a convenience for offline signing workflows.

func (*Transaction) SerializedSize

func (tx *Transaction) SerializedSize() int

SerializedSize returns the wire-format byte count for this signed transaction without allocating the encoded buffer. The result equals len(tx.Marshal()) for any valid transaction.

func (*Transaction) Sign

func (tx *Transaction) Sign(ctx context.Context, signers ...Signer) error

Sign signs the transaction with the provided signers. Every signer must own a public key that appears in the first Message.Header.NumRequiredSignatures entries of Message.AccountKeys; otherwise Sign returns an error naming the offending signer and does not mutate any state.

Signature slots are filled in-place at the index matching each signer's position in the key list. The lookup from public key to slot is O(1): a map is built once per call, so the total cost scales linearly with the number of signers rather than with signers times required slots, satisfying the project's architectural principles on lookup scaling.

The serialized message body is computed once and reused across signers, so marshalling cost is amortised even when many signers are passed in a single call.

After Sign returns, any slot whose signer did not appear in the signers list retains its previous value (zero for a fresh transaction). Callers may call Sign multiple times with different signer sets to accumulate signatures over time, for example when coordinating a multi-party signing flow.

ctx is forwarded to every signer's Sign method, so a cancellation or deadline on ctx will reach remote signers mid-flight.

func (*Transaction) ToBase58

func (tx *Transaction) ToBase58() (string, error)

ToBase58 returns the base58-encoded wire format of the transaction.

func (*Transaction) ToBase64

func (tx *Transaction) ToBase64() (string, error)

ToBase64 returns the base64-encoded wire format of the transaction.

func (*Transaction) UnmarshalFromDecoder

func (tx *Transaction) UnmarshalFromDecoder(d *encoding.Decoder) error

UnmarshalFromDecoder implements encoding.Unmarshaler so that Transaction can be decoded generically via d.DecodeTo(&tx) from within a larger stream.

func (*Transaction) VerifySignatures

func (tx *Transaction) VerifySignatures() error

VerifySignatures checks every filled (non-zero) signature against the current message bytes using stdlib Ed25519 verification. A zero signature slot is treated as unsigned and is skipped. This is a best-effort local sanity check and is not a substitute for the validator's full transaction-validity rules.

type U128

type U128 = encoding.U128

Re-exports of the U128 / U256 primitive types so callers can write `solana.U128` / `solana.U256` in struct fields, matching the PublicKey / Hash / Signature discoverability. Both types keep all methods defined on their underlying encoding.* identities.

type U256

type U256 = encoding.U256

Re-exports of the U128 / U256 primitive types so callers can write `solana.U128` / `solana.U256` in struct fields, matching the PublicKey / Hash / Signature discoverability. Both types keep all methods defined on their underlying encoding.* identities.

type Uint8Slice

type Uint8Slice []uint8

Uint8Slice is a slice of bytes that JSON-marshals as an array of numbers instead of a base64 string.

Go's encoding/json has a special case that renders any slice whose element kind is uint8 (including named types like []byte) as a base64-encoded string. That is not the shape the Solana JSON-RPC uses for fields like CompiledInstruction.Accounts or MessageAddressTableLookup.WritableIndexes, which are transmitted as compact JSON arrays of small integers. Uint8Slice bypasses the special case by implementing json.Marshaler and json.Unmarshaler itself.

The UnmarshalJSON method is a self-contained byte-level parser and does not recursively call encoding/json, keeping the decoding hot path free of reflection and of the stdlib JSON library.

func (Uint8Slice) MarshalJSON

func (s Uint8Slice) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler by rendering the slice as a JSON array of decimal integers. A nil receiver marshals to "null"; an empty non-nil slice marshals to "[]".

func (*Uint8Slice) UnmarshalJSON

func (s *Uint8Slice) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler. It accepts either the JSON token "null" (leaving the receiver nil) or a JSON array whose elements are decimal integers in the range 0..255 inclusive. Whitespace between tokens is tolerated.

type Uint128

type Uint128 struct {
	Lo uint64
	Hi uint64
}

Uint128 is a little-endian unsigned 128-bit integer. Lo holds bits [0:64); Hi holds bits [64:128).

func Uint128FromBigInt

func Uint128FromBigInt(x *big.Int) Uint128

func (Uint128) BigInt

func (u Uint128) BigInt() *big.Int

func (Uint128) Bytes

func (u Uint128) Bytes() [16]byte

func (Uint128) IsZero

func (u Uint128) IsZero() bool

func (Uint128) MarshalToEncoder

func (u Uint128) MarshalToEncoder(e *encoding.Encoder)

func (Uint128) String

func (u Uint128) String() string

func (*Uint128) UnmarshalFromDecoder

func (u *Uint128) UnmarshalFromDecoder(d *encoding.Decoder) error

type Uint256

type Uint256 struct {
	Lo Uint128
	Hi Uint128
}

Uint256 is a little-endian unsigned 256-bit integer.

func (Uint256) BigInt

func (u Uint256) BigInt() *big.Int

func (Uint256) Bytes

func (u Uint256) Bytes() [32]byte

func (Uint256) IsZero

func (u Uint256) IsZero() bool

func (Uint256) MarshalToEncoder

func (u Uint256) MarshalToEncoder(e *encoding.Encoder)

func (Uint256) String

func (u Uint256) String() string

func (*Uint256) UnmarshalFromDecoder

func (u *Uint256) UnmarshalFromDecoder(d *encoding.Decoder) error

Directories

Path Synopsis
Package benchmarks is the home of Phase A performance measurements.
Package benchmarks is the home of Phase A performance measurements.
Package encoding provides Solana wire-format serialization primitives.
Package encoding provides Solana wire-format serialization primitives.
Package helpers provides pure-logic decoders and statistics used by the client package.
Package helpers provides pure-logic decoders and statistics used by the client package.
internal
hdwallet
Package hdwallet implements SLIP-0010 hierarchical deterministic key derivation for Ed25519.
Package hdwallet implements SLIP-0010 hierarchical deterministic key derivation for Ed25519.
testutil
Package testutil provides shared test helpers for solana-go.
Package testutil provides shared test helpers for solana-go.
Package rpc is a minimal, clean-room JSON-RPC 2.0 client for the Solana HTTP endpoint.
Package rpc is a minimal, clean-room JSON-RPC 2.0 client for the Solana HTTP endpoint.
programs
address-lookup-table
Package addresslookuptable provides typed instruction builders for the Solana Address Lookup Table program.
Package addresslookuptable provides typed instruction builders for the Solana Address Lookup Table program.
associated-token-account
Package associatedtokenaccount provides typed instruction builders for the Associated Token Account program, the Solana program that canonicalises the mapping from (wallet, mint) pairs to a specific token account address.
Package associatedtokenaccount provides typed instruction builders for the Associated Token Account program, the Solana program that canonicalises the mapping from (wallet, mint) pairs to a specific token account address.
compute-budget
Package computebudget provides typed instruction builders for the Solana ComputeBudget program.
Package computebudget provides typed instruction builders for the Solana ComputeBudget program.
memo
Package memo provides typed instruction builders for the SPL Memo program, which records arbitrary UTF-8 strings in the transaction log.
Package memo provides typed instruction builders for the SPL Memo program, which records arbitrary UTF-8 strings in the transaction log.
secp256k1
Package secp256k1 provides instruction builders for the Solana secp256k1 precompile program, which verifies Ethereum-style ECDSA signatures.
Package secp256k1 provides instruction builders for the Solana secp256k1 precompile program, which verifies Ethereum-style ECDSA signatures.
stake
Package stake provides typed instruction builders for the Solana Stake program.
Package stake provides typed instruction builders for the Solana Stake program.
system
Package system provides typed instruction builders for the Solana System program.
Package system provides typed instruction builders for the Solana System program.
token
Package token provides typed instruction builders for the SPL Token program.
Package token provides typed instruction builders for the SPL Token program.
token2022
Package token2022 provides typed instruction builders for the SPL Token-2022 program (TokenzQd...), the extension-capable successor to the classic SPL Token program (Tokenkeg...).
Package token2022 provides typed instruction builders for the SPL Token-2022 program (TokenzQd...), the extension-capable successor to the classic SPL Token program (Tokenkeg...).
vote
Package vote provides typed instruction builders for the Solana Vote program.
Package vote provides typed instruction builders for the Solana Vote program.
Package rpc provides the typed Solana JSON-RPC client.
Package rpc provides the typed Solana JSON-RPC client.
Package tx provides a fluent transaction builder for Solana.
Package tx provides a fluent transaction builder for Solana.
Package ws provides the low-level WebSocket transport for Solana JSON-RPC pub/sub notifications.
Package ws provides the low-level WebSocket transport for Solana JSON-RPC pub/sub notifications.

Jump to

Keyboard shortcuts

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