← back to kyawgyi13122-ship-it__launchpad

Function bodies 1,118 total

All specs Real LLM only Function bodies
parseSwapsRequest method · go · L634-L671 (38 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) parseSwapsRequest(r *http.Request) (*models.SwapsRequest, error) {
	req := &models.SwapsRequest{}
	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 address := query.Get("address"); address != "" {
		req.Address = &address
	}

	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
}
parseSearchRequest method · go · L673-L696 (24 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) parseSearchRequest(r *http.Request) (*models.SearchRequest, error) {
	req := &models.SearchRequest{}
	query := r.URL.Query()

	req.Query = strings.TrimSpace(query.Get("q"))

	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
	}

	return req, nil
}
blockSummaryToDTO method · go · L700-L725 (26 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) blockSummaryToDTO(chainID uint64, chainName string, block *indexer.Block, summary *indexer.BlockSummary) models.BlockSummaryDTO {
	var proposerAddr *string
	if block.ProposerAddress != "" {
		proposerAddr = &block.ProposerAddress
	}

	numTxs := 0
	numEvents := 0
	if summary != nil {
		numTxs = int(summary.NumTxs)
		numEvents = int(summary.NumEvents)
	}

	return models.BlockSummaryDTO{
		ChainID:         chainID,
		ChainName:       chainName,
		Height:          block.Height,
		Hash:            block.Hash,
		Timestamp:       block.Time,
		ProposerAddress: proposerAddr,
		NumTxs:          numTxs,
		NumEvents:       numEvents,
		TotalFees:       0,   // Not tracked in BlockSummary
		BlockTime:       5.0, // Placeholder: 5 seconds average block time
	}
}
blockDetailsToDTO method · go · L727-L786 (60 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) blockDetailsToDTO(chainID uint64, block *indexer.Block, summary *indexer.BlockSummary) models.BlockDetailsDTO {
	var proposerAddr *string
	if block.ProposerAddress != "" {
		proposerAddr = &block.ProposerAddress
	}

	return models.BlockDetailsDTO{
		ChainID:         chainID,
		Height:          block.Height,
		Hash:            block.Hash,
		Timestamp:       block.Time,
		ProposerAddress: proposerAddr,

		// Transaction counters
		NumTxsSend:              int(summary.NumTxsSend),
		NumTxsStake:             int(summary.NumTxsStake),
		NumTxsEditStake:         int(summary.NumTxsEditStake),
		NumTxsUnstake:           int(summary.NumTxsUnstake),
		NumTxsPause:             int(summary.NumTxsPause),
		NumTxsUnpause:           int(summary.NumTxsUnpause),
		NumTxsChangeParameter:   int(summary.NumTxsChangeParameter),
		NumTxsDAOTransfer:       int(summary.NumTxsDaoTransfer),
		NumTxsCertificateResult: int(summary.NumTxsCertificateResults),
		NumTxsSubsidy:           int
transactionToDTO method · go · L788-L830 (43 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) transactionToDTO(chainID uint64, tx *indexer.Transaction, includeFullMessage bool) models.TransactionDTO {
	dto := models.TransactionDTO{
		ChainID:          chainID,
		Height:           tx.Height,
		TxHash:           tx.TxHash,
		Timestamp:        tx.HeightTime,
		MessageType:      tx.MessageType,
		Signer:           tx.Signer,
		Counterparty:     tx.Counterparty,
		Amount:           tx.Amount,
		Fee:              tx.Fee,
		Memo:             nil, // Memo field not in indexer.Transaction
		ValidatorAddress: tx.ValidatorAddress,
		DestChainID:      tx.ChainID, // ChainID in Transaction is the destination chain
		OrderID:          tx.OrderID,
		PoolID:           nil, // PoolID not in indexer.Transaction
		SellAssetChainID: nil, // Not separate fields in indexer
		BuyAssetChainID:  nil, // Not separate fields in indexer
		SellAmount:       tx.SellAmount,
		BuyAmount:        tx.BuyAmount,
		LimitPrice:       tx.Price,
	}

	// Include full message JSON for detail v
GetAddressDetails method · go · L834-L873 (40 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) GetAddressDetails(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	logger := middleware.GetLogger(ctx)

	// Parse address from URL
	address := chi.URLParam(r, "address")
	if address == "" {
		response.BadRequest(w, "Address is required", "")
		return
	}

	// Parse query parameters
	includeTransactions := r.URL.Query().Get("include_transactions") == "true"
	transactionLimit := 10
	if limitStr := r.URL.Query().Get("transaction_limit"); limitStr != "" {
		if limit, err := strconv.Atoi(limitStr); err == nil && limit > 0 && limit <= 100 {
			transactionLimit = limit
		}
	}

	// Build request
	req := &models.AddressDetailsRequest{
		Address:             address,
		IncludeTransactions: includeTransactions,
		TransactionLimit:    transactionLimit,
	}

	// Get address details from service
	details, err := h.explorerSvc.GetAddressDetails(ctx, req)
	if err != nil {
		logger.Error("failed to get address details",
			zap.Error(err),
			zap.String("address", a
GetNetworkOverview method · go · L877-L926 (50 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) GetNetworkOverview(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	logger := middleware.GetLogger(ctx)

	// Parse chain_id query parameter
	var chainID *uint64
	if chainIDStr := r.URL.Query().Get("chain_id"); chainIDStr != "" {
		parsed, err := strconv.ParseUint(chainIDStr, 10, 64)
		if err != nil {
			response.BadRequest(w, "Invalid chain_id parameter", err.Error())
			return
		}
		chainID = &parsed
	}

	// Parse start_time query parameter
	var startTime *time.Time
	if startTimeStr := r.URL.Query().Get("start_time"); startTimeStr != "" {
		parsed, err := parseTimeParam(startTimeStr)
		if err != nil {
			response.BadRequest(w, "Invalid start_time parameter", err.Error())
			return
		}
		startTime = &parsed
	}

	// Parse end_time query parameter
	var endTime *time.Time
	if endTimeStr := r.URL.Query().Get("end_time"); endTimeStr != "" {
		parsed, err := parseTimeParam(endTimeStr)
		if err != nil {
			response.BadRequest(w, "Invalid end_time parame
All rows scored by the Repobility analyzer (https://repobility.com)
parseTimeParam function · go · L929-L943 (15 LOC)
internal/handlers/explorer.go
func parseTimeParam(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)")
}
GetTrending method · go · L947-L984 (38 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) GetTrending(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	logger := middleware.GetLogger(ctx)

	// Parse limit parameter
	limit := 20 // Default
	if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
		parsedLimit, err := strconv.Atoi(limitStr)
		if err != nil {
			response.BadRequest(w, "Invalid limit parameter", err.Error())
			return
		}

		// Apply bounds
		if parsedLimit < 1 {
			limit = 1
		} else if parsedLimit > 100 {
			limit = 100
		} else {
			limit = parsedLimit
		}
	}

	// Get trending chains from service
	trending, err := h.explorerSvc.GetTrending(ctx, limit)
	if err != nil {
		logger.Error("failed to get trending chains", zap.Error(err))
		response.InternalServerError(w, "Failed to retrieve trending chains")
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]interface{}{
		"data":       trending.Data,
		"pagination": trending.Pagination,
	})
GetPools method · go · L988-L1037 (50 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) GetPools(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	logger := middleware.GetLogger(ctx)

	// Parse query parameters
	req, err := h.parsePoolsRequest(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}
	if req == nil {
		logger.Error("parsePoolsRequest returned nil request")
		response.InternalServerError(w, "Failed to parse request")
		return
	}

	// 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"
	}

	// Build query options
	opts := h.buildPoolQueryOptions(req)

	// Fetch pools from service
	pools, pagination, err := h.explorerSvc.GetPools(ctx, opts)
	if err != nil {
		logger.Error("failed to get pools", zap.Error(err))
		response.InternalServerError(w, "Failed to retrieve pools")
		return
	}

	// Prepare response with pagination
	responseData := map
GetPool method · go · L1041-L1074 (34 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) GetPool(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	logger := middleware.GetLogger(ctx)

	// Parse chain_id from URL
	chainIDStr := chi.URLParam(r, "chain_id")
	chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
	if err != nil {
		response.BadRequest(w, "Invalid chain_id", err.Error())
		return
	}

	// Parse pool_id from URL
	poolIDStr := chi.URLParam(r, "pool_id")
	poolID, err := strconv.ParseUint(poolIDStr, 10, 64)
	if err != nil {
		response.BadRequest(w, "Invalid pool_id", err.Error())
		return
	}

	// Fetch pool from service
	pool, err := h.explorerSvc.GetPool(ctx, chainID, poolID)
	if err != nil {
		logger.Error("failed to get pool",
			zap.Error(err),
			zap.Uint64("chain_id", chainID),
			zap.Uint64("pool_id", poolID),
		)
		response.NotFound(w, "Pool not found")
		return
	}

	response.Success(w, http.StatusOK, pool)
}
GetLPPositions method · go · L1078-L1127 (50 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) GetLPPositions(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	logger := middleware.GetLogger(ctx)

	// Parse query parameters
	req, err := h.parseLPPositionsRequest(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}
	if req == nil {
		logger.Error("parseLPPositionsRequest returned nil request")
		response.InternalServerError(w, "Failed to parse request")
		return
	}

	// 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"
	}

	// Build query options
	opts := h.buildLPPositionQueryOptions(req)

	// Fetch LP positions from service
	positions, pagination, err := h.explorerSvc.GetLPPositions(ctx, opts)
	if err != nil {
		logger.Error("failed to get LP positions", zap.Error(err))
		response.InternalServerError(w, "Failed to retrieve LP positions")
		return
	}

	/
GetLPPositionsByAddress method · go · L1131-L1199 (69 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) GetLPPositionsByAddress(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	logger := middleware.GetLogger(ctx)

	// Parse address from URL
	address := chi.URLParam(r, "address")
	if address == "" {
		response.BadRequest(w, "Address is required", "")
		return
	}

	// Validate address format (40 character hex string)
	if matched, _ := regexp.MatchString("^[a-fA-F0-9]{40}$", address); !matched {
		response.BadRequest(w, "Invalid address format", "Address must be a 40-character hexadecimal string")
		return
	}

	// Parse optional query parameters
	var chainID *uint64
	if chainIDStr := r.URL.Query().Get("chain_id"); chainIDStr != "" {
		parsed, err := strconv.ParseUint(chainIDStr, 10, 64)
		if err != nil {
			response.BadRequest(w, "Invalid chain_id", err.Error())
			return
		}
		chainID = &parsed
	}

	// Parse limit
	limit := 50 // Default for address-specific queries
	if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
		parsedLimit, err := st
parsePoolsRequest method · go · L1203-L1244 (42 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) parsePoolsRequest(r *http.Request) (*models.PoolsRequest, error) {
	req := &models.PoolsRequest{}
	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 poolIDStr := query.Get("pool_id"); poolIDStr != "" {
		poolID, err := strconv.ParseUint(poolIDStr, 10, 64)
		if err != nil {
			return nil, err
		}
		req.PoolID = &poolID
	}

	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
}
parseLPPositionsRequest method · go · L1246-L1291 (46 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) parseLPPositionsRequest(r *http.Request) (*models.LPPositionsRequest, error) {
	req := &models.LPPositionsRequest{}
	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 address := query.Get("address"); address != "" {
		req.Address = &address
	}

	if poolIDStr := query.Get("pool_id"); poolIDStr != "" {
		poolID, err := strconv.ParseUint(poolIDStr, 10, 64)
		if err != nil {
			return nil, err
		}
		req.PoolID = &poolID
	}

	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.S
Want this analysis on your repo? https://repobility.com/scan/
buildPoolQueryOptions method · go · L1293-L1310 (18 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) buildPoolQueryOptions(req *models.PoolsRequest) crosschain.QueryOptions {
	opts := crosschain.QueryOptions{
		Limit:   req.Limit,
		OrderBy: "height",
		Desc:    req.Sort == "desc",
		Filters: make(map[string]string),
	}

	if req.ChainID != nil {
		opts.ChainIDs = []uint64{*req.ChainID}
	}

	if req.PoolID != nil {
		opts.Filters["pool_id"] = strconv.FormatUint(*req.PoolID, 10)
	}

	return opts
}
buildLPPositionQueryOptions method · go · L1312-L1333 (22 LOC)
internal/handlers/explorer.go
func (h *ExplorerHandler) buildLPPositionQueryOptions(req *models.LPPositionsRequest) crosschain.QueryOptions {
	opts := crosschain.QueryOptions{
		Limit:   req.Limit,
		OrderBy: "height",
		Desc:    req.Sort == "desc",
		Filters: make(map[string]string),
	}

	if req.ChainID != nil {
		opts.ChainIDs = []uint64{*req.ChainID}
	}

	if req.Address != nil {
		opts.Filters["address"] = *req.Address
	}

	if req.PoolID != nil {
		opts.Filters["pool_id"] = strconv.FormatUint(*req.PoolID, 10)
	}

	return opts
}
HealthCheck function · go · L12-L20 (9 LOC)
internal/handlers/health.go
func HealthCheck(w http.ResponseWriter, r *http.Request) {
	healthResponse := models.HealthResponse{
		Status:    "healthy",
		Timestamp: time.Now().Format(time.RFC3339),
		Version:   "1.0.0", // This could come from build info
	}

	response.Success(w, http.StatusOK, healthResponse)
}
NewMetricsHandler function · go · L58-L72 (15 LOC)
internal/handlers/metrics.go
func NewMetricsHandler(
	dexMetricsRepo DEXMetricsRepository,
	orderBookMetricsRepo OrderBookMetricsRepository,
	liquidityMetricsRepo LiquidityMetricsRepository,
	tradingMetricsRepo TradingMetricsRepository,
	validator *validators.Validator,
) *MetricsHandler {
	return &MetricsHandler{
		dexMetricsRepo:       dexMetricsRepo,
		orderBookMetricsRepo: orderBookMetricsRepo,
		liquidityMetricsRepo: liquidityMetricsRepo,
		tradingMetricsRepo:   tradingMetricsRepo,
		validator:            validator,
	}
}
parseMetricsQueryParams method · go · L86-L155 (70 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) parseMetricsQueryParams(r *http.Request) (*MetricsQueryParams, error) {
	params := &MetricsQueryParams{}

	// Parse start_time
	if startTimeStr := r.URL.Query().Get("start_time"); startTimeStr != "" {
		startTime, err := time.Parse(time.RFC3339, startTimeStr)
		if err != nil {
			return nil, fmt.Errorf("invalid start_time format: must be RFC3339 (ISO 8601)")
		}
		params.StartTime = &startTime
	}

	// Parse end_time
	if endTimeStr := r.URL.Query().Get("end_time"); endTimeStr != "" {
		endTime, err := time.Parse(time.RFC3339, endTimeStr)
		if err != nil {
			return nil, fmt.Errorf("invalid end_time format: must be RFC3339 (ISO 8601)")
		}
		params.EndTime = &endTime
	}

	// Parse granularity
	params.Granularity = r.URL.Query().Get("granularity")
	if params.Granularity == "" {
		params.Granularity = "hourly" // Default
	}

	// Parse page
	if pageStr := r.URL.Query().Get("page"); pageStr != "" {
		page, err := strconv.Atoi(pageStr)
		if err != nil || page < 1 {
		
setDefaultTimeRange method · go · L158-L167 (10 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) setDefaultTimeRange(params *MetricsQueryParams) {
	now := time.Now()
	if params.StartTime == nil {
		defaultStart := now.Add(-24 * time.Hour)
		params.StartTime = &defaultStart
	}
	if params.EndTime == nil {
		params.EndTime = &now
	}
}
parsePaginationParams method · go · L170-L194 (25 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) parsePaginationParams(r *http.Request) MetricsPagination {
	page := 1
	limit := 20

	if pageStr := r.URL.Query().Get("page"); pageStr != "" {
		if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
			page = p
		}
	}

	if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
		if l, err := strconv.Atoi(limitStr); err == nil && l > 0 {
			limit = l
			if limit > 100 {
				limit = 100 // Max limit
			}
		}
	}

	return MetricsPagination{
		Page:   page,
		Limit:  limit,
		Offset: (page - 1) * limit,
	}
}
GetAllDEXMetrics method · go · L202-L220 (19 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) GetAllDEXMetrics(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	params, err := h.parseMetricsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	h.setDefaultTimeRange(params)

	metrics, err := h.dexMetricsRepo.GetAllDEXMetricsAcrossChains(ctx, params.StartTime, params.EndTime)
	if err != nil {
		response.InternalServerError(w, fmt.Sprintf("Failed to retrieve DEX metrics: %s", err.Error()))
		return
	}

	response.Success(w, http.StatusOK, metrics)
}
If a scraper extracted this row, it came from Repobility (https://repobility.com)
GetAllDEXMetricsByChain method · go · L224-L248 (25 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) GetAllDEXMetricsByChain(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	chainIDStr := chi.URLParam(r, "chain_id")
	chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
	if err != nil {
		response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
		return
	}

	params, err := h.parseMetricsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	h.setDefaultTimeRange(params)

	metrics, err := h.dexMetricsRepo.GetAllDEXMetrics(ctx, chainID, params.StartTime, params.EndTime)
	if err != nil {
		response.InternalServerError(w, fmt.Sprintf("Failed to retrieve DEX metrics: %s", err.Error()))
		return
	}

	response.Success(w, http.StatusOK, metrics)
}
GetLPHoldings method · go · L255-L276 (22 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) GetLPHoldings(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	params, err := h.parseMetricsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	if params.Address == "" {
		response.BadRequest(w, "Missing required parameter", "address query parameter is required")
		return
	}

	metrics, err := h.liquidityMetricsRepo.GetLPHoldings(ctx, params.Address)
	if err != nil {
		response.InternalServerError(w, fmt.Sprintf("Failed to retrieve LP holdings: %s", err.Error()))
		return
	}

	response.Success(w, http.StatusOK, metrics)
}
GetAllLiquidityMetrics method · go · L286-L321 (36 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) GetAllLiquidityMetrics(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	params, err := h.parseMetricsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	h.setDefaultTimeRange(params)

	// Parse optional pool_id query parameter
	var poolID *uint64
	if poolIDStr := r.URL.Query().Get("pool_id"); poolIDStr != "" {
		pid, err := strconv.ParseUint(poolIDStr, 10, 64)
		if err != nil {
			response.BadRequest(w, "Invalid pool_id parameter", err.Error())
			return
		}
		poolID = &pid
	}

	// Default granularity if not specified
	granularity := models.TimeGranularity(params.Granularity)
	if params.Granularity == "" {
		granularity = models.GranularityHourly
	}

	metrics, err := h.liquidityMetricsRepo.GetAllLiquidityMetricsAcrossChains(ctx, poolID, params.StartTime, params.EndTime, granularity)
	if err != nil {
		response.InternalServerError(w, fmt.Sprintf("Failed to retrieve liquidity metrics: %s",
GetAllLiquidityMetricsByChain method · go · L325-L366 (42 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) GetAllLiquidityMetricsByChain(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	chainIDStr := chi.URLParam(r, "chain_id")
	chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
	if err != nil {
		response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
		return
	}

	params, err := h.parseMetricsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	h.setDefaultTimeRange(params)

	// Parse optional pool_id query parameter
	var poolID *uint64
	if poolIDStr := r.URL.Query().Get("pool_id"); poolIDStr != "" {
		pid, err := strconv.ParseUint(poolIDStr, 10, 64)
		if err != nil {
			response.BadRequest(w, "Invalid pool_id parameter", err.Error())
			return
		}
		poolID = &pid
	}

	// Default granularity if not specified
	granularity := models.TimeGranularity(params.Granularity)
	if params.Granularity == "" {
		granularity = models.GranularityHourly
	}

	metrics, err := h.liquidityMetricsRepo.
GetAllTradingMetrics method · go · L378-L404 (27 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) GetAllTradingMetrics(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	params, err := h.parseMetricsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	h.setDefaultTimeRange(params)

	// Parse optional query parameters
	rankBy := r.URL.Query().Get("rank_by")
	if rankBy == "" {
		rankBy = "volume" // Default to volume ranking
	}

	pagination := h.parsePaginationParams(r)

	metrics, err := h.tradingMetricsRepo.GetAllTradingMetricsAcrossChains(ctx, params.StartTime, params.EndTime, rankBy, pagination)
	if err != nil {
		response.InternalServerError(w, fmt.Sprintf("Failed to retrieve trading metrics: %s", err.Error()))
		return
	}

	response.Success(w, http.StatusOK, metrics)
}
GetAllTradingMetricsByChain method · go · L408-L440 (33 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) GetAllTradingMetricsByChain(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	chainIDStr := chi.URLParam(r, "chain_id")
	chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
	if err != nil {
		response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
		return
	}

	params, err := h.parseMetricsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	h.setDefaultTimeRange(params)

	// Parse optional query parameters
	rankBy := r.URL.Query().Get("rank_by")
	if rankBy == "" {
		rankBy = "volume" // Default to volume ranking
	}

	pagination := h.parsePaginationParams(r)

	metrics, err := h.tradingMetricsRepo.GetAllTradingMetrics(ctx, chainID, params.StartTime, params.EndTime, rankBy, pagination)
	if err != nil {
		response.InternalServerError(w, fmt.Sprintf("Failed to retrieve trading metrics: %s", err.Error()))
		return
	}

	response.Success(w, http.StatusOK, metrics)
}
GetAllOrderbookMetrics method · go · L448-L466 (19 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) GetAllOrderbookMetrics(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	params, err := h.parseMetricsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	h.setDefaultTimeRange(params)

	metrics, err := h.orderBookMetricsRepo.GetAllOrderbookMetricsAcrossChains(ctx, params.StartTime, params.EndTime)
	if err != nil {
		response.InternalServerError(w, fmt.Sprintf("Failed to retrieve orderbook metrics: %s", err.Error()))
		return
	}

	response.Success(w, http.StatusOK, metrics)
}
GetAllOrderbookMetricsByChain method · go · L470-L494 (25 LOC)
internal/handlers/metrics.go
func (h *MetricsHandler) GetAllOrderbookMetricsByChain(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	chainIDStr := chi.URLParam(r, "chain_id")
	chainID, err := strconv.ParseUint(chainIDStr, 10, 64)
	if err != nil {
		response.Error(w, http.StatusBadRequest, "Invalid chain ID", "")
		return
	}

	params, err := h.parseMetricsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	h.setDefaultTimeRange(params)

	metrics, err := h.orderBookMetricsRepo.GetAllOrderbookMetrics(ctx, chainID, params.StartTime, params.EndTime)
	if err != nil {
		response.InternalServerError(w, fmt.Sprintf("Failed to retrieve orderbook metrics: %s", err.Error()))
		return
	}

	response.Success(w, http.StatusOK, metrics)
}
Repobility · open methodology · https://repobility.com/research/
NewParamsHandler function · go · L22-L28 (7 LOC)
internal/handlers/params.go
func NewParamsHandler(rpcClient *canopy.Client, validator *validators.Validator, logger *zap.Logger) *ParamsHandler {
	return &ParamsHandler{
		rpcClient: rpcClient,
		validator: validator,
		logger:    logger,
	}
}
parseHeightParam function · go · L32-L42 (11 LOC)
internal/handlers/params.go
func parseHeightParam(r *http.Request) uint64 {
	heightStr := r.URL.Query().Get("height")
	if heightStr == "" {
		return 0
	}
	height, err := strconv.ParseUint(heightStr, 10, 64)
	if err != nil {
		return 0
	}
	return height
}
GetFeeParams method · go · L45-L73 (29 LOC)
internal/handlers/params.go
func (h *ParamsHandler) GetFeeParams(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	// Parse optional height query parameter (default: 0 = latest)
	height := parseHeightParam(r)

	// Call RPC client
	params, libErr := h.rpcClient.FeeParams(height)
	if libErr != nil {
		custommiddleware.GetLogger(ctx).Error("failed to query fee params",
			zap.Error(libErr),
			zap.Uint64("height", height),
		)
		response.InternalServerError(w, "Failed to query fee parameters")
		return
	}

	// Check for nil response
	if params == nil {
		custommiddleware.GetLogger(ctx).Error("received nil fee params",
			zap.Uint64("height", height),
		)
		response.InternalServerError(w, "Failed to query fee parameters")
		return
	}

	// Return JSON response
	response.Success(w, http.StatusOK, params)
}
GetGovParams method · go · L76-L104 (29 LOC)
internal/handlers/params.go
func (h *ParamsHandler) GetGovParams(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	// Parse optional height query parameter (default: 0 = latest)
	height := parseHeightParam(r)

	// Call RPC client
	params, libErr := h.rpcClient.GovParams(height)
	if libErr != nil {
		custommiddleware.GetLogger(ctx).Error("failed to query governance params",
			zap.Error(libErr),
			zap.Uint64("height", height),
		)
		response.InternalServerError(w, "Failed to query governance parameters")
		return
	}

	// Check for nil response
	if params == nil {
		custommiddleware.GetLogger(ctx).Error("received nil governance params",
			zap.Uint64("height", height),
		)
		response.InternalServerError(w, "Failed to query governance parameters")
		return
	}

	// Return JSON response
	response.Success(w, http.StatusOK, params)
}
GetConParams method · go · L107-L135 (29 LOC)
internal/handlers/params.go
func (h *ParamsHandler) GetConParams(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	// Parse optional height query parameter (default: 0 = latest)
	height := parseHeightParam(r)

	// Call RPC client
	params, libErr := h.rpcClient.ConParams(height)
	if libErr != nil {
		custommiddleware.GetLogger(ctx).Error("failed to query consensus params",
			zap.Error(libErr),
			zap.Uint64("height", height),
		)
		response.InternalServerError(w, "Failed to query consensus parameters")
		return
	}

	// Check for nil response
	if params == nil {
		custommiddleware.GetLogger(ctx).Error("received nil consensus params",
			zap.Uint64("height", height),
		)
		response.InternalServerError(w, "Failed to query consensus parameters")
		return
	}

	// Return JSON response
	response.Success(w, http.StatusOK, params)
}
GetValParams method · go · L138-L166 (29 LOC)
internal/handlers/params.go
func (h *ParamsHandler) GetValParams(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	// Parse optional height query parameter (default: 0 = latest)
	height := parseHeightParam(r)

	// Call RPC client
	params, libErr := h.rpcClient.ValParams(height)
	if libErr != nil {
		custommiddleware.GetLogger(ctx).Error("failed to query validator params",
			zap.Error(libErr),
			zap.Uint64("height", height),
		)
		response.InternalServerError(w, "Failed to query validator parameters")
		return
	}

	// Check for nil response
	if params == nil {
		custommiddleware.GetLogger(ctx).Error("received nil validator params",
			zap.Uint64("height", height),
		)
		response.InternalServerError(w, "Failed to query validator parameters")
		return
	}

	// Return JSON response
	response.Success(w, http.StatusOK, params)
}
NewPortfolioHandler function · go · L21-L27 (7 LOC)
internal/handlers/portfolio.go
func NewPortfolioHandler(portfolioService *portfolio.Service, validator *validators.Validator, logger *zap.Logger) *PortfolioHandler {
	return &PortfolioHandler{
		portfolioService: portfolioService,
		validator:        validator,
		logger:           logger,
	}
}
GetPortfolioOverview method · go · L30-L54 (25 LOC)
internal/handlers/portfolio.go
func (h *PortfolioHandler) GetPortfolioOverview(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	var req models.PortfolioOverviewRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		response.BadRequest(w, "Invalid JSON payload", err.Error())
		return
	}

	// Get portfolio overview
	overview, err := h.portfolioService.GetPortfolioOverview(ctx, &req)
	if err != nil {
		if err == portfolio.ErrNoAddressesProvided {
			response.BadRequest(w, "No addresses provided", err.Error())
			return
		}
		middleware.GetLogger(ctx).Error("failed to get portfolio overview",
			zap.Error(err),
		)
		response.InternalServerError(w, "Failed to retrieve portfolio overview")
		return
	}

	response.Success(w, http.StatusOK, overview)
}
All rows scored by the Repobility analyzer (https://repobility.com)
GetAccountBalances method · go · L57-L81 (25 LOC)
internal/handlers/portfolio.go
func (h *PortfolioHandler) GetAccountBalances(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	var req models.AccountBalancesRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		response.BadRequest(w, "Invalid JSON payload", err.Error())
		return
	}

	// Get account balances
	balances, err := h.portfolioService.GetAccountBalances(ctx, &req)
	if err != nil {
		if err == portfolio.ErrNoAddressesProvided {
			response.BadRequest(w, "No addresses provided", err.Error())
			return
		}
		middleware.GetLogger(ctx).Error("failed to get account balances",
			zap.Error(err),
		)
		response.InternalServerError(w, "Failed to retrieve account balances")
		return
	}

	response.Success(w, http.StatusOK, balances)
}
GetPortfolioPerformance method · go · L84-L126 (43 LOC)
internal/handlers/portfolio.go
func (h *PortfolioHandler) GetPortfolioPerformance(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	var req models.PortfolioPerformanceRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		response.BadRequest(w, "Invalid JSON payload", err.Error())
		return
	}

	// Set defaults
	if req.Period == "" {
		req.Period = "30d"
	}
	if req.Granularity == "" {
		req.Granularity = "daily"
	}

	// Get portfolio performance
	performance, err := h.portfolioService.GetPortfolioPerformance(ctx, &req)
	if err != nil {
		if err == portfolio.ErrNoAddressesProvided {
			response.BadRequest(w, "No addresses provided", err.Error())
			return
		}
		if err == portfolio.ErrInvalidPeriod {
			response.BadRequest(w, "Invalid period", err.Error())
			return
		}
		if err == portfolio.ErrInvalidGranularity {
			response.BadRequest(w, "Invalid granularity", err.Error())
			return
		}
		middleware.GetLogger(ctx).Error("failed to get portfolio performance",
			zap.Error(err),
			zap.S
GetAssetAllocation method · go · L129-L153 (25 LOC)
internal/handlers/portfolio.go
func (h *PortfolioHandler) GetAssetAllocation(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	var req models.AssetAllocationRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		response.BadRequest(w, "Invalid JSON payload", err.Error())
		return
	}

	// Get asset allocation
	allocation, err := h.portfolioService.GetAssetAllocation(ctx, &req)
	if err != nil {
		if err == portfolio.ErrNoAddressesProvided {
			response.BadRequest(w, "No addresses provided", err.Error())
			return
		}
		middleware.GetLogger(ctx).Error("failed to get asset allocation",
			zap.Error(err),
		)
		response.InternalServerError(w, "Failed to retrieve asset allocation")
		return
	}

	response.Success(w, http.StatusOK, allocation)
}
GetMultiChainBalance method · go · L156-L180 (25 LOC)
internal/handlers/portfolio.go
func (h *PortfolioHandler) GetMultiChainBalance(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	var req models.MultiChainBalanceRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		response.BadRequest(w, "Invalid JSON payload", err.Error())
		return
	}

	// Get multi-chain balance
	balance, err := h.portfolioService.GetMultiChainBalance(ctx, &req)
	if err != nil {
		if err == portfolio.ErrNoAddressesProvided {
			response.BadRequest(w, "No addresses provided", err.Error())
			return
		}
		middleware.GetLogger(ctx).Error("failed to get multi-chain balance",
			zap.Error(err),
		)
		response.InternalServerError(w, "Failed to retrieve multi-chain balance")
		return
	}

	response.Success(w, http.StatusOK, balance)
}
ListRoutes function · go · L18-L39 (22 LOC)
internal/handlers/routes.go
func ListRoutes(router *chi.Mux) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var routes []RouteInfo

		// Walk through all registered routes
		chi.Walk(router, func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
			routes = append(routes, RouteInfo{
				Method:      method,
				Path:        route,
				Middlewares: len(middlewares),
			})
			return nil
		})

		// Return routes as JSON
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(map[string]interface{}{
			"data":  routes,
			"count": len(routes),
		})
	}
}
NewStakingHandler function · go · L20-L25 (6 LOC)
internal/handlers/staking.go
func NewStakingHandler(stakingService *staking.Service, logger *zap.Logger) *StakingHandler {
	return &StakingHandler{
		stakingService: stakingService,
		logger:         logger,
	}
}
GetStakingPositions method · go · L29-L64 (36 LOC)
internal/handlers/staking.go
func (h *StakingHandler) GetStakingPositions(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	// Get authenticated user ID from context
	userIDStr, ok := ctx.Value("userID").(string)
	if !ok {
		response.Unauthorized(w, "Authentication required")
		return
	}

	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		response.BadRequest(w, "Invalid user ID", err.Error())
		return
	}

	// Parse query parameters
	req, err := h.parseQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	// Get staking positions
	positionsResp, err := h.stakingService.GetStakingPositions(ctx, userID, req)
	if err != nil {
		h.logger.Error("failed to get staking positions",
			zap.Error(err),
			zap.String("user_id", userID.String()),
		)
		response.InternalServerError(w, "Failed to get staking positions")
		return
	}

	response.Success(w, http.StatusOK, positionsResp)
}
parseQueryParams method · go · L67-L108 (42 LOC)
internal/handlers/staking.go
func (h *StakingHandler) parseQueryParams(r *http.Request) (*models.StakingPositionsRequest, error) {
	req := &models.StakingPositionsRequest{}

	// Parse chain_ids (comma-separated)
	if chainIDsStr := r.URL.Query().Get("chain_ids"); chainIDsStr != "" {
		chainIDParts := strings.Split(chainIDsStr, ",")
		chainIDs := make([]uint64, 0, len(chainIDParts))
		for _, part := range chainIDParts {
			chainID, err := strconv.ParseUint(strings.TrimSpace(part), 10, 64)
			if err != nil {
				return nil, err
			}
			chainIDs = append(chainIDs, chainID)
		}
		req.ChainIDs = chainIDs
	}

	// Parse status filter
	if status := r.URL.Query().Get("status"); status != "" {
		req.Status = status
	}

	// Parse limit
	if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
		limit, err := strconv.Atoi(limitStr)
		if err != nil {
			return nil, err
		}
		req.Limit = limit
	}

	// Parse offset
	if offsetStr := r.URL.Query().Get("offset"); offsetStr != "" {
		offset, err := strconv.ParseUint(offsetStr, 10,
Want this analysis on your repo? https://repobility.com/scan/
GetStakingRewards method · go · L112-L147 (36 LOC)
internal/handlers/staking.go
func (h *StakingHandler) GetStakingRewards(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	// Get authenticated user ID from context
	userIDStr, ok := ctx.Value("userID").(string)
	if !ok {
		response.Unauthorized(w, "Authentication required")
		return
	}

	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		response.BadRequest(w, "Invalid user ID", err.Error())
		return
	}

	// Parse query parameters
	req, err := h.parseRewardsQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	// Get staking rewards
	rewardsResp, err := h.stakingService.GetStakingRewards(ctx, userID, req)
	if err != nil {
		h.logger.Error("failed to get staking rewards",
			zap.Error(err),
			zap.String("user_id", userID.String()),
		)
		response.InternalServerError(w, "Failed to get staking rewards")
		return
	}

	response.Success(w, http.StatusOK, rewardsResp)
}
GetUnstakingQueue method · go · L151-L186 (36 LOC)
internal/handlers/staking.go
func (h *StakingHandler) GetUnstakingQueue(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	// Get authenticated user ID from context
	userIDStr, ok := ctx.Value("userID").(string)
	if !ok {
		response.Unauthorized(w, "Authentication required")
		return
	}

	userID, err := uuid.Parse(userIDStr)
	if err != nil {
		response.BadRequest(w, "Invalid user ID", err.Error())
		return
	}

	// Parse query parameters
	req, err := h.parseUnstakingQueryParams(r)
	if err != nil {
		response.BadRequest(w, "Invalid query parameters", err.Error())
		return
	}

	// Get unstaking queue
	queueResp, err := h.stakingService.GetUnstakingQueue(ctx, userID, req)
	if err != nil {
		h.logger.Error("failed to get unstaking queue",
			zap.Error(err),
			zap.String("user_id", userID.String()),
		)
		response.InternalServerError(w, "Failed to get unstaking queue")
		return
	}

	response.Success(w, http.StatusOK, queueResp)
}
parseRewardsQueryParams method · go · L189-L225 (37 LOC)
internal/handlers/staking.go
func (h *StakingHandler) parseRewardsQueryParams(r *http.Request) (*models.StakingRewardsRequest, error) {
	req := &models.StakingRewardsRequest{}

	// Parse chain_ids (comma-separated)
	if chainIDsStr := r.URL.Query().Get("chain_ids"); chainIDsStr != "" {
		chainIDParts := strings.Split(chainIDsStr, ",")
		chainIDs := make([]uint64, 0, len(chainIDParts))
		for _, part := range chainIDParts {
			chainID, err := strconv.ParseUint(strings.TrimSpace(part), 10, 64)
			if err != nil {
				return nil, err
			}
			chainIDs = append(chainIDs, chainID)
		}
		req.ChainIDs = chainIDs
	}

	// Parse limit
	if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
		limit, err := strconv.Atoi(limitStr)
		if err != nil {
			return nil, err
		}
		req.Limit = limit
	}

	// Parse offset
	if offsetStr := r.URL.Query().Get("offset"); offsetStr != "" {
		offset, err := strconv.ParseUint(offsetStr, 10, 64)
		if err != nil {
			return nil, err
		}
		req.Offset = offset
	}

	return req, nil
}
‹ prevpage 6 / 23next ›