From 5055c04629aabf0423e5557cc116d25c0e2b0dd1 Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 22 Oct 2025 12:14:37 -0400 Subject: [PATCH] mild refactoring --- event.go | 112 +++++++++++++++++++++++++++--------------------------- filter.go | 78 ++++++++++++++++++------------------- 2 files changed, 95 insertions(+), 95 deletions(-) diff --git a/event.go b/event.go index 331e24d..e1c7bb4 100644 --- a/event.go +++ b/event.go @@ -26,14 +26,14 @@ var ( Hex128Pattern = regexp.MustCompile("^[a-f0-9]{128}$") ) -func (event Event) Serialize() ([]byte, error) { +func (e Event) Serialize() ([]byte, error) { serialized := []interface{}{ 0, - event.PubKey, - event.CreatedAt, - event.Kind, - event.Tags, - event.Content, + e.PubKey, + e.CreatedAt, + e.Kind, + e.Tags, + e.Content, } bytes, err := json.Marshal(serialized) @@ -43,8 +43,8 @@ func (event Event) Serialize() ([]byte, error) { return bytes, nil } -func (event Event) GetID() (string, error) { - bytes, err := event.Serialize() +func (e Event) GetID() (string, error) { + bytes, err := e.Serialize() if err != nil { return "", err } @@ -52,54 +52,6 @@ func (event Event) GetID() (string, error) { return hex.EncodeToString(hash[:]), nil } -func (event Event) Validate() error { - if err := event.ValidateStructure(); err != nil { - return err - } - - if err := event.ValidateID(); err != nil { - return err - } - - return ValidateSignature(event.ID, event.Sig, event.PubKey) -} - -func (event Event) ValidateStructure() error { - if !Hex64Pattern.MatchString(event.PubKey) { - return fmt.Errorf("pubkey must be 64 lowercase hex characters") - } - - if !Hex64Pattern.MatchString(event.ID) { - return fmt.Errorf("id must be 64 hex characters") - } - - if !Hex128Pattern.MatchString(event.Sig) { - return fmt.Errorf("signature must be 128 hex characters") - } - - for _, tag := range event.Tags { - if len(tag) < 2 { - return fmt.Errorf("tags must contain at least two elements") - } - } - - return nil -} - -func (event Event) ValidateID() error { - computedID, err := event.GetID() - if err != nil { - return fmt.Errorf("failed to compute event id") - } - if event.ID == "" { - return fmt.Errorf("event id is empty") - } - if computedID != event.ID { - return fmt.Errorf("event id %q does not match computed id %q", event.ID, computedID) - } - return nil -} - func SignEvent(eventID, privateKeyHex string) (string, error) { skBytes, err := hex.DecodeString(privateKeyHex) if err != nil { @@ -121,6 +73,54 @@ func SignEvent(eventID, privateKeyHex string) (string, error) { return hex.EncodeToString(sig.Serialize()), nil } +func (e Event) Validate() error { + if err := e.ValidateStructure(); err != nil { + return err + } + + if err := e.ValidateID(); err != nil { + return err + } + + return ValidateSignature(e.ID, e.Sig, e.PubKey) +} + +func (e Event) ValidateStructure() error { + if !Hex64Pattern.MatchString(e.PubKey) { + return fmt.Errorf("pubkey must be 64 lowercase hex characters") + } + + if !Hex64Pattern.MatchString(e.ID) { + return fmt.Errorf("id must be 64 hex characters") + } + + if !Hex128Pattern.MatchString(e.Sig) { + return fmt.Errorf("signature must be 128 hex characters") + } + + for _, tag := range e.Tags { + if len(tag) < 2 { + return fmt.Errorf("tags must contain at least two elements") + } + } + + return nil +} + +func (e Event) ValidateID() error { + computedID, err := e.GetID() + if err != nil { + return fmt.Errorf("failed to compute event id") + } + if e.ID == "" { + return fmt.Errorf("event id is empty") + } + if computedID != e.ID { + return fmt.Errorf("event id %q does not match computed id %q", e.ID, computedID) + } + return nil +} + func ValidateSignature(eventID, eventSig, publicKeyHex string) error { idBytes, err := hex.DecodeString(eventID) if err != nil { diff --git a/filter.go b/filter.go index fd8c2e6..7d250de 100644 --- a/filter.go +++ b/filter.go @@ -17,36 +17,36 @@ type Filter struct { Extensions map[string]json.RawMessage } -func (filter Filter) MarshalJSON() ([]byte, error) { +func (f Filter) MarshalJSON() ([]byte, error) { outputMap := make(map[string]interface{}) // Add standard fields - if filter.IDs != nil { - outputMap["ids"] = filter.IDs + if f.IDs != nil { + outputMap["ids"] = f.IDs } - if filter.Authors != nil { - outputMap["authors"] = filter.Authors + if f.Authors != nil { + outputMap["authors"] = f.Authors } - if filter.Kinds != nil { - outputMap["kinds"] = filter.Kinds + if f.Kinds != nil { + outputMap["kinds"] = f.Kinds } - if filter.Since != nil { - outputMap["since"] = *filter.Since + if f.Since != nil { + outputMap["since"] = *f.Since } - if filter.Until != nil { - outputMap["until"] = *filter.Until + if f.Until != nil { + outputMap["until"] = *f.Until } - if filter.Limit != nil { - outputMap["limit"] = *filter.Limit + if f.Limit != nil { + outputMap["limit"] = *f.Limit } // Add tags - for key, values := range filter.Tags { + for key, values := range f.Tags { outputMap["#"+key] = values } // Merge extensions - for key, raw := range filter.Extensions { + for key, raw := range f.Extensions { // Disallow standard keys in extensions standardKeys := []string{"ids", "authors", "kinds", "since", "until", "limit"} found := false @@ -76,7 +76,7 @@ func (filter Filter) MarshalJSON() ([]byte, error) { return json.Marshal(outputMap) } -func (filter *Filter) UnmarshalJSON(data []byte) error { +func (f *Filter) UnmarshalJSON(data []byte) error { // Decode into raw map raw := make(map[string]json.RawMessage) if err := json.Unmarshal(data, &raw); err != nil { @@ -85,21 +85,21 @@ func (filter *Filter) UnmarshalJSON(data []byte) error { // Extract standard fields if v, ok := raw["ids"]; ok { - if err := json.Unmarshal(v, &filter.IDs); err != nil { + if err := json.Unmarshal(v, &f.IDs); err != nil { return err } delete(raw, "ids") } if v, ok := raw["authors"]; ok { - if err := json.Unmarshal(v, &filter.Authors); err != nil { + if err := json.Unmarshal(v, &f.Authors); err != nil { return err } delete(raw, "authors") } if v, ok := raw["kinds"]; ok { - if err := json.Unmarshal(v, &filter.Kinds); err != nil { + if err := json.Unmarshal(v, &f.Kinds); err != nil { return err } delete(raw, "kinds") @@ -107,39 +107,39 @@ func (filter *Filter) UnmarshalJSON(data []byte) error { if v, ok := raw["since"]; ok { if string(raw["since"]) == "null" { - filter.Since = nil + f.Since = nil } else { var val int if err := json.Unmarshal(v, &val); err != nil { return err } - filter.Since = &val + f.Since = &val } delete(raw, "since") } if v, ok := raw["until"]; ok { if string(raw["until"]) == "null" { - filter.Until = nil + f.Until = nil } else { var val int if err := json.Unmarshal(v, &val); err != nil { return err } - filter.Until = &val + f.Until = &val } delete(raw, "until") } if v, ok := raw["limit"]; ok { if string(raw["limit"]) == "null" { - filter.Limit = nil + f.Limit = nil } else { var val int if err := json.Unmarshal(v, &val); err != nil { return err } - filter.Limit = &val + f.Limit = &val } delete(raw, "limit") } @@ -148,57 +148,57 @@ func (filter *Filter) UnmarshalJSON(data []byte) error { for key := range raw { if strings.HasPrefix(key, "#") { // Leave Tags as `nil` unless tag fields exist - if filter.Tags == nil { - filter.Tags = make(map[string][]string) + if f.Tags == nil { + f.Tags = make(map[string][]string) } tagKey := strings.TrimPrefix(key, "#") var tagValues []string if err := json.Unmarshal(raw[key], &tagValues); err != nil { return err } - filter.Tags[tagKey] = tagValues + f.Tags[tagKey] = tagValues delete(raw, key) } } // Place remaining fields in extensions if len(raw) > 0 { - filter.Extensions = raw + f.Extensions = raw } return nil } -func (filter Filter) Matches(event Event) bool { +func (f Filter) Matches(event Event) bool { // Check ID - if len(filter.IDs) > 0 { - if !matchesPrefix(event.ID, filter.IDs) { + if len(f.IDs) > 0 { + if !matchesPrefix(event.ID, f.IDs) { return false } } // Check Author - if len(filter.Authors) > 0 { - if !matchesPrefix(event.PubKey, filter.Authors) { + if len(f.Authors) > 0 { + if !matchesPrefix(event.PubKey, f.Authors) { return false } } // Check Kind - if len(filter.Kinds) > 0 { - if !matchesKinds(event.Kind, filter.Kinds) { + if len(f.Kinds) > 0 { + if !matchesKinds(event.Kind, f.Kinds) { return false } } // Check Timestamp - if !matchesTimeRange(event.CreatedAt, filter.Since, filter.Until) { + if !matchesTimeRange(event.CreatedAt, f.Since, f.Until) { return false } // Check Tags - if len(filter.Tags) > 0 { - if !matchesTags(event.Tags, filter.Tags) { + if len(f.Tags) > 0 { + if !matchesTags(event.Tags, f.Tags) { return false } }