2026-02-10 11:32:49 -08:00
|
|
|
package rest
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// handleSearch handles GET /api/v1/search
|
|
|
|
|
func (s *Server) handleSearch(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
if r.Method != http.MethodGet {
|
2026-02-16 03:09:53 -08:00
|
|
|
writeMethodNotAllowed(w)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if !s.requireDB(w) {
|
2026-02-10 11:32:49 -08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query := r.URL.Query().Get("q")
|
|
|
|
|
if query == "" {
|
|
|
|
|
writeValidationError(w, fmt.Errorf("search query required"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate and determine search type
|
|
|
|
|
searchType, value, err := validateSearchQuery(query)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeValidationError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Route to appropriate handler based on search type
|
|
|
|
|
switch searchType {
|
|
|
|
|
case "block":
|
|
|
|
|
blockNumber, err := validateBlockNumber(value)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeValidationError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.handleGetBlockByNumber(w, r, blockNumber)
|
|
|
|
|
case "transaction":
|
|
|
|
|
if !isValidHash(value) {
|
|
|
|
|
writeValidationError(w, ErrInvalidHash)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.handleGetTransactionByHash(w, r, value)
|
|
|
|
|
case "address":
|
|
|
|
|
if !isValidAddress(value) {
|
|
|
|
|
writeValidationError(w, ErrInvalidAddress)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
r.URL.RawQuery = "address=" + value
|
|
|
|
|
s.handleGetAddress(w, r)
|
|
|
|
|
default:
|
|
|
|
|
writeValidationError(w, fmt.Errorf("unsupported search type"))
|
|
|
|
|
}
|
|
|
|
|
}
|