Function bodies 1,118 total
NewAuthHandler function · go · L23-L29 (7 LOC)internal/handlers/auth.go
func NewAuthHandler(authService *auth.Service, validator *validators.Validator, logger *zap.Logger) *AuthHandler {
return &AuthHandler{
authService: authService,
validator: validator,
logger: logger,
}
}SendEmailCode method · go · L32-L67 (36 LOC)internal/handlers/auth.go
func (h *AuthHandler) SendEmailCode(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req models.EmailAuthRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Generate and send verification code
code, err := h.authService.SendEmailCode(ctx, req.Email)
if err != nil {
middleware.GetLogger(ctx).Error("failed to send email code",
zap.Error(err),
zap.String("email", req.Email),
)
response.InternalServerError(w, "Failed to send verification code")
return
}
// In development, we might want to return the code for testing
// In production, this should NOT be returned
response.Success(w, http.StatusOK, map[string]interface{}{
"message": "Verification code sent successfully",
VerifyEmailCode method · go · L70-L138 (69 LOC)internal/handlers/auth.go
func (h *AuthHandler) VerifyEmailCode(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req models.VerifyEmailCodeRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Verify code
if err := h.authService.VerifyCode(req.Email, req.Code); err != nil {
if err == auth.ErrInvalidCode {
response.BadRequest(w, "Invalid verification code", nil)
return
}
if err == auth.ErrCodeExpired {
response.BadRequest(w, "Verification code has expired", nil)
return
}
middleware.GetLogger(ctx).Error("failed to verify code",
zap.Error(err),
zap.String("email", req.Email),
)
response.InternalServerError(w, "Failed to verify code")
return
}
// Get user agent and IP address for seLogout method · go · L141-L163 (23 LOC)internal/handlers/auth.go
func (h *AuthHandler) Logout(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get token from Authorization header
token := extractTokenFromHeader(r)
if token == "" {
response.BadRequest(w, "Missing authorization token", nil)
return
}
// Revoke the token
if err := h.authService.RevokeSession(ctx, token); err != nil {
middleware.GetLogger(ctx).Error("failed to revoke session",
zap.Error(err),
)
response.InternalServerError(w, "Failed to logout")
return
}
response.Success(w, http.StatusOK, map[string]interface{}{
"message": "Logged out successfully",
})
}GetSessions method · go · L166-L214 (49 LOC)internal/handlers/auth.go
func (h *AuthHandler) GetSessions(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get user ID from context (set by auth middleware)
userID, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "User not authenticated")
return
}
userUUID, err := uuid.Parse(userID)
if err != nil {
response.BadRequest(w, "Invalid user ID", nil)
return
}
// Get current session token to mark it in the response
currentToken := extractTokenFromHeader(r)
var currentSessionID string
if currentToken != "" {
_, currentSession, err := h.authService.ValidateToken(ctx, currentToken)
if err == nil && currentSession != nil {
currentSessionID = currentSession.ID.String()
}
}
// Get all active sessions
sessions, err := h.authService.GetActiveSessions(ctx, userUUID)
if err != nil {
middleware.GetLogger(ctx).Error("failed to get sessions",
zap.Error(err),
zap.String("user_id", userID),
)
response.InternalServerError(w, "Failed to retrieve sesRevokeSession method · go · L217-L279 (63 LOC)internal/handlers/auth.go
func (h *AuthHandler) RevokeSession(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get session ID from URL
sessionIDStr := chi.URLParam(r, "id")
sessionID, err := uuid.Parse(sessionIDStr)
if err != nil {
response.BadRequest(w, "Invalid session ID", nil)
return
}
// Get user ID from context
userID, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "User not authenticated")
return
}
userUUID, err := uuid.Parse(userID)
if err != nil {
response.BadRequest(w, "Invalid user ID", nil)
return
}
// Verify the session belongs to the user (security check)
sessions, err := h.authService.GetActiveSessions(ctx, userUUID)
if err != nil {
middleware.GetLogger(ctx).Error("failed to get sessions",
zap.Error(err),
zap.String("user_id", userID),
)
response.InternalServerError(w, "Failed to revoke session")
return
}
found := false
for _, session := range sessions {
if session.ID == sessionID {
found = true
break
extractTokenFromHeader function · go · L282-L294 (13 LOC)internal/handlers/auth.go
func extractTokenFromHeader(r *http.Request) string {
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
return ""
}
// Bearer token format: "Bearer <token>"
if len(authHeader) > 7 && authHeader[:7] == "Bearer " {
return authHeader[7:]
}
return ""
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
extractIPAddress function · go · L297-L309 (13 LOC)internal/handlers/auth.go
func extractIPAddress(r *http.Request) string {
ipAddress := r.RemoteAddr
// Strip port from IP address
if colonIdx := len(ipAddress) - 1; colonIdx > 0 {
for i := colonIdx; i >= 0; i-- {
if ipAddress[i] == ':' {
ipAddress = ipAddress[:i]
break
}
}
}
return ipAddress
}GetSIWENonce method · go · L315-L345 (31 LOC)internal/handlers/auth.go
func (h *AuthHandler) GetSIWENonce(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req models.SIWENonceRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Generate nonce for this wallet address
nonce, err := h.authService.GenerateSIWENonce(req.Address)
if err != nil {
middleware.GetLogger(ctx).Error("failed to generate SIWE nonce",
zap.Error(err),
zap.String("address", req.Address),
)
response.InternalServerError(w, "Failed to generate nonce")
return
}
response.Success(w, http.StatusOK, models.SIWENonceResponse{
Nonce: nonce,
})
}VerifySIWE method · go · L349-L403 (55 LOC)internal/handlers/auth.go
func (h *AuthHandler) VerifySIWE(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req models.SIWEVerifyRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Get user agent and IP address for session tracking
userAgent := r.Header.Get("User-Agent")
ipAddress := extractIPAddress(r)
// Complete SIWE login flow
loginResponse, err := h.authService.CompleteSIWELogin(ctx, req.Message, req.Signature, userAgent, ipAddress)
if err != nil {
// Handle specific SIWE errors
switch err {
case auth.ErrInvalidNonce:
response.BadRequest(w, "Invalid or expired nonce", nil)
return
case auth.ErrInvalidSignature:
response.BadRequest(w, "Invalid signature", nil)
return
case auth.ErrInvaLinkWallet method · go · L407-L470 (64 LOC)internal/handlers/auth.go
func (h *AuthHandler) LinkWallet(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get user ID from context (set by auth middleware)
userID, ok := ctx.Value("userID").(string)
if !ok {
response.Unauthorized(w, "User not authenticated")
return
}
userUUID, err := uuid.Parse(userID)
if err != nil {
response.BadRequest(w, "Invalid user ID", nil)
return
}
var req models.WalletLinkRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Link wallet to user
walletAddress, err := h.authService.LinkWalletToUser(ctx, userUUID, req.Message, req.Signature)
if err != nil {
// Handle specific errors
switch err {
case auth.ErrInvalidNonce:
response.BadRequest(w, "Invalid or expired nNewChainHandler function · go · L31-L39 (9 LOC)internal/handlers/chains.go
func NewChainHandler(chainService *chainsvc.Service, virtualPoolService *virtualpool.Service, rpcClient *canopy.Client, validator *validators.Validator, logger *zap.Logger) *ChainHandler {
return &ChainHandler{
chainService: chainService,
virtualPoolService: virtualPoolService,
rpcClient: rpcClient,
validator: validator,
logger: logger,
}
}GetChains method · go · L42-L102 (61 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetChains(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Parse query parameters
var params models.ChainsQueryParams
if err := h.parseQueryParams(r, ¶ms); err != nil {
response.BadRequest(w, "Invalid query parameters", err.Error())
return
}
// Validate query parameters
if err := h.validator.Validate(¶ms); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Set defaults
if params.Page == 0 {
params.Page = 1
}
if params.Limit == 0 {
params.Limit = 20
}
// Parse include relations
include := []string{}
if params.Include != "" {
parts := strings.Split(params.Include, ",")
for _, part := range parts {
trimmed := strings.TrimSpace(part)
if trimmed != "" {
include = append(include, trimmed)
}
}
}
// Get chains
chains, pagination, err := h.chainService.GetChains(
ctx,
params.Status,
params.CreatedBy,
params.TemplateCGetChain method · go · L105-L126 (22 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetChain(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainID := chi.URLParam(r, "id")
include := r.URL.Query().Get("include")
chain, err := h.chainService.GetChainByID(ctx, chainID, include)
if err != nil {
if err == chainsvc.ErrChainNotFound {
response.NotFound(w, "Chain not found")
return
}
middleware.GetLogger(ctx).Error("failed to retrieve chain",
zap.Error(err),
zap.String("chain_id", chainID),
zap.String("include", include),
)
response.InternalServerError(w, "Failed to retrieve chain")
return
}
response.Success(w, http.StatusOK, chain)
}CreateChain method · go · L129-L167 (39 LOC)internal/handlers/chains.go
func (h *ChainHandler) CreateChain(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
userID := h.getUserIDFromContext(ctx)
var req models.CreateChainRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Create chain
chain, err := h.chainService.CreateChain(ctx, &req, userID)
if err != nil {
if err == chainsvc.ErrChainAlreadyExists {
middleware.GetLogger(ctx).Warn("create chain failed - chain already exists",
zap.Error(err),
zap.String("user_id", userID),
zap.String("chain_name", req.ChainName),
)
response.Conflict(w, "Chain name already exists", nil)
return
}
middleware.GetLogger(ctx).Error("failed to create chain",
zap.Error(err),
zap.String("user_id", userSame scanner, your repo: https://repobility.com — Repobility
DeleteChain method · go · L170-L189 (20 LOC)internal/handlers/chains.go
func (h *ChainHandler) DeleteChain(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
userID := h.getUserIDFromContext(ctx)
err = h.chainService.DeleteChain(ctx, chainID, userID)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, map[string]string{
"message": "Chain deleted successfully",
})
}UpdateChainDescription method · go · L192-L223 (32 LOC)internal/handlers/chains.go
func (h *ChainHandler) UpdateChainDescription(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
userID := h.getUserIDFromContext(ctx)
var req models.UpdateChainDescriptionRequest
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Update chain description
chain, err := h.chainService.UpdateChainDescription(ctx, chainID, userID, &req)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, chain)
}GetRepository method · go · L226-L242 (17 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetRepository(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
repo, err := h.chainService.GetRepositoryByChainID(ctx, chainID)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, repo)
}CreateRepository method · go · L245-L276 (32 LOC)internal/handlers/chains.go
func (h *ChainHandler) CreateRepository(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
userID := h.getUserIDFromContext(ctx)
var req models.CreateChainRepositoryRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Create repository
repo, err := h.chainService.CreateRepositoryByChainID(ctx, chainID, userID, &req)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusCreated, repo)
}UpdateRepository method · go · L279-L310 (32 LOC)internal/handlers/chains.go
func (h *ChainHandler) UpdateRepository(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
userID := h.getUserIDFromContext(ctx)
var req models.UpdateChainRepositoryRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Update repository
repo, err := h.chainService.UpdateRepositoryByChainID(ctx, chainID, userID, &req)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, repo)
}GetTransactions method · go · L313-L359 (47 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetTransactions(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
// Parse query parameters
var params models.TransactionsQueryParams
if err := h.parseQueryParams(r, ¶ms); err != nil {
response.BadRequest(w, "Invalid query parameters", err.Error())
return
}
// Validate query parameters
if err := h.validator.Validate(¶ms); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Set defaults
if params.Page == 0 {
params.Page = 1
}
if params.Limit == 0 {
params.Limit = 20
}
// Get transactions
transactions, pagination, err := h.chainService.GetTransactions(
ctx,
chainID,
params.UserID,
params.TransactionType,
params.Page,
params.Limit,
)
if err != nil {GetPriceHistory method · go · L362-L386 (25 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetPriceHistory(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
// Parse query parameters
var params models.PriceHistoryQueryParams
if err := h.parsePriceHistoryParams(r, ¶ms); err != nil {
response.BadRequest(w, "Invalid query parameters", err.Error())
return
}
// Get price history from service
candles, err := h.chainService.GetPriceHistory(ctx, chainID, params.StartTime, params.EndTime)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, candles)
}GetMarketCapHistory method · go · L389-L413 (25 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetMarketCapHistory(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
// Parse query parameters (reuse the same parser as price history)
var params models.MarketCapHistoryQueryParams
if err := h.parseMarketCapHistoryParams(r, ¶ms); err != nil {
response.BadRequest(w, "Invalid query parameters", err.Error())
return
}
// Get market cap history from service
candles, err := h.chainService.GetMarketCapHistory(ctx, chainID, params.StartTime, params.EndTime)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, candles)
}Source: Repobility analyzer · https://repobility.com
GetAssets method · go · L416-L432 (17 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetAssets(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
assets, err := h.chainService.GetAssets(ctx, chainID)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, assets)
}CreateAsset method · go · L435-L466 (32 LOC)internal/handlers/chains.go
func (h *ChainHandler) CreateAsset(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
userID := h.getUserIDFromContext(ctx)
var req models.CreateChainAssetRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Create asset
asset, err := h.chainService.CreateAsset(ctx, chainID, userID, &req)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusCreated, asset)
}UpdateAsset method · go · L469-L501 (33 LOC)internal/handlers/chains.go
func (h *ChainHandler) UpdateAsset(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
assetID := chi.URLParam(r, "asset_id")
userID := h.getUserIDFromContext(ctx)
var req models.UpdateChainAssetRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Update asset
asset, err := h.chainService.UpdateAsset(ctx, chainID, assetID, userID, &req)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, asset)
}GetSocials method · go · L504-L520 (17 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetSocials(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
socials, err := h.chainService.GetSocials(ctx, chainID)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, socials)
}CreateSocial method · go · L523-L554 (32 LOC)internal/handlers/chains.go
func (h *ChainHandler) CreateSocial(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
userID := h.getUserIDFromContext(ctx)
var req models.CreateChainSocialLinkRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Create social link
social, err := h.chainService.CreateSocial(ctx, chainID, userID, &req)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusCreated, social)
}UpdateSocial method · go · L557-L589 (33 LOC)internal/handlers/chains.go
func (h *ChainHandler) UpdateSocial(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
socialID := chi.URLParam(r, "social_id")
userID := h.getUserIDFromContext(ctx)
var req models.UpdateChainSocialLinkRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
response.BadRequest(w, "Invalid JSON payload", err.Error())
return
}
// Validate request
if err := h.validator.Validate(&req); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Update social link
social, err := h.chainService.UpdateSocial(ctx, chainID, socialID, userID, &req)
if err != nil {
h.handleServiceError(w, err)
return
}
response.Success(w, http.StatusOK, social)
}getUserIDFromContext method · go · L592-L599 (8 LOC)internal/handlers/chains.go
func (h *ChainHandler) getUserIDFromContext(ctx context.Context) string {
// This would be set by the auth middleware
userID, ok := ctx.Value("userID").(string)
if !ok {
return ""
}
return userID
}parseQueryParams method · go · L601-L659 (59 LOC)internal/handlers/chains.go
func (h *ChainHandler) parseQueryParams(r *http.Request, params interface{}) error {
// This would typically use a library like gorilla/schema or similar
// For now, we'll parse manually based on the request type
switch p := params.(type) {
case *models.ChainsQueryParams:
p.Status = r.URL.Query().Get("status")
p.CreatedBy = r.URL.Query().Get("created_by")
p.TemplateID = r.URL.Query().Get("template_id")
p.TemplateCategory = r.URL.Query().Get("template_category")
p.TemplateSupportedLanguage = r.URL.Query().Get("template_supported_language")
p.Include = r.URL.Query().Get("include")
if pageStr := r.URL.Query().Get("page"); pageStr != "" {
if page, err := strconv.Atoi(pageStr); err == nil {
p.Page = page
}
}
if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
if limit, err := strconv.Atoi(limitStr); err == nil {
p.Limit = limit
}
}
case *models.TransactionsQueryParams:
p.UserID = r.URL.Query().Get("user_id")
p.TransactionType = r.URepobility — the code-quality scanner for AI-generated software · https://repobility.com
parsePriceHistoryParams method · go · L661-L681 (21 LOC)internal/handlers/chains.go
func (h *ChainHandler) parsePriceHistoryParams(r *http.Request, params *models.PriceHistoryQueryParams) error {
// Parse start_time if provided
if startTimeStr := r.URL.Query().Get("start_time"); startTimeStr != "" {
startTime, err := parseTime(startTimeStr)
if err != nil {
return err
}
params.StartTime = &startTime
}
// Parse end_time if provided
if endTimeStr := r.URL.Query().Get("end_time"); endTimeStr != "" {
endTime, err := parseTime(endTimeStr)
if err != nil {
return err
}
params.EndTime = &endTime
}
return nil
}parseMarketCapHistoryParams method · go · L683-L703 (21 LOC)internal/handlers/chains.go
func (h *ChainHandler) parseMarketCapHistoryParams(r *http.Request, params *models.MarketCapHistoryQueryParams) error {
// Parse start_time if provided
if startTimeStr := r.URL.Query().Get("start_time"); startTimeStr != "" {
startTime, err := parseTime(startTimeStr)
if err != nil {
return err
}
params.StartTime = &startTime
}
// Parse end_time if provided
if endTimeStr := r.URL.Query().Get("end_time"); endTimeStr != "" {
endTime, err := parseTime(endTimeStr)
if err != nil {
return err
}
params.EndTime = &endTime
}
return nil
}parseTime function · go · L706-L720 (15 LOC)internal/handlers/chains.go
func parseTime(timeStr string) (time.Time, error) {
// Try RFC3339 format first (standard format)
t, err := time.Parse(time.RFC3339, timeStr)
if err == nil {
return t, nil
}
// Try RFC3339Nano as fallback
t, err = time.Parse(time.RFC3339Nano, timeStr)
if err == nil {
return t, nil
}
return time.Time{}, fmt.Errorf("invalid time format, expected RFC3339/ISO 8601 (e.g., 2006-01-02T15:04:05Z)")
}GetHolders method · go · L723-L781 (59 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetHolders(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
// Parse query parameters
var params models.HoldersQueryParams
if err := h.parseQueryParams(r, ¶ms); err != nil {
response.BadRequest(w, "Invalid query parameters", err.Error())
return
}
// Validate query parameters
if err := h.validator.Validate(¶ms); err != nil {
validationErrors := h.validator.FormatErrors(err)
response.ValidationError(w, validationErrors)
return
}
// Set defaults
if params.Page == 0 {
params.Page = 1
}
if params.Limit == 0 {
params.Limit = 20
}
if params.SortBy == "" {
params.SortBy = "balance"
}
if params.Order == "" {
params.Order = "desc"
}
// Get holders
holders, pagination, err := h.virtualPoolService.GetHolders(
ctx,
chainID,
pGetChainAccolades method · go · L784-L804 (21 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetChainAccolades(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
accolades, err := h.chainService.GetChainAccolades(ctx, chainID)
if err != nil {
middleware.GetLogger(ctx).Error("failed to retrieve accolades",
zap.Error(err),
zap.Uint64("chain_id", chainID),
)
response.InternalServerError(w, "Failed to retrieve accolades")
return
}
response.Success(w, http.StatusOK, accolades)
}ValidateChainAvailability method · go · L807-L835 (29 LOC)internal/handlers/chains.go
func (h *ChainHandler) ValidateChainAvailability(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Parse query parameters
name := r.URL.Query().Get("name")
symbol := r.URL.Query().Get("symbol")
tokenName := r.URL.Query().Get("token_name")
// At least one parameter must be provided
if name == "" && symbol == "" && tokenName == "" {
response.BadRequest(w, "At least one parameter (name, symbol, or token_name) must be provided", "")
return
}
// Check availability
result, err := h.chainService.CheckAvailability(ctx, name, symbol, tokenName)
if err != nil {
middleware.GetLogger(ctx).Error("failed to check availability",
zap.Error(err),
zap.String("name", name),
zap.String("symbol", symbol),
zap.String("token_name", tokenName),
)
response.InternalServerError(w, "Failed to check availability")
return
}
response.Success(w, http.StatusOK, result)
}GetChainStatistics method · go · L838-L859 (22 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetChainStatistics(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
// Get comprehensive statistics from indexer
stats, err := h.chainService.GetChainStatistics(ctx, chainID)
if err != nil {
middleware.GetLogger(ctx).Error("failed to retrieve chain statistics",
zap.Error(err),
zap.Uint64("chain_id", chainID),
)
response.InternalServerError(w, "Failed to retrieve chain statistics")
return
}
response.Success(w, http.StatusOK, stats)
}GetChainBondingCurve method · go · L862-L883 (22 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetChainBondingCurve(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
chainIDStr := chi.URLParam(r, "id")
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
return
}
// Get bonding curve data (works for both virtual and graduated chains)
data, err := h.chainService.GetBondingCurveData(ctx, chainID)
if err != nil {
middleware.GetLogger(ctx).Error("failed to retrieve bonding curve data",
zap.Error(err),
zap.Uint64("chain_id", chainID),
)
response.InternalServerError(w, "Failed to retrieve bonding curve data")
return
}
response.Success(w, http.StatusOK, data)
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
GetChainHeight method · go · L886-L931 (46 LOC)internal/handlers/chains.go
func (h *ChainHandler) GetChainHeight(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get chain ID from URL
chainID := chi.URLParam(r, "id")
// Verify chain exists
_, err := h.chainService.GetChainByID(ctx, chainID, "")
if err != nil {
if err == chainsvc.ErrChainNotFound {
response.NotFound(w, "Chain not found")
return
}
middleware.GetLogger(ctx).Error("failed to retrieve chain",
zap.Error(err),
zap.String("chain_id", chainID),
)
response.InternalServerError(w, "Failed to retrieve chain")
return
}
// Query the Canopy node for current block height
heightPtr, libErr := h.rpcClient.Height()
if libErr != nil {
middleware.GetLogger(ctx).Error("failed to query block height from Canopy node",
zap.Error(libErr),
zap.String("chain_id", chainID),
)
response.InternalServerError(w, "Failed to query block height")
return
}
if heightPtr == nil {
middleware.GetLogger(ctx).Error("received nil height from Canopy node",
zap.StrinhandleServiceError method · go · L933-L957 (25 LOC)internal/handlers/chains.go
func (h *ChainHandler) handleServiceError(w http.ResponseWriter, err error) {
switch err {
case chainsvc.ErrChainNotFound:
response.NotFound(w, "Chain not found")
case chainsvc.ErrChainAlreadyExists:
response.Conflict(w, "Chain already exists", nil)
case chainsvc.ErrChainNotInDraftStatus:
response.UnprocessableEntity(w, "Chain is not in draft status", nil)
case chainsvc.ErrUnauthorized:
response.Forbidden(w, "Access denied")
case chainsvc.ErrRepositoryNotFound:
response.NotFound(w, "Repository not found")
case chainsvc.ErrRepositoryAlreadyExists:
response.Conflict(w, "Repository already exists for this chain", nil)
case chainsvc.ErrAssetNotFound:
response.NotFound(w, "Asset not found")
case chainsvc.ErrSocialLinkNotFound:
response.NotFound(w, "Social link not found")
case chainsvc.ErrSocialLinkAlreadyExists:
response.Conflict(w, "Social link for this platform already exists for this chain", nil)
default:
h.logger.Error("unhandled service error", zap.ErrorNewExplorerHandler function · go · L57-L69 (13 LOC)internal/handlers/explorer.go
func NewExplorerHandler(
indexerRepo ExplorerHandlerIndexer,
explorerSvc *explorer.Service,
validator *validators.Validator,
logger *zap.Logger,
) *ExplorerHandler {
return &ExplorerHandler{
indexerRepo: indexerRepo,
explorerSvc: explorerSvc,
validator: validator,
logger: logger,
}
}GetBlocks method · go · L73-L165 (93 LOC)internal/handlers/explorer.go
func (h *ExplorerHandler) GetBlocks(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := middleware.GetLogger(ctx)
// Parse query parameters
req, err := h.parseBlocksRequest(r)
if err != nil {
response.BadRequest(w, "Invalid query parameters", err.Error())
return
}
if req == nil {
logger.Error("parseBlocksRequest returned nil request")
response.InternalServerError(w, "Failed to parse request")
return
}
// Default to root chain if no chain specified
chainID := uint64(1)
if req.ChainID != nil {
chainID = *req.ChainID
}
// Set default limit
if req.Limit == 0 {
req.Limit = 20
}
if req.Limit > 100 {
req.Limit = 100
}
// Default sort to descending (most recent first)
if req.Sort == "" {
req.Sort = "desc"
}
// Fetch blocks from indexer
blocks, pagination, err := h.indexerRepo.ListBlocks(ctx, chainID, req.Cursor, req.Limit, req.Sort)
if err != nil {
logger.Error("failed to list blocks",
zap.Error(err),
zap.Uint64("chain_idGetBlock method · go · L169-L220 (52 LOC)internal/handlers/explorer.go
func (h *ExplorerHandler) GetBlock(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := middleware.GetLogger(ctx)
// Parse height from URL
heightStr := chi.URLParam(r, "height")
height, err := strconv.ParseUint(heightStr, 10, 64)
if err != nil {
response.BadRequest(w, "Invalid block height", err.Error())
return
}
// Parse chain_id from query (default to root chain)
chainID := uint64(1)
if chainIDStr := r.URL.Query().Get("chain_id"); chainIDStr != "" {
parsedChainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.BadRequest(w, "Invalid chain_id", err.Error())
return
}
chainID = parsedChainID
}
// Fetch block from indexer
block, err := h.indexerRepo.GetBlock(ctx, chainID, height)
if err != nil {
logger.Error("failed to get block",
zap.Error(err),
zap.Uint64("chain_id", chainID),
zap.Uint64("height", height),
)
response.NotFound(w, "Block not found")
return
}
// Fetch block summary for transactGetTransactions method · go · L224-L298 (75 LOC)internal/handlers/explorer.go
func (h *ExplorerHandler) GetTransactions(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := middleware.GetLogger(ctx)
// Parse query parameters
req, err := h.parseTransactionsRequest(r)
if err != nil {
response.BadRequest(w, "Invalid query parameters", err.Error())
return
}
if req == nil {
logger.Error("parseTransactionsRequest returned nil request")
response.InternalServerError(w, "Failed to parse request")
return
}
// Default to root chain if no chain specified
chainID := uint64(1)
if req.ChainID != nil {
chainID = *req.ChainID
}
// Set default limit
if req.Limit == 0 {
req.Limit = 20
}
if req.Limit > 100 {
req.Limit = 100
}
// Default sort to descending (most recent first)
if req.Sort == "" {
req.Sort = "desc"
}
// Fetch transactions from indexer
txs, pagination, err := h.indexerRepo.ListTransactions(ctx, chainID, req.Cursor, req.Limit, req.Sort, req.MessageType)
if err != nil {
logger.Error("failed to list transacGetTransaction method · go · L302-L340 (39 LOC)internal/handlers/explorer.go
func (h *ExplorerHandler) GetTransaction(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := middleware.GetLogger(ctx)
// Parse hash from URL
txHash := chi.URLParam(r, "hash")
if txHash == "" {
response.BadRequest(w, "Transaction hash is required", "")
return
}
// Parse chain_id from query (default to root chain)
chainID := uint64(1)
if chainIDStr := r.URL.Query().Get("chain_id"); chainIDStr != "" {
parsedChainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
response.BadRequest(w, "Invalid chain_id", err.Error())
return
}
chainID = parsedChainID
}
// Fetch transaction from indexer
tx, err := h.indexerRepo.GetTransaction(ctx, chainID, txHash)
if err != nil {
logger.Error("failed to get transaction",
zap.Error(err),
zap.Uint64("chain_id", chainID),
zap.String("tx_hash", txHash),
)
response.NotFound(w, "Transaction not found")
return
}
// Transform to DTO with full message JSON
txDTO := h.transactionGetSwaps method · go · L344-L442 (99 LOC)internal/handlers/explorer.go
func (h *ExplorerHandler) GetSwaps(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := middleware.GetLogger(ctx)
// Parse query parameters
req, err := h.parseSwapsRequest(r)
if err != nil {
response.BadRequest(w, "Invalid query parameters", err.Error())
return
}
if req == nil {
logger.Error("parseSwapsRequest returned nil request")
response.InternalServerError(w, "Failed to parse request")
return
}
// Default to root chain if no chain specified
chainID := uint64(1)
if req.ChainID != nil {
chainID = *req.ChainID
}
// Set default limit
if req.Limit == 0 {
req.Limit = 20
}
if req.Limit > 100 {
req.Limit = 100
}
// Default sort to descending (most recent first)
if req.Sort == "" {
req.Sort = "desc"
}
// Fetch transactions filtered by swap message types
// We'll query for dexLimitOrder transactions which represent swaps
messageType := "dexLimitOrder"
txs, pagination, err := h.indexerRepo.ListTransactions(ctx, chainID, req.CurSame scanner, your repo: https://repobility.com — Repobility
Search method · go · L446-L548 (103 LOC)internal/handlers/explorer.go
func (h *ExplorerHandler) Search(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := middleware.GetLogger(ctx)
// Parse query parameters
req, err := h.parseSearchRequest(r)
if err != nil {
response.BadRequest(w, "Invalid search query", err.Error())
return
}
if req == nil {
logger.Error("parseSearchRequest returned nil request")
response.InternalServerError(w, "Failed to parse request")
return
}
// Validate request
if err := h.validator.Validate(req); err != nil {
response.BadRequest(w, "Invalid search query", err.Error())
return
}
// Default to root chain if no chain specified
chainID := uint64(1)
if req.ChainID != nil {
chainID = *req.ChainID
}
// Set default limit
if req.Limit == 0 {
req.Limit = 10
}
if req.Limit > 50 {
req.Limit = 50
}
// Detect query type and search accordingly
results := []models.SearchResultDTO{}
// Check if query is a block height (numeric)
if height, err := strconv.ParseUint(req.Query, 10, 64)parseBlocksRequest method · go · L552-L585 (34 LOC)internal/handlers/explorer.go
func (h *ExplorerHandler) parseBlocksRequest(r *http.Request) (*models.BlocksRequest, error) {
req := &models.BlocksRequest{}
query := r.URL.Query()
if chainIDStr := query.Get("chain_id"); chainIDStr != "" {
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
return nil, err
}
req.ChainID = &chainID
}
if limitStr := query.Get("limit"); limitStr != "" {
limit, err := strconv.Atoi(limitStr)
if err != nil {
return nil, err
}
req.Limit = limit
}
if cursorStr := query.Get("cursor"); cursorStr != "" {
cursor, err := strconv.ParseUint(cursorStr, 10, 64)
if err != nil {
return nil, err
}
req.Cursor = &cursor
}
if sort := query.Get("sort"); sort != "" {
req.Sort = sort
}
return req, nil
}parseTransactionsRequest method · go · L587-L632 (46 LOC)internal/handlers/explorer.go
func (h *ExplorerHandler) parseTransactionsRequest(r *http.Request) (*models.TransactionsRequest, error) {
req := &models.TransactionsRequest{}
query := r.URL.Query()
if chainIDStr := query.Get("chain_id"); chainIDStr != "" {
chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
if err != nil {
return nil, err
}
req.ChainID = &chainID
}
if messageType := query.Get("message_type"); messageType != "" {
req.MessageType = &messageType
}
if signer := query.Get("signer"); signer != "" {
req.Signer = &signer
}
if counterparty := query.Get("counterparty"); counterparty != "" {
req.Counterparty = &counterparty
}
if limitStr := query.Get("limit"); limitStr != "" {
limit, err := strconv.Atoi(limitStr)
if err != nil {
return nil, err
}
req.Limit = limit
}
if cursorStr := query.Get("cursor"); cursorStr != "" {
cursor, err := strconv.ParseUint(cursorStr, 10, 64)
if err != nil {
return nil, err
}
req.Cursor = &cursor
}
if sort := query.Get(