Skip to content

Commit f6517d9

Browse files
committed
API and tests done;
1 parent 3c3055f commit f6517d9

19 files changed

+1091
-16
lines changed

cmd/api/handler/responses/signal.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// SPDX-FileCopyrightText: 2025 Bb Strategy Pte. Ltd. <celenium@baking-bad.org>
2+
// SPDX-License-Identifier: MIT
3+
4+
package responses
5+
6+
import (
7+
"time"
8+
9+
"github.com/celenium-io/celestia-indexer/internal/storage"
10+
pkgTypes "github.com/celenium-io/celestia-indexer/pkg/types"
11+
)
12+
13+
type SignalVersion struct {
14+
Id uint64 `example:"321" format:"int64" json:"id" swaggertype:"integer"`
15+
Height pkgTypes.Level `example:"100" format:"int64" json:"height" swaggertype:"integer"`
16+
Time time.Time `example:"2025-07-04T03:10:57+00:00" format:"date-time" json:"time" swaggertype:"string"`
17+
VotingPower string `example:"9348" format:"int64" json:"voting_power" swaggertype:"string"`
18+
Version uint64 `example:"1" format:"int64" json:"version" swaggertype:"integer"`
19+
MsgId uint64 `example:"2" format:"int64" json:"msg_id" swaggertype:"integer"`
20+
TxId uint64 `example:"3" format:"int64" json:"tx_id" swaggertype:"integer"`
21+
}
22+
23+
func NewSignalVersion(signal storage.SignalVersion) SignalVersion {
24+
result := SignalVersion{
25+
Id: signal.Id,
26+
Height: signal.Height,
27+
Time: signal.Time,
28+
VotingPower: signal.VotingPower.String(),
29+
Version: signal.Version,
30+
MsgId: signal.MsgId,
31+
TxId: signal.TxId,
32+
}
33+
34+
return result
35+
}
36+
37+
type Upgrade struct {
38+
Id uint64 `example:"321" format:"int64" json:"id" swaggertype:"integer"`
39+
Height pkgTypes.Level `example:"100" format:"int64" json:"height" swaggertype:"integer"`
40+
Time time.Time `example:"2025-07-04T03:10:57+00:00" format:"date-time" json:"time" swaggertype:"string"`
41+
Version uint64 `example:"1" format:"int64" json:"version" swaggertype:"integer"`
42+
MsgId uint64 `example:"2" format:"int64" json:"msg_id" swaggertype:"integer"`
43+
TxId uint64 `example:"3" format:"int64" json:"tx_id" swaggertype:"integer"`
44+
45+
Signer *ShortAddress `json:"signer,omitempty"`
46+
}
47+
48+
func NewUpgrade(upgrade storage.Upgrade) Upgrade {
49+
result := Upgrade{
50+
Id: upgrade.Id,
51+
Height: upgrade.Height,
52+
Time: upgrade.Time,
53+
Version: upgrade.Version,
54+
MsgId: upgrade.MsgId,
55+
TxId: upgrade.TxId,
56+
}
57+
58+
if upgrade.Signer != nil {
59+
result.Signer = NewShortAddress(upgrade.Signer)
60+
}
61+
62+
return result
63+
}

