first commit

This commit is contained in:
thloyi
2025-12-12 17:55:36 +08:00
commit c9b0fc5ca5
8 changed files with 6658 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/.idea

3883
geyser.pb.go Normal file

File diff suppressed because it is too large Load Diff

272
geyser.proto Normal file
View File

@@ -0,0 +1,272 @@
syntax = "proto3";
import "google/protobuf/timestamp.proto";
import public "solana-storage.proto";
option go_package = "github.com/rpcpool/yellowstone-grpc/examples/golang/proto";
package geyser;
service Geyser {
rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeUpdate) {}
rpc Ping(PingRequest) returns (PongResponse) {}
rpc GetLatestBlockhash(GetLatestBlockhashRequest) returns (GetLatestBlockhashResponse) {}
rpc GetBlockHeight(GetBlockHeightRequest) returns (GetBlockHeightResponse) {}
rpc GetSlot(GetSlotRequest) returns (GetSlotResponse) {}
rpc IsBlockhashValid(IsBlockhashValidRequest) returns (IsBlockhashValidResponse) {}
rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {}
}
enum CommitmentLevel {
PROCESSED = 0;
CONFIRMED = 1;
FINALIZED = 2;
}
enum SlotStatus {
SLOT_PROCESSED = 0;
SLOT_CONFIRMED = 1;
SLOT_FINALIZED = 2;
SLOT_FIRST_SHRED_RECEIVED = 3;
SLOT_COMPLETED = 4;
SLOT_CREATED_BANK = 5;
SLOT_DEAD = 6;
}
message SubscribeRequest {
map<string, SubscribeRequestFilterAccounts> accounts = 1;
map<string, SubscribeRequestFilterSlots> slots = 2;
map<string, SubscribeRequestFilterTransactions> transactions = 3;
map<string, SubscribeRequestFilterTransactions> transactions_status = 10;
map<string, SubscribeRequestFilterBlocks> blocks = 4;
map<string, SubscribeRequestFilterBlocksMeta> blocks_meta = 5;
map<string, SubscribeRequestFilterEntry> entry = 8;
optional CommitmentLevel commitment = 6;
repeated SubscribeRequestAccountsDataSlice accounts_data_slice = 7;
optional SubscribeRequestPing ping = 9;
optional uint64 from_slot = 11;
}
message SubscribeRequestFilterAccounts {
repeated string account = 2;
repeated string owner = 3;
repeated SubscribeRequestFilterAccountsFilter filters = 4;
optional bool nonempty_txn_signature = 5;
}
message SubscribeRequestFilterAccountsFilter {
oneof filter {
SubscribeRequestFilterAccountsFilterMemcmp memcmp = 1;
uint64 datasize = 2;
bool token_account_state = 3;
SubscribeRequestFilterAccountsFilterLamports lamports = 4;
}
}
message SubscribeRequestFilterAccountsFilterMemcmp {
uint64 offset = 1;
oneof data {
bytes bytes = 2;
string base58 = 3;
string base64 = 4;
}
}
message SubscribeRequestFilterAccountsFilterLamports {
oneof cmp {
uint64 eq = 1;
uint64 ne = 2;
uint64 lt = 3;
uint64 gt = 4;
}
}
message SubscribeRequestFilterSlots {
optional bool filter_by_commitment = 1;
optional bool interslot_updates = 2;
}
message SubscribeRequestFilterTransactions {
optional bool vote = 1;
optional bool failed = 2;
optional string signature = 5;
repeated string account_include = 3;
repeated string account_exclude = 4;
repeated string account_required = 6;
}
message SubscribeRequestFilterBlocks {
repeated string account_include = 1;
optional bool include_transactions = 2;
optional bool include_accounts = 3;
optional bool include_entries = 4;
}
message SubscribeRequestFilterBlocksMeta {}
message SubscribeRequestFilterEntry {}
message SubscribeRequestAccountsDataSlice {
uint64 offset = 1;
uint64 length = 2;
}
message SubscribeRequestPing {
int32 id = 1;
}
message SubscribeUpdate {
repeated string filters = 1;
oneof update_oneof {
SubscribeUpdateAccount account = 2;
SubscribeUpdateSlot slot = 3;
SubscribeUpdateTransaction transaction = 4;
SubscribeUpdateTransactionStatus transaction_status = 10;
SubscribeUpdateBlock block = 5;
SubscribeUpdatePing ping = 6;
SubscribeUpdatePong pong = 9;
SubscribeUpdateBlockMeta block_meta = 7;
SubscribeUpdateEntry entry = 8;
}
google.protobuf.Timestamp created_at = 11;
}
message SubscribeUpdateAccount {
SubscribeUpdateAccountInfo account = 1;
uint64 slot = 2;
bool is_startup = 3;
}
message SubscribeUpdateAccountInfo {
bytes pubkey = 1;
uint64 lamports = 2;
bytes owner = 3;
bool executable = 4;
uint64 rent_epoch = 5;
bytes data = 6;
uint64 write_version = 7;
optional bytes txn_signature = 8;
}
message SubscribeUpdateSlot {
uint64 slot = 1;
optional uint64 parent = 2;
SlotStatus status = 3;
optional string dead_error = 4;
}
message SubscribeUpdateTransaction {
SubscribeUpdateTransactionInfo transaction = 1;
uint64 slot = 2;
}
message SubscribeUpdateTransactionInfo {
bytes signature = 1;
bool is_vote = 2;
solana.storage.ConfirmedBlock.Transaction transaction = 3;
solana.storage.ConfirmedBlock.TransactionStatusMeta meta = 4;
uint64 index = 5;
}
message SubscribeUpdateTransactionStatus {
uint64 slot = 1;
bytes signature = 2;
bool is_vote = 3;
uint64 index = 4;
solana.storage.ConfirmedBlock.TransactionError err = 5;
}
message SubscribeUpdateBlock {
uint64 slot = 1;
string blockhash = 2;
solana.storage.ConfirmedBlock.Rewards rewards = 3;
solana.storage.ConfirmedBlock.UnixTimestamp block_time = 4;
solana.storage.ConfirmedBlock.BlockHeight block_height = 5;
uint64 parent_slot = 7;
string parent_blockhash = 8;
uint64 executed_transaction_count = 9;
repeated SubscribeUpdateTransactionInfo transactions = 6;
uint64 updated_account_count = 10;
repeated SubscribeUpdateAccountInfo accounts = 11;
uint64 entries_count = 12;
repeated SubscribeUpdateEntry entries = 13;
}
message SubscribeUpdateBlockMeta {
uint64 slot = 1;
string blockhash = 2;
solana.storage.ConfirmedBlock.Rewards rewards = 3;
solana.storage.ConfirmedBlock.UnixTimestamp block_time = 4;
solana.storage.ConfirmedBlock.BlockHeight block_height = 5;
uint64 parent_slot = 6;
string parent_blockhash = 7;
uint64 executed_transaction_count = 8;
uint64 entries_count = 9;
}
message SubscribeUpdateEntry {
uint64 slot = 1;
uint64 index = 2;
uint64 num_hashes = 3;
bytes hash = 4;
uint64 executed_transaction_count = 5;
uint64 starting_transaction_index = 6; // added in v1.18, for solana 1.17 value is always 0
}
message SubscribeUpdatePing {}
message SubscribeUpdatePong {
int32 id = 1;
}
// non-streaming methods
message PingRequest {
int32 count = 1;
}
message PongResponse {
int32 count = 1;
}
message GetLatestBlockhashRequest {
optional CommitmentLevel commitment = 1;
}
message GetLatestBlockhashResponse {
uint64 slot = 1;
string blockhash = 2;
uint64 last_valid_block_height = 3;
}
message GetBlockHeightRequest {
optional CommitmentLevel commitment = 1;
}
message GetBlockHeightResponse {
uint64 block_height = 1;
}
message GetSlotRequest {
optional CommitmentLevel commitment = 1;
}
message GetSlotResponse {
uint64 slot = 1;
}
message GetVersionRequest {}
message GetVersionResponse {
string version = 1;
}
message IsBlockhashValidRequest {
string blockhash = 1;
optional CommitmentLevel commitment = 2;
}
message IsBlockhashValidResponse {
uint64 slot = 1;
bool valid = 2;
}

