Merge branch 'main' into dev.v2

# Conflicts:
#	bridge/pkg/solana/submitter.go

Change-Id: I45b6e8f398b879915793987c5db38c839e8d1cc9
This commit is contained in:
Leo 2021-06-22 18:52:06 +02:00
commit c1d0f165d6
99 changed files with 26857 additions and 92 deletions

View File

@ -7,6 +7,7 @@ The following dependencies are required for local development:
- [Go](https://golang.org/dl/) >= 1.15.6 - [Go](https://golang.org/dl/) >= 1.15.6
- [Docker](https://docs.docker.com/engine/install/) / moby-engine >= 19.03 - [Docker](https://docs.docker.com/engine/install/) / moby-engine >= 19.03
- [Tilt](http://tilt.dev/) >= 0.17.10 - [Tilt](http://tilt.dev/) >= 0.17.10
- [NodeJS/npm](https://nodejs.org/en/download/) >= 14
- Any of the local Kubernetes clusters supported by Tilt. - Any of the local Kubernetes clusters supported by Tilt.
We recommend [minikube](https://kubernetes.io/docs/setup/learning-environment/minikube/) with the kvm2 driver. We recommend [minikube](https://kubernetes.io/docs/setup/learning-environment/minikube/) with the kvm2 driver.

View File

@ -15,6 +15,22 @@ spoken - this is a very complex piece of software which targets a bleeding-edge,
Mistakes happen, and no matter how hard you try and whether you pay someone to audit it, it may eat your tokens, set Mistakes happen, and no matter how hard you try and whether you pay someone to audit it, it may eat your tokens, set
your printer on fire or startle your cat. Cryptocurrencies are a high-risk investment, no matter how fancy. your printer on fire or startle your cat. Cryptocurrencies are a high-risk investment, no matter how fancy.
### READ FIRST BEFORE USING WORMHOLE
- Much of the Solana ecosystem uses wrapped assets issued by a centralized bridge operated by FTX (the "Sollet bridge").
Markets on Serum or Raydium are using those centralized assets rather than Wormhole wrapped assets. These have names
like "Wrapped BTC" or "Wrapped ETH". Wormhole is going to replace the FTX bridge eventually, but this will take some
time - meanwhile, **Wormhole wrapped assets aren't terribly useful yet since there're no market for them.**
- Other tokens on Solana like USDC and USDT are **centralized native tokens issued on multiple chains**. If you transfer
USDT from Ethereum to Solana, you will get "Wormhole Wrapped USDT" (wwUSDT), rather than native USDT.
- **Solana's SPL tokens have no on-chain metadata**. Wormhole can't know the name of the token when you
transfer assets to Ethereum. All tokens are therefore named "WWT" plus the address of the SPL token.
The reverse is also true - Wormhole knows the name of the ERC20 token, but there's no way to store it on Solana.
There's an [off-chain name registry](https://github.com/solana-labs/token-list) that some block explorers use, but
if you transfer an uncommon token to Solana, it may not show with a name on block explorers.
### Repo overview ### Repo overview
- **[bridge/](bridge/)** — The guardian node which connects to both chains, observes data and submits VAAs. - **[bridge/](bridge/)** — The guardian node which connects to both chains, observes data and submits VAAs.

View File

@ -87,6 +87,17 @@ k8s_resource("guardian", resource_deps=["proto-gen", "solana-devnet"], port_forw
port_forward(6060, name="Debug/Status Server [:6060]"), port_forward(6060, name="Debug/Status Server [:6060]"),
]) ])
# publicRPC proxy that allows grpc over http1, for local development
k8s_yaml_with_ns("./devnet/envoy-proxy.yaml")
k8s_resource("envoy-proxy", resource_deps=["guardian"],
objects=['envoy-proxy:ConfigMap:wormhole'],
port_forwards=[
port_forward(8080, name="gRPC proxy for guardian's publicRPC data [:8080]"),
port_forward(9901, name="gRPC proxy admin [:9901]"), # for proxy debugging
])
# solana agent and cli (runs alongside bridge) # solana agent and cli (runs alongside bridge)
docker_build( docker_build(
@ -163,6 +174,28 @@ k8s_resource("web", port_forwards=[
port_forward(3000, name="Experimental Web UI [:3000]") port_forward(3000, name="Experimental Web UI [:3000]")
]) ])
# explorer web app
docker_build(
ref = "explorer",
context = "./explorer",
dockerfile = "./explorer/Dockerfile",
ignore = ["./explorer/node_modules"],
live_update = [
sync("./explorer/src", "/home/node/app/src"),
sync("./explorer/public", "/home/node/app/public"),
],
)
k8s_yaml_with_ns("devnet/explorer.yaml")
k8s_resource("explorer",
resource_deps=["envoy-proxy"],
port_forwards=[
port_forward(8001, name="Explorer Web UI [:8001]")
]
)
# terra devnet # terra devnet
docker_build( docker_build(

12
bridge/cmd/debug/debug.go Normal file
View File

@ -0,0 +1,12 @@
package debug
import "github.com/spf13/cobra"
var DebugCmd = &cobra.Command{
Use: "debug",
Short: "Debugging utilities",
}
func init() {
DebugCmd.AddCommand(decodeVaaCmd)
}

View File

@ -0,0 +1,64 @@
package debug
import (
"context"
"encoding/hex"
"github.com/certusone/wormhole/bridge/pkg/solana"
"github.com/certusone/wormhole/bridge/pkg/supervisor"
"github.com/certusone/wormhole/bridge/pkg/vaa"
"github.com/spf13/cobra"
"go.uber.org/zap"
"log"
"strings"
)
var (
agentRPC *string
skipPreflight *bool
)
func init() {
agentRPC = postVaaSolanaCmd.Flags().String("agentRPC", "", "Solana agent sidecar gRPC socket path")
skipPreflight = postVaaSolanaCmd.Flags().Bool("skipPreflight", false, "Set skip_preflight flag on submission")
DebugCmd.AddCommand(postVaaSolanaCmd)
}
var postVaaSolanaCmd = &cobra.Command{
Use: "post-vaa-solana [DATA]",
Short: "Submit a hex-encoded VAA to Solana using the specified agent sidecar",
Run: func(cmd *cobra.Command, args []string) {
vaaQueue := make(chan *vaa.VAA)
logger, err := zap.NewDevelopment()
if err != nil {
panic(err)
}
supervisor.New(context.Background(), logger, func(ctx context.Context) error {
if err := supervisor.Run(ctx, "solvaa",
solana.NewSolanaVAASubmitter(*agentRPC, vaaQueue, *skipPreflight).Run); err != nil {
return err
}
select {
case <-ctx.Done():
return nil
}
})
for _, arg := range args {
arg = strings.TrimPrefix(arg, "0x")
b, err := hex.DecodeString(arg)
if err != nil {
log.Fatal(err)
}
v, err := vaa.Unmarshal(b)
if err != nil {
log.Fatal(err)
}
vaaQueue <- v
}
select {}
},
}

View File

@ -9,11 +9,6 @@ import (
"strings" "strings"
) )
var DebugCmd = &cobra.Command{
Use: "debug",
Short: "Debugging utilities",
}
var decodeVaaCmd = &cobra.Command{ var decodeVaaCmd = &cobra.Command{
Use: "decode-vaa [DATA]", Use: "decode-vaa [DATA]",
Short: "Decode a hex-encoded VAA", Short: "Decode a hex-encoded VAA",
@ -34,7 +29,3 @@ var decodeVaaCmd = &cobra.Command{
} }
}, },
} }
func init() {
DebugCmd.AddCommand(decodeVaaCmd)
}

View File

