153 lines
4.7 KiB
Go
153 lines
4.7 KiB
Go
package track4
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/explorer/backend/auth"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// Server handles Track 4 endpoints
|
|
type Server struct {
|
|
db *pgxpool.Pool
|
|
roleMgr *auth.RoleManager
|
|
chainID int
|
|
}
|
|
|
|
// NewServer creates a new Track 4 server
|
|
func NewServer(db *pgxpool.Pool, chainID int) *Server {
|
|
return &Server{
|
|
db: db,
|
|
roleMgr: auth.NewRoleManager(db),
|
|
chainID: chainID,
|
|
}
|
|
}
|
|
|
|
// HandleBridgeEvents handles GET /api/v1/track4/operator/bridge/events
|
|
func (s *Server) HandleBridgeEvents(w http.ResponseWriter, r *http.Request) {
|
|
// Get operator address from context
|
|
operatorAddr, _ := r.Context().Value("user_address").(string)
|
|
if operatorAddr == "" {
|
|
writeError(w, http.StatusUnauthorized, "unauthorized", "Operator address required")
|
|
return
|
|
}
|
|
|
|
// Check IP whitelist
|
|
ipAddr := r.RemoteAddr
|
|
if whitelisted, _ := s.roleMgr.IsIPWhitelisted(r.Context(), operatorAddr, ipAddr); !whitelisted {
|
|
writeError(w, http.StatusForbidden, "forbidden", "IP address not whitelisted")
|
|
return
|
|
}
|
|
|
|
// Log operator event
|
|
s.roleMgr.LogOperatorEvent(r.Context(), "bridge_events_read", &s.chainID, operatorAddr, "bridge/events", "read", map[string]interface{}{}, ipAddr, r.UserAgent())
|
|
|
|
// Return bridge events (simplified)
|
|
response := map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"events": []map[string]interface{}{},
|
|
"control_state": map[string]interface{}{
|
|
"paused": false,
|
|
"maintenance_mode": false,
|
|
"last_update": time.Now().UTC().Format(time.RFC3339),
|
|
},
|
|
},
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
// HandleValidators handles GET /api/v1/track4/operator/validators
|
|
func (s *Server) HandleValidators(w http.ResponseWriter, r *http.Request) {
|
|
operatorAddr, _ := r.Context().Value("user_address").(string)
|
|
ipAddr := r.RemoteAddr
|
|
|
|
if whitelisted, _ := s.roleMgr.IsIPWhitelisted(r.Context(), operatorAddr, ipAddr); !whitelisted {
|
|
writeError(w, http.StatusForbidden, "forbidden", "IP address not whitelisted")
|
|
return
|
|
}
|
|
|
|
s.roleMgr.LogOperatorEvent(r.Context(), "validators_read", &s.chainID, operatorAddr, "validators", "read", map[string]interface{}{}, ipAddr, r.UserAgent())
|
|
|
|
response := map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"validators": []map[string]interface{}{},
|
|
"total_validators": 0,
|
|
"active_validators": 0,
|
|
},
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
// HandleContracts handles GET /api/v1/track4/operator/contracts
|
|
func (s *Server) HandleContracts(w http.ResponseWriter, r *http.Request) {
|
|
operatorAddr, _ := r.Context().Value("user_address").(string)
|
|
ipAddr := r.RemoteAddr
|
|
|
|
if whitelisted, _ := s.roleMgr.IsIPWhitelisted(r.Context(), operatorAddr, ipAddr); !whitelisted {
|
|
writeError(w, http.StatusForbidden, "forbidden", "IP address not whitelisted")
|
|
return
|
|
}
|
|
|
|
s.roleMgr.LogOperatorEvent(r.Context(), "contracts_read", &s.chainID, operatorAddr, "contracts", "read", map[string]interface{}{}, ipAddr, r.UserAgent())
|
|
|
|
response := map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"contracts": []map[string]interface{}{},
|
|
},
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
// HandleProtocolState handles GET /api/v1/track4/operator/protocol-state
|
|
func (s *Server) HandleProtocolState(w http.ResponseWriter, r *http.Request) {
|
|
operatorAddr, _ := r.Context().Value("user_address").(string)
|
|
ipAddr := r.RemoteAddr
|
|
|
|
if whitelisted, _ := s.roleMgr.IsIPWhitelisted(r.Context(), operatorAddr, ipAddr); !whitelisted {
|
|
writeError(w, http.StatusForbidden, "forbidden", "IP address not whitelisted")
|
|
return
|
|
}
|
|
|
|
s.roleMgr.LogOperatorEvent(r.Context(), "protocol_state_read", &s.chainID, operatorAddr, "protocol/state", "read", map[string]interface{}{}, ipAddr, r.UserAgent())
|
|
|
|
response := map[string]interface{}{
|
|
"data": map[string]interface{}{
|
|
"protocol_version": "1.0.0",
|
|
"chain_id": s.chainID,
|
|
"config": map[string]interface{}{
|
|
"bridge_enabled": true,
|
|
"max_transfer_amount": "1000000000000000000000000",
|
|
},
|
|
"state": map[string]interface{}{
|
|
"total_locked": "50000000000000000000000000",
|
|
"total_bridged": "10000000000000000000000000",
|
|
"active_bridges": 2,
|
|
},
|
|
"last_updated": time.Now().UTC().Format(time.RFC3339),
|
|
},
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
func writeError(w http.ResponseWriter, statusCode int, code, message string) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(statusCode)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"error": map[string]interface{}{
|
|
"code": code,
|
|
"message": message,
|
|
},
|
|
})
|
|
}
|
|
|