diff --git a/cmd/api/handler/search.go b/cmd/api/handler/search.go index ef9d69a4..9a345f9c 100644 --- a/cmd/api/handler/search.go +++ b/cmd/api/handler/search.go @@ -80,6 +80,8 @@ func (handler SearchHandler) Search(c echo.Context) error { switch { case isAddress(req.Search): response, err = handler.searchAddress(c.Request().Context(), req.Search) + case isValoperAddress(req.Search): + response, err = handler.searchValoperAddress(c.Request().Context(), req.Search) case hashRegexp.MatchString(req.Search): response, err = handler.searchHash(c.Request().Context(), req.Search) case namespaceRegexp.MatchString(req.Search): @@ -116,6 +118,32 @@ func (handler SearchHandler) searchAddress(ctx context.Context, search string) ( return []responses.SearchItem{result}, nil } +func (handler SearchHandler) searchValoperAddress(ctx context.Context, search string) ([]responses.SearchItem, error) { + _, hash, err := types.Address(search).Decode() + if err != nil { + return nil, err + } + + address, err := handler.address.ByHash(ctx, hash) + if err != nil { + return nil, err + } + validator, err := handler.validator.ByAddress(ctx, search) + if err != nil { + return nil, err + } + + return []responses.SearchItem{ + { + Type: "validator", + Result: responses.NewValidator(validator), + }, { + Type: "address", + Result: responses.NewAddress(address), + }, + }, nil +} + func (handler SearchHandler) searchHash(ctx context.Context, search string) ([]responses.SearchItem, error) { search = strings.TrimPrefix(search, "0x") data, err := hex.DecodeString(search) diff --git a/cmd/api/handler/validators.go b/cmd/api/handler/validators.go index a2654c05..4498628c 100644 --- a/cmd/api/handler/validators.go +++ b/cmd/api/handler/validators.go @@ -43,17 +43,18 @@ func (v *CelestiaApiValidator) Validate(i interface{}) error { } func isAddress(address string) bool { - switch len(address) { - case 47: - return validateAddress(address, pkgTypes.AddressPrefixCelestia) - case 54: - return validateAddress(address, pkgTypes.AddressPrefixValoper) - default: + return validateAddress(address, pkgTypes.AddressPrefixCelestia, 47) +} + +func isValoperAddress(address string) bool { + return validateAddress(address, pkgTypes.AddressPrefixValoper, 54) +} + +func validateAddress(address string, wantPrefix string, length int) bool { + if len(address) != length { return false } -} -func validateAddress(address string, wantPrefix string) bool { prefix, _, err := bech32.DecodeAndConvert(address) if err != nil { return false @@ -64,7 +65,7 @@ func validateAddress(address string, wantPrefix string) bool { func addressValidator() validator.Func { return func(fl validator.FieldLevel) bool { - return isAddress(fl.Field().String()) + return isAddress(fl.Field().String()) || isValoperAddress(fl.Field().String()) } } diff --git a/cmd/api/handler/validators_test.go b/cmd/api/handler/validators_test.go index fbe97fe3..b3f08be4 100644 --- a/cmd/api/handler/validators_test.go +++ b/cmd/api/handler/validators_test.go @@ -22,7 +22,7 @@ func Test_isAddress(t *testing.T) { }, { name: "test 2", address: "celestiavaloper1qycj0ymu9fqvwgyw4xz93p3n4a83jjk7sm2wzh", - want: true, + want: false, }, { name: "test 3", address: "invalid", @@ -40,3 +40,35 @@ func Test_isAddress(t *testing.T) { }) } } + +func Test_isValoperAddress(t *testing.T) { + tests := []struct { + name string + address string + want bool + }{ + { + name: "test 1", + address: "celestia12y6fchaufs4tmn8e8wlk3rtrrftpqp6vr228a7", + want: false, + }, { + name: "test 2", + address: "celestiavaloper1qycj0ymu9fqvwgyw4xz93p3n4a83jjk7sm2wzh", + want: true, + }, { + name: "test 3", + address: "invalid", + want: false, + }, { + name: "test 4", + address: "celestiavaloper111111111111111111111111111111111111111", + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := isValoperAddress(tt.address) + require.Equal(t, tt.want, got, tt.name) + }) + } +}