@ -26,6 +26,7 @@ import (
"github.com/certusone/wormhole/bridge/pkg/p2p" "github.com/certusone/wormhole/bridge/pkg/p2p"
"github.com/certusone/wormhole/bridge/pkg/processor" "github.com/certusone/wormhole/bridge/pkg/processor"
gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1" gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1"
"github.com/certusone/wormhole/bridge/pkg/publicrpc"
"github.com/certusone/wormhole/bridge/pkg/readiness" "github.com/certusone/wormhole/bridge/pkg/readiness"
solana "github.com/certusone/wormhole/bridge/pkg/solana" solana "github.com/certusone/wormhole/bridge/pkg/solana"
"github.com/certusone/wormhole/bridge/pkg/supervisor" "github.com/certusone/wormhole/bridge/pkg/supervisor"
@ -71,6 +72,8 @@ var (
unsafeDevMode *bool unsafeDevMode *bool
devNumGuardians *uint devNumGuardians *uint
nodeName *string nodeName *string
publicRPC *string
) )
func init() { func init() {
@ -108,6 +111,8 @@ func init() {
unsafeDevMode = BridgeCmd.Flags().Bool("unsafeDevMode", false, "Launch node in unsafe, deterministic devnet mode") unsafeDevMode = BridgeCmd.Flags().Bool("unsafeDevMode", false, "Launch node in unsafe, deterministic devnet mode")
devNumGuardians = BridgeCmd.Flags().Uint("devNumGuardians", 5, "Number of devnet guardians to include in guardian set") devNumGuardians = BridgeCmd.Flags().Uint("devNumGuardians", 5, "Number of devnet guardians to include in guardian set")
nodeName = BridgeCmd.Flags().String("nodeName", "", "Node name to announce in gossip heartbeats") nodeName = BridgeCmd.Flags().String("nodeName", "", "Node name to announce in gossip heartbeats")
publicRPC = BridgeCmd.Flags().String("publicRPC", "", "Listen address for public gRPC interface")
} }
var ( var (
@ -380,10 +385,13 @@ func runBridge(cmd *cobra.Command, args []string) {
logger.Fatal("failed to create admin service socket", zap.Error(err)) logger.Fatal("failed to create admin service socket", zap.Error(err))
} }
// subscriber channel multiplexing for public gPRC streams
rawHeartbeatListeners := publicrpc.HeartbeatStreamMultiplexer(logger)
// Run supervisor. // Run supervisor.
supervisor.New(rootCtx, logger, func(ctx context.Context) error { supervisor.New(rootCtx, logger, func(ctx context.Context) error {
if err := supervisor.Run(ctx, "p2p", p2p.Run( if err := supervisor.Run(ctx, "p2p", p2p.Run(
obsvC, sendC, priv, *p2pPort, *p2pNetworkID, *p2pBootstrap, *nodeName, rootCtxCancel)); err != nil { obsvC, sendC, rawHeartbeatListeners, priv, *p2pPort, *p2pNetworkID, *p2pBootstrap, *nodeName, rootCtxCancel)); err != nil {
return err return err
} }
@ -402,7 +410,7 @@ func runBridge(cmd *cobra.Command, args []string) {
} }
if err := supervisor.Run(ctx, "solvaa", if err := supervisor.Run(ctx, "solvaa",
solana.NewSolanaVAASubmitter(*agentRPC, lockC, solanaVaaC).Run); err != nil { solana.NewSolanaVAASubmitter(*agentRPC, solanaVaaC, false).Run); err != nil {
return err return err
} }
@ -436,6 +444,12 @@ func runBridge(cmd *cobra.Command, args []string) {
if err := supervisor.Run(ctx, "admin", adminService); err != nil { if err := supervisor.Run(ctx, "admin", adminService); err != nil {
return err return err
} }
if *publicRPC != "" {
if err := supervisor.Run(ctx, "publicrpc",
publicrpc.PublicrpcServiceRunnable(logger, *publicRPC, rawHeartbeatListeners)); err != nil {
return err
}
}
logger.Info("Started internal services") logger.Info("Started internal services")

View File

@ -25,6 +25,7 @@ import (
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1" gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1"
"github.com/certusone/wormhole/bridge/pkg/publicrpc"
"github.com/certusone/wormhole/bridge/pkg/supervisor" "github.com/certusone/wormhole/bridge/pkg/supervisor"
) )
@ -54,6 +55,7 @@ func init() {
func Run(obsvC chan *gossipv1.SignedObservation, func Run(obsvC chan *gossipv1.SignedObservation,
sendC chan []byte, sendC chan []byte,
rawHeartbeatListeners *publicrpc.PublicRawHeartbeatConnections,
priv crypto.PrivKey, priv crypto.PrivKey,
port uint, port uint,
networkID string, networkID string,
@ -203,6 +205,8 @@ func Run(obsvC chan *gossipv1.SignedObservation,
GuardianAddr: DefaultRegistry.guardianAddress, GuardianAddr: DefaultRegistry.guardianAddress,
}}} }}}
rawHeartbeatListeners.PublishHeartbeat(msg.GetHeartbeat())
b, err := proto.Marshal(&msg) b, err := proto.Marshal(&msg)
if err != nil { if err != nil {
panic(err) panic(err)
@ -268,6 +272,7 @@ func Run(obsvC chan *gossipv1.SignedObservation,
logger.Debug("heartbeat received", logger.Debug("heartbeat received",
zap.Any("value", m.Heartbeat), zap.Any("value", m.Heartbeat),
zap.String("from", envelope.GetFrom().String())) zap.String("from", envelope.GetFrom().String()))
rawHeartbeatListeners.PublishHeartbeat(msg.GetHeartbeat())
p2pMessagesReceived.WithLabelValues("heartbeat").Inc() p2pMessagesReceived.WithLabelValues("heartbeat").Inc()
case *gossipv1.GossipMessage_SignedObservation: case *gossipv1.GossipMessage_SignedObservation:
obsvC <- m.SignedObservation obsvC <- m.SignedObservation

View File

@ -0,0 +1,57 @@
package publicrpc
import (
"fmt"
"net"
"go.uber.org/zap"
"google.golang.org/grpc"
publicrpcv1 "github.com/certusone/wormhole/bridge/pkg/proto/publicrpc/v1"
"github.com/certusone/wormhole/bridge/pkg/supervisor"
)
// gRPC server & method for handling streaming proto connection
type publicrpcServer struct {
publicrpcv1.UnimplementedPublicrpcServer
rawHeartbeatListeners *PublicRawHeartbeatConnections
logger *zap.Logger
}
func (s *publicrpcServer) GetRawHeartbeats(req *publicrpcv1.GetRawHeartbeatsRequest, stream publicrpcv1.Publicrpc_GetRawHeartbeatsServer) error {
s.logger.Info("gRPC heartbeat stream opened by client")
// create a channel and register it for heartbeats
receiveChan := make(chan *publicrpcv1.Heartbeat, 50)
// clientId is the reference to the subscription that we will use for unsubscribing when the client disconnects.
clientId := s.rawHeartbeatListeners.subscribeHeartbeats(receiveChan)
for {
select {
// Exit on stream context done
case <-stream.Context().Done():
s.logger.Info("raw heartbeat stream closed by client", zap.Int("clientId", clientId))
s.rawHeartbeatListeners.unsubscribeHeartbeats(clientId)
return stream.Context().Err()
case msg := <-receiveChan:
stream.Send(msg)
}
}
}
func PublicrpcServiceRunnable(logger *zap.Logger, listenAddr string, rawHeartbeatListeners *PublicRawHeartbeatConnections) supervisor.Runnable {
l, err := net.Listen("tcp", listenAddr)
if err != nil {
logger.Fatal("failed to listen for publicrpc service", zap.Error(err))
}
logger.Info(fmt.Sprintf("publicrpc server listening on %s", listenAddr))
rpcServer := &publicrpcServer{
rawHeartbeatListeners: rawHeartbeatListeners,
logger: logger.Named("publicrpcserver"),
}
grpcServer := grpc.NewServer()
publicrpcv1.RegisterPublicrpcServer(grpcServer, rpcServer)
return supervisor.GRPCServer(grpcServer, l, false)
}

View File

@ -0,0 +1,87 @@
package publicrpc
import (
"math/rand"
"sync"
"github.com/prometheus/client_golang/prometheus"
"go.uber.org/zap"
publicrpcv1 "github.com/certusone/wormhole/bridge/pkg/proto/publicrpc/v1"
)
// track the number of active connections
var (
currentPublicHeartbeatStreamsOpen = prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "wormhole_publicrpc_rawheartbeat_connections",
Help: "Current number of clients consuming gRPC raw heartbeat streams",
})
)
func init() {
prometheus.MustRegister(currentPublicHeartbeatStreamsOpen)
}
// multiplexing to distribute heartbeat messages to all the open connections
type PublicRawHeartbeatConnections struct {
mu sync.RWMutex
subs map[int]chan<- *publicrpcv1.Heartbeat
logger *zap.Logger
}
func HeartbeatStreamMultiplexer(logger *zap.Logger) *PublicRawHeartbeatConnections {
ps := &PublicRawHeartbeatConnections{
subs: map[int]chan<- *publicrpcv1.Heartbeat{},
logger: logger.Named("heartbeatmultiplexer"),
}
return ps
}
// getUniqueClientId loops to generate & test integers for existence as key of map. returns an int that is not a key in map.
func (ps *PublicRawHeartbeatConnections) getUniqueClientId() int {
clientId := rand.Intn(1e6)
found := false
for found {
clientId = rand.Intn(1e6)
_, found = ps.subs[clientId]
}
return clientId
}
// subscribeHeartbeats adds a channel to the subscriber map, keyed by arbitary clientId
func (ps *PublicRawHeartbeatConnections) subscribeHeartbeats(ch chan *publicrpcv1.Heartbeat) int {
ps.mu.Lock()
defer ps.mu.Unlock()
clientId := ps.getUniqueClientId()
ps.logger.Info("subscribeHeartbeats for client", zap.Int("client", clientId))
ps.subs[clientId] = ch
currentPublicHeartbeatStreamsOpen.Set(float64(len(ps.subs)))
return clientId
}
// PublishHeartbeat sends a message to all channels in the subscription map
func (ps *PublicRawHeartbeatConnections) PublishHeartbeat(msg *publicrpcv1.Heartbeat) {
ps.mu.RLock()
defer ps.mu.RUnlock()
for client, ch := range ps.subs {
select {
case ch <- msg:
ps.logger.Debug("published message to client", zap.Int("client", client))
default:
ps.logger.Debug("buffer overrrun when attempting to publish message", zap.Int("client", client))
}
}
}
// unsubscribeHeartbeats removes the client's channel from the subscription map
func (ps *PublicRawHeartbeatConnections) unsubscribeHeartbeats(clientId int) {
ps.mu.Lock()
defer ps.mu.Unlock()
ps.logger.Debug("unsubscribeHeartbeats for client", zap.Int("clientId", clientId))
delete(ps.subs, clientId)
currentPublicHeartbeatStreamsOpen.Set(float64(len(ps.subs)))
}

View File

@ -1,4 +1,4 @@
package ethereum package solana
import ( import (
"context" "context"

View File

@ -1,4 +1,4 @@
package ethereum package solana
import ( import (
"encoding/hex" "encoding/hex"

View File

@ -1,4 +1,4 @@
package ethereum package solana
import ( import (
"context" "context"
@ -46,11 +46,12 @@ type (
messageChan chan *common.MessagePublication messageChan chan *common.MessagePublication
vaaChan chan *vaa.VAA vaaChan chan *vaa.VAA
skipPreflight bool
} }
) )
func NewSolanaVAASubmitter(url string, lockEvents chan *common.MessagePublication, vaaQueue chan *vaa.VAA) *SolanaVAASubmitter { func NewSolanaVAASubmitter(url string, lockEvents chan *common.MessagePublication, vaaQueue chan *vaa.VAA, skipPreflight bool) *SolanaVAASubmitter {
return &SolanaVAASubmitter{url: url, messageChan: lockEvents, vaaChan: vaaQueue} return &SolanaVAASubmitter{url: url, messageChan: lockEvents, vaaChan: vaaQueue, skipPreflight: skipPreflight}
} }
func (e *SolanaVAASubmitter) Run(ctx context.Context) error { func (e *SolanaVAASubmitter) Run(ctx context.Context) error {
@ -113,8 +114,8 @@ func (e *SolanaVAASubmitter) Run(ctx context.Context) error {
} }
h := hex.EncodeToString(m.Bytes()) h := hex.EncodeToString(m.Bytes())
timeout, cancel := context.WithTimeout(ctx, 15*time.Second) timeout, cancel := context.WithTimeout(ctx, 120*time.Second)
res, err := c.SubmitVAA(timeout, &agentv1.SubmitVAARequest{Vaa: vaaBytes}) res, err := c.SubmitVAA(timeout, &agentv1.SubmitVAARequest{Vaa: vaaBytes, SkipPreflight: e.skipPreflight})
cancel() cancel()
if err != nil { if err != nil {
st, ok := status.FromError(err) st, ok := status.FromError(err)

View File

@ -10,6 +10,9 @@ spec:
- port: 8999 - port: 8999
name: p2p name: p2p
protocol: UDP protocol: UDP
- port: 7070
name: public-grpc
protocol: TCP
clusterIP: None clusterIP: None
selector: selector:
app: guardian app: guardian
@ -84,6 +87,8 @@ spec:
- --unsafeDevMode - --unsafeDevMode
- --bridgeKey - --bridgeKey
- /tmp/bridge.key - /tmp/bridge.key
- --publicRPC
- "[::]:7070"
- --adminSocket - --adminSocket
- /tmp/admin.sock - /tmp/admin.sock
# - --logLevel=debug # - --logLevel=debug
@ -103,6 +108,9 @@ spec:
- containerPort: 6060 - containerPort: 6060
name: pprof name: pprof
protocol: TCP protocol: TCP
- containerPort: 7070
name: public-grpc
protocol: TCP
- name: agent - name: agent
image: solana-agent image: solana-agent
volumeMounts: volumeMounts:

128
devnet/envoy-proxy.yaml Normal file
View File

@ -0,0 +1,128 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: envoy-proxy
name: envoy-proxy
spec:
ports:
- name: http-debug
port: 8080
protocol: TCP
- name: admin-debug
port: 9901
protocol: TCP
selector:
app: envoy-proxy
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: envoy-proxy
name: envoy-proxy
spec:
serviceName: envoy-proxy
replicas: 1
selector:
matchLabels:
app: envoy-proxy
template:
metadata:
labels:
app: envoy-proxy
spec:
containers:
- name: envoy-proxy
image: envoyproxy/envoy:v1.17.0@sha256:80df344b5651c57265a03b47f583c139d3ce955415746c00cf5aff08c7e78e44
volumeMounts:
- name: config-volume
mountPath: /etc/envoy/envoy.yaml
subPath: envoy.yaml
command: [
"/usr/local/bin/envoy",
"-c",
"/etc/envoy/envoy.yaml",
"-l",
"trace",
"--log-path",
"/tmp/envoy_info.log"]
ports:
- containerPort: 8080
name: http-debug
protocol: TCP
- containerPort: 9901
name: admin-debug
protocol: TCP
volumes:
- name: config-volume
configMap:
name: envoy-proxy
---
kind: ConfigMap
apiVersion: v1
metadata:
name: envoy-proxy
labels:
app: envoy-proxy
selector:
matchLabels:
app: envoy-proxy
data:
envoy.yaml: |
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: echo_service
timeout: 0s
max_stream_duration:
grpc_timeout_header_max: 0s
cors:
allow_origin_string_match:
- prefix: "*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: "1728000"
expose_headers: custom-header-1,grpc-status,grpc-message
http_filters:
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.cors
- name: envoy.filters.http.router
clusters:
- name: echo_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
load_assignment:
cluster_name: cluster_0
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: guardian
port_value: 7070
---

44
devnet/explorer.yaml Normal file
View File

@ -0,0 +1,44 @@
---
apiVersion: v1
kind: Service
metadata:
name: explorer
labels:
app: explorer
spec:
ports:
- port: 8001
name: http
protocol: TCP
clusterIP: None
selector:
app: explorer
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: explorer
spec:
selector:
matchLabels:
app: explorer
serviceName: explorer
replicas: 1
template:
metadata:
labels:
app: explorer
spec:
terminationGracePeriodSeconds: 1
containers:
- name: explorer
image: explorer
command:
- /usr/local/bin/npm
- run
- build-and-serve
tty: true
ports:
- containerPort: 8001
name: gatsbyserver
protocol: TCP

29
explorer/.babelrc Normal file
View File

@ -0,0 +1,29 @@
{
"env": {
"production": {
"plugins": ["babel-plugin-jsx-remove-data-test-id"]
},
"test": {}
},
"plugins": [
[
"module-resolver",
{
"root": ["./src"],
"alias": {
"~": "./src"
}
}
]
],
"presets": [
[
"babel-preset-gatsby",
{
"targets": {
"browsers": [">0.25%", "not dead"]
}
}
]
]
}

10
explorer/.editorconfig Normal file
View File

@ -0,0 +1,10 @@
root = true
[*]
charset = utf-8
tab_width = 2
indent_size = 2
end_of_line = lf
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

9
explorer/.env.sample Normal file
View File

@ -0,0 +1,9 @@
# General
GATSBY_TELEMETRY_DISABLED=1
GATSBY_SITE_URL=http://localhost:8000
GATSBY_ENVIRONMENT=development
GATSBY_APP_RPC_URL=http://localhost:8080
# Profiling
ENABLE_BUNDLE_ANALYZER=0

3
explorer/.eslintignore Normal file
View File

@ -0,0 +1,3 @@
.cache
public
proto

189
explorer/.eslintrc.js Normal file
View File

@ -0,0 +1,189 @@
const {
rules: baseImportsRules,
} = require('eslint-config-airbnb-base/rules/imports');
module.exports = {
globals: {
// Gatsby Config
__PATH_PREFIX__: true,
},
env: {
// Allow `window` global
browser: true,
},
// Global ESLint Settings
// =================================
settings: {
'import/resolver': {
node: {
paths: ['./', 'src'],
extensions: ['.js', '.jsx', '.ts', '.tsx', 'json'],
},
// Resolve Aliases
// =================================
alias: {
map: [
['~', './src'],
['@theme/styled', './src/styled'],
],
extensions: ['.js', '.jsx', '.ts', '.tsx', 'json', '.d.ts'],
},
},
},
// ===========================================
// Set up ESLint for .js / .jsx files
// ===========================================
// .js / .jsx uses babel-eslint
parser: 'babel-eslint',
// Plugins
// =================================
plugins: ['no-only-tests'],
// Extend Other Configs
// =================================
extends: [
'eslint:recommended',
'airbnb',
// Disable rules that conflict with Prettier
// !!! Prettier must be last to override other configs
'prettier/react',
'plugin:prettier/recommended',
],
rules: {
// This project uses TS. Disable prop-types check
'react/prop-types': 0,
// Allow snake_case due to inconsistent APIs
camelcase: 0,
// Prevents exclusion of tests from passing lint check
'no-only-tests/no-only-tests': 'error',
},
// https://eslint.org/docs/user-guide/configuring#report-unused-eslint-disable-comments
reportUnusedDisableDirectives: true,
// =================================
// Overrides for Specific Files
// =================================
overrides: [
// =================================
// TypeScript Files
// =================================
{
files: ['**/*.{ts,tsx}'],
// allow ESLint to understand TypeScript syntax
// https://github.com/iamturns/eslint-config-airbnb-typescript/blob/master/lib/shared.js#L10
parserOptions: {
// Lint with Type Information
// https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/TYPED_LINTING.md
tsconfigRootDir: __dirname,
project: './tsconfig.json',
},
extends: [
// ESLint's inbuilt 'recommended' config
'eslint:recommended',
// Disables rules from the 'eslint:recommended' that are already covered by TypeScript's typechecker
'plugin:@typescript-eslint/eslint-recommended',
// Turns on rules from @typescript-eslint/eslint-plugin
'plugin:@typescript-eslint/recommended',
// Lint with Type Information
// https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/TYPED_LINTING.md
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'airbnb-typescript',
// Disable rules that conflict with Prettier
// !!! Prettier must be last to override other configs
'prettier/react',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
],
rules: {
// This project uses TS. Disable prop-types check
'react/prop-types': 'off',
// Allow snake_case due to inconsistent APIs
'@typescript-eslint/camelcase': 0,
// Makes no sense to allow type inferrence for expression parameters, but require typing the response
'@typescript-eslint/explicit-function-return-type': 0,
// Reduce props spreading rule to a warning, not an error
'react/jsx-props-no-spreading': 1,
'no-restricted-imports': [
'warn',
{
paths: [
],
},
],
},
},
// =================================
// index.ts Files (Re-exporting a directory's files)
// =================================
{
files: ['**/index.{js,ts,tsx}'],
rules: {
// Allow named exports in a directory's index files
'import/prefer-default-export': 0,
},
},
// =================================
// Gatsby Files
// =================================
{
files: ['**/**/gatsby-*.js'],
rules: {
'no-console': 0,
// Allow import devDependencies in Gatsby files.
'import/no-extraneous-dependencies': [
2,
{
devDependencies: true,
// Tells ESLint where the path to the folder containing package.json is for nested files like /plugin/**/gatsby-*.js
packageDir: './',
},
],
'react/no-danger': 0,
'react/jsx-props-no-spreading': 0,
// Allow 'jsx' in .js files
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
'import/prefer-default-export': 0,
// Append 'ts' and 'tsx' when importing files from a folder/index.ts
'import/extensions': [
baseImportsRules['import/extensions'][0],
baseImportsRules['import/extensions'][1],
{
...baseImportsRules['import/extensions'][2],
ts: 'never',
tsx: 'never',
},
],
},
},
// =================================
// Test Files
// =================================
{
files: ['**/test-utils/*.{js,ts,tsx}', '**/**/*.test.{js,ts,tsx}'],
// Allow `jest` global
extends: ['plugin:jest/recommended'],
rules: {
// Allow import devDependencies in tests
'import/no-extraneous-dependencies': 0,
'react/jsx-props-no-spreading': 0,
'jsx-a11y/alt-text': 0,
},
},
// =================================
// Storybook Files
// =================================
{
files: ['**/*.stories.{js,ts,tsx}'],
rules: {
// Allow import devDependencies in stories
'import/no-extraneous-dependencies': 0,
'react/jsx-props-no-spreading': 0,
'jsx-a11y/alt-text': 0,
},
},
],
};

76
explorer/.gitignore vendored Normal file
View File

@ -0,0 +1,76 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# dotenv environment variables file
.env*
!.env.sample
# gatsby files
.cache/
public
# Mac files
.DS_Store
# Yarn
yarn-error.log
.pnp/
.pnp.js
# Yarn Integrity file
.yarn-integrity
# Storybook
.out
# protos
proto

3
explorer/.prettierignore Normal file
View File

@ -0,0 +1,3 @@
.cache
public
proto

5
explorer/.prettierrc Normal file
View File

@ -0,0 +1,5 @@
{
"$schema": "http://json.schemastore.org/prettierrc",
"singleQuote": true,
"trailingComma": "es5"
}

View File

@ -0,0 +1,19 @@
import React from 'react';
import { IntlContextProvider } from 'gatsby-plugin-intl/intl-context';
import { locales, messages } from '../preview';
const intlConfig = {
language: 'en',
languages: locales,
messages: messages,
originalPath: '/',
redirect: true,
routed: true,
};
const GatsbyIntlProvider = storyFn => (
<IntlContextProvider value={intlConfig}>{storyFn()}</IntlContextProvider>
);
export default GatsbyIntlProvider;

View File

@ -0,0 +1 @@
export { default as GatsbyIntlProvider } from './GatsbyIntlProvider';

View File

@ -0,0 +1,16 @@
module.exports = {
stories: ['../src/**/*.stories.tsx'],
addons: [
'@storybook/addon-actions/register',
'@storybook/addon-viewport/register',
'storybook-addon-intl/register',
{
name: '@storybook/preset-typescript',
options: {
tsLoaderOptions: {
transpileOnly: true,
},
},
},
],
};

View File

@ -0,0 +1,7 @@
/**
* `manager.js` replaces `addons.js` and allows you to customize how Storybooks app UI renders.
* That is, everything outside of the Canvas (preview iframe).
* In common cases, you probably wont need this file except when youre theming Storybook.
*
* https://medium.com/storybookjs/declarative-storybook-configuration-49912f77b78
*/

View File

@ -0,0 +1,5 @@
<link
href="https://fonts.googleapis.com/css?family=Lora:400,700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="https://use.typekit.net/amn5iwe.css" />

View File

@ -0,0 +1,70 @@
import { addDecorator, addParameters } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
import { setIntlConfig, withIntl } from 'storybook-addon-intl';
import { GatsbyIntlProvider } from './decorators';
import supportedLanguages from '../src/utils/i18n/supportedLanguages'
// Gatsby Setup
// ============================================
// Gatsby's Link overrides:
// Gatsby defines a global called ___loader to prevent its method calls from creating console errors you override it here
global.___loader = {
enqueue: () => {},
hovering: () => {},
};
// Gatsby internal mocking to prevent unnecessary errors in storybook testing environment
global.__PATH_PREFIX__ = '';
// This is to utilized to override the window.___navigate method Gatsby defines and uses to report what path a Link would be taking us to if it wasn't inside a storybook
window.___navigate = pathname => {
action('NavigateTo:')(pathname);
};
// Storybook Addons
// ============================================
// TODO: Add our breakpoints to the list of viewport options
addParameters({
viewport: {
viewports: INITIAL_VIEWPORTS,
defaultViewport: 'responsive',
},
options: {
panelPosition: 'right',
},
});
// Storybook Decorators
// ============================================
// gatsby-plugin-intl Provider ================
// Set supported locales
export const locales = supportedLanguages.map(language => language.languageTag);
// TODO: import these with fs as esModules, rather than require('...json'), so that
// nested keys work (objects with key/values, rather than just "homepage.title" keys).
// Import translation messages
export const messages = locales.reduce((acc, locale) => {
return {
...acc,
[locale]: require(`../src/locales/${locale}.json`),
};
}, {});
const getMessages = locale => messages[locale];
// Set `storybook-addon-intl` configuration (handles `react-intl`)
setIntlConfig({
locales,
defaultLocale: 'en',
getMessages,
});
// Register decorators
// Adds gatsby-plugin-intl IntlContextProvider which wraps the Gatsby Link component
addDecorator(GatsbyIntlProvider);
// Adds react-intl
addDecorator(withIntl);

View File

@ -0,0 +1,111 @@
import path from 'path'
import dotenv from 'dotenv'
dotenv.config({
path: `.env.${process.env.NODE_ENV}`,
});
import antdThemeOverrides from '../src/AntdTheme'
import { getThemeVariables } from 'antd/dist/theme'
export default ({ config }) => {
// Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
// ========================================================
config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/];
// Add Babel rules
// ========================================================
// use installed babel-loader which is v8.0-beta (which is meant to work with @babel/core@7)
config.module.rules[0].use[0].loader = require.resolve('babel-loader');
// use @babel/preset-react for JSX and env (instead of staged presets)
config.module.rules[0].use[0].options.presets = [
require.resolve('@babel/preset-react'),
require.resolve('@babel/preset-env'),
// Emotion preset must run BEFORE reacts preset to properly convert css-prop.
// Babel preset-ordering runs reversed (from last to first). Emotion has to be after React preset.
];
config.module.rules[0].use[0].options.plugins = [
// use @babel/plugin-proposal-class-properties for class arrow functions
require.resolve('@babel/plugin-proposal-class-properties'),
// use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
require.resolve('babel-plugin-remove-graphql-queries'),
];
// Prefer Gatsby ES6 entrypoint (module) over commonjs (main) entrypoint
// ========================================================
config.resolve.mainFields = ['browser', 'module', 'main'];
// Add Webpack rules for TypeScript
// ========================================================
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [
['react-app', { flow: false, typescript: true }],
// Emotion preset must run BEFORE reacts preset to properly convert css-prop.
// Babel preset-ordering runs reversed (from last to first). Emotion has to be after React preset.
],
plugins: [
require.resolve('@babel/plugin-proposal-class-properties'),
// use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
require.resolve('babel-plugin-remove-graphql-queries'),
['import', {libraryName: "antd", libraryDirectory: 'es', style: true}]
],
},
});
config.module.rules.push({
test: /\.less$/,
loaders: [
"style-loader",
"css-loader",
{
loader: "less-loader",
options: {
lessOptions: {
javascriptEnabled: true,
modifyVars: {
...getThemeVariables({
dark: true, // Enable dark mode
compact: true, // Enable compact mode,
}),
...antdThemeOverrides,
}
}
}
}
],
include: path.resolve(__dirname, "../")
})
config.resolve.extensions.push('.ts', '.tsx');
// Add SVGR Loader
// ========================================================
// Remove svg rules from existing webpack rule
const assetRule = config.module.rules.find(({ test }) => test.test('.svg'));
const assetLoader = {
loader: assetRule.loader,
options: assetRule.options || assetRule.query,
};
config.module.rules.unshift({
test: /\.svg$/,
use: ['@svgr/webpack', assetLoader],
});
// Mirror project aliases for some reason (should be picked up by .babelrc)
// ========================================================
config.resolve.alias['~/utils'] = path.resolve(__dirname, '../src/utils');
config.resolve.alias['~/components'] = path.resolve(
__dirname,
'../src/components'
);
config.resolve.alias['~/images'] = path.resolve(__dirname, '../src/images');
config.resolve.alias['~/icons'] = path.resolve(__dirname, '../src/icons');
return config;
};

35
explorer/.svgo.yml Normal file
View File

@ -0,0 +1,35 @@
# multipass: true
# full: true
plugins:
- cleanupIDs: true
minify: true
- cleanupListOfValues: true
- convertColors: true
- convertStyleToAttrs: true
- convertTransform: true
- cleanupNumericValues: true
floatPrecision: 3
- mergePaths: true
- minifyStyles: true
- moveElemesAttrsToGroup: true
- removeAttrs: true
attrs: 'fill-rule'
- removeComments: true
- removeDesc: true
removeAny: true
- removeDimensions: true
- removeViewBox: false
- removeDoctype: true
- removeEditorsNSData: true
- removeEmptyAttrs: true
- removeEmptyContainers: true
- removeEmptyText: true
- removeNonInheritableGroupAttrs: true
- removeTitle: false
- removeUnknownsAndDefaults: true
- removeUnusedNS: true
- removeUselessDefs: true
- removeUselessStrokeAndFill: true
- removeXMLProcInst: true
- sortAttrs: true

78
explorer/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,78 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
// launches Chrome and allows debugging from vscode.
// you can set breakpoints in .tsx files, etc.
"type": "pwa-chrome",
"request": "launch",
"name": "Debug in Chrome",
"url": "http://localhost:8000",
"webRoot": "${workspaceFolder}"
},
{
// for debugging the gatsby dev server
"name": "Gatsby develop",
"type": "node",
"request": "launch",
"protocol": "inspector",
"program": "${workspaceRoot}/node_modules/gatsby/dist/bin/gatsby",
"preLaunchTask": {"type": "npm", "script": "clean"},
"args": ["develop"],
"stopOnEntry": false,
"runtimeArgs": ["--nolazy", "--max-http-header-size=16385"],
"sourceMaps": false,
"env": {
"NODE_OPTIONS": "-r esm"
}
},
{
// for debugging gatsby via it's 'debug' command
"name": "Gatsby debug",
"type": "node",
"request": "launch",
"protocol": "inspector",
"program": "${workspaceRoot}/node_modules/gatsby/dist/bin/gatsby",
"preLaunchTask": {"type": "npm", "script": "clean"},
"args": ["debug"],
"stopOnEntry": false,
"runtimeArgs": ["--nolazy", "--inspect-brk"],
"sourceMaps": false,
"env": {
"NODE_OPTIONS": "-r esm"
}
},
{
// for debugging the gatsby build process
"name": "Gatsby build",
"type": "node",
"request": "launch",
"protocol": "inspector",
"program": "${workspaceRoot}/node_modules/gatsby/dist/bin/gatsby",
"args": ["build"],
"stopOnEntry": false,
"sourceMaps": false,
"env": {
"NODE_OPTIONS": "-r esm"
}
},
{
"type": "node",
"request": "launch",
"name": "translate.ts",
"runtimeArgs": [
"-r",
"ts-node/register"
],
"args": [
"${workspaceFolder}/translate.ts"
],
"env": {
"NODE_OPTIONS": "-r esm"
}
}
]
}

12
explorer/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,12 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "clean",
"problemMatcher": [],
"label": "npm: clean",
"detail": "rm -rf public && rm -rf .cache"
}
]
}

