diff --git a/Dockerfile b/Dockerfile index e6cda073..ea049e10 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /app ADD . . -RUN CGO_ENABLED=0 go build -o ./bin/algorun *.go +RUN CGO_ENABLED=0 go build -o ./bin/algorun main.go && CGO_ENABLED=0 go build -o ./bin/fortiter daemon/main.go FROM algorand/algod:latest @@ -20,6 +20,7 @@ ADD .docker/start_empty.sh /node/run/start_empty.sh ADD .docker/start_fast_catchup.sh /node/run/start_fast_catchup.sh COPY --from=builder /app/bin/algorun /bin/algorun +COPY --from=BUILDER /app/bin/fortiter /bin/fortiter RUN apt-get update && apt-get install jq -y diff --git a/Makefile b/Makefile index 195d9e3a..a77c39c0 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ build: - CGO_ENABLED=0 go build -o bin/algorun *.go + CGO_ENABLED=0 go build -o bin/algorun main.go +build-daemon: + CGO_ENABLED=0 go build -o bin/fortiter -ldflags "-X cmd.version=testing" daemon/main.go test: go test -coverpkg=./... -covermode=atomic ./... generate: diff --git a/cmd/root.go b/cmd/root.go index 2e03a8d9..6deb5400 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,7 +7,7 @@ import ( "github.com/algorandfoundation/algorun-tui/api" "github.com/algorandfoundation/algorun-tui/cmd/configure" "github.com/algorandfoundation/algorun-tui/cmd/node" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui" "github.com/algorandfoundation/algorun-tui/ui/explanations" "github.com/algorandfoundation/algorun-tui/ui/style" @@ -64,15 +64,15 @@ var ( v.StatusCode()) } - partkeys, err := internal.GetPartKeys(ctx, client) + partkeys, err := nodekit.GetPartKeys(ctx, client) if err != nil { return fmt.Errorf( style.Red.Render("failed to get participation keys: %s")+ explanations.TokenNotAdmin, err) } - state := internal.StateModel{ - Status: internal.StatusModel{ + state := nodekit.StateModel{ + Status: nodekit.StatusModel{ State: "INITIALIZING", Version: "N/A", Network: "N/A", @@ -80,7 +80,7 @@ var ( NeedsUpdate: true, LastRound: 0, }, - Metrics: internal.MetricsModel{ + Metrics: nodekit.MetricsModel{ RoundTime: 0, TPS: 0, RX: 0, @@ -91,10 +91,10 @@ var ( Client: client, Context: ctx, } - state.Accounts, err = internal.AccountsFromState(&state, new(internal.Clock), client) + state.Accounts, err = nodekit.AccountsFromState(&state, new(nodekit.Clock), client) cobra.CheckErr(err) // Fetch current state - err = state.Status.Fetch(ctx, client, new(internal.HttpPkg)) + err = state.Status.Fetch(ctx, client, new(nodekit.HttpPkg)) cobra.CheckErr(err) m, err := ui.NewViewportViewModel(&state, client) @@ -106,7 +106,7 @@ var ( tea.WithFPS(120), ) go func() { - state.Watch(func(status *internal.StateModel, err error) { + state.Watch(func(status *nodekit.StateModel, err error) { if err == nil { p.Send(state) } diff --git a/cmd/status.go b/cmd/status.go index 62bd010f..a1b7abc8 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui" "github.com/algorandfoundation/algorun-tui/ui/style" tea "github.com/charmbracelet/bubbletea" @@ -27,8 +27,8 @@ var statusCmd = &cobra.Command{ // Get Algod from configuration client, err := getClient() cobra.CheckErr(err) - state := internal.StateModel{ - Status: internal.StatusModel{ + state := nodekit.StateModel{ + Status: nodekit.StatusModel{ State: "SYNCING", Version: "N/A", Network: "N/A", @@ -36,7 +36,7 @@ var statusCmd = &cobra.Command{ NeedsUpdate: true, LastRound: 0, }, - Metrics: internal.MetricsModel{ + Metrics: nodekit.MetricsModel{ RoundTime: 0, TPS: 0, RX: 0, @@ -44,14 +44,14 @@ var statusCmd = &cobra.Command{ }, ParticipationKeys: nil, } - err = state.Status.Fetch(context.Background(), client, new(internal.HttpPkg)) + err = state.Status.Fetch(context.Background(), client, new(nodekit.HttpPkg)) cobra.CheckErr(err) // Create the TUI view := ui.MakeStatusViewModel(&state) p := tea.NewProgram(view, tea.WithAltScreen()) go func() { - state.Watch(func(status *internal.StateModel, err error) { + state.Watch(func(status *nodekit.StateModel, err error) { cobra.CheckErr(err) p.Send(state) }, context.Background(), client) diff --git a/daemon/cmd/root.go b/daemon/cmd/root.go new file mode 100644 index 00000000..ec9a5a3c --- /dev/null +++ b/daemon/cmd/root.go @@ -0,0 +1,204 @@ +package cmd + +import ( + "context" + "encoding/json" + "fmt" + "github.com/algorand/go-algorand/config" + "github.com/algorandfoundation/algorun-tui/daemon/fortiter" + "github.com/algorandfoundation/algorun-tui/daemon/rpc" + "github.com/algorandfoundation/algorun-tui/ui/style" + "github.com/charmbracelet/log" + "github.com/jmoiron/sqlx" + "github.com/labstack/echo-contrib/echoprometheus" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + _ "github.com/mattn/go-sqlite3" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "io" + "os" + "strings" +) + +const BANNER = ` + ______ ______ ______ ______ __ ______ ______ ______ +/\ ___\ /\ __ \ /\ == \ /\__ _\ /\ \ /\__ _\ /\ ___\ /\ == \ +\ \ __\ \ \ \/\ \ \ \ __< \/_/\ \/ \ \ \ \/_/\ \/ \ \ __\ \ \ __< + \ \_\ \ \_____\ \ \_\ \_\ \ \_\ \ \_\ \ \_\ \ \_____\ \ \_\ \_\ + \/_/ \/_____/ \/_/ /_/ \/_/ \/_/ \/_/ \/_____/ \/_/ /_/ +` + +var version = "" +var ( + Version = version + sqlFile string + rootCmd = &cobra.Command{ + Version: Version, + Use: "fortiter", + Short: "Consume all the data", + Long: style.Purple(BANNER) + "\n", + RunE: func(cmd *cobra.Command, args []string) error { + log.SetOutput(cmd.OutOrStdout()) + + e := echo.New() + e.HideBanner = true + + // TODO: handle user interaction + e.Use(middleware.Logger()) + e.Use(middleware.Recover()) + e.Use(echoprometheus.NewMiddleware("fortiter")) + e.Static("/", "public") + + fmt.Println(style.Magenta(BANNER)) + fmt.Println(style.LightBlue("Database: ") + viper.GetString("database")) + + algodConfig := viper.GetString("data") + if algodConfig != "" { + fmt.Println(style.LightBlue("Configuration: ") + algodConfig) + } + logFile := viper.GetString("log") + if logFile != "" { + fmt.Println(style.LightBlue("Log: ") + logFile) + } + var si = fortiter.Handlers{PrometheusHandler: echoprometheus.NewHandler()} + rpc.RegisterHandlers(e, si) + + db, err := sqlx.Connect("sqlite3", viper.GetString("database")) + cobra.CheckErr(err) + + // exec the schema or fail; multi-statement Exec behavior varies between + // database drivers; pq will exec them all, sqlite3 won't, ymmv + db.MustExec(fortiter.Schema) + db.MustExec(fortiter.StatsSchema) + + err = fortiter.Sync(context.Background(), logFile, db) + cobra.CheckErr(err) + + return e.Start(":1337") + }, + } +) + +func check(err interface{}) { + if err != nil { + log.Fatal(err) + panic(err) + } +} + +// Handle global flags and set usage templates +func init() { + log.SetReportTimestamp(false) + initConfig() + // Configure Version + if Version == "" { + Version = "unknown (built from source)" + } + rootCmd.Version = Version + + // Bindings + rootCmd.PersistentFlags().StringVar(&sqlFile, "database", "fortiter.db", style.LightBlue("database file location")) + _ = viper.BindPFlag("database", rootCmd.PersistentFlags().Lookup("database")) + // Update Long Text + rootCmd.Long += + //style.Magenta("Database: ") + viper.GetViper().ConfigFileUsed() + "\n" + + style.LightBlue("Database: ") + viper.GetString("database") + + if viper.GetString("data") != "" { + rootCmd.Long += + style.Magenta("\nAlgorand Data: ") + viper.GetString("data") + } +} + +// Execute executes the root command. +func Execute() error { + return rootCmd.Execute() +} + +type AlgodConfig struct { + EndpointAddress string `json:"EndpointAddress"` +} + +func initExistingAlgod() { + algorandData, exists := os.LookupEnv("ALGORAND_DATA") + + // Load the Algorand Data Configuration + if exists && algorandData != "" { + // Placeholder for Struct + var algodConfig config.Local + + dataConfigPath := algorandData + "/config.json" + + // Open the config.json File + configFile, err := os.Open(dataConfigPath) + check(err) + + // Read the bytes of the File + byteValue, _ := io.ReadAll(configFile) + err = json.Unmarshal(byteValue, &algodConfig) + check(err) + + // Close the open handle + err = configFile.Close() + check(err) + + // Replace catchall address with localhost + if strings.Contains(algodConfig.EndpointAddress, "0.0.0.0") { + algodConfig.EndpointAddress = strings.Replace(algodConfig.EndpointAddress, "0.0.0.0", "127.0.0.1", 1) + } + + // Handle Token Path + tokenPath := algorandData + "/algod.admin.token" + + tokenFile, err := os.Open(tokenPath) + check(err) + + byteValue, err = io.ReadAll(tokenFile) + check(err) + } +} +func initConfig() { + // Load ALGORAND_DATA/config.json + algorandData, exists := os.LookupEnv("ALGORAND_DATA") + + // Load the Algorand Data Configuration + if exists && algorandData != "" { + // Placeholder for Struct + var algodConfig config.Local + + dataConfigPath := algorandData + "/config.json" + + // Open the config.json File + configFile, err := os.Open(dataConfigPath) + check(err) + + // Read the bytes of the File + byteValue, _ := io.ReadAll(configFile) + err = json.Unmarshal(byteValue, &algodConfig) + check(err) + + // Close the open handle + err = configFile.Close() + check(err) + + // Find the log file + logPath, _ := algodConfig.ResolveLogPaths(algorandData) + + // Handle Token Path + tokenPath := algorandData + "/algod.admin.token" + + tokenFile, err := os.Open(tokenPath) + check(err) + + byteValue, err = io.ReadAll(tokenFile) + check(err) + + // Set the server configuration + viper.Set("server", "http://"+algodConfig.EndpointAddress) + viper.Set("token", string(byteValue)) + viper.Set("data", dataConfigPath) + viper.Set("log", logPath) + } + +} diff --git a/daemon/fortiter.db b/daemon/fortiter.db new file mode 100644 index 00000000..887f7907 Binary files /dev/null and b/daemon/fortiter.db differ diff --git a/daemon/fortiter/agreements.go b/daemon/fortiter/agreements.go new file mode 100644 index 00000000..2d43800a --- /dev/null +++ b/daemon/fortiter/agreements.go @@ -0,0 +1,20 @@ +package fortiter + +import ( + "github.com/algorand/go-algorand/logging/logspec" + "github.com/jmoiron/sqlx" + _ "github.com/mattn/go-sqlite3" + "time" +) + +type AgreementEvent struct { + logspec.AgreementEvent + Message string `json:"msg"` + Time time.Time `json:"time"` +} + +func SaveAgreement(event AgreementEvent, db *sqlx.DB) error { + a := event.AgreementEvent + db.MustExec("INSERT INTO agreements (type, round, period, step, hash, sender, object_round, object_period, object_step, weight, weight_total, message, time) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)", a.Type, a.Round, a.Period, a.Step, a.Hash, a.Sender, a.ObjectRound, a.ObjectPeriod, a.ObjectStep, a.Weight, a.WeightTotal, event.Message, event.Time) + return nil +} diff --git a/daemon/fortiter/handlers.go b/daemon/fortiter/handlers.go new file mode 100644 index 00000000..4fa7acbf --- /dev/null +++ b/daemon/fortiter/handlers.go @@ -0,0 +1,65 @@ +package fortiter + +import ( + "fmt" + "github.com/algorandfoundation/algorun-tui/api" + "github.com/gorilla/websocket" + "github.com/jmoiron/sqlx" + "github.com/labstack/echo/v4" + "net/http" +) + +type Handlers struct { + PrometheusHandler echo.HandlerFunc + client api.ClientWithResponses + db *sqlx.DB +} + +var ( + upgrader = websocket.Upgrader{} +) + +func (h Handlers) GetAgreementEvents(c echo.Context, hash string) error { + //rows, err := h.db.NamedQuery(`SELECT * FROM agreements WHERE hash=:first_name`) + //if err != nil { + // return err + //} + return c.String(http.StatusOK, "Hello") +} + +func (h Handlers) GetStatus(c echo.Context) error { + return c.String(http.StatusOK, "Hello, World!") +} + +type LogWssMessage struct { + method string +} + +func (h Handlers) GetWs(c echo.Context) error { + ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil) + if err != nil { + return err + } + defer ws.Close() + for { + // Write + err := ws.WriteMessage(websocket.TextMessage, []byte("Hello, Client!")) + if err != nil { + break + //c.Logger().Error(err) + } + + // Read + _, msg, err := ws.ReadMessage() + if err != nil { + break + //c.Logger().Error(err) + } + fmt.Printf("{ \"message\": \"%s\" }\n", msg) + } + return nil +} + +func (h Handlers) GetMetrics(c echo.Context) error { + return h.PrometheusHandler(c) +} diff --git a/daemon/fortiter/logspec.go b/daemon/fortiter/logspec.go new file mode 100644 index 00000000..34fdbfce --- /dev/null +++ b/daemon/fortiter/logspec.go @@ -0,0 +1,101 @@ +package fortiter + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "github.com/algorand/go-algorand/logging/logspec" + "github.com/jmoiron/sqlx" + "io" + "os" + "os/exec" + "strings" + "time" +) + +func LogFile(filename *string) (io.ReadCloser, error) { + var inputStream io.ReadCloser = os.Stdin + if *filename == "" { + return inputStream, errors.New("no input file specified") + } + if *filename != "" { + f, err := os.Open(*filename) + if err != nil { + return nil, err + } + // Close the handle - we just wanted to verify it was valid + f.Close() + cmd := exec.Command("tail", "-n", "-1000", "-F", *filename) + inputStream, err = cmd.StdoutPipe() + if err != nil { + return nil, err + } + err = cmd.Start() + if err != nil { + return nil, err + } + } + return inputStream, nil +} + +func Sync(ctx context.Context, filepath string, db *sqlx.DB) error { + stats := make(map[string]Stats) + + go Watch(filepath, func(line string, lm map[string]interface{}, err error) { + if lm["Context"] != nil && lm["Context"] == "Agreement" { + if lm["Hash"] != nil { + var event logspec.AgreementEvent + dec := json.NewDecoder(strings.NewReader(line)) + _ = dec.Decode(&event) + + t, _ := time.Parse(time.RFC3339, lm["time"].(string)) + err = SaveAgreement(AgreementEvent{ + AgreementEvent: event, + Message: lm["msg"].(string), + Time: t, + }, db) + + if event.Sender != "" { + var stat Stats + stat, ok := stats[event.Sender] + if !ok { + stats[event.Sender] = Stats{ + Address: event.Sender, + Sent: 0, + Received: 0, + Failed: 0, + Success: 0, + } + stat = stats[event.Sender] + } else { + stat.Received++ + } + stat.SaveStats(*db) + } + } + } + }) + + return nil +} + +func Watch(filepath string, cb func(line string, lm map[string]interface{}, err error)) { + inputStream, err := LogFile(&filepath) + if err != nil { + cb("", make(map[string]interface{}), err) + } + scanner := bufio.NewScanner(inputStream) + for scanner.Scan() { + line := scanner.Text() + var event map[string]interface{} + dec := json.NewDecoder(strings.NewReader(line)) + err := dec.Decode(&event) + if err != nil { + cb("", event, err) + break + } else { + cb(line, event, nil) + } + } +} diff --git a/daemon/fortiter/schema.go b/daemon/fortiter/schema.go new file mode 100644 index 00000000..9eebf299 --- /dev/null +++ b/daemon/fortiter/schema.go @@ -0,0 +1,20 @@ +package fortiter + +var Schema = ` +CREATE TABLE IF NOT EXISTS agreements ( + type INTEGER, + round INTEGER, + period INTEGER, + step INTEGER, + hash TEXT, + sender TEXT, + object_round INTEGER, + object_period INTEGER, + object_step INTEGER, + weight INTEGER, + weight_total INTEGER, + + message TEXT, + time INTEGER +); +` diff --git a/daemon/fortiter/stats.go b/daemon/fortiter/stats.go new file mode 100644 index 00000000..406ceb10 --- /dev/null +++ b/daemon/fortiter/stats.go @@ -0,0 +1,41 @@ +package fortiter + +import ( + "fmt" + "github.com/jmoiron/sqlx" +) + +var StatsSchema = ` +CREATE TABLE IF NOT EXISTS stats ( + address TEXT PRIMARY KEY, + sent INTEGER, + received INTEGER, + failed INTEGER, + success INTEGER +) +` + +type Stats struct { + Address string + Sent uint64 + Received uint64 + Failed uint64 + Success uint64 +} + +func (s *Stats) String() string { + return fmt.Sprintf("Address: %s\nSent: %d\nReceived: %d\nFailed: %d\nSuccess: %d\n", + s.Address, s.Sent, s.Received, s.Failed, s.Success) +} + +func (s *Stats) SaveStats(db sqlx.DB) error { + var stats Stats + err := db.Get(&stats, "SELECT * FROM stats WHERE address = ?", s.Address) + if err != nil { + db.MustExec("INSERT INTO stats (address, sent, received, failed, success) VALUES (?, ?, ?, ?, ?)", s.Address, s.Sent, s.Received, s.Failed, s.Success) + } else { + db.MustExec("UPDATE stats SET sent = ?, received = ?, failed = ?, success = ? WHERE address = ?", + s.Sent, s.Received, s.Failed, s.Success, s.Address) + } + return nil +} diff --git a/daemon/generate.yaml b/daemon/generate.yaml new file mode 100644 index 00000000..6ef41060 --- /dev/null +++ b/daemon/generate.yaml @@ -0,0 +1,2 @@ +package: rpc +output: ./rpc/gen.go \ No newline at end of file diff --git a/daemon/main.go b/daemon/main.go new file mode 100644 index 00000000..ca7cf3e6 --- /dev/null +++ b/daemon/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/algorandfoundation/algorun-tui/daemon/cmd" +) + +var version = "development" + +// main initializes the Echo framework, hides its default startup banner, prints a custom BANNER, +// registers the HTTP handlers, starts the algod process, and begins listening for HTTP requests on port 1323. +func main() { + fmt.Println("Algorun TUI") + fmt.Println("Version:", version) + err := cmd.Execute() + if err != nil { + return + } +} diff --git a/daemon/migrations/.gitkeep b/daemon/migrations/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/daemon/oas3.schema.yaml b/daemon/oas3.schema.yaml new file mode 100644 index 00000000..a4d9d35d --- /dev/null +++ b/daemon/oas3.schema.yaml @@ -0,0 +1,86 @@ +openapi: 3.0.1 +info: + contact: + name: Algonode.io + url: https://algonode.io/contact + description: API endpoint for algod operations. + title: Algod REST API. + version: '3.16' +servers: + - url: http://localhost:1337/ + - url: https://mainnet-api.algonode.cloud/ + - url: https://testnet-api.algonode.cloud/ + - url: https://betanet-api.algonode.cloud/ +paths: + /metrics: + get: + operationId: getMetrics + responses: + '200': + content: + application/text: + schema: + type: string + description: Prometheus Exposition Endpoint + /agreement/{hash}: + get: + operationId: getAgreementEvents + parameters: + - name: hash + in: path + description: 'Hash to lookup' + required: true + schema: + type: string + responses: + '200': + content: + application/json: + schema: + type: string + description: Get Agreement events by Hash + /ws: + get: + operationId: getWs + responses: + '200': + content: + application/json: + schema: + type: string + description: Stuff + /status: + get: + operationId: getStatus + summary: Retrieve current status + responses: + '200': + description: Respond with Status + content: + application/json: + schema: + $ref: "#/components/schemas/Status" +components: + schemas: + Status: + type: object + description: A status response + properties: + state: + type: string + description: The state of the node + version: + type: string + description: Version reported by the node + network: + type: string + description: Network ID + voting: + type: boolean + description: If the network is voting on an upgrade + needsUpdate: + type: boolean + description: If the node requires and update + lastRound: + type: number + description: Last round the status has knowledge of \ No newline at end of file diff --git a/daemon/public/favicon.ico b/daemon/public/favicon.ico new file mode 100644 index 00000000..a8b07957 Binary files /dev/null and b/daemon/public/favicon.ico differ diff --git a/daemon/public/index.html b/daemon/public/index.html new file mode 100644 index 00000000..e9901162 --- /dev/null +++ b/daemon/public/index.html @@ -0,0 +1,34 @@ + + + + + + WebSocket + + + +

+ + + + + \ No newline at end of file diff --git a/daemon/rpc/gen.go b/daemon/rpc/gen.go new file mode 100644 index 00000000..3534699e --- /dev/null +++ b/daemon/rpc/gen.go @@ -0,0 +1,228 @@ +// Package rpc provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.2.0 DO NOT EDIT. +package rpc + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "fmt" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/labstack/echo/v4" + "github.com/oapi-codegen/runtime" +) + +// Status A status response +type Status struct { + // LastRound Last round the status has knowledge of + LastRound *float32 `json:"lastRound,omitempty"` + + // NeedsUpdate If the node requires and update + NeedsUpdate *bool `json:"needsUpdate,omitempty"` + + // Network Network ID + Network *string `json:"network,omitempty"` + + // State The state of the node + State *string `json:"state,omitempty"` + + // Version Version reported by the node + Version *string `json:"version,omitempty"` + + // Voting If the network is voting on an upgrade + Voting *bool `json:"voting,omitempty"` +} + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /agreement/{hash}) + GetAgreementEvents(ctx echo.Context, hash string) error + + // (GET /metrics) + GetMetrics(ctx echo.Context) error + // Retrieve current status + // (GET /status) + GetStatus(ctx echo.Context) error + + // (GET /ws) + GetWs(ctx echo.Context) error +} + +// ServerInterfaceWrapper converts echo contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface +} + +// GetAgreementEvents converts echo context to params. +func (w *ServerInterfaceWrapper) GetAgreementEvents(ctx echo.Context) error { + var err error + // ------------- Path parameter "hash" ------------- + var hash string + + err = runtime.BindStyledParameterWithOptions("simple", "hash", ctx.Param("hash"), &hash, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter hash: %s", err)) + } + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetAgreementEvents(ctx, hash) + return err +} + +// GetMetrics converts echo context to params. +func (w *ServerInterfaceWrapper) GetMetrics(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetMetrics(ctx) + return err +} + +// GetStatus converts echo context to params. +func (w *ServerInterfaceWrapper) GetStatus(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetStatus(ctx) + return err +} + +// GetWs converts echo context to params. +func (w *ServerInterfaceWrapper) GetWs(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.GetWs(ctx) + return err +} + +// This is a simple interface which specifies echo.Route addition functions which +// are present on both echo.Echo and echo.Group, since we want to allow using +// either of them for path registration +type EchoRouter interface { + CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route + TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route +} + +// RegisterHandlers adds each server route to the EchoRouter. +func RegisterHandlers(router EchoRouter, si ServerInterface) { + RegisterHandlersWithBaseURL(router, si, "") +} + +// Registers handlers, and prepends BaseURL to the paths, so that the paths +// can be served under a prefix. +func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) { + + wrapper := ServerInterfaceWrapper{ + Handler: si, + } + + router.GET(baseURL+"/agreement/:hash", wrapper.GetAgreementEvents) + router.GET(baseURL+"/metrics", wrapper.GetMetrics) + router.GET(baseURL+"/status", wrapper.GetStatus) + router.GET(baseURL+"/ws", wrapper.GetWs) + +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "H4sIAAAAAAAC/6RUXW/bOgz9KwTvffSN21vgXsBvARZ0AbahaLvtYeiDYjGxWlvUJDppEfi/D1JsB8hH", + "t6Jvgnh4eHhEcYslN44tWQlYbDGUFTUqHe9ESZtOmkLpjRPDFgucQkgR8BQc20CYofPsyIuhhK9VkFtu", + "rT5O/qSCgI8xkIoGpkoFeLK8qUmvCHiJGcqLIyzQts2CPHYZWiIdvjqthI5p58tEZ1kTePrZGk8BlNXQ", + "7hJGvgVzTcruCGXD/umY7MsuAPMP+7wg3thVTIuSTyi477uJ8kctp/LX5ENKOWT4tguAJ8deSMPi5XUi", + "lng660XfhQmwQwJbUBZat/JKn7KkG6948UilYBevjF1yLFKyFVVKPFrVRNS0XnEUNzGMGba+xgIrEReK", + "PFf7WD5kdtnhJN3Mgax2bKzAkj3ELA1xlFSEhElUaaQeqmm4nd3dw/RmHiOjk3g1ufwv0rMjq5xJNxeT", + "yziYSqo0k7laeaKGrOTbSoWqi5crSv2MBecaC7wmmQ7Y2Tp9jMjjVUNCPmDx49DxjypUIAw181PrMHqG", + "RSqN2WBWrIkZ9sOpsRDfUtb/tyji4H27hwjefbDUwL8XF8MzkE2ylXO1KZPw/DHsRuo835H71yQwNgqU", + "Oo0zF7uJ+C7DvCHxpgyvefW5h7xJrtCzvFHujeeGpKI2wOzZcTDxHmb9+AyCw7i0zunt19o73f3b0xIL", + "/Cvfr8+83515X+FED7eppIaNkQpGWIahbRrlXxJCvKE1Qdl6H98l7FH55tXGvr+7qd++wZ20y2WyOoom", + "vx7+w/7zF3lec6nqioMUl1dX/+fYZduD7dAoYy3JP8qZybgpyppbfQotFOTP0QsSdRb90P0KAAD//34V", + "Tl3xBgAA", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/go.mod b/go.mod index 7134e0ea..1c2f7342 100644 --- a/go.mod +++ b/go.mod @@ -1,17 +1,24 @@ module github.com/algorandfoundation/algorun-tui -go 1.22.0 +go 1.23 -toolchain go1.23.1 +toolchain go1.23.3 require ( + github.com/algorand/go-algorand v0.0.0-20241210191903-f87ae8a83df0 github.com/algorandfoundation/algourl v0.0.0-20241023193235-8bbf72ad0b37 github.com/charmbracelet/bubbles v0.20.0 github.com/charmbracelet/bubbletea v1.1.1 github.com/charmbracelet/lipgloss v0.13.1 github.com/charmbracelet/log v0.4.0 github.com/charmbracelet/x/exp/teatest v0.0.0-20241022174419-46d9bb99a691 + github.com/getkin/kin-openapi v0.127.0 + github.com/gorilla/websocket v1.5.3 + github.com/jmoiron/sqlx v1.4.0 + github.com/labstack/echo-contrib v0.17.1 + github.com/labstack/echo/v4 v4.12.0 github.com/manifoldco/promptui v0.9.0 + github.com/mattn/go-sqlite3 v1.14.24 github.com/oapi-codegen/oapi-codegen/v2 v2.4.1 github.com/oapi-codegen/runtime v1.1.1 github.com/spf13/cobra v1.8.1 @@ -20,10 +27,42 @@ require ( ) require ( + github.com/algorand/go-deadlock v0.2.4 // indirect + github.com/algorand/msgp v1.1.60 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/josharian/native v1.1.0 // indirect + github.com/jsimonetti/rtnetlink v1.4.2 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/labstack/gommon v0.4.2 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mdlayher/netlink v1.7.2 // indirect + github.com/mdlayher/socket v0.4.1 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + github.com/prometheus/client_golang v1.20.5 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.60.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + go.opencensus.io v0.24.0 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/protobuf v1.35.1 // indirect ) require ( @@ -64,11 +103,11 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0b57cc4a..d3209058 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,18 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= +github.com/algorand/go-algorand v0.0.0-20241210191903-f87ae8a83df0 h1:BhP29Vz4Mc+vBaKvGmFJXOPd6r9BMf8vDFC9vXD0CoY= +github.com/algorand/go-algorand v0.0.0-20241210191903-f87ae8a83df0/go.mod h1:TkqTtafNw3U8TLpRUdGNwgptFY7lJ+R5t5CfT90r81Q= github.com/algorand/go-algorand-sdk/v2 v2.6.0 h1:pfL8lloEi26l6PwAFicmPUguWgKpy1eZZTMlQcci5h0= github.com/algorand/go-algorand-sdk/v2 v2.6.0/go.mod h1:4ayerzjoWChm3kuVhbgFgURTbaYTtlj0c41eP3av5lw= github.com/algorand/go-codec/codec v1.1.10 h1:zmWYU1cp64jQVTOG8Tw8wa+k0VfwgXIPbnDfiVa+5QA= github.com/algorand/go-codec/codec v1.1.10/go.mod h1:YkEx5nmr/zuCeaDYOIhlDg92Lxju8tj2d2NrYqP7g7k= +github.com/algorand/go-deadlock v0.2.4 h1:UMs6GwE2wHC6BUZo5z32/+SrBey1LQjbkZQ3V7DoGVA= +github.com/algorand/go-deadlock v0.2.4/go.mod h1:tewhAviZpVq2cnGHmfT50l6RwWLnuygnfNntCN2fz0M= +github.com/algorand/msgp v1.1.60 h1:+IVUC34+tSj1P2M1mkYtl4GLyfzdzXfBLSw6TDT19M8= +github.com/algorand/msgp v1.1.60/go.mod h1:RqZQBzAFDWpwh5TlabzZkWy+6kwL9cvXfLbU0gD99EA= github.com/algorandfoundation/algourl v0.0.0-20241023193235-8bbf72ad0b37 h1:zt00SDlTcFiYPvq+Wo/ZDmRwM2gBRW/VhOQ/zaplBAk= github.com/algorandfoundation/algourl v0.0.0-20241023193235-8bbf72ad0b37/go.mod h1:o91gtX3JDwJpS10P5cm6dwUsArtNtX+3kDshhelHTJ8= github.com/algorandfoundation/go-tinyqr v0.0.0-20241018103413-2082a3d637eb h1:NFKjd5BKatUpYUXiofxvWd0VqVoinsVzugtQw/W+vKs= @@ -11,11 +21,18 @@ github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7D github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/aws/aws-sdk-go v1.34.0 h1:brux2dRrlwCF5JhTL7MUT3WUwo9zfDHZZp3+g3Mvlmo= +github.com/aws/aws-sdk-go v1.34.0/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY= @@ -38,67 +55,160 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5O github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.12.3 h1:8ht6F9MquybnY97at+VDZb3eQQr8ev79RueWeVaEcG4= +github.com/cilium/ebpf v0.12.3/go.mod h1:TctK1ivibvI3znr66ljgi4hqOT8EYQjz1KWBfb1UVgM= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= +github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= +github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= +github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= +github.com/jsimonetti/rtnetlink v1.4.2 h1:Df9w9TZ3npHTyDn0Ev9e1uzmN2odmXd0QX+J5GTEn90= +github.com/jsimonetti/rtnetlink v1.4.2/go.mod h1:92s6LJdE+1iOrw+F2/RO7LYI2Qd8pPpFNNUYW06gcoM= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo-contrib v0.17.1 h1:7I/he7ylVKsDUieaGRZ9XxxTYOjfQwVzHzUYrNykfCU= +github.com/labstack/echo-contrib v0.17.1/go.mod h1:SnsCZtwHBAZm5uBSAtQtXQHI3wqEA73hvTn0bYMKnZA= +github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= +github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= +github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= +github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= +github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a h1:2MaM6YC3mGu54x+RKAA6JiFFHlHDY1UbkxqppT7wYOg= github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/oapi-codegen/oapi-codegen/v2 v2.4.1 h1:ykgG34472DWey7TSjd8vIfNykXgjOgYJZoQbKfEeY/Q= github.com/oapi-codegen/oapi-codegen/v2 v2.4.1/go.mod h1:N5+lY1tiTDV3V1BeHtOxeWXHoPVeApvsvjJqegfoaz8= github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 h1:qli3BGQK0tYDkSEvZ/FzZTi9ZrOX86Q6CIhKLGc489A= +github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -123,56 +233,121 @@ github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +pgregory.net/rapid v0.6.2 h1:ErW5sL+UKtfBfUTsWHDCoeB+eZKLKMxrSd1VJY6W4bw= +pgregory.net/rapid v0.6.2/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/internal/README.md b/internal/nodekit/README.md similarity index 100% rename from internal/README.md rename to internal/nodekit/README.md diff --git a/internal/accounts.go b/internal/nodekit/accounts.go similarity index 99% rename from internal/accounts.go rename to internal/nodekit/accounts.go index 28d815fe..1dacee91 100644 --- a/internal/accounts.go +++ b/internal/nodekit/accounts.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "bytes" diff --git a/internal/accounts_test.go b/internal/nodekit/accounts_test.go similarity index 99% rename from internal/accounts_test.go rename to internal/nodekit/accounts_test.go index e1f23e82..0f04210a 100644 --- a/internal/accounts_test.go +++ b/internal/nodekit/accounts_test.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/block.go b/internal/nodekit/block.go similarity index 98% rename from internal/block.go rename to internal/nodekit/block.go index 8ca8d54e..2d4794b1 100644 --- a/internal/block.go +++ b/internal/nodekit/block.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/block_test.go b/internal/nodekit/block_test.go similarity index 97% rename from internal/block_test.go rename to internal/nodekit/block_test.go index 5b39feed..fadacfa0 100644 --- a/internal/block_test.go +++ b/internal/nodekit/block_test.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/github.go b/internal/nodekit/github.go similarity index 97% rename from internal/github.go rename to internal/nodekit/github.go index 87abc699..1fd56302 100644 --- a/internal/github.go +++ b/internal/nodekit/github.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "encoding/json" diff --git a/internal/github_test.go b/internal/nodekit/github_test.go similarity index 98% rename from internal/github_test.go rename to internal/nodekit/github_test.go index 8b0b1d40..91c4fa32 100644 --- a/internal/github_test.go +++ b/internal/nodekit/github_test.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "bytes" diff --git a/internal/http.go b/internal/nodekit/http.go similarity index 93% rename from internal/http.go rename to internal/nodekit/http.go index 9f2fc57f..f27f3aaa 100644 --- a/internal/http.go +++ b/internal/nodekit/http.go @@ -1,4 +1,4 @@ -package internal +package nodekit import "net/http" diff --git a/internal/metrics.go b/internal/nodekit/metrics.go similarity index 98% rename from internal/metrics.go rename to internal/nodekit/metrics.go index c3bd98b0..54928ade 100644 --- a/internal/metrics.go +++ b/internal/nodekit/metrics.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/metrics_test.go b/internal/nodekit/metrics_test.go similarity index 99% rename from internal/metrics_test.go rename to internal/nodekit/metrics_test.go index 7cf091d9..383215cf 100644 --- a/internal/metrics_test.go +++ b/internal/nodekit/metrics_test.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/participation.go b/internal/nodekit/participation.go similarity index 99% rename from internal/participation.go rename to internal/nodekit/participation.go index 55b0594d..62ca7de3 100644 --- a/internal/participation.go +++ b/internal/nodekit/participation.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/participation_test.go b/internal/nodekit/participation_test.go similarity index 99% rename from internal/participation_test.go rename to internal/nodekit/participation_test.go index 55bac2d0..cca4727e 100644 --- a/internal/participation_test.go +++ b/internal/nodekit/participation_test.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/rangetype.go b/internal/nodekit/rangetype.go similarity index 85% rename from internal/rangetype.go rename to internal/nodekit/rangetype.go index 10e8497f..7f704ad2 100644 --- a/internal/rangetype.go +++ b/internal/nodekit/rangetype.go @@ -1,4 +1,4 @@ -package internal +package nodekit type RangeType string diff --git a/internal/state.go b/internal/nodekit/state.go similarity index 99% rename from internal/state.go rename to internal/nodekit/state.go index 0db012b3..2b44a4c5 100644 --- a/internal/state.go +++ b/internal/nodekit/state.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/state_test.go b/internal/nodekit/state_test.go similarity index 98% rename from internal/state_test.go rename to internal/nodekit/state_test.go index a3f19e45..dad50b77 100644 --- a/internal/state_test.go +++ b/internal/nodekit/state_test.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/status.go b/internal/nodekit/status.go similarity index 99% rename from internal/status.go rename to internal/nodekit/status.go index adb2c25a..3732c651 100644 --- a/internal/status.go +++ b/internal/nodekit/status.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/status_test.go b/internal/nodekit/status_test.go similarity index 98% rename from internal/status_test.go rename to internal/nodekit/status_test.go index e8d969bd..0a5faac1 100644 --- a/internal/status_test.go +++ b/internal/nodekit/status_test.go @@ -1,4 +1,4 @@ -package internal +package nodekit import ( "context" diff --git a/internal/time.go b/internal/nodekit/time.go similarity index 88% rename from internal/time.go rename to internal/nodekit/time.go index eb3fa8fb..6e862cbc 100644 --- a/internal/time.go +++ b/internal/nodekit/time.go @@ -1,4 +1,4 @@ -package internal +package nodekit import "time" diff --git a/ui/app/accounts.go b/ui/app/accounts.go index 1287fac4..0761c048 100644 --- a/ui/app/accounts.go +++ b/ui/app/accounts.go @@ -1,14 +1,14 @@ package app import ( - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" tea "github.com/charmbracelet/bubbletea" ) -type AccountSelected internal.Account +type AccountSelected nodekit.Account // EmitAccountSelected waits for and retrieves a new set of table rows from a given channel. -func EmitAccountSelected(account internal.Account) tea.Cmd { +func EmitAccountSelected(account nodekit.Account) tea.Cmd { return func() tea.Msg { return AccountSelected(account) } diff --git a/ui/app/app_test.go b/ui/app/app_test.go index 90ce2deb..e1096c16 100644 --- a/ui/app/app_test.go +++ b/ui/app/app_test.go @@ -2,7 +2,7 @@ package app import ( "context" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/internal/test" uitest "github.com/algorandfoundation/algorun-tui/ui/internal/test" "testing" @@ -11,7 +11,7 @@ import ( func Test_GenerateCmd(t *testing.T) { client := test.GetClient(false) - fn := GenerateCmd("ABC", internal.TimeRange, int(time.Second*60), uitest.GetState(client)) + fn := GenerateCmd("ABC", nodekit.TimeRange, int(time.Second*60), uitest.GetState(client)) res := fn() evt, ok := res.(ModalEvent) if !ok { @@ -22,7 +22,7 @@ func Test_GenerateCmd(t *testing.T) { } client = test.GetClient(true) - fn = GenerateCmd("ABC", internal.TimeRange, int(time.Second*60), uitest.GetState(client)) + fn = GenerateCmd("ABC", nodekit.TimeRange, int(time.Second*60), uitest.GetState(client)) res = fn() evt, ok = res.(ModalEvent) if !ok { diff --git a/ui/app/keys.go b/ui/app/keys.go index f5eb4ead..7d73b721 100644 --- a/ui/app/keys.go +++ b/ui/app/keys.go @@ -2,10 +2,10 @@ package app import ( "context" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "time" "github.com/algorandfoundation/algorun-tui/api" - "github.com/algorandfoundation/algorun-tui/internal" tea "github.com/charmbracelet/bubbletea" ) @@ -18,7 +18,7 @@ type DeleteKey *api.ParticipationKey func EmitDeleteKey(ctx context.Context, client api.ClientWithResponsesInterface, id string) tea.Cmd { return func() tea.Msg { - err := internal.DeletePartKey(ctx, client, id) + err := nodekit.DeletePartKey(ctx, client, id) if err != nil { return DeleteFinished{ Err: &err, @@ -32,11 +32,11 @@ func EmitDeleteKey(ctx context.Context, client api.ClientWithResponsesInterface, } } -func GenerateCmd(account string, rangeType internal.RangeType, duration int, state *internal.StateModel) tea.Cmd { +func GenerateCmd(account string, rangeType nodekit.RangeType, duration int, state *nodekit.StateModel) tea.Cmd { return func() tea.Msg { var params api.GenerateParticipationKeysParams - if rangeType == internal.TimeRange { + if rangeType == nodekit.TimeRange { params = api.GenerateParticipationKeysParams{ Dilution: nil, First: int(state.Status.LastRound), @@ -50,7 +50,7 @@ func GenerateCmd(account string, rangeType internal.RangeType, duration int, sta } } - key, err := internal.GenerateKeyPair(state.Context, state.Client, account, ¶ms) + key, err := nodekit.GenerateKeyPair(state.Context, state.Client, account, ¶ms) if err != nil { return ModalEvent{ Key: nil, diff --git a/ui/internal/test/state.go b/ui/internal/test/state.go index 3f159e95..f6536828 100644 --- a/ui/internal/test/state.go +++ b/ui/internal/test/state.go @@ -3,22 +3,22 @@ package test import ( "context" "github.com/algorandfoundation/algorun-tui/api" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" mock2 "github.com/algorandfoundation/algorun-tui/internal/test/mock" "time" ) -func GetState(client api.ClientWithResponsesInterface) *internal.StateModel { - sm := &internal.StateModel{ - Status: internal.StatusModel{ - State: internal.StableState, +func GetState(client api.ClientWithResponsesInterface) *nodekit.StateModel { + sm := &nodekit.StateModel{ + Status: nodekit.StatusModel{ + State: nodekit.StableState, Version: "v-test", Network: "v-test-network", Voting: false, NeedsUpdate: false, LastRound: 0, }, - Metrics: internal.MetricsModel{ + Metrics: nodekit.MetricsModel{ Enabled: true, Window: 100, RoundTime: time.Second * 2, @@ -36,11 +36,11 @@ func GetState(client api.ClientWithResponsesInterface) *internal.StateModel { Client: client, Context: context.Background(), } - values := make(map[string]internal.Account) + values := make(map[string]nodekit.Account) for _, key := range *sm.ParticipationKeys { val, ok := values[key.Address] if !ok { - values[key.Address] = internal.Account{ + values[key.Address] = nodekit.Account{ Address: key.Address, Status: "Offline", Balance: 0, diff --git a/ui/modal/controller.go b/ui/modal/controller.go index 06a698ed..d8eb14d2 100644 --- a/ui/modal/controller.go +++ b/ui/modal/controller.go @@ -1,7 +1,7 @@ package modal import ( - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/app" "github.com/algorandfoundation/algorun-tui/ui/modals/generate" "github.com/algorandfoundation/algorun-tui/ui/style" @@ -28,7 +28,7 @@ func (m ViewModel) HandleMessage(msg tea.Msg) (*ViewModel, tea.Cmd) { m.Open = true m.exceptionModal.Message = msg.Error() m.SetType(app.ExceptionModal) - case internal.StateModel: + case nodekit.StateModel: m.State = &msg m.transactionModal.State = &msg m.infoModal.State = &msg diff --git a/ui/modal/model.go b/ui/modal/model.go index b720886d..d48a5d3e 100644 --- a/ui/modal/model.go +++ b/ui/modal/model.go @@ -2,7 +2,7 @@ package modal import ( "github.com/algorandfoundation/algorun-tui/api" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/app" "github.com/algorandfoundation/algorun-tui/ui/modals/confirm" "github.com/algorandfoundation/algorun-tui/ui/modals/exception" @@ -22,7 +22,7 @@ type ViewModel struct { Height int // State for Context/Client - State *internal.StateModel + State *nodekit.StateModel // Address defines the string format address of the entity Address string @@ -82,7 +82,7 @@ func (m *ViewModel) SetType(modal app.ModalType) { } } -func New(parent string, open bool, state *internal.StateModel) *ViewModel { +func New(parent string, open bool, state *nodekit.StateModel) *ViewModel { return &ViewModel{ Parent: parent, Open: open, diff --git a/ui/modals/confirm/confirm.go b/ui/modals/confirm/confirm.go index 62b016f5..71b41128 100644 --- a/ui/modals/confirm/confirm.go +++ b/ui/modals/confirm/confirm.go @@ -2,7 +2,7 @@ package confirm import ( "github.com/algorandfoundation/algorun-tui/api" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/app" "github.com/algorandfoundation/algorun-tui/ui/style" tea "github.com/charmbracelet/bubbletea" @@ -16,10 +16,10 @@ type ViewModel struct { Controls string BorderColor string ActiveKey *api.ParticipationKey - Data *internal.StateModel + Data *nodekit.StateModel } -func New(state *internal.StateModel) *ViewModel { +func New(state *nodekit.StateModel) *ViewModel { return &ViewModel{ Width: 0, Height: 0, diff --git a/ui/modals/generate/controller.go b/ui/modals/generate/controller.go index 2df09791..72ddf84e 100644 --- a/ui/modals/generate/controller.go +++ b/ui/modals/generate/controller.go @@ -1,10 +1,10 @@ package generate import ( + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "strconv" "time" - "github.com/algorandfoundation/algorun-tui/internal" "github.com/algorandfoundation/algorun-tui/ui/app" "github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/textinput" @@ -76,7 +76,7 @@ func (m ViewModel) HandleMessage(msg tea.Msg) (*ViewModel, tea.Cmd) { switch m.Step { case AddressStep: addr := m.Input.Value() - if !internal.ValidateAddress(addr) { + if !nodekit.ValidateAddress(addr) { m.InputError = "Error: invalid address" return &m, nil } @@ -91,18 +91,18 @@ func (m ViewModel) HandleMessage(msg tea.Msg) (*ViewModel, tea.Cmd) { } m.InputTwoError = "" m.SetStep(WaitingStep) - var rangeType internal.RangeType + var rangeType nodekit.RangeType var dur int switch m.Range { case Day: dur = int(time.Hour*24) * val - rangeType = internal.TimeRange + rangeType = nodekit.TimeRange case Month: dur = int(time.Hour*24*30) * val - rangeType = internal.TimeRange + rangeType = nodekit.TimeRange case Round: dur = val - rangeType = internal.RoundRange + rangeType = nodekit.RoundRange } return &m, tea.Sequence(app.EmitShowModal(app.GenerateModal), app.GenerateCmd(m.Input.Value(), rangeType, dur, m.State)) diff --git a/ui/modals/generate/model.go b/ui/modals/generate/model.go index 3abf78f2..5bc2beb1 100644 --- a/ui/modals/generate/model.go +++ b/ui/modals/generate/model.go @@ -1,7 +1,7 @@ package generate import ( - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/charmbracelet/bubbles/cursor" "github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/textinput" @@ -40,7 +40,7 @@ type ViewModel struct { Controls string BorderColor string - State *internal.StateModel + State *nodekit.StateModel cursorMode cursor.Mode } @@ -53,7 +53,7 @@ var DefaultControls = "( esc to cancel )" var DefaultTitle = "Generate Consensus Participation Keys" var DefaultBorderColor = "2" -func New(address string, state *internal.StateModel) *ViewModel { +func New(address string, state *nodekit.StateModel) *ViewModel { input := textinput.New() input2 := textinput.New() diff --git a/ui/modals/info/info.go b/ui/modals/info/info.go index cbe80cec..edf086c4 100644 --- a/ui/modals/info/info.go +++ b/ui/modals/info/info.go @@ -2,7 +2,7 @@ package info import ( "github.com/algorandfoundation/algorun-tui/api" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/app" "github.com/algorandfoundation/algorun-tui/ui/style" "github.com/algorandfoundation/algorun-tui/ui/utils" @@ -19,10 +19,10 @@ type ViewModel struct { BorderColor string Active bool Participation *api.ParticipationKey - State *internal.StateModel + State *nodekit.StateModel } -func New(state *internal.StateModel) *ViewModel { +func New(state *nodekit.StateModel) *ViewModel { return &ViewModel{ Width: 0, Height: 0, diff --git a/ui/modals/transaction/controller.go b/ui/modals/transaction/controller.go index 0ff7b1b1..07d1350f 100644 --- a/ui/modals/transaction/controller.go +++ b/ui/modals/transaction/controller.go @@ -3,7 +3,7 @@ package transaction import ( "encoding/base64" "github.com/algorand/go-algorand-sdk/v2/types" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/app" "github.com/algorandfoundation/algourl/encoder" tea "github.com/charmbracelet/bubbletea" @@ -43,7 +43,7 @@ func (m ViewModel) HandleMessage(msg tea.Msg) (*ViewModel, tea.Cmd) { m.UpdateState() return &m, cmd } -func (m *ViewModel) Account() *internal.Account { +func (m *ViewModel) Account() *nodekit.Account { if m.Participation == nil || m.State == nil || m.State.Accounts == nil { return nil } diff --git a/ui/modals/transaction/model.go b/ui/modals/transaction/model.go index dadba88b..cadeae34 100644 --- a/ui/modals/transaction/model.go +++ b/ui/modals/transaction/model.go @@ -3,7 +3,7 @@ package transaction import ( "fmt" "github.com/algorandfoundation/algorun-tui/api" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/style" "github.com/algorandfoundation/algourl/encoder" ) @@ -21,7 +21,7 @@ type ViewModel struct { Active bool // Pointer to the State - State *internal.StateModel + State *nodekit.StateModel IsOnline bool // Components @@ -38,7 +38,7 @@ func (m ViewModel) FormatedAddress() string { } // New creates and instance of the ViewModel with a default controls.Model -func New(state *internal.StateModel) *ViewModel { +func New(state *nodekit.StateModel) *ViewModel { return &ViewModel{ State: state, Title: "Offline Transaction", diff --git a/ui/modals/transaction/view.go b/ui/modals/transaction/view.go index b5201a31..2e86f3e8 100644 --- a/ui/modals/transaction/view.go +++ b/ui/modals/transaction/view.go @@ -1,7 +1,7 @@ package transaction import ( - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/style" "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/x/ansi" @@ -29,7 +29,7 @@ func (m ViewModel) View() string { } intro := "Sign this transaction to " + verb + " your account keys:" - link, _ := internal.ToLoraDeepLink(m.State.Status.Network, m.Active, m.Account().IncentiveEligible, *m.Participation) + link, _ := nodekit.ToLoraDeepLink(m.State.Status.Network, m.Active, m.Account().IncentiveEligible, *m.Participation) loraText := lipgloss.JoinHorizontal( lipgloss.Bottom, style.WithHyperlink("Click here", link), diff --git a/ui/pages/accounts/accounts_test.go b/ui/pages/accounts/accounts_test.go index 5866a145..bca987f1 100644 --- a/ui/pages/accounts/accounts_test.go +++ b/ui/pages/accounts/accounts_test.go @@ -2,7 +2,7 @@ package accounts import ( "bytes" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/internal/test" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/x/ansi" @@ -13,7 +13,7 @@ import ( ) func Test_New(t *testing.T) { - m := New(&internal.StateModel{}) + m := New(&nodekit.StateModel{}) acc := m.SelectedAccount() if acc != nil { @@ -42,9 +42,9 @@ func Test_New(t *testing.T) { } // Update syncing state - m.Data.Status.State = internal.SyncingState + m.Data.Status.State = nodekit.SyncingState m.makeRows() - if m.Data.Status.State != internal.SyncingState { + if m.Data.Status.State != nodekit.SyncingState { } } diff --git a/ui/pages/accounts/controller.go b/ui/pages/accounts/controller.go index e879be29..ff618be8 100644 --- a/ui/pages/accounts/controller.go +++ b/ui/pages/accounts/controller.go @@ -1,7 +1,7 @@ package accounts import ( - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/app" "github.com/algorandfoundation/algorun-tui/ui/style" tea "github.com/charmbracelet/bubbletea" @@ -18,7 +18,7 @@ func (m ViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m ViewModel) HandleMessage(msg tea.Msg) (ViewModel, tea.Cmd) { switch msg := msg.(type) { - case internal.StateModel: + case nodekit.StateModel: m.Data = &msg m.table.SetRows(*m.makeRows()) case tea.KeyMsg: diff --git a/ui/pages/accounts/model.go b/ui/pages/accounts/model.go index c565a130..0a6430b0 100644 --- a/ui/pages/accounts/model.go +++ b/ui/pages/accounts/model.go @@ -1,18 +1,18 @@ package accounts import ( + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/style" "sort" "strconv" "time" - "github.com/algorandfoundation/algorun-tui/internal" "github.com/charmbracelet/bubbles/table" "github.com/charmbracelet/lipgloss" ) type ViewModel struct { - Data *internal.StateModel + Data *nodekit.StateModel Title string Navigation string @@ -24,7 +24,7 @@ type ViewModel struct { table table.Model } -func New(state *internal.StateModel) ViewModel { +func New(state *nodekit.StateModel) ViewModel { m := ViewModel{ Title: "Accounts", Width: 0, @@ -54,8 +54,8 @@ func New(state *internal.StateModel) ViewModel { return m } -func (m ViewModel) SelectedAccount() *internal.Account { - var account *internal.Account +func (m ViewModel) SelectedAccount() *nodekit.Account { + var account *nodekit.Account var selectedRow = m.table.SelectedRow() if selectedRow != nil { selectedAccount := m.Data.Accounts[selectedRow[0]] @@ -95,7 +95,7 @@ func (m ViewModel) makeRows() *[]table.Row { } // Override the state while syncing - if m.Data.Status.State != internal.StableState { + if m.Data.Status.State != nodekit.StableState { expires = "SYNCING" } diff --git a/ui/pages/keys/controller.go b/ui/pages/keys/controller.go index 1a1f2e6c..9b4365aa 100644 --- a/ui/pages/keys/controller.go +++ b/ui/pages/keys/controller.go @@ -1,7 +1,7 @@ package keys import ( - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/app" "github.com/algorandfoundation/algorun-tui/ui/style" tea "github.com/charmbracelet/bubbletea" @@ -19,7 +19,7 @@ func (m ViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m ViewModel) HandleMessage(msg tea.Msg) (ViewModel, tea.Cmd) { switch msg := msg.(type) { // When the State changes - case internal.StateModel: + case nodekit.StateModel: m.Data = msg.ParticipationKeys m.table.SetRows(*m.makeRows(m.Data)) m.Participation = msg.Accounts[m.Address].Participation @@ -30,7 +30,7 @@ func (m ViewModel) HandleMessage(msg tea.Msg) (ViewModel, tea.Cmd) { m.table.SetRows(*m.makeRows(m.Data)) // When a confirmation Modal is finished deleting case app.DeleteFinished: - internal.RemovePartKeyByID(m.Data, msg.Id) + nodekit.RemovePartKeyByID(m.Data, msg.Id) m.table.SetRows(*m.makeRows(m.Data)) // When the user interacts with the render case tea.KeyMsg: diff --git a/ui/pages/keys/model.go b/ui/pages/keys/model.go index b95bb28e..07764954 100644 --- a/ui/pages/keys/model.go +++ b/ui/pages/keys/model.go @@ -1,7 +1,7 @@ package keys import ( - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "sort" "github.com/algorandfoundation/algorun-tui/ui/style" @@ -127,7 +127,7 @@ func (m ViewModel) makeRows(keys *[]api.ParticipationKey) *[]table.Row { var activeId *string if m.Participation != nil { - activeId = internal.FindParticipationIdForVoteKey(keys, m.Participation.VoteParticipationKey) + activeId = nodekit.FindParticipationIdForVoteKey(keys, m.Participation.VoteParticipationKey) } for _, key := range *keys { if key.Address == m.Address { diff --git a/ui/protocol.go b/ui/protocol.go index a9e91e59..7a4cd55b 100644 --- a/ui/protocol.go +++ b/ui/protocol.go @@ -1,7 +1,7 @@ package ui import ( - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/style" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" @@ -11,7 +11,7 @@ import ( // ProtocolViewModel includes the internal.StatusModel and internal.MetricsModel type ProtocolViewModel struct { - Data internal.StatusModel + Data nodekit.StatusModel TerminalWidth int TerminalHeight int IsVisible bool @@ -32,7 +32,7 @@ func (m ProtocolViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m ProtocolViewModel) HandleMessage(msg tea.Msg) (ProtocolViewModel, tea.Cmd) { switch msg := msg.(type) { // Handle a Status Update - case internal.StatusModel: + case nodekit.StatusModel: m.Data = msg return m, nil // Update Viewport Size @@ -96,7 +96,7 @@ func (m ProtocolViewModel) View() string { } // MakeProtocolViewModel constructs a ProtocolViewModel using a given StatusModel and predefined metrics. -func MakeProtocolViewModel(state *internal.StateModel) ProtocolViewModel { +func MakeProtocolViewModel(state *nodekit.StateModel) ProtocolViewModel { return ProtocolViewModel{ Data: state.Status, TerminalWidth: 0, diff --git a/ui/protocol_test.go b/ui/protocol_test.go index a207be37..930dfe42 100644 --- a/ui/protocol_test.go +++ b/ui/protocol_test.go @@ -2,7 +2,7 @@ package ui import ( "bytes" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/x/ansi" "github.com/charmbracelet/x/exp/golden" @@ -13,7 +13,7 @@ import ( var protocolViewSnapshots = map[string]ProtocolViewModel{ "Hidden": { - Data: internal.StatusModel{ + Data: nodekit.StatusModel{ State: "SYNCING", Version: "v0.0.0-test", Network: "test-v1", @@ -26,7 +26,7 @@ var protocolViewSnapshots = map[string]ProtocolViewModel{ IsVisible: false, }, "HiddenHeight": { - Data: internal.StatusModel{ + Data: nodekit.StatusModel{ State: "SYNCING", Version: "v0.0.0-test", Network: "test-v1", @@ -39,7 +39,7 @@ var protocolViewSnapshots = map[string]ProtocolViewModel{ IsVisible: true, }, "Visible": { - Data: internal.StatusModel{ + Data: nodekit.StatusModel{ State: "SYNCING", Version: "v0.0.0-test", Network: "test-v1", @@ -52,7 +52,7 @@ var protocolViewSnapshots = map[string]ProtocolViewModel{ IsVisible: true, }, "VisibleSmall": { - Data: internal.StatusModel{ + Data: nodekit.StatusModel{ State: "SYNCING", Version: "v0.0.0-test", Network: "test-v1", @@ -65,7 +65,7 @@ var protocolViewSnapshots = map[string]ProtocolViewModel{ IsVisible: true, }, "NoVoteOrUpgrade": { - Data: internal.StatusModel{ + Data: nodekit.StatusModel{ State: "SYNCING", Version: "v0.0.0-test", Network: "test-v1", @@ -78,7 +78,7 @@ var protocolViewSnapshots = map[string]ProtocolViewModel{ IsVisible: true, }, "NoVoteOrUpgradeSmall": { - Data: internal.StatusModel{ + Data: nodekit.StatusModel{ State: "SYNCING", Version: "v0.0.0-test", Network: "test-v1", @@ -103,13 +103,13 @@ func Test_ProtocolSnapshot(t *testing.T) { // Test_ProtocolMessages handles any additional tests like sending messages func Test_ProtocolMessages(t *testing.T) { - state := internal.StateModel{ - Status: internal.StatusModel{ + state := nodekit.StateModel{ + Status: nodekit.StatusModel{ LastRound: 1337, NeedsUpdate: true, - State: internal.SyncingState, + State: nodekit.SyncingState, }, - Metrics: internal.MetricsModel{ + Metrics: nodekit.MetricsModel{ RoundTime: 0, TX: 0, RX: 0, @@ -134,7 +134,7 @@ func Test_ProtocolMessages(t *testing.T) { teatest.WithCheckInterval(time.Millisecond*100), teatest.WithDuration(time.Second*3), ) - tm.Send(internal.StatusModel{ + tm.Send(nodekit.StatusModel{ State: "", Version: "", Network: "", diff --git a/ui/status.go b/ui/status.go index 63eb60fd..50d0f93e 100644 --- a/ui/status.go +++ b/ui/status.go @@ -2,7 +2,7 @@ package ui import ( "fmt" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/style" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" @@ -14,7 +14,7 @@ import ( // StatusViewModel is extended from the internal.StatusModel type StatusViewModel struct { - Data *internal.StateModel + Data *nodekit.StateModel TerminalWidth int TerminalHeight int IsVisible bool @@ -34,7 +34,7 @@ func (m StatusViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m StatusViewModel) HandleMessage(msg tea.Msg) (StatusViewModel, tea.Cmd) { switch msg := msg.(type) { // Is it a heartbeat of the latest round? - case internal.StateModel: + case nodekit.StateModel: m.Data = &msg // Is it a resize event? case tea.WindowSizeMsg: @@ -83,7 +83,7 @@ func (m StatusViewModel) View() string { var end string switch m.Data.Status.State { - case internal.StableState: + case nodekit.StableState: end = style.Green.Render(strings.ToUpper(string(m.Data.Status.State))) + " " default: end = style.Yellow.Render(strings.ToUpper(string(m.Data.Status.State))) + " " @@ -94,7 +94,7 @@ func (m StatusViewModel) View() string { row1 := lipgloss.JoinHorizontal(lipgloss.Left, beginning, middle, end) roundTime := fmt.Sprintf("%.2fs", float64(m.Data.Metrics.RoundTime)/float64(time.Second)) - if m.Data.Status.State != internal.StableState { + if m.Data.Status.State != nodekit.StableState { roundTime = "--" } beginning = style.Blue.Render(" Round time: ") + roundTime @@ -104,7 +104,7 @@ func (m StatusViewModel) View() string { row2 := lipgloss.JoinHorizontal(lipgloss.Left, beginning, middle, end) tps := fmt.Sprintf("%.2f", m.Data.Metrics.TPS) - if m.Data.Status.State != internal.StableState { + if m.Data.Status.State != nodekit.StableState { tps = "--" } beginning = style.Blue.Render(" TPS: ") + tps @@ -124,7 +124,7 @@ func (m StatusViewModel) View() string { } // MakeStatusViewModel constructs the model to be used in a tea.Program -func MakeStatusViewModel(state *internal.StateModel) StatusViewModel { +func MakeStatusViewModel(state *nodekit.StateModel) StatusViewModel { // Create the Model m := StatusViewModel{ Data: state, diff --git a/ui/status_test.go b/ui/status_test.go index fc10d856..e307f4a9 100644 --- a/ui/status_test.go +++ b/ui/status_test.go @@ -2,7 +2,7 @@ package ui import ( "bytes" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "testing" "time" @@ -14,13 +14,13 @@ import ( var statusViewSnapshots = map[string]StatusViewModel{ "Syncing": { - Data: &internal.StateModel{ - Status: internal.StatusModel{ + Data: &nodekit.StateModel{ + Status: nodekit.StatusModel{ LastRound: 1337, NeedsUpdate: true, State: "SYNCING", }, - Metrics: internal.MetricsModel{ + Metrics: nodekit.MetricsModel{ RoundTime: 0, TX: 0, }, @@ -30,13 +30,13 @@ var statusViewSnapshots = map[string]StatusViewModel{ IsVisible: true, }, "Hidden": { - Data: &internal.StateModel{ - Status: internal.StatusModel{ + Data: &nodekit.StateModel{ + Status: nodekit.StatusModel{ LastRound: 1337, NeedsUpdate: true, State: "SYNCING", }, - Metrics: internal.MetricsModel{ + Metrics: nodekit.MetricsModel{ RoundTime: 0, TX: 0, }, @@ -46,13 +46,13 @@ var statusViewSnapshots = map[string]StatusViewModel{ IsVisible: false, }, "Loading": { - Data: &internal.StateModel{ - Status: internal.StatusModel{ + Data: &nodekit.StateModel{ + Status: nodekit.StatusModel{ LastRound: 1337, NeedsUpdate: true, State: "SYNCING", }, - Metrics: internal.MetricsModel{ + Metrics: nodekit.MetricsModel{ RoundTime: 0, TX: 0, }, @@ -73,13 +73,13 @@ func Test_StatusSnapshot(t *testing.T) { } func Test_StatusMessages(t *testing.T) { - state := internal.StateModel{ - Status: internal.StatusModel{ + state := nodekit.StateModel{ + Status: nodekit.StatusModel{ LastRound: 1337, NeedsUpdate: true, - State: internal.SyncingState, + State: nodekit.SyncingState, }, - Metrics: internal.MetricsModel{ + Metrics: nodekit.MetricsModel{ RoundTime: 0, TX: 0, RX: 0, diff --git a/ui/viewport.go b/ui/viewport.go index dad291f9..c5fef4fc 100644 --- a/ui/viewport.go +++ b/ui/viewport.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" "github.com/algorandfoundation/algorun-tui/api" - "github.com/algorandfoundation/algorun-tui/internal" + "github.com/algorandfoundation/algorun-tui/internal/nodekit" "github.com/algorandfoundation/algorun-tui/ui/app" "github.com/algorandfoundation/algorun-tui/ui/modal" "github.com/algorandfoundation/algorun-tui/ui/pages/accounts" @@ -18,7 +18,7 @@ type ViewportViewModel struct { PageWidth, PageHeight int TerminalWidth, TerminalHeight int - Data *internal.StateModel + Data *nodekit.StateModel // Header Components status StatusViewModel @@ -57,7 +57,7 @@ func (m ViewportViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } m.page = msg // When the state updates - case internal.StateModel: + case nodekit.StateModel: m.Data = &msg m.accountsPage, cmd = m.accountsPage.HandleMessage(msg) cmds = append(cmds, cmd) @@ -75,7 +75,7 @@ func (m ViewportViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg.String() { case "g": // Only open modal when it is closed and not syncing - if !m.modal.Open && m.Data.Status.State == internal.StableState && m.Data.Metrics.RoundTime > 0 { + if !m.modal.Open && m.Data.Status.State == nodekit.StableState && m.Data.Metrics.RoundTime > 0 { address := "" selected := m.accountsPage.SelectedAccount() if selected != nil { @@ -86,7 +86,7 @@ func (m ViewportViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { Address: address, Type: app.GenerateModal, }) - } else if m.Data.Status.State != internal.StableState || m.Data.Metrics.RoundTime == 0 { + } else if m.Data.Status.State != nodekit.StableState || m.Data.Metrics.RoundTime == 0 { genErr := errors.New("Please wait for more data to sync before generating a key") m.modal, cmd = m.modal.HandleMessage(genErr) cmds = append(cmds, cmd) @@ -211,7 +211,7 @@ func (m ViewportViewModel) headerView() string { } // NewViewportViewModel handles the construction of the TUI viewport -func NewViewportViewModel(state *internal.StateModel, client api.ClientWithResponsesInterface) (*ViewportViewModel, error) { +func NewViewportViewModel(state *nodekit.StateModel, client api.ClientWithResponsesInterface) (*ViewportViewModel, error) { m := ViewportViewModel{ Data: state,