Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
blockchain-develop committed Apr 29, 2024
1 parent bb43830 commit 2e017cb
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 0 deletions.
76 changes: 76 additions & 0 deletions rpc/getBlock.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,79 @@ type GetBlockResult struct {
// The number of blocks beneath this block.
BlockHeight *uint64 `json:"blockHeight"`
}

func (cl *Client) GetParsedBlockWithOpts(
ctx context.Context,
slot uint64,
opts *GetBlockOpts,
) (out *GetParsedBlockResult, err error) {

obj := M{
"encoding": solana.EncodingJSONParsed,
}

if opts != nil {
if opts.TransactionDetails != "" {
obj["transactionDetails"] = opts.TransactionDetails
}
if opts.Rewards != nil {
obj["rewards"] = opts.Rewards
}
if opts.Commitment != "" {
obj["commitment"] = opts.Commitment
}
if opts.MaxSupportedTransactionVersion != nil {
obj["maxSupportedTransactionVersion"] = *opts.MaxSupportedTransactionVersion
}
}

params := []interface{}{slot, obj}

err = cl.rpcClient.CallForInto(ctx, &out, "getBlock", params)

if err != nil {
return nil, err
}
if out == nil {
// Block is not confirmed.
return nil, ErrNotConfirmed
}
return
}

type GetParsedBlockResult struct {
// The blockhash of this block.
Blockhash solana.Hash `json:"blockhash"`

// The blockhash of this block's parent;
// if the parent block is not available due to ledger cleanup,
// this field will return "11111111111111111111111111111111".
PreviousBlockhash solana.Hash `json:"previousBlockhash"`

// The slot index of this block's parent.
ParentSlot uint64 `json:"parentSlot"`

// Present if "full" transaction details are requested.
Transactions []ParsedTransactionWithMeta `json:"transactions"`

// Present if "signatures" are requested for transaction details;
// an array of signatures, corresponding to the transaction order in the block.
Signatures []solana.Signature `json:"signatures"`

// Present if rewards are requested.
Rewards []BlockReward `json:"rewards"`

// Estimated production time, as Unix timestamp (seconds since the Unix epoch).
// Nil if not available.
BlockTime *solana.UnixTimeSeconds `json:"blockTime"`

// The number of blocks beneath this block.
BlockHeight *uint64 `json:"blockHeight"`
}

type ParsedTransactionWithMeta struct {
Slot uint64
BlockTime *solana.UnixTimeSeconds
Transaction *ParsedTransaction
Meta *ParsedTransactionMeta
}
123 changes: 123 additions & 0 deletions rpc/ws/parsedBlockSubscribe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2022 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 ws

import (
"github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/rpc"
)

type ParsedBlockResult struct {
Context struct {
Slot uint64
} `json:"context"`
Value struct {
Slot uint64 `json:"slot"`
Err interface{} `json:"err,omitempty"`
Block *rpc.GetParsedBlockResult `json:"block,omitempty"`
} `json:"value"`
}

// NOTE: Unstable, disabled by default
//
// Subscribe to receive notification anytime a new block is Confirmed or Finalized.
//
// **This subscription is unstable and only available if the validator was started
// with the `--rpc-pubsub-enable-block-subscription` flag. The format of this
// subscription may change in the future**
func (cl *Client) ParsedBlockSubscribe(
filter BlockSubscribeFilter,
opts *BlockSubscribeOpts,
) (*ParsedBlockSubscription, error) {
var params []interface{}
if filter != nil {
switch v := filter.(type) {
case BlockSubscribeFilterAll:
params = append(params, "all")
case *BlockSubscribeFilterMentionsAccountOrProgram:
params = append(params, rpc.M{"mentionsAccountOrProgram": v.Pubkey})
}
}
if opts != nil {
obj := make(rpc.M)
if opts.Commitment != "" {
obj["commitment"] = opts.Commitment
}
obj["encoding"] = solana.EncodingJSONParsed
if opts.TransactionDetails != "" {
obj["transactionDetails"] = opts.TransactionDetails
}
if opts.Rewards != nil {
obj["rewards"] = opts.Rewards
}
if opts.MaxSupportedTransactionVersion != nil {
obj["maxSupportedTransactionVersion"] = *opts.MaxSupportedTransactionVersion
}
if len(obj) > 0 {
params = append(params, obj)
}
}
genSub, err := cl.subscribe(
params,
nil,
"blockSubscribe",
"blockUnsubscribe",
func(msg []byte) (interface{}, error) {
var res ParsedBlockResult
err := decodeResponseFromMessage(msg, &res)
return &res, err
},
)
if err != nil {
return nil, err
}
return &ParsedBlockSubscription{
sub: genSub,
}, nil
}

type ParsedBlockSubscription struct {
sub *Subscription
}

func (sw *ParsedBlockSubscription) Recv() (*ParsedBlockResult, error) {
select {
case d := <-sw.sub.stream:
return d.(*ParsedBlockResult), nil
case err := <-sw.sub.err:
return nil, err
}
}

func (sw *ParsedBlockSubscription) Err() <-chan error {
return sw.sub.err
}

func (sw *ParsedBlockSubscription) Response() <-chan *ParsedBlockResult {
typedChan := make(chan *ParsedBlockResult, 1)
go func(ch chan *ParsedBlockResult) {
// TODO: will this subscription yield more than one result?
d, ok := <-sw.sub.stream
if !ok {
return
}
ch <- d.(*ParsedBlockResult)
}(typedChan)
return typedChan
}

func (sw *ParsedBlockSubscription) Unsubscribe() {
sw.sub.Unsubscribe()
}

0 comments on commit 2e017cb

Please sign in to comment.