364
geyser_grpc.pb.go Normal file
View File

@@ -0,0 +1,364 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v6.33.1
// source: geyser.proto
package proto
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
Geyser_Subscribe_FullMethodName = "/geyser.Geyser/Subscribe"
Geyser_Ping_FullMethodName = "/geyser.Geyser/Ping"
Geyser_GetLatestBlockhash_FullMethodName = "/geyser.Geyser/GetLatestBlockhash"
Geyser_GetBlockHeight_FullMethodName = "/geyser.Geyser/GetBlockHeight"
Geyser_GetSlot_FullMethodName = "/geyser.Geyser/GetSlot"
Geyser_IsBlockhashValid_FullMethodName = "/geyser.Geyser/IsBlockhashValid"
Geyser_GetVersion_FullMethodName = "/geyser.Geyser/GetVersion"
)
// GeyserClient is the client API for Geyser service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type GeyserClient interface {
Subscribe(ctx context.Context, opts ...grpc.CallOption) (Geyser_SubscribeClient, error)
Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PongResponse, error)
GetLatestBlockhash(ctx context.Context, in *GetLatestBlockhashRequest, opts ...grpc.CallOption) (*GetLatestBlockhashResponse, error)
GetBlockHeight(ctx context.Context, in *GetBlockHeightRequest, opts ...grpc.CallOption) (*GetBlockHeightResponse, error)
GetSlot(ctx context.Context, in *GetSlotRequest, opts ...grpc.CallOption) (*GetSlotResponse, error)
IsBlockhashValid(ctx context.Context, in *IsBlockhashValidRequest, opts ...grpc.CallOption) (*IsBlockhashValidResponse, error)
GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error)
}
type geyserClient struct {
cc grpc.ClientConnInterface
}
func NewGeyserClient(cc grpc.ClientConnInterface) GeyserClient {
return &geyserClient{cc}
}
func (c *geyserClient) Subscribe(ctx context.Context, opts ...grpc.CallOption) (Geyser_SubscribeClient, error) {
stream, err := c.cc.NewStream(ctx, &Geyser_ServiceDesc.Streams[0], Geyser_Subscribe_FullMethodName, opts...)
if err != nil {
return nil, err
}
x := &geyserSubscribeClient{stream}
return x, nil
}
type Geyser_SubscribeClient interface {
Send(*SubscribeRequest) error
Recv() (*SubscribeUpdate, error)
grpc.ClientStream
}
type geyserSubscribeClient struct {
grpc.ClientStream
}
func (x *geyserSubscribeClient) Send(m *SubscribeRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *geyserSubscribeClient) Recv() (*SubscribeUpdate, error) {
m := new(SubscribeUpdate)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *geyserClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PongResponse, error) {
out := new(PongResponse)
err := c.cc.Invoke(ctx, Geyser_Ping_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *geyserClient) GetLatestBlockhash(ctx context.Context, in *GetLatestBlockhashRequest, opts ...grpc.CallOption) (*GetLatestBlockhashResponse, error) {
out := new(GetLatestBlockhashResponse)
err := c.cc.Invoke(ctx, Geyser_GetLatestBlockhash_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *geyserClient) GetBlockHeight(ctx context.Context, in *GetBlockHeightRequest, opts ...grpc.CallOption) (*GetBlockHeightResponse, error) {
out := new(GetBlockHeightResponse)
err := c.cc.Invoke(ctx, Geyser_GetBlockHeight_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *geyserClient) GetSlot(ctx context.Context, in *GetSlotRequest, opts ...grpc.CallOption) (*GetSlotResponse, error) {
out := new(GetSlotResponse)
err := c.cc.Invoke(ctx, Geyser_GetSlot_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *geyserClient) IsBlockhashValid(ctx context.Context, in *IsBlockhashValidRequest, opts ...grpc.CallOption) (*IsBlockhashValidResponse, error) {
out := new(IsBlockhashValidResponse)
err := c.cc.Invoke(ctx, Geyser_IsBlockhashValid_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *geyserClient) GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) {
out := new(GetVersionResponse)
err := c.cc.Invoke(ctx, Geyser_GetVersion_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// GeyserServer is the server API for Geyser service.
// All implementations must embed UnimplementedGeyserServer
// for forward compatibility
type GeyserServer interface {
Subscribe(Geyser_SubscribeServer) error
Ping(context.Context, *PingRequest) (*PongResponse, error)
GetLatestBlockhash(context.Context, *GetLatestBlockhashRequest) (*GetLatestBlockhashResponse, error)
GetBlockHeight(context.Context, *GetBlockHeightRequest) (*GetBlockHeightResponse, error)
GetSlot(context.Context, *GetSlotRequest) (*GetSlotResponse, error)
IsBlockhashValid(context.Context, *IsBlockhashValidRequest) (*IsBlockhashValidResponse, error)
GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error)
mustEmbedUnimplementedGeyserServer()
}
// UnimplementedGeyserServer must be embedded to have forward compatible implementations.
type UnimplementedGeyserServer struct {
}
func (UnimplementedGeyserServer) Subscribe(Geyser_SubscribeServer) error {
return status.Errorf(codes.Unimplemented, "method Subscribe not implemented")
}
func (UnimplementedGeyserServer) Ping(context.Context, *PingRequest) (*PongResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
}
func (UnimplementedGeyserServer) GetLatestBlockhash(context.Context, *GetLatestBlockhashRequest) (*GetLatestBlockhashResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetLatestBlockhash not implemented")
}
func (UnimplementedGeyserServer) GetBlockHeight(context.Context, *GetBlockHeightRequest) (*GetBlockHeightResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetBlockHeight not implemented")
}
func (UnimplementedGeyserServer) GetSlot(context.Context, *GetSlotRequest) (*GetSlotResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetSlot not implemented")
}
func (UnimplementedGeyserServer) IsBlockhashValid(context.Context, *IsBlockhashValidRequest) (*IsBlockhashValidResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsBlockhashValid not implemented")
}
func (UnimplementedGeyserServer) GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented")
}
func (UnimplementedGeyserServer) mustEmbedUnimplementedGeyserServer() {}
// UnsafeGeyserServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to GeyserServer will
// result in compilation errors.
type UnsafeGeyserServer interface {
mustEmbedUnimplementedGeyserServer()
}
func RegisterGeyserServer(s grpc.ServiceRegistrar, srv GeyserServer) {
s.RegisterService(&Geyser_ServiceDesc, srv)
}
func _Geyser_Subscribe_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(GeyserServer).Subscribe(&geyserSubscribeServer{stream})
}
type Geyser_SubscribeServer interface {
Send(*SubscribeUpdate) error
Recv() (*SubscribeRequest, error)
grpc.ServerStream
}
type geyserSubscribeServer struct {
grpc.ServerStream
}
func (x *geyserSubscribeServer) Send(m *SubscribeUpdate) error {
return x.ServerStream.SendMsg(m)
}
func (x *geyserSubscribeServer) Recv() (*SubscribeRequest, error) {
m := new(SubscribeRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func _Geyser_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PingRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GeyserServer).Ping(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Geyser_Ping_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GeyserServer).Ping(ctx, req.(*PingRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Geyser_GetLatestBlockhash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetLatestBlockhashRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GeyserServer).GetLatestBlockhash(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Geyser_GetLatestBlockhash_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GeyserServer).GetLatestBlockhash(ctx, req.(*GetLatestBlockhashRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Geyser_GetBlockHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetBlockHeightRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GeyserServer).GetBlockHeight(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Geyser_GetBlockHeight_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GeyserServer).GetBlockHeight(ctx, req.(*GetBlockHeightRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Geyser_GetSlot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetSlotRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GeyserServer).GetSlot(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Geyser_GetSlot_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GeyserServer).GetSlot(ctx, req.(*GetSlotRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Geyser_IsBlockhashValid_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(IsBlockhashValidRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GeyserServer).IsBlockhashValid(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Geyser_IsBlockhashValid_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GeyserServer).IsBlockhashValid(ctx, req.(*IsBlockhashValidRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Geyser_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetVersionRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GeyserServer).GetVersion(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Geyser_GetVersion_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GeyserServer).GetVersion(ctx, req.(*GetVersionRequest))
}
return interceptor(ctx, in, info, handler)
}
// Geyser_ServiceDesc is the grpc.ServiceDesc for Geyser service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Geyser_ServiceDesc = grpc.ServiceDesc{
ServiceName: "geyser.Geyser",
HandlerType: (*GeyserServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Ping",
Handler: _Geyser_Ping_Handler,
},
{
MethodName: "GetLatestBlockhash",
Handler: _Geyser_GetLatestBlockhash_Handler,
},
{
MethodName: "GetBlockHeight",
Handler: _Geyser_GetBlockHeight_Handler,
},
{
MethodName: "GetSlot",
Handler: _Geyser_GetSlot_Handler,
},
{
MethodName: "IsBlockhashValid",
Handler: _Geyser_IsBlockhashValid_Handler,
},
{
MethodName: "GetVersion",
Handler: _Geyser_GetVersion_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "Subscribe",
Handler: _Geyser_Subscribe_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "geyser.proto",
}

8
go.mod Normal file
View File

@@ -0,0 +1,8 @@
module go.onsig.ai/onsig/yellowstone-proto
go 1.25
require (
google.golang.org/grpc v1.75.1
google.golang.org/protobuf v1.36.10
)

2
go.sum Normal file
View File

@@ -0,0 +1,2 @@
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=

1979
solana-storage.pb.go Normal file

File diff suppressed because it is too large Load Diff

149
solana-storage.proto Normal file
View File

@@ -0,0 +1,149 @@
syntax = "proto3";
package solana.storage.ConfirmedBlock;
option go_package = "github.com/rpcpool/yellowstone-grpc/examples/golang/proto";
message ConfirmedBlock {
string previous_blockhash = 1;
string blockhash = 2;
uint64 parent_slot = 3;
repeated ConfirmedTransaction transactions = 4;
repeated Reward rewards = 5;
UnixTimestamp block_time = 6;
BlockHeight block_height = 7;
NumPartitions num_partitions = 8;
}
message ConfirmedTransaction {
Transaction transaction = 1;
TransactionStatusMeta meta = 2;
}
message Transaction {
repeated bytes signatures = 1;
Message message = 2;
}
message Message {
MessageHeader header = 1;
repeated bytes account_keys = 2;
bytes recent_blockhash = 3;
repeated CompiledInstruction instructions = 4;
bool versioned = 5;
repeated MessageAddressTableLookup address_table_lookups = 6;
}
message MessageHeader {
uint32 num_required_signatures = 1;
uint32 num_readonly_signed_accounts = 2;
uint32 num_readonly_unsigned_accounts = 3;
}
message MessageAddressTableLookup {
bytes account_key = 1;
bytes writable_indexes = 2;
bytes readonly_indexes = 3;
}
message TransactionStatusMeta {
TransactionError err = 1;
uint64 fee = 2;
repeated uint64 pre_balances = 3;
repeated uint64 post_balances = 4;
repeated InnerInstructions inner_instructions = 5;
bool inner_instructions_none = 10;
repeated string log_messages = 6;
bool log_messages_none = 11;
repeated TokenBalance pre_token_balances = 7;
repeated TokenBalance post_token_balances = 8;
repeated Reward rewards = 9;
repeated bytes loaded_writable_addresses = 12;
repeated bytes loaded_readonly_addresses = 13;
ReturnData return_data = 14;
bool return_data_none = 15;
// Sum of compute units consumed by all instructions.
// Available since Solana v1.10.35 / v1.11.6.
// Set to `None` for txs executed on earlier versions.
optional uint64 compute_units_consumed = 16;
}
message TransactionError {
bytes err = 1;
}
message InnerInstructions {
uint32 index = 1;
repeated InnerInstruction instructions = 2;
}
message InnerInstruction {
uint32 program_id_index = 1;
bytes accounts = 2;
bytes data = 3;
// Invocation stack height of an inner instruction.
// Available since Solana v1.14.6
// Set to `None` for txs executed on earlier versions.
optional uint32 stack_height = 4;
}
message CompiledInstruction {
uint32 program_id_index = 1;
bytes accounts = 2;
bytes data = 3;
}
message TokenBalance {
uint32 account_index = 1;
string mint = 2;
UiTokenAmount ui_token_amount = 3;
string owner = 4;
string program_id = 5;
}
message UiTokenAmount {
double ui_amount = 1;
uint32 decimals = 2;
string amount = 3;
string ui_amount_string = 4;
}
message ReturnData {
bytes program_id = 1;
bytes data = 2;
}
enum RewardType {
Unspecified = 0;
Fee = 1;
Rent = 2;
Staking = 3;
Voting = 4;
}
message Reward {
string pubkey = 1;
int64 lamports = 2;
uint64 post_balance = 3;
RewardType reward_type = 4;
string commission = 5;
}
message Rewards {
repeated Reward rewards = 1;
NumPartitions num_partitions = 2;
}
message UnixTimestamp {
int64 timestamp = 1;
}
message BlockHeight {
uint64 block_height = 1;
}
message NumPartitions {
uint64 num_partitions = 1;
}