-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
132 lines (112 loc) · 3.72 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package main
import (
"context"
"log"
"log/slog"
"net/url"
"os"
"time"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/sethvargo/go-envconfig"
"github.com/warden-protocol/wardenprotocol/keychain-sdk"
)
type Config struct {
ProxyURL url.URL `env:"PROXY_URL, default=http://localhost:8080"`
ProxyTimeout time.Duration `env:"PROXY_TIMEOUT, default=5s"`
ChainID string `env:"CHAIN_ID, default=warden"`
GRPCURL string `env:"GRPC_URL, default=localhost:9090"`
GRPCInsecure bool `env:"GRPC_INSECURE, default=true"`
DerivationPath string `env:"DERIVATION_PATH, default=m/44'/118'/0'/0/0"`
Mnemonic string `env:"MNEMONIC, default=exclude try nephew main caught favorite tone degree lottery device tissue tent ugly mouse pelican gasp lava flush pen river noise remind balcony emerge"`
KeychainID uint64 `env:"KEYCHAIN_ID, default=1"`
BatchInterval time.Duration `env:"BATCH_INTERVAL, default=8s"`
BatchSize int `env:"BATCH_SIZE, default=7"`
GasLimit uint64 `env:"GAS_LIMIT, default=400000"`
TxTimeout time.Duration `env:"TX_TIMEOUT, default=120s"`
TxFee int64 `env:"TX_FEE, default=400000"`
LogLevel slog.Level `env:"LOG_LEVEL, default=info"`
LogFormat string `env:"LOG_FORMAT, default=plain"`
}
func main() {
cfg := readConfig()
logger := initLogger(cfg)
client := NewClient(cfg.ProxyURL, cfg.ProxyTimeout)
app := keychain.NewApp(keychain.Config{
Logger: logger,
ChainID: cfg.ChainID,
GRPCURL: cfg.GRPCURL,
GRPCInsecure: cfg.GRPCInsecure,
DerivationPath: cfg.DerivationPath,
Mnemonic: cfg.Mnemonic,
KeychainID: cfg.KeychainID,
GasLimit: cfg.GasLimit,
BatchInterval: cfg.BatchInterval,
BatchSize: cfg.BatchSize,
TxTimeout: cfg.TxTimeout,
TxFees: sdk.NewCoins(sdk.NewCoin("uward", math.NewInt(cfg.TxFee))),
})
app.SetKeyRequestHandler(func(w keychain.KeyResponseWriter, req *keychain.KeyRequest) {
logger := logger.With("id", req.Id)
res, err := client.requestKey(req)
if err != nil {
logger.Error("proxying key request", "err", err)
_ = w.Reject("internal error")
return
}
if res.Ok {
if err := w.Fulfil(res.Key); err != nil {
logger.Error("fulfilling key request", "err", err)
}
logger.Info("key request fulfilled")
} else {
logger.Error("key request rejected", "reason", res.RejectReason)
if err := w.Reject(res.RejectReason); err != nil {
logger.Error("rejecting key request", "err", err)
}
}
})
app.SetSignRequestHandler(func(w keychain.SignResponseWriter, req *keychain.SignRequest) {
logger := logger.With("id", req.Id)
res, err := client.requestSignature(req)
if err != nil {
logger.Error("proxying signature request", "err", err)
_ = w.Reject("internal error")
return
}
if res.Ok {
if err := w.Fulfil(res.Signature); err != nil {
logger.Error("fulfilling signature request", "err", err)
}
logger.Info("signature request fulfilled")
} else {
logger.Error("signature request rejected", "reason", res.RejectReason)
if err := w.Reject(res.RejectReason); err != nil {
logger.Error("rejecting signature request", "err", err)
}
}
})
if err := app.Start(context.Background()); err != nil {
panic(err)
}
}
func readConfig() Config {
var cfg Config
if err := envconfig.Process(context.Background(), &cfg); err != nil {
log.Fatal(err)
}
return cfg
}
func initLogger(c Config) *slog.Logger {
out := os.Stderr
var opts slog.HandlerOptions
opts.Level = c.LogLevel
var handler slog.Handler
switch c.LogFormat {
case "plain":
handler = slog.NewTextHandler(out, &opts)
case "json":
handler = slog.NewJSONHandler(out, &opts)
}
return slog.New(handler)
}