15
explorer/Dockerfile Normal file
View File

@ -0,0 +1,15 @@
# syntax=docker.io/docker/dockerfile:experimental@sha256:de85b2f3a3e8a2f7fe48e8e84a65f6fdd5cd5183afa6412fff9caa6871649c44
# Derivative of ethereum/Dockerfile, look there for an explanation on how it works.
FROM node:lts-alpine@sha256:2ae9624a39ce437e7f58931a5747fdc60224c6e40f8980db90728de58e22af7c
RUN mkdir -p /app
WORKDIR /app
ADD . .
# create .env files from .env.sample, if they do not already exist.
RUN [[ ! -f .env.development ]] && cp .env.sample .env.development
RUN [[ ! -f .env.production ]] && cp .env.sample .env.production
RUN npm ci

90
explorer/README.md Normal file
View File

@ -0,0 +1,90 @@
# wormhole explorer
A web app built with:
- [GatsbyJS](https://www.gatsbyjs.com/)
- [gatsby-plugin-intl](https://www.gatsbyjs.com/plugins/gatsby-plugin-intl/)
- [Typescript](https://www.typescriptlang.org/)
- [Ant Design](https://ant.design/)
## Notable files
- Supported Languages - add/remove supported languages here [./src/utils/i18n/supportedLanguages.js](../src/utils/i18n/supportedLanguages.js)
- Multilangual copy [./src/locales](./src/locales)
- Top level pages & client side routes. Adding a file here creates a @reach-router route [./src/pages](./src/pages)
- SEO config, inherited by all pages [./src/components/SEO/SEO.tsx](./src/components/SEO/SEO.tsx)
- Main layout HOC, contains top-menu nav and footer [./src/components/Layout/DefaultLayout.tsx](./src/components/Layout/DefaultLayout.tsx)
- Gatsby plugins [./gatsby-config.js](./gatsby-config.js)
- Ant Design theme variables, overrides Antd defaults [./src/AntdTheme.js](./src/AntdTheme.js)
## Repo setup
Installing dependencies with npm:
npm install
Create a `.env` file for your development environment, from the `.env.sample`:
cp .env.sample .env.development
## Developing
Start the development server with the npm script:
npm run dev
Then open the web app in your browser at [http://localhost:8000](http://localhost:8000)
## Debugging
### NodeJs debugging with VSCode
You can debug the Gatsby dev server or build process using VSCode's debbuger. Checkout [.vscode/launch.json](./.vscode/launch.json) to see the NodeJS debugging options.
These debugger configs will let you set breakpoints in the Gatsby node programs ([./gatsby-config.js](./gatsby-config.js), [./gatsby-node.js](./gatsby-node.js)) to debug webpack, Gatsby plugins, etc.
### Browser debugging with VSCode
With the [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) extension installed, you can inspect the web app and set broswer breakpoints from VSCode. With the dev server (`npm run dev`) running, select & run [Debug in Chrome](./.vscode/launch.json#L12) from the debugger pane.
## Storybook component rendering
[Storybook](https://storybook.js.org/) can render components with sytles and locales, for UI component development.
Run Storybook with:
npm run storybook
See [./src/components/Button/button.stories.tsx](./src/components/Button/button.stories.tsx)
## eslint linting & formatting
Check linting:
npm run lint
Fix linting errors:
npm run format
## Ant Design Theming
Ant Design [default less variables](https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less) can be overridden in [./src/AntdTheme.js](./src/AntdTheme.js), which is used in [./gatsby-config.js#L51](./gatsby-config.js#L51).
## Programmatic Translations
Translations can be made for the supported languages ([./src/utils/i18n/supportedLanguages.js](../src/utils/i18n/supportedLanguages.js)). The English language definition file ([./src/locales/en.json](./src/locales/en.json)) will be read and used as the source, using either DeepL or Google Translate to supply the translations.
### Translating with DeepL
Pass your DeepL Pro api key to the npm script:
npm run translate:deepl -- your-DeepL-Pro-api-key-here
### Translating with Google Translate
With your Service Account [credentials](https://github.com/leolabs/json-autotranslate#google-translate) saved to a file locally, pass the path to the .json file to the npm script:
npm run translate:google -- ./your-GCP-service-account.json

View File

@ -0,0 +1,3 @@
// Related to jest.config.js `moduleNameMapper` on how to handle imports.
// Use this stub to mock static file imports which Jest cant handle
module.exports = 'test-file-stub';

View File

@ -0,0 +1,27 @@
import React from 'react';
const gatsbyPluginIntl = jest.requireActual('gatsby-plugin-intl');
module.exports = {
...gatsbyPluginIntl,
Link: jest
.fn()
.mockImplementation(
({
activeClassName,
activeStyle,
getProps,
innerRef,
partiallyActive,
ref,
replace,
to,
language,
...rest
}) =>
React.createElement('a', {
...rest,
href: to,
})
),
};

View File

@ -0,0 +1,29 @@
import React from 'react';
const gatsby = jest.requireActual('gatsby');
// Mocks graphql() function, Link component, and StaticQuery component
module.exports = {
...gatsby,
graphql: jest.fn(),
Link: jest.fn().mockImplementation(
// these props are invalid for an `a` tag
({
activeClassName,
activeStyle,
getProps,
innerRef,
partiallyActive,
ref,
replace,
to,
...rest
}) =>
React.createElement('a', {
...rest,
href: to,
})
),
StaticQuery: jest.fn(),
useStaticQuery: jest.fn(),
};

View File

@ -0,0 +1 @@
module.exports = { ReactComponent: 'icon-mock' };

View File

@ -0,0 +1,6 @@
import React from 'react';
import { App } from './src/components/App';
// Duplicated in gatsby-ssr.js for server side rendering during the build
export const wrapRootElement = props => <App {...props} />;

54
explorer/gatsby-config.js Normal file
View File

@ -0,0 +1,54 @@
import dotenv from 'dotenv';
import { getThemeVariables } from 'antd/dist/theme';
import supportedLanguages from './src/utils/i18n/supportedLanguages';
import antdThemeOverrides from './src/AntdTheme';
dotenv.config({
path: `.env.${process.env.NODE_ENV}`,
});
const languages = supportedLanguages.map(language => language.languageTag);
const plugins = [
'gatsby-plugin-react-helmet',
'gatsby-plugin-typescript',
'gatsby-plugin-remove-serviceworker',
'gatsby-plugin-svgr',
{
resolve: 'gatsby-plugin-intl',
options: {
path: `${__dirname}/src/locales`,
languages,
defaultLanguage: 'en',
redirect: true,
},
},
{
resolve: 'gatsby-plugin-antd',
options: {
style: true,
},
},
{
resolve: `gatsby-plugin-less`,
options: {
lessOptions: {
javascriptEnabled: true,
modifyVars: {
...getThemeVariables({
dark: true, // Enable dark mode
compact: true, // Enable compact mode,
}),
...antdThemeOverrides,
},
},
},
},
];
// Bundle analyzer, dev only
if (process.env.ENABLE_BUNDLE_ANALYZER === '1') {
plugins.push('gatsby-plugin-webpack-bundle-analyser-v2');
}
export { plugins };

46
explorer/gatsby-node.js Normal file
View File

@ -0,0 +1,46 @@
import path from 'path';
import dotenv from 'dotenv';
dotenv.config({
path: `.env.${process.env.NODE_ENV}`,
});
export const onCreateWebpackConfig = function addPathMapping({
stage,
actions,
getConfig,
}) {
actions.setWebpackConfig({
resolve: {
alias: {
'~': path.resolve(__dirname, 'src'),
},
},
});
// TODO: make sure this only runs in dev
actions.setWebpackConfig({
devtool: 'eval-source-map',
});
// Attempt to improve webpack vender code splitting
if (stage === 'build-javascript') {
const config = getConfig();
config.optimization.splitChunks.cacheGroups = {
...config.optimization.splitChunks.cacheGroups,
vendors: {
test: /[\\/]node_modules[\\/]/,
enforce: true,
chunks: 'all',
priority: 1,
},
};
// Ensure Gatsby does not do any css code splitting
config.optimization.splitChunks.cacheGroups.styles.priority = 10;
actions.replaceWebpackConfig(config);
}
};

37
explorer/gatsby-ssr.js Normal file
View File

@ -0,0 +1,37 @@
import React from 'react';
import dotenv from 'dotenv';
import { App } from './src/components/App';
import supportedLanguages from './src/utils/i18n/supportedLanguages';
dotenv.config({
path: `.env.${process.env.NODE_ENV}`,
});
// Duplicated in gatsby-browser.js for client side rendering
export const wrapRootElement = props => <App {...props} />;
export const onRenderBody = ({ pathname, setHeadComponents }) => {
// Create a string to allow a regex replacement for SEO hreflang links: https://support.google.com/webmasters/answer/189077?hl=en
const supportedLocaleRegexGroups = supportedLanguages
.map(language => language.languageTag)
.join('|');
const hrefLangLinks = [
...supportedLanguages.map(language => {
// Must be a fully qualified site URL
const href = `${process.env.GATSBY_SITE_URL}/${language.languageTag +
pathname.replace(new RegExp(`^/(${supportedLocaleRegexGroups})`), '')}`;
return (
<link
hrefLang={language.languageTag}
href={href}
key={`href-lang-${language.languageTag}`}
/>
);
}),
];
setHeadComponents(hrefLangLinks);
};

42
explorer/jest.config.js Normal file
View File

@ -0,0 +1,42 @@
const config = {
// all ts or tsx files need to be transformed using jest-preprocess.js
// Set up Babel config in jest-preprocess.js
transform: {
// Allow tests in TypeScript using the .ts or .tsx
'^.+\\.[jt]sx?$': '<rootDir>/test-utils/jest-preprocess.js',
},
testRegex: '(/__tests__/.*(test|spec))\\.([tj]sx?)$',
moduleDirectories: ['node_modules', __dirname],
// Works like webpack rules. Tells Jest how to handle imports
moduleNameMapper: {
// Mock static file imports and assets which Jest cant handle
// stylesheets use the package identity-obj-proxy
'.+\\.(css|styl|less|sass|scss)$': 'identity-obj-proxy',
// Manual mock other files using file-mock.js
'.+\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/file-mock.js',
// Mock SVG
'\\.svg': '<rootDir>/__mocks__/svgr-mock.js',
'^~/(.*)$': '<rootDir>/src/$1',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
testPathIgnorePatterns: ['node_modules', '.cache', 'public'],
// Gatsby includes un-transpiled ES6 code. Exclude the gatsby module.
transformIgnorePatterns: ['node_modules/(?!(gatsby)/)'],
globals: {
__PATH_PREFIX__: '',
},
collectCoverageFrom: [
'src/**/*.{js,jsx,ts,tsx}',
'!<rootDir>/src/**/*.stories.{ts,tsx}',
'!<rootDir>/src/**/__tests__/**/*',
'!<rootDir>/src/components/**/index.ts',
'!<rootDir>/node_modules/',
'!<rootDir>/test-utils/',
],
testURL: 'http://localhost',
setupFiles: ['<rootDir>/test-utils/loadershim.js', 'jest-localstorage-mock'],
setupFilesAfterEnv: ['<rootDir>/test-utils/setup-test-env.ts'],
};
module.exports = config;

8
explorer/jsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["src/*"],
}
}
}

24010
explorer/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

127
explorer/package.json Normal file
View File

@ -0,0 +1,127 @@
{
"name": "wormhole-explorer",
"author": "https://certus.one",
"description": "A visualizer for Wormhole Bridge info",
"version": "1.0.0",
"homepage": "https://github.com/certusone/wormhole",
"bugs": "https://github.com/certusone/wormhole",
"keywords": [
"gatsby",
"typescript",
"storybook",
"react-intl",
"svgr",
"jest",
"grpc",
"antd",
"ethereum",
"solana",
"terra",
"bsc",
"web3",
"defi"
],
"license": "MIT",
"jest": {
"setupTestFrameworkScriptFile": "<rootDir>/setup-test-env.js"
},
"scripts": {
"build": "NODE_OPTIONS='-r esm' gatsby build",
"clean": "rm -rf public && rm -rf .cache",
"dev": "npm run clean && NODE_OPTIONS='-r esm' node --max-http-header-size=16385 node_modules/.bin/gatsby develop --port=8001",
"debug": "npm run clean && NODE_OPTIONS='-r esm' node --nolazy --inspect-brk node_modules/.bin/gatsby develop",
"serve": "NODE_OPTIONS='-r esm' node --max-http-header-size=16385 node_modules/.bin/gatsby serve --port=8001",
"build-and-serve": "npm run build && npm run serve",
"lint": "npm run lint:js && npm run lint:ts",
"lint:js": "./node_modules/.bin/eslint --color --ext .js,.jsx .",
"lint:ts": "./node_modules/.bin/eslint --color --ext .ts,.tsx .",
"eslint-prettier-check-all": "npm run eslint-prettier-check-ts && npm run eslint-prettier-check-js",
"eslint-prettier-check-ts": "eslint --print-config src/pages/index.tsx | eslint-config-prettier-check",
"eslint-prettier-check-js": "eslint --print-config gatsby-browser.js | eslint-config-prettier-check",
"test": "jest",
"test:coverage": "npm run test --coverage",
"test:watch": "jest --watch",
"format": "npm run lint:js --fix && npm run lint:ts --fix",
"storybook": "NODE_OPTIONS='-r esm' gatsby build && NODE_OPTIONS='-r esm' start-storybook",
"storybook:build": "NODE_OPTIONS='-r esm' gatsby build && build-storybook -c .storybook -o .out",
"translate:deepl": "node_modules/.bin/json-autotranslate -i src/locales -d -m none --directory-structure ngx-translate --service=deepl -c",
"translate:google": "node_modules/.bin/json-autotranslate -i src/locales -d -m none --directory-structure ngx-translate --service=google-translate -c"
},
"dependencies": {
"@improbable-eng/grpc-web": "^0.14.0",
"@reach/router": "^1.3.1",
"@svgr/webpack": "^5.1.0",
"antd": "^4.15.4",
"babel-plugin-module-resolver": "^4.0.0",
"core-js": "2.6.10",
"dotenv": "^8.2.0",
"esm": "^3.2.25",
"gatsby": "^2.19.19",
"gatsby-image": "^2.2.41",
"gatsby-plugin-antd": "^2.2.0",
"gatsby-plugin-intl": "0.3.3",
"gatsby-plugin-less": "4.6.0",
"gatsby-plugin-react-helmet": "^3.1.22",
"gatsby-plugin-remove-serviceworker": "^1.0.0",
"gatsby-plugin-svgr": "^2.0.2",
"gatsby-plugin-typescript": "^2.1.27",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-helmet": "^5.2.1",
"react-time-ago": "^6.2.2"
},
"devDependencies": {
"@babel/core": "^7.8.4",
"@storybook/addon-actions": "^5.3.13",
"@storybook/addon-info": "^5.3.13",
"@storybook/addon-viewport": "^5.3.13",
"@storybook/preset-typescript": "^1.2.0",
"@storybook/react": "^5.3.13",
"@testing-library/jest-dom": "^5.1.1",
"@testing-library/react": "^9.4.0",
"@types/google-protobuf": "^3.15.2",
"@types/javascript-time-ago": "^2.0.2",
"@types/jest": "^25.1.3",
"@types/mocha": "^8.2.2",
"@types/node": "^13.7.4",
"@types/react": "^16.9.50",
"@types/react-dom": "^16.9.5",
"@types/react-helmet": "^5.0.15",
"@types/react-intl": "2.3.18",
"@types/storybook__react": "^5.2.1",
"@typescript-eslint/eslint-plugin": "^2.34.0",
"@typescript-eslint/parser": "^2.20.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^25.1.0",
"babel-loader": "^8.0.6",
"babel-plugin-jsx-remove-data-test-id": "^2.1.3",
"babel-plugin-remove-graphql-queries": "^2.7.23",
"babel-preset-gatsby": "^0.2.29",
"babel-preset-react-app": "^9.1.1",
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-airbnb-typescript": "^7.0.0",
"eslint-config-prettier": "^6.10.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jest": "^23.7.0",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-no-only-tests": "^2.4.0",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.18.3",
"eslint-plugin-react-hooks": "^2.4.0",
"gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.8",
"identity-obj-proxy": "^3.0.0",
"jest": "^25.1.0",
"jest-localstorage-mock": "^2.4.0",
"json-autotranslate": "^1.8.0",
"prettier": "^1.19.1",
"react-docgen-typescript-loader": "^3.6.0",
"react-test-renderer": "^16.12.0",
"storybook-addon-intl": "^2.4.1",
"ts-essentials": "^6.0.1",
"ts-jest": "^25.2.1",
"ts-loader": "^6.2.1",
"typescript": "^3.8.2"
}
}

21
explorer/src/@types/assets/index.d.ts vendored Normal file
View File

@ -0,0 +1,21 @@
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
declare module '*.jpg' {
const jpgContent: string;
export { jpgContent };
}
declare module '*.png' {
const pngContent: string;
export { pngContent };
}
declare module '*.json' {
const jsonContent: string;
export { jsonContent };
}

1
explorer/src/@types/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

View File

@ -0,0 +1 @@
declare module 'react-time-ago';

View File

@ -0,0 +1,4 @@
export default {
'primary-color': '#546e7a',
'link-color': 'lighten(@primary-color, 20%);', // lighten for proper contrast
};

View File

@ -0,0 +1,21 @@
/* the selector matches and external link (ie. starting with http),
not including links to the current domain */
[href^="http"]:not(.no-external-icon)::after {
content: "(external link)";
display: inline-block;
width: 1.1em;
height: 1.1em;
text-indent: 1em;
white-space: nowrap;
overflow: hidden;
background-image: url(../../icons/external.svg);
background-repeat: no-repeat;
background-position: center;
background-size: 100%;
margin-left: 0.3em;
}
// see if it's possible to use these in other less files
@header-height: 64px;
@footer-height: 88px;
@content-height: calc(~"100vh - (@{header-height} + @{footer-height})");

View File

@ -0,0 +1,18 @@
import { ReactNode } from 'react';
import TimeAgo from 'javascript-time-ago'
import en from 'javascript-time-ago/locale/en'
TimeAgo.addDefaultLocale(en)
import './App.less'
/**
* This component exists to provide a reusable application wrapper for use in Gatsby API's, testing, etc.
*/
const App = ({ element }: { element: ReactNode }) => {
return element;
};
export default App;

View File

@ -0,0 +1 @@
export { default as App } from './App';

View File

@ -0,0 +1,13 @@
# Example Stories and Tests
## Storybook: component rendering
Files that end in `*.stories.tsx` are rendered by storybook.
Storybook can be used to check component rendering, with styles and locales.
## Jest: component testing
Files that end in `*.test.tsx` are included in Jest testing (run with `yarn test`).
Jest can be used to ensure content (ie. language definiton) and accessiblity requirements are met.

View File

@ -0,0 +1,16 @@
import React from 'react';
import { render } from 'test-utils';
import { Button } from 'antd';
describe('<Button />', () => {
describe('Antd button rendering', () => {
test('should render Button component', () => {
const { getByText } = render(<Button>Click Me</Button>);
const button = getByText('Click Me');
expect(button).toBeTruthy()
});
});
});

View File

@ -0,0 +1,45 @@
import React from 'react';
import { FormattedMessage } from 'gatsby-plugin-intl';
import { Button } from 'antd';
export default {
title: 'Button',
};
export const Link = () => (
<Button type="link">
<FormattedMessage id="homepage.title" />
</Button>
);
export const Primary = () => (
<Button type="primary" >
<FormattedMessage id="homepage.title" />
</Button>
);
export const Large = () => (
<Button type="primary" size="large">
<FormattedMessage id="homepage.title" />
</Button>
);
export const Loading = () => (
<Button type="primary" loading>
<FormattedMessage id="homepage.title" />
</Button>
);
export const Outline = () => (
<Button type="ghost">
<FormattedMessage id="homepage.title" />
</Button>
);
export const Danger = () => (
<Button danger>
<FormattedMessage id="homepage.title" />
</Button>
);

View File

@ -0,0 +1,3 @@
.ant-table.ant-table-small .ant-table-tbody .ant-table-wrapper:only-child .ant-table {
margin: -4px -4px -4px 1px;
}

View File

@ -0,0 +1,76 @@
import React from 'react';
import { Table } from 'antd';
import { ColumnsType } from 'antd/es/table'
import { IntlShape } from 'gatsby-plugin-intl';
import ReactTimeAgo from 'react-time-ago'
import { Heartbeat, Heartbeat_Network } from '~/proto/gossip/v1/gossip'
import { ReactComponent as EthereumIcon } from '~/icons/ethereum.svg';
import { ReactComponent as SolanaIcon } from '~/icons/solana.svg';
import { ReactComponent as TerraIcon } from '~/icons/terra.svg';
import './GuardiansTable.less'
// TODO: find SOT for network enums
const networkEnums = ['Terra', 'Solana', 'Ethereum']
const networkIcons = [
<TerraIcon key="1" style={{ height: 18, margin: '0 4px' }} />,
<SolanaIcon key="2" style={{ height: 18, margin: '0 4px' }} />,
<EthereumIcon key="3" style={{ height: 24, margin: '0 4px' }} />
]
const expandedRowRender = (intl: IntlShape) => (item: Heartbeat) => {
const columns: ColumnsType<Heartbeat_Network> = [
{ title: '', dataIndex: 'id', key: 'icon', render: (id: number) => networkIcons[id] },
{ title: intl.formatMessage({ id: 'network.network' }), dataIndex: 'id', key: 'id', responsive: ['md'],
render: (id: number) => networkEnums[id]
},
{ title: intl.formatMessage({ id: 'network.address' }), dataIndex: 'bridgeAddress', key: 'bridgeAddress' },
{ title: intl.formatMessage({ id: 'network.blockHeight' }), dataIndex: 'height', key: 'height', responsive: ['md'], }
];
return (
<Table<Heartbeat_Network>
rowKey="id"
columns={columns}
dataSource={item.networks}
pagination={false}
/>
)
};
const GuardiansTable = ({ heartbeats, intl }: { heartbeats: { [nodeName: string]: Heartbeat }, intl: IntlShape }) => {
const columns: ColumnsType<Heartbeat> = [
{ title: intl.formatMessage({ id: 'network.guardian' }), key: 'guardian',
render: (item: Heartbeat) => <>{item.nodeName}<br />{item.guardianAddr}</>
},
{ title: intl.formatMessage({ id: 'network.version' }), dataIndex: 'version', key: 'version', responsive: ['lg'] },
{ title: intl.formatMessage({ id: 'network.networks' }), dataIndex: 'networks', key: 'networks', responsive: ['md'],
render: (networks: Heartbeat_Network[]) => networks.map(network => networkIcons[network.id])
},
{ title: intl.formatMessage({ id: 'network.heartbeat' }), dataIndex: 'counter', key: 'counter', responsive: ['xl'] },
{ title: intl.formatMessage({ id: 'network.lastHeartbeat' }), dataIndex: 'timestamp', key: 'timestamp', responsive: ['sm'],
render: (timestamp: string) =>
<ReactTimeAgo date={new Date(Number(timestamp.slice(0, -6)))} locale={intl.locale} timeStyle="round" />
}
];
return (
<Table<Heartbeat>
columns={columns}
size="small"
expandable={{
expandedRowRender: expandedRowRender(intl),
expandRowByClick: true,
}}
dataSource={Object.values(heartbeats)}
loading={Object.keys(heartbeats).length === 0}
rowKey="nodeName"
pagination={false}
/>
)
}
export default GuardiansTable

View File

@ -0,0 +1 @@
export { default as GuardiansTable } from './GuardiansTable';

View File

@ -0,0 +1,9 @@
// import theme to get antd less variables + overrides from AntdTheme.js
@import "~antd/lib/style/themes/dark";
.logo {
float: left;
font-size: 1.6rem;
font-weight: 700;
}

View File

@ -0,0 +1,62 @@
/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';
import { Layout, Menu } from 'antd';
const { Header, Content, Footer } = Layout;
import { useIntl, FormattedMessage } from 'gatsby-plugin-intl';
import { useLocation } from '@reach/router';
import { Link } from 'gatsby'
import './DefaultLayout.less'
type Props = {};
const DefaultLayout: React.FC<Props> = ({
children,
...props
}) => {
const intl = useIntl()
const location = useLocation()
return (
<Layout style={{ minHeight: '100vh' }}>
<Header>
<Menu
theme="dark"
mode="horizontal"
selectedKeys={[location.pathname.split('/')[2]]}
style={{display: 'flex', justifyContent: 'space-around'}}
>
<Menu.Item key="">
<Link to={`/${intl.locale}/`}>
<span className="logo">
<FormattedMessage id="homepage.title" />
</span>
</Link>
</Menu.Item>
<Menu.Item key="network">
<Link to={`/${intl.locale}/network/`}>{intl.formatMessage({id: "nav.networkLink"})}</Link>
</Menu.Item>
<Menu.Item key="code">
<a
href="https://github.com/certusone/wormhole"
target="_blank"
rel="noopener noreferrer"
>
{intl.formatMessage({id: "nav.codeLink"})}
</a>
</Menu.Item>
</Menu>
</Header>
<Content>
<div
{...props}
>
{children}
</div>
</Content>
<Footer style={{textAlign: 'center'}} className="primary-test">
{intl.formatMessage({id: "footer.createdWith"})}{``}<br />©{new Date().getFullYear()}
</Footer>
</Layout>
);
};
export default DefaultLayout;

View File

@ -0,0 +1 @@
export { default as Layout } from './DefaultLayout';

View File

@ -0,0 +1,53 @@
import React from 'react';
import Helmet, { HelmetProps } from 'react-helmet';
import { useIntl } from 'gatsby-plugin-intl';
import { Location } from '@reach/router';
type Props = {
/** Description text for the description meta tags */
description?: string;
} & HelmetProps
/**
* An SEO component that handles all element in the head that can accept
*/
const SEO: React.FC<Props> = ({ children, description = '', title}) => {
const metaDescription = description;
const intl = useIntl()
return (
<Location>
{({ location }) => (
<Helmet
htmlAttributes={{
lang: intl.locale,
}}
title={title}
>
<meta name="description" content={metaDescription} />
{/* OG tags */}
<meta
property="og:url"
content={process.env.GATSBY_SITE_URL + location.pathname}
/>
<meta property="og:type" content="website" />
<meta property="og:title" content={title} />
<meta property="og:description" content={metaDescription} />
<meta property="og:locale" content={intl.locale} />
{/* "summary" is the type of twitter card. Hardcoded string is OK here. */}
<meta property="twitter.card" content="summary" />
<meta property="twitter.creator" content="@CertusOne" />
<meta property="twitter.title" content={title} />
<meta property="twitter.description" content={metaDescription} />
{/* PWA tags */}
<meta name="theme-color" content="#546e7a"/>
{children}
</Helmet>
)}
</Location>
);
};
export default SEO

View File

@ -0,0 +1 @@
export { default as SEO } from './SEO';

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="BACKGROUND" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill:#F0B90B;}
</style>
<rect y="0" class="st0" width="512" height="512"/>
<g>
<path class="st1" d="M87.1,256.4l0.3,99.2l84.3,49.6v58.1L38,384.8V227.4L87.1,256.4z M87.1,157.2V215L38,186v-57.8l49.1-29
l49.3,29L87.1,157.2z M206.8,128.2l49.1-29l49.3,29l-49.3,29L206.8,128.2z"/>
<path class="st1" d="M122.5,335v-58.1l49.1,29v57.8L122.5,335L122.5,335z M206.8,425.9l49.1,29l49.3-29v57.8l-49.3,29l-49.1-29
L206.8,425.9z M375.6,128.2l49.1-29l49.3,29V186l-49.3,29v-57.8L375.6,128.2z M424.7,355.6l0.3-99.2l49.1-29v157.5l-133.6,78.4
v-58.1L424.7,355.6L424.7,355.6z"/>
<path class="st1" d="M389.5,335l-49.1,28.8V306l49.1-29V335z"/>
<path class="st1" d="M389.5,177.8l0.3,58.1l-84.5,49.6v99.4l-49.1,28.8l-49.1-28.8v-99.4l-84.5-49.6v-58.1l49.3-29l84,49.8
l84.5-49.8l49.3,29H389.5z M122.5,78.6L255.9,0l133.6,78.6l-49.1,29l-84.5-49.8l-84.3,49.8L122.5,78.6z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 163 40.4" class="">
<title>logo-certus-one-white</title>
<path d="M20.2 36.28A16.08 16.08 0 1135.05 14h4.38a20.2 20.2 0 100 12.34h-4.38a16.1 16.1 0 01-14.85 9.94z"
fill="rgba(0,64,220,.9)"></path>
<path
d="M27.75 22.26a7.84 7.84 0 110-4.12h8.4a16.08 16.08 0 00-1.1-4.14h-4.63a12 12 0 100 12.34h4.63a16.08 16.08 0 001.1-4.11zM39.43 26.38h4.26a24.46 24.46 0 00.7-4.12h-4.13a20.06 20.06 0 01-.83 4.12zM40.27 18.14h4.12a24.18 24.18 0 00-.71-4.14h-4.25a19.85 19.85 0 01.84 4.14z"
fill="rgba(0,64,220,.9)"></path>
<path d="M40.37 20.2c0-.7 0-1.38-.1-2.06h-4.12a16.39 16.39 0 010 4.12h4.12c.06-.68.1-1.37.1-2.06z" fill="rgba(0,64,220,.9)">
</path>
<circle cx="20.18" cy="20.16" r="3.22" fill="rgba(0,64,220,.9)"></circle>
<path
d="M48.46 18.14H44.4c.05.67.09 1.34.09 2s0 1.41-.1 2.1h4.06q.09-1 .09-2.1c0-.66-.03-1.33-.08-2zM62.8 27.17a7 7 0 115.88-10.78 5.64 5.64 0 01.91 2.19H66a3.5 3.5 0 00-3.25-2.34 3.7 3.7 0 00-3.6 3.92 3.78 3.78 0 003.62 4A3.55 3.55 0 0066 21.89h3.59a6.89 6.89 0 01-6.79 5.28zM133 27.12a6.91 6.91 0 01-7-6.78 7.72 7.72 0 01.53-2.86 6.11 6.11 0 01.87-1.5 7 7 0 115.6 11.14zm0-10.89a3.72 3.72 0 00-3.66 3.91 3.66 3.66 0 107.29.05 3.76 3.76 0 00-3.56-3.96zM88.72 16.94a3.32 3.32 0 00-1.8.48 2.83 2.83 0 00-1.13 1.42v-1.71h-3.1v9.76h3.2v-4.83a2.62 2.62 0 01.15-.88 2 2 0 01.46-.74 2.49 2.49 0 01.75-.51 3.7 3.7 0 011-.19h.49zM96.31 19.76h-2v3.88a.81.81 0 00.31.76 1.65 1.65 0 00.83.17h.42a2.82 2.82 0 01.41 0v2.35l-.87.05a8.77 8.77 0 01-.88 0 7.19 7.19 0 01-1.68-.17 2 2 0 01-1.59-1.61 7.65 7.65 0 01-.15-1.66v-3.77h-1.04V17h1.07v-2.82h3.2V17h2zM107.65 26.89h-3.1v-1.34a3.2 3.2 0 01-1.28 1.19 3.75 3.75 0 01-1.69.43 4.58 4.58 0 01-1.74-.29 2.65 2.65 0 01-1.15-.88 3.33 3.33 0 01-.59-1.32 8.15 8.15 0 01-.17-1.68v-5.87h3.2v5.66a1.83 1.83 0 00.4 1.36 1.65 1.65 0 001.18.39 1.7 1.7 0 00.56-.1 1.54 1.54 0 00.57-.34 2.23 2.23 0 00.44-.67 2.71 2.71 0 00.18-1.07v-5.23h3.19zM112.41 23.67a1.29 1.29 0 00.52 1.09 1.51 1.51 0 00.54.26 2.75 2.75 0 00.65.08 2.25 2.25 0 00.49-.06 1.62 1.62 0 00.48-.17 1.32 1.32 0 00.38-.32.78.78 0 00.15-.48.65.65 0 00-.17-.46 1.28 1.28 0 00-.4-.29 1.8 1.8 0 00-.51-.17l-.48-.12c-.5-.12-1-.23-1.55-.33a6.17 6.17 0 01-1.47-.47 3 3 0 01-1.09-.85 2.47 2.47 0 01-.42-1.54 2.4 2.4 0 01.42-1.46 3.28 3.28 0 011.08-.91 5 5 0 011.45-.48 9 9 0 011.51-.14 9.28 9.28 0 011.58.14 4.59 4.59 0 011.42.49 2.85 2.85 0 011.05 1 3.06 3.06 0 01.44 1.57h-3a.93.93 0 00-.42-.85 1.86 1.86 0 00-1-.24 3.31 3.31 0 00-.44 0 1.63 1.63 0 00-.45.09.89.89 0 00-.34.23.52.52 0 00-.14.39.65.65 0 00.35.56 3.13 3.13 0 00.9.37c.35.09.74.18 1.17.25l1.19.23a3.52 3.52 0 011.21.47 2.87 2.87 0 01.76.7 2.16 2.16 0 01.39.77 2.38 2.38 0 01.12.69 3 3 0 01-.43 1.65 3.28 3.28 0 01-1.09 1.07 4.74 4.74 0 01-1.5.58 7.88 7.88 0 01-1.66.18 8.85 8.85 0 01-1.71-.16 4.83 4.83 0 01-1.52-.56 3.25 3.25 0 01-1.09-1.09 3.43 3.43 0 01-.46-1.69zM120.74 23.39h3.5v3.5h-3.5zM141.5 17.13h3.1v1.34a3 3 0 01.56-.68 3.61 3.61 0 01.76-.51 4.22 4.22 0 01.86-.32 3.92 3.92 0 01.88-.11 4 4 0 011.93.39 2.83 2.83 0 011.05 1 3.21 3.21 0 01.45 1.23 8.93 8.93 0 01.09 1.19v6.26H148v-5.7a2.32 2.32 0 00-.14-.86 1.24 1.24 0 00-.47-.61 1.65 1.65 0 00-1-.24 1.61 1.61 0 00-.78.18 1.64 1.64 0 00-.54.47 2.06 2.06 0 00-.31.67 2.8 2.8 0 00-.1.77v5.32h-3.2zM81.22 22a5.22 5.22 0 10-10.43-.09 5.26 5.26 0 005 5.21h.69a6.28 6.28 0 001.24-.12 5 5 0 001.43-.58 4.13 4.13 0 001.12-1 3.93 3.93 0 00.73-1.48h-3a1.51 1.51 0 01-.73.8 2.29 2.29 0 01-1.09.27 2.05 2.05 0 01-1.58-.6 1.77 1.77 0 01-.31-.46 2.61 2.61 0 01-.29-1.16h7.16a4.19 4.19 0 00.06-.79zm-5.17-3a1.75 1.75 0 011.34.58A2.17 2.17 0 0178 21h-4a2.63 2.63 0 01.68-1.44 1.84 1.84 0 011.37-.56zM163 22a5.22 5.22 0 10-10.43-.09 5.26 5.26 0 005 5.21h.69a6.5 6.5 0 001.24-.12 4.82 4.82 0 001.42-.58 4 4 0 001.13-1 3.93 3.93 0 00.71-1.45h-3a1.55 1.55 0 01-.73.8 2.33 2.33 0 01-1.1.27 2 2 0 01-1.57-.6 2.1 2.1 0 01-.32-.46 2.61 2.61 0 01-.28-1.16h7.16A4.19 4.19 0 00163 22zm-5.17-3a1.75 1.75 0 011.34.58 2.17 2.17 0 01.56 1.41h-4a2.57 2.57 0 01.69-1.44 1.84 1.84 0 011.41-.55z"
fill="rgba(0,64,220,.9)"></path>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Creator: CorelDRAW 2019 (64-Bit) -->
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="100%" height="100%" version="1.1" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"
viewBox="0 0 784.37 1277.39"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<g id="_1421394342400">
<g>
<polygon fill="#343434" fill-rule="nonzero" points="392.07,0 383.5,29.11 383.5,873.74 392.07,882.29 784.13,650.54 "/>
<polygon fill="#8C8C8C" fill-rule="nonzero" points="392.07,0 -0,650.54 392.07,882.29 392.07,472.33 "/>
<polygon fill="#3C3C3B" fill-rule="nonzero" points="392.07,956.52 387.24,962.41 387.24,1263.28 392.07,1277.38 784.37,724.89 "/>
<polygon fill="#8C8C8C" fill-rule="nonzero" points="392.07,1277.38 392.07,956.52 -0,724.89 "/>
<polygon fill="#141414" fill-rule="nonzero" points="392.07,882.29 784.13,650.54 392.07,472.33 "/>
<polygon fill="#393939" fill-rule="nonzero" points="0,650.54 392.07,882.29 392.07,472.33 "/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<path fill="#000" stroke="#546e7a" stroke-width="10"
d="m43,35H5v60h60V57M45,5v10l10,10-30,30 20,20 30-30 10,10h10V5z"/>
</svg>

After

Width:  |  Height:  |  Size: 232 B

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 397.7 311.7" style="enable-background:new 0 0 397.7 311.7;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#SVGID_1_);}
.st1{fill:url(#SVGID_2_);}
.st2{fill:url(#SVGID_3_);}
</style>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="360.8791" y1="351.4553" x2="141.213" y2="-69.2936" gradientTransform="matrix(1 0 0 -1 0 314)">
<stop offset="0" style="stop-color:#00FFA3"/>
<stop offset="1" style="stop-color:#DC1FFF"/>
</linearGradient>
<path class="st0" d="M64.6,237.9c2.4-2.4,5.7-3.8,9.2-3.8h317.4c5.8,0,8.7,7,4.6,11.1l-62.7,62.7c-2.4,2.4-5.7,3.8-9.2,3.8H6.5
c-5.8,0-8.7-7-4.6-11.1L64.6,237.9z"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="264.8291" y1="401.6014" x2="45.163" y2="-19.1475" gradientTransform="matrix(1 0 0 -1 0 314)">
<stop offset="0" style="stop-color:#00FFA3"/>
<stop offset="1" style="stop-color:#DC1FFF"/>
</linearGradient>
<path class="st1" d="M64.6,3.8C67.1,1.4,70.4,0,73.8,0h317.4c5.8,0,8.7,7,4.6,11.1l-62.7,62.7c-2.4,2.4-5.7,3.8-9.2,3.8H6.5
c-5.8,0-8.7-7-4.6-11.1L64.6,3.8z"/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="312.5484" y1="376.688" x2="92.8822" y2="-44.061" gradientTransform="matrix(1 0 0 -1 0 314)">
<stop offset="0" style="stop-color:#00FFA3"/>
<stop offset="1" style="stop-color:#DC1FFF"/>
</linearGradient>
<path class="st2" d="M333.1,120.1c-2.4-2.4-5.7-3.8-9.2-3.8H6.5c-5.8,0-8.7,7-4.6,11.1l62.7,62.7c2.4,2.4,5.7,3.8,9.2,3.8h317.4
c5.8,0,8.7-7,4.6-11.1L333.1,120.1z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 2000 2000" style="enable-background:new 0 0 2000 2000;" xml:space="preserve">
<style type="text/css">
.st0{fill:#172852;}
.st1{fill:#FFD83D;}
.st2{fill:#FF6F03;}
</style>
<circle class="st0" cx="1000" cy="1000" r="1000"/>
<g>
<path class="st1" d="M805.5,446.9c117.1-43.8,248.9-43.9,368.2-7.9c155.3,48.2,286.4,165.4,354.9,312.5
c18.9,41.9,37,85.6,38.8,132.2c-87.3-50.6-183-83.4-278.9-113.3c-153.4-55.3-314-93.7-459.2-169.7c-33.8-20.2-76.9-40.9-86.1-83
C739.5,481.3,778,461,805.5,446.9"/>
<path class="st1" d="M452,800.9c33.9-92,89.5-177.4,165-240.7c19.2,157.9,86.4,310.5,197.4,425.3
c133.1,138.3,322.7,223.2,515.6,220c76.6,2.4,151.5-15.3,226.2-29.6c-73.5,265.6-364.6,441.9-634.3,399.5
c-162.8-20.8-313.1-117.2-403.8-253.3C415.8,1171.7,390,972,452,800.9z"/>
</g>
<path class="st2" d="M1288.5,770.4c95.9,29.9,191.6,62.7,278.9,113.3l5.9,3.1c8.1,60.9,14,123,3.2,184
c-43.9-18.6-79.5-51.3-116.7-80.2C1388.2,931,1315.1,862.8,1288.5,770.4"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,31 @@
{
"homepage": {
"title": "Wormhole Bridge",
"description": "A decentralized multi-chain event protocol, for DeFi",
"subtext": "A new way to bridge between chains and verify layer-1 events"
},
"nav": {
"networkLink": "network",
"codeLink": "code"
},
"footer": {
"createdWith": "Built with"
},
"404": {
"message": "The page you visited does not exist"
},
"network": {
"title": "Wormhole Network",
"description": "The Wormhole Bridge Guardians",
"listening": "Listening for Guardian heartbeats...",
"guardiansFound": "Guardians currently validating",
"heartbeat": "Heartbeat #",
"blockHeight": "Block height",
"address": "Address",
"network": "Network",
"networks": "Networks",
"version": "Version",
"lastHeartbeat": "Last Heartbeat",
"guardian": "Guardian"
}
}

View File

@ -0,0 +1,12 @@
import React from 'react'
import { Result } from 'antd'
import { useIntl } from 'gatsby-plugin-intl';
export default () => {
const intl = useIntl()
return <Result
status="404"
title="404"
subTitle={intl.formatMessage({id: '404.message'})}
/>
}

View File

@ -0,0 +1,168 @@
import React, { useRef, useEffect } from 'react';
import { Typography } from 'antd'
const { Title } = Typography
import { useIntl } from 'gatsby-plugin-intl';
import { Layout } from '~/components/Layout';
import { SEO } from '~/components/SEO';
import { ReactComponent as EthereumIcon } from '~/icons/ethereum.svg';
import { ReactComponent as SolanaIcon } from '~/icons/solana.svg';
import { ReactComponent as TerraIcon } from '~/icons/terra.svg';
import { ReactComponent as BinanceChainIcon } from '~/icons/binancechain.svg';
const headerHeight = 64
const footerHeight = 88
const contentHeight = `calc(100vh - (${headerHeight}px + ${footerHeight}px))`
const Index = () => {
const intl = useIntl()
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
if (canvasRef.current) {
// (maybe) TODO: refactor this away from es5?
// maybe not, as this will be replaced by Breakout (design firm) designs.
// pulled this animation from here https://codepen.io/lans/pen/WQGZoZ
// Global Animation Setting
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback: any) {
window.setTimeout(callback, 1000 / 60);
};
// Global Canvas Setting
let canvas = canvasRef.current // document.getElementById('particle');
let ctx = canvas.getContext('2d');
if (ctx != null) {
const resizeCanvas = () => {
canvas.width = window.innerWidth
canvas.height = (window.innerHeight - (headerHeight + footerHeight))
emitter = new Emitter(canvas.width / 2, canvas.height / 2);
}
window.addEventListener('resize', resizeCanvas, false);
canvas.width = window.innerWidth
canvas.height = (window.innerHeight - (headerHeight + footerHeight))
// Particles Around the Parent
const Particle = function (x: number, y: number, dist: number, rbgStr: string) {
this.angle = Math.random() * 2 * Math.PI;
this.radius = Math.random();
this.opacity = (Math.random() * 5 + 2) / 10;
this.distance = (1 / this.opacity) * dist;
this.speed = this.distance * 0.00009
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
this.draw = function () {
if (!ctx) return
ctx.fillStyle = `rgba(${rbgStr},${this.opacity})`
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2, false);
ctx.fill();
ctx.closePath();
}
this.update = function () {
this.angle += this.speed;
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
this.draw();
}
}
const Emitter = function (x: number, y: number) {
this.position = { x: x, y: y };
this.radius = 60;
this.count = 4000;
this.particles = [];
for (var i = 0; i < this.count; i++) {
this.particles.push(new Particle(this.position.x, this.position.y, this.radius, "255,233,31"));
this.particles.push(new Particle(this.position.x, this.position.y, this.radius, "255,110,253"));
this.particles.push(new Particle(this.position.x, this.position.y, this.radius, "166,128,255"));
this.particles.push(new Particle(this.position.x, this.position.y, this.radius, "128,232,255"));
}
}
Emitter.prototype = {
draw: function () {
if (!ctx) return
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2, false);
ctx.fill();
ctx.closePath();
},
update: function () {
for (var i = 0; i < this.count; i++) {
this.particles[i].update();
}
this.draw();
}
}
let emitter = new Emitter(canvas.width / 2, canvas.height / 2);
const loop = () => {
if (!ctx) return
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.canvas.width = window.innerWidth
ctx.canvas.height = (window.innerHeight - (headerHeight + footerHeight))
emitter.update();
window.requestAnimFrame(loop);
}
loop();
}
}
}, []);
const iconStyles = { width: 100, margin: '0 4px' }
const iconWithCaption = (IconEle: React.ElementType, caption: string, figureStyle: object = {}) => {
return <figure style={{...iconStyles, ...figureStyle}}>
<IconEle />
<figcaption style={{textAlign: 'center'}}>{caption}</figcaption>
</figure>
}
return (
<Layout>
<SEO
title={intl.formatMessage({ id: 'homepage.title' })}
description={intl.formatMessage({ id: 'homepage.description' })}
/>
<div style={{ position: 'relative', height: contentHeight, width:"100vw" }}>
<div style={{ position: 'absolute', top: '5vh', zIndex: 100, width: '100%', textAlign: 'center'}}>
<Title level={1}>{intl.formatMessage({ id: 'homepage.description' })}</Title>
<Title level={2}>{intl.formatMessage({ id: 'homepage.subtext' })}</Title>
</div>
<div style={{ position: 'absolute', bottom: '5vh', zIndex: 100, width: '100%' }}>
<div style={{ display: 'flex', justifyContent: 'space-evenly', alignContent: 'flex-end',
alignItems: 'center', margin: '0 8px'}}>
{iconWithCaption(EthereumIcon, 'Ethereum', {width: 70})}
{iconWithCaption(TerraIcon, 'Terra')}
{iconWithCaption(BinanceChainIcon, 'Binance Smart Chain')}
{iconWithCaption(SolanaIcon, 'Solana')}
</div>
</div>
<canvas ref={canvasRef} height={contentHeight} width="100vw" style={{ position: 'relative', zIndex: 99 }} />
</div>
</Layout>
);
};
export default Index

View File

@ -0,0 +1,62 @@
import React, { useEffect, useState } from 'react';
import { Typography } from 'antd';
const { Title } = Typography;
import { injectIntl, WrappedComponentProps } from 'gatsby-plugin-intl';
import { grpc } from '@improbable-eng/grpc-web';
import { Layout } from '~/components/Layout';
import { SEO } from '~/components/SEO';
import { GuardiansTable } from '~/components/GuardiansTable'
import { Heartbeat } from '~/proto/gossip/v1/gossip'
import { PublicrpcGetRawHeartbeatsDesc, GetRawHeartbeatsRequest } from '~/proto/publicrpc/v1/publicrpc'
const Network = ({ intl }: WrappedComponentProps) => {
const [heartbeats, setHeartbeats] = useState<{ [nodeName: string]: Heartbeat }>({})
const addHeartbeat = (hb: grpc.ProtobufMessage) => {
const hbObj = hb.toObject() as Heartbeat
hbObj.networks.sort((a, b) => b.id - a.id)
const { nodeName } = hbObj
heartbeats[nodeName] = hbObj
setHeartbeats({ ...heartbeats })
}
useEffect(() => {
const client = grpc.client(PublicrpcGetRawHeartbeatsDesc, {
host: String(process.env.GATSBY_APP_RPC_URL)
})
client.onMessage(addHeartbeat)
client.start()
client.send({ serializeBinary: () => GetRawHeartbeatsRequest.encode({}).finish(), toObject: () => { return {} } })
return function cleanup() {
client.close()
}
}, [])
return (
<Layout>
<SEO
title={intl.formatMessage({ id: 'network.title' })}
description={intl.formatMessage({ id: 'network.description' })}
/>
<div style={{ margin: '1em' }}>
<Title level={1}>{intl.formatMessage({ id: 'network.title' })}</Title>
{Object.keys(heartbeats).length === 0 ?
<Title level={2}>
{intl.formatMessage({ id: 'network.listening' })}
</Title>
:
<Title level={2}>
{Object.keys(heartbeats).length}&nbsp;
{intl.formatMessage({ id: 'network.guardiansFound' })}
</Title>
}
<GuardiansTable heartbeats={heartbeats} intl={intl} />
</div>
</Layout>
)
};
export default injectIntl(Network)

View File

@ -0,0 +1,8 @@
type Language = {
label: string
languageTag: string
}
const supportedLanguages = require('./supportedLanguages') as Language[]
export { supportedLanguages };

View File

@ -0,0 +1,8 @@
// NOTE, we don't translate the language labels, they should appear translated for their target audience.
export default [
{
label: 'English',
languageTag: 'en',
}
];

View File

@ -0,0 +1,20 @@
import { isBrowser } from '~/utils/system';
// eslint-disable-next-line @typescript-eslint/unbound-method
if (isBrowser() && !window.HTMLCanvasElement.prototype.toBlob) {
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
value(callback: BlobCallback, type?: string | undefined, quality?: number) {
setTimeout(() => {
const binStr = atob(this.toDataURL(type, quality).split(',')[1]);
const len = binStr.length;
const arr = new Uint8Array(len);
for (let i = 0; i < len; i += 1) {
arr[i] = binStr.charCodeAt(i);
}
callback(new Blob([arr], { type: type || 'image/png' }));
});
},
});
}

View File

@ -0,0 +1 @@
export { default as isBrowser } from './isBrowser';

View File

@ -0,0 +1,10 @@
/**
* Checks if window is available. Helps determine wether the code being executed
* is in a node context or a browser context.
*
* @export
* @returns
*/
export default function isBrowser() {
return typeof window !== 'undefined';
}

View File

@ -0,0 +1,9 @@
import { Link } from 'gatsby';
export type GetRenderComponentProps<T> = T extends
| React.ComponentType
| typeof Link
? React.ComponentProps<T>
: T extends 'a'
? React.HTMLProps<T>
: {};

BIN
explorer/static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,25 @@
import React, { ReactElement, ComponentProps, FunctionComponent } from 'react';
import { render } from '@testing-library/react';
import { IntlProvider } from 'react-intl';
import * as messages from '~/locales/en.json';
const AllTheProviders: React.FC = ({ children }) => {
return (
<IntlProvider locale="en" messages={messages}>
{children}
</IntlProvider>
);
};
const customRender = (
ui: ReactElement<ComponentProps<FunctionComponent>>,
options?: object
) => render(ui, { wrapper: AllTheProviders, ...options });
// re-export everything
export * from '@testing-library/react';
// override render method
export { customRender as render };

View File

@ -0,0 +1,6 @@
// Set up Babel config
const babelOptions = {
presets: ['babel-preset-gatsby', '@babel/preset-typescript'],
};
module.exports = require('babel-jest').createTransformer(babelOptions);

View File

@ -0,0 +1,7 @@
/* eslint-disable no-underscore-dangle */
// Related to jest.config.js globals
// Load in this loadershim into `setupFiles` for all files that will be included before all tests are run
global.___loader = {
enqueue: jest.fn(),
};

View File

@ -0,0 +1,5 @@
import '@testing-library/jest-dom/extend-expect';
// import { matchers } from 'jest-emotion';
// expect.extend(matchers);

28
explorer/tsconfig.json Normal file
View File

@ -0,0 +1,28 @@
{
"compileOnSave": false,
"compilerOptions": {
"target": "es5",
"module": "es6",
"types": ["node", "jest", "mocha"],
"moduleResolution": "node",
"esModuleInterop": true,
"typeRoots": ["./src/@types", "./node_modules/@types"],
"lib": ["dom", "es2015", "es2017", "es2018", "esnext.intl", "es2017.intl", "es2018.intl"],
"jsx": "react",
"sourceMap": true,
"strict": true,
"resolveJsonModule": true,
"noUnusedLocals": true,
"noImplicitAny": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"downlevelIteration": true,
"baseUrl": "./",
"paths": {
"~/*": ["src/*"],
}
},
"include": ["./src/**/*", "./test-utils/**/*", "./__mocks__/**/*"],
"exclude": ["node_modules", "plugins"]
}

View File

@ -3,6 +3,7 @@
( (
cd tools/ cd tools/
./build.sh ./build.sh
npm install
) )
( (
@ -16,10 +17,24 @@ tools/bin/buf protoc \
-Iproto \ -Iproto \
-Ithird_party/googleapis \ -Ithird_party/googleapis \
--plugin tools/bin/protoc-gen-go \ --plugin tools/bin/protoc-gen-go \
--go_opt=module=github.com/certusone/wormhole/bridge/pkg \
--go_out=bridge/pkg/ proto/**/**/** --go_out=bridge/pkg/ proto/**/**/**
tools/bin/buf protoc \ tools/bin/buf protoc \
-Iproto \ -Iproto \
-Ithird_party/googleapis \ -Ithird_party/googleapis \
--plugin tools/bin/protoc-gen-go-grpc \ --plugin tools/bin/protoc-gen-go-grpc \
--go-grpc_opt=module=github.com/certusone/wormhole/bridge/pkg \
--go-grpc_out=bridge/pkg/ proto/**/**/** --go-grpc_out=bridge/pkg/ proto/**/**/**
mkdir -p explorer/src/proto
tools/bin/buf protoc \
-Iproto \
-Ithird_party/googleapis \
--plugin tools/node_modules/.bin/protoc-gen-ts_proto \
--ts_proto_opt=esModuleInterop=true \
--ts_proto_opt=env=browser \
--ts_proto_opt=forceLong=string \
--ts_proto_opt=outputClientImpl=grpc-web \
--ts_proto_out=explorer/src/proto/ proto/**/**/**

View File

@ -4,7 +4,7 @@ package agent.v1;
// TODO: documentation // TODO: documentation
option go_package = "proto/agent/v1;agentv1"; option go_package = "github.com/certusone/wormhole/bridge/pkg/proto/agent/v1;agentv1";
service Agent { service Agent {
rpc SubmitVAA (SubmitVAARequest) returns (SubmitVAAResponse); rpc SubmitVAA (SubmitVAARequest) returns (SubmitVAAResponse);
@ -16,6 +16,7 @@ message Empty {
message SubmitVAARequest { message SubmitVAARequest {
bytes vaa = 1; bytes vaa = 1;
bool skip_preflight = 2;
} }
message SubmitVAAResponse { message SubmitVAAResponse {

View File

@ -2,7 +2,8 @@ syntax = "proto3";
package gossip.v1; package gossip.v1;
option go_package = "proto/gossip/v1;gossipv1"; // full path of the resulting Go file is required in order to import in whisper.proto
option go_package = "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1;gossipv1";
message GossipMessage { message GossipMessage {
oneof message { oneof message {

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package node.v1; package node.v1;
option go_package = "proto/node/v1;nodev1"; option go_package = "github.com/certusone/wormhole/bridge/pkg/proto/node/v1;nodev1";
import "google/api/annotations.proto"; import "google/api/annotations.proto";

View File

@ -0,0 +1,22 @@
syntax = "proto3";
// only relevant for protobuf namespace
package publicrpc.v1;
// only relevant for Go namespace
option go_package = "github.com/certusone/wormhole/bridge/pkg/proto/publicrpc/v1;publicrpcv1";
// public import will include the required types in the Go output
import public "gossip/v1/gossip.proto";
// Publicrpc service exposes endpoints to be consumed externally; GUIs, historical record keeping, etc.
service Publicrpc {
// GetRawHeartbeats rpc endpoint returns a stream of the p2p heartbeat messages received.
// The GetRawHeartbeats stream will include all messages received by the guardian,
// without any filtering or verification of message content.
rpc GetRawHeartbeats (GetRawHeartbeatsRequest) returns (stream gossip.v1.Heartbeat);
}
// GetRawHeartbeatsRequest is an empty request, sent as part of a request to start a stream.
message GetRawHeartbeatsRequest {
}

View File

@ -92,7 +92,7 @@ impl Agent for AgentImpl {
}; };
for mut tx in verify_txs { for mut tx in verify_txs {
match sign_and_send(&rpc, &mut tx, vec![&key]) { match sign_and_send(&rpc, &mut tx, vec![&key], request.skip_preflight) {
Ok(_) => (), Ok(_) => (),
Err(e) => { Err(e) => {
return Err(Status::new( return Err(Status::new(
@ -104,13 +104,13 @@ impl Agent for AgentImpl {
} }
let mut transaction2 = Transaction::new_with_payer(&[ix], Some(&key.pubkey())); let mut transaction2 = Transaction::new_with_payer(&[ix], Some(&key.pubkey()));
match sign_and_send(&rpc, &mut transaction2, vec![&key]) { match sign_and_send(&rpc, &mut transaction2, vec![&key], request.skip_preflight) {
Ok(s) => Ok(Response::new(SubmitVaaResponse { Ok(s) => Ok(Response::new(SubmitVaaResponse {
signature: s.to_string(), signature: s.to_string(),
})), })),
Err(e) => Err(Status::new( Err(e) => Err(Status::new(
Code::Internal, Code::Internal,
format!("tx sending failed: {}", e), format!("tx sending failed: {:?}", e),
)), )),
} }
}) })
@ -253,7 +253,7 @@ fn pack_sig_verification_txs<'a>(
let payload = VerifySigPayload { let payload = VerifySigPayload {
signers: signature_status, signers: signature_status,
hash: vaa_hash, hash: vaa_hash,
initial_creation: tx_index == 0, initial_creation: false,
}; };
let verify_ix = match verify_signatures( let verify_ix = match verify_signatures(
@ -285,6 +285,7 @@ fn sign_and_send(
rpc: &RpcClient, rpc: &RpcClient,
tx: &mut Transaction, tx: &mut Transaction,
keys: Vec<&Keypair>, keys: Vec<&Keypair>,
skip_preflight: bool,
) -> Result<Signature, ClientError> { ) -> Result<Signature, ClientError> {
let (recent_blockhash, _fee_calculator) = rpc.get_recent_blockhash()?; let (recent_blockhash, _fee_calculator) = rpc.get_recent_blockhash()?;
@ -296,7 +297,7 @@ fn sign_and_send(
commitment: CommitmentLevel::Processed, commitment: CommitmentLevel::Processed,
}, },
RpcSendTransactionConfig { RpcSendTransactionConfig {
skip_preflight: false, skip_preflight,
preflight_commitment: Some(CommitmentLevel::Processed), preflight_commitment: Some(CommitmentLevel::Processed),
encoding: None, encoding: None,
}, },

View File

@ -3,8 +3,8 @@ module github.com/certusone/wormhole/bridge/tools
go 1.14 go 1.14
require ( require (
github.com/bufbuild/buf v0.27.1 github.com/bufbuild/buf v0.43.0
github.com/spf13/cobra v1.1.1 github.com/spf13/cobra v1.1.3
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0
google.golang.org/protobuf v1.25.0 google.golang.org/protobuf v1.26.1-0.20210520194023-50a85913fbce
) )

View File

@ -17,6 +17,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
@ -26,11 +27,14 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1U
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bufbuild/buf v0.27.1 h1:OLDamR4ReadO93ImDwz7PQ7Ua6p/xf/cRP252m5PBuk= github.com/bufbuild/buf v0.43.0 h1:viYO0nNip/Bb0n1PJm/5pEI5UPlTXw/0sNmbudnyRlU=
github.com/bufbuild/buf v0.27.1/go.mod h1:q8CGqHamyFxjZqrxS/6G72s7xTVr5zBAkiyhAOlb60c= github.com/bufbuild/buf v0.43.0/go.mod h1:QR9e01JeNXUOrt6FOAsFaBLYB2TMXZ8NITzdr0BGGsg=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 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/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@ -42,7 +46,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
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.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/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
@ -53,14 +61,14 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84= github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY=
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@ -69,36 +77,46 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 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.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.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-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.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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.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.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.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.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 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.3/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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -122,17 +140,18 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jhump/protoreflect v1.7.1-0.20200723220026-11eaaf73e0ec h1:LeWD9kGWul9js18sWzNP2SjMuO6smUEpXt8OmRs7qU0= github.com/jhump/protoreflect v1.8.3-0.20210527202629-05026f325d15 h1:aMVEeA7R0Mf8bZ5vUe3r4dy+ahhkjYEVsQXVJQMc5pQ=
github.com/jhump/protoreflect v1.7.1-0.20200723220026-11eaaf73e0ec/go.mod h1:D8nEtk+lKr8kMTMiLayswAtSSeHYDaRYk9r78Cy11mM= github.com/jhump/protoreflect v1.8.3-0.20210527202629-05026f325d15/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.11.1 h1:bPb7nMRdOZYDrpPMTA3EInUQrdgoBinqUuSwlGdKDdE= github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU=
github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -167,10 +186,11 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.5.0 h1:042Buzk+NhDI+DeSAA62RwJL8VAuZUMQZUjCsRz1Mug= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM=
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@ -185,13 +205,16 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@ -199,10 +222,8 @@ github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7 h1:O63eWlXlvyw4YdsuatjRIU6emvJ2fqz+PTdMEoxIT2s= github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7/go.mod h1:yk5b0mALVusDL5fMM6Rd1wgnoO5jUPhwsQ6LQAJTidQ= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@ -214,35 +235,35 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/twitchtv/twirp v8.0.0+incompatible h1:uYHA8+9cit/+LUfQjL6zo/0QDKTo4U2H/WAnJ6LfhBU=
github.com/twitchtv/twirp v8.0.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -250,7 +271,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -264,15 +284,17 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -288,11 +310,17 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -300,6 +328,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -313,16 +342,23 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea h1:+WiDlPBBaO+h9vPNZi8uJ3k4BkKQB7Iow3aqwHVA5hI=
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -342,17 +378,15 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6 h1:nULzSsKgihxFGLnQFv2T7lE5vIhOtg8ZPpJHapEt7o0=
golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -365,7 +399,6 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -375,16 +408,22 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20201015140912-32ed001d685c h1:FM0/YezufKHjM3Y9gndHmhytJuCHW0bExs92Pu3LTQ0= google.golang.org/genproto v0.0.0-20210524171403-669157292da3 h1:xFyh6GBb+NO1L0xqb978I3sBPQpk6FrKO0jJGRvdj/0=
google.golang.org/genproto v0.0.0-20201015140912-32ed001d685c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210524171403-669157292da3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= 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.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.39.0-dev.0.20210519181852-3dd75a6888ce h1:UwAg44F4WVGhmEWcBpHqAfe5XGLe6FwErLFEfbmeNdI=
google.golang.org/grpc v1.39.0-dev.0.20210519181852-3dd75a6888ce/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0 h1:lQ+dE99pFsb8osbJB3oRfE5eW4Hx6a/lZQr8Jh+eoT4= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0 h1:lQ+dE99pFsb8osbJB3oRfE5eW4Hx6a/lZQr8Jh+eoT4=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@ -395,9 +434,12 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 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.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.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.26.1-0.20210520194023-50a85913fbce h1:nVuQ4k/NgcScf/FWjCN+NO1lTEMTfTBIFp5w7/qxyUA=
google.golang.org/protobuf v1.26.1-0.20210520194023-50a85913fbce/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
@ -409,18 +451,18 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=

182
tools/package-lock.json generated Normal file
View File

@ -0,0 +1,182 @@
{
"name": "tools",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://npm/@protobufjs%2faspromise/-/aspromise-1.1.2.tgz",
"integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=",
"dev": true
},
"@protobufjs/base64": {
"version": "1.1.2",
"resolved": "https://npm/@protobufjs%2fbase64/-/base64-1.1.2.tgz",
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
"dev": true
},
"@protobufjs/codegen": {
"version": "2.0.4",
"resolved": "https://npm/@protobufjs%2fcodegen/-/codegen-2.0.4.tgz",
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
"dev": true
},
"@protobufjs/eventemitter": {
"version": "1.1.0",
"resolved": "https://npm/@protobufjs%2feventemitter/-/eventemitter-1.1.0.tgz",
"integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=",
"dev": true
},
"@protobufjs/fetch": {
"version": "1.1.0",
"resolved": "https://npm/@protobufjs%2ffetch/-/fetch-1.1.0.tgz",
"integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
"dev": true,
"requires": {
"@protobufjs/aspromise": "^1.1.1",
"@protobufjs/inquire": "^1.1.0"
}
},
"@protobufjs/float": {
"version": "1.0.2",
"resolved": "https://npm/@protobufjs%2ffloat/-/float-1.0.2.tgz",
"integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=",
"dev": true
},
"@protobufjs/inquire": {
"version": "1.1.0",
"resolved": "https://npm/@protobufjs%2finquire/-/inquire-1.1.0.tgz",
"integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=",
"dev": true
},
"@protobufjs/path": {
"version": "1.1.2",
"resolved": "https://npm/@protobufjs%2fpath/-/path-1.1.2.tgz",
"integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=",
"dev": true
},
"@protobufjs/pool": {
"version": "1.1.0",
"resolved": "https://npm/@protobufjs%2fpool/-/pool-1.1.0.tgz",
"integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=",
"dev": true
},
"@protobufjs/utf8": {
"version": "1.1.0",
"resolved": "https://npm/@protobufjs%2futf8/-/utf8-1.1.0.tgz",
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=",
"dev": true
},
"@types/long": {
"version": "4.0.1",
"resolved": "https://npm/@types%2flong/-/long-4.0.1.tgz",
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==",
"dev": true
},
"@types/node": {
"version": "15.6.1",
"resolved": "https://npm/@types%2fnode/-/node-15.6.1.tgz",
"integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==",
"dev": true
},
"@types/object-hash": {
"version": "1.3.4",
"resolved": "https://npm/@types%2fobject-hash/-/object-hash-1.3.4.tgz",
"integrity": "sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA==",
"dev": true
},
"@types/prettier": {
"version": "1.19.1",
"resolved": "https://npm/@types%2fprettier/-/prettier-1.19.1.tgz",
"integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==",
"dev": true
},
"dataloader": {
"version": "1.4.0",
"resolved": "https://npm/dataloader/-/dataloader-1.4.0.tgz",
"integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==",
"dev": true
},
"lodash": {
"version": "4.17.21",
"resolved": "https://npm/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"long": {
"version": "4.0.0",
"resolved": "https://npm/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
"dev": true
},
"object-hash": {
"version": "1.3.1",
"resolved": "https://npm/object-hash/-/object-hash-1.3.1.tgz",
"integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==",
"dev": true
},
"prettier": {
"version": "2.3.0",
"resolved": "https://npm/prettier/-/prettier-2.3.0.tgz",
"integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==",
"dev": true
},
"protobufjs": {
"version": "6.11.2",
"resolved": "https://npm/protobufjs/-/protobufjs-6.11.2.tgz",
"integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==",
"dev": true,
"requires": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
"@protobufjs/codegen": "^2.0.4",
"@protobufjs/eventemitter": "^1.1.0",
"@protobufjs/fetch": "^1.1.0",
"@protobufjs/float": "^1.0.2",
"@protobufjs/inquire": "^1.1.0",
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.0",
"@types/long": "^4.0.1",
"@types/node": ">=13.7.0",
"long": "^4.0.0"
}
},
"ts-poet": {
"version": "4.5.0",
"resolved": "https://npm/ts-poet/-/ts-poet-4.5.0.tgz",
"integrity": "sha512-Vs2Zsiz3zf5qdFulFTIEpaLdgWeHXKh+4pv+ycVqEh+ZuUOVGrN0i9lbxVx7DB1FBogExytz3OuaBMJfWffpSQ==",
"dev": true,
"requires": {
"@types/prettier": "^1.19.0",
"lodash": "^4.17.15",
"prettier": "^2.0.2"
}
},
"ts-proto": {
"version": "1.81.1",
"resolved": "https://npm/ts-proto/-/ts-proto-1.81.1.tgz",
"integrity": "sha512-yp9ADpwZHWoraUF92vaX5pQPz5N0byOc7FO7kNMnIskkyDFhRwLKIYdj8souqRh3BSaXFeMo04804BDaBq8kGw==",
"dev": true,
"requires": {
"@types/object-hash": "^1.3.0",
"dataloader": "^1.4.0",
"object-hash": "^1.3.1",
"protobufjs": "^6.8.8",
"ts-poet": "^4.5.0",
"ts-proto-descriptors": "^1.2.1"
}
},
"ts-proto-descriptors": {
"version": "1.2.1",
"resolved": "https://npm/ts-proto-descriptors/-/ts-proto-descriptors-1.2.1.tgz",
"integrity": "sha512-iSHiQAaovi9sBwjiSCca/E089uv0IMt9Cfe0wV5AJwZppGa47yfih97Q+1006bdSLWkxf5Pk3VDQnt1yRTMV8w==",
"dev": true,
"requires": {
"long": "^4.0.0",
"protobufjs": "^6.8.8"
}
}
}
}

9
tools/package.json Normal file
View File

@ -0,0 +1,9 @@
{
"name": "tools",
"version": "1.0.0",
"description": "tooling for building web code from protobufs",
"devDependencies": {
"ts-proto": "^1.81.1"
},
"dependencies": {}
}

View File

@ -1,3 +1,5 @@
// +build tools
// package tool pins a number of Go dependencies that we use. Go builds really fast, // package tool pins a number of Go dependencies that we use. Go builds really fast,
// so wherever we can, we just build from source rather than pulling in third party binaries. // so wherever we can, we just build from source rather than pulling in third party binaries.
package main package main