Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/gin-contrib/zap v1.1.4
github.com/gin-gonic/gin v1.10.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/maestro-org/go-sdk v1.2.0
go.uber.org/automaxprocs v1.6.0
go.uber.org/zap v1.27.0
gopkg.in/yaml.v2 v2.4.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/maestro-org/go-sdk v1.2.0 h1:0YbC5bwRWklV25L1Z4p2pg2VQYasZGDaC9Epfxwd3a0=
github.com/maestro-org/go-sdk v1.2.0/go.mod h1:EYaRwFT8nkwFzZsN6xK256j+r7ASUUn9p44RlaqYjE8=
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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down
68 changes: 67 additions & 1 deletion internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package api
import (
"bytes"
"context"
"encoding/hex"
"fmt"
"io"
"net/http"
Expand All @@ -30,6 +31,7 @@ import (
cors "github.com/gin-contrib/cors"
ginzap "github.com/gin-contrib/zap"
"github.com/gin-gonic/gin"
maestro "github.com/maestro-org/go-sdk/client"

"github.com/blinklabs-io/tx-submit-api-mirror/internal/config"
"github.com/blinklabs-io/tx-submit-api-mirror/internal/logging"
Expand Down Expand Up @@ -196,10 +198,74 @@ func handleSubmitTx(c *gin.Context) {
connReused,
)
} else {
logger.Errorw(fmt.Sprintf("failed to send request to backend %s: got response %d, %s", backend, resp.StatusCode, string(respBody)), "latency", elapsedTime.Seconds(), "connReused", connReused)
logger.Errorw(
fmt.Sprintf(
"failed to send request to backend %s: got response %d, %s",
backend,
resp.StatusCode,
string(respBody),
),
"latency",
elapsedTime.Seconds(),
"connReused",
connReused,
)
}
}(backend)
}
// Optional Maestro
if cfg.Maestro.ApiKey != "" {
go func(cfg *config.Config, rawTx []byte) {
txHex := hex.EncodeToString(rawTx)
maestroClient := maestro.NewClient(cfg.Maestro.ApiKey, cfg.Maestro.Network)
startTime := time.Now()
if cfg.Maestro.TurboTx {
_, err := maestroClient.TxManagerSubmitTurbo(txHex)
elapsedTime := time.Since(startTime)
if err != nil {
logger.Errorw(
fmt.Sprintf(
"failed to send request to Maestro: got response %v",
err,
),
"latency",
elapsedTime.Seconds(),
)
return
}
logger.Infow(
fmt.Sprintf(
"successfully submitted transaction %s to Maestro TurboTx",
tx.Hash(),
),
"latency",
elapsedTime.Seconds(),
)
return
}
_, err := maestroClient.TxManagerSubmit(txHex)
elapsedTime := time.Since(startTime)
if err != nil {
logger.Errorw(
fmt.Sprintf(
"failed to send request to Maestro: got response %v",
err,
),
"latency",
elapsedTime.Seconds(),
)
return
}
logger.Infow(
fmt.Sprintf(
"successfully submitted transaction %s to Maestro",
tx.Hash(),
),
"latency",
elapsedTime.Seconds(),
)
}(cfg, rawTx)
}
// Return transaction ID
c.String(202, tx.Hash())
}
Expand Down
27 changes: 19 additions & 8 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,48 @@ import (
)

type Config struct {
Logging LoggingConfig `yaml:"logging"`
Api ApiConfig `yaml:"api"`
Logging LoggingConfig `yaml:"logging"`
Maestro MaestroConfig `yaml:"maestro"`
Tls TlsConfig `yaml:"tls"`
Backends []string `yaml:"backends" envconfig:"BACKENDS"`
}

type LoggingConfig struct {
Level string `yaml:"level" envconfig:"LOGGING_LEVEL"`
}

type ApiConfig struct {
ListenAddress string `yaml:"address" envconfig:"API_LISTEN_ADDRESS"`
ListenPort uint `yaml:"port" envconfig:"API_LISTEN_PORT"`
ClientTimeout uint `yaml:"client_timeout" envconfig:"CLIENT_TIMEOUT"`
}

type LoggingConfig struct {
Level string `yaml:"level" envconfig:"LOGGING_LEVEL"`
}

type MaestroConfig struct {
ApiKey string `yaml:"apiKey" envconfig:"MAESTRO_API_KEY"`
Network string `yaml:"network" envconfig:"MAESTRO_NETWORK"`
TurboTx bool `yaml:"turboTx" envconfig:"MAESTRO_TURBO_TX"`
}

type TlsConfig struct {
CertFilePath string `yaml:"certFilePath" envconfig:"TLS_CERT_FILE_PATH"`
KeyFilePath string `yaml:"keyFilePath" envconfig:"TLS_KEY_FILE_PATH"`
}

// Singleton config instance with default values
var globalConfig = &Config{
Logging: LoggingConfig{
Level: "info",
},
Api: ApiConfig{
ListenAddress: "",
ListenPort: 8090,
ClientTimeout: 60000, // [ms]
},
Logging: LoggingConfig{
Level: "info",
},
Maestro: MaestroConfig{
Network: "mainnet",
TurboTx: false,
},
}

func Load(configFile string) (*Config, error) {
Expand Down