github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/events/parse.go (about) 1 package events 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/onflow/flow-go/model/flow" 8 ) 9 10 type ParsedEventType int 11 12 const ( 13 ProtocolEventType ParsedEventType = iota + 1 14 AccountEventType 15 ) 16 17 type ParsedEvent struct { 18 Type ParsedEventType 19 EventType flow.EventType 20 Address string 21 Contract string 22 ContractName string 23 Name string 24 } 25 26 // ParseEvent parses an event type into its parts. There are 2 valid EventType formats: 27 // - flow.[EventName] 28 // - A.[Address].[Contract].[EventName] 29 // Any other format results in an error. 30 func ParseEvent(eventType flow.EventType) (*ParsedEvent, error) { 31 parts := strings.Split(string(eventType), ".") 32 33 switch parts[0] { 34 case "flow": 35 if len(parts) == 2 { 36 return &ParsedEvent{ 37 Type: ProtocolEventType, 38 EventType: eventType, 39 Contract: parts[0], 40 ContractName: parts[0], 41 Name: parts[1], 42 }, nil 43 } 44 45 case "A": 46 if len(parts) == 4 { 47 return &ParsedEvent{ 48 Type: AccountEventType, 49 EventType: eventType, 50 Address: parts[1], 51 Contract: fmt.Sprintf("A.%s.%s", parts[1], parts[2]), 52 ContractName: parts[2], 53 Name: parts[3], 54 }, nil 55 } 56 } 57 58 return nil, fmt.Errorf("invalid event type: %s", eventType) 59 } 60 61 // ValidateEvent validates an event type is properly formed and for the correct network, and returns 62 // a parsed event. If the event type is invalid, an error is returned. 63 func ValidateEvent(eventType flow.EventType, chain flow.Chain) (*ParsedEvent, error) { 64 parsed, err := ParseEvent(eventType) 65 if err != nil { 66 return nil, err 67 } 68 69 // only account type events have an address field 70 if parsed.Type != AccountEventType { 71 return parsed, nil 72 } 73 74 contractAddress := flow.HexToAddress(parsed.Address) 75 if !chain.IsValid(contractAddress) { 76 return nil, fmt.Errorf("invalid event contract address") 77 } 78 79 return parsed, nil 80 }