github.com/diadata-org/diadata@v1.4.593/pkg/dia/helpers/substrate-helper/event.go (about) 1 package substratehelper 2 3 import ( 4 "errors" 5 "fmt" 6 7 gsrpc "github.com/diadata-org/diadata/pkg/dia/helpers/substrate-helper/gsrpc" 8 "github.com/diadata-org/diadata/pkg/dia/helpers/substrate-helper/gsrpc/registry/parser" 9 "github.com/diadata-org/diadata/pkg/dia/helpers/substrate-helper/gsrpc/registry/retriever" 10 "github.com/diadata-org/diadata/pkg/dia/helpers/substrate-helper/gsrpc/registry/state" 11 12 "github.com/diadata-org/diadata/pkg/dia/helpers/substrate-helper/gsrpc/types" 13 14 "github.com/sirupsen/logrus" 15 ) 16 17 type SubstrateEventHelper struct { 18 logger *logrus.Entry 19 API *gsrpc.SubstrateAPI 20 } 21 22 func NewSubstrateEventHelper(nodeURL string, logger *logrus.Entry) (*SubstrateEventHelper, error) { 23 api, err := gsrpc.NewSubstrateAPI(nodeURL) 24 if err != nil { 25 return nil, fmt.Errorf("failed to connect to Substrate node: %v", err) 26 } 27 return &SubstrateEventHelper{API: api, logger: logger}, nil 28 } 29 30 func (s *SubstrateEventHelper) ListenForSpecificBlock(blockNumber uint64, callback func([]*parser.Event, uint64)) error { 31 blockHash, err := s.API.RPC.Chain.GetBlockHash(blockNumber) 32 if err != nil { 33 message := fmt.Sprintf("Failed to fetch block hash: %v", err) 34 s.logger.Errorf(message, err) 35 return errors.New(message) 36 } 37 38 events, err := s.DecodeEvents(blockHash) 39 if err != nil { 40 message := fmt.Sprintf("Failed to decode events: %v", err) 41 s.logger.Errorf(message, err) 42 return err 43 } 44 45 callback(events, blockNumber) 46 47 return nil 48 } 49 50 func (s *SubstrateEventHelper) DecodeEvents(blockHash types.Hash) ([]*parser.Event, error) { 51 r, err := retriever.NewDefaultEventRetriever(state.NewEventProvider(s.API.RPC.State), s.API.RPC.State) 52 53 if err != nil { 54 return nil, fmt.Errorf("couldn't create event retriever: %s", err) 55 } 56 57 events, err := r.GetEvents(blockHash) 58 59 if err != nil { 60 return nil, fmt.Errorf("couldn't retrieve events for block hash %d: %s", blockHash, err) 61 } 62 63 s.logger.Infof("Found %d events\n", len(events)) 64 65 return events, nil 66 } 67 68 // ListenForNewBlocks listens for new blocks and continuously decodes events. 69 func (s *SubstrateEventHelper) ListenForNewBlocks(callback func([]*parser.Event, uint64)) error { 70 sub, err := s.API.RPC.Chain.SubscribeNewHeads() 71 if err != nil { 72 return fmt.Errorf("failed to subscribe to new heads: %v", err) 73 } 74 s.logger.Info("Listening for new blocks...") 75 76 for { 77 head := <-sub.Chan() 78 blockNumber := uint64(head.Number) 79 blockHash, err := s.API.RPC.Chain.GetBlockHash(blockNumber) 80 if err != nil { 81 s.logger.Errorf("Failed to fetch block hash: %v\n", err) 82 continue 83 } 84 s.logger.Infof("\nNew block detected! Block number: %v, Block hash: %v\n", head.Number, blockHash.Hex()) 85 86 events, err := s.DecodeEvents(blockHash) 87 if err != nil { 88 s.logger.Errorf("Failed to decode events: %v\n", err) 89 continue 90 } 91 92 callback(events, blockNumber) 93 } 94 }