cmd/api/handler/signal.go

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
// SPDX-FileCopyrightText: 2025 Bb Strategy Pte. Ltd. <celenium@baking-bad.org>
2+
// SPDX-License-Identifier: MIT
3+
4+
package handler
5+
6+
import (
7+
"context"
8+
"encoding/hex"
9+
"github.com/celenium-io/celestia-indexer/cmd/api/handler/responses"
10+
"github.com/celenium-io/celestia-indexer/internal/storage"
11+
"github.com/labstack/echo/v4"
12+
)
13+
14+
type SignalHandler struct {
15+
signals storage.ISignalVersion
16+
upgrades storage.IUpgrade
17+
validator storage.IValidator
18+
tx storage.ITx
19+
address storage.IAddress
20+
}
21+
22+
func NewSignalHandler(
23+
signals storage.ISignalVersion,
24+
upgrades storage.IUpgrade,
25+
validator storage.IValidator,
26+
tx storage.ITx,
27+
address storage.IAddress,
28+
) *SignalHandler {
29+
return &SignalHandler{
30+
signals: signals,
31+
upgrades: upgrades,
32+
validator: validator,
33+
tx: tx,
34+
address: address,
35+
}
36+
}
37+
38+
type signalsRequest struct {
39+
Limit int `example:"10" query:"limit" swaggertype:"integer" validate:"omitempty,min=1,max=100"`
40+
Offset int `example:"0" query:"offset" swaggertype:"integer" validate:"omitempty,min=0"`
41+
Version uint64 `example:"7" query:"version" swaggertype:"integer" validate:"omitempty"`
42+
ValidatorId uint64 `example:"1488" query:"validator_id" swaggertype:"string" validate:"omitempty"`
43+
TxHash string `example:"97589d917f13c7d1d5b01dcc0a3df84c8b4337e47dae492e03c274cc77ded173" query:"tx_hash" swaggertype:"string" validate:"omitempty"`
44+
From int64 `example:"1692892095" query:"from" swaggertype:"integer" validate:"omitempty,min=1"`
45+
To int64 `example:"1692892095" query:"to" swaggertype:"integer" validate:"omitempty,min=1"`
46+
Sort string `example:"asc" query:"sort" swaggertype:"string" validate:"omitempty,oneof=asc desc"`
47+
}
48+
49+
func (req *signalsRequest) ToFilters(
50+
ctx context.Context,
51+
txs storage.ITx) (storage.ListSignalsFilter, error) {
52+
var filters = storage.ListSignalsFilter{
53+
Limit: req.Limit,
54+
Offset: req.Offset,
55+
ValidatorId: req.ValidatorId,
56+
Version: req.Version,
57+
TxHash: req.TxHash,
58+
Sort: desc,
59+
}
60+
61+
if req.Limit > 0 {
62+
filters.Limit = req.Limit
63+
}
64+
if req.Sort != "" {
65+
filters.Sort = pgSort(req.Sort)
66+
}
67+
68+
if req.TxHash != "" {
69+
hash, err := hex.DecodeString(req.TxHash)
70+
if err != nil {
71+
return filters, err
72+
}
73+
74+
tx, err := txs.ByHash(ctx, hash)
75+
if err != nil {
76+
return filters, err
77+
}
78+
79+
filters.TxId = &tx.Id
80+
}
81+
82+
return filters, nil
83+
}
84+
85+
// List godoc
86+
//
87+
// @Summary List signals
88+
// @Description List signals
89+
// @Tags signal
90+
// @ID list-signal
91+
// @Param version query integer false "Version"
92+
// @Param validator_id query integer false "Validator internal id"
93+
// @Param tx_hash query string false "Transaction hash"
94+
// @Param limit query integer false "Count of requested entities" mininum(1) maximum(100)
95+
// @Param offset query integer false "Offset" mininum(1)
96+
// @Param from query integer false "Time from in unix timestamp" mininum(1)
97+
// @Param to query integer false "Time to in unix timestamp" mininum(1)
98+
// @Param sort query string false "Sort order. Default: desc" Enums(asc, desc)
99+
// @Produce json
100+
// @Success 200 {array} responses.SignalVersion
101+
// @Failure 400 {object} Error
102+
// @Failure 500 {object} Error
103+
// @Router /signal [get]
104+
func (handler *SignalHandler) List(c echo.Context) error {
105+
req, err := bindAndValidate[signalsRequest](c)
106+
if err != nil {
107+
return badRequestError(c, err)
108+
}
109+
filters, err := req.ToFilters(c.Request().Context(), handler.tx)
110+
if err != nil {
111+
return handleError(c, err, handler.tx)
112+
}
113+
114+
signals, err := handler.signals.List(c.Request().Context(), filters)
115+
if err != nil {
116+
return handleError(c, err, handler.tx)
117+
}
118+
119+
response := make([]responses.SignalVersion, len(signals))
120+
for i := range signals {
121+
response[i] = responses.NewSignalVersion(signals[i])
122+
}
123+
124+
return returnArray(c, response)
125+
}
126+
127+
type upgradesRequest struct {
128+
Limit int `example:"10" query:"limit" swaggertype:"integer" validate:"omitempty,min=1,max=100"`
129+
Offset int `example:"0" query:"offset" swaggertype:"integer" validate:"omitempty,min=0"`
130+
Height uint64 `example:"12345678" query:"height" swaggertype:"integer" validate:"omitempty"`
131+
TxHash string `example:"97589d917f13c7d1d5b01dcc0a3df84c8b4337e47dae492e03c274cc77ded173" query:"tx_hash" swaggertype:"string" validate:"omitempty"`
132+
Signer string `example:"celestia1ps2778x42p833xesk7jh6vy0qu8485e3pz8g72" query:"signer" swaggertype:"string" validate:"omitempty"`
133+
Sort string `example:"asc" query:"sort" swaggertype:"string" validate:"omitempty,oneof=asc desc"`
134+
}
135+
136+
func (req *upgradesRequest) ToFilters(
137+
ctx context.Context,
138+
address storage.IAddress,
139+
txs storage.ITx) (storage.ListUpgradesFilter, error) {
140+
var filters = storage.ListUpgradesFilter{
141+
Limit: req.Limit,
142+
Offset: req.Offset,
143+
Height: req.Height,
144+
TxHash: req.TxHash,
145+
Signer: req.Signer,
146+
Sort: desc,
147+
}
148+
149+
if req.Limit > 0 {
150+
filters.Limit = req.Limit
151+
}
152+
if req.Sort != "" {
153+
filters.Sort = pgSort(req.Sort)
154+
}
155+
if req.Signer != "" {
156+
addrId, err := address.IdByAddress(ctx, req.Signer)
157+
if err != nil {
158+
return filters, err
159+
}
160+
filters.SignerId = &addrId
161+
}
162+
163+
if req.TxHash != "" {
164+
hash, err := hex.DecodeString(req.TxHash)
165+
if err != nil {
166+
return filters, err
167+
}
168+
169+
tx, err := txs.ByHash(ctx, hash)
170+
if err != nil {
171+
return filters, err
172+
}
173+
174+
filters.TxId = &tx.Id
175+
}
176+
177+
return filters, nil
178+
}
179+
180+
// Upgrades godoc
181+
//
182+
// @Summary List upgrades
183+
// @Description List upgrades
184+
// @Tags signal
185+
// @ID list-upgrades
186+
// @Param height query integer false "Number of block"
187+
// @Param tx_hash query string false "Transaction hash"
188+
// @Param signer query string false "Signer address"
189+
// @Param limit query integer false "Count of requested entities" mininum(1) maximum(100)
190+
// @Param offset query integer false "Offset" mininum(1)
191+
// @Param sort query string false "Sort order. Default: desc" Enums(asc, desc)
192+
// @Produce json
193+
// @Success 200 {array} responses.Upgrade
194+
// @Failure 400 {object} Error
195+
// @Failure 500 {object} Error
196+
// @Router /signal/upgrade [get]
197+
func (handler *SignalHandler) Upgrades(c echo.Context) error {
198+
req, err := bindAndValidate[upgradesRequest](c)
199+
if err != nil {
200+
return badRequestError(c, err)
201+
}
202+
filters, err := req.ToFilters(c.Request().Context(), handler.address, handler.tx)
203+
if err != nil {
204+
return handleError(c, err, handler.address)
205+
}
206+
207+
upgrades, err := handler.upgrades.List(c.Request().Context(), filters)
208+
if err != nil {
209+
return handleError(c, err, handler.tx)
210+
}
211+
212+
response := make([]responses.Upgrade, len(upgrades))
213+
for i := range upgrades {
214+
response[i] = responses.NewUpgrade(upgrades[i])
215+
}
216+
217+
return returnArray(c, response)
218+
}

0 commit comments

Comments
 (0)